///////////////////////////////////////////////////////////////////// // // DoCone - Function to apply an elemental cone damage effect given // the following arguments: // // nDieSize - die size to roll (d4, d6, or d8) // nBonusDam - bonus damage per die, or 0 for none // nConeEffect - unused (this is in 2da) // nVictimEffect - visual effect to apply to target(s) // nDamageType - elemental damage type of the cone (DAMAGE_TYPE_xxx) // nSaveType - save type used for cone (SAVE_TYPE_xxx) // nSchool - spell school, defaults to SPELL_SCHOOL_EVOCATION // nSpellID - spell ID to use for events // ///////////////////////////////////////////////////////////////////// #include "prc_inc_spells" #include "prc_add_spell_dc" void DoCone (int nDieSize, int nBonusDam, int nDieCap, int nConeEffect /* unused */, int nVictimEffect, int nDamageType, int nSaveType, int nSchool = SPELL_SCHOOL_EVOCATION, int nSpellID = -1) { PRCSetSchool(nSchool); // Get the spell ID if it was not given. if (-1 == nSpellID) nSpellID = PRCGetSpellId(); // Get effective caster level and hand it to the SR engine. Then // cap it at our die cap. int nCasterLvl = PRCGetCasterLevel(OBJECT_SELF); int nPenetr = nCasterLvl + SPGetPenetr(); if (nCasterLvl > nDieCap) nCasterLvl = nDieCap; // Figure out where the cone was targetted. location lTargetLocation = PRCGetSpellTargetLocation(); // Adjust the damage type of necessary. nDamageType = PRCGetElementalDamageType(nDamageType, OBJECT_SELF); //Declare major variables int nDamage; float fDelay; object oTarget; // Declare the spell shape, size and the location. Capture the first target object in the shape. // Cycle through the targets within the spell shape until an invalid object is captured. oTarget = MyFirstObjectInShape(SHAPE_SPELLCONE, 11.0, lTargetLocation, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE); while(GetIsObjectValid(oTarget)) { if(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF)) { //Fire cast spell at event for the specified target PRCSignalSpellEvent(oTarget, TRUE, nSpellID); //Get the distance between the target and caster to delay the application of effects fDelay = PRCGetSpellEffectDelay(lTargetLocation, oTarget); //Make SR check, and appropriate saving throw(s). if(!PRCDoResistSpell(OBJECT_SELF, oTarget,nPenetr, fDelay) && (oTarget != OBJECT_SELF)) { int nSaveDC = PRCGetSaveDC(oTarget,OBJECT_SELF); // Roll damage for each target int nDamage = PRCGetMetaMagicDamage(nDamageType, nCasterLvl, nDieSize, nBonusDam); // Acid Sheath adds +1 damage per die to acid descriptor spells if (GetHasDescriptor(nSpellID, DESCRIPTOR_ACID) && GetHasSpellEffect(SPELL_MESTILS_ACID_SHEATH, OBJECT_SELF)) nDamage += nCasterLvl; nDamage += SpellDamagePerDice(OBJECT_SELF, nCasterLvl); // Adjust damage according to Reflex Save, Evasion or Improved Evasion nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, nSaveDC, nSaveType); // Apply effects to the currently selected target. if(nDamage > 0) { effect eDamage = PRCEffectDamage(oTarget, nDamage, nDamageType); effect eVis = EffectVisualEffect(nVictimEffect); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget)); PRCBonusDamage(oTarget); } } } //Select the next target within the spell shape. oTarget = MyNextObjectInShape(SHAPE_SPELLCONE, 11.0, lTargetLocation, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE); } // Let the SR engine know that we are done and clear out school local var. PRCSetSchool(); } // Test main //void main(){}