//:: Created by xwarren // Converts integer value into ASF ip constant. The proportion is // 1:5, meaning 1 = 5% ASF reduction, 2 = 10% etc. int GetIPASF(int asf); // Converts ip ASF constant into integer value int GetASF(int IP_ASF); // Removes all previously applied asf properties from the PCs skin void RemoveASFBonus(object oSkin); #include "prc_class_const" #include "inc_item_props" const string PRC_ASF_FLAG = "PRC_ArcaneSpellFailure"; int GetIPASF(int asf) { switch(asf) { case 1: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT; case 2: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT; case 3: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_15_PERCENT; case 4: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_20_PERCENT; case 5: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_25_PERCENT; case 6: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_30_PERCENT; case 7: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_35_PERCENT; case 8: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_40_PERCENT; case 9: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_45_PERCENT; case 10: return IP_CONST_ARCANE_SPELL_FAILURE_MINUS_50_PERCENT; } return -1; } int GetASF(int IP_ASF) { switch(IP_ASF) { case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_50_PERCENT: return -10; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_45_PERCENT: return -9; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_40_PERCENT: return -8; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_35_PERCENT: return -7; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_30_PERCENT: return -6; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_25_PERCENT: return -5; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_20_PERCENT: return -4; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_15_PERCENT: return -3; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT: return -2; case IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT: return -1; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_5_PERCENT: return 1; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_10_PERCENT: return 2; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_15_PERCENT: return 3; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_20_PERCENT: return 4; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_25_PERCENT: return 5; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_30_PERCENT: return 6; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_35_PERCENT: return 7; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_40_PERCENT: return 8; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_45_PERCENT: return 9; case IP_CONST_ARCANE_SPELL_FAILURE_PLUS_50_PERCENT: return 10; } return -1; } int checkASF(object oItem) { int total; itemproperty ip = GetFirstItemProperty(oItem); while(GetIsItemPropertyValid(ip)) { if(GetItemPropertyType(ip) == ITEM_PROPERTY_ARCANE_SPELL_FAILURE) { total += GetASF(GetItemPropertyCostTableValue(ip)); } ip = GetNextItemProperty(oItem); } return total; } void RemoveASFBonus(object oSkin) { itemproperty ip = GetFirstItemProperty(oSkin); while(GetIsItemPropertyValid(ip)) { if(GetItemPropertyType(ip) == ITEM_PROPERTY_ARCANE_SPELL_FAILURE && GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT) { RemoveItemProperty(oSkin, ip); } ip = GetNextItemProperty(oSkin); } } int ReducedSpellFailure(object oPC, object oArmor) { int nAC = GetBaseAC(oArmor); int nASF; //spellsword bonus int nSSLvl = GetLevelByClass(CLASS_TYPE_SPELLSWORD, oPC); if(nSSLvl) { if (nSSLvl > 10) nASF = (nSSLvl + 7) / 2; else if(nSSLvl > 4) nASF = ((nSSLvl - 1) / 2) * 2; else if(nSSLvl > 2) nASF = 3; else nASF = 2; } //medium or light armor equiped if(nAC < 6) { //Rage mage - arcane spell failure reduced by 10% while wearing light or medium armor. if(GetLevelByClass(CLASS_TYPE_RAGE_MAGE, oPC) >= 2) nASF += 2; //light armor equiped if(nAC < 4) { if(GetLevelByClass(CLASS_TYPE_BLADESINGER, oPC) > 5 || GetLevelByClass(CLASS_TYPE_MINSTREL_EDGE, oPC) || (GetLevelByClass(CLASS_TYPE_BARD, oPC) && GetPRCSwitch(PRC_BARD_LIGHT_ARMOR_SPELLCASTING))) { int nASFArmor = checkASF(oArmor); if (nAC == 1) nASFArmor += 1; else if (nAC == 2) nASFArmor += 2; else if (nAC == 3) nASFArmor += 4; if(nASFArmor > 0) nASF += nASFArmor; } } } return nASF; } void main() { object oPC = OBJECT_SELF; object oArmor; int iEquip = GetLocalInt(oPC, "ONEQUIP"); switch(iEquip) { case 0: oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oPC); break; case 1: oArmor = GetItemLastUnequipped(); break; case 2: oArmor = GetItemLastEquipped(); break; } if(GetBaseItemType(oArmor) != BASE_ITEM_ARMOR)//no need to run the script if we're called from equip/unequip event but the armor was not changed return; object oSkin = GetPCSkin(oPC); int iBonus = GetLocalInt(oSkin, PRC_ASF_FLAG); int nASF = ReducedSpellFailure(oPC, oArmor);// 1 point = 5% if(nASF == iBonus)// the bonus is the same - nothing to do return; // First thing is to remove old ASF RemoveASFBonus(oSkin); SetLocalInt(oSkin, PRC_ASF_FLAG, nASF); //add asf - max 100% while(nASF) { if(nASF > 10) { AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_50_PERCENT), oSkin); nASF -= 10; } else { AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyArcaneSpellFailure(GetIPASF(nASF)), oSkin); nASF = 0; } } }