1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  5. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  6. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  7. The results are out! Check them out.
    Dismiss Notice
  8. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  9. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  10. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Spell - Chain Frost v3.1

Submitted by Dark_Dragon
This bundle is marked as approved. It works and satisfies the submission rules.
Chain Frost spell, contains:

Spell - Chain Frost
Spell - Dark Ritual(Trigger)
Item - Scepter
Other - Frost Hands



Changelog

Version 1.01 - Fixed a bug whit geting nearest unit and air missile rate at hight.

Version 1.02 - Now it does not effect invisuable and invulnerable units, added few more comments in code and added non-undead unit - (footman) for Dark Ritual.

Version 1.03 - Fixed bug that can cause less jumps, little slower spell so that missile is seen more often.

Version 1.04 - Fixed bug that causes first AI target to run, variables cleared and lol "2 x Do Nothing" action removed in else function + comments and welcome stuff.

Version 1.05 Final - Now points are stored in variables and cleared as ' variables ', also few new comments and minor additions.

Version 1.06 - Now maded in jass. So now people can take jass or GUI. Jass is better because the stuff is maded much better and if spell is casted more times (at same time) it will no leak in jass while in GUI it will but in jass I did not include the custom sound system. My advice to you is to use jass instead of GUI but its your choice.

Version 1.06b - Fixed a leak whit a GUI location when first target is attacking lich.

Version 1.07 - I dont think I will update this spell any more times but if I will to edit the graphics. This version totaly transforms this spell from pro style to ultimate total using natives as much as posible, coordinates coded functions DamageFactorEx adds new check for invulnerable units so the invulnerable unit cannot be effected, RawCode functions which allowes GUI-ers simply edit reading "readme", included special coded sounds + graphics which creates a little terrain deformation and more nova effect. There is also many more code fixes which whos never been detected. You can set in code do you want to use sounds or graphics. I think enough comments are writed to help users do what they want. If you have future questions email me at: <darkdragon_hr@yahoo.com>

Version 1.07b - Thanks a lot to jareph for finding a bug when one unit stays that missile is headed to mid of map. That did not happen every time to me but at last it did so bug where in that target is not null when is dead. So now is fixed + some more details code fixes. Again thanks a lot jareph.

Version 1.08 - Last update, spell is now fully MUI, optimized a bit + as sad the graphics are updated. If you dont like graphics you can easily disable them by using function UsingGraphics to false. Missile also now starts at last been height.

Version 1.09 - Heavy GUI fix (optimizations) + mass group leek fix. Jass many optimizations + first lag fix.

Version 1.1 - 1.24+ compatible (i suggest 1.24b "beta"+) since 1.24 bugs, game can crash.
Optimized the code heavy more then 2x less lines, and much better.
Spell is fully editable now...
Spell is recoded in vJass now.

Version 2.0
- Totally recoded in zinc
- Spell now uses mini library.


Version 3.0 - Chain Frost
- Optimized code
- Spell now ends when it deals its max damage/per cast rather than having finite jumps
- Max spell damage is level modifiable now
- Spell damage per jump is now trigger based, rather than 'frost nova' based
- Spell no longer uses 'frost nova' to deal damage but rather calls 'UnitChill' from DD Lib
- 'UnitChill' now allows for level modifiable duration of slow
- Frost Nova effect now shows propertly on air units, rather than on land
- Icy Particles now fall down to the ground when hitting air units, rather than dissapearing in mid air
- Ultimate spell deals raw damage now
- Minnor bug fixes and tweaked the constants a bit
- Spell is no longer 'Sleep' based ability, but rather 'Channel' based ability, meaning that casing CFrost on unit does not produce 'mini stun'
- New constant added for option to either pick trully random or nerby unit when jumping
- Used new feature on hive to add multi-images

Version 3.0b - Chain Frost
- Now added 'NovaHeroDamagePercentage(level)' function which can be modified to alter efficiency of damage dealing on heros and it is level adjustable. 100% means raw damage.


Version 3.1 - Chain Frost
- Modified for Warcraft 3 v1.30 using new DD Library.






Code
Code (vJASS):

//巸ڮ铨࿢SH.scrollpos=0
//TESH.alwaysfold=0
// ====================================================================================
//                              Spell: Chain Frost
//                      Autor: Dark Dragon (Spell from DotA)
//
//                                 Installation:
//
// 1) Make sure you have opened the JNGP editor
// 2) Copy from object editor: Chain Frost ('CFro'), Chain Frost (Upgraded) ('CFru'), Chain Frost Upgrade (Scepter) and "Unit Chill" and match its rawcode in "DD Library"
// 3)       Triggers: This trigger "Chain Frost" and "DD Library"
// 4) Paste all of that in your map, save map, give abilities to your units and enjoy!
// 5) Please do note that bellow you can edit spell constants to change spell style to your own needs.
//
// Credits:
//          ('Hey its X' and 'Chriz' - FrostEffect.mdx)
// ====================================================================================



//! zinc
library ChainFrost requires DDLib
{


 // -------------------------------------------------------------------
 //                      EDITABLE GLOBALS
 // -------------------------------------------------------------------
 private {
   
  // *** Main spell rawcode ***
  // Default: 'CFro'
  constant integer   CHAIN_FROST    = 'CFro';
 
  // *** Main spell updated rawcode, if you dont use upgraded, then just change 'CFru' to 0 ***
  // Default: 'CFru'
  constant integer   CHAIN_FROST_UPGRADED = 'CFru';
       
        // *** Frost nova for chain frost rawcode / NOTE: Now modify in DD Library DD_CHILL rawcode ***
  // Default: 'A000'
  //constant integer   FROST_NOVA             = 'CfFn';
       
        // *** Frost nova dummy order / NOTE: no longer in use ***
  // Default: "frostnova"
  //constant string   FROST_NOVA_ORDER        = "frostnova";
 
  // *** Missile effect path ***
  // Default: "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl"
  constant string   MISSILE_PATH   = "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl";
 
  // *** Nova effect path ***
  // Default: "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
  constant string   FROST_PATH    = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl";
 
        // *** Missile speed ***
  // Default: 600.
  constant real   MISSILE_SPEED   = 600.;
       
        // *** Missile size ***
  // Default: 1.4
  constant real   MISSILE_SCALE   = 1.4;
       
        // *** Missile height offset, that is the min z of missile ***
  // Default: 80.
  constant real   MISSILE_Z_OFFSET  = 80.;
       
  // *** Jumps to nerby units first or any within aoe range
  // Default: true
  constant boolean   CF_AOE_PICK_NERBY_UNIT  = true;
 
        // *** Use custom sound ***
  // Default: true
  constant boolean  USE_CSOUND     = true;
       
        // *** Custom sound path ***
  // Default: "Abilities\\Spells\\Other\\BreathOfFrost\\BreathOfFrost1.wav"
  constant string   SOUND_PATH          = "Abilities\\Spells\\Other\\BreathOfFrost\\BreathOfFrost1.wav";
       
  // *** Use custom graphic ***
  // Default: true
  constant boolean  USE_CGRAPHIC   = true;
       
        // *** Custom nova remenant effect path ***
  // Default: "SpecialEffects\\FrostEffect.mdx"
  constant string   NOVA_PATH          = "SpecialEffects\\FrostEffect.mdx";
       
        // *** Nova effect lifespan in seconds ***
        // Default: 6.
        constant real           NOVA_LIFESPAN           = 6.;
       
        // *** Nova percentage size ***
        // Default: 1.25
        constant real           NOVA_SCALE              = 1.25;
       
        // *** Nova decay time in seconds ***
        // Default: .4
        constant real           NOVA_DECAY_TIME         = .4;
       
        // *** Custom graphic effect path ***
  // Default: "Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl"
 
  constant string   GRAPHIC_EFFECT_PATH  = "Abilities\\Weapons\\ZigguratFrostMissile\\ZigguratFrostMissile.mdl";
 
       
        // *** Particles of graphic count ***
        // Default: 8
        constant integer        PARTICLE_COUNT          = 10;
       
        // *** Particles travel distance ***
        // Default: 180.
        constant real           PARTICLE_MIN_RADIUS     = 100.;
  // Default: 300.
        constant real           PARTICLE_MAX_RADIUS     = 300.;
       
        // *** Particle start height offset, that is the min z of particle ***
  // Default: 10.
  constant real   PARTICLE_MIN_HEIGHT  = 10.;
       
        // *** Particles travel height, MIN_HEIGHT + MAX_HEIGHT is overall max height ***
        // Default: 180.
        constant real           PARTICLE_MAX_HEIGHT     = 180.;
       
       
        // *** Particles lifespan in seconds ***
        // Default: .8
        constant real           PARTICLE_LIFESPAN       = 1.2;
       
        // *** Particles percentage size ***
        // Default: .9
        constant real           PARTICLE_SCALE          = .8;
       
  // *** Custom graphic aftereffect path ***
  // Default: "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl"
  constant string   GRAPHIC_AFTEREFFECT_PATH   = "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl";
 
  // *** every x seconds play animation
  // Default: .6
  constant real   GRAPHIC_AFTEREFFECT_ANIMTIME  = .6;
 
  // *** how many seconds does aftereffect last?
  // Default: 4.2
  constant real   GRAPHIC_AFTEREFFECT_DURATION  = 4.2;
 
        // *** Make sure missile is created at caster position, if in debug mode it tells you to enable this, you should ***
        // Default: false
        constant boolean        CHECK_MISSILE_POSITION  = false;
 
 
       
  // *** Level data ***
        // * Jump range
        function JumpRange(integer level) -> real {
            real jrange[];
           
            // ----------------------
            // The range the spell uses to pick next target
            // Default: 500., 550., 550., 600.
            jrange[1] = 500.;
            jrange[2] = 550.;
            jrange[3] = 550.;
            jrange[4] = 600.;
            // ----------------------
           
            return jrange[level];
        }
       
        // * Max Damage per jump
        function NovaDamage(integer level) -> real {
            real dmg[];
           
            // ----------------------
            // Max damage per jump
            // Default: 250, 360, 475, 600
            dmg[1] = 250.;
            dmg[2] = 360.;
            dmg[3] = 475.;
            dmg[4] = 600.;
            // ----------------------
           
            return dmg[level];
        }
 
  // * Nova hero damage percentage alternation, heros will receive percentage of NovaDamage(level)
  function NovaHeroDamagePercentage(integer level) -> real {
   real hero_dmg_perc[];
   
   hero_dmg_perc[1] = 77.;
   hero_dmg_perc[2] = 79.;
   hero_dmg_perc[3] = 81.;
   hero_dmg_perc[4] = 81.;
   
   return hero_dmg_perc[level];
  }
       
  // * Energy contained in nova/max damge spell can deal per cast
  function CFMaxDamage(integer level) -> real {
   real mdmg[];
 
   // ----------------------
            // Max damage per jump
            // Default: 1500, 2520, 3325, 4800
   mdmg[1] = 6. * 250.;
   mdmg[2] = 7. * 360.;
   mdmg[3] = 7. * 475.;
   mdmg[4] = 8. * 600.;
   
   return mdmg[level];
  }
 
  // * Frost / slow duration in seconds
  function FrostSlowDuration(integer level) -> real {
   real dur[];
   
   // ----------------------
            // Duration of freezing effect
            // Default: 8, 9, 10, 10
   dur[1] = 8.;
   dur[2] = 9.;
   dur[3] = 10.;
   dur[4] = 10.;
   
   return dur[level];
  }
 
        // *** this is filter for choosing next unit to jump on
        function JumpUnitFilter() -> code {
            return function() -> boolean {
                cfdata cf = DDMemUnitData();                                            // data access from filterd spell instance
                return (!IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)       &&
                        !IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL)      &&
                        !IsUnitType(GetFilterUnit(), UNIT_TYPE_ANCIENT)         &&
                        !IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE)    &&
      !IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD)            &&
                        IsUnitVisible(GetFilterUnit(), cf.owner)                &&
                        IsUnitEnemy(GetFilterUnit(), cf.owner)                  &&
                        !DDIsUnitWard(GetFilterUnit())                          &&
      BlzIsUnitSelectable(GetFilterUnit())     &&
                        !BlzIsUnitInvulnerable(GetFilterUnit())                 &&
                        (cf.target != GetFilterUnit()));                                // (cf.target is current target, so choose next target should not be same unit)
                    };
        }
 }
   
   
    //===================================================================================
 //     DO NOT EDIT BELOW IF YOU DONT KNOW JASS
 //===================================================================================
 
    // *** custom types ***
    //type iceparticles           extends         effect[PARTICLE_COUNT];
 struct iceparticles {
  effect e[PARTICLE_COUNT];
  real dx[PARTICLE_COUNT], dy[PARTICLE_COUNT];
 
  method operator [](integer index) -> effect {
   return this.e[index];
  }
 
  method operator []=(integer index, effect e) {
   this.e[index] = e;
  }
 }
   
 
    // ----------------------------------------------
    // *** Chain frost data struct ***
   
    struct cfdata {
        unit caster, target, ltarget /*,dummy*/;
        integer lvl;
        real aoe, mx_dmg;
        player owner;
        ddeffect missile;
 
 
  //static     sound       CastSnd         = null;
  //static  constant real  CONST_SPEED  = DD_INTERVAL*PARTICLE_RADIUS/PARTICLE_LIFESPAN;
        //static cfdata               Temp            = p_null;
        //static unit                 ChainNexus[];
        //static integer              CNN             = 0;
       
        static method create(unit c, unit t, integer lvl) -> cfdata {
            cfdata this = allocate();
           
            caster = c;
            target = t;
   //dummy = null;
            owner = GetOwningPlayer(caster);
            this.lvl = lvl;
            missile = p_null;
            mx_dmg = CFMaxDamage(lvl);
            aoe = JumpRange(lvl);
            //ltarget = null;
           
            return this;
        }
       
     // --------------------------------------------------------------------------------------------------------------
  // *** Parabolic particle motion
  static method ParticleZ(integer mxtick, integer tick) -> real {
   return ( (-PARTICLE_MAX_HEIGHT/Pw_2(.5*mxtick)) * Pw_2(tick-(mxtick*.5)) + PARTICLE_MAX_HEIGHT );
  }
 
  // --------------------------------------------------------------------------------------------------------------
  // *** load custom particles at given target position
  static method CreateParticleDispersion(unit target) {
   iceparticles ip = iceparticles.create();
   integer i;
   real x = GetUnitX(target), y = GetUnitY(target);
   real spd, rad;
   
   // *** create missiles
   for(i=0; i < PARTICLE_COUNT; i+=1) {
    ip[i] = AddSpecialEffect(GRAPHIC_EFFECT_PATH, x, y);
    BlzSetSpecialEffectRoll(ip[i], i*2.*bj_PI/PARTICLE_COUNT);
    BlzSetSpecialEffectScale(ip[i], PARTICLE_SCALE);
    BlzSetSpecialEffectZ(ip[i], DDGetUnitZ(target) + PARTICLE_MIN_HEIGHT);
    spd = DD_INTERVAL*DDGetRndReal(PARTICLE_MIN_RADIUS, PARTICLE_MAX_RADIUS)/PARTICLE_LIFESPAN;
    rad = i*2.*bj_PI/PARTICLE_COUNT;
    ip.dx[i] = spd * Cos(rad);
    ip.dy[i] = spd * Sin(rad);
    //ip[i] = xeffect.create(GRAPHIC_EFFECT_PATH, x, y, i*360./PARTICLE_COUNT, PARTICLE_SCALE);
    //ip[i].Z = GetUnitFlyHeight(target) + PARTICLE_MIN_HEIGHT;
   }
   
   // *** start loop
   DDStartTim(DD_INTERVAL, true, ip, function() {
    integer i, tick = DDTimTick(), mxtick = R2I(PARTICLE_LIFESPAN/DD_INTERVAL);
    iceparticles ip = DDTimData();
    boolean in_air = true;
    real x, y;
   
    // *** movement ***
    for(i=0; i < PARTICLE_COUNT; i+=1) {
     if (in_air) {
      //rad = i*2.*bj_PI/PARTICLE_COUNT;
      BlzSetSpecialEffectPosition(ip[i], BlzGetLocalSpecialEffectX(ip[i]) + ip.dx[i],
                 BlzGetLocalSpecialEffectY(ip[i]) + ip.dy[i],
                 BlzGetLocalSpecialEffectZ(ip[i]) + /*wz-DDEffectTerrZ(ip[i]) +*/ ParticleZ(mxtick, tick) - ParticleZ(mxtick, tick-1));
      /*ip[i].X += (PARTICLE_RADIUS/PARTICLE_LIFESPAN)*DD_INTERVAL * Cos(i*2.*bj_PI/PARTICLE_COUNT);
      ip[i].Y += (PARTICLE_RADIUS/PARTICLE_LIFESPAN)*DD_INTERVAL * Sin(i*2.*bj_PI/PARTICLE_COUNT);
      ip[i].Z += wz-ip[i].WZ + ParticleZ(mxtick, tick) - ParticleZ(mxtick, tick-1);*/

      if (BlzGetLocalSpecialEffectZ(ip[i])-DDEffectTerrZ(ip[i]) < 10.) {
       in_air = false;
       i = -01;
      }
     } else {
      x = BlzGetLocalSpecialEffectX(ip[i]);
      y = BlzGetLocalSpecialEffectY(ip[i]);
      DestroyEffect(ip[i]);
      ip[i] = AddSpecialEffect(GRAPHIC_AFTEREFFECT_PATH, x, y);
      BlzSetSpecialEffectScale(ip[i], PARTICLE_SCALE);
     }
    }
   
    // *** done? ***
    if (!in_air) {
     DDStartTim(GRAPHIC_AFTEREFFECT_ANIMTIME, true, ip, function() {
      iceparticles ip = DDTimData();
      integer i;
     
      if (DDTimTick() == GRAPHIC_AFTEREFFECT_DURATION/GRAPHIC_AFTEREFFECT_ANIMTIME) {
       for(i=00; i < PARTICLE_COUNT; i+=01) {
        DestroyEffect(ip[i]);
        ip[i] = null;
       }
       ip.destroy();
       DDQuitTim();
       return;
      }
     
      for(i=00; i < PARTICLE_COUNT; i+=01)
       BlzPlaySpecialEffect(ip[i], ANIM_TYPE_BIRTH);
     });
     DDQuitTim();
    }
   
   });
  }
 
  // --------------------------------------------------------------------------------------------------------------
  // *** creates nova effect ***
  static method CreateNovaEffect(unit target) {
   if (!IsUnitType(target, UNIT_TYPE_FLYING))
    ddeffect.create(NOVA_PATH, GetUnitX(target), GetUnitY(target), GetRandomReal(0., 2.*bj_PI), NOVA_SCALE).destroyx(NOVA_LIFESPAN);
  }
   
        method NewMissile(unit c) {
            missile = ddeffect.createZ(MISSILE_PATH,
            GetUnitX(c), GetUnitY(c), DDGetUnitZ(c) + MISSILE_Z_OFFSET,
            Atan2(-GetUnitY(c)+GetUnitY(target), -GetUnitX(c)+GetUnitX(target)),
            MISSILE_SCALE);
        }
 
        method MissileHit() {
   real dmg = RMinBJ(NovaDamage(lvl), mx_dmg);
   /*
   dummy = DDLoadDummy();
   
            SetUnitOwner(dummy, owner, false);
            SetUnitX(dummy, GetUnitX(target) - 5. * Cos( DmyRad() ));
            SetUnitY(dummy, GetUnitY(target) - 5. * Sin( DmyRad() ));
            UnitAddAbility(dummy, FROST_NOVA);
   */

            missile.destroy();
            missile = p_null;
           
            DDUnitShareVisionTimed(target, owner, 1.); // make sure dummy can cast spell
            //if (IssueTargetOrder(dummy, FROST_NOVA_ORDER, target)) {
            if ( DDUnitChill(owner, target, FrostSlowDuration(lvl)) ) {
    static if (USE_CGRAPHIC) {
     CreateNovaEffect(target);
     CreateParticleDispersion(target);
    }
   
    // *** Main effect
    DestroyEffect( AddSpecialEffectTarget(FROST_PATH, target, "origin") );
   
    // *** Main damage
    if (!IsUnitType(target, UNIT_TYPE_HERO)) {
     if (GetWidgetLife(target) > dmg)
      SetWidgetLife(target, GetWidgetLife(target)-dmg);
     else {
      dmg = GetWidgetLife(target);
      UnitDamageTarget(caster, target, 32767., true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS);
     }
    } else {
     if (GetWidgetLife(target) > dmg*NovaHeroDamagePercentage(lvl)/100.)
      SetWidgetLife(target, GetWidgetLife(target)-dmg*NovaHeroDamagePercentage(lvl)/100.);
     else {
      dmg = GetWidgetLife(target)*100./NovaHeroDamagePercentage(lvl);
      UnitDamageTarget(caster, target, 32767., true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS);
     }
    }
    mx_dmg -= dmg;
   }
   
   // -------------------------------------------------------------------------------------------------
   // *** fill nexus with new targets ***
   ltarget = target;
   static if (CF_AOE_PICK_NERBY_UNIT) {
    // *** get new target in nerby range
    DDGroupFillMemArea(GetUnitX(target), GetUnitY(target), aoe*.4, this, JumpUnitFilter());
   
    if (DDMemUnitN() > 00)
     target = DDMemUnit(DDGetRndInt(0, DDMemUnitN()-1));
    else {
     // *** get new target in far range
     DDGroupFillMemArea(GetUnitX(target), GetUnitY(target), aoe, this, JumpUnitFilter());
     target = DDMemUnit(DDGetRndInt(0, DDMemUnitN()-1));
    }
            } else {
    // *** get new target in far range
    DDGroupFillMemArea(GetUnitX(target), GetUnitY(target), aoe*.4, this, JumpUnitFilter());
    target = DDMemUnit(DDGetRndInt(0, DDMemUnitN()-1));
   }
   
            /*
            DDStartTim(1., false, New_pUnit(dummy), function() {
                p_unit pu = DDTimData();
                UnitRemoveAbility(pu[00], FROST_NOVA);
                DDRecycleDummy(pu[00]);
    pu.destroy();
    DDQuitTim();
            });*/

        }
       
        method MissileMove() -> boolean {
            real rad    = Atan2(GetUnitY(target)-missile.Y, GetUnitX(target)-missile.X);
            real dist   = SquareRoot( DDHypot(GetUnitX(target)-missile.X, GetUnitY(target)-missile.Y) );
            real dz     = DDGetUnitZ(target) - missile.Z + MISSILE_Z_OFFSET;
           
   missile.PositionZ(missile.X + MISSILE_SPEED*DD_INTERVAL*Cos(rad),
         missile.Y + MISSILE_SPEED*DD_INTERVAL*Sin(rad),
         missile.Z + ((dz/dist) * MISSILE_SPEED*DD_INTERVAL));
            /*missile.X += MISSILE_SPEED*DD_INTERVAL*Cos(rad);
            missile.Y += MISSILE_SPEED*DD_INTERVAL*Sin(rad);
            missile.Z += (dz/dist) * (MISSILE_SPEED*DD_INTERVAL);*/

            missile.Facing = rad;
           
            //BJDebugMsg(R2S(rad*bj_RADTODEG));
            return dist <= 3.*MISSILE_SPEED*DD_INTERVAL;
        }
    }
   
    // =================================================================
 // =================================================================
 function onInit() {
        trigger t = CreateTrigger();
       
  TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST);
        TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
        TriggerAddCondition(t, Condition(function() -> boolean {
   unit u = GetTriggerUnit(), v = GetSpellTargetUnit();
            integer abillvl;
            cfdata cf;
           
            // ----------------------------------------------------------------
            // *** condition ****
            if (GetSpellAbilityId() !=  CHAIN_FROST && GetSpellAbilityId() !=  CHAIN_FROST_UPGRADED)
                return false;
            // ----------------------------------------------------------------
            if (GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_CAST) {
    if (IsUnitType(v, UNIT_TYPE_MAGIC_IMMUNE)) {
     IssuePointOrder(u, "move",
         GetUnitX(u)+20.*Cos(GetUnitFacing(u)*bj_DEGTORAD),
         GetUnitY(u)+20.*Sin(GetUnitFacing(u)*bj_DEGTORAD));
     DisplayErrorMsgPlayer(GetOwningPlayer(u), bj_QUEUE_DELAY_HINT, "Can't cast on magic immune units!");
    }
    u = null; v = null;
    return false;
   }
   // ----------------------------------------------------------------
   
            abillvl = GetUnitAbilityLevel(u, GetSpellAbilityId());
            if (GetSpellAbilityId() ==  CHAIN_FROST_UPGRADED) abillvl += 1;
           
            // *** store data ***
            cf = cfdata.create(u, v, abillvl);
            cf.NewMissile(cf.caster);
            debug if (!IsUnitInRangeXY(cf.caster, cf.missile.X, cf.missile.Y, 100.) && !CHECK_MISSILE_POSITION)
                BJDebugMsg("|cffff0000Error:|rChain Frost missile not created at caster position, please enable \"CHECK_MISSILE_POSITION\".");
            //UnitShareVision(cf.target, cf.owner, true);
           
            if (USE_CSOUND)
    DDGenericSound(SOUND_PATH, 100., GetUnitX(cf.caster), GetUnitY(cf.caster), 3500., 1.);
           
            // *** init timer and start periodic spell actions ***
            DDStartTim(DD_INTERVAL, true, cf, function() {
                cfdata cf = DDTimData();
   
    static if (CHECK_MISSILE_POSITION) {
     if (DDTimTick() == 01)
      cf.missile.PositionZ(GetUnitX(cf.caster), GetUnitY(cf.caster), MISSILE_Z_OFFSET);
    }
     
    // *** move missile and check if reached target ***
    if (cf.MissileMove()) {
     // *** hit the target ***
     cf.MissileHit();
     
     // *** end spell ***
     if (cf.target == null || cf.mx_dmg < 0.1) {
      //UnitShareVision(cf.ltarget, cf.owner, false);
      cf.destroy();
      DDQuitTim();
      return;
     }
     
     // *** new missile ***
     if (cf.missile == p_null && cf.mx_dmg > 0.) {
      cf.NewMissile(cf.ltarget);
      //UnitShareVision(cf.ltarget, cf.owner, false);
      //UnitShareVision(cf.target, cf.owner, true);
     }
    }
   
            });
           
   u = null; v = null;
            return false;
        }));
       
    }

}

//! endzinc

// ============================================================================================
// NOTE: This lua script is for old version of spell, I recommend to just copy and paste abilities and dummy to your map

// Change me from /* to // and then back to /* after saving and reopening the map
    // |
    // ˇ
      /*
     
// Credits: PurgeandFire for lua tutorial
//! externalblock extension=lua ObjectMerger $FILENAME$
     //! i -- ===================================================
     
     //! i CHAIN_FROST_DAMAGE_ID                = "CfFn"
     //! i FREEZING_FIELD_ABIL_ID               = "FFld"
     //! i FREEZING_FIELD_IMPROVED_ABIL_ID      = "FFdu" -- Set this value to "nil" if not using upgrader
  //! i CHAIN_FROST_ABIL_ID     = "CFro"
  //! i CHAIN_FROST_IMPROVED_ABIL_ID   = "CFru" -- Set this value to "nil" if not using upgrader or if not using chain frost spell
  //! i AGHANIM_SCEPTER_ABIL_ID    = "Aghs"
   
     //! i -- ===================================================
   
     //! i setobjecttype("abilities")
     //! i createobject("AUfn", CHAIN_FROST_DAMAGE_ID)
     //! i makechange(current,"anam", "Chain Frost Chill")
     //! i makechange(current,"alev", "1")
     //! i makechange(current,"aher", false)
     
     // i local i = 0
     // i local dmg = { "250.", "360.", "475.", "600." }
     // i for i=1, 4 do
        // i local si = tostring(i)
        //! i makechange(current,"Ufn1",si,"0.")
        //! i makechange(current,"Ufn2",si,0.)
        //! i makechange(current,"aare",si,"0.")
        //! i makechange(current,"ahdu",si,"10.")
        //! i makechange(current,"adur",si,"10.")
        //! i makechange(current,"amcs",si,"0")
        //! i makechange(current,"aran",si,"99999.")
     // i end
     
     
     //! i createobject("AUsl", CHAIN_FROST_ABIL_ID)
     //! i makechange(current,"anam", "Chain Frost")
     //! i makechange(current,"alev", "3")
     //! i makechange(current,"abpx", "3")
     //! i makechange(current,"arpx", "3")
     //! i makechange(current,"arhk", "C")
     //! i makechange(current,"ahky", "C")
     //! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNBreathofFrost.blp")
     //! i makechange(current,"arar", "ReplaceableTextures\\CommandButtons\\BTNBreathofFrost.blp")
     //! i makechange(current,"aret", "Learn |cffffcc00C|rhain Frost - [|cffffcc00Level ".. string.char(37) .."d|r]")
     //! i makechange(current,"arut", "Sends a breath of frost that jumps n times through nearby enemys dealing damage and slowing them for 10 seconds. |n|n|cFF0054A6Level 1|r - Each jump deals 250 damage, 6 jumps.|n|cFF0054A6Level 2|r - Each jump deals 360 damage, 7 jumps.|n|cFF0054A6Level 3|r - Each jump deals 475 damage, 7 jumps.")
     
     //! i local i = 0
     //! i local manacost = { "200", "325", "500" }
     //! i for i=1, 3 do
        //! i local si = tostring(i)
        //! i makechange(current,"Usl1",si,".01")
        //! i makechange(current,"aran",si,"750.")
  //! i makechange(current,"abuf",si,nil)
        //! i makechange(current,"acdn",si,tostring(22.5-2.5*i))
  //! i makechange(current,"ahdu",si,".01")
        //! i makechange(current,"adur",si,".01")
        //! i makechange(current,"amcs",si, manacost[i])
  //! i makechange(current,"atp1",si,"|cffffcc00C|rhain Frost - [|cffffcc00Level "..si.."|r]")
 
     //! i end
     
     //! i makechange(current,"aub1","1", "Sends a breath of frost that jumps 6 times through nearby enemys dealing 250 damage and slowing for 10 seconds.")
     //! i makechange(current,"aub1","2", "Sends a breath of frost that jumps 7 times through nearby enemys dealing 360 damage and slowing for 10 seconds.")
     //! i makechange(current,"aub1","3", "Sends a breath of frost that jumps 7 times through nearby enemys dealing 475 damage and slowing for 10 seconds.")

    //! i if (CHAIN_FROST_IMPROVED_ABIL_ID ~= nil) then
   //! i createobject("AUsl", CHAIN_FROST_IMPROVED_ABIL_ID)
   //! i makechange(current,"anam", "Chain Frost")
         //! i makechange(current,"ansf", " ( Upgraded )")
   //! i makechange(current,"alev", "3")
   //! i makechange(current,"abpx", "3")
   //! i makechange(current,"arpx", "3")
   //! i makechange(current,"arhk", "C")
   //! i makechange(current,"ahky", "C")
   //! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNBreathofFrost.blp")
   //! i makechange(current,"arar", "ReplaceableTextures\\CommandButtons\\BTNBreathofFrost.blp")
   //! i makechange(current,"aret", "Learn |cffffcc00C|rhain Frost - [|cffffcc00Level ".. string.char(37) .."d|r]")
   //! i makechange(current,"arut", "Sends a breath of frost that jumps n times through nearby enemys dealing damage and slowing them for 10 seconds. |n|n|cFF0054A6Level 1|r - Each jump deals 360 damage, 7 jumps.|n|cFF0054A6Level 2|r - Each jump deals 475 damage, 7 jumps.|n|cFF0054A6Level 3|r - Each jump deals 600 damage, 8 jumps.")
   
   //! i local i = 0
   //! i local manacost = { "200", "325", "500" }
   //! i for i=1, 3 do
   //! i local si = tostring(i)
   //! i makechange(current,"Usl1",si,".01")
   //! i makechange(current,"aran",si,"750.")
   //! i makechange(current,"abuf",si,nil)
   //! i makechange(current,"acdn",si,tostring(22.5-2.5*i))
   //! i makechange(current,"ahdu",si,".01")
   //! i makechange(current,"adur",si,".01")
   //! i makechange(current,"amcs",si, manacost[i])
   //! i makechange(current,"atp1",si,"|cffffcc00C|rhain Frost - [|cffffcc00Level "..si.."|r]")
   
   //! i end
   
   //! i makechange(current,"aub1","1", "Sends a breath of frost that jumps 7 times through nearby enemys dealing 360 damage and slowing for 10 seconds.")
   //! i makechange(current,"aub1","2", "Sends a breath of frost that jumps 7 times through nearby enemys dealing 475 damage and slowing for 10 seconds.")
   //! i makechange(current,"aub1","3", "Sends a breath of frost that jumps 8 times through nearby enemys dealing 600 damage and slowing for 10 seconds.")
 //! i end
 
  //! i if (FREEZING_FIELD_IMPROVED_ABIL_ID ~= nil or CHAIN_FROST_IMPROVED_ABIL_ID ~= nil) then
  //! i createobject("ANeg", AGHANIM_SCEPTER_ABIL_ID)
  //! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNINV_Wand_05.blp")
        //! i makechange(current,"Neg4","1", CHAIN_FROST_ABIL_ID..","..CHAIN_FROST_IMPROVED_ABIL_ID)
  //! i if (FREEZING_FIELD_IMPROVED_ABIL_ID ~= nil) then
   //! i makechange(current,"Neg3","1", FREEZING_FIELD_ABIL_ID..","..FREEZING_FIELD_IMPROVED_ABIL_ID)
  //! i else
   //! i makechange(current,"Neg3","1", nil)
  //! i end
  //! i makechange(current,"Neg5","1", nil)
  //! i makechange(current,"Neg6","1", nil)
  //! i makechange(current,"Neg1","1", "0.")
  //! i makechange(current,"Neg2","1", "0.")
  //! i makechange(current,"aher", false)
  //! i makechange(current,"abuf","1", nil)
  //! i makechange(current,"alev", "1")
  //! i makechange(current,"arac", "nightelf")
  //! i makechange(current,"anam", "CF & FF Upgrader")
  //! i end
     
//! endexternalblock

       */

    // ^
    // |
// Change me from */ to // and then back to */ after saving and reopening the map
// ============================================================================================
 


Installation instructions in zinc trigger Chain Frost at top, if you still have some questions, feel free to ask.

~Dark Dragon



Keywords:
Chain Frost, Ice, Lich, Dota, Cold, Missile, Frost, Death, Nova
Contents

Spell - Chain Frost (Map)

Reviews
Moderator
PurplePoot: Enough of the leaks are fixed (1 left, 17 fixed), so (approved). I advise you try to fix the last one, but it's your choice.
  1. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    I understand what you want to say jareph but using global whitout my system UserTimerData i cant get which array i need to use in other function. Sry but i just cant get this bug i kill all units leave only one, cast chain frost and it jumps once the spell ends. I just cant get missile go to center of map. And about loop, blizzards TriggerSleepAction min precision is 0.1 sec which means i cant use loop. When you use that function you can set to wait 0.10 but it will sometimes wait 0.15, 0.20, 0.13, 0.10,... you cant knowe that is why many programesrs ignore this function. Timer is precius but you cant make sleep action of it. So if you use loop whitout wait in it it will move missile instantly to target units location. And so sry jareph i just cant get this bug.

    Herman I only tried to explain how can people who dont knowe jass use it in there map. Only read Readme in jass code. You only need to edit rawcodes, thats all. It is writed in code how to do it. And I dont have problems whit GUI ^^ I use it to when the time is right for GUI. But coding spells and such things I think its better in jass. I also started my programing knowledge on GUI. About invulnerable filters i did not undersand exactly what did u mean but if you code in GUI u can check if units level of Invulnerable(neutral) is 0 or does he has buff devine shield. I maded my own function which checks can unit be damaged. That works even if programer makes unit invulnerable in trigger way. And dont worry about long code in jass, its much shorter then in GUI if you will do all that i did (when you convert it) + this code does not lag a lot coz i used natives as much as possible :) Gues u guys are having fun using this spell and one last thing, thanks for comments and downloading
     
  2. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    o, ok

    By the way, this spell is really cool :)
     
  3. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    thank you :)
     
  4. jareph

    jareph

    Joined:
    Oct 20, 2007
    Messages:
    348
    Resources:
    2
    Maps:
    2
    Resources:
    2
    sry for so long reply,
    all question i think have been explained &gt;.&lt;
    swt...
    your chain frost can can be multiple casted in same time? and i wan to ask will JASS can easy make a skill can be multiple casted in same time?
     
  5. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    yes this spell is MUI, and about doing that in jass is much more easy than in GUI because you can use local variables which is much better then globals, other if you need a global variable for another trigger then use global or make handle function + you can make your own functions which can be used to any kind of your coding skills. If you don't understand something than just ask
     
  6. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    O wait a second, i just re-read your post that you made after mine

    Yeah I just learned what a loop was

    (putting the wait at the end of the trigg to make it start over + a wait action)

    Whenever I do any kind of trigger in GUI that involves an &quot;over time&quot; condition, (usually only with moving units) I always make a unit group global, and a trigger that fires at every .01 secs
    That same trigger has a condition that checks for the unit group to be empty, if it is, the trigger basically doesn't exist (if you wanted to make damned-sure it is disabled when it needs to be, there are other methods)

    Anyway, add the unit to the unit group (the dummy unit), and make an action that moves the unit (using polar coordinates) a small distance

    This way, all you need to do is remove the unit from the unit group after its function is complete (I usually kill it, and in another trigger specify what happens when it dies, makes it less ugly)

    Thats how you make any speed of a projectile you would like in GUI (I made a grenade spell recently, I personally love it cuz it uses everything I know in GUI, but its ignored because somebody beat me to it &gt;&lt;)

    Looking at that map would explain how I would do it in GUI very effectively (and it would definitely take less coding than what you made)
    __________________________
    Update #1

    If you'd like, I could make my own MUI + GUI chain frost, and give it/show it to you
    __________________________
    Update #2

    I finished my own GUI version of this spell, there aren't any leaks (that i know of) and it can be edited with fair ease (although some parts of it could be difficult) there is only one bug &quot;I think&quot; happens when the units target dies + decays, the frost flies off the map, but I fixed it with a distance check
    ___________________________
    Update #3

    Yup, that was the problem
    There is a tracking &quot;thing&quot; (thing being a series of actions) that makes the nova follow the target unit, but sometimes, the nova flies out, a long distance, and the returns

    This allows enough time for the unit to decay and dissappear, making the nova fly continually

    I added two conditions, one if the nova flies 2000+ away from the point, or the target is dead (the trigger fires fast enough so you don't need to worry about decaying)

    Just ask me for the map n ill send it to you, anyway you'd like (b.net, epicwar, THISSITE, aim, xfire, etc.)
     
  7. jareph

    jareph

    Joined:
    Oct 20, 2007
    Messages:
    348
    Resources:
    2
    Maps:
    2
    Resources:
    2
    sry here 1 more question,
    i m not understand how set a units movement speed more than 522 in jass...
    is that like this?
    call SetUnitMoveSpeed( &lt;Unit&gt;, 800.00 )
     
  8. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    You can make a unit movement speed goes to any kind of speed by using timer which runs some code and code is that you move the unit to his point offset by angle between 2 points and setting move to your speed * timer speed. Here example:

    function YourCode takes nothing returns nothing
    local location l = GetUnitLoc( yourUnit )
    local location offset = PolarProjectionBJ( l, speed*0.01, AngleBetweenPoints(l, targetPoint))
    call SetUnitPositionLoc( yourUnit, offset )
    call RemoveLocation( l )
    call RemoveLocation( offset )
    endfunction

    call TimerStart( whichTimer, 0.01, true, function YourCode )

    this should look something like this


    Ok herman send me your map
     
  9. jareph

    jareph

    Joined:
    Oct 20, 2007
    Messages:
    348
    Resources:
    2
    Maps:
    2
    Resources:
    2
    oh thx

    that mean there got no difference for GUI ^^
     
  10. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    y something like that just in jass is better to use only timer for running other function, other then creating new trigger and using timer which is non-native. Other than that there is no big difference
     
  11. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    Sorry about the delay Dark_Dragon (was workin on height + special effect for flying), how would you like it sent???

    ____________________________
    Update #1

    Ahhh, nevermind I'll just put it up

    ____________________________
    Update #2

    I didn't add an item ultimate, but that could be done easily

    Unrelated: What do you mean &quot;Other - Frost Hands&quot; in your spell pack???
     
  12. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    The frost hands are the sphere effects on lich. If you want you can upload your spell here or send me on my mail &lt;darkdragon_bx@yahoo.com&gt;
     
  13. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    I already uploaded it &gt;&lt;
    http://www.hiveworkshop.com/resources_new/spells/1214/
     
  14. Bobo_The_Kodo

    Bobo_The_Kodo

    Joined:
    Jan 15, 2007
    Messages:
    192
    Resources:
    0
    Resources:
    0
    First.. WTF is with the triggered Dark Ritual... did you know that lich already has an ability called Dark Ritual that does EXACTLY the same thing?

    Second, one of the groups is not initialized

    Third, try not to be so arrogant.

    Fourth, give credit to Vexorian for caster system functions?
     
  15. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    This trigger dark ritual can be cast on any unit that is the difference.

    All groups work fine and are local variables and are of course initialized.

    Don't know what do you mean that I am arrogant I did not say its best chain frost spell but one of the best and that is true, I changed name to ultimate only because it has Jass and GUI.

    Last I am not using caster system, don't know where you see any of this functions I coded all by myself. Its not enough to say something when you don't look very well first.
     
  16. eWs.Azure

    eWs.Azure

    Joined:
    Apr 1, 2008
    Messages:
    23
    Resources:
    0
    Resources:
    0
    n1 :D is it just like the ulti of lich in dota ? :p
     
  17. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    it is idea from dota but this is fare more better coded spell then in dota, dont get me wrong in dota this spell is coded well because it is optimized but not visual and spell well made because its only a missile move to current point not constant and graphics are not anything special + no air missile move and many more. As I sad its good enough as it is in dota but as this is my fav spell I wanted to make it a pro spell.
     
  18. Kingdragun

    Kingdragun

    Joined:
    Apr 22, 2008
    Messages:
    2
    Resources:
    0
    Resources:
    0
    Hi i am a new member and i am doing a map. i really need new skill, but download the magics is not enaught. so plizz tell me how works importing skilles. do i need JASS??? where i can download?
     
  19. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok this spell is coded in jass and GUI. The only thing you need to do is just copy units and abilities from object editor (you will see them &quot;custom units and spells&quot;) after that just go to trigger editor (F4), and find code in jass which is far more better then GUI. Copy it and past it in your map. Now go to object editor in your map find so called &quot;raw codes&quot; of units and abilities in your map and just change them in code its all.

    Note if you are new and cant rely do that or dont understand you can mail me your map and I will send you whit imported spell in your map &lt;darkdragon_hr@yahoo.com&gt;

    Good Luck!
     
  20. cHeRoL

    cHeRoL

    Joined:
    Mar 30, 2008
    Messages:
    655
    Resources:
    2
    Spells:
    2
    Resources:
    2
    I wish I know how to put these ability into my map. :(