1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Join Texturing Contest #30 now in a legendary battle of mythological creatures!
    Dismiss Notice
  3. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice
  4. Melee Mapping Contest #3 - Results are out! Congratulate the winners and check plenty of new 4v4 melee maps designed for this competition!
    Dismiss Notice
  5. The winners of our cinematic soundtrack competition have been decided! Step by the Music Contest #11 - Results to check the entries and congratulate the winners!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice

Spell - Freezing Field 2.0

Submitted by Dark_Dragon
This bundle is marked as approved. It works and satisfies the submission rules.
DotA - Freezing Field Remasterd Contains:
Spell - Freezing Field
Item - Scepter


Summons multi explosions around the Jaina damaging enemys and slowing them for x seconds.



Spell requires JNGP v5d or JNGP v2

Changelog


Version 1.1 - Heavy reduced code and no lag when casting anymore.

Version 1.2 - Reduced code again and lag completly removed.

Version 1.3 - Now casters offset is also cleared ( caster point stored and cleared )

Version 1.4 - One of greater spells in world, allowing jass programers to use jass code and GUI programers to use GUI. Still there is 2x Jass triggers one for jass-ers, one for GUI-ers (Jass Advanced) - wich contains 2x triggers one jass and other GUI vars setup for jass trigger. However there is the GUI 4x trigger which I dont suggest to use.
Ver 1.4 adds 2x jass triggers 1x GUI trigger which allows GUI-ers simply edit and custom grafics in both jass allowed SINGLE GUI NOT but GUI jass yes. Very simple edit grafics to for GUI-ers and jass-ers. Maded in Jass Craft editor.

Version 1.4b - Reduced code and used more natives.

Version 1.5 - This is final update, changes are: Code fully optimized and MUI for 2x triggers. (GUI and Jass) and (Jass), single GUI does not need updates as no one will use it, because the GUI trigger which setups Jass one will to very high optimizations in your map.

Version 1.6 - Some fixes in GUI and JASS + jass fixes first lag cast.

Version 1.7 - Spell now contains GUI, GUI/Jass, Jass, vJass (codes) well as you can see its arranged by how good it is first is the worsest and last is the best. Well we are talking about leaks and performances so pick what you want, but note that every code is different, not all codes create custom graphics and some create in different way. I must say that all other then final vJass code are using constant explosions which means they will be create all around you 100%, since we can't know how randomize will work. However i decided to improve random generator with my own simple one and seed. The vJass code does not leak even a single leak and is the fastest, most readable and best documented. I highly suggest you to pick vJass as you can fully customize Freezing Field spell there and you don't need to copy any globals and such... Just go to Freezing Field vJass code and start reading from top until it says don't edit here if you don't know jass.
All installation documentation is in that trigger so you need to know english to understand how easy you can modify this spell. The vJass uses all dynamic objects for spell and as said does not leak anything. However if you still want some other code like you don't understand vJass and you want Jass then pick that, or maybe you just want GUI. As fare as I remember GUI is not MPI, nor did i check it out now. Well you will get the idea of how GUI is done so if you want make it for yourself MUI coz I am not GUI programmer any more and it just blocks my mind to make things how they should be. I would really update GUI but its pointless as even by using GUI your map will leak so as i know how bad GUI is not to say 'SLOW' i just can't code back in it. Ofc i like GUI coz all my programming knowledge started on GUI.

Version 1.7b - Just made dummys unselectable!
Credits goes to N8-11_GER for telling me about this

Version 1.8 (Final) - Optimized script, improved performances and made it 1.24+ compatible!

Version 2.0 - Freezing Field Remasterd
- Totally recoded in zinc
- Can be modified a lot in setup part of trigger
- Now uses mini library



Have fun, this is one of my favorite spells and I hope you enjoy as much as I do.
This is an old Freezing Field DotA spell... Not new one!


=================================

Credits:
=================================


IceFrog - For most idea of spell and Scepter
PurplePoot - For teaching me most of the jass and approving this spell
Hanky - For teaching me as well some things i did not understand like boolexpr null leak
Hive - For hosting my project
Blizzard - For making game


===============================
FAQ
===============================


Q: Will you make the GUI leakless and good as vJass, I don't understand vJass?

A: I am sorry but no, even if you make spells in GUI you must use Custom Script to clear 70% of leaks. So fully leakless in GUI is not possible as well as in Jass but jass can handle 94% leaks fixed. As well i must say I am bad in GUI coz it just blocks my imagination to put in code...

Q: You said vJass is fully customizable but i want to change damage amount and can't find that variables, as well there is variable called ExplosionDur[Level] and even if i change that my caster can move after 3.5 seconds, so how do i fix that?

A: That part goes for Object Editor the damage, slow duration and all that is done in Object Editor, find Freezing Field Damage which is dummy ability and set it up to your stile. About channel time you must change value in Object Editor Freezing Field ability and find Channel Duration then change it to your value in Trigger Editor

Q: Do i need to give credits to you?

A: No, the most idea belongs to IceFrog so i don't ask for credits, i just made it because its one of my favorite spells.

Q: Many spells casted at same time causes my computer to lag, does this spell lag?

A: It depends on your computer, but it should not lag for about 3 casts at same time. 4'th cast might cause only a little visible lag. Still it depends on your PC. However i can say that its coded well so it should not lag for you, but test it on your own.

Q: How can i install this spell? when i open my map it just does not want to past it

A: That is because you must not close my map when copy and pasting data. Just use File -> Open Map so your data does not get erased.


Code
Code (vJASS):
// *****************************************************************************
// *                        Spell: Freezing Field
// *                        -> By: Dark Dragon
// *
// *
// *
// *                        --- Installation ---
// *
// * - 1. Copy this trigger and DD Library if not already
// * - 2. Export and import icon if you want
// * - 3. Change '/*' and '*/' to '//' from code below, save your map and reopen it. Change '//' to '/*' and '*/' as was before
// * - 4. Start editing below until it says "don't edit if you don't know jass"
// * - 5. Enjoy!
// *****************************************************************************


     
// ============================================================================================
// 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 FREEZING_FIELD_DAMAGE_ID             = "FFDg"
     //! 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", FREEZING_FIELD_DAMAGE_ID)
     //! i makechange(current,"anam", "Freezing Field Damage")
     //! i makechange(current,"alev", "4")
     //! i makechange(current,"aher", false)
     //! i makechange(current,"arac", "nightelf")
     
     //! i local i = 0
     //! i for i=1, 4 do
        //! i local si = tostring(i)
        //! i makechange(current,"atar",si,"Enemy,Ground,Organic,Self")
        //! i makechange(current,"Ufn2",si,"0.")
        //! i makechange(current,"aare",si,"160.")
        //! i makechange(current,"ahdu",si,"4.")
        //! i makechange(current,"adur",si,"6.")
        //! i makechange(current,"amcs",si,"0")
     //! i end
     //! i makechange(current,"Ufn1","1","105.")
     //! i makechange(current,"Ufn1","2","150.")
     //! i makechange(current,"Ufn1","3","200.")
     //! i makechange(current,"Ufn1","4","260.")
     
     
     //! i createobject("AEsf", FREEZING_FIELD_ABIL_ID)
     //! i makechange(current,"anam", "Freezing Field")
     //! i makechange(current,"alev", "3")
     //! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
     //! i makechange(current,"arar", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
     //! i makechange(current,"aret", "Learn |cffffcc00F|rreezing Field - [|CFF0960B8Level ".. string.char(37) .."d|r]")
     //! i makechange(current,"arut", "Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur1> seconds. |n|n|cFF0960B8Level 1|r -  Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA1> damage.|n|cFF0960B8Level 2|r -  Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA2> damage.|n|cFF0960B8Level 3|r -  Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA3> damage.|nLast <"..FREEZING_FIELD_ABIL_ID..",HeroDur1> seconds.|n|n|cffff0000Channeling|r")
     
     //! i local i = 0
     //! i for i=1, 3 do
        //! i local si = tostring(i)
        //! i makechange(current,"atar",si,"Self")
        //! i makechange(current,"Esf1",si,"0.")
        //! i makechange(current,"Esf2",si,"4.")
        //! i makechange(current,"Esf3",si,"0.")
        //! i makechange(current,"aare",si,"0.")
        //! i makechange(current,"ahdu",si,"4.1")
        //! i makechange(current,"adur",si,"4.1")
        //! i makechange(current,"acdn",si,"10")
        //! i makechange(current,"abuf",si,nil)
        //! i makechange(current,"aeff",si,nil)
        //! i makechange(current,"atp1",si,"|cffffcc00F|rreezing Field - [|CFF0960B8Level "..si.."|r]")
        //! i makechange(current,"aub1",si,"Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur"..si.."> seconds. Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA"..si.."> damage. |n|nLast <"..FREEZING_FIELD_ABIL_ID..",HeroDur"..si.."> seconds.|n|cffff0000Channeling|r")
     //! i end
     //! i makechange(current,"amcs","1","200")
     //! i makechange(current,"amcs","2","250")
     //! i makechange(current,"amcs","3","300")
     
     //! i if (FREEZING_FIELD_IMPROVED_ABIL_ID ~= nil) then
         //! i createobject("AEsf", FREEZING_FIELD_IMPROVED_ABIL_ID)
         //! i makechange(current,"anam", "Freezing Field")
         //! i makechange(current,"ansf", " ( Upgraded )")
         //! i makechange(current,"alev", "3")
         //! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
         //! i makechange(current,"arar", "ReplaceableTextures\\CommandButtons\\BTNFreezingBreath.blp")
         //! i makechange(current,"aret", "Learn |cffffcc00F|rreezing Field - [|CFF0960B8Level ".. string.char(37) .."d|r]")
         //! i makechange(current,"arut", "Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur1> seconds. |n|n|cFF0960B8Level 1|r -  Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA2> damage.|n|cFF0960B8Level 2|r -  Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA3> damage.|n|cFF0960B8Level 3|r -  Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA4> damage.|nLast <"..FREEZING_FIELD_IMPROVED_ABIL_ID..",HeroDur1> seconds.|n|n|cffff0000Channeling|r")
         
         
         //! i local i = 0
         //! i for i=1, 3 do
            //! i local si = tostring(i)
            //! i makechange(current,"atar",si,"Self")
            //! i makechange(current,"Esf1",si,"0.")
            //! i makechange(current,"Esf2",si,"4.")
            //! i makechange(current,"Esf3",si,"0.")
            //! i makechange(current,"aare",si,"0.")
            //! i makechange(current,"ahdu",si,"4.1")
            //! i makechange(current,"adur",si,"4.1")
            //! i makechange(current,"acdn",si,"10")
            //! i makechange(current,"abuf",si,nil)
            //! i makechange(current,"aeff",si,nil)
            //! i makechange(current,"atp1",si,"|cffffcc00F|rreezing Field - [|CFF0960B8Level "..si.."|r]")
            //! i makechange(current,"aub1",si,"Summons multi explosions around the Jaina damaging enemys and slowing them for <"..FREEZING_FIELD_DAMAGE_ID..",Dur"..tostring(i+1).."> seconds. Each Explosion deals <"..FREEZING_FIELD_DAMAGE_ID..",DataA"..tostring(i+1).."> damage. |n|nLast <"..FREEZING_FIELD_IMPROVED_ABIL_ID..",HeroDur"..si.."> seconds.|n|cffff0000Channeling|r")
            //! i makechange(current,"amcs",si,tostring(150+50*i))
         //! i end

     //! 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,"Neg3","1", FREEZING_FIELD_ABIL_ID..","..FREEZING_FIELD_IMPROVED_ABIL_ID)
        //! i if (CHAIN_FROST_IMPROVED_ABIL_ID ~= nil) then
            //! i makechange(current,"Neg4","1", CHAIN_FROST_ABIL_ID..","..CHAIN_FROST_IMPROVED_ABIL_ID)
        //! i else
            //! i makechange(current,"Neg4","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
// ============================================================================================


// =====================================================================
// Freezing Field library
//
//! zinc
library FreezingField requires DDLib
{

    // **********************************************************
    // ---          Editable Spell Globals
    // **********************************************************
   
    // This is the rawcode of the spell frezzing field
    // Default: 'FFld'
    constant    integer             FF_RAWCODE                      = 'FFld';
   
    // This is the rawcode of the spell frezzing field upgraded
    // Default: 'FFdu'
    constant    integer             FFU_RAWCODE                     = 'FFdu';
   
    // This is the dummy ability frost nova
    // Default: 'FFDg'
    constant    integer             DFN_RAWCODE                     = 'FFDg';
   
    // This is the casters channel effect model
    // Default: "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
    constant    string              CEFF_MODEL                      = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl";
   
    // This is the path to sound file which will be played when spell is cast
    // Default: "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget1.wav"
    constant    string              GLACIER_SOUND                   = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget1.wav";
   
    // This is offset from caster to cause nova damage, meaning to not create explosions on position of caster
    // Default: 50.
    constant    real                NOVA_OFFSET                     = 50.;
   
    // Area of effect of nova, radius
    // Default: 70.
    constant    real                NOVA_AREA                       = 70.;
   
    // Area of effect of the spell, radius, AoE can only be certain numbers that follow the formula:
    // NOVA_OFFSET + NOVA_AREA * n, where n is integer number
    // Default: 470. AoE / n is 6
    constant    real                FREEZING_FIELD_AREA             = NOVA_OFFSET + NOVA_AREA * 6.;
   
    // Explosions per second
    // Default: 12
    constant    integer             EXPLOSIONS_PER_SECOND           = 12;
   
    // Use ice fall graphics, eye candy, but uses more system resources
    // Default: true
    constant    boolean             ICE_FALL_USE                    = true;
   
    // Model file used for graphic display
    // Default: "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl"
    constant    string              ICE_FALL_MODEL                  = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl";
   
    // Size of ice fall block (model)
    // Default: .66
    constant    real                ICE_FALL_SCALE                  = .66;
   
    // Ice fall offset from blast point
    // Default: 340., 400.
    constant    real                ICE_FALL_MIN_OFFSET             = 340.;
    constant    real                ICE_FALL_MAX_OFFSET             = 400.;
   
    // Ice fall initial height and gravity acceleration
    // Default: 1200., 3600.
    constant    real                ICE_FALL_HEIGHT                 = 1200.;
    constant    real                ICE_FALL_ACCELERATION           = 3600.;
   
    // Ice fall angle in degrees
    // Default: -20., 50.
    constant    real                ICE_FALL_MIN_ANGLE              = -20.;
    constant    real                ICE_FALL_MAX_ANGLE              = 50.;
   
    // Use custom terrain type
    // Default: true
    constant    boolean             DO_PAINT_FIELD                  = true;
   
    // Terrain type id
    // Default: 'Iice'
    constant    integer             FIELD_TYPE                      = 'Iice';
   
   
    // -------------------------------------------------------------------------------
    // *** Do not edit ***
    // Default: auto
    constant    key                 FREEZING_FIELD_ID;

   
    // =========================================================================
    //  Custom spell code, do not edit unless you know what you are doing
    // =========================================================================
   
    // ---------------------------------------------
    // * Globals
    // ---------------------------------------------
    sound       GlacierExplode              = null;
   
   
    // ---------------------------------------------
    // * Main data for storing terrain type, and altering it
    // ---------------------------------------------
    struct altfield {
        private {
            integer typ[64], var[64];
            boolean blighted[64];
            real X[64], Y[64];
            integer n=0;
           
            unit bc[64];
            integer bca[64];
            integer bcn;
           
            static  constant            integer         BLIGHT_ABIL_LARGE               = 'Abgl';
            static  constant            integer         BLIGHT_ABIL_SMALL               = 'Abgs';
            static  constant            real            BLIGHT_ABIL_RADIUS              = 960.;
           
        }
       
        private method RemoveBlightAbilArea(real x, real y, boolean remove) {
            if (remove) {
                bcn = 0;
                DDGroupFillMemArea(x, y, BLIGHT_ABIL_RADIUS+FREEZING_FIELD_AREA, this, function() -> boolean {
                    thistype this = DDMemUnitData();
                    if (GetUnitAbilityLevel(GetFilterUnit(), BLIGHT_ABIL_LARGE) > 0) {
                        bc[bcn] = GetFilterUnit();
                        bca[bcn] = BLIGHT_ABIL_LARGE;
                        UnitRemoveAbility(bc[bcn], BLIGHT_ABIL_LARGE);
                        bcn += 1;
                    } else if (GetUnitAbilityLevel(GetFilterUnit(), BLIGHT_ABIL_SMALL) > 0) {
                        bc[bcn] = GetFilterUnit();
                        bca[bcn] = BLIGHT_ABIL_SMALL;
                        UnitRemoveAbility(bc[bcn], BLIGHT_ABIL_SMALL);
                        bcn += 1;
                    }
                    return false;
                });
            }
           
            else {
                while(bcn > 0) {
                    bcn -= 1;
                    if (GetUnitAbilityLevel(bc[bcn], bca[bcn]) == 0)
                        UnitAddAbility(bc[bcn], bca[bcn]);
                   
                }
            }
        }
       
       
        method FreezeField(real x, real y) {
            real w = -FREEZING_FIELD_AREA, h, maxh;
            //n = 0;
           
            RemoveBlightAbilArea(x, y, true);
           
            while(w <= FREEZING_FIELD_AREA) {
                maxh = SquareRoot(Pw_2(FREEZING_FIELD_AREA) - Pw_2(w));
                h = -maxh;
               
                do {
                    if (GetTerrainType(x+w, y+h) != FIELD_TYPE) {
                        X[n] = x+w; Y[n] = y+h;
                        typ[n] = GetTerrainType(X[n], Y[n]);
                        var[n] = GetTerrainVariance(X[n], Y[n]);
                       
                        blighted[n] = IsPointBlighted(X[n], Y[n]);
                        if (blighted[n])
                            SetBlightPoint(Player(0xF), X[n], Y[n], false);
                       
                        SetTerrainType(X[n], Y[n], FIELD_TYPE, -1, 1, 0);
                        n += 1;
                    }
                    h += bj_CELLWIDTH;
                } while(h <= maxh);
               
                w += bj_CELLWIDTH;
            }
        }
       
        method UnfreezeField() {
            if (n > 0) {
                while(n >= 0) {
                    n -= 1;
                    SetTerrainType(X[n], Y[n], typ[n], var[n], 1, 0);
                    if (blighted[n])
                        SetBlightPoint(Player(0), X[n], Y[n], true);
                }
            }
            RemoveBlightAbilArea(0., 0., false);
        }
    }
   
    // -----------------------------------------------------
    // *** primary spell data ***
    // -----------------------------------------------------
    struct ffdata {
        unit caster;
        player owner;
        integer rnd[EXPLOSIONS_PER_SECOND], rnd_n;
        integer lvl;
        altfield af;
       
        private {
            static  real        OX[], OY[];
            static  integer     ON = 0;
            static  location    BlastLoc = null;
        }
       
        static method create(unit c, integer l) -> ffdata {
            ffdata this = allocate();
           
            caster      = c;
            owner       = GetOwningPlayer(c);
            rnd_n       = 0;
            lvl         = l;
            static if (DO_PAINT_FIELD) {
                af = altfield.create();
                af.FreezeField(GetUnitX(caster), GetUnitY(caster));
            }
           
            return this;
        }
       
        method destroy() {
            static if (DO_PAINT_FIELD) {
                af.UnfreezeField();
                af.destroy();
            }
            deallocate();
        }
       
        // *** This is called every second ***
        method TryResetRndN(integer tick) {
            if (ModuloInteger(tick, EXPLOSIONS_PER_SECOND) == EXPLOSIONS_PER_SECOND)
                rnd_n = 0;
        }
       
        // *** returns random n, that is not used ***
        // *** every second this is reseted to 0 ***
        private method GetRndN() -> integer {
            integer n, i;
            boolean flag;
           
            do {
                n = GetRandomInt(0, ON-1);
                flag = false;
                for(i=0; i < rnd_n; i+=1)
                    if (rnd[i] == n) {
                        flag = true;
                        break;
                    }
            } while(flag);
           
            rnd[rnd_n] = n;
            rnd_n += 1;
           
            return n;
        }
       
        // *** Gets us the blast location X, Y ***
        method GetRndLoc() -> location {
            integer n = GetRndN();
            MoveLocation(BlastLoc, GetUnitX(caster) + OX[n], GetUnitY(caster) + OY[n]);
            return BlastLoc;
        }
       
        // --------------------------------------------
        // *** Init static globals ***
        static method onInit() {
            real SAFE_SHIFT = 5.;
            real INIT_RADIUS = NOVA_AREA+NOVA_OFFSET;
            integer MAX_I = R2I( ((FREEZING_FIELD_AREA-INIT_RADIUS-NOVA_AREA+SAFE_SHIFT) / (2.*NOVA_AREA)) ), MAX_J;
           
            integer i, j;
            real r;
           
            BlastLoc = Location(0., 0.);
           
            // *** Loop through radius ***
            for(i=0; i <= MAX_I; i+=1) {
                // Get current radius and fill circumference with nova circles
                r = INIT_RADIUS + (i*2.*NOVA_AREA);
                MAX_J = R2I(bj_PI / Atan(NOVA_AREA/r));
                for(j=0; j < MAX_J; j+=1) {
                    // *** Loop through angle, and store points ***
                    OX[ON] = r * Cos(j*(2.*bj_PI/MAX_J));
                    OY[ON] = r * Sin(j*(2.*bj_PI/MAX_J));
                    ON += 1;
                }
            }
            //BJDebugMsg(I2S(ON));
        }
       
    }
   
   
    // -------------------------------------------------------
    // *** Ice fall graphic struct
    // -------------------------------------------------------
    struct icefall {
        private {
            xeffect xe;
            //real x, y, z;
            real ox, oy;
            player p;
            integer l;
           
            static location pLoc = null;
        }
       
        // -----------------------------------
        // *** Constructor
        static method create(player owner, location loc, integer lvl) -> icefall {
            icefall     this            = allocate();
            real        xy_shift        = GetRandomReal(ICE_FALL_MIN_OFFSET, ICE_FALL_MAX_OFFSET);
            real        alpha           = GetRandomReal(ICE_FALL_MIN_ANGLE, ICE_FALL_MAX_ANGLE)*bj_DEGTORAD;
            real        t               = SquareRoot(2.*ICE_FALL_HEIGHT/ICE_FALL_ACCELERATION);
            real        dx              = Cos(alpha),
                        dy              = Sin(alpha);
           
            xe = xeffect.create(ICE_FALL_MODEL, GetLocationX(loc) + xy_shift * dx, GetLocationY(loc) + xy_shift * dy, /*bj_RADTODEG*(alpha-bj_PI)*/bj_UNIT_FACING, ICE_FALL_SCALE);
            xe.Z = ICE_FALL_HEIGHT;
            ox = DD_INTERVAL*-dx*xy_shift/t;
            oy = DD_INTERVAL*-dy*xy_shift/t;
            p = owner;
            l = lvl;
            pLoc = loc;
           
            return this;
        }
       
        // -----------------------------------
        // *** Run motion, auto destroy
        method InitMotion() {
            DDStartTim(DD_INTERVAL, true, this, function() {
                icefall this = DDTimData();
                integer tick = DDTimTick();
               
                // *** Impact?
                if (xe.Z < 10.) {
                    MoveLocation(pLoc, xe.X, xe.Y);
                    FrostNovaExplosion.evaluate(p, pLoc, l);
                    xe.destroy();
                    destroy();
                    DDQuitTim();
                    return;
                }
               
                // *** Motion of ice blocks ***
                xe.X += ox;
                xe.Y += oy;
                xe.Z = ICE_FALL_HEIGHT - (.5*ICE_FALL_ACCELERATION*Pw_2(tick*DD_INTERVAL));
            });
        }
    }
   
   
    function FrostNovaExplosion(player owner, location expLoc, integer lvl) {
        unit dummy = DDLoadSpellDummy(owner, GetLocationX(expLoc), GetLocationY(expLoc), DFN_RAWCODE, lvl);
        UnitRemoveAbility(dummy, 'Aloc');
        IssueTargetOrder(dummy, "frostnova", dummy);
        DDStartTim(1., false, New_pUnit(dummy), function() {
            p_unit pd = DDTimData();
            SetWidgetLife(pd[0], GetUnitState(pd[0], UNIT_STATE_MAX_LIFE));
            UnitAddAbility(pd[0], 'Aloc');
            UnitRemoveAbility(pd[0], DFN_RAWCODE);
            DDRecycleDummy(pd[0]);
            pd.destroy();
            DDQuitTim();
        });
    }
   
    // =========================================================================
    //
    //                      *** Init spell Freezing Field ***
    //
    // =========================================================================

    function onInit() {
        trigger t = CreateTrigger();
        TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
        TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_ENDCAST);
        TriggerAddCondition(t, Condition(function() -> boolean {
            ffdata d;
            integer lvl;
           
            // ------------------------------------------------
            // Primary condition
            // ------------------------------------------------
            if (GetSpellAbilityId() != FF_RAWCODE && GetSpellAbilityId() != FFU_RAWCODE)
                return false;
           
           
            // ------------------------------------------------
            // Check if spell is done
            // ------------------------------------------------
            if (GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_ENDCAST) {
                // *** End spell ***
                DDSet(GetTriggerUnit(), FREEZING_FIELD_ID, 0);
                return false;
            }
           
            // ------------------------------------------------
            // New instance initialize
            // ------------------------------------------------
            lvl = GetUnitAbilityLevel(GetTriggerUnit(), GetSpellAbilityId());
            if (GetSpellAbilityId() == FFU_RAWCODE) lvl += 1;
           
            d = ffdata.create(GetTriggerUnit(), lvl);
           
            // *** Play sound ***
            SetSoundPosition(GlacierExplode, GetUnitX(d.caster), GetUnitY(d.caster), 0.);
            StartSound(GlacierExplode);
           
            // *** Load effects ***
            DestroyEffect( AddSpecialEffectTarget(CEFF_MODEL, d.caster, "origin") );
           
            // *** Is casting = true
            DDSet(GetTriggerUnit(), FREEZING_FIELD_ID, 1);
            DDStartTimInst(1./EXPLOSIONS_PER_SECOND, true, d, function() {
                ffdata d = DDTimData();
                integer tick = DDTimTick();
               
                // *** Quit spell ***
                if (DDGet(d.caster, FREEZING_FIELD_ID) == 0) {
                    d.destroy();
                    DDQuitTim();
                }
               
                // *** Create explosion ***
                static if (ICE_FALL_USE)
                    icefall.create(d.owner, d.GetRndLoc(), d.lvl).InitMotion();
                else
                    FrostNovaExplosion(d.owner, d.GetRndLoc(), d.lvl);
                   
                // *** Every second all possible locs are reseted
                d.TryResetRndN(tick);
                   
            });
           
           
            // ------------------------------------------------
            //
            // *** End trigger condition ***
            //
            return false;
            // ------------------------------------------------
        }));
       
       
        // ----------------------------
        // *** Load sound ***
        GlacierExplode = CreateSound(GLACIER_SOUND, false, true, true, 10, 10, "DefaultEAXON");
        SetSoundParamsFromLabel(GlacierExplode, "FrostNova");
        SetSoundPitch(GlacierExplode, 0.5);
        SetSoundVolume(GlacierExplode, 127);
    }
}
//! endzinc
 



Hope you enjoy the spell!

~Dark Dragon


Keywords:
frost, dota, ice, field, freezing, freezing field, other
Contents

Spell - Freezing Field (Map)

Reviews
Moderator
PurplePoot: When you use Position of FF_Caster offset by (blah), the Position of FF_Caster leaks too. However, enough of the leaks are fixed that ~approved~. Please fix the rest if you find time, though.
  1. PurplePoot:

    When you use Position of FF_Caster offset by (blah), the Position of FF_Caster leaks too. However, enough of the leaks are fixed that ~approved~. Please fix the rest if you find time, though.
     
  2. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok I used Scepter only for people to see how it is done. I dont knowe what do you mean that GUI is only half decent, I say that it is a long code that is the problem in this spell and leaks? Leaks I dont knowe what misses in there. Spell works good. If it does not work to you then please tell me where you found bug.
     
  3. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,162
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    You never destroy any Points, thus causing a good many leaks. Other than that, there aren't any glaring problems.
     
  4. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok I fix all the stuff now this spell is pro for sure.
     
  5. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,162
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    Same problem as with your other spell.
     
  6. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok this is final fix now everything is cleared and code max reduced, please rate and comment ty.
     
  7. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Yes you are right i shuld thing of this sooner sry for waiting.
     
  8. Need_O2

    Need_O2

    Joined:
    Aug 24, 2007
    Messages:
    2,880
    Resources:
    0
    Resources:
    0
    hey you could do that with 1 simple trigger but you love advanced way eh ?
     
  9. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    no i like less code because it will make a ultimate long code if i wuld use all that in one trigger ok.
     
  10. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,162
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    Code (vJASS):
                set l[i] = Location( PolarProjectionX( GetLocationX( udg_FF_Point ), 75, 10 * I2R(i) ), PolarProjectionY( GetLocationY( udg_FF_Point ), 75, 10 * I2R(i) ) )
                call CreateNUnitsAtLoc( 1, Grf_RawCode(), p, l[i], ((10 * I2R(i)) - 90) )
                set udg_u[i] = GetLastCreatedUnit()


    Could be

    Code (vJASS):
    set udg_u[i] = CreateUnit(p,Grt_RawCode(),PolarProjectionX( GetLocationX( udg_FF_Point ), 75, 10 * I2R(i) ),PolarProjectionY( GetLocationY( udg_FF_Point ), 75, 10 * I2R(i) ),((10 * I2R(i)) - 90))


    (same thing with other instances of CreateNUnitsAtLoc)

    Also, I suggest moving completely to coordinates as opposed to locations.

    Also, try to calculate directly in radians for efficiency; just remember that pi radians = 180 degrees, and 2pi radians = 360 degrees.

    Fix these up (a large part of the criticism) and I'll give you some more ;)
     
  11. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Ok you say that you will give me more tips, but I fix more than u say so notify me if you find more things to edit
     
  12. z3rYu

    z3rYu

    Joined:
    Jan 4, 2007
    Messages:
    67
    Resources:
    0
    Resources:
    0
    hey,awesome spell
    how can i change the graphic of the explosion?
     
  13. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    You can change the graphics by seting the dummy's model in object editor, you will find it there good luck
     
  14. vhx

    vhx

    Joined:
    Jan 15, 2008
    Messages:
    36
    Resources:
    0
    Resources:
    0
    Good job. Only problem I have with this spell is that when the loop starts to kick in, the
    Code (Text):
        //=========================
        // Create Effects on caster
        set bj_lastCreatedEffect = AddSpecialEffectTarget( &quot;Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl&quot;, udg_FF_Caster, &quot;origin&quot; )
        call DestroyEffect( bj_lastCreatedEffect )
        //=========================
    Begins to double the lag the spell should cause. I just took it out and called it through a trigger so it shows up once and it works fine.
     
  15. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    ok you can put this line of code in begin casting trigger if you want this effect to be created only once, by default this is created every 1 second ( 3 times ) because spell last 3 seconds, but if you like it this way do it :]
     
  16. Equal

    Equal

    Joined:
    Mar 23, 2007
    Messages:
    306
    Resources:
    1
    Maps:
    1
    Resources:
    1
    is this meant to be MUI ?
    cus as i placed 11 IceMages , set reqierd lvl from 6 to 1 and let them cast...
    hell, after the 2 cast it showd me a Error message,...

    as i continued,
    holy sh*t my PC was frozen too, WC3 stoped completly and i hab to terminate wc3.

    Edit : here is a link to what happens
    http://bildupload.sro.at/p/234428.html
    and the iceEffect circle stays for ever.
     
  17. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    As fare I can tell I made this spell long time ago, I mean I was learning jass in that time so I am sure its not MUI as it uses globals.

    I am on to make it MUI soon.
     
  18. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    588
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    Here is update you needed no locations used less function usage and its as max as possible natives used and constant functions. All is updated other the fully GUI 4x triggers which is not MUI and is ofc pathetic code in your map. But GUI made for jass setup whit global variables will do everything for you in second its 75% faster for yu to copy 2x triggers and edit in GUI only a few globals then all 4x trigger of GUI.

    If you have a problem or dont know how to do something mail me at &lt;darkdragon_hr@yahoo.com&gt; or post comment here.

    Have fun!
     
  19. Teddu

    Teddu

    Joined:
    Jan 26, 2008
    Messages:
    6
    Resources:
    0
    Resources:
    0
    how the heck do you make these spells? please tell me i wana make my own