//:://///////////////////////////////////////////// //:: Molito (Spark Storm) //:: molito.nss //:: Copyright (c) 2025 WizardryEE Project //::////////////////////////////////////////////// /* Causes 3d6 (3-18) points of damage to half of a monster group. Level 3 Mage spell. In Wizardry: Proving Grounds of the Mad Overlord, this is a Level 3 Mage attack spell that targets half of a monster group. */ //::////////////////////////////////////////////// //:: Created By: WizardryEE Project //:: Created On: April 26, 2025 //::////////////////////////////////////////////// #include "prc_inc_spells" #include "prc_add_spell_dc" void main() { // Spell implementation for WizardryEE // Core functionality: Deal 3d6 damage to half of a monster group // Spellcast Hook Code if (!X2PreSpellCastCode()) return; // Set spell school for proper record keeping PRCSetSchool(SPELL_SCHOOL_EVOCATION); // Declare major variables object oCaster = OBJECT_SELF; int nCasterLevel = PRCGetCasterLevel(oCaster); int nMetaMagic = PRCGetMetaMagicFeat(); int nPenetr = nCasterLevel + SPGetPenetr(); int nDamage; float fDelay; // Get the target location location lTarget = PRCGetSpellTargetLocation(); // Create the incendiary cloud visual effect effect eImpact = EffectVisualEffect(VFX_FNF_INCENDIARY); effect eVis = EffectVisualEffect(VFX_IMP_FLAME_S); // Get the elemental damage type (default to electrical) int EleDmg = ChangedElementalDamage(oCaster, DAMAGE_TYPE_ELECTRICAL); // Apply the visual effect at the location ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lTarget); // Declare the spell shape, size and the location object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE); // Count total enemies in the area int nTotalEnemies = 0; object oCounter = oTarget; while (GetIsObjectValid(oCounter)) { if (spellsIsTarget(oCounter, SPELL_TARGET_STANDARDHOSTILE, oCaster)) { nTotalEnemies++; } oCounter = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE); } // Calculate how many to affect (half, rounded up) int nToAffect = (nTotalEnemies + 1) / 2; // Reset target for actual damage application oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE); // Track affected targets int nAffected = 0; // Cycle through the targets within the spell shape while (GetIsObjectValid(oTarget) && nAffected < nToAffect) { if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster)) { // Fire cast spell at event for the specified target SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId())); // Get the distance between the explosion and the target to calculate delay fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20; // Make SR check if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay)) { // Calculate damage - 3d6 electrical damage if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE)) nDamage = 18; // 3 * 6 = 18 (maximum damage) else nDamage = d6(3); if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER)) nDamage += nDamage / 2; // +50% damage // Add bonus damage per die nDamage += SpellDamagePerDice(oCaster, 3); // Adjust the damage based on the Reflex Save, Evasion and Improved Evasion nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, PRCGetSaveDC(oTarget, oCaster), SAVING_THROW_TYPE_ELECTRICITY); if (nDamage > 0) { // Set the damage effect effect eDam = PRCEffectDamage(oTarget, nDamage, EleDmg); // Apply effects to the currently selected target DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget)); DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget)); // Apply any bonus damage effects PRCBonusDamage(oTarget); // Notify damage DelayCommand(fDelay, FloatingTextStringOnCreature("MOLITO: " + IntToString(nDamage) + " spark damage to " + GetName(oTarget), oCaster, TRUE)); // Increment affected count nAffected++; } } } // Select the next target within the spell shape oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE); } // Final notification if (nAffected > 0) { FloatingTextStringOnCreature("MOLITO: Hit " + IntToString(nAffected) + " out of " + IntToString(nTotalEnemies) + " enemies!", oCaster, TRUE); } else { FloatingTextStringOnCreature("MOLITO: No enemies affected", oCaster, TRUE); } // Clean up spell school variable PRCSetSchool(); }