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. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. The Secrets of Warcraft 3 have revealed interesting works. The RESULTS for Abelhawk's Mini-Mapping Contest #15 have come out!
    Dismiss Notice
  7. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  8. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  9. Night Rider gained several songs for his journey. The poll for the 12th Music Contest has started. Check it out!
    Dismiss Notice
  10. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    Dismiss Notice
  11. 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. 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.
     
  2. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok I fix this. Thank you for your comment it realy helped me. Bug whas in geting nearest target so that it will get more or less units.
     
  3. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,162
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    1) the dummy shouldn't damage enemies, you should (so they attack you instead of running away)

    2) Still leaks Locations and Groups

    Oh, and you can remove all the DoNothings.
     
  4. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok look the dummys doesnt attack they cast spell and becasue they have locus enemys canot attack him. That is why enemys run when dummy cast spell, but only first target because this spell is maded from sleep which pauses target for .01 sec. Ok so target whont attack me because it is treated like it sleeps and then dummy casts spell and he run away. Now ok i fix this i will add that target attack pnt on lich and loc remove. Ok ok i will do that.
     
  5. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok I think u will be happy whit this now ^_^.
     
  6. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,162
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    Oh, sorry, too used to JASS projectiles where it would be easy for the caster to damage them x.x

    No problem, then.

    Ugh, about the locations though, sorry, but I don't think you understand how to deal with them

    You can't just

    Do something at Somewhere
    Remove Somewhere

    you have to do (assuming TempPoint is a point variable)

    set TempPoint = Somewhere
    Do Something at TempPoint
    Remove TempPoint

    (same goes for your other spell)
     
  7. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok its finaly all fixed and now its working well whit no lag, thank you for teaching me this I did not knowe I cant remove pos of unit. :)
     
  8. Need_O2

    Need_O2

    Joined:
    Aug 24, 2007
    Messages:
    2,880
    Resources:
    0
    Resources:
    0
    Hey this one is good congratulations
     
  9. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    there is one leak left just so you know..

    If (((Owner of (Target unit of ability being cast)) controller) Not equal to User) then do (Unit - Order (Target unit of ability being cast) to Attack-Move To (Position of (Casting unit))) else do (Do nothing)

    ~~ point leak &gt;&gt;

    Also instead of getting a random unit, get the closest unit.

    If you want your resource to be more valuable, take in the effort to eliminate every leak/bug.

    i dont really download stuff that i can create, yours is good no offence or anything, its just that i dont need it &gt;&gt;
    hmm just so you know when it gets closest unit it becomes more realistic though ur choice ^^
     
  10. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Geting nearest unit is a nice system but in Chain Lightning, Chain Frost uses missile which chooses random unit. I dont like this spell gets neares unit, if you did read Description you will see that in laiter ver it gets nearest unit, but now I dont like this spell to get nearest unit. If you want you have right to modify this spell for your own needs.
     
  11. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    I knowe in chain spells it shuld get closest unit but the chain frost is looking cool when i dont knowe which target it will hit and if it gets closest unit the missile will not be seen so often :( So i think ill let it stay this way

    However ty for comment
     
  12. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    heh alright, gj on ur spell ^^
    btw howcome your so good with math ;D
     
  13. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    That whos not any special math, now this version is uploaded (created) at last. This is many more math and better preformance. It taked me a lot of time to make this but I think you people will have fun using it.
     
  14. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    Wow that is a fancy spell, i like it alot

    Thank you for converting it to GUI, I love to use GUI just cuz i know anything can be done in it
     
  15. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Uhh. I made GUI yes but, plz dont use it GUI makes pathatic lagy code + spell will not work if many players cast it in same time. As you can see I can make this spell in GUI and in Jass, but Jass makes spell the real spell when in GUI is everything done so bad, like GUI uses BJ-s functions which call native of it and there is no point using it. Each If , then, else, uses (creates) a function even if you did used it before. I cant make my own functions and that is very bad coz If you will use GUI the filter for unit group will filter only Invulnerable unit if her has ability Invulnerable(Neutral). Jass uses GetDamageFactorEx so that it works on anything. In Jass missile moves exactly from caster to target (800 ms) and blows target. In GUI missile speed (522 ms) and goes to last position of target it calculates not when missile gets the target but when polledwait ends (using distance). In GUI are used locations which leaks even if I remove them, while in Jass are used coordinates and coded other functions for them. Wow I sad to much, there is a lot more to say but I think this is enough.
     
  16. jareph

    jareph

    Joined:
    Oct 20, 2007
    Messages:
    348
    Resources:
    2
    Maps:
    2
    Resources:
    2
    1st your frost nova was wrong function when there only got 1 unit....the frost was moving to the center of the map, this is because u order it to move to a Variable(point) that have empty.
    2nd GUI can make all the thing that can make in JASS , GUI can make the frost nova that can used by many player in a game and the movespeed can over 522 If u wan !!!!!!
     
  17. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    591
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    I dont knowe how that happen to u but I tested it and it works as suspected. PS WEU users may suspect bugs in any code. Also I never say that in GUI cant be done unit speed of 800, but I sad that my trigger is maded like that coz I am not planing to make a lot of triggers for my spell -.- It looks stupid and you have to use global triggers which generates code for them (its a global variable). The way I like it only one trigger for one spell. And I never sad that GUI sucks, its only in jass can be done much more and better...
     
  18. jareph

    jareph

    Joined:
    Oct 20, 2007
    Messages:
    348
    Resources:
    2
    Maps:
    2
    Resources:
    2
    that was a easy way to make global spell , u juz nid put a &quot;array&quot; to ur variable.
    if u wan see the bug , u kill all nearby units but leave only 1 , and use chain frost , see where the frost going , it was center of map.
    yes, sry the movespeed cant over 522 , but u can use trigger to move it(it wont cause any lag, if it was doing in every 0.01seconds) , it was no maximum.By my was to do , is open up new trigger ,but u can use loop to make it up without open new trigger.
    And urs chain frost is good ^^
     
  19. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    Uhhh, I don't know how JASS is used, and you were talking about &quot;BJ-s's&quot; and &quot;Natives&quot; and in JASS that might be very simple, but for me

    (I learned GUI without any other programming knowledge, hence i didn't have a clue what leaks and other things are)

    I don't understand such things

    You might have problems with GUI because you don't use it... (without practice your skills deteriorate)

    Also, only using one trigger per spell might be just peachy in JASS, but most good (good meaning here, not worthless) GUI spells utilize more than one trigger

    Otherwise,(generally speaking) they are as horrible as you described

    One last thing, you can specify a unit-group to NOT filter away invulnerables (even use the integer check for the ability if necessary)

    Just saying that the missile speed max is 522 is just asking to get attacked on all sides

    Lastly, you can do ALOT with the unit groups and arrays, all it takes is a little clever thought and you can work it out with fairly small amounts of coding (much less than all the JASS writing I have seen)

    There is another version of the Grenades spell that I had made, that i personally thought was pretty clever because it was simple (it was ignored because somebody beat me to it)