Are these functions buggy?

I’ve done a bunch of tests with scripts trying to use these two functions:

RememberEquippedItems(oCreature);
RestoreEquippedItems(oCreature);

Sadly, it seems that they work only somewhat but not so that I can use and trust them.
Anyone know anything about these? They are part of the include script “ginc_item”.

To explain in more detail:

  1. The function RememberEquippedItems(oCreature); is run on all companions. Then they are teleported to a new area where their hands and head are unequipped.
  2. At a later stage you leave this area and when entering a new area I run a RestoreEquippedItems(oCreature); . When testing this with SendMessageToPC it seems that everything is run, however, only two of the four companions in the party are again equipped with the weapons they had equipped before moving to the first area.

yes they are buggy. Here’s better versions of those functions in Nwn2Fixes →

// store info on item about current owner and slot equipped
void RememberEquippedItem(object oOwner, int iSlot)
{
	object oInventoryItem = GetItemInSlot(iSlot, oOwner);
	if (oInventoryItem != OBJECT_INVALID)
	{
		SetLocalInt(oInventoryItem, LAST_SLOT_NUM, iSlot + 1); // Nwn2Fix
		SetLocalObject(oInventoryItem, LAST_SLOT_OBJ, oOwner);
	}
}

// store info on all equipped items of owner
void RememberEquippedItems(object oOwner)
{
    int iSlot;
    for (iSlot = 0; iSlot < NUM_INVENTORY_SLOTS; iSlot++)
    {
		RememberEquippedItem(oOwner, iSlot);
    }
}


// restore item to slot last remembered
void RestoreEquippedItem(object oOwner, object oInventoryItem, int bReset=TRUE)
{
	int iSlot = GetLocalInt(oInventoryItem, LAST_SLOT_NUM);
	//object oOrigOwner = GetLocalObject(oInventoryItem, LAST_SLOT_OBJ);

	if (iSlot > 0)
	{
	    AssignCommand(oOwner, ActionEquipItem(oInventoryItem, iSlot - 1)); // Nwn2Fix
		if (bReset)
		{
			DeleteLocalInt(oInventoryItem, LAST_SLOT_NUM);
			DeleteLocalObject(oInventoryItem, LAST_SLOT_OBJ);
		}
	}
}

// Restore all inventory items to equipment slot last remembered (if any)
void RestoreEquippedItems(object oOwner, int bReset=TRUE)
{
    object oInventoryItem = GetFirstItemInInventory(oOwner);
	object oLeftHandItem;
	int iSlot;
	
	while (oInventoryItem != OBJECT_INVALID)
    {
		iSlot = GetLocalInt(oInventoryItem, LAST_SLOT_NUM);
		
		//EPF 8/29/06 left hand must be equipped after right.  Otherwise the engine
		//    will shift it to the right hand slot automatically.
		if(iSlot - 1 != INVENTORY_SLOT_LEFTHAND) // Nwn2Fix
		{
			RestoreEquippedItem(oOwner, oInventoryItem, bReset);
		}
		else
		{
			oLeftHandItem = oInventoryItem;
		}
        oInventoryItem = GetNextItemInInventory(oOwner); // Nwn2Fix
    }
	
	if(GetIsObjectValid(oLeftHandItem))
	{
		RestoreEquippedItem(oOwner, oLeftHandItem, bReset);
	}
}
2 Likes

Thanks for the reply, @kevL_s ! I was going nuts over this and I thought I did something wrong even though everything told me I didn’t. Glad to see that it wasn’t me this time.

I’ll try your fix.

sure, give 'em a try. It could be something else tho … (failure to re-equip weapons)

When I have you online here speaking to me…

I tried using the buggy restore function just before running a gui script:

void SelectYourParty()
{

    ShowPartySelect(GetFirstPC(),
					TRUE,         // modal
                    "jump_exit",  // callback script on Accept
                    TRUE);        // show close button

}

For some reason when doing that, the gui wouldn’t run. As soon as I removed the RestoreEquippedItems(oCreature); from the script with the SelectYourParty() the GUI would show again. Any thoughts about that?

my guess (and im not looking at it too hard atm) is that the stock version of RestoreEquippedItems() has a potential infinite loop. i think it possible that the engine threw a TMI (too many instructions) and shut the rest of the script down at that pt.

Aha. If that was the case that would be logical, yes.

1 Like

Just tested your improved versions of the functions. Now it works like a charm! Great work, @kevL_s ! Thanks!

1 Like

sweet :)