Aller au contenu

Photo

Clear Inventory


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

#1
andysks

andysks
  • Members
  • 1 645 messages
Hi all, I was doing some tests, to see what works and what not... mainly with Lilac's. Apparently the option to clear all PC's items seems to not function. Is this a thing from NWN1 that is not working in NWN2 or something else? Here is the scripts Lilac's gives. I tried it OnClientEnter and OnEnter. Not from a convo.

void main()
{
    int nCount;
    object oTarget;
    object oItem;

    // Get the creature who triggered this event.
    object oPC = GetEnteringObject();

    // Only fire for (real) PCs.
    if ( !GetIsPC(oPC)  ||  GetIsDMPossessed(oPC) )
        return;

    // Only fire once.
    if ( GetLocalInt(GetModule(), "DO_ONCE__" + GetTag(OBJECT_SELF)) )
        return;
    SetLocalInt(GetModule(), "DO_ONCE__" + GetTag(OBJECT_SELF), TRUE);

    // Relieve the PC of its possessions.
    oTarget = GetObjectByTag("chest_pc_items");
    oItem = GetFirstItemInInventory(oPC);
    while ( oItem != OBJECT_INVALID )
    {
        AssignCommand(oTarget, ActionTakeItem(oItem, oPC));
        oItem = GetNextItemInInventory(oPC);
    }

    // Relieve the PC of its equipment.
    nCount = NUM_INVENTORY_SLOTS;
    while ( nCount-- > 0 )
    {
        oItem = GetItemInSlot(nCount, oPC);
        AssignCommand(oTarget, ActionTakeItem(oItem, oPC));
    }

    // Relieve the PC of its gold.
    AssignCommand(oTarget, TakeGoldFromCreature(GetGold(oPC), oPC));
}

Modifié par andysks, 14 octobre 2013 - 06:36 .


#2
Morbane

Morbane
  • Members
  • 1 883 messages
you have to assign a "value" to oTarget and oItem:

object oTarget = Get*something*

object oItem = GetFIrstInventoryItem().

just as examples since i havent scripted in a while and my memory isnt flash-hot on stock functions

#3
Morbane

Morbane
  • Members
  • 1 883 messages
here is a basic "empty inventory script"
void main()
{
object oPC = GetPCSpeaker();
object oItem = GetFirstItemInInventory(oPC);
object oTarget = GetObjectByTag("rip_off_box");

while (GetIsObjectValid(oPC))
{
while (GetIsObjectValid(oItem))
{
CopyItem(oItem, oTarget);
DestroyObject(oItem, 0.0f, FALSE);

oItem = GetNextItemInInventory(oPC);
}

int nSlot = 0;
while ( nSlot <= NUM_INVENTORY_SLOTS )
{
object oItem = GetItemInSlot(nSlot, oPC);
if (GetIsObjectValid(oItem))
{
CopyItem(oItem, oTarget);
DestroyObject(oItem, 0.0f, 0);
}
nSlot++;
}
}
}

this empties the inventory and all that the "victim" is wearing as well
"rip_off_box" is a container - it does not matter where the container is - as long as its Tag is unique
in this script - if the PC should die in the split second her inventory is being emptied - the while loop will close and the transfer will end - but the chances of that are pretty high against.

and - yes - you can replace GetPCSpeaker() - with - GetEnteringObject()

Modifié par Morbane, 14 octobre 2013 - 08:14 .


#4
andysks

andysks
  • Members
  • 1 645 messages
Ah so it works, just the script was incomplete.
Your scripting memory you say is not flash-hot but still you've helped me quite some times :).

#5
Morbane

Morbane
  • Members
  • 1 883 messages
there are many common scripting challenges -

you just seem to be travelling ground i once wracked my brain over before

8)

#6
Morbane

Morbane
  • Members
  • 1 883 messages
just for fun:

this cleans out the entire party:

void main()
{
object oPC = GetPCSpeaker();
object oFM = GetFirstFactionMember(oPC, FALSE);
object oItem = GetFirstItemInInventory(oFM);
object oTarget = GetObjectByTag("rip_off_box");

while (GetIsObjectValid(oFM))
{
while (GetIsObjectValid(oItem))
{
CopyItem(oItem, oTarget);
DestroyObject(oItem, 0.0f, FALSE);

oItem = GetNextItemInInventory(oFM);
}

int nSlot = 0;
while ( nSlot <= NUM_INVENTORY_SLOTS )
{
object oItem = GetItemInSlot(nSlot, oFM);
if (GetIsObjectValid(oItem))
{
CopyItem(oItem, oTarget);
DestroyObject(oItem, 0.0f, 0);
}
nSlot++;
}
oFM = GetNextFactionMember(oFM, FALSE);
}
}

#7
bealzebub

bealzebub
  • Members
  • 352 messages
what if someone had a bag of holding full of stuff? Would that get transfered intact?

#8
andysks

andysks
  • Members
  • 1 645 messages
I have no idea :D. I was just testing some stuff, so that I know how to do when and if I need them.

#9
bealzebub

bealzebub
  • Members
  • 352 messages
I would also check cursed and other non-removable items. I seem to remember having some trouble with non-removable items being cleared, but then stuck in the chest. I think I just excluded it, it was a dmfi-widget or something.

#10
Dann-J

Dann-J
  • Members
  • 3 161 messages
Container items are a royal pain to deal with, when it comes to moving things between inventories. They can end up duplicating items, or they can crash the game entirely. I don't know for sure what happens if you try to destroy them instead of moving them elsewhere, but I suspect DestroyObject conquers all.

#11
Morbane

Morbane
  • Members
  • 1 883 messages
yes DestroyObject will always work on its own

CopyItem() will crash the game if the container is maxed out as the default is something like 145(or whatever) not sure if you can make it higher as the field is editable in standard containers.

as for portable containers - the actual item would surely get copied/deleted but its contents = ???

#12
kevL

kevL
  • Members
  • 4 056 messages
this subject is unusually complicated and can lay to waste the best laid assumptions ... Some things i've noticed:

- items are treated individually, whether inside a container (or a container) or not.
- a container cannot be destroyed if there is something in it.
- an item marked to be destroyed won't be destroyed until after the script completes; this means that containers can't be destroyed until after, not only after the container is emptied, but after the script completes. (think: DelayCommand() )
- variables that were on items that are copied may be lost, i think (this happened to me for a creature). A CopyVars() function might needed, if you want to preserve those locals
- i have a strong suspicion that *items* marked Plot can be destroyed without removing that flag. (simple to test..)
- and as mentioned you might want special handling for cursed items...



script : Transfer all Items (done ...) <- *does* CopyVars() !

Modifié par kevL, 19 octobre 2013 - 03:30 .


#13
Morbane

Morbane
  • Members
  • 1 883 messages
@kevL

along these lines, is it possible to know - using one of the less thorough scripts + extra code - to detect a portable container and set a var on the PC?

so if it did not copy, an NPC could comment on it or something like that...

#14
kevL

kevL
  • Members
  • 4 056 messages
you mean, not for debugging but as an IG mechanic?


So that in a conversation with an NPC, he/she has a dialognode that says like "Hey, nice box!!" ?

- if the box has a tag just use a stock script like 'gc_check_item' .. from there it gets more complicated i guess.

#15
kevL

kevL
  • Members
  • 4 056 messages
i get it,

pseudo-code:

oContainer = GetFirstItemInInventory(oPC)
while (GetIsObjectValid(oContainer)))
{
if (GetHasInventory(oContainer)) <-- is a container
{
SetLocalInt(oPC, "i_has_container", TRUE)
break;
}

oContainer = GetNextItemInInventory(oPC)
}

#16
Morbane

Morbane
  • Members
  • 1 883 messages

kevL wrote...


i get it,

pseudo-code:

oContainer = GetFirstItemInInventory(oPC)
while (GetIsObjectValid(oContainer)))
{
if (GetHasInventory(oContainer)) <-- is a container <<---- ah-so u no script foo
{
SetLocalInt(oPC, "i_has_container", TRUE)
break;
}

oContainer = GetNextItemInInventory(oPC)
}

#17
andysks

andysks
  • Members
  • 1 645 messages
May I take this a bit further... what do you do if you want to move the inventory of a companion when he's removed from the party, to the PC's inventory?

#18
andysks

andysks
  • Members
  • 1 645 messages
I just saw the link to KevL's script. I guess the ga_kl_transferitems has params for tags where one can be the companion and the other the PC?

#19
kevL

kevL
  • Members
  • 4 056 messages
should work, in theory

If you have a dialog that a companion owns, and the PC talks to him/her, try these values:

PC node: "Give me all yer stuff."
action: ga_kl_transferitems("", "$OWNER", "", "$PC", 1, 1)


[edit] if there's isn't dialog involved, you'd probably want to copy & create an independent script or function ...

Modifié par kevL, 16 octobre 2013 - 09:40 .


#20
andysks

andysks
  • Members
  • 1 645 messages
It kinda happens in a dialogue but the companion is not the owner.
So maybe it could work like ("companiontag","","","$PC",1,1).

#21
kevL

kevL
  • Members
  • 4 056 messages
.. try it

#22
andysks

andysks
  • Members
  • 1 645 messages
You sound uncertain :D. From this thread I get that inventories are quite unstable to be handled with scripts right?

#23
kevL

kevL
  • Members
  • 4 056 messages
I wouldn't say unstable.. just complicated.

& i wouldn't say uncertain.. just ambivalent,


I mean, god only knows what you're doing there with a toolset this powerful

Modifié par kevL, 16 octobre 2013 - 11:35 .


#24
Dann-J

Dann-J
  • Members
  • 3 161 messages
The x0_i0_corpses include file contains some useful functions, like LootInventory() and LootInventorySlots(). They're meant to be used on corpses, but they might work on anything with an inventory.

#25
andysks

andysks
  • Members
  • 1 645 messages
KevL script works fine. Both for creatures or anything that has inventory, like chests.