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 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_MAGBLUE, 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. void DoMagicMissileStorm(int nD8Dice, int nMissiles, int nSpell, int nMIRV = VFX_IMP_MIRV, int nVIS = VFX_IMP_MAGBLUE, int nDAMAGETYPE = DAMAGE_TYPE_MAGICAL, int nReflexSave = FALSE)
  86. {
  87.     object oTarget = OBJECT_INVALID;
  88.     int nCasterLvl = GetCasterLevel(OBJECT_SELF);
  89.     int nMetaMagic = GetMetaMagicFeat();
  90.     int nCnt = 1;
  91.     effect eMissile = EffectVisualEffect(nMIRV);
  92.     effect eVis = EffectVisualEffect(nVIS);
  93.     float fDist = 0.0;
  94.     float fDelay = 0.0;
  95.     float fDelay2, fTime;
  96.     location lTarget = GetSpellTargetLocation(); // missile spread centered around target
  97.     vector vFirstTarget = GetPositionFromLocation(lTarget);
  98.     PrintString("calling DoMagicMissileStorm(nD8Dice=" + IntToString(nD8Dice) + ", nMissiles=" + IntToString(nMissiles) + ")");
  99.  
  100.     oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE, vFirstTarget);
  101.     PrintString("DoMagicMissileStorm: first target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ")");
  102.     //Cycle through the targets within the spell shape until an invalid object is captured.
  103.     while ( (GetIsObjectValid(oTarget)) && (nCnt <= nMissiles) )
  104.     {
  105.         // * caster cannot be harmed by this spell
  106.         if (spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, OBJECT_SELF) &&
  107.            (oTarget != OBJECT_SELF) // &&
  108. //           (( GetObjectType(OBJECT_SELF) == OBJECT_TYPE_PLACEABLE ) ||
  109. //           (GetObjectSeen(oTarget,OBJECT_SELF)))
  110.            )
  111.         {
  112.             //Fire cast spell at event for the specified target
  113.             SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpell));
  114.  
  115.             // * recalculate appropriate distances
  116.             fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
  117.             fDelay = fDist/(3.0 * log(fDist) + 2.0);
  118.  
  119.             if (!MyResistSpell(OBJECT_SELF, oTarget, fDelay))
  120.             {
  121.                 //Roll damage
  122.                 int nDam = d8(nD8Dice);
  123.                 PrintString("DoMagicMissileStorm: target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ") not resisted, base nDam=" + IntToString(nDam));
  124.                 //Enter Metamagic conditions
  125.                 if (nMetaMagic & METAMAGIC_MAXIMIZE) // can't happen with level 7 spell
  126.                 {
  127.                      nDam = nD8Dice*8;//Damage is at max
  128.                 }
  129.                 if (nMetaMagic & METAMAGIC_EMPOWER)
  130.                 {
  131.                     nDam = nDam + nDam/2; //Damage/Healing is +50%
  132.                     PrintString("DoMagicMissileStorm: (empowered) target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ") nDam=" + IntToString(nDam));
  133.                 }
  134.                 // Jan. 29, 2004 - Jonathan Epp
  135.                 // Reflex save was not being calculated for Firebrand
  136.                 if(nReflexSave)
  137.                 {
  138.                     if ( nDAMAGETYPE == DAMAGE_TYPE_ELECTRICAL )
  139.                     {
  140.                         nDam = GetReflexAdjustedDamage(nDam, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_ELECTRICITY);
  141.                     }
  142.                     else if ( nDAMAGETYPE == DAMAGE_TYPE_FIRE )
  143.                     {
  144.                         nDam = GetReflexAdjustedDamage(nDam, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_FIRE);
  145.                     }
  146.                     else if ( nDAMAGETYPE == DAMAGE_TYPE_MAGICAL )
  147.                     {
  148.                         nDam = GetReflexAdjustedDamage(nDam, oTarget, GetSpellSaveDC(), SAVING_THROW_TYPE_SPELL);
  149.                     }
  150.                 }
  151.  
  152.                 fTime = fDelay;
  153.                 fDelay2 += 0.1;
  154.                 fTime += fDelay2;
  155.  
  156.                 //Set damage effect
  157.                 effect eDam = EffectDamage(nDam, nDAMAGETYPE);
  158.                 //Apply the MIRV and damage effect
  159.                 DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
  160.                 DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget));
  161.                 DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
  162.             } // if spell not resisted
  163.             else
  164.             {  // * spell resisted, apply a dummy visual effect
  165.                 ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget);
  166.             }
  167.             nCnt++;// * increment count of missiles fired
  168.         }
  169.         oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lTarget, TRUE, OBJECT_TYPE_CREATURE, vFirstTarget);
  170.         PrintString("DoMagicMissileStorm: new target=" + ObjectToString(oTarget) + " (" + GetName(oTarget) + ")");
  171.     }
  172.  
  173. }