Jump to content

Home

Script help: How to equip items on multiple npc's


T7nowhere

Recommended Posts

The problem I'm having is with equiping items on multiple npc's that use the same .utc and tag. What I'm trying to do give a couple items to 4 npc's and I want then to equipe one of the items. This script works fine to equip the items on the first 2 npc's But it doesn't work for the the last 2 npc's that have the same tag as the second one. Does that make sense :rolleyes:

 

void main ()
{

object oNPC1 = GetObjectByTag("npc tag", 0);
object oNPC2 = GetObjectByTag("npc tag2", 0);
object oNPC3 = GetObjectByTag("npc tag2", 0);
object oNPC4 = GetObjectByTag("npc tag2", 0);
object oolditem1 = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON ,oNPC1);
object oolditem2 = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON ,oNPC2);
object oolditem3 = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON ,oNPC3);
object oolditem4 = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON ,oNPC4);
object oNewitem1 = CreateItemOnObject("item",oNPC1);
object oNewitem2 = CreateItemOnObject("item2",oNPC2);
object oNewitem3 = CreateItemOnObject("item2",oNPC3);
object oNewitem4 = CreateItemOnObject("item2",oNPC4);
object oItem1 = CreateItemOnObject("item3",oNPC1);
object oItem2 = CreateItemOnObject("item4",oNPC1);
object oItem3 = CreateItemOnObject("item5",oNPC1);
object oItem4 = CreateItemOnObject("item6",oNPC2);
object oItem5 = CreateItemOnObject("item7",oNPC3);
object oItem6 = CreateItemOnObject("item8",oNPC4);



    if (GetIsObjectValid (oolditem1))
       {
       DestroyObject(oolditem1);
       }
    if (GetIsObjectValid (oolditem2))
       {
       DestroyObject(oolditem2);
       }
    if (GetIsObjectValid (oolditem3))
       {
       DestroyObject(oolditem3);
       }
    if (GetIsObjectValid (oolditem4))
       {
       DestroyObject(oolditem4);
       }
AssignCommand(oNPC1, ActionEquipItem(oNewitem1,INVENTORY_SLOT_RIGHTWEAPON));
AssignCommand(oNPC2, ActionEquipItem(oNewitem2,INVENTORY_SLOT_RIGHTWEAPON));
AssignCommand(oNPC3, ActionEquipItem(oNewitem3,INVENTORY_SLOT_RIGHTWEAPON));
AssignCommand(oNPC4, ActionEquipItem(oNewitem4,INVENTORY_SLOT_RIGHTWEAPON));


}

Link to comment
Share on other sites

It looks like you are fetching the same object 3 times in a row. Try changing the second parameter for GetObjectByTag like this:

 

void main ()
{

object oNPC1 = GetObjectByTag("npc tag", 0);
object oNPC2 = GetObjectByTag("npc tag2", 0);
object oNPC3 = GetObjectByTag("npc tag2", 1);
object oNPC4 = GetObjectByTag("npc tag2", 2);

// snip

}

 

If this doesn't work, then you'd probably need to create a small while() loop to work around this.

Link to comment
Share on other sites

have you tried upping the nNth tag in the "GetObjectByTag" method?? I'm not sure if it will have an effect or not, but I'd guess that upping that number will reference the different instances of your npc.

 

something like this.

 

object oNPC1 = GetObjectByTag("npc tag", 0);
object oNPC2 = GetObjectByTag("npc tag2", 0);
object oNPC3 = GetObjectByTag("npc tag2", 1);
object oNPC4 = GetObjectByTag("npc tag2", 2);

 

I have no idea if it works this way or not, but its worth a try :)

 

**************************

 

AHHHH! Xcom beat me to it!!!

Link to comment
Share on other sites

Thanks guys that worked great. It was such a minor thing too.

 

Edit: I just thought of something else what do I need to do to make sure those items are only created once. I am using that script in with an on module load script. so if its saved, loaded save, loaded, saved, loaded, ect. Its a potencial exploit for some nice items that I would prefer to avoid ;)

Link to comment
Share on other sites

well, there are number of ways to do that ranging from using global variables to local variables, etc. Much depends on the situation (can those NPCs be killed by the player, are those unique items. etc)

 

But since these are NPCs (not Player), this becomes easier.. (since poor NPCs don't have the previlige of breaking down items.. LOL)

If those are unique items, you can simply check if NPC possesses the specific item and if he does, don't spawn new ones. For example:

 

void main ()
{

object oNPC1 = GetObjectByTag("npc tag", 0);
object oNPC2 = GetObjectByTag("npc tag2", 0);
object oNPC3 = GetObjectByTag("npc tag2", 1);
object oNPC4 = GetObjectByTag("npc tag2", 2);


if (GetIsObjectValid(oNPC1))
{
if (GetIsObjectValid(GetItemPossessedBy(oNPC1, "item TAG")))
{
	// NPC has the item, so the script has been called once before
	// do nothing
	return;
}
} else {
// npc doesn't exist, was killed, some error...???
return;
}

// the rest of the code

}

 

edit: fixed typo

Link to comment
Share on other sites

Ok so I would need to write the if else statments for each item?

 

edit: hmm. I'm getting compilling errors

 

Error: Undeclared identifier GetItemPossesedBy

Error: Required argument missing in call to GetIsObjectValid

 

I assume that all I needed to change was the "item tag" to my items tag. Did I need to do something more.

Link to comment
Share on other sites

From the base line script you have above you wouldn't need to build any more safeties into the script in case of respawn. The reason is your script at the top is using a destroy object function call to destroy the old object. So if your weapon is already equipped the script will destroy the copy currently in hand and then create a new version of it to replace it.

 

 

-edit- since it is a on module load script the save game also retains what has already happened in a module. So if the npc's are already spawned the first time you enter the module and you kill them then they aren't going to spawn again. This is do to the save data that gets saved for that module on entering or exiting the module.

Link to comment
Share on other sites

Originally posted by T7nowhere

I assume that all I needed to change was the "item tag" to my items tag. Did I need to do something more.

 

No, you are right.

Unfortunately, I made a typo (was writing that from memory)

 

It's GetItemPossessedBy (two double asses :D )

Link to comment
Share on other sites

Originally posted by Darkkender

So if the npc's are already spawned the first time you enter the module and you kill them then they aren't going to spawn again. This is do to the save data that gets saved for that module on entering or exiting the module.

 

Ya but you see where the problem comes up is only 1 of the of the items is being destroyed on the npc's. And the other is that sinse it is on module load if the game is saved before the npc's are killed and then reloaded the npc's wll have duplicates of the other items.

Link to comment
Share on other sites

You could make sure the script is run only once by checking if a boolean has been set at the top of the script, and if so abort the script execution. Then set that boolean to true the first time the script runs.

 

When doing the same series of operations several times, it might also be a good idea to put that in a separate function. Avoids lots of repeated code.

 

Like this, to use your modified code as an example:

 

void GiveAndEquip(string sResRef, string sTag="") {
if (sTag == "")
	sTag = sResRef;

if (!GetIsObjectValid( GetItemPossessedBy(OBJECT_SELF, sTag) )) {
	object oolditem = GetItemInSlot( INVENTORY_SLOT_RIGHTWEAPON, OBJECT_SELF );
	object oNewitem = CreateItemOnObject(sResRef, OBJECT_SELF);

    	if (GetIsObjectValid (oolditem))
       	DestroyObject(oolditem);

	ActionEquipItem(oNewitem, INVENTORY_SLOT_RIGHTWEAPON, TRUE );
}
}

void main () {
if (GetLocalBoolean(OBJECT_SELF, 40))
	return;	

SetLocalBoolean(OBJECT_SELF, 40, TRUE);	

object oNPC1 = GetObjectByTag("npc tag", 0);
object oNPC2 = GetObjectByTag("npc tag2", 0);
object oNPC3 = GetObjectByTag("npc tag2", 1);
object oNPC4 = GetObjectByTag("npc tag2", 2);

AssignCommand(oNPC1, GiveAndEquip("item"));
AssignCommand(oNPC2, GiveAndEquip("item2"));
AssignCommand(oNPC3, GiveAndEquip("item2"));
AssignCommand(oNPC4, GiveAndEquip("item2"));

CreateItemOnObject("item3",oNPC1);
CreateItemOnObject("item4",oNPC1);
CreateItemOnObject("item5",oNPC1);
CreateItemOnObject("item6",oNPC2);
CreateItemOnObject("item7",oNPC3);
CreateItemOnObject("item8",oNPC4);
}

 

The above example assumes that your items have the same Tag as their ResRef. This is normally true but isn't necessarily so.

Link to comment
Share on other sites

Thanks Xcom, again it was a simple solution. See this is why I don't like coding ;) got it working the way I want it to now.

 

@stoffe -mkb-

 

I like your script, I'll try it out on next scene that follows a similar scenario and I have a couple more of those :)

 

Thanks again guys, I knew I could count on you to set me up.

Link to comment
Share on other sites

Originally posted by tk102

I would urge caution in using Local booleans on creatures unless you're certain the boolean slot in question is unused by the game. I've seen the use of slots in the 30s but not in the 40s. Just my 2 cents.

 

Agreed, you have to check if they are not already used for something else. Local booleans below 30 and above 65 are used by the Creature AI, and is best not messed with on creatures (unless you are altering the AI of course).

 

Those between 30-64 are in the "designer range" which means they should be used for this kind of thing. But they may (or may not) be in use to keep track of other things already, so you'll need to check the object in question.

 

For example 57 is used on containers to keep track of if random loot has been generated for it, so it would be a bad idea to use that for anything else on objects with an inventory.

 

I used 40 in my example since it seems to be used by many triggers to keep track of if their onenter script has been fired once.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...