Gender based item scripting

Hello, I’am really a noob when it comes to scripting. Problem is I have found a script that I’d like to use here Gender Based Item Scripting. | The Neverwinter Vault .It says it is for NWN2 but I guess it can be used for NWN too ?

Well, I just can’t get it to works… I followed the steps changed item property and renamed oitem with the tag of the armor but no luck…

Again, sorry if I sound like a real noob (I’am)

I’m also new to NWN scripting, though I know an awful lot about programming in general. So I’ll take a stab at this, and we’ll see how it goes.

Pretty sure you’re gonna wanna modify the (module-level) OnPlayerEquipItem script, by default 70_mod_def_equ. It begins,

void main()
{
    object oItem = GetPCItemLastEquipped();
    object oPC   = GetPCItemLastEquippedBy();

You can then do something like,

int gender = GetGender(oPC);

This returns a value defined here: GENDER_* Constant Group - NWN Lexicon Faerun doesn’t limit itself to the gender binary, though I’m pretty sure a PC is gonna be either male or female.

If you want to unequip the item if the PC is male, for example, you can do this:

if(gender == GENDER_MALE && GetTag(oItem) == "SurgeonScrubs")
    ActionUnequipItem(oItem);

Note that, since presumably only certain clothing items are gender-locked, you’ll have to enumerate them by tag. There are various ways of cheating this, for example, let’s say you Tag all your female-only items starting with FO (for Female-Only, for example, FOSurgeonScrubs, FOWorkBoots, FOBandana), then you can do this:

if(gender == GENDER_MALE && GetStringLeft(GetTag(oItem), 2) == "FO")
    ActionUnequipItem(oItem);

Thanks for your answer.

Unfortunally, it did not works.

I added the lines you provided on the OnPlayerEquipItem script, give the name of the tag but no lucks…

Okay, I actually did some tests this time. Rather than ActionUnequipItem(oItem), try this:

DelayCommand(0.1, AssignCommand(oPC, ActionUnequipItem(oItem)));

There’s a lot of weird little quirks about NWN scripting. So the whole bit looks like this:

void main() {
    object oItem = GetPCItemLastEquipped();
    object oPC   = GetPCItemLastEquippedBy();
    int gender = GetGender(oPC);
    if(gender == GENDER_MALE && GetTag(oItem) == "FemaleOnly")
        DelayCommand(0.1, AssignCommand(oPC, ActionUnequipItem(oItem)));
    (...)

The game acts a bit weird if you don’t delay the command a bit.

Yay, it worked!

Thank you so much :wink:

You’re welcome. And I would recommend going down the tag-prefix road,

if(gender == GENDER_MALE && GetStringLeft(GetTag(oItem), 2) == "FO")
    DelayCommand(0.1, AssignCommand(oPC, ActionUnequipItem(oItem)));
else if(gender == GENDER_FEMALE && GetStringLeft(GetTag(oItem), 2) == "MO")
    DelayCommand(0.1, AssignCommand(oPC, ActionUnequipItem(oItem)));

then starting your female-specific items with “FO” and your male-specific items with “MO”. This is case-sensitive, meaning “MO” is not the same as “Mo”, so gender-neutral “MoleskinMoccasin” would be wearable by any gender.

You could also make this:

if(gender != GENDER_FEMALE && GetStringLeft(GetTag(oItem), 2) == "FO")
    DelayCommand(0.1, AssignCommand(oPC, ActionUnequipItem(oItem)));
if(gender != GENDER_MALE && GetStringLeft(GetTag(oItem), 2) == "MO")
    DelayCommand(0.1, AssignCommand(oPC, ActionUnequipItem(oItem)));

The difference between the two cases—and I’m spelling this out since you said you’re new to scripting—The first case will prevent males from equipping female-only items, and females from equipping male-only items. The second case will prevent non-females from equipping female-only items, and non-males from equipping male-only items. Since there are “other” and “both” and “none” as genders, in the first case, NB (nonbinary) creatures will be able to equip any clothing, while in the second, those NBs won’t be able to equip any gender-specific clothing.

As I said, I don’t think this matters, but maybe it’s worth thinking about. If for no reason but to expand your mind.

CEP 2 has a built-in function

  ZEPGenderRestrict(oItem,oPC);

which is called from the Equip event after setting oPC and oItem as before.

This does the unequip for you if necessary.

Thanks again, everything is clear !

70_mod_def_equ isn’t the default OnEquip event. That script - or any other script with the 70_ prefix only appears if you have the CPP installed, which is NOT an official patch. It was compiled by one person - Shadooow.

The actual default OnEquip event for both Diamond and EE is x2_mod_def_equ.

Optionally, you can just use tag-based scripting (script is named for the tag of the item) to check for the gender of the creature equipping the item in the item script’s OnEquip event. If the gender doesn’t match what you specify, then unequip the item (see x2_it_example for more info).

Oh… I’m using the GOG version, which is apparently pretty buggy, so I installed the Community Patch mostly to have sticky combat modes. Playing monk was just too agonizing without it. I didn’t even think about the fact that it might change default scripts in the toolset.

As I said, I’m also new to NWN scripting, so I appreciate you pointing this out.

I have another request, can this be applied to henchmen as well?

No (as far as I know). Reason is that the equip item event does not fire for non-PCs.

What if onAquired is used?

In my case I equip NPCs from OnSpawn script and I use something like this:

oSpawned is the creature.
oItem is the object to be created & equipped.
When oItem is Male only it has a local var containing the ResRef of the Female alternative.
When oItem is Female only it has a local var containing the ResRef of the Male alternative.

//Male case
if (GetGender (oSpawned) == 0 && GetLocalString (oItem, "model_m") != "") {
    sItem = GetLocalString (oItem, "model_m");
    DestroyObject (oItem, 0.0);
    oItem = CreateItemOnObject(sItem, oSpawned, 1, "");
}
//Female case
if (GetGender (oSpawned) == 1 && GetLocalString (oItem, "model_f") != "") {
    sItem = GetLocalString (oItem, "model_f");
    DestroyObject (oItem, 0.0);
    oItem = CreateItemOnObject(sItem, oSpawned, 1, "");
}
AssignCommand(oSpawned,ActionEquipItem(oItem, 1));