Aller au contenu

Photo

Dropping items on player death


  • Veuillez vous connecter pour répondre
12 réponses à ce sujet

#1
Colton

Colton
  • Members
  • 58 messages

I'm trying to get this script to work, it should make players drop all items they have where they die. I have tried to get it to work, but to no avail. If someone could provide me with instructions on how to get this to work that would be great.

void main ()
{
  //Set variables
  int xCount, xGold;
  object xPC, xCorpse, xItem;
  location xLoc;
  //Get player and find locations
  xPC = GetLastPlayerDying();
  xLoc = GetLocation(xPC);
  //Create corpse at player's feet
  xCorpse = CreateObject(OBJECT_TYPE_PLACEABLE,"corpse002",xLoc);
  //Drop equipment on corpse
  for (xCount = 1; xCount < 15; xCount++)
  {
    switch (xCount)
    {
      case 1: xItem = GetItemInSlot(INVENTORY_SLOT_ARMS,xPC); break;
      case 2: xItem = GetItemInSlot(INVENTORY_SLOT_ARROWS,xPC); break;
      case 3: xItem = GetItemInSlot(INVENTORY_SLOT_BELT,xPC); break;
      case 4: xItem = GetItemInSlot(INVENTORY_SLOT_BOLTS,xPC); break;
      case 5: xItem = GetItemInSlot(INVENTORY_SLOT_BOOTS,xPC); break;
      case 6: xItem = GetItemInSlot(INVENTORY_SLOT_BULLETS,xPC); break;
      case 7: xItem = GetItemInSlot(INVENTORY_SLOT_CHEST,xPC); break;
      case 8: xItem = GetItemInSlot(INVENTORY_SLOT_CLOAK,xPC); break;
      case 9: xItem = GetItemInSlot(INVENTORY_SLOT_HEAD,xPC); break;
      case 10: xItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,xPC); break;
      case 11: xItem = GetItemInSlot(INVENTORY_SLOT_LEFTRING,xPC); break;
      case 12: xItem = GetItemInSlot(INVENTORY_SLOT_NECK,xPC); break;
      case 13: xItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,xPC); break;
      case 14: xItem = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,xPC); break;
    }
    if (GetIsObjectValid(xItem))
    {
      AssignCommand(xCorpse,ActionTakeItem(xItem,xPC));
    }
  }
}


#2
kevL

kevL
  • Members
  • 4 070 messages

copy & destroy should work better ... there are also a few niggles that need to be sorted

// helper for laden containers
void TransferBag(object oItem, object oCorpse);

void main()
{
    object oPC = GetLastPlayerDied();

    location lLoc = GetLocation(oPC);
    object oCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, "corpse002", lLoc);

    object oItem = OBJECT_INVALID;

    int iSlot;
    for (iSlot = INVENTORY_SLOT_HEAD; iSlot <= INVENTORY_SLOT_BOLTS; iSlot++)
    {
        oItem = GetItemInSlot(iSlot, oPC);
        if (GetIsObjectValid(oItem)
            && !GetItemCursedFlag(oItem))
        {
            CopyItem(oItem, oCorpse, TRUE);
            DestroyObject(oItem, 0.f, FALSE);
        }
    }

    oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem))
    {
        if (!GetItemCursedFlag(oItem))
        {
            if (!GetHasInventory(oItem)
                || !GetIsObjectValid(GetFirstItemInInventory(oItem)))
            {
                CopyItem(oItem, oCorpse, TRUE);
                DestroyObject(oItem, 0.f, FALSE);
            }
            else // is a container with something in it
            {
                DelayCommand(0.1f, TransferBag(oItem, oCorpse));
            }
        }

        oItem = GetNextItemInInventory(oPC);
    }

    CreateItemOnObject("nw_it_gold001", oCorpse, GetGold(oPC));
}


void TransferBag(object oItem, object oCorpse)
{
    // if a Cursed item is still in the Bag, neither will not be copied or destroyed
    if (!GetIsObjectValid(GetFirstItemInInventory(oItem)))
    {
        CopyItem(oItem, oCorpse, TRUE);
        DestroyObject(oItem, 0.f, FALSE);
    }
}

  • Colton aime ceci

#3
Dann-J

Dann-J
  • Members
  • 3 161 messages

Dead creatures can't have actions added to their action queue, and I doubt that placeables have action queues at all. Therefore ActionTakeItem() wouldn't work in this instance. Hence the need for kevL's approach of recreating the items and destroying the originals.


  • Colton aime ceci

#4
Colton

Colton
  • Members
  • 58 messages

Thats exactly what i need! Can I trigger this with the on player death script?



#5
kevL

kevL
  • Members
  • 4 070 messages

Thats exactly what i need! Can I trigger this with the on player death script?


copy the stuff between
void main()
{
    //......<copy stuff that's in here>......
}
that code should be self contained, and can be pasted into your current onDeath script, as long as you remember the helper function has to go along with it ((same as before))


ps. Leave out the re-definition of oPC though, if the compiler pops an error ...

#6
Colton

Colton
  • Members
  • 58 messages

 



ps. Leave out the re-definition of oPC though, if the compiler pops an error ...

 

So this?

location lLoc = GetLocation(oPC);
    object oCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, "corpse002", lLoc);

    object oItem = OBJECT_INVALID;

    int iSlot;
    for (iSlot = INVENTORY_SLOT_HEAD; iSlot <= INVENTORY_SLOT_BOLTS; iSlot++)
    {
        oItem = GetItemInSlot(iSlot, oPC);
        if (GetIsObjectValid(oItem)
            && !GetItemCursedFlag(oItem))
        {
            CopyItem(oItem, oCorpse, TRUE);
            DestroyObject(oItem, 0.f, FALSE);
        }
    }

    oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem))
    {
        if (!GetItemCursedFlag(oItem))
        {
            if (!GetHasInventory(oItem)
                || !GetIsObjectValid(GetFirstItemInInventory(oItem)))
            {
                CopyItem(oItem, oCorpse, TRUE);
                DestroyObject(oItem, 0.f, FALSE);
            }
            else // is a container with something in it
            {
                DelayCommand(0.1f, TransferBag(oItem, oCorpse));
            }
        }

        oItem = GetNextItemInInventory(oPC);
    }

    CreateItemOnObject("nw_it_gold001", oCorpse, GetGold(oPC));
}


void TransferBag(object oItem, object oCorpse)
{
    // if a Cursed item is still in the Bag, neither will not be copied or destroyed
    if (!GetIsObjectValid(GetFirstItemInInventory(oItem)))
    {
        CopyItem(oItem, oCorpse, TRUE);
        DestroyObject(oItem, 0.f, FALSE);


#7
Colton

Colton
  • Members
  • 58 messages

Right now, this is my on death script. Where does that go? I keep getting errors for everything i put in. 

//::///////////////////////////////////////////////
//:: Death Script
//:: 'kg_mod_death' / NW_O0_DEATH.NSS
//:: Copyright (c) 2012 kevL's / (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*    This script handles specific behavior that
    occurs when an Owned Character dies. It is
    part of the Kingz Gaite campaign setup and
    should not be overridden ... */
/*  This script handles the default behavior
    that occurs when a player dies.
    BK: October 8 2002: Overriden for Expansion */
//:://////////////////////////////////////////////
//:: Created By: Brent Knowles     mod: kevL's
//:: Created On: November 6, 2001   on: May 2009, Jul 2010
//:://////////////////////////////////////////////
// BMA-OEI 7/20/06 -- Temp death screen
// BMA-OEI 11/08/06 -- Added engine death GUI: SCREEN_DEATH_DEFAULT
// (ingamegui.ini) is force closed upon resurrection
// kevL's modified, 2010 ..
//    - modded further, 2012 may 14


// Display death pop-up to oPC

void kL_ShowDeathScreen(object oPC)
{
    DisplayMessageBox(oPC,
                        FALSE,                        // MessageBox STRREF
                        GetStringByStrRef(181408),    // text: "You have died."
                        "gui_cityrespawn",        // callback for 'ok'
                        "",                            // callback for 'cancel'
                        FALSE,                        // no cancel option.
                        "",                            // GUIScreenName: "SCREEN_MESSAGEBOX_DEFAULT"
                        6603,                        // ok STRREF: "Respawn"
                        "Respawn",                    // ok text, overrides STRREF
                        FALSE,                        // cancel STRREF: ""
                        "");                        // cancel text.
}
void main()

{
    SendMessageToPC(GetFirstPC(FALSE), "");

    object oPC = GetLastPlayerDied();
    SendMessageToPC(GetFirstPC(FALSE), "You have died : " + GetName(oPC));

    // try to avoid possible complications
    AssignCommand(oPC, SetCommandable(TRUE));
    AssignCommand(oPC, ClearAllActions(TRUE));

    // he's dead jim
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPC);

    // Check for additional death script
    string sDeathScript = GetLocalString(oPC, "DeathScript");
    if (sDeathScript != "") ExecuteScript(sDeathScript, oPC);


    // player is controlling the OwnedPC; try to switch to Companion:
    if (GetIsPC(oPC))
    {
        object oCompanion;
        string sCompanion = GetFirstRosterMember();
        while (sCompanion != "")
        {
            oCompanion = GetObjectFromRosterName(sCompanion);
            if (GetIsObjectValid(oCompanion)
                    && GetFactionEqual(oCompanion, oPC)
                    && !GetIsDead(oCompanion)
                    && !GetIsCompanionPossessionBlocked(oCompanion)
                    && !GetIsPC(oCompanion))
            {
                // Give control to the first living, unblocked, uncontrolled Companion
                SetOwnersControlledCompanion(oPC, oCompanion);

                return;
            }

            sCompanion = GetNextRosterMember();
        }
    }
    // if you're not controlling the OwnedPC, just let it die unless everyone else is dead too
    else
    {
        // if the character that the player is controlling isn't dead-dead, do nothing.
        oPC = GetControlledCharacter(oPC);
        if (!GetIsDead(oPC, TRUE)) return;

        object oFM = GetFirstFactionMember(oPC, FALSE);
        while (GetIsObjectValid(oFM))
        {
            // if there is a living Companion ( not an Associate or another PC )
            // This really should check for things like, oh Permanent paralysis etc.
            if (oPC != oFM
                    && !GetIsDead(oFM)
//                    && !GetIsCompanionPossessionBlocked(oFM)
                    && !GetIsPC(oFM)
                    && !GetAssociateType(oFM))
            {
                // it's all good.
                return;
            }

            oFM = GetNextFactionMember(oPC, FALSE);
        }

        // else Pop the player into the OwnedCorpse:
        oPC = SetOwnersControlledCompanion(oPC);
    }


    // below this line, the Party is dead! ( except perhaps another PC )
    DelayCommand(4.6f, kL_ShowDeathScreen(oPC));
	
}



#8
kevL

kevL
  • Members
  • 4 070 messages

let's make it into a subfunction or two ...

//::///////////////////////////////////////////////
//:: Death Script
//:: 'kg_mod_death' / NW_O0_DEATH.NSS
//:: Copyright (c) 2012 kevL's / (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*    This script handles specific behavior that
    occurs when an Owned Character dies. It is
    part of the Kingz Gaite campaign setup and
    should not be overridden ... */
/*    This script handles the default behavior
    that occurs when a player dies.
    BK: October 8 2002: Overriden for Expansion */
//:://////////////////////////////////////////////
//:: Created By: Brent Knowles       mod: kevL's
//:: Created On: November 6, 2001    on: May 2009, Jul 2010
//:://////////////////////////////////////////////
// BMA-OEI 7/20/06 -- Temp death screen
// BMA-OEI 11/08/06 -- Added engine death GUI: SCREEN_DEATH_DEFAULT
// (ingamegui.ini) is force closed upon resurrection
// kevL's modified, 2010 ..
//      - modded further, 2012 may 14


// Drop all items & Gold
void DropEverything(object oPC);
//
void TransferBag(object oItem, object oCorpse);


// Display death pop-up to oPC
void kL_ShowDeathScreen(object oPC)
{
    DisplayMessageBox(oPC,
                        FALSE,                        // MessageBox STRREF
                        GetStringByStrRef(181408),    // text: "You have died."
                        "gui_cityrespawn",            // callback for 'ok'
                        "",                         // callback for 'cancel'
                        FALSE,                        // no cancel option.
                        "",                         // GUIScreenName: "SCREEN_MESSAGEBOX_DEFAULT"
                        6603,                        // ok STRREF: "Respawn"
                        "Respawn",                    // ok text, overrides STRREF
                        FALSE,                        // cancel STRREF: ""
                        "");                        // cancel text.
}


void main()
{
    SendMessageToPC(GetFirstPC(FALSE), "");

    object oPC = GetLastPlayerDied();
    SendMessageToPC(GetFirstPC(FALSE), "You have died : " + GetName(oPC));

    DropEverything(oPC); // HERE IT IS.

    // try to avoid possible complications
    AssignCommand(oPC, SetCommandable(TRUE));
    AssignCommand(oPC, ClearAllActions(TRUE));

    // he's dead jim
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPC);

    // Check for additional death script
    string sDeathScript = GetLocalString(oPC, "DeathScript");
    if (sDeathScript != "") ExecuteScript(sDeathScript, oPC);


    // player is controlling the OwnedPC; try to switch to Companion:
    if (GetIsPC(oPC))
    {
        object oCompanion;
        string sCompanion = GetFirstRosterMember();
        while (sCompanion != "")
        {
            oCompanion = GetObjectFromRosterName(sCompanion);
            if (GetIsObjectValid(oCompanion)
                    && GetFactionEqual(oCompanion, oPC)
                    && !GetIsDead(oCompanion)
                    && !GetIsCompanionPossessionBlocked(oCompanion)
                    && !GetIsPC(oCompanion))
            {
                // Give control to the first living, unblocked, uncontrolled Companion
                SetOwnersControlledCompanion(oPC, oCompanion);

                return;
            }

            sCompanion = GetNextRosterMember();
        }
    }
    // if you're not controlling the OwnedPC, just let it die unless everyone else is dead too
    else
    {
        // if the character that the player is controlling isn't dead-dead, do nothing.
        oPC = GetControlledCharacter(oPC);
        if (!GetIsDead(oPC, TRUE)) return;

        object oFM = GetFirstFactionMember(oPC, FALSE);
        while (GetIsObjectValid(oFM))
        {
            // if there is a living Companion ( not an Associate or another PC )
            // This really should check for things like, oh Permanent paralysis etc.
            if (oPC != oFM
                    && !GetIsDead(oFM)
//                    && !GetIsCompanionPossessionBlocked(oFM)
                    && !GetIsPC(oFM)
                    && !GetAssociateType(oFM))
            {
                // it's all good.
                return;
            }

            oFM = GetNextFactionMember(oPC, FALSE);
        }

        // else Pop the player into the OwnedCorpse:
        oPC = SetOwnersControlledCompanion(oPC);
    }


    // below this line, the Party is dead! ( except perhaps another PC )
    DelayCommand(4.6f, kL_ShowDeathScreen(oPC));
}


//
void DropEverything(object oPC)
{
    location lLoc = GetLocation(oPC);
    object oCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, "corpse002", lLoc);

    object oItem = OBJECT_INVALID;

    int iSlot;
    for (iSlot = INVENTORY_SLOT_HEAD; iSlot <= INVENTORY_SLOT_BOLTS; iSlot++)
    {
        oItem = GetItemInSlot(iSlot, oPC);
        if (GetIsObjectValid(oItem)
            && !GetItemCursedFlag(oItem))
        {
            CopyItem(oItem, oCorpse, TRUE);
            DestroyObject(oItem, 0.f, FALSE);
        }
    }

    oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem))
    {
        if (!GetItemCursedFlag(oItem))
        {
            if (!GetHasInventory(oItem)
                || !GetIsObjectValid(GetFirstItemInInventory(oItem)))
            {
                CopyItem(oItem, oCorpse, TRUE);
                DestroyObject(oItem, 0.f, FALSE);
            }
            else // is a container with something in it
            {
                DelayCommand(0.1f, TransferBag(oItem, oCorpse));
            }
        }

        oItem = GetNextItemInInventory(oPC);
    }

    CreateItemOnObject("nw_it_gold001", oCorpse, GetGold(oPC));
}

//
void TransferBag(object oItem, object oCorpse)
{
    // if a Cursed item is still in the Bag, neither will not be copied or destroyed
    if (!GetIsObjectValid(GetFirstItemInInventory(oItem)))
    {
        CopyItem(oItem, oCorpse, TRUE);
        DestroyObject(oItem, 0.f, FALSE);
    }
}

  • Kaldor Silverwand aime ceci

#9
kevL

kevL
  • Members
  • 4 070 messages

btw, if you want to remove that first SendMessageToPC() .. just delete it or put // in front of it.


  • Colton aime ceci

#10
Colton

Colton
  • Members
  • 58 messages

Well, it works! KevL, I can't thank you enough. This was the last script i needed to work fully, awesome...



#11
kevL

kevL
  • Members
  • 4 070 messages

i'm kinda astonished myself, but hey Tally Ho

& debug later,



#12
kevL

kevL
  • Members
  • 4 070 messages

oh, Cotlon, here's an exercise for ya

I forgot to take the gold away from the PC ... when he gets back to his corpse he'd have double



#13
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 598 messages

The OC has a script 11a_comp_unload_inv that is used to drop all of Bevil's items into a bag. I used that as the basis for the scripts I developed as my enhancements to Baldur's Gate Reloaded so that when party members die their belongings are dropped as was done in BG. So for an alternative way to accomplish this you can download my BGR Enhancements and look at the bg_module_on_heartbat.nss script.

 

Regards