1. //::///////////////////////////////////////////////
  2. //:: Sun Shards
  3. //:: meb_sunshards
  4. //:: 2010 MrZork
  5. //::
  6. //:: Bioware's Firebrand and DoMissileStorm (from x0_i0_spells.nss) are
  7. //:: the templates for this spell.
  8. //:://////////////////////////////////////////////
  9. /*
  10. Description:
  11. Caster Level(s): Wizard / Sorcerer 7
  12. Innate Level: 7
  13. School: Evocation
  14. Component(s): Verbal, Somatic
  15. Range: Medium
  16. Area of Effect / Target: Colossal
  17. Duration: Instant
  18. Save: Reflex 1/2
  19. Spell Resistance: Yes
  20.  
  21. Bolts of magical energy (one per four caster levels, rounded down) burst
  22. forth from the caster and target random enemies in the area. If there
  23. are more enemies than bolts, only the nearest are targeted. If there are
  24. more bolts than enemies in range, the excess bolts disappear. Each bolt
  25. impacts for 5d8 of magical damage plus 1d8 per two caster levels, to a
  26. maximum of 25d8 total at caster level 40. Those targets who make a
  27. reflex save suffer half damage.
  28. */
  29.  
  30. #include "X0_I0_SPELLS"
  31. #include "x2_inc_spellhook"
  32.  
  33. void DoMagicMissileStorm(int nD8Dice, int nMissiles, int nSpell, int nMIRV = VFX_IMP_MIRV, int nVIS = VFX_IMP_MAGBLUE, int nCASTERFX = FALSE, int nDAMAGETYPE = DAMAGE_TYPE_MAGICAL, int nReflexSave = FALSE);
  34.  
  35. void main()
  36. {
  37.  
  38. /*
  39.   Spellcast Hook Code
  40.   Added 2003-06-20 by Georg
  41.   If you want to make changes to all spells,
  42.   check x2_inc_spellhook.nss to find out more
  43.  
  44. */
  45.  
  46.     if (!X2PreSpellCastCode())
  47.     {
  48.     // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
  49.         return;
  50.     }
  51.  
  52. // End of Spell Cast Hook
  53.  
  54.  
  55.     int nDamage =  5 + GetCasterLevel(OBJECT_SELF)/2;
  56.     if (nDamage > 25)
  57.         nDamage = 25;
  58.     int nMissiles =  GetCasterLevel(OBJECT_SELF)/4;
  59.  
  60.     // 840 is the spells.2da line of the Sun Shards spell
  61.     // may want to use VFX_IMP_SUNSTRIKE instead of VFX_IMP_MIRV
  62.     // ditto for VFX_IMP_PULSE_FIRE or VFX_IMP_FLAME_M or VFX_IMP_FLAME_S instead of VFX_IMP_MAGBLUE
  63.     DoMagicMissileStorm(nDamage, nMissiles, 840, VFX_IMP_MIRV, VFX_IMP_FLAME_M, VFX_IMP_PULSE_FIRE, DAMAGE_TYPE_MAGICAL, TRUE);
  64. }
  65.  
  66.  
  67. //::///////////////////////////////////////////////
  68. //:: DoMissileStorm
  69. //:: Copyright (c) 2002 Bioware Corp.
  70. //:://////////////////////////////////////////////
  71. /*
  72.     Fires a volley of missiles around the area
  73.     of the object selected. Only one missile can hit each
  74.     target, Firebrand-style rather than Isaac's * Storm-style.
  75.  
  76.     Each missiles (nD8Dice)d6 damage.
  77.     There are casterlevel missiles (to a cap as specified)
  78. */
  79. //:://////////////////////////////////////////////
  80. //:: Created By: Brent
  81. //:: Created On: July 31, 2002
  82. //:://////////////////////////////////////////////
  83. //:: Modified March 14 2003: Removed the option to hurt chests/doors
  84. //::  was potentially causing bugs when no creature targets available.
  85. //:: Modified Aug 2010 for use with Sun Shards. Added nCASTERFX (default
  86. //:: is FALSE for none) for the effect that plays on the caster)
  87. void DoMagicMissileStorm(int nD8Dice, int nMissiles, int nSpell, int nMIRV = VFX_IMP_MIRV, int nVIS = VFX_IMP_MAGBLUE, int nCASTERFX = FALSE, int nDAMAGETYPE = DAMAGE_TYPE_MAGICAL, int nReflexSave = FALSE)
  88. {
  89.     object oTarget = OBJECT_INVALID;
  90.     int nCasterLvl = GetCasterLevel(OBJECT_SELF);
  91.     int nMetaMagic = GetMetaMagicFeat();
  92.     int nCnt = 1;
  93.     effect eMissile = EffectVisualEffect(nMIRV);
  94.     effect eVis = EffectVisualEffect(nVIS);
  95.     float fDist = 0.0;
  96.     float fDelay = 0.0;
  97.     float fDelay2, fTime;
  98.     location lTarget = GetSpellTargetLocation(); // missile spread centered around target
  99.  
  100.     if (nCASTERFX)
  101.         {
  102.         effect eCaster = EffectVisualEffect(nCASTERFX);
  103.         ApplyEffectToObject(DURATION_TYPE_INSTANT, eCaster, oTarget);
  104.         }
  105.  
  106.     oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
  107.     //PrintString("DoMagicMissileStorm: first target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ")");
  108.     //Cycle through the targets within the spell shape until an invalid object is captured.
  109.     while ( (GetIsObjectValid(oTarget)) && (nCnt <= nMissiles) )
  110.     {
  111.         // * caster cannot be harmed by this spell
  112.         if (spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF) &&
  113.            (oTarget != OBJECT_SELF) &&
  114.            (GetObjectSeen(oTarget,OBJECT_SELF))
  115.            )
  116.         {
  117.             //Fire cast spell at event for the specified target
  118.             SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpell));
  119.  
  120.             // * recalculate appropriate distances
  121.             fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
  122.             fDelay = fDist/(3.0 * log(fDist) + 2.0);
  123.  
  124.             if (!MyResistSpell(OBJECT_SELF, oTarget, fDelay))
  125.             {
  126.                 //Roll damage
  127.                 int nDam = d8(nD8Dice);
  128.                 //PrintString("DoMagicMissileStorm: target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ") not resisted, base nDam=" + IntToString(nDam));
  129.                 //Enter Metamagic conditions
  130.                 if (nMetaMagic & METAMAGIC_MAXIMIZE) // can't happen with level 7 spell
  131.                 {
  132.                      nDam = nD8Dice*8;//Damage is at max
  133.                 }
  134.                 if (nMetaMagic & METAMAGIC_EMPOWER)
  135.                 {
  136.                     nDam = nDam + nDam/2; //Damage/Healing is +50%
  137.                     //PrintString("DoMagicMissileStorm: (empowered) target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ") nDam=" + IntToString(nDam));
  138.                 }
  139.                 // Jan. 29, 2004 - Jonathan Epp
  140.                 // Reflex save was not being calculated for Firebrand
  141.                 if(nReflexSave)
  142.                 {
  143.                     if ( nDAMAGETYPE == DAMAGE_TYPE_ELECTRICAL )
  144.                     {
  145.                         nDam = GetReflexAdjustedDamage(nDam, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_ELECTRICITY);
  146.                     }
  147.                     else if ( nDAMAGETYPE == DAMAGE_TYPE_FIRE )
  148.                     {
  149.                         nDam = GetReflexAdjustedDamage(nDam, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_FIRE);
  150.                     }
  151.                     else if ( nDAMAGETYPE == DAMAGE_TYPE_MAGICAL )
  152.                     {
  153.                         nDam = GetReflexAdjustedDamage(nDam, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_SPELL);
  154.                     }
  155.                 }
  156.  
  157.                 fTime = fDelay;
  158.                 fDelay2 += 0.1;
  159.                 fTime += fDelay2;
  160.  
  161.                 //Set damage effect
  162.                 effect eDam = EffectDamage(nDam, nDAMAGETYPE);
  163.                 //Apply the MIRV and damage effect
  164.                 DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
  165.                 DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget));
  166.                 DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
  167.             } // if spell not resisted
  168.             else
  169.             {  // * spell resisted, apply a dummy visual effect
  170.                 ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget);
  171.             }
  172.             nCnt++;// * increment count of missiles fired
  173.         }
  174.         oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
  175.         //PrintString("DoMagicMissileStorm: new target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ")");
  176.     }
  177.  
  178. }