• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

DD Universal Pack v5.1c

This pack contains many different type of spells.


Coded in Warcraft 3 v1.30, JNGP is no longer needed.

This works with my edited libraries which are now in the map itself, you will need to copy and paste the library to your map once for all spells to work.





v1 - First release with 3 spells:
- Slash Strike
- Electric Field
- Dark Torture


v2 - Few fixes + better test map + 1 new spell
- Frost Eruption


v3 - An extreme updata to my spell pack
- Heavy improved test map
- Fixed 'Handle Stack Corruption'
- Improved performances of all spells
- Added 4 new spells
- Shadow Crossing
- Algid Aura
- Nature Blessing
- Water Exhausting


v3b - Additional update to v3
- Fixed bug with Slash Strike
- Fixed bug with Nature Blessing
- Improved performances of Nature Blessing
- Made tooltips on Shadow Crossing and Dark Torture more readable


v4 - Fixed old rare bugs which i found out!
- Used my librarys on almost all spells
- Spells are now faster and less leakless (groupex)
- Added 3 new spells (4 spell was lost by me loosing electricity and all stuff was not saved...)
- Instinct Flash
- Terror Blade
- Black Magic


v4b - Made spells stable to work with default JNGP
- Fixed some minor and big bugs


v4c - Fixed more bugs
- Recompiled map in non-debug mode (forgot in v4b...)
- Used suggestions by Dr. Boom
- Fixed green buff in Water Exhausting
- Made Frost Eruption be based on Channel ability and give "target image"
- Some odd lag fixed...


v4d - Spells where broken for a long time now, so this update primarely fixes that
- Some code changes in library and spells
- Volume of sounds are now user configurable
- Fixed bug when sound fail to preload, thous sounds do not play when first casted
Sounds are now propertly preloaded


v4e - Fixed bug with Electric Field, when heros are killed they cant be revived. Now they can be revived.

v5 - Recoded many spells and made them compatible with new DD Library 1.2
- Electrolix Zap - Frost Eruption
- Frostmourne Impale - Nature Blessing
- Instinct Flash - Algid Aura


v5.1 - Recoded many spells and made them compatible with new DD Library and WC3 Patch v1.30
- Added new spells:
- Terror Blade
- Summon Skeletons
- Bubble Blast


v5.1b - Fixed desync sound bug

v5.1c - Added channel version of 'Summon Skeletons' spell requested by hemmedo






Electrolix Zap

Calls for a bolts of lightning down from the sky to strike any enemy unit, dealing damage. Any unit that gets killed by this ability will be burned with lighting. The other units will get purged.


JASS:
[/B]
//TESH.scrollpos=33
//TESH.alwaysfold=0
/*
 **********************************************************************************************************
 
          Installation:
  
  1) Copy DD Library to your map
  2) Copy ElectrolixZap abilities (hero and dummy versions) to your map
  3) Export and Import 'thunder1.wav' sound from this map to yours
  4) Export and Import 'Great Lightning.mdx' models from this map to yours
  5) Copy this trigger to your map and modify it to your liking below
  6) Made on Warcraft III v1.30
 
 **********************************************************************************************************
*/

//! zinc
library ElectrolixZap requires DDLib
{

 // *******************************************************************************
 
 // * Ability Id found in object editor
 // Default:  'elfd'
 constant integer    ABILITY_ELECTROLIX_ZAP        = 'elfd';
 
 // * Sound file being played when spell is cast
 // Default: "Custom\\Ambient\\thunder1.wav"
 constant  string     SOUND_THUNDER           = "Custom\\Ambient\\thunder1.wav";
 // Default: 100.
 constant  real     SOUND_THUNDER_VOL         = 100.;
 // Default: 3500.
 constant real    SOUND_MAX_DISTANCE         = 3500.;
 
 // * Should camera shake when spell is cast
 constant boolean    USE_CAMERA_NOISE         = true;
 // Default: 2.5
 constant real    CAMERA_NOISE_DURATION        = 2.5;
 
 // * Should terrain deformation happen?
 constant boolean    USE_TERRAIN_DEFORM         = true;
 // Default: 200.
 constant  real     TERRAIN_DEFORM_DEPTH         = 200.;
 // Default: 1.
 constant  real     TERRAIN_DEFORM_DURATION        = 1.;
 
 // * Primary lightning strike effect created during initial spell cast
 // Default: "Lightning\\Great Lightning.mdl"
 constant  string     EFFECT_GREAT_LIGHTNING         = "Lightning\\Great Lightning.mdx";
 constant  real     EFFECT_GREAT_LIGHTNING_SIZE       = 1.2;
 constant  real     EFFECT_GREAT_LIGHTNING_ANIMATION_SPEED    = 50.;
 
 // * Secondary lightning bolts created during initial spell cast
 // Default: "Doodads\\Cinematic\\Lightningbolt\\Lightningbolt.mdx"
 constant  string     EFFECT_LIGHTING_BOLT         = "Doodads\\Cinematic\\Lightningbolt\\Lightningbolt.mdx";
 // Default: 1.
 constant  real     EFFECT_LIGHTING_BOLT_SIZE       = 1.;
 // Default: 200.
 constant  real     EFFECT_LIGHTING_BOLT_ANIMATION_SPEED    = 200.;
 // Default: 25
 constant  integer    NUMBER_OF_LIGHTINING_BOLTS       = 25;
 // Default: 0.15 seconds
 constant  real     LIGHTNING_BOLT_STRIKE_INTERVAL       = 0.15;
 // Default: "Doodads\\LordaeronSummer\\Props\\SmokeSmudge\\SmokeSmudge0.mdl"
 constant  string     EFFECT_LIGHTING_BOLT_SMOKE_MODEL_1     = "Doodads\\LordaeronSummer\\Props\\SmokeSmudge\\SmokeSmudge0.mdl";
 // Default: ""
 constant  string     EFFECT_LIGHTING_BOLT_SMOKE_MODEL_2     = "";//"Doodads\\LordaeronSummer\\Props\\SmokeSmudge\\SmokeSmudge1.mdl";
 // Default: ""
 constant  string     EFFECT_LIGHTING_BOLT_SMOKE_MODEL_3     = "";//"Doodads\\LordaeronSummer\\Props\\SmokeSmudge\\SmokeSmudge2.mdl";
 // Default: 1.2
 constant  real     EFFECT_LIGHTING_BOLT_SMOKE_MODEL_SIZE    = 1.2;
 // Default: 20.
 constant  real     EFFECT_LIGHTING_BOLT_SMOKE_MODEL_Z_OFFSET   = 20.;
 // Default: 15.
 constant  real     EFFECT_LIGHTING_BOLT_SMOKE_MODEL_DURATION   = 15.;
 
 
 // * After initial primary and secondary bolts, wait for a while before damaging units
 constant real    THUNDER_DAMAGE_DELAY        = 0.6;
 
 // * Dealing damage and summon shield/lightning on targets
 // Default: "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldTarget.mdx"
 constant  string     EFFECT_LIGHTNING_UNIT_ZAP        = "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldTarget.mdx";
 
 // * Load dummies and shock target with forked lightning, add thunder clap effect and purge
 // Default: 'efef'
 constant  integer    ABILITY_DUMMY_ELECTRIC_SHOCK       = 'efef';
 // Default: 1000.
 constant real    DUMMY_LIGHTNING_HEIGHT        = 1000.;
 // Default: "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdx"
 constant  string     EFFECT_DUMMY_ELECTRIC_SHOCK       = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdx";
 // Deafault: 'Apg2'
 constant  integer    ABILITY_DUMMY_PURGE         = 'Apg2';
 
 // * Upon unit dying change its color and animation speed
 constant integer    COLOR_LIGHTNING_BURN_RED       = 00;
 constant integer    COLOR_LIGHTNING_BURN_GREEN       = 00;
 constant integer    COLOR_LIGHTNING_BURN_BLUE       = 00;
 constant real    COLOR_LIGHTNING_BURN_FADE_DURATION     = 5.;
 constant real    LIGHTNING_BURN_ANIMATION_SPEED      = .75;
 
 
 // * When unit gets burned, he gets 'ELECTRIFY_SFX' effect on him
 constant integer    ELECTRIFY_COUNT          = 4;
 constant real    ELECTRIFY_INTERVAL         = .66;
 constant string    ELECTRIFY_SFX          = "Abilities\\Weapons\\Bolt\\BoltImpact.mdx";
 
 
 
 // ==============================================================================================================================================
 // * Level data
 
 function InitElectrolixZapLevelData() {
  // * This is AOE (Area of Effect)/(radius) per level
  // Default 1: 610
  // Default 2: 660
  // Default 3: 705
  ELECTROLIX_ZAP_AOE[01]     = 610.;
  ELECTROLIX_ZAP_AOE[02]     = 660.;
  ELECTROLIX_ZAP_AOE[03]     = 705.;
  
  // This is damage to target per level
  // Default 1: 125
  // Default 2: 260
  // Default 3: 400
  ELECTROLIX_ZAP_DAMAGE[01]    = 125.;
  ELECTROLIX_ZAP_DAMAGE[02]    = 260.;
  ELECTROLIX_ZAP_DAMAGE[03]    = 400.;
  
  // This is the max damage spell can deal to all units
  // Default 1: 1000
  // Default 2: 2100
  // Default 3: 3250
  ELECTROLIX_ZAP_MAX_DAMAGE[01]   = 1000.;
  ELECTROLIX_ZAP_MAX_DAMAGE[02]   = 2100.;
  ELECTROLIX_ZAP_MAX_DAMAGE[03]  = 3250.;
 }
 
 
 //***********************************************************************
 //                    Main Unit Group Filter
 function ElecutixZapGroupFilter(unit f, player caster) -> boolean {
  return !IsUnitType(f, UNIT_TYPE_DEAD)    &&
      !IsUnitType(f, UNIT_TYPE_STRUCTURE)   &&
      !IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) &&
      !IsUnitType(f, UNIT_TYPE_MECHANICAL)  &&
      IsUnitEnemy(f, caster)      &&
      IsUnitVisible(f, caster)     &&
      !DDIsUnitWard(f)       &&
      !BlzIsUnitInvulnerable(f);
 }
 
 // *******************************************************************************
 // *    Spell other variables (non-modifiable)
 // *******************************************************************************
 
 type smokecluster extends effect[NUMBER_OF_LIGHTINING_BOLTS];
 
 effect    LastLigBolt   = null;
 real   ELECTROLIX_ZAP_AOE[];
 real   ELECTROLIX_ZAP_DAMAGE[];
 real   ELECTROLIX_ZAP_MAX_DAMAGE[];
 smokecluster pSmokeGroup[];
 
 struct ezdata {
  unit u;
  real aoe;
  player owner;
  real x, y;
  real mxDmg, dmg;
  effect e[64];
  integer i=00;
  group g, dg;
   
  static thistype Temp  = p_null;
 }
 
 struct dmgdelay {
  unit u, f;
  real dmg;
  integer n;
 }
 
 struct unitfade {
  unit u;
  real r, g, b;
  real vr, vg, vb;
  boolean burn=false;
  
  static unitfade pUF[];
 }
 
 function RawDamage2Damage(unit u, real dmg) -> real {
  if (IsUnitType(u, UNIT_TYPE_HERO)) {
   if (UnitHasItemOfTypeBJ(u, 'brac'))
    return dmg*.5;
   return dmg*.75;
  }
  return dmg;
 }
 
 //===========================================================================
 // Main init electric field function
 function onInit() {
  //--------------------->
  //* Load init locals
  //<--------------------
  trigger   t = CreateTrigger();
  
  // *** Initialize constants
  InitElectrolixZapLevelData();
  
  
  // ###############################################################
        TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
        TriggerAddCondition(t, Condition(function() -> boolean {
   real   x = GetSpellTargetX(), y = GetSpellTargetY();
   unit   u = GetTriggerUnit();
   integer   lvl = GetUnitAbilityLevel(u, GetSpellAbilityId());
   integer   i;
   sound    s;
   real   d;
   p_real   pr;
   effect   e;
            ezdata          ezd;
  
   if (GetSpellAbilityId() != ABILITY_ELECTROLIX_ZAP)
    return false;

   
   // Play sound and shake camera for players within spell cast range
   DDGenericSound(SOUND_THUNDER, SOUND_THUNDER_VOL, x, y, SOUND_MAX_DISTANCE, 1.);
   static if (USE_CAMERA_NOISE)
    DDCameraSetSourceNoiseForPlayers(x, y, 70., 1750., SOUND_MAX_DISTANCE, CAMERA_NOISE_DURATION);
   /*
   for (i=00; i < bj_MAX_PLAYERS; i+=01) {
    if (GetLocalPlayer() == Player(i)) {
     d = SquareRoot( Pw_2(GetCameraTargetPositionX()-x) + Pw_2(GetCameraTargetPositionY()-y) );
     if (d < SOUND_MAX_DISTANCE) {
      s = CreateSound(SOUND_THUNDER, false, false, false, 10, 10, "");
      SetSoundVolume(s, R2I(SOUND_THUNDER_VOL-d*(SOUND_THUNDER_VOL/SOUND_MAX_DISTANCE)));
      StartSound(s);
      KillSoundWhenDone(s);
      s = null;
      
      static if (USE_CAMERA_NOISE)
       CameraSetSourceNoise(70.-(d*(70./SOUND_MAX_DISTANCE)), 1750.-(d*(1750./SOUND_MAX_DISTANCE)));
     }
    }
   }
   
   static if (USE_CAMERA_NOISE)
    DDStartTim(CAMERA_NOISE_DURATION, false, p_null, function() {
     CameraSetSourceNoise(0., 0.);
    });
   
   */
   // * Terrain deformation crater action
   static if (USE_TERRAIN_DEFORM)
    TerrainDeformCrater(x, y, ELECTROLIX_ZAP_AOE[lvl], TERRAIN_DEFORM_DEPTH, R2I(TERRAIN_DEFORM_DURATION*1000.), false);
   
   // * Load main big thunder effect
   e = AddSpecialEffect(EFFECT_GREAT_LIGHTNING, x, y);
   BlzSetSpecialEffectScale(e, EFFECT_GREAT_LIGHTNING_SIZE);
   BlzSetSpecialEffectTimeScale(e, EFFECT_GREAT_LIGHTNING_ANIMATION_SPEED/100.);
   DestroyEffect(e); e = null;
   
   // * Load extra lightning effects
   if (NUMBER_OF_LIGHTINING_BOLTS > 00) {
    pr = p_real.create();
    pr[00] = Pow(ELECTROLIX_ZAP_AOE[lvl], 1.3333);//*ELECTROLIX_ZAP_AOE[lvl];
    pr[01] = x; pr[02] = y;
    
    pSmokeGroup[pr] = smokecluster.create();
    DDStartTim(EFFECT_LIGHTING_BOLT_SMOKE_MODEL_DURATION, false, pSmokeGroup[pr], function() {
     smokecluster sc = DDTimData();
     integer i;
     for(i=00; i < NUMBER_OF_LIGHTINING_BOLTS; i+=01) {
      DestroyEffect(sc[i]); sc[i] = null;
     }
     sc.destroy();
     DDQuitTim();
    });
    
    DDStartTim(LIGHTNING_BOLT_STRIKE_INTERVAL, true, pr, function() {
     p_real   pr     = DDTimData();
     real   r     = Pow( GetRandomReal(50., pr[00]), .75 );
     real   rad    = GetRandomReal(0., bj_PI*2.);
     effect   smoke;
     integer  smoke_rnd_n  = 00;
     real  x, y;
     
     DestroyEffect(LastLigBolt);
     if (DDTimTick() == NUMBER_OF_LIGHTINING_BOLTS) {
      LastLigBolt = null;
      pr.destroy();
      DDQuitTim();
      return;
     }
     
     if (EFFECT_LIGHTING_BOLT_SMOKE_MODEL_2 != "")
      smoke_rnd_n += 01;
     if (EFFECT_LIGHTING_BOLT_SMOKE_MODEL_3 != "")
      smoke_rnd_n += 01;
     smoke_rnd_n = GetRandomInt(00, smoke_rnd_n);
     
     x = pr[01] + r * Cos(rad); y = pr[02] + r * Sin(rad);
     LastLigBolt = AddSpecialEffect(EFFECT_LIGHTING_BOLT, x, y);
     BlzSetSpecialEffectScale(LastLigBolt, EFFECT_LIGHTING_BOLT_SIZE);
     BlzSetSpecialEffectTimeScale(LastLigBolt, EFFECT_LIGHTING_BOLT_ANIMATION_SPEED/100.);
     if (smoke_rnd_n == 00)
      smoke = AddSpecialEffect(EFFECT_LIGHTING_BOLT_SMOKE_MODEL_1, x, y);
     else if (smoke_rnd_n == 01)
      smoke = AddSpecialEffect(EFFECT_LIGHTING_BOLT_SMOKE_MODEL_2, x, y);
     else
      smoke = AddSpecialEffect(EFFECT_LIGHTING_BOLT_SMOKE_MODEL_3, x, y);
     BlzSetSpecialEffectScale(smoke, EFFECT_LIGHTING_BOLT_SMOKE_MODEL_SIZE);
     BlzSetSpecialEffectZ(smoke, DDTerrZ(x, y) + EFFECT_LIGHTING_BOLT_SMOKE_MODEL_Z_OFFSET);
     pSmokeGroup[pr][00] = smoke;
     pSmokeGroup[pr] += smokecluster(01);
    });
   }
  
   ezd = ezdata.create();
   ezd.u = u;
   ezd.aoe = ELECTROLIX_ZAP_AOE[lvl];
   ezd.owner = GetOwningPlayer(u);
   ezd.x = x; ezd.y = y;
   ezd.dmg = ELECTROLIX_ZAP_DAMAGE[lvl];
   ezd.mxDmg = ELECTROLIX_ZAP_MAX_DAMAGE[lvl];
   
   DDStartTim(THUNDER_DAMAGE_DELAY, false, ezd, function() {
    ezdata.Temp = DDTimData();
    ezdata.Temp.g = DDLoadGroup();
    
    GroupEnumUnitsInRange(ezdata.Temp.g, ezdata.Temp.x, ezdata.Temp.y, ezdata.Temp.aoe, Filter(function() -> boolean {
     ezdata ezd = ezdata.Temp;
     
     if ( ElecutixZapGroupFilter(GetFilterUnit(), ezd.owner) ) {
      // *  Do pre-damage so taht creeps dont run away from invulnerable dummy units
      if (GetPlayerController(GetOwningPlayer(GetFilterUnit())) == MAP_CONTROL_CREEP)
       IssuePointOrder(GetFilterUnit(), "attack", GetUnitX(ezd.u), GetUnitY(ezd.u));
      
      ezd.e[ezd.i] = AddSpecialEffectTarget(EFFECT_LIGHTNING_UNIT_ZAP, GetFilterUnit(), "origin");
      ezd.i += 01;
     }
     
     return true;
    }));
    
    ezdata.Temp.dg = DDLoadGroup();
    DDStartTim(THUNDER_DAMAGE_DELAY, false, ezdata.Temp, function() {
     ezdata ezd = DDTimData();
     ezdata.Temp = ezd;
     ezd.dmg = RMinBJ(ezd.mxDmg/ezd.i, ezd.dmg);
     
     ForGroup(ezd.g, function() {
      ezdata ezd = ezdata.Temp;
      unit u = GetEnumUnit();
      real x = GetUnitX(u), y = GetUnitY(u);
      real rad = GetRandomReal(0., bj_PI*2);
      real dist = GetRandomReal(225., 375.);
      unit d = DDLoadSpellDummy(ezd.owner, x + dist * Cos(rad), y + dist * Sin(rad), ABILITY_DUMMY_ELECTRIC_SHOCK, 01);
      real dmg;
      dmgdelay dd;
      
      ezd.i -= 01;
      DestroyEffect(ezd.e[ezd.i]);
      ezd.e[ezd.i] = null;
      
      if (IsUnitEnemy(u, ezd.owner) && !IsUnitType(u, UNIT_TYPE_DEAD)) {
       SetUnitFlyHeight(d, DUMMY_LIGHTNING_HEIGHT, 0.);
       IssueTargetOrder(d, "chainlightning", u);
       DestroyEffect(AddSpecialEffectTarget(EFFECT_DUMMY_ELECTRIC_SHOCK, u, "origin"));
      }
      
      // * if unit dies, then dummy cant cast spell on that unit
      GroupAddUnit(ezd.dg, d);
      dmg = RawDamage2Damage(u, ezd.dmg);
      dd = dmgdelay.create();
      dd.u = ezd.u; dd.f = u;
      dd.dmg = dmg;
      dd.n = ELECTRIFY_COUNT;
      DDStartTim(.2, false, dd, function() {
       dmgdelay dd = DDTimData();
       unitfade uf;
       
       if (IsUnitEnemy(dd.f, GetOwningPlayer(dd.u)) && !IsUnitType(dd.f, UNIT_TYPE_DEAD)) {
        UnitDamageTarget(dd.u, dd.f, dd.dmg, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNKNOWN, null);
        
        SetUnitVertexColor(dd.f, COLOR_LIGHTNING_BURN_RED, COLOR_LIGHTNING_BURN_GREEN, COLOR_LIGHTNING_BURN_BLUE, 255);
        SetUnitTimeScale(dd.f, LIGHTNING_BURN_ANIMATION_SPEED);
        DDStartTim(ELECTRIFY_INTERVAL, true, dd, function() {
         dmgdelay dd = DDTimData();
         
         DestroyEffect(AddSpecialEffectTarget(ELECTRIFY_SFX, dd.f, "origin"));
         
         dd.n -= 01;
         if (dd.n == 00) {
          dd.destroy();
          DDQuitTim();
         }
        });
        
        if (!IsUnitType(dd.f, UNIT_TYPE_DEAD)) {
         uf = unitfade.pUF[H2ID(dd.f)];
         if (uf == p_null) {
          uf = unitfade.create();
          uf.u = dd.f;
          unitfade.pUF[H2ID(dd.f)] = uf;
          
          DDStartTim(DD_INTERVAL, true, uf, function() {
           unitfade uf = DDTimData();
           
           uf.r += uf.vr;
           uf.g += uf.vg;
           uf.b += uf.vb;
           
           SetUnitVertexColor(uf.u, R2I(255.*Pw_2(uf.r)), R2I(255.*Pw_2(uf.g)), R2I(255.*Pw_2(uf.b)), 255);
           
           if (uf.r > 1. || uf.burn) {
            if (uf.burn)
             SetUnitVertexColor(uf.u, COLOR_LIGHTNING_BURN_RED, COLOR_LIGHTNING_BURN_GREEN, COLOR_LIGHTNING_BURN_BLUE, 255);
            else
             SetUnitTimeScale(uf.u, 1.);
            unitfade.pUF[H2ID(uf.u)] = p_null;
            uf.u = null;
            uf.destroy();
            DDQuitTim();
           }
           
          });
         }
         
         uf.r = COLOR_LIGHTNING_BURN_RED / 255.;
         uf.g = COLOR_LIGHTNING_BURN_GREEN / 255.;
         uf.b = COLOR_LIGHTNING_BURN_BLUE / 255.;
         uf.vr = DD_INTERVAL * (1.-uf.r) / COLOR_LIGHTNING_BURN_FADE_DURATION;
         uf.vg = DD_INTERVAL * (1.-uf.g) / COLOR_LIGHTNING_BURN_FADE_DURATION;
         uf.vb = DD_INTERVAL * (1.-uf.b) / COLOR_LIGHTNING_BURN_FADE_DURATION;
        } else if (IsUnitType(dd.f, UNIT_TYPE_HERO)) {
         SetUnitVertexColor(dd.f, 255, 255, 255, 255);
        } else if (unitfade.pUF[H2ID(dd.f)] != p_null)
         unitfade.pUF[H2ID(dd.f)].burn = true;
       } else
        dd.destroy();
       
       DDQuitTim();
      });
      
      d = null;
      u = null;
     });
     
     DDStartTim(.3, true, ezd, function() {
      ezdata.Temp = DDTimData();
      
      // First run, wait for 1 x .3 secs
      if (DDTimTick() == 01) {
       ForGroup(ezdata.Temp.dg, function() {
        unit e = GetEnumUnit(), t = FirstOfGroup(ezdata.Temp.g);
        UnitRemoveAbility(e, ABILITY_DUMMY_ELECTRIC_SHOCK);
        UnitAddAbility(e, ABILITY_DUMMY_PURGE);
        SetUnitX(e, GetUnitX(t)); SetUnitY(e, GetUnitY(t));
        IssueTargetOrder(e, "purge", t);
        GroupRemoveUnit(ezdata.Temp.g, t);
        
        e = null; t = null;
       });
       return;
      }
      
      // Second run, wait for 2 x .3 secs
      ForGroup(ezdata.Temp.dg, function() {
       UnitRemoveAbility(GetEnumUnit(), ABILITY_DUMMY_PURGE);
       DDRecycleDummy(GetEnumUnit());
      });
      
      DDRecycleGroup(ezdata.Temp.g);
      DDRecycleGroup(ezdata.Temp.dg);
      ezdata.Temp.destroy();
      DDQuitTim();
     });
     
     DDQuitTim();
    });
    
    
    DDQuitTim();
   });
  
   return false;
  }));
 
        t = null;
    }
}
//! endzinc


[B]

Frostmourne Impale

Shoots a wave of dark blades which damage any unit who comes in range and when they are hit they will be drastically slowed for short amount of time.


JASS:
[/B]
//TESH.scrollpos=15
//TESH.alwaysfold=0
//**************************************************************************************
//                              Installation:
//
// - 1. Copy this trigger and "DD Library" to your map
// - 2. Go to Import Manager (F12) and extract BTNDarkTouch.blp and its DISBTN version
//      sword_create.wav, sword_disappere.wav, sword_cut.wav and sword_start.wav
//      Frostmourne.mdx and DarkRitualTarget.mdx
// - 3. Import all of this to your map and set ther path to as you can see here (in my map)
// - 4. Go to Object Manager (F6) and copy "Frostmourne Impale Slow(Dummy)" ability and
//      main hero ability "Frostmourne Impale". When you are pasting them to your map make sure you
//      match there rawcodes with ones below
// - 5. If you want different raw codes edit the below as well
// - 6. Made on Warcraft III v1.30
// - 7. Edit data below to your own will and enjoy the spell
//
//
//**************************************************************************************

//! zinc
library FrostmourneImpale requires DDLib
{

 // *****************************************************************************************
 //        === Main Data ===
 // *****************************************************************************************
 
    // This is the raw code of the spell 'Frostmourne Impale'
    // Default: 'Drkt'
    constant integer      ABILITY_FROSTMOURNE_IMPALE       = 'Drkt';
    // This is the raw code of the sword 'Unit'
    // Default: 'drks'
    //constant integer      DUMMY_SWORD_RAWCODE        = 'drks';
    // This is the raw code of 'Frostmourne Impale Slow (dummy)' ability
    // Default: 'dtsd'
    constant integer      DUMMY_SLOW_RAWCODE         = 'dtsd';
 // Issue order for 'DUMMY_SLOW_RAWCODE' ability
 // Default: "slow"
    constant string       DUMMY_SLOW_ISSUEORDER        = "slow";
 // How offten are swords created, one after another
    // Default: 0.2
    constant real       SWORD_CREATION_INTERVAL       = 0.2;
 // Distance from caster and closest sword
 // Default: 250.
    constant real       SWORD_CREATION_OFFSET_FROM_CASTER    = 250.;
 // Distance from sword to sword
 // Default: 70.
    constant real       SWORD_CREATION_OFFSET_FROM_SWORD    = 70.;
 // Time it takes for sword to launch
 // Default: 1.
 constant real      SWORD_CREATE_LAUNCH_DURATION     = 1.;
 // Height of sword
 // Default: 110.
 constant real       SWORD_HEIGHT          = 110.;
 // Collision area around the sword, if units are found within it, they are hit
 // Default: 60.
 constant real       SWORD_COLLISION_SIZE       = 60.;
 // Sword creation start transparency / Sword disappear end transparency
 // Default: 00
 constant integer      SWORD_CREATE_START_ALPHA      = 00;
 // Sword creation end transparency / Sword disappear start transparency
 // Default: 255
 constant integer      SWORD_CREATE_END_ALPHA       = 255;
 // Time it takes for sword to appear
 // Default: 0.9
 constant real      SWORD_CREATE_FADE_DURATION      = .9;
 // Time it takes for sword to disappear
 // Default: 2.5
 constant real      SWORD_DISAPPEAR_DURATION      = 2.5;
 // Disappearing speed of sword
 // Default: 100.
 constant real      SWORD_DISAPPEAR_MOVE_SPEED      = 100.;
 
 // *****************************************************************************************
 //        === Effect ===
 // *****************************************************************************************
 
 // This is the file path to sword model
    // Default: "Spells\\FrostmourneImpale\\Frostmourne.mdx"
    constant string       SWORD_MODEL_PATH         = "Spells\\FrostmourneImpale\\Frostmourne.mdx";
 // This is size/scaling of sword
    // Default: 1.
    constant real       SWORD_MODEL_SIZE         = 1.;
    // This is trail effect missile of each sword
    // Default: "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl"
    constant string       SWORD_AFTER_EFFECT_SFX        = "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdx";
 // Appear and disappear sfx on sword
 // Default: "Spells\\FrostmourneImpale\\DarkRitualTarget.mdx"
    constant string       SWORD_CREATE_SFX         = "Spells\\FrostmourneImpale\\DarkRitualTarget.mdx";
 // Trail effect and appear/disappear effect height
 // Default: 60.
    constant real       SWORD_CREATE_SFX_HEIGHT       = 60.;
 // Trail effect and appear/disappear effect size
 // Default: 0.4
    constant real       SWORD_CREATE_SFX_SIZE        = .4;
 
    // Blood effect upon sword hit
    // Default: "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
    constant string       BLOOD_EFFECT          = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl";
 
 // *****************************************************************************************
 //        === Sound ===
 // *****************************************************************************************
 
 // Sound path of sword creation
    // Default: "Custom\\Spells\\Dark Torture\\sword_create.wav"
    constant string       SWORD_CREATE_SOUND_PATH       = "Custom\\Spells\\Frostmourne Impale\\sword_create.wav";
 constant real       SWORD_CREATE_SOUND_PATH_VOL      = 55.;
    // Sound path of sword launch
    // Default: "Custom\\Spells\\Dark Torture\\sword_start.wav"
    constant string       SWORD_SOUND_START_PATH        = "Custom\\Spells\\Frostmourne Impale\\sword_start.wav";
 constant real       SWORD_SOUND_START_PATH_VOL       = 80.;
    
    // Sound path of sword hiting the target
    // Default: "Custom\\Spells\\Dark Torture\\sword_hit.wav"
    constant string       SWORD_HIT_PATH          = "Custom\\Spells\\Frostmourne Impale\\sword_cut.wav";
 constant real       SWORD_HIT_PATH_VOL        = 70.;
    // Sound of swords disappearing
    // Default: "Custom\\Spells\\Dark Torture\\sword_disappere.wav"
    constant string       SWORD_DISAPPEAR_PATH        = "Custom\\Spells\\Frostmourne Impale\\sword_disappere.wav";
 constant real       SWORD_DISAPPEAR_PATH_VOL       = 70.;
 
 // This is max sound hear range
    // Default: 3500.
    constant real       SOUND_MAX_DISTANCE         = 3500.;
    
 // *****************************************************************************************
 //        === Level Data ===
 // *****************************************************************************************
 
 // --------------------------------------------------------------
    // This variables are not supposed to be modified here, modify them below in Setup function
    integer    MAX_SWORD_COUNT[];
    real     SWORD_MAX_TRAVEL_DISTANCE[];
    real     SINGLE_SWORD_DAMAGE[];
    real     SWORD_MOVE_SPEED[];
 // --------------------------------------------------------------

 // This part of code is used to define spell constants per level
 function FrostmourneImpale_Setup() {
  // Default: Level 1 = 8
  // Default: Level 2 = 9
  // Default: Level 3 = 10
  MAX_SWORD_COUNT[01] = 8;
  MAX_SWORD_COUNT[02] = 9;
  MAX_SWORD_COUNT[03] = 10;
  
  // Default: Level 1 = 125.
  // Default: Level 2 = 220.
  // Default: Level 3 = 300.
  SINGLE_SWORD_DAMAGE[01] = 125.;
  SINGLE_SWORD_DAMAGE[02] = 220.;
  SINGLE_SWORD_DAMAGE[03] = 300.;
  
  // Default: Level 1 = 1250.
  // Default: Level 2 = 1350.
  // Default: Level 3 = 1500.
  SWORD_MAX_TRAVEL_DISTANCE[01] = 1250.;
  SWORD_MAX_TRAVEL_DISTANCE[02] = 1350.;
  SWORD_MAX_TRAVEL_DISTANCE[03] = 1500.;
  
  // Default: Level 1 = 900.
  // Default: Level 2 = 1100.
  // Default: Level 3 = 1200.
  SWORD_MOVE_SPEED[01] = 900.;
  SWORD_MOVE_SPEED[02] = 1100.;
  SWORD_MOVE_SPEED[03] = 1200.;
 }
 
 // *****************************************************************************************
 //        === Unit Damage Filter  ===
 // *****************************************************************************************
 
 function FrostmourneImpaleUnitFilter(unit f, player owner) -> boolean {
  return !IsUnitType(f, UNIT_TYPE_STRUCTURE)   &&
      !IsUnitType(f, UNIT_TYPE_MECHANICAL)   &&
      !IsUnitType(f, UNIT_TYPE_DEAD)    &&
      !IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE)  &&
      !IsUnitType(f, UNIT_TYPE_FLYING)    &&
      !BlzIsUnitInvulnerable(f)     &&
      IsUnitEnemy(f, owner);
 }
 
 // ==========================================================================================
 //        *** Spell Code ***
 // ==========================================================================================
 
 struct sword {
  ddeffect s;
  player p;
  unit dmy;
  ddeffect trail;
  real x, y;
  real vx, vy;
  real dist, spd;
  integer lvl;
  group g;
  boolean disappear_off;
  
  static player Owner = null;
  
  static method create(real px, real py, real rad, player owner, integer abilLvl) -> thistype {
   thistype this = allocate();
   real tz = DDTerrZ(px, py);
   
   g = DDLoadGroup();
   s = ddeffect.createZ(SWORD_MODEL_PATH, px, py, SWORD_HEIGHT + tz, rad, SWORD_MODEL_SIZE);
   s.Fade(SWORD_CREATE_START_ALPHA/2.55, SWORD_CREATE_END_ALPHA/2.55, SWORD_CREATE_FADE_DURATION);
   p = owner;
   //s = CreateUnit(owner, DUMMY_SWORD_RAWCODE, px, py, rad*bj_RADTODEG);
   //SetUnitFlyHeight(s, SWORD_HEIGHT, 0.);
   lvl = abilLvl;
   x = px; y = py;
   vx = DD_INTERVAL * SWORD_MOVE_SPEED[lvl] * Cos(rad);
   vy = DD_INTERVAL * SWORD_MOVE_SPEED[lvl] * Sin(rad);
   dist = SWORD_MAX_TRAVEL_DISTANCE[lvl];
   spd = DD_INTERVAL*SWORD_MOVE_SPEED[lvl];
   disappear_off = true;
   trail = ddeffect.createZ(SWORD_AFTER_EFFECT_SFX, x, y, SWORD_HEIGHT + tz, rad, SWORD_CREATE_SFX_SIZE);
   
   DDGenericSound(SWORD_CREATE_SOUND_PATH, SWORD_CREATE_SOUND_PATH_VOL, px, py, SOUND_MAX_DISTANCE, 1.);
   //DDFadeUnit(s, SWORD_CREATE_START_ALPHA, SWORD_CREATE_END_ALPHA, SWORD_CREATE_FADE_DURATION);
   ddeffect.createZ(SWORD_CREATE_SFX, px, py, SWORD_CREATE_SFX_HEIGHT + tz, rad, SWORD_CREATE_SFX_SIZE).destroyx(SWORD_DISAPPEAR_DURATION);
   
   return this;
  }
  
  method SwordLaunch() {
   DDGenericSound(SWORD_SOUND_START_PATH, SWORD_SOUND_START_PATH_VOL, x, y, SOUND_MAX_DISTANCE, 1.);
   
   DDStartTim(DD_INTERVAL, true, this, function() {
    sword this = DDTimData();
    unit fg;
    
    x += vx; y += vy;
    s.Position(x, y);
    trail.Position(x, y);
    /*SetUnitX(s, x);
    SetUnitY(s, y);
    trail.X = x;
    trail.Y = y;*/
    
    if (g != null) {
     if (IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)) {
      DDRecycleGroup(g);
      dist = 0.;
      g = null;
      return;
     }
     
     Owner = p;
     GroupEnumUnitsInRange(g, x, y, SWORD_COLLISION_SIZE, Filter(function() -> boolean {
      return FrostmourneImpaleUnitFilter(GetFilterUnit(), Owner);
     }));
     
     fg = FirstOfGroup(g);
     if (fg != null) {
      dmy = DDLoadSpellDummy(Owner, x, y, DUMMY_SLOW_RAWCODE, 01);
      IssueTargetOrder(dmy, DUMMY_SLOW_ISSUEORDER, fg);
      UnitDamageTarget(dmy, fg, SINGLE_SWORD_DAMAGE[lvl], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_METAL_HEAVY_STAB);
      DestroyEffect(AddSpecialEffectTarget(BLOOD_EFFECT, fg, "origin"));
      DDGenericSound(SWORD_HIT_PATH, SWORD_HIT_PATH_VOL, x, y, SOUND_MAX_DISTANCE, 1.); 
      DDRecycleGroup(g);
      dist = 0.;
      g = null;
     }
     fg = null;
    }
    
    dist -= spd;
    if (dist < 0.) {
     if (disappear_off) {
      trail.destroy();
      trail = ddeffect.createZ(SWORD_CREATE_SFX, x, y, SWORD_CREATE_SFX_HEIGHT+DDTerrZ(x, y), trail.Facing, SWORD_CREATE_SFX_SIZE);
      //trail.Z = SWORD_HEIGHT;
      //trail.Pitch = 00;
      DDGenericSound(SWORD_DISAPPEAR_PATH, SWORD_DISAPPEAR_PATH_VOL, x, y, SOUND_MAX_DISTANCE, 1.);
      s.Fade(SWORD_CREATE_END_ALPHA/2.55, SWORD_CREATE_START_ALPHA/2.55, SWORD_DISAPPEAR_DURATION);
      //DDFadeUnit(s, SWORD_CREATE_END_ALPHA, SWORD_CREATE_START_ALPHA, SWORD_DISAPPEAR_DURATION);
      dist = SWORD_DISAPPEAR_MOVE_SPEED*SWORD_DISAPPEAR_DURATION;
      vx = DD_INTERVAL*SWORD_DISAPPEAR_MOVE_SPEED*vx/spd;
      vy = DD_INTERVAL*SWORD_DISAPPEAR_MOVE_SPEED*vy/spd;
      spd = DD_INTERVAL*SWORD_DISAPPEAR_MOVE_SPEED;
      disappear_off = false;
      
      if (g != null) {
       DDRecycleGroup(g);
       g = null;
      }
     } else {
      if (dmy != null) {
       UnitRemoveAbility(dmy, DUMMY_SLOW_RAWCODE);
       DDRecycleDummy(dmy);
       dmy = null;
      }
      trail.destroy();
      s.destroy();
      //RemoveUnit(s);
      //s = null;
      destroy();
      DDQuitTim();
     }
    }
   });
  }
 }
 
 struct data {
  unit u;
  real x, y;
  real tx, ty;
  integer lvl;
  real rad;
  real ox, oy;
  integer rnd_mx_n;
  integer rnd[32];
 }
 
 function onInit() {
  trigger t = CreateTrigger();
  
  FrostmourneImpale_Setup();
  
  TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
  TriggerAddCondition(t, Condition(function() -> boolean {
   data d;
   integer i;
   
   if (GetSpellAbilityId() != ABILITY_FROSTMOURNE_IMPALE)
    return false;
   
   d = data.create();
   d.u = GetTriggerUnit();
   d.x = GetWidgetX(d.u); d.y = GetWidgetY(d.u);
   d.tx = GetSpellTargetX(); d.ty = GetSpellTargetY();
   d.lvl = GetUnitAbilityLevel(d.u, ABILITY_FROSTMOURNE_IMPALE);
   d.rad = Atan2(d.y-d.ty, d.x-d.tx);
   d.ox = d.x + SWORD_CREATION_OFFSET_FROM_CASTER * Cos(d.rad);
   d.oy = d.y + SWORD_CREATION_OFFSET_FROM_CASTER * Sin(d.rad);
   d.rnd_mx_n = MAX_SWORD_COUNT[d.lvl];
   d.rad += bj_PI/2.;
   for(i=00; i < MAX_SWORD_COUNT[d.lvl]; i+=01) {
    d.rnd[i] = i-(MAX_SWORD_COUNT[d.lvl]/2);
   }
   
   DDStartTim(SWORD_CREATION_INTERVAL, true, d, function() {
    data d = DDTimData();
    sword s;
    integer rnd_n = GetRandomInt(00, d.rnd_mx_n-01);
    
    s = sword.create(d.ox + SWORD_CREATION_OFFSET_FROM_SWORD*d.rnd[rnd_n] * Cos(d.rad),
         d.oy + SWORD_CREATION_OFFSET_FROM_SWORD*d.rnd[rnd_n] * Sin(d.rad),
         (d.rad+(bj_PI/2)),
         GetOwningPlayer(d.u),
         d.lvl);
    
    DDStartTim(SWORD_CREATE_LAUNCH_DURATION, false, s, function() {
     sword(DDTimData()).SwordLaunch();
     DDQuitTim();
    });
    
    d.rnd_mx_n -= 01;
    d.rnd[rnd_n] = d.rnd[d.rnd_mx_n];
    
    if (d.rnd_mx_n == 00) {
     d.destroy();
     DDQuitTim();
    }
    
   });
   
   return false;
  }));
 }

}
//! endzinc
[B]

Frost Eruption

Sends an orb of frost at targt point, on landing explodes dealing damage and freezing all enemy ground units, while air units get slowed.


JASS:
//TESH.scrollpos=0
//TESH.alwaysfold=0
//**************************************************************************************
//                              Installation:
//
//
// - 1. Copy this trigger and DD Library to your map.
// - 2. Go to Import Manager (F12) and extract icons: BTNCRFrostShock.blp and its DISBTN version
//      sounds: fe_start.mp3, fe_explode1.mp3 and fe_explode2.mp3
//      Models: FrozenOrb.mdx, Frost2.mdx, FreezingRing.mdx, BlizzardEruption.mdx and (dummy.mdx -> if not from before)
// - 3. Import all of this to your map and set there path to as you can see here (in my map)
// - 4. Go to Object Manager (F6) and copy:
//      Air Freeze (Dummy) ability, Frost Eruption buff and
//      main ability Frost Eruption. When you are pasting them to your map make sure you
//      type the following rawcodes:
//      Frost Eruption:         'Feru'
//      Air Freeze (Dummy):     'Afre'
//      Frost Eruption {Buff}:  'Bfer'
// - 5. If you want different raw codes edit the below as well:
// - 6. Made on Warcraft III v1.30
// - 7. Edit data below to your own will and enjoy the spell:
//
//**************************************************************************************

//! zinc
library FrostEruption requires DDLib
{


    // The raw code of the spell Frost Eruption
    // Default: 'Feru'
    constant  integer    ABILITY_FROST_ERUPTION        = 'Feru';
 // This is scale / size of main orb
    // Default: 1.32
    constant  real     ORB_SCALE            = 1.32;
    constant  real     ORB_INITIAL_Z           = 70.;
    constant  real     ORB_MAX_HEIGHT           = 350.;
    constant  real     ORB_TRAVEL_TIME          = 2.;
 
    // With this ability air units are slowed
    // Default: 'Afre'
    constant  integer    ABILITY_AIR_FREEZE          = 'Afre';
    constant  integer    BUFF_AIR_FREEZE           = 'Bfer';
    // This is orb model path
    // Default: "Spells\\FrostEruption\\FrozenOrb.mdl"
    constant  string     ORB_MODEL_PATH           = "Spells\\FrostEruption\\FrozenOrb.mdx";
    // Main frost eruption effect
    // Default: "Spells\\FrostEruption\\BlizzardEruption.mdl"
    constant  string     ORB_ERUPTION_EFFECT         = "Spells\\FrostEruption\\BlizzardEruption.mdx";
 // Default: 2.
    constant  real     ORB_ERUPTION_EFFECT_SIZE       = 2.;
 // Default: 70.
    constant  real     ORB_ERUPTION_EFFECT_ANIMATION_SPEED     = 70.;
    // Frost Eruptions extra explosion effect
    // Default: "Spells\\FrostEruption\\FreezingRing.mdl"
    constant  string     ORB_EXPLOSION_EFFECT         = "Spells\\FrostEruption\\FreezingRing.mdx";
 // Default: 1.6
    constant  real     ORB_EXPLOSION_EFFECT_SIZE       = 1.6;
 // Default: 55.
    constant  real     ORB_EXPLOSION_EFFECT_ANIMATION_SPEED    = 55.;
    // Ground units freezed model path
    // Default: "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl"
    constant  string     FREEZE_EFFECT           = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdx";
    // This is orb's trail effect
    // Default: "Spells\\FrostEruption\\Frost2.mdx"
    constant  string     TRAIL_MODEL_PATH          = "Spells\\FrostEruption\\Frost2.mdx";
 // This is orb's trail effect size
    // Default: 1.
 constant  real     TRAIL_SCALE           = 1.;
    // Sound file on load (on spell cast)
    // Default: "Custom\\Spells\\Frost Eruption\\fe_start.mp3"
    constant  string     SPELL_START_SOUND          = "Custom\\Spells\\Frost Eruption\\fe_start.mp3";
 constant  real     SPELL_START_SOUND_VOL         = 75.;
 constant  real     SOUND_MAX_DISTANCE          = 3500.;
 
    // Sound file's on explosion
    // Default: "Custom\\Spells\\Frost Eruption\\fe_explode1.mp3"    
    constant  string     SPELL_EXPLODE_SOUND_1         = "Custom\\Spells\\Frost Eruption\\fe_explode1.mp3";
 constant  real     SPELL_EXPLODE_SOUND_VOL        = 75.; // Both 1 and 2 sounds volume
    // Default: "Custom\\Spells\\Frost Eruption\\fe_explode2.mp3"
    constant  string     SPELL_EXPLODE_SOUND_2         = "Custom\\Spells\\Frost Eruption\\fe_explode2.mp3";
    
    // Terrain deformation depth
    // Default: 180.
    constant  real     EXPLOSION_DEAPTH          = 180.;
    // Terrain deformatiob timeout
    // Default: 0.66
    constant  real     TERRAIN_DEFORMATION_DURATION       = 0.66;
    // Cameras power magnitude
    // Default: 20.
    constant  real     CAMERA_MAGNITUDE          = 20.;
 // Cameras power velocity
    // Default: 1800.
    constant  real     CAMERA_VELOCITY          = 1800.;
    // Camera noise duration
    // Default: 1.85
    constant  real     CAMERA_NOISE_DURATION         = 1.85;
    // How much time will orb need until reaching target point
    // Default: 1.5
    constant  real     ORB_DURATION           = 1.5;
 
 // Alter terrain upon explosion?
 // Default: true
 constant boolean    USE_TERRAIN_TYPE_MODIFICATION      = true;
 // Default: 'Iice'
    constant  integer    TERRAIN_TEXTURE_ID         = 'Iice';
 // Default: 01 / square
    constant  integer    TERRAIN_TEXTURE_SHAPE        = 01;
 // Default: 17
    constant  integer    TERRAIN_TEXTURE_VARIATIONS       = 17;
 // Default: 7.
    constant  real     TERRAIN_TEXTURE_DURATION       = 7.;
 
 
 
 
    
    // Do not edit this variables here edit then below
    real   FE_RADIUS[];
    real   FE_DAMAGE[];
    real   FE_MAX_DAMAGE[];
    real   FE_DURATION[];

 // Edit this to match your level data
 function SetupFrostEruption() {
  // Spells damage:
  // Default: 130 / 215 / 290
  FE_DAMAGE[01]    = 130.;
  FE_DAMAGE[02]    = 215.;
  FE_DAMAGE[03]    = 290.;
  
  // Spells radius:
  // Default: 500 / 515 / 540
  FE_RADIUS[01]    = 500.;
  FE_RADIUS[02]    = 515.;
  FE_RADIUS[03]    = 540.;
  
  // Spells max damage:
  // Default: 700 / 1300 / 1950
  FE_MAX_DAMAGE[01]   = 700.;
  FE_MAX_DAMAGE[02]   = 1300.;
  FE_MAX_DAMAGE[03]   = 1950.;
  
  // Spells ground units freeze duration:
  // Default: 4 / 4.5 / 5.25
  FE_DURATION[01]   = 4.;
  FE_DURATION[02]   = 4.5;
  FE_DURATION[03]   = 5.25;
 }

 // Main damage filter
 function FE_UnitFilter(unit f, player owner) -> boolean {
  return IsUnitEnemy(f, owner)        &&
      !IsUnitType(f, UNIT_TYPE_STRUCTURE)     &&
      !IsUnitType(f, UNIT_TYPE_MECHANICAL)    &&
      !IsUnitType(f, UNIT_TYPE_DEAD)     &&
      !BlzIsUnitInvulnerable(f)      &&
      !IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE);
 }
// ================================================================================
// ******                                                                   ******
//              Do not edit below if you don't know jass
// ******                                                                   ******
// ================================================================================
 
 constant integer TT_MAX_ARRAY = 64;
 
 struct terrtype {
  integer typ[TT_MAX_ARRAY], var[TT_MAX_ARRAY];
  boolean blighted[TT_MAX_ARRAY];
  real x, y, aoe;
  integer n=00;
  group g;
  
  static integer BlightAbilId[];
 }
 
 function ModifieTerrainType(real x, real y, real aoe, terrtype changeToTT) -> terrtype {
  real tx, ty, max_x;
  integer n=00;
  terrtype tt;
  
  if (changeToTT == p_null) {
   tt = terrtype.create();
   tt.g = DDLoadGroup();
   GroupEnumUnitsInRange(tt.g, x, y, aoe+960., function() -> boolean {
    unit u = GetFilterUnit();
    if (GetUnitAbilityLevel(u, 'Abgs') == 01) {
     terrtype.BlightAbilId[H2ID(u)] = 'Abgs';
     UnitRemoveAbility(u, 'Abgs');
     u = null;
     return true;
    } else if (GetUnitAbilityLevel(u, 'Abgl') == 01) {
     terrtype.BlightAbilId[H2ID(u)] = 'Abgs';
     UnitRemoveAbility(u, 'Abgl');
     u = null;
     return true;
    }
    u = null;
    return false;
   });
   
   tt.x = x; tt.y = y; tt.aoe = aoe;
   for(ty=-aoe; ty < aoe; ty+=bj_CELLWIDTH) {
    max_x = SquareRoot((aoe*aoe) - (ty*ty));
    for(tx=-max_x; tx < max_x; tx+=bj_CELLWIDTH) {
     tt.blighted[tt.n] = IsPointBlighted(x+tx, y+ty);
     if (!(tt.blighted[tt.n])) {
      tt.typ[tt.n] = GetTerrainType(x+tx, y+ty);
      tt.var[tt.n] = GetTerrainVariance(x+tx, y+ty);
     } else
      SetBlightPoint(Player(00), x+tx, y+ty, false);
     tt.n += 01;
     SetTerrainType(x+tx, y+ty, TERRAIN_TEXTURE_ID, GetRandomInt(00, TERRAIN_TEXTURE_VARIATIONS), 01, TERRAIN_TEXTURE_SHAPE);
    }
   }
   return tt;
  }
  
  tt = changeToTT;
  x = tt.x; y = tt.y; aoe = tt.aoe;
  for(ty=-aoe; ty < aoe; ty+=bj_CELLWIDTH) {
   max_x = SquareRoot((aoe*aoe) - (ty*ty));
   for(tx=-max_x; tx < max_x; tx+=bj_CELLWIDTH) {
    if (!(tt.blighted[n]))
     SetTerrainType(x+tx, y+ty, tt.typ[n], tt.var[n], 01, TERRAIN_TEXTURE_SHAPE);
    else
     SetBlightPoint(Player(00), x+tx, y+ty, true);
    n += 01;
   }
  }
  
  ForGroup(tt.g, function() {
   unit u = GetEnumUnit();
   UnitAddAbility(u, terrtype.BlightAbilId[H2ID(u)]);
   u = null;
  });
  DDRecycleGroup(tt.g);
  tt.destroy();
  return p_null;
 }
 
 // --------------------------------------------------------------------------------------------
 
 effect   FBEffect[];

 struct orb {
  ddeffect o, ot;
  real vx, vy, tz;
  real dist, mxDist, a;
  real spd;
  integer lvl;
  player owner;
  unit u;
  real dmg;
  group g;
  unit dmy;
  integer cnt=00;
  terrtype tt;
  
  static method create(unit u, real x, real y, real tx, real ty, player owner, integer lvl) -> thistype {
   thistype this = allocate();
   
   real rad = Atan2(ty-y, tx-x);
   mxDist = SquareRoot( Pw_2(x-tx) +  Pw_2(y-ty) ) / 2.;
   dist = -mxDist;
   a = -ORB_MAX_HEIGHT/Pw_2(mxDist);
   tz = DDTerrZ(x, y);
   o = ddeffect.createZ(ORB_MODEL_PATH, x, y, ORB_INITIAL_Z+tz,rad, ORB_SCALE);
   ot = ddeffect.createZ(TRAIL_MODEL_PATH, x, y, ORB_INITIAL_Z+tz, rad, TRAIL_SCALE);
   //o.Z = ORB_INITIAL_Z;
   spd = DD_INTERVAL * (2.*mxDist / ORB_TRAVEL_TIME);
   vx =  spd * Cos(rad);
   vy =  spd * Sin(rad);
   //tz = o.WZ;
   this.owner = owner;
   this.lvl = lvl;
   this.u = u;
   
   return this;
  }
  
  method LaunchOrb() {
   DDStartTim(DD_INTERVAL, true, this, function() {
    orb this = DDTimData();
    ddeffect oe;
    effect e;
    
    dist += spd;
    o.PositionZ(o.X + vx, o.Y + vy, a*Pw_2(dist) + ORB_MAX_HEIGHT+tz);
    ot.PositionZ(o.X, o.Y, o.Z);
    /*o.X += vx; o.Y += vy;
    o.Z = (tz-o.WZ) + a*Pw_2(dist) + ORB_MAX_HEIGHT;
    ot.X = o.X; ot.Y = o.Y; ot.Z = o.Z;*/
    
    if (dist > mxDist) {
     g = DDLoadGroup();
     DDGFilterDataSet(this);
     GroupEnumUnitsInRange(g, o.X, o.Y, FE_RADIUS[lvl], Filter(function() -> boolean {
      if (FE_UnitFilter(GetFilterUnit(), orb(DDGFilterData()).owner)) {
       orb(DDGFilterData()).cnt += 01;
       return true;
      }
      return false;
     }));
     
     if (cnt > 00) {
      dmg = FE_MAX_DAMAGE[lvl] / cnt; // division by zero?
      if (dmg > FE_DAMAGE[lvl])
       dmg = FE_DAMAGE[lvl];
     
      ForGroup(g, function() {
       orb o = DDGFilterData();
       unit e = GetEnumUnit();
       UnitDamageTarget(o.u, e, o.dmg, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null);
       if (!IsUnitType(e, UNIT_TYPE_FLYING) && !IsUnitType(e, UNIT_TYPE_DEAD) && FBEffect[H2ID(e)] == null) {
        FBEffect[H2ID(e)] = AddSpecialEffectTarget(FREEZE_EFFECT, e, "origin");
        PauseUnit(e, true);
       }
       e = null;
      });
      
      dmy = DDLoadSpellDummy(owner, o.X, o.Y, ABILITY_AIR_FREEZE, lvl);
      UnitRemoveAbility(dmy, 'Aloc');
      IssueTargetOrder(dmy, "frostnova", dmy);
      
      DDStartTim(FE_DURATION[lvl]-.05, false, this, function() {
       orb o = DDTimData();
       
       UnitAddAbility(o.dmy, 'Aloc');
       UnitRemoveAbility(o.dmy, ABILITY_AIR_FREEZE);
       DDRecycleDummy(o.dmy);
       
       ForGroup(o.g, function() {
        unit e = GetEnumUnit();
        if (!IsUnitType(e, UNIT_TYPE_FLYING) /*&& GetUnitAbilityLevel(e, BUFF_AIR_FREEZE) != 00*/) {
         PauseUnit(e, false);
         UnitRemoveAbility(e, BUFF_AIR_FREEZE);        
         DestroyEffect(FBEffect[H2ID(e)]);
         FBEffect[H2ID(e)] = null;
        }
        e = null;
       });
       DDRecycleGroup(o.g);
       o.destroy();
       DDQuitTim();
      });
     } else
      DDRecycleGroup(g);
     
     static if (USE_TERRAIN_TYPE_MODIFICATION)
      DDStartTim(TERRAIN_TEXTURE_DURATION, false, ModifieTerrainType(o.X, o.Y, FE_RADIUS[lvl]-bj_CELLWIDTH, p_null), function() {
       ModifieTerrainType(0., 0., 0., terrtype( DDTimData() ));
       DDQuitTim();
      });
     TerrainDeformCrater(o.X, o.Y, FE_RADIUS[lvl], EXPLOSION_DEAPTH, R2I(TERRAIN_DEFORMATION_DURATION*1000.), false);
     DDCameraSetSourceNoiseForPlayers(o.X, o.Y, CAMERA_MAGNITUDE, CAMERA_VELOCITY, SOUND_MAX_DISTANCE, CAMERA_NOISE_DURATION);
     oe = ddeffect.create(ORB_ERUPTION_EFFECT, o.X, o.Y, GetRandomReal(0., bj_PI*2.), ORB_ERUPTION_EFFECT_SIZE)/*.destroyx(2.)*/;
     oe.Animation(ANIM_TYPE_BIRTH);
     oe.AnimationSpeed(ORB_ERUPTION_EFFECT_ANIMATION_SPEED);
     oe.destroyx(2.*(ORB_ERUPTION_EFFECT_ANIMATION_SPEED/100.));
     //DestroyEffectTimed(AddSpecialEffect(ORB_ERUPTION_EFFECT, o.X, o.Y), 3.);
     e = AddSpecialEffect(ORB_EXPLOSION_EFFECT, o.X, o.Y);
     BlzSetSpecialEffectScale(e, ORB_EXPLOSION_EFFECT_SIZE);
     BlzSetSpecialEffectTimeScale(e, ORB_EXPLOSION_EFFECT_ANIMATION_SPEED/100.);
     DestroyEffect(e); e = null;
     if (GetRandomInt(00, 01) == 01)
      DDGenericSound(SPELL_EXPLODE_SOUND_1, SPELL_EXPLODE_SOUND_VOL, o.X, o.Y, SOUND_MAX_DISTANCE, 1.);
     else
      DDGenericSound(SPELL_EXPLODE_SOUND_2, SPELL_EXPLODE_SOUND_VOL, o.X, o.Y, SOUND_MAX_DISTANCE, 1.);
     
     //ot.X = DDMaxX; ot.Y = DDMaxY;
     o.destroy();
     ot.destroy();
     DDQuitTim();
    }
    
   });
  }
 }

 //====================================================================================
 // Main Setup Function For FE
 function onInit() {
  // Load locals...
  trigger tg = CreateTrigger();
  
  // Setup user spell
  SetupFrostEruption();
  
  // Register trigger events
  TriggerRegisterAnyUnitEventBJ(tg, EVENT_PLAYER_UNIT_SPELL_EFFECT);
  TriggerRegisterAnyUnitEventBJ(tg, EVENT_PLAYER_UNIT_DEATH);
  TriggerAddCondition(tg, Condition(function() -> boolean {
   unit u;
   real x, y,
     tx, ty;
   orb o;
   
   if (GetTriggerEventId() == EVENT_PLAYER_UNIT_DEATH) {
    u = GetTriggerUnit();
    if (FBEffect[H2ID(u)] != null) {
     PauseUnit(u, false);
     DestroyEffect(FBEffect[H2ID(u)]);
     FBEffect[H2ID(u)] = null;
    }
    u = null;
    return false;
   }
   
   if (GetSpellAbilityId() != ABILITY_FROST_ERUPTION)
    return false;
   
   u = GetTriggerUnit();
   x = GetWidgetX(u); y = GetWidgetY(u);
   tx = GetSpellTargetX(); ty = GetSpellTargetY();
   
   
   o = orb.create(u, x, y, tx, ty, GetOwningPlayer(u), GetUnitAbilityLevel(u, ABILITY_FROST_ERUPTION));
   DDGenericSound(SPELL_START_SOUND, SPELL_START_SOUND_VOL, SOUND_MAX_DISTANCE, x, y, 1.);
   o.LaunchOrb();
   
   u = null;
   return false;
  }));

 }

}
//! endzinc[/B]

[B]

Algid Aura

Slowes down units around caster for x seconds and dealing slight damage every x seconds (pulse width), while chilling lasts less time.


JASS:
[/B]
//TESH.scrollpos=24
//TESH.alwaysfold=0
//**************************************************************************************
//                              Installation:
//
//
// - 1. Made on Warcraft III v1.30
// - 2. Copy this trigger and DD Library to your map.
// - 3. Go to Import Manager (F12) and extract icons: BTNAlgirAura.blp and its: DISBTN, PAS and DISPAS version
// - 4. Import all of this to your map and set there path to as you can see here (in my map)
// - 5. Go to Object Manager (F6) and copy:
//  abilities: Algid Aura (Dummy) and main ability Algid Aura
//  buffs: Algid Aura (Buff) and Algid Aura (Ability Buff)
//  When you are pasting them to your map make sure you
//      type the following rawcodes or modify them below:
//      Algid Aura:         'Algd'
//      Algid Aura (Dummy):     'Aldm'
//      Algid Aura (Buff):   'Alga'
//      Algid Aura (Ability Buff): 'AlgB'
// - 6. Edit data below to your own will and enjoy the aura:
//
//**************************************************************************************

//! zinc
library AlgidAura requires DDLib
{

 // *****************************************************************************************
 //        === Main Data ===
 // *****************************************************************************************
 
    // Default: 'Algd'
    constant  integer    ABILITY_ALGID_AURA         = 'Algd';
    // Default: 'Aldm'
    constant  integer    ABILITY_ALGID_AURA_DUMMY       = 'Aldm';
 // Default: "frostnova"
    constant  string     ABILITY_ALGID_AURA_DUMMY_ORDER_ID     = "frostnova";
 
 
 real AA_PULSE_WIDTH[];
 
 // *****************************************************************************************
 
 // Edit this to match your level data
 function SetupAlgidAura() {
  // Spells damage:
  // Default: 5 / 5 / 4
  AA_PULSE_WIDTH[01]    = 5.;
  AA_PULSE_WIDTH[02]    = 5.;
  AA_PULSE_WIDTH[03]    = 4.;
 }
 
 // *****************************************************************************************
 
 timer  AATim[];
 
 struct data {
  unit u;
  unit d;
  
  static thistype  Data[];
 }

 //====================================================================================
 // Main Setup Function For FE
 function onInit() {
  // Load locals...
  trigger tg = CreateTrigger();
  
  // Setup user spell
  SetupAlgidAura();
  
  // Register trigger events
  TriggerRegisterAnyUnitEventBJ(tg, EVENT_PLAYER_HERO_SKILL);
  TriggerAddCondition(tg, Condition(function() -> boolean {
   unit u;
   integer id;
   data d;
   
   if (GetLearnedSkill() != ABILITY_ALGID_AURA)
    return false;
   
   u = GetTriggerUnit();
   id = H2ID(u);
   if (AATim[id] == null) {
    AATim[id] = CreateTimer();
    d = data.create();
    data.Data[H2ID(AATim[id])] = d;
    d.u = u; d.d = DDLoadDummy();
    UnitRemoveAbility(d.d, 'Aloc');
    SetUnitOwner(d.d, GetOwningPlayer(u), false);
    UnitAddAbility(d.d, ABILITY_ALGID_AURA_DUMMY);
   } else
    d = data.Data[H2ID(AATim[id])];
   SetUnitAbilityLevel(d.d, ABILITY_ALGID_AURA_DUMMY, GetLearnedSkillLevel());
   
   TimerStart(AATim[id], AA_PULSE_WIDTH[GetLearnedSkillLevel()], true, function() {
    data d = data.Data[H2ID(GetExpiredTimer())];
    
    if (!IsUnitType(d.u, UNIT_TYPE_DEAD)) {
     SetUnitX(d.d, GetWidgetX(d.u));
     SetUnitY(d.d, GetWidgetY(d.u));
     IssueTargetOrder(d.d, ABILITY_ALGID_AURA_DUMMY_ORDER_ID, d.d);
    }
   });
   
   u = null;
   return false;
  }));

 }

}
//! endzinc
[B]

Nature Blessing

Raises magic missiles from the ground, which travel at position of caster, exploding and protecting any ally unit with shield which reduces any taken damage, as well it increases n% hp regeneration per point of life missing.


JASS:
[/B]
//TESH.scrollpos=30
//TESH.alwaysfold=0
/*
 **********************************************************************************************************
 
          Installation:
  
  1) Copy this trigger and 'DD Library' to your map
  2) Copy Nature Blessing abilitie to your map
  3) Export and Import 'GaiaShield.mdx', 'GaiaMissile.mdx', 'NatureExplosion.mdx' sound from this map to yours
  4) Modify constants to your liking below
  5) Made on Warcraft III v1.30
 
 **********************************************************************************************************
*/

//! zinc
library NatureBlessing requires DDLib
{

  // This is the main raw code of ability Nature Blessing
  // Default: 'Nbls'
  constant integer   NATURE_BLESSING     = 'Nbls';
  
  // Natures shield effect model path
  // Default: "Spells\\NatureBlessing\\GaiaShield.mdx"
  constant string   NATURE_SHIELD_EFFECT   = "Spells\\NatureBlessing\\GaiaShield.mdx";
  
  // Natures missile effect model path
  // Default: "Spells\\NatureBlessing\\GaiaMissle.mdx"
  constant string   NATURE_MISSILE_EFFECT   = "Spells\\NatureBlessing\\GaiaMissle.mdx";
  
  // Natures explosion model effect path
  // Default: "Spells\\NatureBlessing\\NatureExplosion.mdx"
  constant string   NATURE_EXPLOSION_EFFECT   = "Spells\\NatureBlessing\\NatureExplosion.mdl";
  
  // Natures missile fire sound path (this sound is played when missiles start to move)
  // Default: "Abilities\\Spells\\NightElf\\Tranquility\\TranquilityTarget1.wav"
  constant string   NATURE_SHOOT_SOUND    = "Abilities\\Spells\\NightElf\\Tranquility\\TranquilityTarget1.wav";
  constant real   NATURE_SHOOT_SOUND_VOL   = 100.;
  constant real   NATURE_SHOOT_SOUND_PITCH  = 1.5;
  constant real   NATURE_SHOOT_SOUND_MAX_DISTANCE = 3500.;
  
  // Nature explosion sound file path (is played when nature explosion is caused)
  // Default: "Abilities\\Spells\\NightElf\\Tranquility\\Tranquility.wav"
  constant string   NATURE_EXPLOSION_SOUND   = "Abilities\\Spells\\NightElf\\Tranquility\\Tranquility.wav";
  constant real   NATURE_EXPLOSION_SOUND_VOL  = 90.;
  
  // This is number of nature missiles created
  // Default: 12
  constant integer   MISSILES_COUNT     = 12;
  // Default: 1.2
  constant real   MISSILE_SIZE     = 1.2;
  
  // This is min and max distance from caster to missiles start point
  // Default: 400 / 600
  constant real   MISSILE_MIN_DISTANCE   = 400.;
  constant real   MISSILE_MAX_DISTANCE   = 600.;
  
  // This is min and max finish height / caster position of missiles
  // Default: 75 / 400
  constant real   MISSILE_MIN_HEIGHT    = 40.;
  constant real   MISSILE_MAX_HEIGHT    = 400.;
  
  // This is missiles value which tells how much time they need to reach caster and how long it takse for them to manifest
  // Default: 0.75 / 0.5
  constant real   MISSILE_TRAVEL_TIME    = .9;
  constant real   MISSILE_BIRTH_TIME    = 0.5;
  
  // Default: 50
  constant real   MISSILE_INITIAL_HEIGHT   = 10.;
  
  // Default: 0.2 seconds
  constant real   HEAL_INTERVAL     = .2;
  // --------------------------------------------------------------
  // *** Do not edit level variables here edit them below ***
  real   EXPLOSION_AOE[];
  real   SHIELD_PROTECT[];
  real   HEAL_PERC_AMOUNT[];
  real   SPELL_DURATION[];
 
 // -----------------------------------------------------------------
 //     *** Edit level data here ***
 function NatureBlessingLevelSetup() {
  // This is AOE of explosion "effect"
  // Default: 410 / 530 / 650
  EXPLOSION_AOE[01] = 410.;
  EXPLOSION_AOE[02] = 530.;
  EXPLOSION_AOE[03] = 650.;
  
  // Shield protection is amount of damage reduced in percentage
  // Default: 15 / 25 / 35
  SHIELD_PROTECT[01] = 15.;
  SHIELD_PROTECT[02] = 25.;
  SHIELD_PROTECT[03] = 35.;
  
  // This is heal amount in percentage per point of life missing
  // Default: 5 / 7 / 9
  HEAL_PERC_AMOUNT[01] = 5.;
  HEAL_PERC_AMOUNT[02] = 7.;
  HEAL_PERC_AMOUNT[03] = 9.;
  
  // This is how long spell lasts in seconds
  // Default: 10 / 10 / 10
  SPELL_DURATION[01] = 10.;
  SPELL_DURATION[02] = 10.;
  SPELL_DURATION[03] = 10.;
 }
 
 function PickUnitsFilter(unit f, player owner) -> boolean {
  return IsUnitAlly(f, owner)         &&
      !IsUnitType(f, UNIT_TYPE_DEAD)       &&
      !IsUnitType(f, UNIT_TYPE_STRUCTURE)      &&
      !BlzIsUnitInvulnerable(f)       &&
      !DDIsUnitWard(f)          &&
      !IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE)    &&
      !IsUnitType(f, UNIT_TYPE_MECHANICAL);
 }
 
 // #####################################################################################
 // #####################################################################################
 
 timer   Tim = null;
 group   Grp = null;
 
 struct unitdata {
  real dur, heal, shield;
  effect e;
  
  static thistype Att[];
 }
 
 struct missiles {
  ddeffect m[MISSILES_COUNT];
  p_real   pos[MISSILES_COUNT];
  p_real  spd[MISSILES_COUNT];
  integer  cnt;
  
  real  X, Y;
  player  owner;
  integer  lvl;
  
  
  static method create(unit c) -> thistype {
   thistype this = allocate();
   integer i;
   real x = GetWidgetX(c), y = GetWidgetY(c);
   real rad = 0., d;
   
   X = x; Y = y;
   owner = GetOwningPlayer(c);
   lvl = GetUnitAbilityLevel(c, NATURE_BLESSING);
   
   cnt = R2I((MISSILE_TRAVEL_TIME-.1) / DD_INTERVAL);
   for(i=00; i < MISSILES_COUNT; i+=01) {
    rad += bj_PI/6.;
    d = GetRandomReal(MISSILE_MIN_DISTANCE, MISSILE_MAX_DISTANCE);
    pos[i] = pVector(x + d * Cos(rad), y + d * Sin(rad), MISSILE_INITIAL_HEIGHT);
    spd[i] = pVector(-Cos(rad) * DD_INTERVAL * d / MISSILE_TRAVEL_TIME,
         -Sin(rad) * DD_INTERVAL * d / MISSILE_TRAVEL_TIME,
         DD_INTERVAL * (GetRandomReal(MISSILE_MIN_HEIGHT, MISSILE_MAX_HEIGHT)-MISSILE_INITIAL_HEIGHT) / MISSILE_TRAVEL_TIME);
    m[i] = ddeffect.createZ(NATURE_MISSILE_EFFECT, pos[i][00], pos[i][01], pos[i][02] + DDTerrZ(pos[i][00], pos[i][01]), rad, MISSILE_SIZE);
   }
   
   return this;
  }
  
  method destroy() {
   integer i;
   
   for(i=00; i < MISSILES_COUNT; i+=01) {
    m[i].destroy();
    pos[i].destroy();
    spd[i].destroy();
   }
   deallocate();
  }
  
  method Step() -> boolean {
   integer i;
   
   for(i=00; i < MISSILES_COUNT; i+=01) {
    pos[i][00] += spd[i][00];
    pos[i][01] += spd[i][01];
    pos[i][02] += spd[i][02];
    
    m[i].PositionZ(pos[i][00], pos[i][01], pos[i][02]);
    //m[i].Y = pos[i][01];
    //m[i].Z = pos[i][02];
   }
   
   cnt -= 01;
   return (cnt == 00);
  }
  
 }
 
 
 // ==========================================================================================
 function onInit() {
  trigger t = CreateTrigger();
  
  Grp = CreateGroup();
  NatureBlessingLevelSetup();
  
  // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  
  TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
  TriggerAddCondition(t, Condition(function() -> boolean {
   missiles ms;
   unit u;
   
   if (GetSpellAbilityId() != NATURE_BLESSING)
    return false;
   
   u = GetTriggerUnit();
   ms = missiles.create(u);
   
   // Play sound and shake camera for players within spell cast range
   DDGenericSound(NATURE_SHOOT_SOUND, NATURE_SHOOT_SOUND_VOL, GetWidgetX(u), GetWidgetY(u), NATURE_SHOOT_SOUND_MAX_DISTANCE, NATURE_SHOOT_SOUND_PITCH);
   
   DDStartTim(MISSILE_BIRTH_TIME, false, ms, function() {
    DDStartTim(DD_INTERVAL, true, DDTimData(), function() {
     missiles ms = DDTimData();
     trigger t;
     
     if (ms.Step()) {
      DDGenericSound(NATURE_EXPLOSION_SOUND, NATURE_EXPLOSION_SOUND_VOL, ms.X, ms.Y, NATURE_SHOOT_SOUND_MAX_DISTANCE, 1.8);
      ddeffect.create(NATURE_EXPLOSION_EFFECT, ms.X, ms.Y, GetRandomReal(0., bj_PI*2.), EXPLOSION_AOE[ms.lvl]/250.).destroyx(3.);
      
      DDGroupFilterArea(ms.X, ms.Y, EXPLOSION_AOE[ms.lvl], ms, function() -> boolean {
       unitdata ud;
       missiles ms = DDGFilterData();
       unit f = GetFilterUnit();
       
       if (PickUnitsFilter(f, ms.owner)) {
        if (ud.Att[GetHandleId(f)-0x100000] == p_null) {
         ud = unitdata.create();
         ud.Att[GetHandleId(f)-0x100000] = ud;
         ud.e = AddSpecialEffectTarget(NATURE_SHIELD_EFFECT, f, "origin");
         GroupAddUnit(Grp, f);
        } else
         ud = ud.Att[GetHandleId(f)-0x100000];
        
        ud.heal   = HEAL_PERC_AMOUNT[ms.lvl] / 100.;
        ud.shield   = SHIELD_PROTECT[ms.lvl] / 100.;
        ud.dur    = SPELL_DURATION[ms.lvl];
       }
       
       f = null;
       return false;
      });
      
      if (Tim == null) {
       Tim = DDLoadTim();
      
      TimerStart(Tim, HEAL_INTERVAL, true, function() {
       ForGroup(Grp, function() {
        unit e = GetEnumUnit();
        unitdata ud = unitdata.Att[GetHandleId(e)-0x100000];
        
        SetWidgetLife( e, GetWidgetLife(e) + (HEAL_INTERVAL * ud.heal * (GetUnitState(e, UNIT_STATE_MAX_LIFE)-GetWidgetLife(e))) );
        
        ud.dur -= .2;
        if (ud.dur < 0. || IsUnitType(e, UNIT_TYPE_DEAD)) {
         GroupRemoveUnit(Grp, e);
         ud.Att[GetHandleId(e)-0x100000] = p_null;
         DestroyEffect(ud.e);
         ud.e = null;
         ud.destroy();
         if (FirstOfGroup(Grp) == null) {
          DDRecycleTim(Tim);
          Tim = null;
         }
        }
        
        e = null;
       });
      });
      
      }
      
      ms.destroy();
      DDQuitTim();
     }
    });
    DDQuitTim();
   });
   
   u = null;
   return false;
  }));
  
  // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  
  t = CreateTrigger();
  DDTriggerRegisterAnyUnitDamaged(t);
  TriggerAddCondition(t, Condition(function() -> boolean {
   unit u = GetTriggerUnit();
   unitdata ud = unitdata.Att[GetHandleId(u)-0x100000];
    
   if (ud == p_null) {
    u = null;
    return false;
   }
   
   SetWidgetLife(u, GetWidgetLife(u) + (GetEventDamage() * ud.shield));
   
   u = null;
   return false;
  }));
  
  // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  
 }
 
}
//! endzin
[B]

Instinct Flash

Quickly moves to targeted point dealing heavy damage to any enemy unit which comes near caster.


JASS:
[/B]
//TESH.scrollpos=15
//TESH.alwaysfold=0
//**************************************************************************************
//                              Installation:
//
//
// - 1. Made on Warcraft III v1.30
// - 2. Copy 'this trigger' and 'DD Library' to your map.
// - 3. Go to Import Manager (F12) and extract icons: BTNInstinctFlash.blp and DISBTN versions
//      sounds: sword_chop.wav, sword_echo.wav, sword_draw.wav, sword_dmg1.wav, sword_dmg2.wav
// - 4. Import all of this to your map and set there path to as you can see here (in my map)
// - 5. Go to Object Manager (F6) and copy:
//  units: Illusion Blademaster
//  ability: Instinct Flash
//  When you are pasting them to your map make sure you type the following rawcodes:
//      Illusion Blademaster:   'ssib'
//  Instinct Flash:         'InFl'
// - 6. If you want different raw codes you must edit them below as well:
// - 7. Edit data below to your own will and enjoy!
//
//**************************************************************************************

//! zinc
library InstinctFlash requires DDLib
{

  // *****************************************************************************************
  //        === Main Data ===
  // *****************************************************************************************
    
  // This is the raw code of the spell
  // Default: InFl
  constant integer   ABILITY_INSTINCT_FLASH     = 'InFl';
  
  // This is the raw code of illusion
  // Default: ssib
  constant integer   UNIT_ILLUSION_RAWCODE     = 'ssib';
  
  // *****************************************************************************************
  //        === Effects ===
  // *****************************************************************************************
  
  // Model file of spells motion sfx
  // Default: Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl
  constant string   EFFECT_BLADE_ATTACHMENT     = "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl";
  constant string   EFFECT_BLADE_ATTACH_POINT    = "weapon";
  // Default: Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl
  constant string   EFFECT_WATER_IMPACT      = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl";
  // Default: Objects\\SpawnQModels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl
  constant string   EFFECT_GROUND_IMPACT     = "Objects\\SpawnModels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl";
  // Default: Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl
  constant string   EFFECT_UNIT_SLASH_BLEAD     = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl";
  
  
  // *****************************************************************************************
  //        === Sounds ===
  // *****************************************************************************************
  
  // Default: Custom\\Spells\\Instinct Flash\\sword_draw.wav
  constant string   SOUND_DRAW        = "Custom\\Spells\\Instinct Flash\\sword_draw.wav";
  // Default: 85.
  constant real   SOUND_DRAW_VOL       = 85.;
  // Default: Custom\\Spells\\Instinct Flash\\sword_echo.wav
  constant string    SOUND_ECHO        = "Custom\\Spells\\Instinct Flash\\sword_echo.wav";
  // Default: 45.
  constant real   SOUND_ECHO_VOL       = 45.;
  // Default: Custom\\Spells\\Instinct Flash\\sword_dmg1.wav
  constant string   SOUND_DMG1        = "Custom\\Spells\\Instinct Flash\\sword_dmg1.wav";
  // Default: 45.
  constant real   SOUND_DMG1_VOL       = 85.;
  // Default: Custom\\Spells\\Instinct Flash\\sword_dmg2.wav
  constant string   SOUND_DMG2        = "Custom\\Spells\\Instinct Flash\\sword_dmg2.wav";
  // Default: 85.
  constant real   SOUND_DMG2_VOL       = 85.;
  // Default: Custom\\Spells\\Instinct Flash\\sword_chop.wav
  constant string   SOUND_CHOP        = "Custom\\Spells\\Instinct Flash\\sword_chop.wav";
  // Default: 85.
  constant real   SOUND_CHOP_VOL       = 85.;
  // Default: 3500.
  constant real   SOUND_MAX_DISTANCE      = 3500.;
  
  // *****************************************************************************************
  //        === Initial Illusions ===
  // *****************************************************************************************
  
        // Max illusion creation distance (height)
  // Default: 300
  constant real   ILLUSION_HEIGHT       = 300.;
  
  // Max illusion creation distance (width)
  // Default: 550
  constant real   ILLUSION_WIDTH       = 550.;
  
  // This is duration of illusions in seconds
  // Default: 0.6
  constant real   ILLUSION_DURATION      = .6;
  
  // This is the animation speed of illusions in percentage
  // Default: 100*(1.4-0.15)*0.4 ( 1.4 = Animation duration, 0.4 = Illusion duration, -0.15 extra constant value )
  constant real   ILLUSION_ANIMATION_SPEED    = 70.;
  
  // This is animation of illusion which should be played
  // Default: 9 (stand ready)
  constant integer   ILLUSION_ANIMATION_ID     = 9; // (1.4)
  
  // Maximum number of illusions at same time
  // Default: 8
  constant integer   MAX_ILLUSIONS       = 8;
  constant integer   MAX_ILLUSIONS_ARRAY      = 4;
  
  // 
  constant integer   ILLUSION_COLOR_RED      = 125;
  constant integer   ILLUSION_COLOR_GREEN     = 125;
  constant integer   ILLUSION_COLOR_BLUE      = 240;
  constant integer   ILLUSION_COLOR_ALPHA     = 128;
  
  // *****************************************************************************************
  //        === Caster Motion ===
  // *****************************************************************************************
  
  // This is casters end animation
  // Default: 8 (attack 2)
  constant integer   CASTER_ATTACK_ANIMATION_ID    = 8; // (1.134)
  // Speed at which caster is traveling after multiple illusions are fused
  // Default: 1000.
  constant real   CASTER_SPEED       = 1000.;
  // Default: 150
  constant integer   CASTER_COLOR_ALPHA      = 150;
  // Casters end animation speed in percentage
  // Default: 200
  constant real   CASTER_ANIMATION_SPEED     = 200.;
  // This is the area of damage effect
  // Default: 135
  constant real   CASTER_DAMAGE_RANGE      = 135.;
  
  // *****************************************************************************************
  //        === Killed Units Motion  ===
  // *****************************************************************************************
  
  // Defines travel distance of units which are pushed
  // Default: 330
  constant real   PUSH_DISTANCE       = 330.;
  
  // Defines travel height of units which are pushed
  // Default: 230
  constant real   PUSH_HEIGHT        = 230.;
  
  // Defines start push speed
  // Default: 500
  constant real   PUSH_SPEED        = 500.;
  
  // *****************************************************************************************
  //   *** (Aftereffect Illusions From Casters Movement) ***
  // *****************************************************************************************
  
  // This is casters end animation
  // Default: 8 (attack 2)
  constant integer   AEFF_ILLUSION_ATTACK_ANIMATION_ID  = 8; // (1.134)
  
  // Duration of casters end animation
  // Default: 0.66
  constant real   AEFF_ILLUSION_DURATION     = .66;
  
  // Casters end animation speed in percentage
  // Default: 100*1.134/0.5 (1.134 = animation duration, 0.5 seconds to finish animation)
  constant real   AEFF_ILLUSION_ANIMATION_SPEED   = 226.8;
  
  // How much distance caster passes to produce a single aftereffect illusion
  // Default: 125.
  constant real   AEFF_ILLUSION_DISTANCE_STEP    = 125.;
  
  
  real   DamageAmount[];
 
 // *****************************************************************************************
 //        === Level Data ===
 // *****************************************************************************************
 
 // *** Edit level data below ***
 function InstinctFlash_Setup() {
  // *** This is the damage per level ***
  // Default: 175 / 285 / 400
  DamageAmount[01]  = 175.;
  DamageAmount[02]  = 285.;
  DamageAmount[03]  = 400.;
  
  // *** This is the color of illusions ***
  // Arguments: red, green, blue, alpha (from 0 to 255)
  // Default: 125, 125, 240, 255
  //Color = CreateColor(125, 125, 240, 255)
  
 }
 
 // *****************************************************************************************
 //        === Unit Filter ===
 // *****************************************************************************************
 
 function UnitFilter_Setup(unit u, player p) -> boolean {
  return !IsUnitType(u, UNIT_TYPE_STRUCTURE)    &&
      !IsUnitType(u, UNIT_TYPE_FLYING)     &&
      !IsUnitType(u, UNIT_TYPE_MECHANICAL)    &&
      !BlzIsUnitInvulnerable(u)      &&
      !DDIsUnitWard(u)         &&
      !IsUnitType(u, UNIT_TYPE_DEAD)     &&
      IsUnitEnemy(u, p);
      
 }
 
 
 // ==============================================================================
 //     DO NOT EDIT BELOW IF YOU DONT KNOW JASS
 // ==============================================================================
 
 struct uknockback {
  unit u;
  real x, y, wz;
  real dx, dy;
  real a, dist;
  
  static method create(unit u, real rad) -> thistype {
   thistype this = allocate();
   
   this.u = u;
   UnitAddAbility(u, DD_ABILITY_CROWN_FORM);
   x = GetWidgetX(u); y = GetWidgetY(u); wz = DDTerrZ(x, y);
   a = PUSH_HEIGHT / Pw_2(PUSH_DISTANCE/2.);
   dx = DD_INTERVAL * PUSH_SPEED * Cos(rad);
   dy = DD_INTERVAL * PUSH_SPEED * Sin(rad);
   dist = PUSH_DISTANCE;
   
   return this;
  }
  
  method ApplyMotion() {
   DDStartTim(DD_INTERVAL, true, this, function() {
    thistype this = DDTimData();
    
    x += dx; y += dy;
    SetUnitX(u, x); SetUnitY(u, y);
    SetUnitFlyHeight(u, wz - DDTerrZ(x, y) + PUSH_HEIGHT - a*Pw_2(dist-(PUSH_DISTANCE/2.)), 0.);
    
    dist -= DD_INTERVAL * PUSH_SPEED;
    if (dist < 0.) {
     if (!IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY/*AMPHIBIOUSPATHING*/))
      DestroyEffect(AddSpecialEffect(EFFECT_WATER_IMPACT, x, y));
     else
      DestroyEffect(AddSpecialEffect(EFFECT_GROUND_IMPACT, x, y));
     u = null;
     destroy();
     DDQuitTim();
    }
   });
  }
 }
 
 struct iflash {
  unit u;
  player p;
  effect e;
  real x, y;
  real dx, dy;
  real dist, spd;
  group g, gd;
  integer lvl;
  real fac;
  
  static method create(unit u, real tx, real ty, real rad) -> thistype {
   thistype this = allocate();
   
   this.u = u;
   fac = bj_RADTODEG*rad;
   lvl = GetUnitAbilityLevel(u, ABILITY_INSTINCT_FLASH);
   p = GetOwningPlayer(u);
   x = GetUnitX(u); y = GetUnitY(u);
   spd = DD_INTERVAL * CASTER_SPEED;
   dx = spd * Cos(rad); dy = spd * Sin(rad);
   dist = SquareRoot( DDHypot(tx-x, ty-y) );
   g = DDLoadGroup(); gd = DDLoadGroup();
   
   SetUnitPathing(u, false);
   SetUnitAnimationByIndex(u, CASTER_ATTACK_ANIMATION_ID);
   ShowUnit(this.u, true);
   PauseUnit(u, true);
   e = AddSpecialEffectTarget(EFFECT_BLADE_ATTACHMENT, this.u, EFFECT_BLADE_ATTACH_POINT);
   SetUnitVertexColor(u, 255, 255, 255, CASTER_COLOR_ALPHA);
   SetUnitTimeScale(u, CASTER_ANIMATION_SPEED/100.);
   
   return this;
  }
  
  method ApplyMotion() {
   DDStartTim(DD_INTERVAL, true, this, function() {
    thistype this = DDTimData();
    unit ae_ill;
    
    x += dx; y += dy;
    dist -= spd;
    SetUnitX(u, x); SetUnitY(u, y);
    
    if (ModuloReal(dist, AEFF_ILLUSION_DISTANCE_STEP) < spd) {
     ae_ill = CreateUnit(Player(15), UNIT_ILLUSION_RAWCODE, x, y, fac);
     SetUnitColor(ae_ill, GetPlayerColor(p));
     SetUnitVertexColor(ae_ill, ILLUSION_COLOR_RED, ILLUSION_COLOR_GREEN, ILLUSION_COLOR_BLUE, CASTER_COLOR_ALPHA);
     SetUnitPathing(ae_ill, false);
     SetUnitX(ae_ill, x); SetUnitY(ae_ill, y);
     PauseUnit(ae_ill, true);
     SetUnitAnimationByIndex(ae_ill, CASTER_ATTACK_ANIMATION_ID);
     DestroyEffect(AddSpecialEffectTarget(EFFECT_BLADE_ATTACHMENT, ae_ill, EFFECT_BLADE_ATTACH_POINT));
     DDFadeUnit(ae_ill, CASTER_COLOR_ALPHA, 00, AEFF_ILLUSION_DURATION);
    }
    
    DDGFilterDataSet(this);
    GroupEnumUnitsInRange(g, x, y, CASTER_DAMAGE_RANGE, Filter(function() -> boolean {
     thistype this = DDGFilterData();
     unit f = GetFilterUnit();
     if (UnitFilter_Setup(f, p) && !IsUnitInGroup(f, gd)) {
      //UnitDamageTarget(u, f, DamageAmount[lvl], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null);
      DDSpellDamage(u, f, DamageAmount[lvl]);
      DestroyEffect(AddSpecialEffectTarget(EFFECT_UNIT_SLASH_BLEAD, f, "origin"));
      GroupAddUnit(gd, f);
      if (GetRandomInt(00, 01) == 01)
       DDGenericSound(SOUND_DMG1, SOUND_DMG1_VOL, x, y, SOUND_MAX_DISTANCE, 1.);
      else
       DDGenericSound(SOUND_DMG2, SOUND_DMG2_VOL, x, y, SOUND_MAX_DISTANCE, 1.);
      
      if (IsUnitType(f, UNIT_TYPE_DEAD)) {
       uknockback.create(f, Atan2(GetWidgetY(f)-GetWidgetY(u), GetWidgetX(f)-GetWidgetX(u))).ApplyMotion();
       DDGenericSound(SOUND_CHOP, SOUND_CHOP_VOL, x, y, SOUND_MAX_DISTANCE, 1.);
      }
     }
     
     f = null;
     return false;
    }));
    
    if (dist < 0.) {
     SetUnitPathing(u, true);
     PauseUnit(u, false);
     SetUnitTimeScale(u, 1.);
     SetUnitVertexColor(u, 255, 255, 255, 255);
     DDStartTim(.6, false, New_pUnit(u), function() {
      p_unit pu = DDTimData();
      SetUnitAnimation(pu[00], "stand");
      pu.destroy();
      DDQuitTim();
     });
     if (GetLocalPlayer() == p)
      SelectUnit(u, true);
     DDRecycleGroup(g);
     DDRecycleGroup(gd);
     DestroyEffect(e);
     e = null;
     destroy();
     DDQuitTim();
    }
   });
  }
 }
 

 struct illusions {
  unit il[MAX_ILLUSIONS], u;
  real dist[MAX_ILLUSIONS_ARRAY];
  effect e[MAX_ILLUSIONS];
  real w_spd;
  real dx, dy;
  real dx2, dy2;
  real x, y, tx, ty;
  real rad;
  
  static method create(unit u, real tx, real ty) -> thistype {
   thistype this = allocate();
   integer i;
   playercolor pc = GetPlayerColor(GetOwningPlayer(u));
   real px, py;
   
   this.u = u;
   this.tx = tx; this.ty = ty;
   x = GetUnitX(u); y = GetUnitY(u);
   w_spd = DD_INTERVAL * ILLUSION_HEIGHT / ILLUSION_DURATION;
   rad = Atan2(ty-y, tx-x);
   dx = Cos(rad); dy = Sin(rad);
   
   for(i=01; i < MAX_ILLUSIONS_ARRAY+01; i+=01) {
    px = x + (i*ILLUSION_WIDTH)/MAX_ILLUSIONS * -dy;
    py = y + (i*ILLUSION_WIDTH)/MAX_ILLUSIONS * dx;
    px += ( (ILLUSION_HEIGHT / Pw_2(ILLUSION_WIDTH/02)) ) * Pw_2((i-01)*ILLUSION_WIDTH/MAX_ILLUSIONS) * dx;
    py += ( (ILLUSION_HEIGHT / Pw_2(ILLUSION_WIDTH/02)) ) * Pw_2((i-01)*ILLUSION_WIDTH/MAX_ILLUSIONS) * dy;
    il[i-01] = CreateUnit(Player(15), UNIT_ILLUSION_RAWCODE, px, py, bj_RADTODEG*rad);
    e[i-01] = AddSpecialEffectTarget(EFFECT_BLADE_ATTACHMENT, il[i-01], "weapon");
    SetUnitVertexColor(il[i-01], ILLUSION_COLOR_RED, ILLUSION_COLOR_GREEN, ILLUSION_COLOR_BLUE, ILLUSION_COLOR_ALPHA);
    SetUnitColor(il[i-01], pc);
    SetUnitTimeScale(il[i-01], ILLUSION_ANIMATION_SPEED/100.);
    SetUnitAnimationByIndex(il[i-01], ILLUSION_ANIMATION_ID);
    
    px = x - (i*ILLUSION_WIDTH)/MAX_ILLUSIONS * -dy;
    py = y - (i*ILLUSION_WIDTH)/MAX_ILLUSIONS * dx;
    px += ( (ILLUSION_HEIGHT / Pw_2(ILLUSION_WIDTH/02)) ) * Pw_2((i-01)*ILLUSION_WIDTH/MAX_ILLUSIONS) * dx;
    py += ( (ILLUSION_HEIGHT / Pw_2(ILLUSION_WIDTH/02)) ) * Pw_2((i-01)*ILLUSION_WIDTH/MAX_ILLUSIONS) * dy;
    il[(i-01)+MAX_ILLUSIONS_ARRAY] = CreateUnit(Player(15), UNIT_ILLUSION_RAWCODE, px, py, bj_RADTODEG*rad);
    e[i-01+MAX_ILLUSIONS_ARRAY] = AddSpecialEffectTarget(EFFECT_BLADE_ATTACHMENT, il[i-01+MAX_ILLUSIONS_ARRAY], "weapon");
    SetUnitVertexColor(il[(i-01)+MAX_ILLUSIONS_ARRAY], ILLUSION_COLOR_RED, ILLUSION_COLOR_GREEN, ILLUSION_COLOR_BLUE, ILLUSION_COLOR_ALPHA);
    SetUnitColor(il[(i-01)+MAX_ILLUSIONS_ARRAY], pc);
    SetUnitTimeScale(il[(i-01)+MAX_ILLUSIONS_ARRAY], ILLUSION_ANIMATION_SPEED/100.);
    SetUnitAnimationByIndex(il[(i-01)+MAX_ILLUSIONS_ARRAY], ILLUSION_ANIMATION_ID);
    
    dist[i-01] = (i*ILLUSION_HEIGHT*2.)/MAX_ILLUSIONS;
   }
   
   return this;
  }
  
  method ApplyMotion() {
   DDStartTim(DD_INTERVAL, true, this, function() {
    thistype this = DDTimData();
    integer i;
    real px, py;
    real sq;
    
    for(i=01; i < MAX_ILLUSIONS_ARRAY+01; i+=01) {
     dist[i-01] -=  w_spd;
     sq = SquareRoot(Pw_2(ILLUSION_WIDTH/02)*dist[i-01] / ILLUSION_HEIGHT);
     px = x + dist[i-01] * dx;
     py = y + dist[i-01] * dy;
     px += sq * -dy; // +90 degrees
     py += sq * dx;
     SetUnitX(il[i-01], px); SetUnitY(il[i-01], py);
     px = x + dist[i-01] * dx; 
     py = y + dist[i-01] * dy;
     px -= sq * -dy; // -90 degrees
     py -= sq * dx;
     SetUnitX(il[i-01+MAX_ILLUSIONS_ARRAY], px); SetUnitY(il[i-01+MAX_ILLUSIONS_ARRAY], py);
     
     if (dist[i-01] < 0. && il[i-01] != null) {
      RemoveUnit(il[i-01]);
      RemoveUnit(il[i-01+MAX_ILLUSIONS_ARRAY]);
      il[i-01] = null;
      il[i-01+MAX_ILLUSIONS_ARRAY] = null;
     }
    }
    
    if (il[MAX_ILLUSIONS_ARRAY-01] == null) {
     DDGenericSound(SOUND_ECHO, SOUND_ECHO_VOL, x, y, SOUND_MAX_DISTANCE, 1.);
     iflash.create(u, tx, ty, rad).ApplyMotion();
     destroy();
     DDQuitTim();
    }
   });
  }
 }
 
 // *** Main map startup function ***
 function onInit() {
  // *** Load locals ***
  trigger t = CreateTrigger();
  
  // *** Define users setup ***
  InstinctFlash_Setup();
  
  // *** Event / cond / act registering ***
  TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
  TriggerAddCondition(t, Condition(function() -> boolean {
   illusions il;
   unit u;
   
   if (GetSpellAbilityId() != ABILITY_INSTINCT_FLASH)
    return false;
   
   u = GetTriggerUnit();
   il = illusions.create(u, GetSpellTargetX(), GetSpellTargetY());
   il.ApplyMotion();
   ShowUnit(u, false);
   //SetUnitTimeScale(u, ILLUSION_ANIMATION_SPEED/100.);
   //SetUnitAnimationByIndex(u, ILLUSION_ANIMATION_ID);
   
   
   DDGenericSound(SOUND_DRAW, SOUND_DRAW_VOL, GetSpellTargetX(), GetSpellTargetY(), SOUND_MAX_DISTANCE, 1.);
   
   return false;
  }));
  
 }
 
}
//! endzinc


[B]

Summon Skeletons

Summons n skeletons which last for 50 seconds.



JASS:
//TESH.scrollpos=15
//TESH.alwaysfold=0
//**************************************************************************************
//                              Installation:
//
// - 1. Made on Warcraft III v1.30
// - 2. Go to Import Manager (F12) and extract NecroticBlast.mdx, BTNSummonSkeletons.blp (Credits: PrinceYaser) and its DISBTN version
// - 3. Import all of this to your map and set ther path to as you can see here (in my map)
// - 4. Go to Object Manager (F6) and copy "Summon Skeletons" ability.
//   When you are pasting them to your map make sure you match there rawcodes with ones below
// - 5. If you want different raw codes edit the below as well
// - 6. Edit data below to your own will and enjoy the spell
// - 7. Copy this trigger and "DD Library" to your map
//
//
//**************************************************************************************

//! zinc
library SummonSkeletons requires DDLib
{

 // *****************************************************************************************
 //        === Main Data ===
 // *****************************************************************************************
 
    // This is the raw code of the spell 'Summon Skeletons'
    // Default: 'A000'
    constant integer      ABILITY_SUMMON_SKELETONS       = 'A000';
 //constant real       SUMMON_SKELETONS_BLIGHT_DURATION    = 5.;
    constant real       SUMMON_SKELETONS_INTERVAL       = .33; // How offten are skeletons created
    constant real       SUMMON_SKELETONS_RISE_TIME       = 2.33;
    constant string       SUMMON_SKELETONS_RISE_ANIMATION     = "birth";
    constant real       SUMMON_SKELETONS_START_TRANSPARENCY    = 85.;
    constant real       SKELETONS_MIN_RISE_DISTANCE      = 125.; // Min distance from skeleton and caster
    constant real       SKELETONS_MIN_SPAWN_RANGE      = 100.; // Min distance between skeletons
    
 
 // *****************************************************************************************
 //        === Effect ===
 // *****************************************************************************************
 
 constant string      SUMMON_SKELETON_CASTER_EFFECT     = "Spells\\SummonSkeletons\\NecroticBlast.mdx"; // UgoUgo
 
 constant string      SUMMON_SKELETON_RISE_EFFECT      = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl";
 constant string      SUMMON_SKELETON_RISE_EFFECT_EX     = "Abilities\\Spells\\Undead\\RaiseSkeletonWarrior\\RaiseSkeleton.mdl";
 constant string      SUMMON_SKELETON_GROUND_EFFECT     = "Abilities\\Spells\\Undead\\PlagueCloud\\PlagueCloudCaster.mdl";//"SharedModels\\Smoke1_Green.mdl";
 constant real      SUMMON_SKELETON_GROUND_EFFECT_SIZE    = 1.;
 constant real      SUMMON_SKELETON_GROUND_EFFECT_HEIGHT   = -10.;
 
 constant string       SUMMON_SKELETONS_RISE_GRAVE_EFFECT    = "Abilities\\Spells\\Undead\\Graveyard\\GraveMarker.mdl";
 constant real       SUMMON_SKELETONS_RISE_GRAVE_EFFECT_FACING_OFFSET= 30.;
 constant real       SUMMON_SKELETONS_RISE_GRAVE_DURATION   = 6.;
 constant real       SUMMON_SKELETONS_RISE_GRAVE_DISTANCE_OFFSET  = 70.;
 
 constant string       SUMMON_SKELETONS_FIRE_EFFECT     = "Abilities\\Spells\\NightElf\\Immolation\\ImmolationDamage.mdl";
 constant string       SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_1   = "foot left";
 constant string       SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_2   = "foot right";
 constant string       SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_3   = "hand left";
 constant string       SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_4   = "hand right";
 constant string       SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_5   = "head";
 constant string       SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_6   = "origin";
 
 
    
 // *****************************************************************************************
 //        === Level Data ===
 // *****************************************************************************************
 
 // --------------------------------------------------------------
    // This variables are not supposed to be modified here, modify them below in Setup function
 integer    SKELETONS_TYPE_COLOR_RED[];
 integer    SKELETONS_TYPE_COLOR_GREEN[];
 integer    SKELETONS_TYPE_COLOR_BLUE[];
    integer    SKELETONS_COUNT[];
    integer    SKELETONS_TYPE_ID[];
 real    SKELETONS_LIFESPAN[];
    real     SKELETONS_MAX_RISE_DISTANCE[];
    real     SUMMON_SKELETONS_RISE_GRAVE_SIZE[];
    
 // --------------------------------------------------------------

 // This part of code is used to define spell constants per level
 function SummonSkeletons_Setup() {
  // Default: Level 1 = 'ndr1'
  // Default: Level 2 = 'ndr2'
  // Default: Level 3 = 'ndr3'
  SKELETONS_TYPE_ID[01]     = 'ndr1';
  SKELETONS_TYPE_ID[02]     = 'ndr2';
  SKELETONS_TYPE_ID[03]     = 'ndr3';
  
  // Default: Level 1 = 50.
  // Default: Level 2 = 50.
  // Default: Level 3 = 50.
  SKELETONS_LIFESPAN[01]     = 50.;
  SKELETONS_LIFESPAN[02]     = 50.;
  SKELETONS_LIFESPAN[03]     = 50.;
  
  // Default: Level 1 = 230 RGB
  // Default: Level 2 = 200 RGB
  // Default: Level 3 = 150 RGB
  SKELETONS_TYPE_COLOR_RED [01]  = 230;
  SKELETONS_TYPE_COLOR_GREEN [01]  = 230;
  SKELETONS_TYPE_COLOR_BLUE [01]  = 230;
  SKELETONS_TYPE_COLOR_RED [02]  = 200;
  SKELETONS_TYPE_COLOR_GREEN [02]  = 200;
  SKELETONS_TYPE_COLOR_BLUE [02]  = 200;
  SKELETONS_TYPE_COLOR_RED [03]  = 150;
  SKELETONS_TYPE_COLOR_GREEN [03]  = 150;
  SKELETONS_TYPE_COLOR_BLUE [03]  = 150;
  
  // Default: Level 1 = 4
  // Default: Level 2 = 5
  // Default: Level 3 = 6
  SKELETONS_COUNT[01]     = 4;
  SKELETONS_COUNT[02]     = 5;
  SKELETONS_COUNT[03]     = 6;
  
  // * Max skeleton rise distance from caster
  // Default: Level 1 = 400.
  // Default: Level 2 = 400.
  // Default: Level 3 = 400.
  SKELETONS_MAX_RISE_DISTANCE[01]  = 400.;
  SKELETONS_MAX_RISE_DISTANCE[02]  = 400.;
  SKELETONS_MAX_RISE_DISTANCE[03]  = 400.;
  
  // Default: Level 1 = 0.9
  // Default: Level 2 = 1.1
  // Default: Level 3 = 1.3
  SUMMON_SKELETONS_RISE_GRAVE_SIZE[01] = 0.9;
  SUMMON_SKELETONS_RISE_GRAVE_SIZE[02] = 1.1;
  SUMMON_SKELETONS_RISE_GRAVE_SIZE[03] = 1.3;
 }
 
 // *****************************************************************************************
 //        === Main Code  ===
 // *****************************************************************************************
 
 type cluster  extends  effect[06];
 
 struct fadeskel {
  unit u;
  integer lvl;
  real trans;
  real rate, e_trans, dur;
   
  static constant real INTERVAL = .1;
 }
  
 // *** fadeskels unit over time ***
 function DDFadeSkel(unit u, integer lvl) {
  fadeskel f = fadeskel.create();
   
  f.u = u;
  f.lvl = lvl;
  f.trans = (100.-SUMMON_SKELETONS_START_TRANSPARENCY)*2.55;
  f.rate = ((255.-f.trans)/SUMMON_SKELETONS_RISE_TIME)*fadeskel.INTERVAL;
  f.dur = SUMMON_SKELETONS_RISE_TIME;
   
  PauseUnit(u, true);
  SetUnitAnimation(u, SUMMON_SKELETONS_RISE_ANIMATION);
  SetUnitVertexColor(f.u,
         SKELETONS_TYPE_COLOR_RED[lvl],
         SKELETONS_TYPE_COLOR_GREEN[lvl],
         SKELETONS_TYPE_COLOR_BLUE[lvl],
         R2I(f.trans));
  // --- Start thread ---
  DDStartTim(fadeskel.INTERVAL, true, f, function() {
   fadeskel f = DDTimData();
    
   f.trans += f.rate;
   f.dur -= fadeskel.INTERVAL;
   SetUnitVertexColor(f.u,
          SKELETONS_TYPE_COLOR_RED[f.lvl],
          SKELETONS_TYPE_COLOR_GREEN[f.lvl],
          SKELETONS_TYPE_COLOR_BLUE[f.lvl],
          R2I(f.trans));
    
   if (f.dur < 0.) {
    PauseUnit(f.u, false);
    SetUnitAnimation(f.u, "stand");
    SetUnitVertexColor(f.u,
          SKELETONS_TYPE_COLOR_RED[f.lvl],
          SKELETONS_TYPE_COLOR_GREEN[f.lvl],
          SKELETONS_TYPE_COLOR_BLUE[f.lvl],
          255);
    f.u = null;
    f.destroy();
    DDQuitTim();
   }
  });
 }
 
 struct data {
  player p;
  real fac;
  real x, y;
  integer lvl, ns;
  integer nskels;
  unit sk[33];
  p_real vec;
  
  static boolean DestsFlag = false;
 }
 /*
 struct blightdata {
  integer tt, tv;
  real x, y;
 }*/
 
 function onInit() {
  trigger t = CreateTrigger();
  
  SummonSkeletons_Setup();
  
  TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
  TriggerAddCondition(t, Condition(function() -> boolean {
   data d;
   integer i;
   unit u;
   
   if (GetSpellAbilityId() != ABILITY_SUMMON_SKELETONS)
    return false;
   
   d = data.create();
   u = GetTriggerUnit();
   d.p = GetOwningPlayer(u);
   d.fac = GetUnitFacing(u);
   d.x = GetWidgetX(u); d.y = GetWidgetY(u);
   d.lvl = GetUnitAbilityLevel(u, ABILITY_SUMMON_SKELETONS);
   d.vec = p_real.create();
   d.nskels = 00;
   
   DestroyEffect(AddSpecialEffectTarget(SUMMON_SKELETON_CASTER_EFFECT, u, "origin"));
   
   DDStartTim(SUMMON_SKELETONS_INTERVAL, true, d, function() {
    data d = DDTimData();
    real dist, cdist, rad;
    boolean skeleton_pathing_invalid;
    real x, y;
    real vx, vy;
    unit sk;
    effect e;
    //blightdata bd;
    cluster cl;
    integer i;
    
    do {
     //skeleton_pathing_invalid = true;
     //dist = GetRandomReal(SKELETONS_MIN_RISE_DISTANCE, SKELETONS_MAX_RISE_DISTANCE[d.lvl]);
     //rad = GetRandomReal(0., bj_PI*2.);
     
     dist = DDGetRndReal(SKELETONS_MIN_RISE_DISTANCE, SKELETONS_MAX_RISE_DISTANCE[d.lvl]);
     rad = GetRandomReal(0., 2.*bj_PI);
     
     
     if (d.nskels > 00) {
      for(i=00; i < d.nskels; i+=01) {
       if (IsUnitInRangeXY(d.sk[i], d.x + dist * Cos(rad), d.y + dist * Sin(rad), SKELETONS_MIN_SPAWN_RANGE)) {
        //dist = SquareRoot(DDGetRndReal(Pw_2(SKELETONS_MIN_RISE_DISTANCE), Pw_2(SKELETONS_MAX_RISE_DISTANCE[d.lvl])));
        //dist = GetRandomReal(SKELETONS_MIN_RISE_DISTANCE, SKELETONS_MAX_RISE_DISTANCE[d.lvl]);
        //rad = GetRandomReal(0., bj_PI*2.);
        dist = DDGetRndReal(SKELETONS_MIN_RISE_DISTANCE, SKELETONS_MAX_RISE_DISTANCE[d.lvl]);
        rad = GetRandomReal(0., 2.*bj_PI);
        i = -01;
       }
      }
     }
     
     cdist = 0.;
     x = d.x; y = d.y;
     vx = 64.*Cos(rad); vy = 64.*Sin(rad);
     
     do {
      cdist += 64.;
      x += vx; y += vy;
      data.DestsFlag = false;
      d.vec[00] = x; d.vec[01] = y;
      DDEnumDestsInRange(d.vec, bj_CELLWIDTH, null, function() { data.DestsFlag = true; });
      skeleton_pathing_invalid = IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) || IsTerrainPathable(x, y, PATHING_TYPE_AMPHIBIOUSPATHING) || data.DestsFlag;
      //if (skeleton_pathing_invalid)
       //break;
     } while(cdist < dist+64. && !skeleton_pathing_invalid);
    } while(skeleton_pathing_invalid);
    
    x = d.x + dist * Cos(rad);
    y = d.y + dist * Sin(rad);
    sk = CreateUnit(d.p, SKELETONS_TYPE_ID[d.lvl], x, y, d.fac);
    d.sk[d.nskels] = sk;
    cl = cluster.create();
    cl[00] = AddSpecialEffectTarget(SUMMON_SKELETONS_FIRE_EFFECT, sk, SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_1);
    cl[01] = AddSpecialEffectTarget(SUMMON_SKELETONS_FIRE_EFFECT, sk, SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_2);
    cl[02] = AddSpecialEffectTarget(SUMMON_SKELETONS_FIRE_EFFECT, sk, SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_3);
    cl[03] = AddSpecialEffectTarget(SUMMON_SKELETONS_FIRE_EFFECT, sk, SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_4);
    cl[04] = AddSpecialEffectTarget(SUMMON_SKELETONS_FIRE_EFFECT, sk, SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_5);
    cl[05] = AddSpecialEffectTarget(SUMMON_SKELETONS_FIRE_EFFECT, sk, SUMMON_SKELETONS_FIRE_EFFECT_ATTACH_6);
    DDStartTim(SKELETONS_LIFESPAN[d.lvl], false, cl, function() {
     cluster cl = DDTimData();
     DestroyEffect(cl[00]); cl[00] = null;
     DestroyEffect(cl[01]); cl[01] = null;
     DestroyEffect(cl[02]); cl[02] = null;
     DestroyEffect(cl[03]); cl[03] = null;
     DestroyEffect(cl[04]); cl[04] = null;
     DestroyEffect(cl[05]); cl[05] = null;
     cl.destroy();
     DDQuitTim();
    });
    UnitApplyTimedLife(sk, 'Brai', SKELETONS_LIFESPAN[d.lvl]);
    DestroyEffect(AddSpecialEffectTarget(SUMMON_SKELETON_RISE_EFFECT, sk, "origin"));
    DestroyEffect(AddSpecialEffectTarget(SUMMON_SKELETON_RISE_EFFECT_EX, sk, "origin"));
    e = AddSpecialEffect(SUMMON_SKELETON_GROUND_EFFECT, x, y);
    BlzSetSpecialEffectZ(e, DDTerrZ(x, y) + SUMMON_SKELETON_GROUND_EFFECT_HEIGHT);
    BlzSetSpecialEffectScale(e, SUMMON_SKELETON_GROUND_EFFECT_SIZE);
    DDDestroyEffectTimed(e, SUMMON_SKELETONS_RISE_GRAVE_DURATION);
    DDFadeSkel(sk, d.lvl);
    sk = null;
    
    
    /*
    bd = blightdata.create();
    bd.x = x; bd.y = y;
    bd.tt = GetTerrainType(x, y);
    bd.tv = GetTerrainVariance(x, y);
    SetTerrainType(bd.x, bd.y, 'Jdtr', 00, 01, 01);
    //SetBlightPoint(Player(00), x, y, true);
    DDStartTim(SUMMON_SKELETONS_BLIGHT_DURATION, false, bd, function() {
     blightdata bd = DDTimData();
     //SetBlightPoint(Player(00), bd.x, bd.y, false);
     SetTerrainType(bd.x, bd.y, bd.tt, bd.tv, 01, 01);
     bd.destroy();
     DDQuitTim();
    });*/
    
    
    //DDDestroyEffectTimed(e, SUMMON_SKELETONS_RISE_GRAVE_DURATION);
    
    x -= SUMMON_SKELETONS_RISE_GRAVE_DISTANCE_OFFSET * Cos(d.fac*bj_DEGTORAD);
    y -= SUMMON_SKELETONS_RISE_GRAVE_DISTANCE_OFFSET * Sin(d.fac*bj_DEGTORAD);
    e = AddSpecialEffect(SUMMON_SKELETONS_RISE_GRAVE_EFFECT, x, y);
    BlzSetSpecialEffectRoll(e, (d.fac+SUMMON_SKELETONS_RISE_GRAVE_EFFECT_FACING_OFFSET)*bj_DEGTORAD);
    BlzSetSpecialEffectScale(e, SUMMON_SKELETONS_RISE_GRAVE_SIZE[d.lvl]);
    DDDestroyEffectTimed(e, SUMMON_SKELETONS_RISE_GRAVE_DURATION);
    e = null;
    
    d.nskels += 01;
    if (d.nskels == SKELETONS_COUNT[d.lvl]) {
     while(d.nskels > 00) {
      d.nskels -= 01;
      d.sk[d.nskels] = null;
     }
     d.vec.destroy();
     d.destroy();
     DDQuitTim();
    }
    
   });
   
   return false;
  }));
 }

}
//! endzinc



Terror Blade

Gives a n% chance per attack to corrupt the target with attackers hate for his enemies, reducing armor, damage and dealing extra damage on activation. This ability cant trigger if target is already effected.

JASS:
//TESH.scrollpos=0
//TESH.alwaysfold=0
//**************************************************************************************
//                            Spell: Terror Blade
//                            Author: Dark Dragon
//                            Date: 8 June 2009
//
//
//                              Installation:
//
//
// - 1. Made on Warcraft III v1.30
// - 2. Go to Import Manager (F12) and extract icons: BTNTerrorBlade.blp, DISBTN, PAS and DISPAS versions
// - 3. Import all of this to your map and set there path to as you can see here (in my map)
// - 4. Go to Object Manager (F6) and copy:
//  abilities: Terror Blade and Terror Blade Effect
//  buffs: Terror Blade (Buff)
//  When you are pasting them to your map make sure you
//      type the following rawcodes:
//  Terror Blade:           'Trbl'
//  Terror Blade Effect:    'Tble'
//      Terror Blade (Buff):    'Btbl'
// - 5. If you want different raw codes you must edit them below as well:
// - 6. Edit data below to your own will and enjoy!
// - 7. And of course copy 'this trigger' and 'DD Library' to your map.
//
//**************************************************************************************



// ======================================================================
// * Spell: Terror Blade
//  * Library Load (Whole code that spell needs is inside the library)
// ======================================================================
//! zinc
library TerrorBlade requires DDLib
{
 
 // ---------------------------------------------------------------------
 //
 //   *** MAIN SPELL CONSTANTS SETUP VALUES ***
 //
 //
 // * The following values are for you to modifly for your own needs
 // * Below are constants and after that are level data values
 // * Modify all of them as you want!
 // ---------------------------------------------------------------------
 
 // --------------------------------------------
 //     *** Global Constants Scope ***
 // --------------------------------------------
 // --- The raw code of spell ---
 // Default: Trbl
 constant  integer     ABILITY_TERROR_BLADE      = 'Trbl';
  
 // --- The raw code of the spells dummy effect ---
 // Default: Tble
 constant integer     ABILITY_TERROR_BLADE_DUMMY     = 'Tble';
 
 // --- Dummy ability order string ---
 // Default: innerfire
 constant string     ABILITY_TERROR_BLADE_DUMMY_ORDER   = "innerfire";
  
 // --- The raw code of buff ---
 // Default: Btbl
 constant integer     ABILITY_TERROR_BLADE_BUFF     = 'Btbl';
 
 // --- The corruption effect path ---
 // Default: Abilities\\Spells\\Other\\HowlOfTerror\\HowlTarget.mdl
 constant string     TARGET_ATTACHMENT_EFFECT_PATH    = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlTarget.mdl";

 // --- The darkness effect path ---
 // Default: Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl
 //constant string     DARKNESS_EFFECT        = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl";
  
 // --- This is the terror movement effect path ---
 // Default: Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl
 constant string     TERROR_BLADE_WAVE_EFFECT_PATH    = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl";
 
 // --- Terror wave effect z offset ---
 // Default: 65
 constant real     TERROR_BLADE_WAVE_HEIGHT     = 65.;
 
 // --- Terrors effect size in percentage ---
 // Default: 100
 constant real     TERROR_BLADE_WAVE_SIZE      = 1.;
 
 // --- Terror effects speed in coordinates per second ---
 // Default: 475
 constant real     TERROR_BLADE_WAVE_SPEED      = 475.;
 
 // --- Terror effects travel distance ---
 // Default: 200
 constant real     TERROR_BLADE_WAVE_DISTANCE     = 200.;
  
 // --- Tells can this spell be triggered even if target is already effected ---
 // Default: false
 constant boolean     CAN_TRIGGER_AT_SAME_TIME     = false;
  
 // --- Can this spell effect undead-units ---
 // Default: true
 constant boolean     CAN_EFFECT_UNDEAD_UNITS      = true;
  
 // --- Show floating text ---
 // Default: true
 constant boolean     SHOW_FLOATING_TEXT       = true;
 
 // --- How long floating text lasts in seconds ---
 // Default: 5.0
 constant real     FLOATING_TEXT_DURATION      = 5.;
  
 // --- Where is an effect attached on caster ---
 // Default: weapon
 //constant string     CASTER_ATTACH_POINT       = "weapon";
 
 // --------------------------------------------------------------------
 // * Level data do not edit here edit them below in function setup *
 //
 // { 
   real   TERROR_DURATION[];
   integer   TERROR_CHANCE[];
   real   TERROR_EXTRA_DAMAGE[];
   
   // *** Special non-level data ***
   string    TARGET_ATTACH_POINT[];
   real   FT_COLOR[];
 // }
 
 // -------------------------------------------------------------
 //  *** Level data is configured here ***
 // -------------------------------------------------------------
 function TerrorBladeLevel_Setup() {
  // --- This is duration (how long the effect lasts per level) ---
  // Default: 10 / 10 / 10
  TERROR_DURATION[01] = 10.;
  TERROR_DURATION[02] = 10.;
  TERROR_DURATION[03] = 10.;
  
  // --- Extra damage per level on triggering ---
  // Default: 20 / 35 / 50
  TERROR_EXTRA_DAMAGE[01] = 20.;
  TERROR_EXTRA_DAMAGE[02] = 35.;
  TERROR_EXTRA_DAMAGE[03] = 50.;
  
  // --- Chance in percentage to trigger this ability per level ---
  // Default: 25 / 30 / 30
  TERROR_CHANCE[01] = 25;
  TERROR_CHANCE[02] = 30;
  TERROR_CHANCE[03] = 30;
  
  // -----------------------------------------
  // --- Special non-level multiple data ---
  // -----------------------------------------
  
  // --- Attach points on target unit ---
  // --- Number of effects attached to target depend ---
  // --- on how much attach points u add here ---
  // Default: origin, weapon...
  TARGET_ATTACH_POINT[01] = "origin";
  TARGET_ATTACH_POINT[02] = "weapon";
  //set TargetAPoint[3] = "head" ...
  
  // --- This is the color of floating text ---
        // --- This has no effect if 'SHOW_FLOATING_TEXT' is off ---
        // --- Args: Red / Green / Blue / Transparency
  // Default: 60 / 13 / 40 / 0
  FT_COLOR[00] = 60.;
  FT_COLOR[01] = 13.;
  FT_COLOR[02] = 40.;
  FT_COLOR[03] = 0.;
  
 }
 
 // * 
 function TerrorBladeFilter(unit victim, player attackerPlayer) -> boolean {
  static if (!CAN_EFFECT_UNDEAD_UNITS) {
   return !IsUnitType(victim, UNIT_TYPE_MECHANICAL)    &&
       !IsUnitType(victim, UNIT_TYPE_STRUCTURE)     &&
       !IsUnitType(victim, UNIT_TYPE_ANCIENT)     &&
       !IsUnitType(victim, UNIT_TYPE_MAGIC_IMMUNE)    &&
       !IsUnitType(victim, UNIT_TYPE_UNDEAD)     &&
       !IsUnitType(victim, UNIT_TYPE_FLYING)     &&
       IsUnitEnemy(victim, attackerPlayer)      &&
       !DDIsUnitWard(victim);
  } else {
   return !IsUnitType(victim, UNIT_TYPE_MECHANICAL)    &&
       !IsUnitType(victim, UNIT_TYPE_STRUCTURE)     &&
       !IsUnitType(victim, UNIT_TYPE_ANCIENT)     &&
       !IsUnitType(victim, UNIT_TYPE_MAGIC_IMMUNE)    &&
       !IsUnitType(victim, UNIT_TYPE_FLYING)     &&
       IsUnitEnemy(victim, attackerPlayer)      &&
       !DDIsUnitWard(victim);
  }    
 }
 
 
 // ==============================================================================
 //    *** DO NOT EDIT BELOW IF YOU DONT KNOW JASS ***
 // ==============================================================================
 
 real UnitAttackTime[];
 real UnitAttackElapsedTime[];
 
 struct data {
  ddeffect wave;
  real x, y, dx, dy;
  real dist;
 }
 
 struct terrorized {
  unit v, dmy;
  effect e[02];
  real dur;
  boolean osuccess;
 }
 
 function onInit() {
  trigger t = CreateTrigger();
  
  TerrorBladeLevel_Setup();
  
  TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED);
  DDTriggerRegisterAnyUnitDamaged(t);
  TriggerAddCondition(t, Condition(function() -> boolean {
   unit u, v;
   integer id;
   real at_t;
   integer lvl;
   data d;
   real rad;
   terrorized t;
   integer ch;
   
   if (GetTriggerEventId() == EVENT_PLAYER_UNIT_ATTACKED) {
    if (GetUnitAbilityLevel(GetAttacker(), ABILITY_TERROR_BLADE) > 00)
     UnitAttackTime[H2ID(GetAttacker())] = DDGetGameElapsedTime();
    return false;
   }
   
   u = GetEventDamageSource();
   lvl = GetUnitAbilityLevel(u, ABILITY_TERROR_BLADE);
   if (lvl > 00) {
    id = H2ID(u);
    at_t = DDGetGameElapsedTime()-UnitAttackTime[id];
    
    /*DDMsg(R2S(at_t));
    DDMsg(R2S(UnitAttackElapsedTime[(id*04)+01]));
    DDMsg(R2S(UnitAttackElapsedTime[(id*04)+02]));
    DDMsg(R2S(UnitAttackElapsedTime[(id*04)+03]));*/
    
    // *** Is melee damage?
    if (R2I(at_t/.05)            == R2I(UnitAttackElapsedTime[(id*04)+01]/.05) &&
     R2I(UnitAttackElapsedTime[(id*04)+01]/.05) == R2I(UnitAttackElapsedTime[(id*04)+02]/.05) &&
     R2I(UnitAttackElapsedTime[(id*04)+02]/.05) == R2I(UnitAttackElapsedTime[(id*04)+03]/.05))
    {
     if (DDGetRndInt(01, 100) <= TERROR_CHANCE[lvl]) {
      v = GetTriggerUnit();
      static if (!CAN_TRIGGER_AT_SAME_TIME)
       if (GetUnitAbilityLevel(v, ABILITY_TERROR_BLADE_BUFF) > 00) {
        u = null; v = null;
        UnitAttackElapsedTime[ (id*04) + R2I(UnitAttackElapsedTime[(id*04)]) ] = at_t;
        UnitAttackElapsedTime[(id*04)] += 1.;
        if (UnitAttackElapsedTime[(id*04)] == 4.) UnitAttackElapsedTime[(id*04)] = 0.;
        return false;
       }
      
      if (TerrorBladeFilter(v, GetOwningPlayer(u))) {
       d = data.create();
       d.x = GetWidgetX(u); d.y = GetWidgetY(u);
       d.wave = ddeffect.createZ(TERROR_BLADE_WAVE_EFFECT_PATH, d.x, d.y, DDTerrZ(d.x, d.y) + TERROR_BLADE_WAVE_HEIGHT, DDGetRndReal(0., bj_PI*2.), TERROR_BLADE_WAVE_SIZE);
       rad = Atan2(GetWidgetY(v)-d.y, GetWidgetX(v)-d.x);
       d.dx = TERROR_BLADE_WAVE_SPEED*DD_INTERVAL*Cos(rad);
       d.dy = TERROR_BLADE_WAVE_SPEED*DD_INTERVAL*Sin(rad);
       d.dist = TERROR_BLADE_WAVE_DISTANCE;
       
       DDStartTim(DD_INTERVAL, true, d, function() {
        data d = DDTimData();
        
        d.wave.Position(d.wave.X + d.dx, d.wave.Y + d.dy);
        
        d.dist -= TERROR_BLADE_WAVE_SPEED*DD_INTERVAL;
        if (d.dist < 0.) {
         d.wave.destroy();
         d.destroy();
         DDQuitTim();
        }
       });
       BlzSetEventDamage(GetEventDamage() + TERROR_EXTRA_DAMAGE[lvl]);
       //UnitDamageTarget(u, v, TERROR_EXTRA_DAMAGE[lvl], true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS);
       static if (SHOW_FLOATING_TEXT)
        DDNewTextTagUnit(v, I2S(R2I(TERROR_EXTRA_DAMAGE[lvl]))+"!", FLOATING_TEXT_DURATION, FT_COLOR[00], FT_COLOR[01], FT_COLOR[02], FT_COLOR[03]);
       
       t = terrorized.create();
       t.v = v;
       t.e[00] = AddSpecialEffectTarget(TARGET_ATTACHMENT_EFFECT_PATH, v, TARGET_ATTACH_POINT[01]);
       t.e[01] = AddSpecialEffectTarget(TARGET_ATTACHMENT_EFFECT_PATH, v, TARGET_ATTACH_POINT[02]);
       t.dur = TERROR_DURATION[lvl];
       t.dmy = DDLoadSpellDummy(GetOwningPlayer(u), d.x, d.y, ABILITY_TERROR_BLADE_DUMMY, lvl);
       IssueTargetOrder(t.dmy, ABILITY_TERROR_BLADE_DUMMY_ORDER, v);
       DDStartTim(.1, true, t, function() {
        terrorized t = DDTimData();
        
        t.dur -= .1;
        if (t.dur > 9.)
         return;
        if (IsUnitType(t.v, UNIT_TYPE_DEAD) || t.dur < 0. || GetUnitAbilityLevel(t.v, ABILITY_TERROR_BLADE_BUFF) == 00) {
         UnitRemoveAbility(t.dmy, ABILITY_TERROR_BLADE_DUMMY);
         DDRecycleDummy(t.dmy);
         t.v = null;
         t.dmy = null;
         DestroyEffect(t.e[00]); t.e[00] = null;
         DestroyEffect(t.e[01]); t.e[01] = null;
         t.destroy();
         DDQuitTim();
        }
       });
      }
     }
    }
    UnitAttackElapsedTime[ (id*04) + R2I(UnitAttackElapsedTime[(id*04)]) ] = at_t;
    UnitAttackElapsedTime[(id*04)] += 1.;
    if (UnitAttackElapsedTime[(id*04)] == 4.) UnitAttackElapsedTime[(id*04)] = 0.;
   }
   
   u = null; v = null;
   return false;
  }));
 }
 
}
//! endzinc




[B]

Bubble Blast

Raises 'n' water orbs from the ground which will float around the caster. After short amount of time waves will fall to the ground dealing damage to any nearby enemy and remove all positive buffs from them. Any unit which was effected will be pushed away from caster.

JASS:
//TESH.scrollpos=0
//TESH.alwaysfold=0
//**************************************************************************************
//                              Installation:
//
// - 1. Made on Warcraft III v1.30
// - 2. Go to Import Manager (F12) and extract BTNWaterExhausting.blp and its DISBTN version,
//  BubbleSpawn.mdx, WaterOrb.mdx, WaterBurst.mdx
//  water_wave.wav, water_splash1.wav, water_splash2.wav, water_splash3.wav
// - 3. Import all of this to your map and set ther path to as you can see here (in my map)
// - 4. Go to Object Manager (F6) and copy "Bubble Blast" ability.
//   When you are pasting them to your map make sure you match there rawcodes with ones below
// - 5. If you want different raw codes edit the below as well
// - 6. Copy this trigger and "DD Library" to your map
// - 7. Edit data below to your own will and enjoy the spell
//
// Credits:
//  MajorSonnwaitts, Pyritie, JetFangInferno, dueeast.com (sounds)
//
//**************************************************************************************

//! zinc
library BubbleBlast requires DDLib
{
 
 // ************************************************************************************************
 //        --- Ability Constants ---
 // ************************************************************************************************
 
 constant  integer      BUBBLE_BLAST_ABILITY_ID      = 'wtex';
 constant  boolean      BUBBLE_BLAST_REMOVE_POSITIVE_BUFFS   = true;
 constant  boolean      BUBBLE_BLAST_REMOVE_NEGATIVE_BUFFS   = false;
 // Effect attached to unit on which buffs are removed and its attach point
 constant string      BUBBLE_BLAST_REMOVE_BUFFS_MODEL_PATH  = "Abilities\\Spells\\Human\\DispelMagic\\DispelMagicTarget.mdl";
 constant string      BUBBLE_BLAST_REMOVE_BUFFS_ATTACH_POINT  = "origin";
 
 
 constant boolean      USE_KNOCKBACK         = true;
 constant real      KNOCKBACK_TRAVEL_DISTANCE     = 225.;
 constant real      KNOCKBACK_TRAVEL_SPEED      = 300.;
 constant string      KNOCKBACK_TRAVEL_GROUND_DRAG_EFFECT_PATH = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveDamage.mdl";
 constant string      KNOCKBACK_DRAG_EFFECT_ATTACH_POINT   = "foot";
 // How offten is 'KNOCKBACK_TRAVEL_GROUND_DRAG_EFFECT_PATH' effect created
 constant real      KNOCKBACK_TRAVEL_GROUND_DRAG_EFFECT_INTERVAL= 0.25;
 
 // ************************************************************************************************
 //        --- Effect Constants ---
 // ************************************************************************************************
 
 constant string      BUBBLE_SPAWN_MODEL_PATH      = "Spells\\BubbleBlast\\BubbleSpawn.mdx";
 constant real      BUBBLE_SPAWN_MODEL_SIZE      = 0.5;
 constant real      BUBBLE_SPAWN_MODEL_MIN_DURATION    = 7.;
 constant real      BUBBLE_SPAWN_MODEL_MAX_DURATION    = 9.;
 
 constant string      WATER_ORB_MODEL_PATH      = "Spells\\BubbleBlast\\WaterOrb.mdx";
 constant real      WATER_ORB_MODEL_SIZE      = 2.;
 constant real      WATER_ORB_TRAVEL_SPEED      = 330.;
 // Apcisa (X) direction only motion. The way ellipse works is that virtual points move around caster
 // at x-axes 'WATER_ORB_ELLIPSE_X_TRAVEL_SPEED', while y is calculated. Orb then based on its position
 // moves towards that virtual point from its current location
 constant real      WATER_ORB_ELLIPSE_X_TRAVEL_SPEED   = 190.;
 // ellipse a = value based on 'BUBBLE_SPAWN_MIN/MAX_AOE', while ellipse b = a*'WATER_ORB_ELLIPSE_FACTOR'
 constant  real      WATER_ORB_ELLIPSE_FACTOR     = 0.66;
 // gravity actiong on orb when it starts falling defined in coordinates per square second
 constant real      WATER_ORB_FALL_ACCELERATION     = 555.555;
 constant real      WATER_ORB_MIN_HEIGHT      = 100.;
 constant real      WATER_ORB_MAX_HEIGHT      = 400.;
 
 constant string      WATER_BLAST_MODEL_PATH      = "Spells\\BubbleBlast\\WaterBurst.mdx";
 constant real      WATER_BLAST_MODEL_SIZE      = 0.5;
 constant real      WATER_BLAST_MODEL_DURATION     = 1.33;
 
 constant string      WATER_BLAST_AFTEREFFECT_MODEL_PATH   = "Doodads\\Icecrown\\Water\\BubbleGeyserSteam\\BubbleGeyserSteam.mdx";
 constant real      WATER_BLAST_AFTEREFFECT_MODEL_SIZE   = 1.15;
 constant real      WATER_BLAST_AFTEREFFECT_MODEL_DURATION  = 6.5;
 
 // ************************************************************************************************
 //        --- Sounds Constants ---
 // ************************************************************************************************
 
 constant string      BUBBLE_SPWAN_START_SOUND_PATH    = "Custom\\Spells\\BubbleBlast\\water_wave.wav";
 constant real      BUBBLE_SPWAN_START_SOUND_VOLUME    = 70.;
 constant string      WATER_ORB_IMPACT_SOUND_PATH_01    = "Custom\\Spells\\BubbleBlast\\water_splash1.wav";
 constant real      WATER_ORB_IMPACT_SOUND_VOLUME_01   = 70.;
 constant string      WATER_ORB_IMPACT_SOUND_PATH_02    = "Custom\\Spells\\BubbleBlast\\water_splash2.wav";
 constant real      WATER_ORB_IMPACT_SOUND_VOLUME_02   = 70.;
 constant string      WATER_ORB_IMPACT_SOUND_PATH_03    = "Custom\\Spells\\BubbleBlast\\water_splash3.wav";
 constant real      WATER_ORB_IMPACT_SOUND_VOLUME_03   = 70.;
 constant real      SOUND_MAX_DISTANCE       = 3500.;
 
 
 
 // ---------------------------------------------------------------------
 //    "non-EDITABLE", just declarations!
 // ---------------------------------------------------------------------
 integer  BUBBLE_SPWAN_COUNT[];
 real   WATER_ORB_MIN_DURATION[], WATER_ORB_MAX_DURATION[];
 real   BUBBLE_SPAWN_MIN_AOE[], BUBBLE_SPAWN_MAX_AOE[];
 real  WATER_BLAST_DAMAGE[], WATER_BLAST_AOE[];
 // ---------------------------------------------------------------------
 
 
 function BubbleBlastLevelSetup() {
  // How much orbs are created per level?
  // Level 01 Default: 9
  // Level 02 Default: 11
  // Level 03 Default: 12
  BUBBLE_SPWAN_COUNT[01] = 9;
  BUBBLE_SPWAN_COUNT[02] = 11;
  BUBBLE_SPWAN_COUNT[03] = 12;
 
  // Within min and max range from caster, orbs and bubbles spawn!
  // Level 01 Default: MIN = 200, MAX = 400
  // Level 02 Default: MIN = 200, MAX = 450
  // Level 03 Default: MIN = 200, MAX = 500
  BUBBLE_SPAWN_MIN_AOE[01] = 200.; BUBBLE_SPAWN_MAX_AOE[01] = 400.;
  BUBBLE_SPAWN_MIN_AOE[02] = 200.; BUBBLE_SPAWN_MAX_AOE[02] = 450.;
  BUBBLE_SPAWN_MIN_AOE[03] = 200.; BUBBLE_SPAWN_MAX_AOE[03] = 500.;
 
  // Once water orbs spawn, how long does each one of them last,
  // if min and max are not equal, then each orb lasts for its own duration.
  // Level 01: Min Default: 4.5, Max Default: 6.5
  // Level 02: Min Default: 3.75, Max Default: 5.75
  // Level 03: Min Default: 2.75, Max Default: 4.5
  WATER_ORB_MIN_DURATION[01] = 4.5; WATER_ORB_MAX_DURATION[01] = 6.5;
  WATER_ORB_MIN_DURATION[02] = 3.75; WATER_ORB_MAX_DURATION[02] = 5.75;
  WATER_ORB_MIN_DURATION[03] = 2.75; WATER_ORB_MAX_DURATION[03] = 4.5;
 
  // Upon water burst explosion, how much damage is dealt?
  // Level 01 Default: 100
  // Level 02 Default: 150
  // Level 03 Default: 210
  WATER_BLAST_DAMAGE[01] = 100.;
  WATER_BLAST_DAMAGE[02] = 150.;
  WATER_BLAST_DAMAGE[03] = 210.;
 
  // Upon water burst explosion, what is the radius in which units are damaged?
  // Level 01 Default: 150
  // Level 02 Default: 150
  // Level 03 Default: 150
  WATER_BLAST_AOE[01] = 150.;
  WATER_BLAST_AOE[02] = 150.;
  WATER_BLAST_AOE[03] = 150.;
 }
 
 // *** Which units should be damaged? '!' represents not / inverted
 function WaterBlastUnitFilter(unit f, player castingPlayer) -> boolean {
  return !IsUnitType(f, UNIT_TYPE_STRUCTURE)    &&
      !IsUnitType(f, UNIT_TYPE_DEAD)     &&
      !IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE)   &&
      !IsUnitType(f, UNIT_TYPE_MECHANICAL)    &&
      !IsUnitType(f, UNIT_TYPE_FLYING)     &&
      IsUnitEnemy(f, castingPlayer)     &&
      !BlzIsUnitInvulnerable(f)      &&
      !DDIsUnitWard(f);
 }
 
 // ===========================================================================================
 //    ***************************************************************
 //       *** Spell Code | "non-EDITABLE" ***
 //    ***************************************************************
 // ===========================================================================================
 
 /*public function testAA(unit f) {
  if (IsUnitType(f, UNIT_TYPE_FLYING))
   DDMsg("a");
  if (IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE))
   DDMsg("b");
  if (BlzIsUnitInvulnerable(f))
   DDMsg("c");
 }*/
 
 struct knockback {
  unit u;
  real tim=0.;
  real dist, spd, dx, dy;
 
  static boolean Flag[];
 }
 
 struct waterorb {
  unit u;
  ddeffect orb;
  integer lvl;
  real el_x, el_y, z;
  real x_spd, y_sign, rad_offset;
  real a, b;
  real dur;
 
  method destroy() {
   u = null;
   orb.destroy();
   deallocate();
  }
 
  method GetCoords() {
   el_x += x_spd;
   if (x_spd > 0.) {
    if (el_x > a) {
     x_spd = -x_spd;
     y_sign = -y_sign;
    }
   } else {
    if (el_x < -a) {
     x_spd = -x_spd;
     y_sign = -y_sign;
    }
   }
   el_y = b*y_sign*SquareRoot(1.-Pw_2(el_x/a));
  }
 
  method ApplyMotion() {
   real x, y;
   real dist;
 
   this.GetCoords();
   x = GetWidgetX(u);
   y = GetWidgetY(u);
 
   x += el_x * Cos(rad_offset);
   y += el_x * Sin(rad_offset);
 
   x += el_y * Cos(rad_offset+(bj_PI/2.));
   y += el_y * Sin(rad_offset+(bj_PI/2.));
 
   //rad = Atan2(y-orb.Y, x-orb.X);
   dist = SquareRoot(DDHypot(x-orb.X, y-orb.Y) + Pw_2(z-orb.Z));
   orb.PositionZ(orb.X + (WATER_ORB_TRAVEL_SPEED*DD_INTERVAL*((x-orb.X)/dist)),
        orb.Y + (WATER_ORB_TRAVEL_SPEED*DD_INTERVAL*((y-orb.Y)/dist)),
        orb.Z + (WATER_ORB_TRAVEL_SPEED*DD_INTERVAL*((z-orb.Z)/dist)));
  }
 
  method ApplyFall() {
   x_spd += WATER_ORB_FALL_ACCELERATION*DD_INTERVAL*DD_INTERVAL;
   orb.Z -= x_spd;
  }
 
  method OrbDetonate() {
   integer rnd_snd = DDGetRndInt(01, 03);
   effect e;
 
   if (rnd_snd == 01)
    DDGenericSound(WATER_ORB_IMPACT_SOUND_PATH_01, WATER_ORB_IMPACT_SOUND_VOLUME_01, orb.X, orb.Y, SOUND_MAX_DISTANCE, 1.);
   else if (rnd_snd == 02)
    DDGenericSound(WATER_ORB_IMPACT_SOUND_PATH_02, WATER_ORB_IMPACT_SOUND_VOLUME_02, orb.X, orb.Y, SOUND_MAX_DISTANCE, 1.);
   else
    DDGenericSound(WATER_ORB_IMPACT_SOUND_PATH_03, WATER_ORB_IMPACT_SOUND_VOLUME_03, orb.X, orb.Y, SOUND_MAX_DISTANCE, 1.);
 
   e = AddSpecialEffect(WATER_BLAST_MODEL_PATH, orb.X, orb.Y);
   BlzPlaySpecialEffect(e, ANIM_TYPE_STAND);
   BlzSetSpecialEffectScale(e, WATER_BLAST_MODEL_SIZE);
   DDDestroyEffectTimed(e, WATER_BLAST_MODEL_DURATION);
 
   e = AddSpecialEffect(WATER_BLAST_AFTEREFFECT_MODEL_PATH, orb.X, orb.Y);
   BlzSetSpecialEffectScale(e, WATER_BLAST_AFTEREFFECT_MODEL_SIZE);
   DDDestroyEffectTimed(e, WATER_BLAST_AFTEREFFECT_MODEL_DURATION); e = null;
 
   DDGroupFilterArea(orb.X, orb.Y, WATER_BLAST_AOE[lvl], this, function() {
    waterorb wo = DDGFilterData();
    unit f = GetFilterUnit();
    knockback kb;
    real rad;
 
    if (WaterBlastUnitFilter(f, GetOwningPlayer(wo.u))) {
     UnitRemoveBuffs(f, BUBBLE_BLAST_REMOVE_POSITIVE_BUFFS, BUBBLE_BLAST_REMOVE_NEGATIVE_BUFFS);
     //bj_lastCreatedUnit = DDLoadDummy();
     DDSpellDamage(wo.u, f, WATER_BLAST_DAMAGE[wo.lvl]);
     //DDSpellDamage(bj_lastCreatedUnit, f, WATER_BLAST_DAMAGE[wo.lvl]);
     //DDRecycleDummy(bj_lastCreatedUnit);
     DestroyEffect(AddSpecialEffectTarget(BUBBLE_BLAST_REMOVE_BUFFS_MODEL_PATH, f, BUBBLE_BLAST_REMOVE_BUFFS_ATTACH_POINT));
  
     static if (USE_KNOCKBACK) {
      if (knockback.Flag[H2ID(f)]) {
       f = null;
       return;
      }
   
      knockback.Flag[H2ID(f)] = true;
      kb = knockback.create();
      PauseUnit(f, true);
      kb.u = f;
      kb.dist = KNOCKBACK_TRAVEL_DISTANCE;
      kb.spd = KNOCKBACK_TRAVEL_SPEED*DD_INTERVAL;
      rad = Atan2(GetWidgetY(f)-GetWidgetY(wo.u), GetWidgetX(f)-GetWidgetX(wo.u));
      kb.dx = kb.spd * Cos(rad);
      kb.dy = kb.spd * Sin(rad);
      DDStartTim(DD_INTERVAL, true, kb, function() {
       knockback kb = DDTimData();
    
       kb.tim += DD_INTERVAL;
       if (ModuloReal(kb.tim, KNOCKBACK_TRAVEL_GROUND_DRAG_EFFECT_INTERVAL) <= DD_INTERVAL)
        DestroyEffect(AddSpecialEffectTarget(KNOCKBACK_TRAVEL_GROUND_DRAG_EFFECT_PATH, kb.u, KNOCKBACK_DRAG_EFFECT_ATTACH_POINT));
    
       SetUnitPosition(kb.u, GetWidgetX(kb.u) + kb.dx, GetWidgetY(kb.u) + kb.dy);
    
       kb.dist -= kb.spd;
       if (kb.dist < 0.) {
        knockback.Flag[H2ID(kb.u)] = false;
        PauseUnit(kb.u, false);
        kb.u = null;
        kb.destroy();
        DDQuitTim();
       }
      });
     }
    }
 
    f = null;
   });
  }
 
 }
 
 //b*sqrt(1-(x/a)^2) = y
 function onInit() {
  trigger t = CreateTrigger();
 
  BubbleBlastLevelSetup();
 
  TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
  TriggerAddCondition(t, Condition(function() -> boolean {
   unit u;
   integer i, lvl;
   effect e;
   real x, y, tx, ty;
   real dist, rad;
   waterorb wo;
 
   if (GetSpellAbilityId() != BUBBLE_BLAST_ABILITY_ID)
    return false;
 
   u = GetTriggerUnit();
   x = GetWidgetX(u);
   y = GetWidgetY(u);
   lvl = GetUnitAbilityLevel(u, BUBBLE_BLAST_ABILITY_ID);
 
   DDGenericSound(BUBBLE_SPWAN_START_SOUND_PATH, BUBBLE_SPWAN_START_SOUND_VOLUME, x, y, SOUND_MAX_DISTANCE, 1.);
 
   for(i=00; i < BUBBLE_SPWAN_COUNT[lvl]; i+=01) {
    dist = DDGetRndReal(BUBBLE_SPAWN_MIN_AOE[lvl], BUBBLE_SPAWN_MAX_AOE[lvl]);
    rad = GetRandomReal(0., 2.*bj_PI);
    tx = x + dist * Cos(rad);
    ty = y + dist * Sin(rad);
    e = AddSpecialEffect(BUBBLE_SPAWN_MODEL_PATH, tx, ty);
    BlzSetSpecialEffectScale(e, BUBBLE_SPAWN_MODEL_SIZE);
    DDDestroyEffectTimed(e, DDGetRndReal(BUBBLE_SPAWN_MODEL_MIN_DURATION, BUBBLE_SPAWN_MODEL_MAX_DURATION));
 
    wo = waterorb.create();
    wo.u = u;
    wo.orb = ddeffect.create(WATER_ORB_MODEL_PATH, tx, ty, GetRandomReal(0., 2.*bj_PI), WATER_ORB_MODEL_SIZE);
    wo.a = dist; wo.b = dist*WATER_ORB_ELLIPSE_FACTOR;
    wo.rad_offset = rad;
    wo.y_sign = 1.; if (GetRandomInt(00, 01) == 01) wo.y_sign = -1.;
    wo.x_spd = -WATER_ORB_ELLIPSE_X_TRAVEL_SPEED*DD_INTERVAL;
    wo.z = DDTerrZ(tx, ty) + DDGetRndReal(WATER_ORB_MIN_HEIGHT, WATER_ORB_MAX_HEIGHT);
    wo.dur = DDGetRndReal(WATER_ORB_MIN_DURATION[lvl], WATER_ORB_MAX_DURATION[lvl]);
    wo.lvl = lvl;
 
    DDStartTim(DD_INTERVAL, true, wo, function() {
     waterorb wo = DDTimData();
  
     if (wo.dur > 0. && !IsUnitType(wo.u, UNIT_TYPE_DEAD)) {
      wo.ApplyMotion();
      wo.dur -= DD_INTERVAL;
     } else {
      wo.ApplyFall();
      if (wo.orb.Z < 5.) {
       wo.OrbDetonate();
       wo.destroy();
       DDQuitTim();
      }
     }
    });
   }
 
   u = null;
   e = null;
   return false;
  }));
 }
 
}
//! endzinc
[/B]





Main


Main

Crazyrussian (BTNCRFrostShock)
VaLkYroN
Tranquil
jigrael
Vexorian (JassHelper) (Dummy)
shamanyouranus
JetFangInferno (Blizzard Eruption)
Daelin (Frozen Orb)
Hueter
Anachron
SkriK
bananaHUNT
Dan van Ohllus (DvO's Winter Effects)
KelThuzad (BTNReflex)
Skizzik
Erdie
MajorSonnwaitts (BubblesBuff)
Pyritie (Water High and Uber)
PrinceYaser (BTNNecromancy)
UgoUgo (NecroticBlast)

therecordist.com
freesound.org
dueeast.com (dueeast.com/watersounds.html)

Other

Blizzard
Hive Workshop
JassNewGen Pack team.
Audacity
Notepad++

Additional:

TheBlooddancer
-JonNny
Deaod
s4nji
and every one else who helped.







Q: Does this work with default JNGP?
A: Yes

Q: It took you long to release this patch! will there be v5?
A: No, this is the last version of DDUP spell pack.

Q: Will you make a new spell pack with more spells?
A: Maybe in zinc with new libraries. That ofc is not my priority as i am currently working on campaign and that shall take me more than enough time for coding and overall making mods, spells... Still not sure but maybe ill make a new spell pack.
Currently it is unknown.

Q: Is there at least one spell in GUI?
A: No

Q: Will you convert any of spells from vjass to GUI?
A: No

Q: Are this spells only for melee maps?
A: All of spells are made as for melee maps but you can use them in any map, as they are easy to modify. They have as well "max damage" deal to configure, making sure that they are not overpowered.

Q: I dont know jass and i want to install few spells in my map, can you help?
A: Yes! there is an block of comments at beginning of every spell which tells you exactlly on how to install spell in your map.

Q: Its said that this spells are fully editable but there is no such an option!
A: This options are not in "Object Editor" ofc you must edit them in Object Editor but main spell setup is done in custom script at beginning of each spell.

Q: Ok i found that text so what to do now?
A: Each variable of this you will see can be set to your own value to completelly remake my spells to your own will. Each variable does something different and comments above them say what each value does.

Q: I want to use this spells in my map which will be for multiplayer at battle.net, are they MUI?
A: Yes

Q: I can see a lot of lines even through i dont know jass other spells usually have about 300 or less lines, is this slow?
A: Should not be, but best is to test it on your own PC

Q: I have slow CPU, low RAM... i need to decrease FPS, can i do that and how?
A: Some spells have that editable already in globals section for users. New ones do not have that there since its not a part of something that spell should change and in fact this is my own constatn which can ofc be editable by you. Go to selected spell and press Alt Gr + F -> search dialog will appear. There write TIMER_DELAY press enter. It will point you to constant value you will see it points to 0.025 which is 40 FPS. If you want to change it set it to (1 / Your FPS).

Q: Do your spells leak? Do you use AnyUnitEventBJ which leak filters?
A: No. No.






All custom code from my DD Library

JASS:
//==========================================================================
//                  Dark Dragon Library Code v1.3
//
//      * Made on Warcraft III v1.30.4
//
//  Installation:
//               
//                  1) Export instantdummy.mdx from this map and import it to your map, leave path at "war3mapImported/instantdummy.mdx"
//                  2) Copy this trigger to your map, save your map and then change below line "// external ... " or copy "DD Dummy" and paste it in your map
//     3) Copy and paste "Unit Chill" ability from this map to your map
//     4) Match the rawcodes below to your map or use same ones as below
//
// Credits:
//          ('Vexorian' - dummy.mdx)
//============================================================================

// *** Change "// external" to "//! external", save your map, close map, change back from "//!" to "//" and save map again.
// *** This will create dummy in your map
//
// ==================================
// external ObjectMerger w3u ushd dumy uabi "Aloc,Amrf" uble 0 ucbs 0 ucpt 0 umxp 0 umxr 0 umdl "war3mapImported\instantdummy.mdx" ushu "None" umvh 0 umvs 1 umas 1 umis 1 ucol 0 ufoo 0 uhom 1 umpi 10000 umpm 10000 usid 1 usin 1 unam "DD Dummy"
// ==================================


//! zinc

library DDLib requires optional TimerUtils, optional GroupUtils
{
 
    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
    // *** Lib constants ***
    public {
     
  // ----------------------------------------------------------------------
  // * Start modify/match rawcodes to your map
        constant        integer     DD_DUMMYCODE       = 'dumy';
        constant        integer     DD_ABILITY_CROWN_FORM     = 'Amrf';
  constant   integer  DD_CHILL     = 'Achl';
  constant   integer  DD_CHILL_BUFF    = 'Bfro';
  // * End modify
  // ----------------------------------------------------------------------
 
 
  constant        integer     p_null             = (0x0);
        constant        real        DD_INTERVAL       = .017;
     
                        // map min and max coords
                        real        DDMinX             = 0.;
                        real        DDMinY             = 0.;
                        real        DDMaxX             = 0.;
                        real        DDMaxY             = 0.;
    }
 
 private {
  constant   integer  HARVEST_ID     = 'Ahrl';
  constant  real  TRIGGER_REFRESH_RATE  = (60.)*3.; /// damage detection trigger
                     
                        unit   TreeChecker              = null;
      trigger  TempTrig      = null;
      integer  NTrig       = 0;
      trigger  DmgTrig[];
      p_real   EnumVec      = p_null;
      boolexpr  EnumFilter      = null;
      sound  ErrorSound     = null;
      timer  GameElapsedTimer   = null;
  constant   integer  RND_INT_MAX_ARRAY_N   = 100;
      integer  RndInt[], RndIntWriteN = 00, RndIntReadN = 00;
      trigger  TrigMouseEvent     = null;
      force   RndGenForce     = null;
      real   RndElapsedTime     = 0.;
 }
    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
 
    // * types
    public {
     
        // *** pointer to list of data ***
        type    p_integer           extends     integer[8];
        type    p_real              extends     real[8];
        type    p_unit              extends     unit[8];
     
  function H2ID(handle h) -> integer {
   return GetHandleId(h) - 0x100000;
  }
 
        function New_pInteger(integer i) -> p_integer
        { p_integer p = p_integer.create(); p[0] = i; return p; }
        function New_pReal(real r) -> p_real
  { p_real p = p_real.create(); p[0] = r; return p; }
        function New_pUnit(unit u) -> p_unit
  { p_unit p = p_unit.create(); p[0] = u; return p; }
     
  function pVector(real x, real y, real z) -> p_real {
   p_real v = p_real.create();
   v[0] = x; v[1] = y; v[2] = z;
   return v;
  }
 
  // --------------------------------------------------------------------------------------
 
  function DDMsg(string str) {
   DisplayTimedTextFromPlayer(GetLocalPlayer(), 0., 0., 30., str);
  }
 
  // --------------------------------------------------------------------------------------
 
  function DisplayErrorMsgPlayer(player p, real dur, string msg) {
   if (GetLocalPlayer() == p) {
    StartSound(ErrorSound);
    DisplayTimedTextFromPlayer(p, 0., 0., dur, "|cffffcc00"+ msg +"|r");
   }
  }

    }
 
    // -----------------------------------------------------------------------
    // ->           ***** private globals *****
    // -----------------------------------------------------------------------
    private {
        location    TempLoc         = Location(0., 0.);
        timer       TimerStack[];
        integer     TimN            = 0;
        group       GroupStack[];
        integer     GrpN            = 0;
        unit        DummyStack[];
        integer     DumN            = 0;
  integer  TimTicks[];
  integer  TimData[];
  timer  TimTim1[];
  timer  TimTim2[];
 
 
  integer  UnitStackData = 0;
  unit  UnitStack[];
  integer  US_N   = 0;
     
        public hashtable   DDHT            = InitHashtable();
    }
    // -----------------------------------------------------------------------
 
   public {
 
        // *** Global funcs
     
        function Pw_2(real x) -> real {
            return x*x;
        }
 
  function DDHypot(real x, real y) -> real {
   return (x*x) + (y*y);
  }
     
        function DDTerrZ(real x, real y) -> real {
            MoveLocation(TempLoc, x, y);
            return GetLocationZ(TempLoc);
        }
     
        function DDWidgetTerrZ(widget w) -> real {
   MoveLocation(TempLoc, GetWidgetX(w), GetWidgetY(w));
            return GetLocationZ(TempLoc);
        }
 
  function DDEffectTerrZ(effect e) -> real {
   MoveLocation(TempLoc, BlzGetLocalSpecialEffectX(e), BlzGetLocalSpecialEffectY(e));
            return GetLocationZ(TempLoc);
  }
 
  function DDGetUnitZ(unit u) -> real {
   return BlzGetUnitZ(u) + GetUnitFlyHeight(u);
  }
     
        // =================================================================
        //              *** Save Handle data ****
        // =================================================================
     
        function DDSet(handle h, integer id, integer val) {
            SaveInteger(DDHT, id+1, GetHandleId(h), val);
        }
     
        function DDGet(handle h, integer id) -> integer {
            return LoadInteger(DDHT, id+1, GetHandleId(h));
        }
 
  function DDHas(handle h, integer id) -> boolean {
   return HaveSavedInteger(DDHT, id+1, GetHandleId(h));
  }
 
  function DDFlush(integer id) {
   FlushChildHashtable(DDHT, id+1);
  }
     
        // =================================================================
        //              *** Timer Handling ****
        // =================================================================
 
  // -> check if timer is recycled
  function DDIsTimRecycled(timer t) -> boolean {
   integer i;
   for(i=TimN-01; i >= 00; i-=01)
    if (TimerStack[i] == t)
     return true;
   return false;
  }
 
        // -> Load timer for recycling
        function DDLoadTim() -> timer {
            static if (LIBRARY_TimerUtils) { return NewTimer(); }
            else {
                if (TimN > 0) {
                    TimN -= 1;
                    return TimerStack[TimN];
                }
                return CreateTimer();
            }
        }
     
        // -> recycle loaded timer
        function DDRecycleTim(timer t) {
            static if (LIBRARY_TimerUtils) { ReleaseTimer(t); }
            else {
    static if (DEBUG_MODE)
     if (DDIsTimRecycled(t)) {
      DDMsg("Multiple recycle of timer!");
      return;
     }
                TimerStack[TimN] = t;
                TimN += 1;
            }
        }
     
        // ** Get data stored on expired timer
        function DDTimData() -> integer {
            return TimData[H2ID(GetExpiredTimer())];
        }
 
  // *** Custom timer tick
        function DDCTimTick(timer t) -> integer {
            return TimTicks[H2ID(t)];
        }
 
  // *** Gets current tick and adds next one ***
        function DDTimTick() -> integer {
   integer id = H2ID(GetExpiredTimer());
   TimTicks[id] += 01;
            return TimTicks[id];
        }
     
        // ** start timer with data storage
        function DDStartTim(real secs, boolean looping, integer pdata, code func) -> timer {
            timer t = DDLoadTim();
 
   TimData[H2ID(t)] = pdata;
            TimerStart(t, secs, looping, func);
            return t;
        }
     
        // ** start timer with data storage, and launches it instantly
        function DDStartTimInst(real secs, boolean looping, integer pdata, code func) -> timer {
            timer t1 = DDLoadTim(), t2 = DDLoadTim(), t3 = DDLoadTim();
         
   TimData[H2ID(t2)] = pdata;
            TimerStart(t2, 0., false, func);
 
   TimTim1[H2ID(t3)] = t1;
   TimTim2[H2ID(t3)] = t2;
   TimerStart(t3, .005, false, function() {
    timer t = GetExpiredTimer();
    integer id = H2ID(t);
 
    PauseTimer(t);
    static if (LIBRARY_TimerUtils)
     ReleaseTimer(t);
    else {
     TimerStack[TimN] = t;
     TimN += 1;
    }
 
    t = TimTim2[id];
    if (DDIsTimRecycled(t))
     t = TimTim1[id];
    TimTicks[H2ID(t)] = 00;
    PauseTimer(t);
    static if (LIBRARY_TimerUtils)
     ReleaseTimer(t);
    else {
     TimerStack[TimN] = t;
     TimN += 1;
    }
   });
 
   TimData[H2ID(t1)] = pdata;
            TimerStart(t1, secs, looping, func);
         
            return t1;
        }
     
        // *** Quit expired timer ***
        function DDQuitTim() {
   timer t = GetExpiredTimer();
   TimTicks[H2ID(t)] = 00;
            PauseTimer(t);
   static if (LIBRARY_TimerUtils)
    ReleaseTimer(t);
            else {
                TimerStack[TimN] = t;
                TimN += 1;
            }
        }
 
  function DDQuitTimEx(timer t) {
   TimTicks[H2ID(t)] = 00;
            PauseTimer(t);
   static if (LIBRARY_TimerUtils)
    ReleaseTimer(t);
            else {
                TimerStack[TimN] = t;
                TimN += 1;
            }
        }
     
        // =================================================================
        //              *** Group Handling ****
        // =================================================================
     
        // -> Load timer for recycling
        function DDLoadGroup() -> group {
            static if (LIBRARY_GroupUtils) { return NewGroup(); }
            else {
                if (GrpN > 0) {
                    GrpN -= 1;
                    return GroupStack[GrpN];
                }
                return CreateGroup();
            }
        }
     
        // -> Recycle group
        function DDRecycleGroup(group g) {
            static if (LIBRARY_GroupUtils) { ReleaseGroup(g); }
            else {
    GroupClear(g);
                GroupStack[GrpN] = g;
                GrpN += 1;
            }
        }
     
        // --------------------------------------------------------
        // -- Quick filter area
  private integer GroupFilterData = 00;
 
        function DDGroupFilterArea(real x, real y, real radius, integer data, code func) {
            group g = DDLoadGroup();
   GroupFilterData = data;
            GroupEnumUnitsInRange(g, x, y, radius, Filter(func));
            DDRecycleGroup(g);
        }
     
        // --------------------------------------------------------
        // -- Quick filter rect
        function DDGroupFilterRect(rect r, integer data, code func) {
            group g = DDLoadGroup();
   GroupFilterData = data;
            GroupEnumUnitsInRect(g, r, Filter(func));
            DDRecycleGroup(g);
        }
     
  function DDGFilterData() -> integer {
   return GroupFilterData;
  }
 
  function DDGFilterDataSet(integer data) {
   GroupFilterData = data;
  }
 
  // --------------------------------------------------------
        // *** Filtrates and fills units in to memory
        function DDGroupFillMemArea(real x, real y, real radius, integer data, code filter) {
   group g = DDLoadGroup();
   boolexpr exp = And(Filter(filter), Filter(function() -> boolean {
    UnitStack[US_N] = GetFilterUnit();
    US_N += 1;
    return false;
   }));
   US_N = 0;
   UnitStack[0] = null;
   UnitStackData = data;
   GroupEnumUnitsInRange(g, x, y, radius, exp);
   DDRecycleGroup(g);
   DestroyBoolExpr(exp);
   exp = null;
  }
 
  function DDGroupFillMemRect(rect r, integer data, code filter) {
   group g = DDLoadGroup();
   boolexpr exp = And(Filter(filter), Filter(function() -> boolean {
    UnitStack[US_N] = GetFilterUnit();
    US_N += 1;
    return false;
   }));
   US_N = 0;
   UnitStack[0] = null;
   UnitStackData = data;
   GroupEnumUnitsInRect(g, r, exp);
   DDRecycleGroup(g);
   DestroyBoolExpr(exp);
   exp = null;
  }
 
  function DDMemUnitN() -> integer { return US_N; }
  function DDMemUnitData() -> integer { return UnitStackData; }
 
  function DDMemUnit(integer index) -> unit {
   if (US_N == 0) return null;
   debug {
    if (index < 0) {
     BJDebugMsg("DDMemUnit: index less than 0");
     index = 0;
    } else if (index >= US_N) {
     BJDebugMsg("DDMemUnit: index greater than units alloc size");
     index = 0;
    }
   }
   return UnitStack[index];
  }
  // --------------------------------------------------------
 
  // --------------------------------------------------------
  // ***
     
        // =================================================================
        //              *** Dummy Handling ****
        // =================================================================
     
        // -> Load dummy for recycling
        function DDLoadDummy() -> unit {
            if (DumN > 0) {
                DumN -= 1;
                PauseUnit(DummyStack[DumN], false);
                return DummyStack[DumN];
            }
            return CreateUnit(Player(0xF), DD_DUMMYCODE, DDMaxX, DDMaxY, 0.);
        }
     
        // *** prepares/setups dummy for spell casting
        function DDLoadSpellDummy(player owner, real x, real y, integer abil, integer abilLevel) -> unit {
            unit dummy = DDLoadDummy();
            SetUnitOwner(dummy, owner, false);
            SetUnitX(dummy, x);
            SetUnitY(dummy, y);
            if (abil != p_null) {
                UnitAddAbility(dummy, abil);
                SetUnitAbilityLevel(dummy, abil, abilLevel);
            }
            return dummy;
        }
     
        // -> Recycle dummy
        function DDRecycleDummy(unit u) {
            PauseUnit(u, true);
            DummyStack[DumN] = u;
            DumN += 1;
        }
     
        // -> Recycle dummy timed
        function DDRecycleDummyTimed(unit u, real secs) {
            DDStartTim(secs, false, New_pUnit(u), function() {
                DDRecycleDummy(p_unit(DDTimData())[0]);
                p_unit(DDTimData()).destroy();
                DDQuitTim();
            });
        }
     
        // *** shares vision for timed amount, usually for dummy casting
        function DDUnitShareVisionTimed(unit u, player toP, real secs) {
            p_integer pi = p_integer.create();
         
            pi[0] = New_pUnit(u);
            pi[1] = GetPlayerId(toP);
            UnitShareVision(u, toP, true);
            DDStartTim(secs, false, pi, function() {
                p_integer pi = DDTimData();
             
                UnitShareVision(p_unit(pi[0])[0], Player(pi[1]), false);
                p_unit(pi[0])[0] = null;
                p_unit(pi[0]).destroy();
                pi.destroy();
                DDQuitTim();
            });
         
        }
 
        // *** Remove ability timed ***
        private struct uratimed {
            private {
                unit u;
                integer abil;
            }
         
            static method create(unit whichUnit, integer id, real time) -> uratimed {
                thistype this = allocate();
             
                u = whichUnit;
                abil = id;
                DDStartTim(time, false, this, function() {
                    thistype this = DDTimData();
                    UnitRemoveAbility(u, abil);
                    DDQuitTim();
                    deallocate();
                });
             
                return 0;
            }
        }
        function DDRemoveAbilityTimed(unit u, integer abil, real secs) { uratimed.create(u, abil, secs); }
     
  function DDSpellDamage(unit u, unit v, real dmg) {
   real life = GetWidgetLife(v);
   real dmgfactor = 1.;
 
   if (IsUnitType(v, UNIT_TYPE_HERO)) {
    if (UnitHasItemOfTypeBJ(v, 'brac'))
     dmgfactor = .5;
    else
     dmgfactor = .75;
   }
 
   if (life > dmg*dmgfactor) {
    SetWidgetLife(v, life-(dmg*dmgfactor));
   } else
    UnitDamageTarget(u, v, 99999., false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS);
  }
 
  // -------------------------------------------------------------------------------------
  // *** Chills target unit
  private struct chill {
   unit u, dmy;
   real dur;
 
   static chill Data[];
   //static key CHILL_KEY;
  }
 
  function DDUnitChill(player p, unit u, real dur) -> boolean {
   //chill c = DDGet(u, chill.CHILL_KEY);
   chill c = chill.Data[H2ID(u)];
   unit d;
   real rad;
 
 
   if (c == p_null) {
    c = chill.create();
    c.u = u; c.dur = dur;
    chill.Data[H2ID(u)] = c;
    //DDSet(u, chill.CHILL_KEY, c);
 
    d = DDLoadDummy();
    c.dmy = d;
    rad = GetUnitFacing(d) * bj_DEGTORAD;
    SetUnitOwner(d, p, false);
    UnitAddAbility(d, DD_CHILL);
    SetUnitX(d, GetUnitX(u) - 20.*Cos(rad));
    SetUnitY(d, GetUnitY(u) - 20.*Sin(rad));
 
    if (IssueTargetOrder(d, "frostnova", u)) {
     DDStartTim(.1, true, c, function() {
      chill c = DDTimData();
   
      c.dur -= .1;
      if (c.dur <= 0. || GetUnitAbilityLevel(c.u, DD_CHILL_BUFF) == 00) {
       UnitRemoveAbility(c.u, DD_CHILL_BUFF);
       UnitRemoveAbility(c.dmy, DD_CHILL);
       DDRecycleDummy(c.dmy);
       chill.Data[H2ID(c.u)] = p_null;
       //DDSet(c.u, chill.CHILL_KEY, p_null);
       c.u = null;
       c.destroy();
       DDQuitTim();
      }
     });
     return true;
    }
 
    return false;
   }
 
   c.dur = dur;
 
   return true;
  }
 
  // ------------------------------------------------------------------------------------------------
 
  struct fade {
   unit u;
   real trans;
   real rate, e_trans, dur;
 
   static constant real INTERVAL = .1;
 
   static method create(unit u, real dur, real s_trans, real e_trans) -> fade {
    fade this = allocate();
 
    this.u = u;
    this.trans = s_trans;
    this.rate = ((e_trans-s_trans)/dur)*fade.INTERVAL;
    this.e_trans = e_trans;
    this.dur = dur;
 
    return this;
   }
  }
 
  // *** Fades unit over time ***
  public function DDFadeUnit(unit u, integer from_alpha, integer to_alpha, real duration) {
   fade f = fade.create(u,
         duration,
         from_alpha/2.55,
         to_alpha/2.55);
 
   SetUnitVertexColor(u, 255, 255, 255, from_alpha);
   // --- Start thread ---
   DDStartTim(fade.INTERVAL, true, f, function() {
    fade f = DDTimData();
 
    f.trans += f.rate;
    f.dur -= fade.INTERVAL;
    SetUnitVertexColor(f.u, 255, 255, 255, R2I(f.trans*2.55));
 
    if (f.dur < 0.) {
     SetUnitVertexColor(f.u, 255, 255, 255, R2I(f.e_trans*2.55));
     f.u = null;
     f.destroy();
     DDQuitTim();
    }
   });
     
  }
 
  // ------------------------------------------------------------------------------------------------
 
        // Check if unit is invulnerable
        function DDIsUnitInvulnerable(unit u) -> boolean {
            unit d = DDLoadDummy();
            real hp = GetWidgetLife(u);
            boolean flag;
         
            UnitDamageTarget(d, u, 1., true, false, null, null, null);
            flag = GetWidgetLife(u) == hp;
            SetWidgetLife(u, hp);
            DDRecycleDummy(d);
         
            return flag;
        }
     
        // *** check if unit is ward
        function DDIsUnitWard(unit whichUnit) -> boolean {
            return GetUnitDefaultMoveSpeed(whichUnit) == 0.;
        }
 
        // =================================================================
        //              *** Effect Handling ****
        // =================================================================
     
        // -----------------------------------------------
        // *** Define movable effect
        struct ddeffect {
            private {
                effect e;
                real fac; // facing angle in radians
                real effZ; // pitch in radians
                real decay;
    real stepTrans, cTrans, eTrans;
             
                static constant real        EFFECT_DECAY        = 5.;
            }
         
            // =========================================================================================
            // =========================================================================================
            static method create(string mdl, real x, real y, real facRad, real size) -> ddeffect {
                ddeffect this = allocate();
             
                this.e   = AddSpecialEffect(mdl, x, y);
    this.fac  = facRad;
    this.effZ = 0.;
                BlzSetSpecialEffectRoll(this.e, facRad);
    BlzSetSpecialEffectScale(this.e, size);
             
                return this;
            }
 
   static method createZ(string mdl, real x, real y, real z, real facRad, real size) -> ddeffect {
                ddeffect this = allocate();
             
                this.e   = AddSpecialEffect(mdl, x, y);
    this.fac  = facRad;
    this.effZ = z-DDTerrZ(x, y);
                BlzSetSpecialEffectRoll(this.e, facRad);
    BlzSetSpecialEffectScale(this.e, size);
    BlzSetSpecialEffectZ(this.e, z);
             
                return this;
            }
         
            // -----------------
            method destroy() {
                DestroyEffect(this.e);
                this.e = null;
                deallocate();
            }
         
            // *** destroys effect timed
            method destroyx(real decayTime) {
                DDStartTim(decayTime, false, this, function() {
     ddeffect se = DDTimData();
     BlzSetSpecialEffectPosition(se.e, DDMaxX, DDMaxY, 0.);
                    DestroyEffect(se.e);
     se.e = null;
     se.deallocate();
                    DDQuitTim();
                });
            }
            // =========================================================================================
            // =========================================================================================
         
 
         
   method operator Z=(real z)     { BlzSetSpecialEffectZ(this.e, z); }
 
            method operator X() -> real                 { return BlzGetLocalSpecialEffectX(this.e); }
            method operator Y() -> real                 { return BlzGetLocalSpecialEffectY(this.e); }
            method operator Z() -> real                 { return BlzGetLocalSpecialEffectZ(this.e); }
            method operator WZ() -> real                { return DDEffectTerrZ(this.e); }
            method operator Height() -> real            { return this.Z-this.WZ; }
         
            method operator Facing=(real facRad)        { BlzSetSpecialEffectRoll(this.e, facRad); this.fac = facRad; }
            method operator Facing() -> real            { return this.fac; }
 
   method Position(real x, real y)    { BlzSetSpecialEffectPosition(this.e, x, y, this.effZ+this.WZ); }
   method PositionZ(real x, real y, real z) { BlzSetSpecialEffectPosition(this.e, x, y, z); }
   method Animation(animtype at)    { BlzPlaySpecialEffect(this.e, at); }
   method AnimationSpeed(real animSpeed)  { BlzSetSpecialEffectTimeScale(this.e, animSpeed/100.); }
 
   //method operator Pitch=(integer pitch)  { SetUnitAnimationByIndex(u, pitch); }
         
            //method Face(widget w) { Facing = Atan2(GetWidgetY(w)-Y, GetWidgetX(w)-X)*bj_RADTODEG; }
 
   method Fade(real startTransparency, real endTransparency, real duration) {
    this.cTrans = startTransparency;
    this.eTrans = endTransparency;
    this.stepTrans = .1*(endTransparency-startTransparency) / duration;
 
    BlzSetSpecialEffectAlpha(this.e, R2I(startTransparency*2.55));
 
    DDStartTim(.1, true, this, function() {
     ddeffect dde = DDTimData();
  
     dde.cTrans += dde.stepTrans;
     if (dde.stepTrans > 0.)
      if (dde.cTrans >= dde.eTrans) {
       BlzSetSpecialEffectAlpha(dde.e, R2I(dde.eTrans*2.55));
       DDQuitTim();
       return;
      }
     else
      if (dde.cTrans <= dde.eTrans) {
       BlzSetSpecialEffectAlpha(dde.e, R2I(dde.eTrans*2.55));
       DDQuitTim();
       return;
      }
     BlzSetSpecialEffectAlpha(dde.e, R2I(dde.cTrans*2.55));
    });
   }
 
        }
     
  private type timedeffect extends effect[01];
 
  function DDDestroyEffectTimed(effect e, real secs) {
   timedeffect te = timedeffect.create();
   te[00] = e;
   DDStartTim(secs, true, te, function() {
    timedeffect te = DDTimData();
    DestroyEffect(te[00]);
    te.destroy();
    DDQuitTim();
   });
  }
    }
 
 // ----------------------------------------------------------------------------
    // *** Main damage detection function, registers any damage dealt to units ***
    public function DDTriggerRegisterAnyUnitDamaged(trigger t) {
        DmgTrig[NTrig] = t;
        NTrig += 1;
    }
 
    function InitDamageDetection() {
  code c = function() {
   if (TempTrig != null)
    DestroyTrigger(TempTrig);
 
   TempTrig = CreateTrigger();
   TriggerRegisterEnterRectSimple(TempTrig, bj_mapInitialPlayableArea);
   TriggerAddCondition(TempTrig, function() -> boolean {
    integer i;
 
    // *** Check if we need to exec triggers or register an unit ***
    if (GetTriggerEventId() == EVENT_UNIT_DAMAGED) {
     for(i=0; i < NTrig; i+=1)
      if (IsTriggerEnabled(DmgTrig[i]))
       if (TriggerEvaluate(DmgTrig[i]))
        TriggerExecute(DmgTrig[i]);
    }
    else
     // *** Register new unit ***
     TriggerRegisterUnitEvent(GetTriggeringTrigger(),
            GetTriggerUnit(),
            EVENT_UNIT_DAMAGED);
 
    return false;
   });
 
   DDGroupFilterRect(bj_mapInitialPlayableArea, 00, function() -> boolean {
    TriggerRegisterUnitEvent(TempTrig, GetFilterUnit(), EVENT_UNIT_DAMAGED);
    return false;
   });
  };
  trigger t = CreateTrigger();
 
  TriggerAddAction(t, c);
  TriggerExecute(t);
  DestroyTrigger(t);
  TimerStart(CreateTimer(), TRIGGER_REFRESH_RATE, true, c);
  t = null;
    }
 
 // ---------------------------------------------------------------------------------
 
 // *** Main enum dests in range function ***
    public function DDEnumDestsInRange(p_real vec, real radius, boolexpr filter, code pfunc) {
        rect r = Rect(vec[0]-radius, vec[1]-radius, vec[0]+radius, vec[1]+radius);
 
   EnumVec[0] = vec[0];
   EnumVec[1] = vec[1];
   EnumVec[2] = radius;
         
        if (filter != null) filter = And(EnumFilter, filter);
        else filter = EnumFilter;
        EnumDestructablesInRect(r, filter, pfunc);
 
        if (filter != EnumFilter) { DestroyBoolExpr(filter); filter = null; }
  RemoveRect(r);
  r = null;
    }
     
    function InitEnumDests() {
        EnumVec = p_real.create();
        EnumFilter = Filter(function() -> boolean {
            return Pw_2(EnumVec[0]-GetDestructableX(GetFilterDestructable())) + Pw_2(EnumVec[1]-GetDestructableY(GetFilterDestructable())) < Pw_2(EnumVec[2]);
        });
    }
 
 // --------------------------------------------------------------------------------------
 
 // *** checks is destruct tree ***
    public function DDIsDestructableTree(destructable d) -> boolean {
        if (d != null) {
            PauseUnit(TreeChecker, false);
            if (IssueTargetOrder(TreeChecker, "harvest", d)) {
                PauseUnit(TreeChecker, true);
                return true;
            }
            PauseUnit(TreeChecker, true);
        }
        return false;
    }

    function InitDestTreeCheck() {
        TreeChecker = CreateUnit(Player(bj_PLAYER_NEUTRAL_EXTRA), DD_DUMMYCODE, DDMaxX, DDMaxY, 0.);
        UnitAddAbility(TreeChecker, HARVEST_ID);
        PauseUnit(TreeChecker, true);
    }
 
 // --------------------------------------------------------------------------------------
 
 public function DDNewTextTagUnit(unit whichUnit, string text, real dur, real red, real green, real blue, real transparency) {
  CreateTextTagUnitBJ( text, whichUnit, 0., 11.00, red, green, blue, transparency );
  SetTextTagPermanentBJ( bj_lastCreatedTextTag, false );
  SetTextTagVelocityBJ( bj_lastCreatedTextTag, 48.00, 90 );
  SetTextTagFadepointBJ( bj_lastCreatedTextTag, dur-1.25 );
  SetTextTagLifespanBJ( bj_lastCreatedTextTag, dur );
 }
 
 // --------------------------------------------------------------------------------------
 
 struct cameranoisedata {
  player p[12];
  integer n=00;
 }
 
 public function DDCameraSetSourceNoiseForPlayers(real x, real y, real mag, real vel, real maxDist, real duration) {
  integer i;
  real d;
  cameranoisedata cnd = cameranoisedata.create();
 
  for (i=00; i < bj_MAX_PLAYERS; i+=01) {
   if (GetLocalPlayer() == Player(i)) {
    d = SquareRoot( Pw_2(GetCameraTargetPositionX()-x) + Pw_2(GetCameraTargetPositionY()-y) );
    if (d < maxDist) {
     cnd.p[cnd.n] = Player(i);
     CameraSetSourceNoise(mag-(d*(mag/maxDist)), vel-(d*(vel/maxDist)));
     CameraSetTargetNoise(mag-(d*(mag/maxDist)), vel-(d*(vel/maxDist)));
     cnd.n += 01;
    }
   }
  }
 
  DDStartTim(duration, false, cnd, function() {
   cameranoisedata cnd = DDTimData();
 
   while(cnd.n != 00) {
    cnd.n -= 01;
    if (GetLocalPlayer() == cnd.p[cnd.n])
     CameraSetSourceNoise(0., 0.);
     CameraSetTargetNoise(0., 0.);
   }
 
   cnd.destroy();
   DDQuitTim();
  });
 }
 
 // --------------------------------------------------------------------------------------
 
 hashtable GenSndTable = null;
 
    public function DDGenericSound(string file, real vol, real x, real y, real mxDist, real pitch) {
  sound s;
  real d;
  integer i;
  integer snd_n, sh;
     
  // Play sound and shake camera for players within spell cast range
  for (i=00; i < bj_MAX_PLAYERS; i+=01) {
   if (GetLocalPlayer() == Player(i)) {
    d = SquareRoot( Pw_2(GetCameraTargetPositionX()-x) + Pw_2(GetCameraTargetPositionY()-y) );
    if (d < mxDist) {
     sh = StringHash(file);
     snd_n = LoadInteger(GenSndTable, sh, 04);
     s = LoadSoundHandle(GenSndTable, sh, snd_n);
     if (s == null) {
      s = CreateSound(file, false, false, false, 10, 10, "");
      SaveSoundHandle(GenSndTable, sh, snd_n, s);
     } else if (GetSoundIsPlaying(s)) {
      StopSound(s, false, false);
     }
     SetSoundPitch(s, pitch);
     SetSoundVolume(s, R2I((vol-d*(vol/mxDist))*1.27));
     StartSound(s);
     snd_n += 01;
     if (snd_n == 04)
      snd_n = 00;
     SaveInteger(GenSndTable, sh, 04, snd_n);
    }
   }
  }
    }
 
 public function DDGetGameElapsedTime() -> real {
  return TimerGetElapsed(GameElapsedTimer);
 }
 
 public function DDGetRndReal(real min, real max) -> real {
  real rnd = ((max-min)/1000000.)*I2R(RndInt[RndIntReadN]);
  debug if (max > 1000000.)
   DDMsg("ERROR: \"DDGetRndNumber\" - 'max' variable is greater than 1000000!");
  RndIntReadN += 01; if (RndIntReadN == RND_INT_MAX_ARRAY_N) RndIntReadN = 00;
  return min + rnd;
 }
 
 public function DDGetRndInt(integer min, integer max) -> integer {
  return R2I( DDGetRndReal(I2R(min), I2R(max)) );
 }
 
 // ====================================================================
    function onInit() {
  InitDamageDetection();
  InitDestTreeCheck();
  InitEnumDests();
 
        DDMinX = GetRectMinX(bj_mapInitialPlayableArea);
        DDMinY = GetRectMinY(bj_mapInitialPlayableArea);
        DDMaxX = GetRectMaxX(bj_mapInitialPlayableArea);
        DDMaxY = GetRectMaxY(bj_mapInitialPlayableArea);
 
  GenSndTable = InitHashtable();
 
  ErrorSound = CreateSound( "Sound\\Interface\\Error.wav", false, false, false, 10, 10, "" );
  SetSoundParamsFromLabel( ErrorSound, "InterfaceError" );
  SetSoundDuration( ErrorSound, 614 );
  SetSoundVolume(ErrorSound, 127);
 
  GameElapsedTimer = CreateTimer();
  TimerStart(GameElapsedTimer, 10800., false, null);
 
  for(RndIntWriteN=00; RndIntWriteN < RND_INT_MAX_ARRAY_N; RndIntWriteN+=01)
   RndInt[RndIntWriteN] = GetRandomInt(00, 1000000);
 
  RndIntWriteN = 00;
  RndGenForce = CreateForce();
  TrigMouseEvent = CreateTrigger();
  ForForce(bj_FORCE_ALL_PLAYERS, function() {
   if (GetPlayerController(GetEnumPlayer()) == MAP_CONTROL_USER)
    TriggerRegisterPlayerEvent(TrigMouseEvent, GetEnumPlayer(), EVENT_PLAYER_MOUSE_MOVE);
  });
  TriggerAddCondition(TrigMouseEvent, Condition(function() -> boolean {
   real mouseN;
   boolean xFirst = GetRandomInt(00, 01) == 01;
 
   if (!IsPlayerInForce(GetTriggerPlayer(), RndGenForce)) {
    // example: input x = 578.4571496
    //   output rnd n = 4571498
    if (xFirst)
     mouseN = RAbsBJ(BlzGetTriggerPlayerMouseX()) * 100.;
    else
     mouseN = RAbsBJ(BlzGetTriggerPlayerMouseY()) * 100.;
    if (mouseN == 0.)
     return false;
    //mouseN *= 100.;
    RndInt[RndIntWriteN] = R2I((mouseN - I2R(R2I(mouseN))) * 1000.);
    //DDMsg(I2S(RndInt[RndIntWriteN]));
    //RndIntWriteN += 01; if (RndIntWriteN == RND_INT_MAX_ARRAY_N) RndIntWriteN = 00;
 
    if (xFirst)
     mouseN = RAbsBJ(BlzGetTriggerPlayerMouseY()) * 100.;
    else
     mouseN = RAbsBJ(BlzGetTriggerPlayerMouseX()) * 100.;
    RndInt[RndIntWriteN] += R2I((mouseN - I2R(R2I(mouseN))) * 1000.)*1000;
    //DDMsg(I2S(RndInt[RndIntWriteN]));
    RndIntWriteN += 01; if (RndIntWriteN == RND_INT_MAX_ARRAY_N) RndIntWriteN = 00;
    ForceAddPlayer(RndGenForce, GetTriggerPlayer());
   }
 
   if (DDGetGameElapsedTime()-RndElapsedTime > .125) {
    ForceClear(RndGenForce);
    RndElapsedTime = DDGetGameElapsedTime();
   }
 
   return false;
  }));
    }
 
}

//! endzinc




If you have any more questions or suggestions fell free to comment here!
Enjoy!

~Dark Dragon
Contents

DD Universal Pack v5.1c (Map)

Reviews
02:29, 23rd Nov 2008 Dr Super Good: Very good spell pack. All the spells are highly customizable and seem to do their job well. Only problems I noticed are that some spells are not the most efficent. Still I can only recomend using the...
Level 15
Joined
Jul 19, 2007
Messages
618
In past i used GUI
now i am going to JASS (still learning) :D
Amazing spell o_O 5/5
but dummy used point food(go to low upkeep no high)

no its not dummys its units in map! heros use food and ur units archers, huntress, footman... all use food and when some of them dies it goes to no upkeep and when they revive then it again goes to low upkeep... and so on but dummys themselfs do not use food :D

anyway ty for comment!

~DD
 
Level 15
Joined
Jul 19, 2007
Messages
618
I can`t stop wonder how great is it. This spells are... awesome.

This is beautiful what you can create with (v)JASS.

thanks! i am glade you like them. well about part with vjass.. its not like i did any thing special.. you can make it with jass as well if you want. but vjass is more readable and looks better if you ask me.. ofc much more easy to edit and that kind of stuff!
 
Level 15
Joined
Jul 19, 2007
Messages
618
They were before in JASS. Right?

ah no no i did not mean they where in jass. when i started learning vjass and learned basics i started making my first spell pack. its this one! so triggers are sorted from my first spell to the last one and you can see that new ones are more advanced then first ones... however all spells where always in vjass. Water Explosion is the spell which was before in jass and now is in vjass, but that spell is not in this pack...

Greets!
~Dark Dragon
 
Level 15
Joined
Jul 19, 2007
Messages
618
Hmm I thought, that it was in JASS somewhen... Anyway I love the ice one and the death knight. They`re beautiful. But 1000 lines of JASS are kinda much ^^

indeed a lot of lines is quite bad, but good as well. they are most of part inlined and fully editable (dont use blizzard dummy spells) thats why it has a lot of lines.

anyway i am glade you like the spells.
Greets!
~Dark Dragon
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
Interesting :D

Well we know all the pros here, so I'd stick to the cons:

Instant Flash, you forget to re-select the unit at the end of the cast.

Terror Blade, if the unit dies at the hit in which the 15% returns as true, the special effects stay there above the corpse for the time which the spell is supposed to run.

I only tested the new spells :) I already know the old ones.

I'll check some more later, but I wana eat now...

As always, amazing job by DD!


EDIT:

Man I LOVE your coding style! Amazing!


EDIT: Btw, it's Author and not Autor :p
 
Level 15
Joined
Jan 31, 2007
Messages
502
Nice update
i like the new spells
only thing i disliked was that the blademasters slash deselects the Hero

else im just stunned aggain how you manage to build up such huge scripts for some quite simple sounding spells
i mean, none of the 11 Spells has less than 500 lines o_O
e.g. i cannot image that more than 1500 lines are necessary for Shadow Crossing

anyway again gj :)
 
Level 15
Joined
Jul 19, 2007
Messages
618
huh ty for the comments guys!

all xD said:
fix blademaster selection!

k i really forgot about blademasters selection, gonna fix that soon and i belive that adding an new spell should be needed, i mean 4 spells for v4 xD...

-JonNny said:
else im just stunned aggain how you manage to build up such huge scripts for some quite simple sounding spells

well its actually very simple! spells i like the most are ones which are fully editable! for example Terror Blade could be a lot less lines if i did just made it not to trigger if it is already effected! but its editable in constants and well its just one example... as well i am trying to always make spells have comments so that they are more readable... after looking at such a code it actualy gets that long ;)

Shadow Crossing... well its the spell which has main library, 2 scopes and main spells code! why is that so? well its coz everything is fully editable i did not use Animate Dead but recode blizzards own made engine... in an quite fast way.

Deuterium said:
Terror Blade, if the unit dies at the hit in which the 15% returns as true, the special effects stay there above the corpse for the time which the spell is supposed to run.

hmm well that is an bug from my old librarys! you just need to update JNGPS to latest version and its fixed!

Deuterium said:
EDIT: Btw, it's Author and not Autor :p

yeah right.. i dont know where did i type that but ill find it since u pointed it out. lol i did not even look at what i wrote... omg anyway thanks that will be fixed to!


that as well would be blizzard bug or my old librarys! it would be good to use 1.24b (beta)+

anyway if it really bugs ill find it out and fix it!

thanks everyone and ill try to add one more spell and fix this blademaster selection!

Greets!
~Dark Dragon
 
Level 15
Joined
Jul 19, 2007
Messages
618
Hmm, there`s one thing I don`t like.
When you cast Dark Torture close to the map end, and the blades are behind it, turn on the sounds and discover it by your own ;P

gj! you helped me find out the bug. i did not know what where few people talking about when they said that Dark Torture had such bugs... now i get it, through did not fixed it jet but will do.

i am sure that its some little stuff out there...

Holy shit!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2500/5

i am glade you like the spells!
 
Level 2
Joined
Oct 5, 2009
Messages
30
hi, i love all of these spells and i want to use in my map :D .. Question.. i am currently on Jassnewgen5d .. if i update to the requested jassnewgenspecial.. will it bugg my other spells that required jassnewgen5d? just waiting for the go ahead if its safe to do so.. + cred to you though, great spells ... loved the blademaster and the impaleing swords the best? thought it might be bugged at edge of map?
 
Level 1
Joined
Dec 4, 2009
Messages
6
really nice spells!
thx man ;)

we wait the followings more spells =)
 
Last edited:
Level 15
Joined
Jul 19, 2007
Messages
618
Seas =)

And how I get this now? And don't come up with "Google" -_-
I already search for it - but somehow I get only Bull****

Hi Dr. Boom!

first of all yeah this spell pack was dead for some time now, since JNGPS was not allowed for public. so now this works with default JNGP and you can use this spells in your map.

as well to make stuff clear JNGPS shall not be posted here or anywhere else by me since i am not allowed to.


Greets!
~Dark Dragon
 
Level 18
Joined
Feb 28, 2009
Messages
1,970
Hi Dr. Boom!

first of all yeah this spell pack was dead for some time now, since JNGPS was not allowed for public. so now this works with default JNGP and you can use this spells in your map.

as well to make stuff clear JNGPS shall not be posted here or anywhere else by me since i am not allowed to.


Greets!
~Dark Dragon

Oh, you remade these spells to work again with normal JNGP? Nice to hear that.
 
Level 16
Joined
May 1, 2008
Messages
1,605
Seas =)

+ Perfect scripting!
+ The special effects are very good
+ Also you use perfect and matching sounds
+ Each spell is a unique wonder
+ Many custom effects <-- really wonderful


=== Only 2 small changes I think about it ===

1) Can be better if you use an ability that got an AOE circle for Frost Eruption
2) If I cast Water Exhausting at nearby enemies, they got slowed. The buff text should be not in green but in red.
 
Level 15
Joined
Jul 19, 2007
Messages
618
yeah thanks guys, glade u like the spells and hope u can find good use for them.

Seas =)

+ Perfect scripting!
+ The special effects are very good
+ Also you use perfect and matching sounds
+ Each spell is a unique wonder
+ Many custom effects <-- really wonderful


=== Only 2 small changes I think about it ===

1) Can be better if you use an ability that got an AOE circle for Frost Eruption
2) If I cast Water Exhausting at nearby enemies, they got slowed. The buff text should be not in green but in red.


well yeah i wanted to change that even before u said but was lazy...
anyway i changed it now so enjoy!

Regards!
~Dark Dragon
 
Level 10
Joined
Feb 20, 2008
Messages
448
i got error

when i use jngp i got this error : UNable to find textmacro IF

i did check if my jasshelper was up to date and it is! i also have the ddup.x.j file

O_O what do i did wrong ?
 

Attachments

  • error jngp.JPG
    error jngp.JPG
    40.7 KB · Views: 152
Last edited:
Level 1
Joined
Dec 4, 2009
Messages
6
~Dark_Dragon, correct skill Instinct Flash: when use this skill, I see lines on minimap... maybe create ur dummies end move on a vertical line... fix it please.

yet imported sound is reproduced not on a point and audible strongly when review far from a hero
 
Last edited:
Level 7
Joined
Dec 8, 2005
Messages
319
so i found a bug with dark torture, it casted normally but the swords that follow the artwork half did not trigger

the swords were going from left to right, the first half went and then the first half went again, so it restarted and the left side got a double, while the right half had the swords artwork still and they never disappeared.

hope this helps
 
Level 2
Joined
Apr 9, 2010
Messages
18
These spells are very good.
It took a bit of time to import them to other maps but they all work perfectly.
I am really amazed at what could be done after the 1.24 patch which killed most good scripts and maps.
Again I haven't checked these things for a long time but anyway good job.
 
Level 2
Joined
Apr 1, 2010
Messages
9
Need some help. I imported the spells using the step instructions written in the trigger editor. It was a successful save but some spells (i.e. Frost Eruption) don't show the orb missile and explosion animation while some (i.e Electric Field) doesn't do any damage. Wonder why since all that was needed (imports/triggers) was transferred successfully.
 
Top