Switch Item Properties

I’m wanting to change how armor works in my module. I’m thinking I’ll need to run a script in two spots (OnEnter and OnEquip).

I’d like for the script to first check what damage resistance the armor has and how much and then replace that resistance with a damage immunity instead.

If the player’s armor has:
ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGERESIST_10)

then replace it with this:
ItemPropertyDamageImmunity(IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGEIMMUNITY_10_PERCENT);

If the player’s armor has:
ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGERESIST_25)

then replace it with this:
ItemPropertyDamageImmunity(IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGEIMMUNITY_25_PERCENT);

etc. for each elemental type.

I’ve tried using the GetItemPropertyType but can’t get it to be specific enough to check how much damage resistance the armor has.

There’s no one-to-one mapping between IP_CONST_DAMAGERESIST_* and IP_CONST_DAMAGEIMMUNITY_* groups of constants.

int IP_CONST_DAMAGERESIST_5                     = 1;
int IP_CONST_DAMAGERESIST_10                    = 2;
int IP_CONST_DAMAGERESIST_15                    = 3;
int IP_CONST_DAMAGERESIST_20                    = 4;
int IP_CONST_DAMAGERESIST_25                    = 5;
int IP_CONST_DAMAGERESIST_30                    = 6;
int IP_CONST_DAMAGERESIST_35                    = 7;
int IP_CONST_DAMAGERESIST_40                    = 8;
int IP_CONST_DAMAGERESIST_45                    = 9;
int IP_CONST_DAMAGERESIST_50                    = 10;
int IP_CONST_DAMAGEIMMUNITY_5_PERCENT           = 1;
int IP_CONST_DAMAGEIMMUNITY_10_PERCENT          = 2;
int IP_CONST_DAMAGEIMMUNITY_25_PERCENT          = 3;
int IP_CONST_DAMAGEIMMUNITY_50_PERCENT          = 4;
int IP_CONST_DAMAGEIMMUNITY_75_PERCENT          = 5;
int IP_CONST_DAMAGEIMMUNITY_90_PERCENT          = 6;
int IP_CONST_DAMAGEIMMUNITY_100_PERCENT         = 7;
1 Like

You have to come up with some interpolation method (see ConvertResistanceToImmunity below)

//

#include "x2_inc_itemprop"

void ReplaceResistanceWithImmunity(object oItem);
int ConvertResistanceToImmunity(int nAmount);
int GetItemHasHigherImmunity(object oItem, int nDamageType, int nCheck);

//*** main
void main()
{
	object oTarget = GetEnteringObject();
	object oItem;
	int iSlot;

	for (iSlot = 0; iSlot < NUM_INVENTORY_SLOTS; iSlot++)
	{
		oItem = GetItemInSlot(iSlot, oTarget);
		ReplaceResistanceWithImmunity(oItem);
	}

	oItem = GetFirstItemInInventory(oTarget);
	while (GetIsObjectValid(oItem))
	{
		ReplaceResistanceWithImmunity(oItem);
		oItem = GetNextItemInInventory(oTarget);
	}

}

//
void ReplaceResistanceWithImmunity(object oItem)
{
	int nDamageType, nAmount, nTest;
	itemproperty ipNew;
	itemproperty ipScan = GetFirstItemProperty(oItem);

	while (GetIsItemPropertyValid(ipScan))
	{
		if (GetItemPropertyType(ipScan) == ITEM_PROPERTY_DAMAGE_RESISTANCE
		 && GetItemPropertyDurationType(ipScan) == DURATION_TYPE_PERMANENT)
		{
			nDamageType = GetItemPropertySubType(ipScan);

			// According to Lexicon, ItemPropertyDamageImmunity() works
			// only with these damage types
			if (nDamageType == IP_CONST_DAMAGETYPE_BLUDGEONING
			 || nDamageType == IP_CONST_DAMAGETYPE_PIERCING
			 || nDamageType == IP_CONST_DAMAGETYPE_SLASHING
			 || nDamageType == IP_CONST_DAMAGETYPE_ACID
			 || nDamageType == IP_CONST_DAMAGETYPE_COLD
			 || nDamageType == IP_CONST_DAMAGETYPE_ELECTRICAL
			 || nDamageType == IP_CONST_DAMAGETYPE_FIRE
			 || nDamageType == IP_CONST_DAMAGETYPE_SONIC)
			{
				nAmount = GetItemPropertyCostTableValue(ipScan);
				nAmount = ConvertResistanceToImmunity(nAmount);

				if (nAmount > 0)
				{
					RemoveItemProperty(oItem, ipScan);

					if (!GetItemHasHigherImmunity(oItem, nDamageType, nAmount))
					{
						ipNew = ItemPropertyDamageImmunity(nDamageType, nAmount);
						IPSafeAddItemProperty(oItem, ipNew, 0.0f);
					}
				}
			}
		}

		ipScan = GetNextItemProperty(oItem);
	}
}

//
int ConvertResistanceToImmunity(int nAmount)
{
	switch (nAmount)
	{
		case IP_CONST_DAMAGERESIST_5:
			return IP_CONST_DAMAGEIMMUNITY_5_PERCENT;

		case IP_CONST_DAMAGERESIST_10:
		case IP_CONST_DAMAGERESIST_15:
			return IP_CONST_DAMAGEIMMUNITY_10_PERCENT;

		case IP_CONST_DAMAGERESIST_20:
		case IP_CONST_DAMAGERESIST_25:
		case IP_CONST_DAMAGERESIST_30:
			return IP_CONST_DAMAGEIMMUNITY_25_PERCENT;

		case IP_CONST_DAMAGERESIST_35:
		case IP_CONST_DAMAGERESIST_40:
		case IP_CONST_DAMAGERESIST_45:
		case IP_CONST_DAMAGERESIST_50:
			return IP_CONST_DAMAGEIMMUNITY_50_PERCENT;
	}

	return 0;
}

int GetItemHasHigherImmunity(object oItem, int nDamageType, int nCheck)
{
	int nAmount;
	itemproperty ipScan = GetFirstItemProperty(oItem);
	while (GetIsItemPropertyValid(ipScan))
	{
		if (GetItemPropertyType(ipScan) == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE
		 && GetItemPropertyDurationType(ipScan) == DURATION_TYPE_PERMANENT
		 && GetItemPropertySubType(ipScan) == nDamageType)
		{
			nAmount = GetItemPropertyCostTableValue(ipScan);
			if (nAmount > nCheck)
			{
				return TRUE;
			}
		}
		ipScan = GetNextItemProperty(oItem);
	}

	return FALSE;
}

//untested.

1 Like

Got it all working! Thank you for the help.