Aller au contenu

Photo

Damage immunity from items fix


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

#1
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

As probably most of you are aware, there is a bug with damage immunities from items in NWN2, when they stack beyond 100%, the immunity becomes a vulnerability.

I wanted to fix this, by overriding with a spell effect in case the damage immunity from gear surpasses 100%, with a script attached to a dedicated feat (and then give this feat to everyone).

 

In addition, it's necessary to modify the scripts that handle OnEquip and OnUnequip events (default "x2_mod_def_equ" and the "x2_mod_def_unequ" ) to make them run this script.

 

EDIT: The previous script used recursive calls that could put a lot of heartbeat strain on the computer/server.

const int ITEMIMMUNITY_FIX = -2395;

void RunImmunityFix(object oChar)
{
	int nElement;
	int nElement2;
	int nEquipment;
	int nTOT;
	int nITEM;
	object oEquipment;
	itemproperty iMAIN;
	int nSUB;
	int nType;
	int nTABLE;
	
	effect eImmunity = GetFirstEffect(oChar);
	while(GetIsEffectValid(eImmunity))
	{
		if (GetEffectSpellId(eImmunity) == ITEMIMMUNITY_FIX)
		{
			RemoveEffect(oChar, eImmunity);
		}
		eImmunity = GetNextEffect(oChar);
	}
	
	while (nElement < 14)
	{
		if ((nElement!=3)&&(nElement!=4))
		{
			nTOT = 0;
			nEquipment = 0;
			while (nEquipment < 11)
			{
				nITEM = 0;
				oEquipment = GetItemInSlot(nEquipment, oChar);
			
				if (GetItemHasItemProperty(oEquipment, ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE) == TRUE )
				{
					iMAIN = GetFirstItemProperty(oEquipment);
					nType = GetItemPropertyType(iMAIN);
					nSUB = GetItemPropertySubType(iMAIN);
					while (GetIsItemPropertyValid(iMAIN))
					{
						if ((nType == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE)&&(nSUB == nElement))
						{
							nTABLE = GetItemPropertyCostTableValue(iMAIN);
							nITEM = nITEM + StringToInt(Get2DAString("iprp_immuncost", "Value", nTABLE));
						}
						else if ((nType == ITEM_PROPERTY_DAMAGE_VULNERABILITY)&&(nSUB == nElement))
						{
							nTABLE = GetItemPropertyCostTableValue(iMAIN);
							nITEM = nITEM - StringToInt(Get2DAString("iprp_damvulcost", "Value", nTABLE));
						}
					
						iMAIN = GetNextItemProperty(oEquipment);
						nType = GetItemPropertyType(iMAIN);
						nSUB = GetItemPropertySubType(iMAIN);
					}									
				}
			
				nTOT = nTOT + nITEM; 
			
				nEquipment = nEquipment + 1;
			}
		
			if (nElement == 0)
			{
				nElement2 = DAMAGE_TYPE_BLUDGEONING;
			}
			else if (nElement == 1)
			{
				nElement2 = DAMAGE_TYPE_PIERCING;
			}
			else if (nElement == 2)
			{
				nElement2 = DAMAGE_TYPE_SLASHING;
			}
			else if (nElement == 5)
			{
				nElement2 = DAMAGE_TYPE_MAGICAL;
			}
			else if (nElement == 6)
			{
				nElement2 = DAMAGE_TYPE_ACID;
			}
			else if (nElement == 7)
			{
				nElement2 = DAMAGE_TYPE_COLD;
			}
			else if (nElement == 8)
			{
				nElement2 = DAMAGE_TYPE_DIVINE;
			}
			else if (nElement == 9)
			{
				nElement2 = DAMAGE_TYPE_ELECTRICAL;
			}
			else if (nElement == 10)
			{
				nElement2 = DAMAGE_TYPE_FIRE;
			}
			else if (nElement == 11)
			{
				nElement2 = DAMAGE_TYPE_NEGATIVE;
			}
			else if (nElement == 12)
			{
				nElement2 = DAMAGE_TYPE_POSITIVE;
			}
			else if (nElement == 13)
			{
				nElement2 = DAMAGE_TYPE_SONIC;
			}
			
			if (nTOT > 99)
			{
				eImmunity = EffectDamageResistance(nElement2, 9999);
				eImmunity = ExtraordinaryEffect(eImmunity);
				eImmunity = SetEffectSpellId(eImmunity, ITEMIMMUNITY_FIX);
				DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eImmunity, oChar));
			}
		}
		nElement = nElement + 1;
	}

}

void main()
{
	object oPC = OBJECT_SELF;
	DelayCommand(0.1, RunImmunityFix(oPC));
}


#2
4760

4760
  • Members
  • 1 204 messages

Why are you calling RunImmunityFix recursively? (it's called from main(), but at the end RunImmunityFix calls itself again after a half second delay).



#3
Dann-J

Dann-J
  • Members
  • 3 161 messages

I liked the way immunity worked in the 2nd edition games like Baldur's Gate. If you had more than 100% immunity to an energy type, then that energy type healed you instead of harming you. I don't see that being possible in NWN2 though.

 

The fireball room in Durlag's Tower was a cakewalk with >100% immunity to fire. I had one character who would return there for some free healing. :)


  • GCoyote aime ceci

#4
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

Why are you calling RunImmunityFix recursively? (it's called from main(), but at the end RunImmunityFix calls itself again after a half second delay).

 

Because it's checking the equipment of the character to see if the damage immunity from items surpasses 100% and then applies a temporary effect to grant 100% immunity. 

The logic is that if the character unequips the items that grant the damage immunity and goes below 100% then he should lose the immunity effect.



#5
kevL

kevL
  • Members
  • 4 056 messages
in tests, i found that 100% damImmunity applied as an effect did not cover 180% immunity from 2 rings (90% ea.)

PC still took ~80% dam. So i tried w/ 180% damImmunity ... but eventually had to apply *2* effects, eg. 90% and 90%, or 100% and 80% ....


this is as afar as I got:
// 'fiximmunity'

// debug
void Tell(string sString) { SendMessageToPC(GetFirstPC(FALSE), sString); }

//
void RunImmunityFix(object oTarget)
{
    effect eEffect;
    object oItem;
    itemproperty ipProp;
    int
        iSlot,
        iType,
        iSubType,
        iTable,
        iValue,
        iTotal,
        iDamType_IP,
        iDamType_Eff;

    // cycle damage types
    while (iDamType_IP < 14)
    {
        Tell("\niDamType = " + IntToString(iDamType_IP));

        if (iDamType_IP != 3
            && iDamType_IP != 4) // skip Subdual & Physical types - no corresponding Effects
        {
            // NOTE: The description of ItemPropertyDamageImmunity() says use only the following types
            // - Bludgeoning
            // - Piercing
            // - Slashing
            // - Acid
            // - Cold
            // - Electrical
            // - Fire
            // - Sonic
            // The description of ItemPropertyDamageVulnerability() doesn't say that, but ....

            iTotal = 0;

            // cycle items equipped
            iSlot = INVENTORY_SLOT_HEAD;
            while (iSlot <= INVENTORY_SLOT_BELT)
            {
                iValue = 0;

                oItem = GetItemInSlot(iSlot, oTarget);

                ipProp = GetFirstItemProperty(oItem);
                while (GetIsItemPropertyValid(ipProp))
                {
                    if (GetItemPropertyType(ipProp) == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE
                        && GetItemPropertySubType(ipProp) == iDamType_IP)
                    {
                        iTable = GetItemPropertyCostTableValue(ipProp);
                        iValue += StringToInt(Get2DAString("iprp_immuncost", "Value", iTable));
                        Tell("increase iValue = " + IntToString(iValue));

                        iTotal += iValue;
                        Tell("iTotal = " + IntToString(iTotal));
                    }
                    else if (GetItemPropertyType(ipProp) == ITEM_PROPERTY_DAMAGE_VULNERABILITY
                        && GetItemPropertySubType(ipProp) == iDamType_IP)
                    {
                        iTable = GetItemPropertyCostTableValue(ipProp);
                        iValue -= StringToInt(Get2DAString("iprp_damvulcost", "Value", iTable));
                        Tell("decrease iValue = " + IntToString(iValue));

                        iTotal += iValue;
                        Tell("iTotal = " + IntToString(iTotal));
                    }

                    ipProp = GetNextItemProperty(oItem);
                }

                ++iSlot;
            }

            if (iTotal > 100)
            {
                // convert ip's dType to an effect dType
                switch (iDamType_IP)
                {
                    case 0:
                        iDamType_Eff = DAMAGE_TYPE_BLUDGEONING;
                        Tell("DAMAGE_TYPE_BLUDGEONING");
                    break;

                    case 1:
                        iDamType_Eff = DAMAGE_TYPE_PIERCING;
                        Tell("DAMAGE_TYPE_PIERCING");
                    break;

                    case 2:
                        iDamType_Eff = DAMAGE_TYPE_SLASHING;
                        Tell("DAMAGE_TYPE_SLASHING");
                    break;

                    case 5:
                        iDamType_Eff = DAMAGE_TYPE_MAGICAL;
                        Tell("DAMAGE_TYPE_MAGICAL");
                    break;

                    case 6:
                        iDamType_Eff = DAMAGE_TYPE_ACID;
                        Tell("DAMAGE_TYPE_ACID");
                    break;

                    case 7:
                        iDamType_Eff = DAMAGE_TYPE_COLD;
                        Tell("DAMAGE_TYPE_COLD");
                    break;

                    case 8:
                        iDamType_Eff = DAMAGE_TYPE_DIVINE;
                        Tell("DAMAGE_TYPE_DIVINE");
                    break;

                    case 9:
                        iDamType_Eff = DAMAGE_TYPE_ELECTRICAL;
                        Tell("DAMAGE_TYPE_ELECTRICAL");
                    break;

                    case 10:
                        iDamType_Eff = DAMAGE_TYPE_FIRE;
                        Tell("DAMAGE_TYPE_FIRE");
                    break;

                    case 11:
                        iDamType_Eff = DAMAGE_TYPE_NEGATIVE;
                        Tell("DAMAGE_TYPE_NEGATIVE");
                    break;

                    case 12:
                        iDamType_Eff = DAMAGE_TYPE_POSITIVE;
                        Tell("DAMAGE_TYPE_POSITIVE");
                    break;

                    case 13:
                        iDamType_Eff = DAMAGE_TYPE_SONIC;
                        Tell("DAMAGE_TYPE_SONIC");
                    break;
                }


                // apply enough damage-immunity effects to cover the total of current dType
                int
                    i,
                    j = iTotal / 100;

                for (i = 0; i < j; ++i)
                {
                    eEffect = EffectDamageImmunityIncrease(iDamType_Eff, 100);
                    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
//                  ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oTarget, 0.5f);
                }

                if (iTotal % 100 > 0)
                {
                    eEffect = EffectDamageImmunityIncrease(iDamType_Eff, iTotal % 100);
                    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
                }
            }
        }

        ++iDamType_IP;
    }

//  DelayCommand(0.5f, RunImmunityFix(oTarget));
}


//_________
// * MAIN *
void main()
{
    object oTarget = OBJECT_SELF;
    DelayCommand(0.1f, RunImmunityFix(oTarget));
}


#6
kevL

kevL
  • Members
  • 4 056 messages
no... it screwed up when i put on a 3rd 90% immunity item,
something really borky is going on behind the scenes ......

#7
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

I got it working, the problem was that I had forgotten to reset the Equipment Slot counter, so it only checked Bludgeoning Immunity...

To work around the issues you had, I replaced the damage immunity effect with a 9999 damage resistance effect.

I updated the code in the Opening Post.

Thank you very much for the help kevL, your code also helped improve mine in a couple of ways that I hadn't thought of.



#8
kevL

kevL
  • Members
  • 4 056 messages

To work around the issues you had, I replaced the damage immunity effect with a 9999 damage resistance effect.


cool. works fer me :)

#9
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

Hi,

Thanks for posting. :) Another issue I did not know about .... :(

Any reason why you simply cannot run the function from OnEquipped and OnUnequipped rather than recursively?

Unless there are some temporary effects I am missing, using these two hooks rather than a recall every half second (calling 2da functions quite frequently) may help to reduce heartbeat strain. I know I revamped quite a few of my ideas to avoid too many recursive calls, and left those to only ones where it could not be avoided.

 

UPDATE: Although, having done a bit of background research on this, I think that there is something to be said for having "too much" damage immunity across the board. i.e. If a PC has access to a number of different items offering such protection, then I think there is something to be said for having the PC consider carefully which options they equip due to potential "overflow of interests" as it were.

 

E.g. PC finds three items:

 

1) Ring Prot Fire 100%

2) Ring Prot Elec 100%

3) Helm Prot Fire 75% Prot Elec 75% Prot Acid 75%

 

If there was no penalty for wearing all three items, then the PC simply wears them all, gaining a "free" 75% additional ACID benefit due to not having any concerns about "overflow" due to other items already being worn. Having to weigh up the pro and cons in such a situation, I think is worth considering keeping. Just my thoughts about the topic .... :)

Cheers,
Lance.


  • GCoyote aime ceci

#10
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

Hi,

Thanks for posting. :) Another issue I did not know about .... :(

Any reason why you simply cannot run the function from OnEquipped and OnUnequipped rather than recursively?

Unless there are some temporary effects I am missing, using these two hooks rather than a recall every half second (calling 2da functions quite frequently) may help to reduce heartbeat strain. I know I revamped quite a few of my ideas to avoid too many recursive calls, and left those to only ones where it could not be avoided.

 

UPDATE: Although, having done a bit of background research on this, I think that there is something to be said for having "too much" damage immunity across the board. i.e. If a PC has access to a number of different items offering such protection, then I think there is something to be said for having the PC consider carefully which options they equip due to potential "overflow of interests" as it were.

 

E.g. PC finds three items:

 

1) Ring Prot Fire 100%

2) Ring Prot Elec 100%

3) Helm Prot Fire 75% Prot Elec 75% Prot Acid 75%

 

If there was no penalty for wearing all three items, then the PC simply wears them all, gaining a "free" 75% additional ACID benefit due to not having any concerns about "overflow" due to other items already being worn. Having to weigh up the pro and cons in such a situation, I think is worth considering keeping. Just my thoughts about the topic .... :)

Cheers,
Lance.

 

The Damage Resistance effect applied as a workaround is temporary, in the logic of the algorithm I wanted to check if the character has items equipped with immunities that stack beyond 100% all the time, so when he removes the piece of equipment he loses the damage resistance effect. 

 

I do not know how the OnEquipped and OnUnequipped functions work or where I can find them (I do not even see them among the list of system functions in the toolset), but certainly I would welcome any improvement that could help reduce the strain caused by the script, since, in addition to this script, I also got another one that runs all the time like this one that checks all AC bonus from armor and converts it into physical immunity depending the weight rank and of the armor and shield, or turns it into HP bonus for other misc gear.  :lol:

 

One of my fears was that applying too many passive custom rules with these recursive assignments could kill the computer, I would be really grateful if there was a way to avoid this.



#11
Tchos

Tchos
  • Members
  • 5 042 messages

On Equipped and On Unequipped are events that fire whenever you equip or unequip an item.  There are master scripts controlling what happens during those events, in the module properties.  Those master scripts also include hooks (enabled by default) that first check to see whether there are any special scripts with a certain naming convention including the item's tag, and if so, then it executes any code in those scripts in addition to the ones in the master scripts.



#12
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

I found two scripts called x2_onequip and x2_unonequip.

I modified them (and put in override) with the above code and removed the recursive calls, but it does not seem to work at all.

I even added a floating message to see if the script would fire, but it just does not fire.



#13
Tchos

Tchos
  • Members
  • 5 042 messages

Those are not the names of the scripts that are put in those slots by default.  You'll need to look at your module properties and see what scripts you have in the On Player Equip Item and On Player Unequip Item slots.  It's under View>Module Properties.

 

I would avoid modifying default scripts and overwriting them with the same names.  Rather, use different names and either use hooks to fire them from the default scripts, or simply change the module properties to use the new scripts instead of the default ones.



#14
4760

4760
  • Members
  • 1 204 messages

The way I use the OnEquip and OnUnequip events is through tag-based calls: i_itemtag_eq and  i_itemtag​_ue.

So, if you've got a ring tag it_ring_test, its OnEquip and OnUnequip events would be fired via i_it_ring_test_eq and i_it_ring_test_ue.

 

Unfortunately, that means it has to be done for each item, so Tchos's solution would work better (except it probably will only work for PC I suppose).



#15
Tchos

Tchos
  • Members
  • 5 042 messages

I generally do it via tags, as well.  Those are the hooks I was describing.  Those tag-based scripts fire from the On Player Equip/Unequip Item scripts, so if it doesn't work by customising those scripts directly, it won't work through tag-based scripting, either.  Similarly, just a warning, but if you replace the default scripts with ones that don't include hooks for tag-based scripting, then no tag-based scripts will work for those events.



#16
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

I've got it working. I modified the "x2_mod_def_equ" and the "x2_mod_def_unequ" scripts to run the script in the Opening Post.

I changed effects to permanent, toned down the resistance to 9998 (to not confuse it with other effects that may use 9999, like the Energy Immunity Spells or some possible class feats) and added a check to remove the effect if the total does not surpass 99. Yay.

Thanks for the help everyone, hopefully this script will be helpful to others as well now.

Opening Post updated with the new (and hopefully final, lol) script.



#17
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

I've got it working. I modified the "x2_mod_def_equ" and the "x2_mod_def_unequ" scripts to run the script in the Opening Post.
I changed effects to permanent, toned down the resistance to 9998 (to not confuse it with other effects that may use 9999, like the Energy Immunity Spells or some possible class feats) and added a check to remove the effect if the total does not surpass 99. Yay.
Thanks for the help everyone, hopefully this script will be helpful to others as well now.
Opening Post updated with the new (and hopefully final, lol) script.


Hi,

I see you managed to do what I suggested then ... good for you!

Don't forget to move all your other "item intensive" scripts to there too.

For the record, I use a combination of using these two hooks for the most part (generic stuff) and then tagged-based scripting for some specific stuff.

Cheers,
Lance.

#18
kevL

kevL
  • Members
  • 4 056 messages
note, this can -and should- be replaced
if ((GetEffectType(ePAST) == EFFECT_TYPE_DAMAGE_RESISTANCE) &&
(GetEffectSubType(ePAST) == SUBTYPE_EXTRAORDINARY) &&
(GetEffectDurationType(ePAST) == DURATION_TYPE_PERMANENT) &&
(GetEffectInteger(ePAST, 0) == nElement2) &&
(GetEffectInteger(ePAST, 1) == 9998))
with
if (GetEffectSpellId(ePAST) == [x])
where [x] is a/the appropriate integer-constant.
 
// arbitrary but unique; negative avoids potential Spells.2da conflict
const int ITEMIMMUNITY_FIX = -2395;
// or the row in Spells.2da if this is still tied to a feat w/ spellscript
// in that case, the constant doesn't need to be defined or set, per se
// only checked before RemoveEffect()

//...

if (nTOT > 99)
{
    eImmunity = ExtraordinaryEffect(EffectDamageResistance(nElement2, 9998));
    eImmunity = SetEffectSpellId(eImmunity, ITEMIMMUNITY_FIX);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eImmunity, oChar);
}
else
{
    ePAST = GetFirstEffect(oChar);
    while(GetIsEffectValid(ePAST))
    {
        if (GetEffectSpellId(ePAST) == ITEMIMMUNITY_FIX)
        {
            RemoveEffect(oChar, ePAST);
        }
        ePAST = GetNextEffect(oChar);
    }
}


#19
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

When I try to compile that, it says that const keyword cannot be used on non-global variables.

Does it change anything if I don't use the const keyword?



#20
kevL

kevL
  • Members
  • 4 056 messages

When I try to compile that, it says that const keyword cannot be used on non-global variables.

to make it 'global' put the def'n above void main() -- outside/above function scope.

Does it change anything if I don't use the const keyword?

not really

#21
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

It's not working, the script is not even firing the initial damage resistance anymore.



#22
kevL

kevL
  • Members
  • 4 056 messages
I'm rethinking my version -- some logic issues are coming up ...

will post when it's sorted

#23
kevL

kevL
  • Members
  • 4 056 messages
// 'fixim'
//
// 2015 jul 22b

const int ITEMIMMUNITY_FIX = -2395;


// debug
void Tell(string sString) { SendMessageToPC(GetFirstPC(FALSE), sString); }

//
void RunImmunityFix(object oTarget)
{
    effect eEffect;
    object oItem;
    itemproperty ipProp;
    int
        iSlot,
        iType,
        iSubType,
        iTable,
        iValue,
        iTotal,
        iDType_Ip,
        iDType_Ef;


    // remove all previous applications of Immunity Fix
    eEffect = GetFirstEffect(oTarget);
    while (GetIsEffectValid(eEffect))
    {
        if (GetEffectSpellId(eEffect) == ITEMIMMUNITY_FIX)
        {
            RemoveEffect(oTarget, eEffect);
            eEffect = GetFirstEffect(oTarget);
        }
        else
            eEffect = GetNextEffect(oTarget);
    }


    // cycle damage types
    while (iDType_Ip < 14)
    {
        Tell(". iDamType = " + IntToString(iDType_Ip));

        if (iDType_Ip != 3
            && iDType_Ip != 4) // skip Subdual & Physical types - no corresponding Effects
        {
            // NOTE: The description of ItemPropertyDamageImmunity() says use only the following types
            // - Bludgeoning
            // - Piercing
            // - Slashing
            // - Acid
            // - Cold
            // - Electrical
            // - Fire
            // - Sonic
            // The description of ItemPropertyDamageVulnerability() doesn't say that, but ....


            iTotal = 0;

            // cycle items equipped
            iSlot = INVENTORY_SLOT_HEAD;
            while (iSlot <= INVENTORY_SLOT_BELT)
            {
                iValue = 0;

                oItem = GetItemInSlot(iSlot, oTarget);

                ipProp = GetFirstItemProperty(oItem);
                while (GetIsItemPropertyValid(ipProp))
                {
                    if (GetItemPropertyType(ipProp) == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE
                        && GetItemPropertySubType(ipProp) == iDType_Ip)
                    {
                        iTable = GetItemPropertyCostTableValue(ipProp);
                        iValue += StringToInt(Get2DAString("iprp_immuncost", "Value", iTable));
                        Tell(". . increase iValue = " + IntToString(iValue));
                    }
                    else if (GetItemPropertyType(ipProp) == ITEM_PROPERTY_DAMAGE_VULNERABILITY
                        && GetItemPropertySubType(ipProp) == iDType_Ip)
                    {
                        iTable = GetItemPropertyCostTableValue(ipProp);
                        iValue -= StringToInt(Get2DAString("iprp_damvulcost", "Value", iTable));
                        Tell(". . decrease iValue = " + IntToString(iValue));
                    }

                    ipProp = GetNextItemProperty(oItem);
                }

                iTotal += iValue;
                Tell(". . iTotal = " + IntToString(iTotal));

                ++iSlot;
            }

            if (iTotal > 100)
            {
                // convert ip's dType to an effect dType
                switch (iDType_Ip)
                {
                    case 0:
                        iDType_Ef = DAMAGE_TYPE_BLUDGEONING;
                        Tell(". . . DAMAGE_TYPE_BLUDGEONING");
                    break;

                    case 1:
                        iDType_Ef = DAMAGE_TYPE_PIERCING;
                        Tell(". . . DAMAGE_TYPE_PIERCING");
                    break;

                    case 2:
                        iDType_Ef = DAMAGE_TYPE_SLASHING;
                        Tell(". . . DAMAGE_TYPE_SLASHING");
                    break;

                    case 5:
                        iDType_Ef = DAMAGE_TYPE_MAGICAL;
                        Tell(". . . DAMAGE_TYPE_MAGICAL");
                    break;

                    case 6:
                        iDType_Ef = DAMAGE_TYPE_ACID;
                        Tell(". . . DAMAGE_TYPE_ACID");
                    break;

                    case 7:
                        iDType_Ef = DAMAGE_TYPE_COLD;
                        Tell(". . . DAMAGE_TYPE_COLD");
                    break;

                    case 8:
                        iDType_Ef = DAMAGE_TYPE_DIVINE;
                        Tell(". . . DAMAGE_TYPE_DIVINE");
                    break;

                    case 9:
                        iDType_Ef = DAMAGE_TYPE_ELECTRICAL;
                        Tell(". . . DAMAGE_TYPE_ELECTRICAL");
                    break;

                    case 10:
                        iDType_Ef = DAMAGE_TYPE_FIRE;
                        Tell(". . . DAMAGE_TYPE_FIRE");
                    break;

                    case 11:
                        iDType_Ef = DAMAGE_TYPE_NEGATIVE;
                        Tell(". . . DAMAGE_TYPE_NEGATIVE");
                    break;

                    case 12:
                        iDType_Ef = DAMAGE_TYPE_POSITIVE;
                        Tell(". . . DAMAGE_TYPE_POSITIVE");
                    break;

                    case 13:
                        iDType_Ef = DAMAGE_TYPE_SONIC;
                        Tell(". . . DAMAGE_TYPE_SONIC");
                    break;
                }

                eEffect = EffectDamageResistance(iDType_Ef, 9999);
                eEffect = ExtraordinaryEffect(eEffect);
                eEffect = SetEffectSpellId(eEffect, ITEMIMMUNITY_FIX);
                // delay application so that GUI icons update properly
                DelayCommand(0.001f, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget));
            }
        }

        ++iDType_Ip;
    }

    Tell("\n");
}


//_________
// * MAIN *
void main()
{
    Tell("run ( fixim ) " + GetName(OBJECT_SELF));
    RunImmunityFix(OBJECT_SELF);
//  object oTarget = OBJECT_SELF;
//  DelayCommand(0.1f, RunImmunityFix(oTarget));
}
all the fix-effects should be removed first, so they don't accumulate.

#24
Clangeddin86

Clangeddin86
  • Members
  • 220 messages

Yes, now it works. Thanks for the improvement. 

OP updated (again) with new code. Final this time?  :lol:



#25
kevL

kevL
  • Members
  • 4 056 messages

nop, Lol

well maybe: am playing around with Vulnerabilities + Immunities
and am noticing that there's not exactly a 1:1 relation

eg.
2 rings, each with 100% immunity and 75% vulnerability
Total should be 100 + 100 - 75 - 75 = 50.*

but when 100pts damage is applied, PC takes 75pts

(that's before any fix is applied, fix won't kick in till 100+ ) PC still gets shafted for 25 pts eh


quite frankly there's something bizarre going in the engine. But I might not care quite enough to take it to Bletchley Park if ya know what i mean


*uh or something like that  :blink: