#include "prc_inc_clsfunc" int GetBlastDamageDices(object oInvoker, int nInvokerLevel) { int nDmgDice; if(nInvokerLevel < 13) nDmgDice = (nInvokerLevel + 1) / 2; else if(nInvokerLevel < 20) nDmgDice = (nInvokerLevel + 7) / 3; else nDmgDice = 9 + (nInvokerLevel - 20) / 2; //check for the epic feats if(GetHasFeat(FEAT_EPIC_ELDRITCH_BLAST_I, oInvoker)) { int nFeatAmt = 0; int bDone = FALSE; while(!bDone) { if(nFeatAmt >= 9) bDone = TRUE; else if(GetHasFeat(FEAT_EPIC_ELDRITCH_BLAST_II + nFeatAmt, oInvoker)) nFeatAmt++; else bDone = TRUE; } nDmgDice += nFeatAmt; } return nDmgDice; } // Spellblast should use only AoE spells but Dispel Magic can be cast as AoE or single target // we make sure here that we use AoE version int CheckSpecialTarget(int nSpellID) { return nSpellID == SPELL_DISPEL_MAGIC || nSpellID == SPELL_GREATER_DISPELLING || nSpellID == SPELL_LESSER_DISPEL || nSpellID == SPELL_MORDENKAINENS_DISJUNCTION || nSpellID == SPELL_POWER_WORD_KILL; } void DoSpellBlast(object oPC, int bHit) { int nSpellbookID = GetLocalInt(oPC, "ET_SPELL_CURRENT"); //DoDebug("nSpellbookID = "+IntToString(nSpellbookID)); if(nSpellbookID) { object oTarget = GetSpellTargetObject(); if(GetIsObjectValid(oTarget)) { nSpellbookID--; DeleteLocalInt(oPC, "ET_SPELL_CURRENT"); int nSpellID = GetLocalInt(oPC, "ET_REAL_SPELL_CURRENT"); //DoDebug("nSpellID = "+IntToString(nSpellID)); string sArray = GetLocalString(oPC, "ET_SPELL_CURRENT"); //DoDebug("sArray = "+sArray); int nUses = sArray == "" ? GetHasSpell(nSpellbookID, oPC) : persistant_array_get_int(oPC, sArray, nSpellbookID); if(nUses) { // expend spell use if(sArray == "") { DecrementRemainingSpellUses(oPC, nSpellID); } else { nUses--; persistant_array_set_int(oPC, sArray, nSpellbookID, nUses); } // use AoE Dispel Magic int bTargetOverride = CheckSpecialTarget(nSpellID); if(bHit) { int nCastingClass = GetETArcaneClass(oPC); int nDC = 10 + PRCGetSpellLevelForClass(nSpellID, nCastingClass) + GetDCAbilityModForClass(nCastingClass, oPC); //clear action queue to apply spell effect right after blast effect ClearAllActions(); //override PRCDoMeleeTouchAttack() - we already know that blast hit ActionDoCommand(SetLocalInt(oPC, "AttackHasHit", bHit)); SetLocalInt(oPC, "EldritchSpellBlast", TRUE); ActionCastSpell(nSpellID, 0, nDC, 0, METAMAGIC_NONE, nCastingClass, FALSE, bTargetOverride); ActionDoCommand(DeleteLocalInt(oPC, "AttackHasHit")); DelayCommand(0.5, DeleteLocalInt(oPC, "EldritchSpellBlast")); } } } } } void ApplyBlastDamage(object oCaster, object oTarget, int iAttackRoll, int iSR, int iDamage, int iDamageType, int iDamageType2, int nHellFire, int bSneak = TRUE, int nMsg = FALSE) { if (DEBUG) DoDebug("ApplyBlastDamage oCaster "+GetName(oCaster)+" oTarget "+GetName(oTarget)+" iAttackRoll "+IntToString(iAttackRoll)+" iSR "+IntToString(iSR)+" iDamage "+IntToString(iDamage)+" iDamageType "+IntToString(iDamageType)+" iDamageType2 "+IntToString(iDamageType2)+" nHellFire "+IntToString(nHellFire)+" bSneak "+IntToString(bSneak)+" nMsg "+IntToString(nMsg)); // Is it a critical hit? iDamage *= iAttackRoll; if(iAttackRoll) { // Heal the Undead if (iDamageType == DAMAGE_TYPE_NEGATIVE && (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD || GetLocalInt(oTarget, "AcererakHealing") || (GetHasFeat(FEAT_TOMB_TAINTED_SOUL, oTarget) && GetAlignmentGoodEvil(oTarget) != ALIGNMENT_GOOD))) { //Set the heal effect effect eHeal = EffectHeal(iDamage); ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget); } else // Other targets { if(!GetPRCSwitch(PRC_SPELL_SNEAK_DISABLE) && bSneak) iDamage += SpellSneakAttackDamage(oCaster, oTarget); effect eDamage; if(!iSR) { if(iDamageType == iDamageType2) eDamage = EffectDamage(iDamage, iDamageType); else { eDamage = EffectDamage(iDamage / 2, iDamageType); eDamage = EffectLinkEffects(eDamage, EffectDamage(iDamage / 2, iDamageType2)); } if(nHellFire) eDamage = EffectLinkEffects(eDamage, EffectDamage(d6(nHellFire), DAMAGE_TYPE_DIVINE)); } else if(iDamageType == DAMAGE_TYPE_ACID || iDamageType2 == DAMAGE_TYPE_ACID) { if(iDamageType == iDamageType2) eDamage = EffectDamage(iDamage, iDamageType); else eDamage = EffectDamage(iDamage / 2, iDamageType); } ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget); } } } int HellFireConDamage(object oPC) { if(GetIsImmune(oPC, IMMUNITY_TYPE_ABILITY_DECREASE)) { if(DEBUG) DoDebug("HellFireConDamage: Immune to ability damage!"); return FALSE; } ApplyAbilityDamage(oPC, ABILITY_CONSTITUTION, 1, DURATION_TYPE_TEMPORARY, TRUE, -1.0); return TRUE; } int GetIsHellFireBlast(object oPC) { if(GetLocalInt(oPC, "INV_HELLFIRE")) { DeleteLocalInt(oPC, "INV_HELLFIRE"); return TRUE; } return FALSE; }