//:://///////////////////////////////////////////// //:: Shifting effects application spellscript //:: prc_shft_effap //:://///////////////////////////////////////////// /** @file prc_shft_effap Applies those effects of shifting that need an effect placed on the shifter in order to bind said effects to a specific spellID. @author Ornedan @date Created - 2006.07.02 */ //::////////////////////////////////////////////// //::////////////////////////////////////////////// ////////////////////////////////////////////////// /* Constants */ ////////////////////////////////////////////////// ////////////////////////////////////////////////// /* Function prototypes */ ////////////////////////////////////////////////// ////////////////////////////////////////////////// /* Includes */ ////////////////////////////////////////////////// #include "prc_alterations" #include "prc_inc_shifting" const string PRC_Shifter_ApplyEffects_Generation = "PRC_Shifter_ApplyEffects_Generation"; ////////////////////////////////////////////////// /* Function definitions */ ////////////////////////////////////////////////// void main() { object oApplier = OBJECT_SELF; object oShifter = PRCGetSpellTargetObject(); if (GetLocalInt(oShifter, PRC_Shifter_ApplyEffects_EvalPRC_Generation) != GetLocalInt(oShifter, PRC_EvalPRCFeats_Generation)) { //EvalPRCFeats has been called again since this application was scheduled, //so don't apply--let the application scheduled by the later call to EvalPRCFeats //do it instead. return; } int nGeneration = PRC_NextGeneration(GetLocalInt(oShifter, PRC_Shifter_ApplyEffects_Generation)); SetLocalInt(oShifter, PRC_Shifter_ApplyEffects_Generation, nGeneration); int bApplyAll = GetLocalInt(oShifter, "PRC_SHIFTER_APPLY_ALL_SPELL_EFFECTS"); DeleteLocalInt(oShifter, "PRC_SHIFTER_APPLY_ALL_SPELL_EFFECTS"); int nSTR_AttackBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_AttackBonus"); int nSTR_DamageBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_DamageBonus"); int nSTR_DamageType = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_DamageType"); int nSTR_SaveAndSkillBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraSTR_SaveAndSkillBonus"); int nDEX_ACBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraDEX_ACBonus"); int nDEX_SaveAndSkillBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraDEX_SaveAndSkillBonus"); int nCON_HPBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraCON_HPBonus"); int nCON_SaveAndSkillBonus = GetLocalInt(oShifter, "PRC_Shifter_ExtraCON_SaveAndSkillBonus"); //Remove any old effects _prc_inc_shifting_RemoveSpellEffects(oShifter, bApplyAll); //Add any new effects //STR-based attack bonus if(nSTR_AttackBonus > 0) { int nAttackIncrease = nSTR_AttackBonus; if (nAttackIncrease > 20) nAttackIncrease = 20; DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectAttackIncrease(nAttackIncrease, ATTACK_BONUS_MISC)), oShifter); } else if (nSTR_AttackBonus < 0) { int nAttackDecrease = -nSTR_AttackBonus; if (nAttackDecrease > 20) //TODO: What's the actual cap? nAttackDecrease = 20; DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectAttackDecrease(nAttackDecrease, ATTACK_BONUS_MISC)), oShifter); } //STR-based damage bonus if(nSTR_DamageBonus > 0) { int nDamageBonusConstant; switch(nSTR_DamageBonus) { case 1 : nDamageBonusConstant = DAMAGE_BONUS_1 ; break; case 2 : nDamageBonusConstant = DAMAGE_BONUS_2 ; break; case 3 : nDamageBonusConstant = DAMAGE_BONUS_3 ; break; case 4 : nDamageBonusConstant = DAMAGE_BONUS_4 ; break; case 5 : nDamageBonusConstant = DAMAGE_BONUS_5 ; break; case 6 : nDamageBonusConstant = DAMAGE_BONUS_6 ; break; case 7 : nDamageBonusConstant = DAMAGE_BONUS_7 ; break; case 8 : nDamageBonusConstant = DAMAGE_BONUS_8 ; break; case 9 : nDamageBonusConstant = DAMAGE_BONUS_9 ; break; case 10: nDamageBonusConstant = DAMAGE_BONUS_10; break; case 11: nDamageBonusConstant = DAMAGE_BONUS_11; break; case 12: nDamageBonusConstant = DAMAGE_BONUS_12; break; case 13: nDamageBonusConstant = DAMAGE_BONUS_13; break; case 14: nDamageBonusConstant = DAMAGE_BONUS_14; break; case 15: nDamageBonusConstant = DAMAGE_BONUS_15; break; case 16: nDamageBonusConstant = DAMAGE_BONUS_16; break; case 17: nDamageBonusConstant = DAMAGE_BONUS_17; break; case 18: nDamageBonusConstant = DAMAGE_BONUS_18; break; case 19: nDamageBonusConstant = DAMAGE_BONUS_19; break; default: nDamageBonusConstant = DAMAGE_BONUS_20; // The value is >= 20, the bonus limit is +20 } DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectDamageIncrease(nDamageBonusConstant, nSTR_DamageType)), oShifter); } else if(nSTR_DamageBonus < 0) { DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectDamageDecrease(-nSTR_DamageBonus, nSTR_DamageType)), oShifter); } //DEX-based AC bonus if (nDEX_ACBonus > 0) DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectACIncrease(nDEX_ACBonus)), oShifter); else if (nDEX_ACBonus < 0) DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectACDecrease(-nDEX_ACBonus)), oShifter); //DEX-based save bonus if (nDEX_SaveAndSkillBonus > 0) DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nDEX_SaveAndSkillBonus)), oShifter); else if (nDEX_SaveAndSkillBonus < 0) DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_REFLEX, -nDEX_SaveAndSkillBonus)), oShifter); //TODO: what about forms that are immune to saving throw decrease? Use code similar to _prc_inc_shifting_BypassItemProperties()? //CON-based save bonus if (nCON_SaveAndSkillBonus > 0) DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, nCON_SaveAndSkillBonus)), oShifter); else if (nCON_SaveAndSkillBonus < 0) DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_FORT, -nCON_SaveAndSkillBonus)), oShifter); //TODO: what about forms that are immune to saving throw decrease? Use code similar to _prc_inc_shifting_BypassItemProperties()? //STR, DEX, and CON based skill bonuses int i = 0; string sSkillKeyAbility; effect eTotalSkillEffect; int bHaveTotalSkillEffect = FALSE; while((sSkillKeyAbility = Get2DACache("skills", "KeyAbility", i)) != "") { int nSaveAndSkillBonus = 0; if (sSkillKeyAbility == "STR") nSaveAndSkillBonus = nSTR_SaveAndSkillBonus; else if (sSkillKeyAbility == "DEX") nSaveAndSkillBonus = nDEX_SaveAndSkillBonus; else if (sSkillKeyAbility == "CON") nSaveAndSkillBonus = nCON_SaveAndSkillBonus; effect eSkillEffect; if(nSaveAndSkillBonus > 0) { eSkillEffect = EffectLinkEffects(eTotalSkillEffect, EffectSkillIncrease(i, nSaveAndSkillBonus)); } else if (nSaveAndSkillBonus < 0) { eSkillEffect = EffectLinkEffects(eTotalSkillEffect, EffectSkillDecrease(i, -nSaveAndSkillBonus)); //TODO: what about forms that are immune to skill decrease? Use code similar to _prc_inc_shifting_BypassItemProperties()? } if (!bHaveTotalSkillEffect) { eTotalSkillEffect = eSkillEffect; bHaveTotalSkillEffect = TRUE; } else eTotalSkillEffect = EffectLinkEffects(eTotalSkillEffect, eSkillEffect); i += 1; } if (bHaveTotalSkillEffect) DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(eTotalSkillEffect), oShifter); //Natural AC if(GetLocalInt(oShifter, "PRC_Shifter_NaturalAC")) { int nNaturalAC = GetLocalInt(oShifter, "PRC_Shifter_NaturalAC"); DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectACIncrease(nNaturalAC, AC_NATURAL_BONUS)), oShifter); } //Harmlessly invisible if (bApplyAll) { if(GetLocalInt(oShifter, "PRC_Shifter_HarmlessInvisible")) { if(DEBUG_EFFECTS || DEBUG) DoDebug("Applying Harmless Invisibility effect"); DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectInvisibility(INVISIBILITY_TYPE_NORMAL)), oShifter); } } //CON-based HP bonus if (bApplyAll) { if(DEBUG_EFFECTS || DEBUG) DoDebug("Applying Temporary HP effect: " + IntToString(nCON_HPBonus)); //Apply temporary HP separately from other effects--linking it with other effects //causes those other effects to be removed when the temporary HP is used up. if (nCON_HPBonus > 0) { DelayApplyEffectToObject(0.0f, PRC_Shifter_ApplyEffects_Generation, DURATION_TYPE_PERMANENT, SupernaturalEffect(EffectTemporaryHitpoints(nCON_HPBonus)), oShifter); } else if (nCON_HPBonus < 0) { //TODO } } if (GetIsObjectValid(oApplier) && GetResRef(oApplier) == "x0_rodwonder") { //Queue deletion of the applicator object DestroyObject(oApplier, 6.0f); } }