Aller au contenu

Photo

On Player Equip Item Script


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

#1
kamal_

kamal_
  • Members
  • 5 240 messages

This module level script does not seem to fire for cohorts. I created a cohort and added him to my party using the SoZ cohort join method (Umoja is my test cohort), when he equips something, I am not getting the debug message I added eg "script running..." for the cohort. When the main pc equips the same item, the script runs and I see my debug message.

 

I am trying to do things with the cohort, controlling their ability to wear categories of items (for instance, cohort will not wear any heavy armor, but will wear light/medium), so tag based scripting at the item aquired level is not an option. So bascially I need to detect when the cohort equips something, as I can script the rest of what I want.

 

I checked Okku on MotB as he's item restricted, but he works via the module On Player Equip Item script, so there seems to be a difference in how the cohorts are treated versus companions.



#2
Dann-J

Dann-J
  • Members
  • 3 161 messages

Okku also has an automatic level-up system that removes certain feats from him, like the weapon and armour proficiencies he should get as a fighter. If you can remove a certain feat from a cohort (like heavy armour proficiency), then you won't need the OnEquip scripts - they simply won't be able to equip certain items to begin with.



#3
kamal_

kamal_
  • Members
  • 5 240 messages

Okku also has an automatic level-up system that removes certain feats from him, like the weapon and armour proficiencies he should get as a fighter. If you can remove a certain feat from a cohort (like heavy armour proficiency), then you won't need the OnEquip scripts - they simply won't be able to equip certain items to begin with.

Yes, I started by looked at Okku since I knew he was item restricted. Okku can't wear armor or use weapons not because those item slots are unavailable, but because he lacks any weapon and armor proficiencies. If you manually give him the proficiencies or remove the feat stripping bit from his level up script, he can use weapons and wear armor. Okku, the thayan golem you build etc have code specific to them in the MotB module On Player Equip script, so I figured I could do the same for my cohort, but my testing was showing the script wasn't firing when I had the cohort equip.

 

What I want is a cohort to have a general no to using a given item category, but with exceptions that I will add that are tag based. So a cohort that won't wear any heavy armor, except the suit of "armor of being awesome". For that to happen, they need to have the appropriate feats so they are capable of wearing heavy armor, but refuse to wear heavy armor except for the particular armor. Scripting the willingness to wear/not wear in a tag system is not a problem, it's just a matter of I can't figure out how to access the onEquip of cohorts.



#4
Dann-J

Dann-J
  • Members
  • 3 161 messages

On OnAcquired tag-based script for the special armour could give them back the heavy armour feat, and curse the armour so it can't be taken back from them. A tag-based OnUnequip script could prevent you from removing the armour (re-equipping it immediately if it's removed), which would prevent them from wearing other sets of heavy armour (that's how my cursed item scripts function).

 

If they're a class that usually allows them to have that proficiency feat, and they have an automatic level-up script that usually removes it from them, then a check for that particular armour item in their inventory can determine whether the feat is removed during level-up or not.



#5
Tchos

Tchos
  • Members
  • 5 042 messages

Well, since it's a unique item, you could always create a special proficiency feat required to use that item alone, if you create a new baseitem for it.



#6
kamal_

kamal_
  • Members
  • 5 240 messages

On OnAcquired tag-based script for the special armour could give them back the heavy armour feat, and curse the armour so it can't be taken back from them. A tag-based OnUnequip script could prevent you from removing the armour (re-equipping it immediately if it's removed), which would prevent them from wearing other sets of heavy armour (that's how my cursed item scripts function).

 

If they're a class that usually allows them to have that proficiency feat, and they have an automatic level-up script that usually removes it from them, then a check for that particular armour item in their inventory can determine whether the feat is removed during level-up or not.

The first paragraph has the exploit of giving them the armor so they get the proficiency, then giving them a different set of armor and having them equip that instead. And in this case since it would be a group of armors, not just a specific one, an onaquire that forces equip would cause problems if you gave them multiple acceptable armors to carry around.

 

Tchos suggestion of a new baseitem and special feats sounds like the it would work. I'm not fond of altering those 2das since it's something that can cause compatibility problems (Kaedrin has his feats.2da and is implementing new base items for instance), so my preference is the onEquip script because I can use tag scripting to make my own item categories like I did for hidden weaponry in Crimmor.



#7
kevL

kevL
  • Members
  • 4 056 messages
I've been playing around with the PlayerEquip/Unequip scripts a fair bit lately,

what's the difference between a Companion and a cohort? Like you say, kam_ the script fires for Companions (Okku, thayan golem) ... I thought "cohort" was just the SoZ fancy-name for "companion"

so, uh, what's the diff?

#8
Tchos

Tchos
  • Members
  • 5 042 messages

I would like to know, too, as I had not seen a difference between them.



#9
Dann-J

Dann-J
  • Members
  • 3 161 messages

And in this case since it would be a group of armors, not just a specific one, an onaquire that forces equip would cause problems if you gave them multiple acceptable armors to carry around.

 

 

I initially encountered that very problem with my cursed item scripts, when you tried to equip one cursed item over the top of another cursed item in the same slot. Both tried to re-equip themselves when they were displaced by the other. Infinite equip/unequip loops aren't pretty.

 

I eventually contrived a system whereby the OnEquip script checks whether or not the item it replaced is also cursed, and short-circuited the re-equip for one of the items. I'm looking at my own scripts at the moment (just downloaded them from the Nexus, as I'm at work at the moment). It took me a while to figure out how it worked (I coded it three years ago): :wub:

 

OnEquip:

  • If the item has a local INT called 'Cursed', then set the Cursed flag on it to TRUE
  • Store the current equipped slot number as an INT called 'slot' on the equipped item
  • Loop through the inventory looking for any other items that have a 'slot' INT that matches the current slot number. If there is, set the currently equipped item's cursed flag to FALSE

OnUnequip:

  • If the item is not cursed, set a local INT on it called 'slot' to -1 and end the script
  • Otherwise (cursed flag is TRUE) re-equip it after a brief delay (0.1 seconds)

 

Here's the logic. The first cursed item that is equipped will have a cursed flag that is TRUE and will have a slot INT matching the current slot number it's in. When a second cursed item tries to displace it, it will initially also have a cursed flag that is TRUE. The old item that got automatically unequipped will soon get re-equipped by its OnUnequip script. In the mean time, the OnEquip script identifies that old item by its 'slot' INT value, and sets the newly equipped item to not be cursed. When the other item's OnUnequip script re-equips it 0.1 seconds later, the item that replaced it is no longer cursed, so the OnUnequip script of that replacement item doesn't try to re-equip itself in turn.



#10
kamal_

kamal_
  • Members
  • 5 240 messages

I've been playing around with the PlayerEquip/Unequip scripts a fair bit lately,what's the difference between a Companion and a cohort? Like you say, kam_ the script fires for Companions (Okku, thayan golem) ... I thought "cohort" was just the SoZ fancy-name for "companion"so, uh, what's the diff?


I havn't examined the companion/cohort party joining scripts to see if there were differences. Like you I had thought they were the same thing and the only difference was that companions had more interactivity/their own sidequests/ that sort of thing than cohorts, but no functional difference. Howeverthe player onequip script doesnt seem to run for cohorts (I have set the cohort to use companion scripts in it's properties, so it doesnt seem to be a matter of it running a default creature script).

#11
kevL

kevL
  • Members
  • 4 056 messages
The creature's AI scripts don't/won't matter. I think ...

my understanding of onEquip is simply, if(PC or isOnRoster) fire away.


I have a test-script somewhere called C-info that gives comprehensive info on the party/roster. I guess this copy should be okay.

Are you sure your onEquip script isn't shorting out, internal to itself, before it gets to the debug message?

#12
kamal_

kamal_
  • Members
  • 5 240 messages
I will have to doublecheck the script when im home from work, but the "I'm running" debug section I think is the very first thing after the void main and the stock scripts defining of the object and pc.

#13
kevL

kevL
  • Members
  • 4 056 messages
ok,
when you get back, try a compile and run of c-info ingame (target or, if possible, control the suspect cohort if you like). It should say who's on the Roster in any case.

#14
kamal_

kamal_
  • Members
  • 5 240 messages

ok,
when you get back, try a compile and run of c-info ingame (target or, if possible, control the suspect cohort if you like). It should say who's on the Roster in any case.

ok,

my module level on Player Equip script starts with a debug sent to first pc. Since this is a test module this is always the player. This fires when the player equips an item, but does not fire when a cohort equips an item. The cohort is added via the ka_cohort_join and ga_roster_party_add scripts, I am using a modified copy of Umoja's conversation so I can add the cohort directly as a first response option to his hello.

 

void main()
{
SendMessageToPC (GetFirstPC(), "on player equip script running");

// other stuff...

}

 

Here are the full results of c-info.

https://dl.dropboxus...894/c-info1.jpg

https://dl.dropboxus...894/c-info2.jpg



#15
kevL

kevL
  • Members
  • 4 056 messages
C-info tells me that when you ran it:

- AAAAA Smith is your PC
- you were controlling Dog Brute

- both are currently in the party

- roster members are
Dog Pack Leader
Dog Brute
bd_dog_flanker


now, the funny thing is Dog Brute is not set as Available. That means it's considered to be in another party. go figur. /jk

Okay, if all you're using in dialog is 'ka_cohort_join' and 'ga_roster_party_add' ... that's not enough. you see, in the official campaigns what they've done is put all potential companions onto the Roster at the very start of the game. Then they merely get revealed on the Party Select menu later - or something like that. That is, neither of those scripts expressly adds NPC to the roster ... although Dog Brute appears to be on the Roster ....

Try instead these two ga_ scripts in this order

ga_roster_add_object("dogbrute", "bd_dog_brute")
ga_roster_party_add("dogbrute")


hopefully its Available flag will switch TRUE.
  • kamal_ aime ceci

#16
kevL

kevL
  • Members
  • 4 056 messages
edit: oh i get it, it's not Available because it's already in the party

anyway, try add_object / party add

#17
kevL

kevL
  • Members
  • 4 056 messages
WAIT A SECOND, lul

if you're using

SendMessageToPC(GetFirstPC(), "on player equip script running");

while controlling Dog Brute the message won't show. Use GetFirstPC(FALSE) ....


the other stuff about ga_* still holds, tho
  • kamal_ aime ceci

#18
kamal_

kamal_
  • Members
  • 5 240 messages

WAIT A SECOND, lul

if you're using

SendMessageToPC(GetFirstPC(), "on player equip script running");

while controlling Dog Brute the message won't show. Use GetFirstPC(FALSE) ....


the other stuff about ga_* still holds, tho

Thanks! Adding that FALSE did it and I get the debug message when the cohort is selected. The ga_roster_add_object wasn't needed to get the debug message (though I will keep it in there), possibly because I used AddRosterMemberByCharacter("bd_dog_brute", oCohort); in the OnEnter for the area.

 

Now to go about creating my custom item categories :D



#19
kevL

kevL
  • Members
  • 4 056 messages
schweet..

#20
kamal_

kamal_
  • Members
  • 5 240 messages

No matter how many gnomes you kill and take their armor, armor that won't "magically resize itself" no matter how high your UMD skill!



#21
kamal_

kamal_
  • Members
  • 5 240 messages

ok, this is the module level script. It allows you to restrict equipping items to companions based on tags. Thus, hypothetically we could allow Okku to wear armor made for a bear, but prevent our player from wearing it because they can't wear something made for a bear (we'd also have to adjust Okku's level up script so it doesn't remove his fighter proficiencies in addition to this script).

 

It also allows you to make whole categories of items that are not cursed, but only specific npcs can use, no matter how high the UMD scores of other companions, without having to write item scripts for each possible item. Instead you make pseudo categories based on tag prefixes. The most obvious example would be to have race specific armor without necessitating new baseitems entries for light/medium/heavy armor for every player race.

//::///////////////////////////////////////////////
/*
This module player equip script uses modified code from MoTB for handling Okku and the other companions who can't equip all item slots in order to
allow for groups of restricted items without needing to write equip scripts for each item individually.
this allows you to make your own item categories, such as gnome specific armor that no other race can wear no matter what their UMD skill is.
*/
//:://////////////////////////////////////////////
#include "x2_inc_switches"
// #include "x2_inc_intweapon"  //necessary for intelligent weapons
#include "ginc_item"
const int STR_REF_NOT_ALLOWED	= 210757;	

void main()
{
    object oItem = GetPCItemLastEquipped();
    object oPC   = GetPCItemLastEquippedBy();
	int bEquipForbidden = FALSE;
	
	// here's where we handle companions who are restricted from wearing items in given slots, for instance no usable off arm slot for a one armed companion
	string sTag = GetTag(oPC);
	if ((sTag == "companion_1")
		||	(sTag == "companion_2")
		||	(sTag == "companion_3"))
		{
		int nSlot = GetSlotOfEquippedItem(oItem, oPC);
		
		// for creatures like Okku where all non-creature items forbidden by default, Okku can never weild a weapon
		//you would leave this in to block a creature from equipping in any non creature slot
		if (!GetIsCreatureSlot(nSlot))
			{
			//	bEquipForbidden = TRUE; 
			}		
		
		// Now for slot based exceptions, for instance Okku is allowed to wear rings and amulets, so for our hypothetical one armed companion we would
		//block  INVENTORY_SLOT_LEFTHAND
		//forbidden = False means it's allowed.
		if 	( (sTag == "companion_1") 
			|| 	(sTag == "companion_2") 
			||	(sTag == "companion_3"))
			{
			if ((nSlot == INVENTORY_SLOT_NECK) 
				|| (nSlot == INVENTORY_SLOT_LEFTRING)
				|| (nSlot == INVENTORY_SLOT_RIGHTRING))
				{				
				bEquipForbidden = FALSE;
				}
			}	
	}
	
	// by default this will never be happen in this example as we've commented out above the only condition where it can be set to true. 
	// But we could add conditions as we like.
	// in this case, the creature can not wear any items other than in the specified slots.
	if (bEquipForbidden == TRUE)
	{
		AssignCommand(oPC, ActionUnequipItem(oItem));
		SendMessageToPCByStrRef(oPC, STR_REF_NOT_ALLOWED);
		return;
	}

     // tag based scripting :-)
     if (GetModuleSwitchValue(MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS) == TRUE)
     {
        SetUserDefinedItemEventNumber(X2_ITEM_EVENT_EQUIP);
        int nRet =   ExecuteScriptAndReturnInt(GetUserDefinedItemEventScriptName(oItem),OBJECT_SELF);
        if (nRet == X2_EXECUTE_SCRIPT_END)
        {
           return;
        }
		
		/*
		new stuff, we are going to use tag based scripts to make race specific armor and enforce it, no :"use magical device" exception. kamal
		we want our companions like to be restricted to armor made specifically for them, and no humanoids to be able to wear it
		likewise, Okku can't wear people armor
		*/
		
		string sTag = GetTag (oItem);
		int nAppearance = GetAppearanceType(oPC);
		SendMessageToPC (GetFirstPC(FALSE), "nAppearance is " +IntToString(nAppearance));

		if (nAppearance == 12) //we could add other appearances here, maybe dire bears or something
			{
			// 181 is bear_black, while technically this is available as appearance_type_bear_black, using the number shows emphasizes we 
			// need to look at the nwn2 appearances.2da since a lot of the appearance_type_ globals are nwn1 leftovers
			if (FindSubString(sTag, "bd_bearitem_") == -1)
				{
				AssignCommand(oPC, ActionUnequipItem(oItem));
				SendMessageToPCByStrRef(oPC, STR_REF_NOT_ALLOWED);
				return;
				}
			}  
		
		else //if you wanted to have multiple different restrictions by appearance type, you could do else if's as above, however you'd else with this else
			{
				if (FindSubString(sTag, "bd_bearitem_") != -1)
				{
				AssignCommand(oPC, ActionUnequipItem(oItem));
				SendMessageToPCByStrRef(oPC, STR_REF_NOT_ALLOWED);
				return;
				}
			}
     }

	ExecuteScript("x2_mod_def_equ", OBJECT_SELF);
}

DM : I don't care what your UMD score is gnome, you can't wear armor made for a bear.

 



#22
Tchos

Tchos
  • Members
  • 5 042 messages

Sounds good.



#23
Dann-J

Dann-J
  • Members
  • 3 161 messages

I modified the OnPlayerEquip script a while back to include checks for minimum ability scores, deity, and gender, based on local variables on the item. I never actually got around to creating any such items though (it was more an experiment on whether I *could* do it).

 

These are the bits I added to the SoZ version of the script:

//OnEquip restrictions - set local variables on item for restrictions
//STR (integer) sets minimum strength
//DEX (integer) sets minimum dexterity
//INT (integer) sets minimum intelligence
//WIS (integer) sets minimum wisdom
//CHA (integer) sets minimum charisma
//Deity (String) sets required deity
//Gender (String) sets required gender (M/F or m/f)

string sItemGender = GetLocalString(oItem, "Gender");
int iItemGender = 0;
if ( sItemGender == "f" || sItemGender == "F")
	iItemGender = 1;
int iPCGender = GetGender(oPC);// 0 male, 1 female
if (sItemGender == "")
	iItemGender = iPCGender;

int iItemSTR = GetLocalInt(oItem, "STR");
int iItemDEX = GetLocalInt(oItem, "DEX");
int iItemINT = GetLocalInt(oItem, "INT");
int iItemWIS = GetLocalInt(oItem, "WIS");
int iItemCHA = GetLocalInt(oItem, "CHA");
int iItemCON = GetLocalInt(oItem, "CON");

int iPCSTR = GetAbilityScore(oPC, 0, FALSE);
int iPCDEX = GetAbilityScore(oPC, 1, FALSE);
int iPCCON = GetAbilityScore(oPC, 2, FALSE);
int iPCINT = GetAbilityScore(oPC, 3, FALSE);
int iPCWIS = GetAbilityScore(oPC, 4, FALSE);
int iPCCHA = GetAbilityScore(oPC, 5, FALSE);

string sItemDeity = GetLocalString(oItem, "Deity");
string sPCDeity = GetDeity(oPC);
if (sItemDeity == "")
	sItemDeity = sPCDeity;

if (iPCSTR < iItemSTR || iPCDEX < iItemDEX || iPCCHA < iItemCHA
	|| iPCINT < iItemINT || iPCWIS < iItemWIS
	|| sItemDeity != sPCDeity || iItemGender != iPCGender)
	{
	bEquipForbidden = TRUE;// end OnEquip restrictions
	}

  • kamal_ aime ceci

#24
Tchos

Tchos
  • Members
  • 5 042 messages

Level restrictions would be cool, too.



#25
Dann-J

Dann-J
  • Members
  • 3 161 messages

Level restrictions would be cool, too.

 

I find level restrictions to be hard to justify, unless it's something as coarse as 'epic' or 'non-epic'. A level 9 fighter with a strength of 20 can't equip a certain set of armour, yet a level 10 fighter with a strength of 18 can? What difference is that one extra level actually making? A restriction based on an ability score, or a BAB, or the presence of a certain feat, would at least make some sense.