Hi All,
I know we can test to see if a PC has effects like EffectDamageResistance and EffectDamageImmunityIncrease, but is it possible to determine the subcategory protection that this type of effect offers?
E.g. If testing just for a resistance or immunity versus fire? i.e. A sub value of the main effect type.
Thanks in advance,
Lance.
Getting Effect SubTypes ... Is It Possible?
#1
Posté 29 juin 2015 - 02:04
#2
Posté 29 juin 2015 - 08:34
prepare yerself, get a Coffee.
GetEffectSubType(eEffect) gets the "subtype" ( inside a GetFirst/NextEffect(oCreature) loop ). the returns:
int SUBTYPE_MAGICAL = 8; int SUBTYPE_SUPERNATURAL = 16; int SUBTYPE_EXTRAORDINARY = 24;.... But i doubt that's quite what you're looking for. Instead, GetEffectInteger() is the cookie. Have a look through the testing script below (it runs from the console on a targetted creature, with an (int)Effect_Type passed in on the command line); the return from GetEffectInteger() is either a constant (scripted or literal) or a reference to a row# in a .2da ...
An effect has one or more 'effect integers' depending on how many are needed for its construction.
// 'testeffect'
//
void Tell(string sTell) { SendMessageToPC(GetFirstPC(FALSE), sTell); }
// ___________
// ** MAIN ***
void main(int iEffType)
{
object oTest = GetPlayerCurrentTarget(OBJECT_SELF);
if (!GetIsObjectValid(oTest)
|| GetObjectType(oTest) != OBJECT_TYPE_CREATURE)
{
oTest = OBJECT_SELF;
}
Tell("\nrun ( testeffect ) on " + GetName(oTest));
effect eEffect = GetFirstEffect(oTest);
while (GetIsEffectValid(eEffect))
{
if (GetEffectType(eEffect) == iEffType)
{
Tell(". Creator : " + GetName(GetEffectCreator(eEffect)) + " ( "
+ GetTag(GetEffectCreator(eEffect)) + " )");
Tell(". Type : " + IntToString(GetEffectType(eEffect)));
Tell(". Sub Type : " + IntToString(GetEffectSubType(eEffect)));
Tell(". Duration Type : " + IntToString(GetEffectDurationType(eEffect)));
Tell(". Spell ID : " + IntToString(GetEffectSpellId(eEffect)));
Tell(". Integer 0 : " + IntToString(GetEffectInteger(eEffect, 0)));
Tell(". Integer 1 : " + IntToString(GetEffectInteger(eEffect, 1)));
Tell(". Integer 2 : " + IntToString(GetEffectInteger(eEffect, 2)));
Tell(". Integer 3 : " + IntToString(GetEffectInteger(eEffect, 3)));
Tell(". Integer 4 : " + IntToString(GetEffectInteger(eEffect, 4)));
Tell(". Integer 5 : " + IntToString(GetEffectInteger(eEffect, 5)));
Tell(". Integer 6 : " + IntToString(GetEffectInteger(eEffect, 6)));
Tell(". Integer 7 : " + IntToString(GetEffectInteger(eEffect, 7)) + "\n");
}
else
{
Tell(". found Other Effect : " + IntToString(GetEffectType(eEffect)) + "\n");
}
eEffect = GetNextEffect(oTest);
}
}here's an example,apply test effect:
object oTarget = GetPlayerCurrentTarget(OBJECT_SELF);
effect eEffect = EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 10, 100); // EFFECT_TYPE_DAMAGE_RESISTANCE #1
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);and here is the output fromrs testeffect(1)
Creator : Calen Wyle Type : 1 // EFFECT_TYPE_DAMAGE_RESISTANCE SubType : 8 // SUBTYPE_MAGICAL DurationType : 2 // DURATION_TYPE_PERMANENT Spell ID : -1 // no spell ID Integer0 : 128 // DAMAGE_TYPE_ELECTRICAL Integer1 : 10 // 10 pts resistance Integer2 : 100 // up to 100 pts total.
Ps. subtypes of itemproperties are what you were thinking of, but subtypes of effects are a different animal
#3
Posté 30 juin 2015 - 12:09
hey Lance,
prepare yerself, get a Coffee.
GetEffectSubType(eEffect) gets the "subtype" ( inside a GetFirst/NextEffect(oCreature) loop ). the returns:int SUBTYPE_MAGICAL = 8; int SUBTYPE_SUPERNATURAL = 16; int SUBTYPE_EXTRAORDINARY = 24;.... But i doubt that's quite what you're looking for. Instead, GetEffectInteger() is the cookie. Have a look through the testing script below (it runs from the console on a targetted creature, with an (int)Effect_Type passed in on the command line); the return from GetEffectInteger() is either a constant (scripted or literal) or a reference to a row# in a .2da ...
An effect has one or more 'effect integers' depending on how many are needed for its construction.
// 'testeffect' // void Tell(string sTell) { SendMessageToPC(GetFirstPC(FALSE), sTell); } // ___________ // ** MAIN *** void main(int iEffType) { object oTest = GetPlayerCurrentTarget(OBJECT_SELF); if (!GetIsObjectValid(oTest) || GetObjectType(oTest) != OBJECT_TYPE_CREATURE) { oTest = OBJECT_SELF; } Tell("\nrun ( testeffect ) on " + GetName(oTest)); effect eEffect = GetFirstEffect(oTest); while (GetIsEffectValid(eEffect)) { if (GetEffectType(eEffect) == iEffType) { Tell(". Creator : " + GetName(GetEffectCreator(eEffect)) + " ( " + GetTag(GetEffectCreator(eEffect)) + " )"); Tell(". Type : " + IntToString(GetEffectType(eEffect))); Tell(". Sub Type : " + IntToString(GetEffectSubType(eEffect))); Tell(". Duration Type : " + IntToString(GetEffectDurationType(eEffect))); Tell(". Spell ID : " + IntToString(GetEffectSpellId(eEffect))); Tell(". Integer 0 : " + IntToString(GetEffectInteger(eEffect, 0))); Tell(". Integer 1 : " + IntToString(GetEffectInteger(eEffect, 1))); Tell(". Integer 2 : " + IntToString(GetEffectInteger(eEffect, 2))); Tell(". Integer 3 : " + IntToString(GetEffectInteger(eEffect, 3))); Tell(". Integer 4 : " + IntToString(GetEffectInteger(eEffect, 4))); Tell(". Integer 5 : " + IntToString(GetEffectInteger(eEffect, 5))); Tell(". Integer 6 : " + IntToString(GetEffectInteger(eEffect, 6))); Tell(". Integer 7 : " + IntToString(GetEffectInteger(eEffect, 7)) + "\n"); } else { Tell(". found Other Effect : " + IntToString(GetEffectType(eEffect)) + "\n"); } eEffect = GetNextEffect(oTest); } }here's an example,
apply test effect:object oTarget = GetPlayerCurrentTarget(OBJECT_SELF); effect eEffect = EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 10, 100); // EFFECT_TYPE_DAMAGE_RESISTANCE #1 ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);and here is the output from
rs testeffect(1)Creator : Calen Wyle Type : 1 // EFFECT_TYPE_DAMAGE_RESISTANCE SubType : 8 // SUBTYPE_MAGICAL DurationType : 2 // DURATION_TYPE_PERMANENT Spell ID : -1 // no spell ID Integer0 : 128 // DAMAGE_TYPE_ELECTRICAL Integer1 : 10 // 10 pts resistance Integer2 : 100 // up to 100 pts total.Ps. subtypes of itemproperties are what you were thinking of, but subtypes of effects are a different animal
Hi KevL,
Yes, I believe this is what I was after. i.e. "Subtypes of effects", as in my example. So, thanks for this! (Just me not knowing the correct terminology the engine uses.)
I did not know that "sub types" of effects were referenced with the GetEffectInteger functions. Again, naming could have been better. Now you have pointed it out though, perhaps I will be able to get my head around this some more ... later. ![]()
Just out of interest, is there a maximum limit to the number of integers recognised? i.e. I see you have 0-7 ... Is that just to get a sample return, or are there some effects that use all 7 integers?
Much thanks again!
Lance.
#4
Posté 30 juin 2015 - 12:18
But there -could- be more
#5
Posté 11 juillet 2015 - 04:03
OK, I spent a little more time looking at your testing function (which worked great by the way) and now realise that ...
int iDAMTYPE = GetEffectInteger(eEffect, 0);
.... is what I was after .... where iDAMTYPE takes the value of the standard DAMAGE_TYPE_**** values, where DAMAGE_TYPE_FIRE = 256.
This is the exact thing I was looking for, and so will make a quick function up to check for these values, based on this knowledge now.
Many Thanks,
Lance.
#6
Posté 11 juillet 2015 - 05:04
extra: test script for Itemproperties
// 'testip'
//
void Tell(string sTell) { SendMessageToPC(GetFirstPC(FALSE), sTell); }
void main()
{
Tell("\nrun ( testip ) " + GetName(OBJECT_SELF));
object oItem = GetPlayerCurrentTarget(OBJECT_SELF);
if (!GetIsObjectValid(oItem)
|| GetObjectType(oItem) != OBJECT_TYPE_ITEM)
{
Tell(". error : An item must be targetted.");
return;
}
itemproperty ipTest = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(ipTest))
{
int iType = GetItemPropertyType(ipTest);
int iDurType = GetItemPropertyDurationType(ipTest);
int iSubType = GetItemPropertySubType(ipTest);
int iCostTable = GetItemPropertyCostTable(ipTest);
int iCostTableValue = GetItemPropertyCostTableValue(ipTest);
int iParam1 = GetItemPropertyParam1(ipTest);
int iParam1Value = GetItemPropertyParam1Value(ipTest);
Tell(". Type = " + IntToString(iType));
Tell(". DurType = " + IntToString(iDurType));
Tell(". SubType = " + IntToString(iSubType));
Tell(". CostTable = " + IntToString(iCostTable));
Tell(". CostTableValue = " + IntToString(iCostTableValue));
Tell(". Param1 = " + IntToString(iParam1));
Tell(". Param1Value = " + IntToString(iParam1Value));
Tell("\n");
ipTest = GetNextItemProperty(oItem);
}
}stash t'in thy toolkit,
#7
Posté 11 juillet 2015 - 05:30
sweet,
extra: test script for Itemproperties// 'testip' // void Tell(string sTell) { SendMessageToPC(GetFirstPC(FALSE), sTell); } void main() { Tell("\nrun ( testip ) " + GetName(OBJECT_SELF)); object oItem = GetPlayerCurrentTarget(OBJECT_SELF); if (!GetIsObjectValid(oItem) || GetObjectType(oItem) != OBJECT_TYPE_ITEM) { Tell(". error : An item must be targetted."); return; } itemproperty ipTest = GetFirstItemProperty(oItem); while (GetIsItemPropertyValid(ipTest)) { int iType = GetItemPropertyType(ipTest); int iDurType = GetItemPropertyDurationType(ipTest); int iSubType = GetItemPropertySubType(ipTest); int iCostTable = GetItemPropertyCostTable(ipTest); int iCostTableValue = GetItemPropertyCostTableValue(ipTest); int iParam1 = GetItemPropertyParam1(ipTest); int iParam1Value = GetItemPropertyParam1Value(ipTest); Tell(". Type = " + IntToString(iType)); Tell(". DurType = " + IntToString(iDurType)); Tell(". SubType = " + IntToString(iSubType)); Tell(". CostTable = " + IntToString(iCostTable)); Tell(". CostTableValue = " + IntToString(iCostTableValue)); Tell(". Param1 = " + IntToString(iParam1)); Tell(". Param1Value = " + IntToString(iParam1Value)); Tell("\n"); ipTest = GetNextItemProperty(oItem); } }stash t'in thy toolkit,
Twill doest!
By the way, I have *NOT* tested to see if the DAMAGE_TYPE_XXX are *always* at integer 0 (zero) for every effect type. e.g. I don't know if the same integer 0 (zero) is where the DAMAGE_TYPE_XXX is stored when checking for Damage Resistance, as opposed to the Damage Immunity checked for last time.
Which brings me to my next point ... I thought (had hoped) that *items* which bestowed Damage Resistance and/or Damage Immunity, would return the same information when using your "testeffect" function on a PC that wore such an item. It appears, however, that this implementation of said Resistance/Immunity is not returned when tested on the PC wearing the item. Now, I am guessing the item itself will return the values (if tested, which I have not done yet), BUT this means a function to *TEST* for a PC having a certain elemental type of protection on them requires both a test on the PC themselves ... and a cycle through equipped items that may be bestowing such a property.
KEVL: Do you fancy writing such a function to test for such elemental protections on a PC? (I had started to modify your testeffect function for such a purpose, but have currently stopped when I realised this "limitation" when wearing items.)
The idea is that a conditional function (used in a conversation most likely) will return TRUE if a PC has a certain elemental protection vs a certain damage type on them. E.g. A PC wearing a ring with Damage Resistance 10 v FIRE does not return any values when the PC is tested at the moment ... which would with the correct function.
I can (and will) write the function myself if I have to, but notice you knock them out quicker than I do, especially as I am trying to alpha test the module and am trying to keep new scripting to a minimum at the moment.
Anyway, thanks for the extra testing function. DO let me know if you fancy having a go at writing that script/function ... just so I know if I am going to have to prepare it myself.
Cheers,
Lance.
HERE IS WHAT I STARTED WITH (Before I realised items did not return the value on the PC:-
// CHECK FOR ANY RESISTANCES VERSUS "DAMAGE TYPE" CONDITION (VIA INTEGER 0):-
// RETURNS TRUE IF TEST SUBJECT HAS *ANY* IMMUNITY OR RESISTANCE TO TESTED DAMAGE TYPE.
// oTESTSUBJECT is the subject to test if they have some sort of resistance or immunity to DAMAGE_TYPE_XXXXX
// DAMAGE_TYPE_VERSUS CAN BE ONE OF THE STANDARD DAMAGE_TYPE_XXXXX VALUES (E.g. FIRE = 256)
int StartingConditional(object oTESTSUBJECT, int DAMAGE_TYPE_VERSUS = 0)
{
int iFOUND = 0;
effect eEffect = GetFirstEffect(oTESTSUBJECT);
while (GetIsEffectValid(eEffect))
{
int iEffType = GetEffectType(eEffect);
// DAMAGE RESISTANCE (1) AND DAMAGE IMMUNITY (44) USE THE SAME INTEGER (0) TO RETURN DAMAGE TYPE
// NOT TESTED IF EFFECTS RETURN THE SAME VALUE AT INTEGER ZERO
if (iEffType == 44 || iEffType == 1)
{
// GATHER ALL DATA ANYWAY (JUST IN CASE I WILL EXPAND THIS FUNCTION)
object oCreator = GetEffectCreator(eEffect);
string sCreatorTag = GetTag(oCreator);
string sCreatorName = GetName(oCreator);
string sType = IntToString(GetEffectType(eEffect));
string sSubType = IntToString(GetEffectSubType(eEffect));
string sDurationType = IntToString(GetEffectDurationType(eEffect));
string sSpellID = IntToString(GetEffectSpellId(eEffect));
int iInteger0 = GetEffectInteger(eEffect, 0);
int iInteger1 = GetEffectInteger(eEffect, 1);
int iInteger2 = GetEffectInteger(eEffect, 2);
int iInteger3 = GetEffectInteger(eEffect, 3);
int iInteger4 = GetEffectInteger(eEffect, 4);
int iInteger5 = GetEffectInteger(eEffect, 5);
int iInteger6 = GetEffectInteger(eEffect, 6);
int iInteger7 = GetEffectInteger(eEffect, 7);
if(iInteger0 == DAMAGE_TYPE_VERSUS){iFOUND = 1; break;}
}
eEffect = GetNextEffect(oTESTSUBJECT);
}
return iFOUND;
}
#8
Posté 11 juillet 2015 - 07:52
Twill doest!
N.B.: The Early Modern English first person conjugation of "do" is simply "do" (2nd person = "dost", 3rd person = "doth").
#9
Posté 11 juillet 2015 - 08:15
N.B.: The Early Modern English first person conjugation of "do" is simply "do" (2nd person = "dost", 3rd person = "doth").
I was using "Old Althéa" ....
Will post alpha-testing stuff in a bit.
Cheers,
Lance.
#10
Posté 11 juillet 2015 - 08:27
Twill doest!
By the way, I have *NOT* tested to see if the DAMAGE_TYPE_XXX are *always* at integer 0 (zero) for every effect type. e.g. I don't know if the same integer 0 (zero) is where the DAMAGE_TYPE_XXX is stored when checking for Damage Resistance, as opposed to the Damage Immunity checked for last time.
i doubt it *has* to always be at int_0 (see notes). Further, a check should be made to ensure that the integer really pertains to an increase (or immunity), and not perhaps a vulnerability ... or whatever. ( There is a way to determine these things more logically - ie. by just studying code - but i think that code is buried in some crafting include, and I'm sure it would be more of an exercise than anything practical regardless ....)
note: I did quick tests and it looks the same for both effectTypes.
note2: but am sure, in these cases, it is.
Which brings me to my next point ... I thought (had hoped) that *items* which bestowed Damage Resistance and/or Damage Immunity, would return the same information when using your "testeffect" function on a PC that wore such an item. It appears, however, that this implementation of said Resistance/Immunity is not returned when tested on the PC wearing the item. Now, I am guessing the item itself will return the values (if tested, which I have not done yet), BUT this means a function to *TEST* for a PC having a certain elemental type of protection on them requires both a test on the PC themselves ... and a cycle through equipped items that may be bestowing such a property.
... and Feats ?
no, an itemproperty is an "itemproperty" and an effect is an "effect" -- totally different animals.
and a feat is a feat
The GetSpellResistance() function is a very handy one-off that examines all three types, but i don't believe there is anything else like that, such as GetElementalModifier(oTarget)
note: I did quick tests and it looks the same for both Itemproperty types, too.
KEVL: Do you fancy writing such a function to test for such elemental protections on a PC? (I had started to modify your testeffect function for such a purpose, but have currently stopped when I realised this "limitation" when wearing items.)
The idea is that a conditional function (used in a conversation most likely) will return TRUE if a PC has a certain elemental protection vs a certain damage type on them. E.g. A PC wearing a ring with Damage Resistance 10 v FIRE does not return any values when the PC is tested at the moment ... which would with the correct function.
I can (and will) write the function myself if I have to, but notice you knock them out quicker than I do, especially as I am trying to alpha test the module and am trying to keep new scripting to a minimum at the moment.
correction: i *post* them quicker. Time spent scratching my head ... doesn't count. /heh
anyway, here's a quick one:
// 'gc_fireresist'
//
// Returns TRUE if oTarget has Resistance/Immunity as an effect or an equipped itemproperty.
// Valid values for iType:
// 0 - magical
// 1 - acid
// 2 - cold
// 3 - divine
// 4 - electrical
// 5 - fire
// 6 - negative
// 7 - positive
// 8 - sonic
int StartingConditional(int iType)
{
object oTarget = GetPCSpeaker(); // kiss
// convert iType into constants
int
iEfType,
iIpType;
switch (iType)
{
default:
case 0:
iEfType = DAMAGE_TYPE_MAGICAL;
iIpType = IP_CONST_DAMAGETYPE_MAGICAL;
break;
case 1:
iEfType = DAMAGE_TYPE_ACID;
iIpType = IP_CONST_DAMAGETYPE_ACID;
break;
case 2:
iEfType = DAMAGE_TYPE_COLD;
iIpType = IP_CONST_DAMAGETYPE_COLD;
break;
case 3:
iEfType = DAMAGE_TYPE_DIVINE;
iIpType = IP_CONST_DAMAGETYPE_DIVINE;
break;
case 4:
iEfType = DAMAGE_TYPE_ELECTRICAL;
iIpType = IP_CONST_DAMAGETYPE_ELECTRICAL;
break;
case 5:
iEfType = DAMAGE_TYPE_FIRE;
iIpType = IP_CONST_DAMAGETYPE_FIRE;
break;
case 6:
iEfType = DAMAGE_TYPE_NEGATIVE;
iIpType = IP_CONST_DAMAGETYPE_NEGATIVE;
break;
case 7:
iEfType = DAMAGE_TYPE_POSITIVE;
iIpType = IP_CONST_DAMAGETYPE_POSITIVE;
break;
case 8:
iEfType = DAMAGE_TYPE_SONIC;
iIpType = IP_CONST_DAMAGETYPE_SONIC;
break;
}
// check effects
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
if ((GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_RESISTANCE // EffectDamageResistance()
|| GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE) // EffectDamageImmunityIncrease()
&& GetEffectInteger(eEffect, 0) == iEfType)
{
return TRUE;
}
eEffect = GetNextEffect(oTarget);
}
// check itemproperties equipped
object oEquip;
itemproperty ipProp;
int iSlot;
for (iSlot = 0; iSlot != NUM_INVENTORY_SLOTS; ++iSlot)
{
oEquip = GetItemInSlot(iSlot, oTarget);
if (GetIsObjectValid(oEquip))
{
ipProp = GetFirstItemProperty(oEquip);
while (GetIsItemPropertyValid(ipProp))
{
if ((GetItemPropertyType(ipProp) == ITEM_PROPERTY_DAMAGE_RESISTANCE // Damage Resistance / ItemPropertyDamageResistance()
|| GetItemPropertyType(ipProp) == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE) // Immunity:Damage Type / ItemPropertyDamageImmunity()
&& GetItemPropertySubType(ipProp) == iIpType)
{
return TRUE;
}
ipProp = GetNextItemProperty(oEquip);
}
}
}
return FALSE;
}
#11
Posté 13 juillet 2015 - 08:03
<SNIP>
correction: i *post* them quicker. Time spent scratching my head ... doesn't count. /heh
anyway, here's a quick one:// 'gc_fireresist' // // Returns TRUE if oTarget has Resistance/Immunity as an effect or an equipped itemproperty. // Valid values for iType: // 0 - magical // 1 - acid // 2 - cold // 3 - divine // 4 - electrical // 5 - fire // 6 - negative // 7 - positive // 8 - sonic int StartingConditional(int iType) { object oTarget = GetPCSpeaker(); // kiss // convert iType into constants int iEfType, iIpType; switch (iType) { default: case 0: iEfType = DAMAGE_TYPE_MAGICAL; iIpType = IP_CONST_DAMAGETYPE_MAGICAL; break; case 1: iEfType = DAMAGE_TYPE_ACID; iIpType = IP_CONST_DAMAGETYPE_ACID; break; case 2: iEfType = DAMAGE_TYPE_COLD; iIpType = IP_CONST_DAMAGETYPE_COLD; break; case 3: iEfType = DAMAGE_TYPE_DIVINE; iIpType = IP_CONST_DAMAGETYPE_DIVINE; break; case 4: iEfType = DAMAGE_TYPE_ELECTRICAL; iIpType = IP_CONST_DAMAGETYPE_ELECTRICAL; break; case 5: iEfType = DAMAGE_TYPE_FIRE; iIpType = IP_CONST_DAMAGETYPE_FIRE; break; case 6: iEfType = DAMAGE_TYPE_NEGATIVE; iIpType = IP_CONST_DAMAGETYPE_NEGATIVE; break; case 7: iEfType = DAMAGE_TYPE_POSITIVE; iIpType = IP_CONST_DAMAGETYPE_POSITIVE; break; case 8: iEfType = DAMAGE_TYPE_SONIC; iIpType = IP_CONST_DAMAGETYPE_SONIC; break; } // check effects effect eEffect = GetFirstEffect(oTarget); while (GetIsEffectValid(eEffect)) { if ((GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_RESISTANCE // EffectDamageResistance() || GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE) // EffectDamageImmunityIncrease() && GetEffectInteger(eEffect, 0) == iEfType) { return TRUE; } eEffect = GetNextEffect(oTarget); } // check itemproperties equipped object oEquip; itemproperty ipProp; int iSlot; for (iSlot = 0; iSlot != NUM_INVENTORY_SLOTS; ++iSlot) { oEquip = GetItemInSlot(iSlot, oTarget); if (GetIsObjectValid(oEquip)) { ipProp = GetFirstItemProperty(oEquip); while (GetIsItemPropertyValid(ipProp)) { if ((GetItemPropertyType(ipProp) == ITEM_PROPERTY_DAMAGE_RESISTANCE // Damage Resistance / ItemPropertyDamageResistance() || GetItemPropertyType(ipProp) == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE) // Immunity:Damage Type / ItemPropertyDamageImmunity() && GetItemPropertySubType(ipProp) == iIpType) { return TRUE; } ipProp = GetNextItemProperty(oEquip); } } } return FALSE; }
Hi KevL,
What a star! (I reckon posting them sooner is good too.
By the way, I reckon this will be a very handy function. Useful for the builder to be able to test for such things I reckon!
Thanks for this, I will give it a go in a while. I have to have a small op/procedure at the hospital now, but see how I feel when I get back.
I look forward to giving it a try though ... As you probably guessed, I do already have a place I need to use this.
Many Thanks,
Lance.
PS. Are there any feats that allow damage resistance or immunity then? (Just want to make sure I have them covered.) And more to the point, I suppose (if there are any) it all depends upon how the feat applies the resistance or immunity. After all, I am unaware of any other means of inferring resistances//immunities outside of the two functions we are already testing for. E.g. Even spells (like Resist ELements) uses one of the functions the testing script now checks. i.e. I think that it may only have been the items that give the protection that was over and above the standard tests we would need to check for regarding such resistances/immunities.
#12
Posté 13 juillet 2015 - 05:18
http://nwn2.wikia.com/wiki/Feat_List(apparently incomplete)
from The stock list at the wiki ... look for spellscripts for Celestial Resistance, Infernal Resistance, Fiendish Resistance, Divine Resistance, etc. I think it'd be better to look through your/ Althea's Feat.2da
Those that don't have a SPELLID, to apply an effect, are hard-coded and should be checked for under the appropriate cases of the switch(), exiting with an early return TRUE
It looks like the Epic Energy Resistances are all hardcoded. If you write up a list of feats that should be checked for, along with the type of energy they resist, i can likely find a decent place in the script ....
/stay well,
my advice: drink water
#13
Posté 13 juillet 2015 - 07:39
there may be some feat-resistances that are hardcoded
http://nwn2.wikia.com/wiki/Feat_List(apparently incomplete)
from The stock list at the wiki ... look for spellscripts for Celestial Resistance, Infernal Resistance, Fiendish Resistance, Divine Resistance, etc. I think it'd be better to look through your/ Althea's Feat.2da
Those that don't have a SPELLID, to apply an effect, are hard-coded and should be checked for under the appropriate cases of the switch(), exiting with an early return TRUE
It looks like the Epic Energy Resistances are all hardcoded. If you write up a list of feats that should be checked for, along with the type of energy they resist, i can likely find a decent place in the script ....
/stay well,
my advice: drink water
Hi KevL,
First, I have certainly been drinking water ... feel a bit better than I did earlier.
You have probably already guessed the feats that would need checking ... basically the elemental protection types, so any that you feel would be worth adding to your function, I would certainly be happy with that.
My Althéa feat.2da is the same as the OC 2da, but with lines added later on if I recall correctly. So, any code you are able to add, should work fine with my existing 2da.
As you can probably guess, I am taking it a bit easier today because of the procedure. It went smoothly enough; I just take longer to recover than most due to suffering from M.E.
I'll catch you later. If you do get time to update your script/function, I will of course, grab it to use.
Many Thanks,
Lance.
#14
Posté 13 juillet 2015 - 09:36

here's a longer one:
// 'gc_fireresist'
//
// Returns TRUE if oTarget has Resistance/Immunity as an effect or an equipped itemproperty.
// Valid values for iType:
// 0 - magical (default)
// 1 - acid
// 2 - cold
// 3 - divine
// 4 - electrical
// 5 - fire
// 6 - negative
// 7 - positive
// 8 - sonic
//
// 2015 jul 13
// - also tests for feats.
// helper
int hasFeat(object oTarget, int iType);
//____________
// * MAIN * //
int StartingConditional(int iType)
{
object oTarget = GetPCSpeaker(); // kiss
// check feats
if (hasFeat(oTarget, iType))
return TRUE;
// convert iType into constants
int
iEfType,
iIpType;
switch (iType)
{
default:
case 0:
iEfType = DAMAGE_TYPE_MAGICAL;
iIpType = IP_CONST_DAMAGETYPE_MAGICAL;
break;
case 1:
iEfType = DAMAGE_TYPE_ACID;
iIpType = IP_CONST_DAMAGETYPE_ACID;
break;
case 2:
iEfType = DAMAGE_TYPE_COLD;
iIpType = IP_CONST_DAMAGETYPE_COLD;
break;
case 3:
iEfType = DAMAGE_TYPE_DIVINE;
iIpType = IP_CONST_DAMAGETYPE_DIVINE;
break;
case 4:
iEfType = DAMAGE_TYPE_ELECTRICAL;
iIpType = IP_CONST_DAMAGETYPE_ELECTRICAL;
break;
case 5:
iEfType = DAMAGE_TYPE_FIRE;
iIpType = IP_CONST_DAMAGETYPE_FIRE;
break;
case 6:
iEfType = DAMAGE_TYPE_NEGATIVE;
iIpType = IP_CONST_DAMAGETYPE_NEGATIVE;
break;
case 7:
iEfType = DAMAGE_TYPE_POSITIVE;
iIpType = IP_CONST_DAMAGETYPE_POSITIVE;
break;
case 8:
iEfType = DAMAGE_TYPE_SONIC;
iIpType = IP_CONST_DAMAGETYPE_SONIC;
break;
}
// check effects
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
if (GetEffectInteger(eEffect, 0) == iEfType
&& (GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_RESISTANCE // EffectDamageResistance()
|| GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE)) // EffectDamageImmunityIncrease()
{
return TRUE;
}
eEffect = GetNextEffect(oTarget);
}
// check itemproperties equipped
object oEquip;
itemproperty ipProp;
int iSlot;
for (iSlot = 0; iSlot != NUM_INVENTORY_SLOTS; ++iSlot)
{
oEquip = GetItemInSlot(iSlot, oTarget);
if (GetIsObjectValid(oEquip))
{
ipProp = GetFirstItemProperty(oEquip);
while (GetIsItemPropertyValid(ipProp))
{
if (GetItemPropertySubType(ipProp) == iIpType
&& (GetItemPropertyType(ipProp) == ITEM_PROPERTY_DAMAGE_RESISTANCE // Damage Resistance / ItemPropertyDamageResistance()
|| GetItemPropertyType(ipProp) == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE)) // Immunity:Damage Type / ItemPropertyDamageImmunity()
{
return TRUE;
}
ipProp = GetNextItemProperty(oEquip);
}
}
}
return FALSE;
}
// helper
int hasFeat(object oTarget, int iType)
{
int iFeat;
switch (iType)
{
// case 0: // magical
// if (GetHasFeat(int nFeat, oTarget, TRUE))
// return TRUE;
// break;
case 1: // acid
if (GetHasFeat(FEAT_AASIMAR_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(1785, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_ACID
|| GetHasFeat(1790, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_ACID
|| GetHasFeat(1869, oTarget, TRUE) // FEAT_EARTH_GENASI_RESISTANCE
|| GetHasFeat(1943, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_ACID
|| GetHasFeat(2082, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_ACID
|| GetHasFeat(2114, oTarget, TRUE) // FEAT_RACIAL_RESIST_ACID_10
|| GetHasFeat(2189, oTarget, TRUE)) // FEAT_FIENDISH_RESISTANCE
{
return TRUE;
}
iFeat = FEAT_EPIC_ENERGY_RESISTANCE_ACID_1;
while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_ACID_10)
{
if (GetHasFeat(iFeat, oTarget, TRUE))
return TRUE;
++iFeat;
}
break;
case 2: // cold
if (GetHasFeat(FEAT_AASIMAR_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(FEAT_TIEFLING_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(FEAT_DIVINE_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(1786, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_COLD
|| GetHasFeat(1791, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_COLD
|| GetHasFeat(1871, oTarget, TRUE) // FEAT_WATER_GENASI_RESISTANCE
|| GetHasFeat(1944, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_COLD
|| GetHasFeat(2083, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_COLD
|| GetHasFeat(2115, oTarget, TRUE)) // FEAT_RACIAL_RESIST_COLD_10
{
return TRUE;
}
iFeat = FEAT_EPIC_ENERGY_RESISTANCE_COLD_1;
while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_COLD_10)
{
if (GetHasFeat(iFeat, oTarget, TRUE))
return TRUE;
++iFeat;
}
break;
// case 3: // divine
// if (GetHasFeat(int nFeat, oTarget, TRUE))
// return TRUE;
// break;
case 4: // electrical
if (GetHasFeat(FEAT_AASIMAR_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(FEAT_TIEFLING_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(FEAT_DIVINE_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(1787, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_ELECTRICAL
|| GetHasFeat(1792, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_ELECTRICAL
|| GetHasFeat(1868, oTarget, TRUE) // FEAT_AIR_GENASI_RESISTANCE
|| GetHasFeat(1945, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_ELECTRICAL
|| GetHasFeat(2041, oTarget, TRUE) // FEAT_STORMLORD_RESISTANCE_TO_ELECTRICITY_5
|| GetHasFeat(2042, oTarget, TRUE) // FEAT_STORMLORD_RESISTANCE_TO_ELECTRICITY_10
|| GetHasFeat(2043, oTarget, TRUE) // FEAT_STORMLORD_RESISTANCE_TO_ELECTRICITY_15
|| GetHasFeat(2044, oTarget, TRUE) // FEAT_STORMLORD_IMMUNITY_TO_ELECTRICITY
|| GetHasFeat(2084, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_ELECTRICAL
|| GetHasFeat(2116, oTarget, TRUE)) // FEAT_RACIAL_RESIST_ELECTRICITY_10
{
return TRUE;
}
iFeat = FEAT_EPIC_ENERGY_RESISTANCE_ELECTRICAL_1;
while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_ELECTRICAL_10)
{
if (GetHasFeat(iFeat, oTarget, TRUE))
return TRUE;
++iFeat;
}
break;
case 5: // fire
if (GetHasFeat(FEAT_TIEFLING_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(FEAT_DIVINE_RESISTANCE, oTarget, TRUE)
|| GetHasFeat(1788, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_FIRE
|| GetHasFeat(1793, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_FIRE
|| GetHasFeat(1870, oTarget, TRUE) // FEAT_FIRE_GENASI_RESISTANCE
|| GetHasFeat(1946, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_FIRE
|| GetHasFeat(2085, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_FIRE
|| GetHasFeat(2189, oTarget, TRUE)) // FEAT_FIENDISH_RESISTANCE
{
return TRUE;
}
iFeat = FEAT_EPIC_ENERGY_RESISTANCE_FIRE_1;
while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_FIRE_10)
{
if (GetHasFeat(iFeat, oTarget, TRUE))
return TRUE;
++iFeat;
}
break;
// case 6: // negative
// if (GetHasFeat(int nFeat, oTarget, TRUE))
// return TRUE;
// break;
// case 7: // positive
// if (GetHasFeat(int nFeat, oTarget, TRUE))
// return TRUE;
// break;
case 8: // sonic
if (GetHasFeat(1789, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_SONIC
|| GetHasFeat(1794, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_SONIC
|| GetHasFeat(1947, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_SONIC
|| GetHasFeat(2086, oTarget, TRUE)) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_SONIC
{
return TRUE;
}
iFeat = FEAT_EPIC_ENERGY_RESISTANCE_SONIC_1;
while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_SONIC_10)
{
if (GetHasFeat(iFeat, oTarget, TRUE))
return TRUE;
++iFeat;
}
break;
}
return FALSE;
}
#15
Posté 14 juillet 2015 - 11:24
and just as i get my ports working the way I want,
here's a longer one:// 'gc_fireresist' // // Returns TRUE if oTarget has Resistance/Immunity as an effect or an equipped itemproperty. // Valid values for iType: // 0 - magical (default) // 1 - acid // 2 - cold // 3 - divine // 4 - electrical // 5 - fire // 6 - negative // 7 - positive // 8 - sonic // // 2015 jul 13 // - also tests for feats. // helper int hasFeat(object oTarget, int iType); //____________ // * MAIN * // int StartingConditional(int iType) { object oTarget = GetPCSpeaker(); // kiss // check feats if (hasFeat(oTarget, iType)) return TRUE; // convert iType into constants int iEfType, iIpType; switch (iType) { default: case 0: iEfType = DAMAGE_TYPE_MAGICAL; iIpType = IP_CONST_DAMAGETYPE_MAGICAL; break; case 1: iEfType = DAMAGE_TYPE_ACID; iIpType = IP_CONST_DAMAGETYPE_ACID; break; case 2: iEfType = DAMAGE_TYPE_COLD; iIpType = IP_CONST_DAMAGETYPE_COLD; break; case 3: iEfType = DAMAGE_TYPE_DIVINE; iIpType = IP_CONST_DAMAGETYPE_DIVINE; break; case 4: iEfType = DAMAGE_TYPE_ELECTRICAL; iIpType = IP_CONST_DAMAGETYPE_ELECTRICAL; break; case 5: iEfType = DAMAGE_TYPE_FIRE; iIpType = IP_CONST_DAMAGETYPE_FIRE; break; case 6: iEfType = DAMAGE_TYPE_NEGATIVE; iIpType = IP_CONST_DAMAGETYPE_NEGATIVE; break; case 7: iEfType = DAMAGE_TYPE_POSITIVE; iIpType = IP_CONST_DAMAGETYPE_POSITIVE; break; case 8: iEfType = DAMAGE_TYPE_SONIC; iIpType = IP_CONST_DAMAGETYPE_SONIC; break; } // check effects effect eEffect = GetFirstEffect(oTarget); while (GetIsEffectValid(eEffect)) { if (GetEffectInteger(eEffect, 0) == iEfType && (GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_RESISTANCE // EffectDamageResistance() || GetEffectType(eEffect) == EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE)) // EffectDamageImmunityIncrease() { return TRUE; } eEffect = GetNextEffect(oTarget); } // check itemproperties equipped object oEquip; itemproperty ipProp; int iSlot; for (iSlot = 0; iSlot != NUM_INVENTORY_SLOTS; ++iSlot) { oEquip = GetItemInSlot(iSlot, oTarget); if (GetIsObjectValid(oEquip)) { ipProp = GetFirstItemProperty(oEquip); while (GetIsItemPropertyValid(ipProp)) { if (GetItemPropertySubType(ipProp) == iIpType && (GetItemPropertyType(ipProp) == ITEM_PROPERTY_DAMAGE_RESISTANCE // Damage Resistance / ItemPropertyDamageResistance() || GetItemPropertyType(ipProp) == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE)) // Immunity:Damage Type / ItemPropertyDamageImmunity() { return TRUE; } ipProp = GetNextItemProperty(oEquip); } } } return FALSE; } // helper int hasFeat(object oTarget, int iType) { int iFeat; switch (iType) { // case 0: // magical // if (GetHasFeat(int nFeat, oTarget, TRUE)) // return TRUE; // break; case 1: // acid if (GetHasFeat(FEAT_AASIMAR_RESISTANCE, oTarget, TRUE) || GetHasFeat(1785, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_ACID || GetHasFeat(1790, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_ACID || GetHasFeat(1869, oTarget, TRUE) // FEAT_EARTH_GENASI_RESISTANCE || GetHasFeat(1943, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_ACID || GetHasFeat(2082, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_ACID || GetHasFeat(2114, oTarget, TRUE) // FEAT_RACIAL_RESIST_ACID_10 || GetHasFeat(2189, oTarget, TRUE)) // FEAT_FIENDISH_RESISTANCE { return TRUE; } iFeat = FEAT_EPIC_ENERGY_RESISTANCE_ACID_1; while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_ACID_10) { if (GetHasFeat(iFeat, oTarget, TRUE)) return TRUE; ++iFeat; } break; case 2: // cold if (GetHasFeat(FEAT_AASIMAR_RESISTANCE, oTarget, TRUE) || GetHasFeat(FEAT_TIEFLING_RESISTANCE, oTarget, TRUE) || GetHasFeat(FEAT_DIVINE_RESISTANCE, oTarget, TRUE) || GetHasFeat(1786, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_COLD || GetHasFeat(1791, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_COLD || GetHasFeat(1871, oTarget, TRUE) // FEAT_WATER_GENASI_RESISTANCE || GetHasFeat(1944, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_COLD || GetHasFeat(2083, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_COLD || GetHasFeat(2115, oTarget, TRUE)) // FEAT_RACIAL_RESIST_COLD_10 { return TRUE; } iFeat = FEAT_EPIC_ENERGY_RESISTANCE_COLD_1; while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_COLD_10) { if (GetHasFeat(iFeat, oTarget, TRUE)) return TRUE; ++iFeat; } break; // case 3: // divine // if (GetHasFeat(int nFeat, oTarget, TRUE)) // return TRUE; // break; case 4: // electrical if (GetHasFeat(FEAT_AASIMAR_RESISTANCE, oTarget, TRUE) || GetHasFeat(FEAT_TIEFLING_RESISTANCE, oTarget, TRUE) || GetHasFeat(FEAT_DIVINE_RESISTANCE, oTarget, TRUE) || GetHasFeat(1787, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_ELECTRICAL || GetHasFeat(1792, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_ELECTRICAL || GetHasFeat(1868, oTarget, TRUE) // FEAT_AIR_GENASI_RESISTANCE || GetHasFeat(1945, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_ELECTRICAL || GetHasFeat(2041, oTarget, TRUE) // FEAT_STORMLORD_RESISTANCE_TO_ELECTRICITY_5 || GetHasFeat(2042, oTarget, TRUE) // FEAT_STORMLORD_RESISTANCE_TO_ELECTRICITY_10 || GetHasFeat(2043, oTarget, TRUE) // FEAT_STORMLORD_RESISTANCE_TO_ELECTRICITY_15 || GetHasFeat(2044, oTarget, TRUE) // FEAT_STORMLORD_IMMUNITY_TO_ELECTRICITY || GetHasFeat(2084, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_ELECTRICAL || GetHasFeat(2116, oTarget, TRUE)) // FEAT_RACIAL_RESIST_ELECTRICITY_10 { return TRUE; } iFeat = FEAT_EPIC_ENERGY_RESISTANCE_ELECTRICAL_1; while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_ELECTRICAL_10) { if (GetHasFeat(iFeat, oTarget, TRUE)) return TRUE; ++iFeat; } break; case 5: // fire if (GetHasFeat(FEAT_TIEFLING_RESISTANCE, oTarget, TRUE) || GetHasFeat(FEAT_DIVINE_RESISTANCE, oTarget, TRUE) || GetHasFeat(1788, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_FIRE || GetHasFeat(1793, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_FIRE || GetHasFeat(1870, oTarget, TRUE) // FEAT_FIRE_GENASI_RESISTANCE || GetHasFeat(1946, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_FIRE || GetHasFeat(2085, oTarget, TRUE) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_FIRE || GetHasFeat(2189, oTarget, TRUE)) // FEAT_FIENDISH_RESISTANCE { return TRUE; } iFeat = FEAT_EPIC_ENERGY_RESISTANCE_FIRE_1; while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_FIRE_10) { if (GetHasFeat(iFeat, oTarget, TRUE)) return TRUE; ++iFeat; } break; // case 6: // negative // if (GetHasFeat(int nFeat, oTarget, TRUE)) // return TRUE; // break; // case 7: // positive // if (GetHasFeat(int nFeat, oTarget, TRUE)) // return TRUE; // break; case 8: // sonic if (GetHasFeat(1789, oTarget, TRUE) // FEAT_WARLOCK_ENERGY_RESISTANCE_SONIC || GetHasFeat(1794, oTarget, TRUE) // FEAT_WARLOCK_IMPROVED_ENERGY_RESISTANCE_SONIC || GetHasFeat(1947, oTarget, TRUE) // FEAT_WARLOCK_EPIC_ENERGY_RESISTANCE_SONIC || GetHasFeat(2086, oTarget, TRUE)) // FEAT_FAVORED_SOUL_ENERGY_RESISTANCE_SONIC { return TRUE; } iFeat = FEAT_EPIC_ENERGY_RESISTANCE_SONIC_1; while (iFeat <= FEAT_EPIC_ENERGY_RESISTANCE_SONIC_10) { if (GetHasFeat(iFeat, oTarget, TRUE)) return TRUE; ++iFeat; } break; } return FALSE; }
Hi KevL,
Many thanks!
This will save me a lot of time, which is much appreciated. Thank you for your time and patience looking into this!
I am sure there sill be quite a few who find this helpful. At least, I would be surprised if it wasn't put to some use by others.
EDIT: I had absolutely no idea that there were so many feats offering elemental protection of sorts! ![]()
PORTS: Is this a game you are playing then? ![]()
Cheers,
Lance.
#16
Posté 14 juillet 2015 - 12:09
the sourcecode, and builds, are available through Openxcom.org (anyone interested still needs a legit copy of the original game, though, for the sound & graphic resources etc.)
anyway, keep your eyes open for more feats -- i think I got most of them but, odds are, I missed some.
#17
Posté 15 juillet 2015 - 08:31
"ports" is what I call the xcom interception windows: viewports.
the sourcecode, and builds, are available through Openxcom.org (anyone interested still needs a legit copy of the original game, though, for the sound & graphic resources etc.)
anyway, keep your eyes open for more feats -- i think I got most of them but, odds are, I missed some.
Hi KevL,
OK, I'll let you know if I see any others, but I doubt I will. After all, I had no idea of that lot!
Cheers,
Lance.





Retour en haut






