This script doesn't work as intended - why?

I have a situation where a character has 3 sorts of clothes. I want to check what the character is wearing at the moment and store that for checking later. For some odd reason it doesn’t work as intended. The character has all the clothes in the inventory and is wearing one of the 3 clothes. However, when testing I get the message: “Lania doesn’t have the clothes”? Why is this? Am I using the GetItemInSlot function the wrong way? In that case, is there some other way to do this? (I already tried removing all the ClearAllActions to no effect)

Here’s my script (with my debug messages):

#include "ginc_companion"

void NotSelectable()
{

RemoveRosterMember("leniac");
//SetIsRosterMemberSelectable("leniac",FALSE);


}

void JumpLania(object oLania)
{

object oDestination = GetObjectByTag("laniastoragewp");

AssignCommand(oLania,ClearAllActions());
AssignCommand(oLania, JumpToObject(oDestination));

}

void main()
{

object oPC = GetFirstPC();

object oLania = GetObjectByTag("leniac");
object oWP = GetObjectByTag("acportalwp");
object oDestination = GetObjectByTag("laniastoragewp");

object oLaniaClothes = GetItemInSlot(INVENTORY_SLOT_CHEST,oLania);

object oLaniaClothing1 = GetObjectByTag("leniacloth1");
object oLaniaClothing2 = GetObjectByTag("leniacloth2");
object oLaniaClothing3 = GetObjectByTag("leniacloth3");

	if(oLaniaClothes == oLaniaClothing1)
	{
		SendMessageToPC(oPC,"Lania clothes 1");
		SetGlobalInt("LaniaClothLabyrinth1",1);

	}

	else if(oLaniaClothes == oLaniaClothing2)
	{

		SendMessageToPC(oPC,"Lania clothes 2");
		SetGlobalInt("LaniaClothLabyrinth2",1);

	}
	
	else if(oLaniaClothes == oLaniaClothing3)
	{
		SendMessageToPC(oPC,"Lania clothes 3");
		SetGlobalInt("LaniaClothLabyrinth3",1);

	}
	else
	{
	
		SendMessageToPC(oPC,"Lania doesn't have the clothes");
	
	}

//SetIsRosterMemberSelectable("leniac",TRUE);

DelayCommand(0.2,AssignCommand(oLania,ClearAllActions()));
//DelayCommand(0.3,AssignCommand(oLania, ActionForceMoveToObject(oWP)));

DelayCommand(2.5,NotSelectable());

//DelayCommand(3.0, SetScriptHidden(oLania,TRUE));

DelayCommand(3.0, JumpLania(oLania));

}

Maybe this object (oLenia) isn’t valid or isn’t unique

Another possible reason is that those objects aren’t unique

object oLaniaClothing1 = GetObjectByTag("leniacloth1");
object oLaniaClothing2 = GetObjectByTag("leniacloth2");
object oLaniaClothing3 = GetObjectByTag("leniacloth3");

Try a tagbased compare insteat of an object based one.

Thanks for the reply. The “leniac” is valid since the rest of the script works and I have other proofs of that too.

The objects aren’t unique no. I have two instances of each, so maybe that’s the problem. Maybe I should do a copy of all the clothes, give them a different tag, to make it work then?

You can never be sure which object is picked. Probably in your case the wrong one.

try

string oLaniaClothes = GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST,oLania));

and

	if(oLaniaClothes == "<Tag of Clothing 1>" )  // etc

That I call “tagbased compare”

1 Like

Copying the 3 items and then giving them each a new tag, resource name and resref seemed to do the trick.

Thanks for the help, @Mmat !

1 Like

you need to “reverse” the conditions.

Your problem here is that you fetch an item with a tag and compare in the condition.

The problem is if you have multiple items with the same tag you may have fetch not the one which you want.

so :

object oLaniaClothes = GetItemInSlot(INVENTORY_SLOT_CHEST,oLania);
string sTag  =  GetTag(oLaniaClothes);

if(sTag == "leniacloth1"){

}

This way you don’t check if the item is the item you fetched, but it check that your item has the tag you wanted.

If that item exist 10 times, it will check that it’s one of the 10.
the way you did it, it checks if it’s “THE ONE” you got with this line :

object oLaniaClothing1 = GetObjectByTag("leniacloth1");

if the item exist 10 times it can work only with one of them, in your case that would be the first “placed” in the game.

It’s possible the fetch item by orders of them placed in the game:

GetObjectByTag("leniacloth1",3);

The array for “GetObjectByTag” start at 0, so this line would check the 4th item with this tag placed in game.

Nevers forget that

GetObjectByTag("leniacloth1");

is in fact :

GetObjectByTag("leniacloth1",0);

Be carrefull with the index, some functions start at 1 and not 0, it’s inconsistent.

To make it work the way you did it you’d need a loop.

iterate on each item with the tag you check, and compare each time if it’s equiped by your NPC.

1 Like

@Shallina - Interesting points you brought up. I had no idea about GetObjectByTag(“itemtag”,0); and so forth. I think I also understand what I did wrong from your explanation. In any case, copying the clothes items and giving them unique tags solved the problem for me, even if I could have done it your way by checking the tag correctly through the GetTag function.

EDIT: Re-reading I see that @Mmat was saying the same thing as you just in different words, so thanks to both of you for explaining this to me.

The problem with using GetObjectByTag is that it gets the FIRST object with that tag which it finds in the module, so if you have other players with the same object or copies elsewhere in the game, the function could easily find one of those and, the more copies exist elsewhere, the more likely it is that one of those will be selected instead of the one held by the PC.
A better approach would be to use GetItemPossessedBy(object oPC,string sTag) since that will ensure that the item you find is the one held by the PC you specify in GetItemPossessedBy and it won’t look elsewhere.

2 Likes