• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Frost Bite v1.0.2

Frost Bite v1.0.2


Credits

Models
-Vexorian

Requires

-Dummy.mdx

Changelogs

v1.0.0
-release
v1.0.1
-fix vacuum indexing
v1.0.2
-fix cast function
-added importing detail


JASS:
native UnitAlive takes unit id returns boolean//Remove this if you already had one
//! zinc
    library FrostBite
    /*-----------------------------------------------------------------------------------/
    /-    v1.0.2
    /-       JC Helas
    /-
    /-   Description:
    /-       Release an ice trap that moves back and forth, after move
    /-       a nova ice will expload that cause them vacuumed to caster's
    /-       position.
    /-
    /-   How to Import:
    /-       1. Goto File>Preferences>General
    /-       2. Mark check the "Automatically create unknown varaibles while pasting data.
    /-       3. Copy the imported dummy.mdx and the custom locust object
    /-       4. Then copy the folder and paste on your map.
    /-
    /-    The spell does not require any libraries.
    /-
    /-----------------------------------------------------------------------------------*/
    {
        private
        {
            /*- Determine the ability ID of Frost Bite -*/
            constant integer SPELL_ID = 'A000'                                            ;
            /*- Determine the dummy id of that stands as frost trap -*/
            constant integer DUM_ID   = 'u000'                                            ;
            /*- Determine the base amount of frost trap -*/
            constant integer LINES    = 12                                                ;
            /*- Determine the additional line per level -*/
            constant integer LINES_LVL= 2                                                 ;
            /*- Determine the damage amount of back and forth -*/
            constant real DAMAGE      = 50.0                                              ;
            /*- Determine the additional amount of damage -*/
            constant real DAMAGE_LVL  = 5.0                                               ;
            /*- Determine the affect of area per line -*/
            constant real DAMAGE_AOE  = 75.0                                              ;
            /*- Determine the distance travel of each line -*/
            constant real DISTANCE    = 600.0                                             ;
            /*- Determine the speed of forth -*/
            constant real SPEED_FORTH = 20.0                                              ;
            /*- Determine the speed of back -*/
            constant real SPEED_BACK  = 35.0                                              ;
            /*- Determine the summoning distance to target caster position -*/
            constant real SUMMON_DIST = 50.0                                              ;
            /*- Determine the speed of vacuum -*/
            constant real VACUUM_SPEED= 25.0                                              ;
            /*- Determine the flying height of vacuumed unit -*/
            constant real VACUUM_Z    = 300.0                                             ;
            /*- Determine the attack type of Frost Bite -*/
            constant attacktype A_TYPE= ATTACK_TYPE_MAGIC                                 ;
            /*- Determine the damage type of Frost Bite -*/
            constant damagetype D_TYPE= DAMAGE_TYPE_NORMAL                                ;
            /*- Determine the owner of dummies -*/
            constant player DUM_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)                    ;
            /*- Determine the model attachment to dummy -*/
            constant string ATTACH    = "origin"                                          ;
            /*- Determine the model of dummy -*/
            constant string MODEL     = "Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl";
            /*- Determine the nova fx -*/
            constant string TARGETFX  = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl";
           
           
            struct data
            {
                player owner;
                unit caster,dummy;
                real angle,rate,speed,dmg,dx,dy;
                effect fx;
                boolean b;
                group g;
            }
           
            struct vacuumdata
            {
                unit u;
                real d,r,z,bz,a;
            }
           
            constant real periodic=0.031250;
            constant group grp=CreateGroup();
            constant timer tmr=CreateTimer();
            integer ix=0;
            integer ic[];
            data link=0;
           
            constant timer vtmr=CreateTimer();
            integer vix=0;
            integer vic[];
           
            function onVacuumLoop()
            {
                integer i=1;
                real x,y;
                vacuumdata this;
                while(i<=vix)
                {
                    this=vic[i];
                    this.r=this.r+VACUUM_SPEED;
                    x=GetUnitX(this.u)+VACUUM_SPEED*Cos(this.a*bj_DEGTORAD);
                    y=GetUnitY(this.u)+VACUUM_SPEED*Sin(this.a*bj_DEGTORAD);
                    SetUnitX(this.u,x);
                    SetUnitY(this.u,y);
                    SetUnitFlyHeight(this.u,this.bz+(Sin(((180.0/this.d)*this.r)*bj_DEGTORAD)*this.z),0.0);
                    if(this.r>=this.d)
                    {
                        SetUnitPathing(this.u,true);
                        SetUnitFlyHeight(this.u,GetUnitDefaultFlyHeight(this.u),0);
                        this.u=null;
                        vacuumdata.destroy(this);
                        vic[i]=vic[vix];
                        vix-=1;
                        i-=1;
                        if(vix==0)PauseTimer(vtmr);
                    }
                    i+=1;
                }
            }
           
            function onVacuum(unit t,real x,real y)
            {
                real dx,dy,xt=GetUnitX(t),yt=GetUnitY(t);
                vacuumdata this=vacuumdata.create();
                vix+=1;vic[vix]=this;
                dx=x-xt;dy=y-yt;
                this.u=t;
                this.r=0.0;
                this.bz=GetUnitFlyHeight(t);
                this.d=SquareRoot(dx*dx+dy*dy)*0.75;
                this.z=(VACUUM_Z/(DISTANCE*0.75))*this.d;
                this.a=bj_RADTODEG*Atan2(y-yt,x-xt);
                UnitAddAbility(t,'Amrf');UnitRemoveAbility(t,'Amrf');
                SetUnitPathing(t,false);
                DestroyEffect(AddSpecialEffect(TARGETFX,xt,yt));
                if(vix==1)TimerStart(vtmr,periodic,true,function onVacuumLoop);
            }
           
            function onFilter(unit t,player p) -> boolean
            {
                return UnitAlive(t) &&
                !IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE) &&
                !IsUnitType(t,UNIT_TYPE_STRUCTURE) &&
                !IsUnitAlly(t,p);
            }
           
            function onLoop()
            {
                data this;
                integer i=1;
                real x,y;
                unit t;
                while(i<=ix)
                {
                    this=ic[i];
                    x=this.dx;
                    y=this.dy;
                    if(this.rate<100.0)
                    {
                        this.rate=this.rate+this.speed;
                        x=x+(Sin(((180.0/100)*this.rate)*bj_DEGTORAD)*DISTANCE)*Cos(this.angle*bj_DEGTORAD);
                        y=y+(Sin(((180.0/100)*this.rate)*bj_DEGTORAD)*DISTANCE)*Sin(this.angle*bj_DEGTORAD);
                        SetUnitX(this.dummy,x);
                        SetUnitY(this.dummy,y);
                        link=this;
                        GroupEnumUnitsInRange(grp,x,y,DAMAGE_AOE,Filter(function()
                        {
                            unit t=GetFilterUnit();
                            if(onFilter(t,link.owner) && !IsUnitInGroup(t,link.g))
                            {
                                UnitDamageTarget(link.caster,t,link.dmg,true,true,A_TYPE,D_TYPE,null);GroupAddUnit(link.g,t);
                                if(!link.b)
                                {
                                    onVacuum(t,link.dx,link.dy);
                                }
                            }
                            else
                            {
                            }
                        }));
                        GroupClear(grp);
                        if(this.rate>=50.0 && this.b)
                        {
                            this.b=false;
                            this.speed=(100.0/DISTANCE)*SPEED_BACK;
                            GroupClear(this.g);
                        }
                    }
                    else
                    {
                        GroupClear(this.g);
                        DestroyEffect(this.fx);
                        KillUnit(this.dummy);
                        this.caster=null;
                        this.dummy=null;
                        this.owner=null;
                        data.destroy(this);
                        ic[i]=ic[ix];
                        ix-=1;
                        i-=1;
                        if(ix==0)PauseTimer(tmr);
                    }
                    i+=1;
                }
            }
           
            function onCast() -> boolean
            {
                unit u;
                player p;
                real x1,y1,x2,y2,a,d;
                integer i,lvl;
                data this;
                if(GetSpellAbilityId()==SPELL_ID)
                {
                    u=GetTriggerUnit();
                    p=GetOwningPlayer(u);
                    lvl=GetUnitAbilityLevel(u,SPELL_ID);
                    i=LINES+(LINES_LVL*lvl);
                    d=DAMAGE+(DAMAGE_LVL*lvl);
                    x1=GetUnitX(u);
                    y1=GetUnitY(u);
                    a=360.0/i;
                    while(i>0)
                    {
                        x2=x1+SUMMON_DIST*Cos((a*i)*bj_DEGTORAD);
                        y2=y1+SUMMON_DIST*Sin((a*i)*bj_DEGTORAD);
                        this=data.create();
                        ix+=1;ic[ix]=this;
                        this.b=true;
                        this.dx=x2;
                        this.dy=y2;
                        this.dmg=d;
                        this.rate=0.0;
                        this.speed=(100.0/DISTANCE)*SPEED_FORTH;
                        this.angle=a*i;
                        this.caster=u;
                        this.owner=p;
                        this.dummy=CreateUnit(DUM_OWNER,DUM_ID,x2,y2,a*i);
                        this.fx=AddSpecialEffectTarget(MODEL,this.dummy,ATTACH);
                        if(this.g==null)this.g=CreateGroup();
                        if(ix==1)TimerStart(tmr,periodic,true,function onLoop);
                        i-=1;
                    }
                    u=null;
                }
                return false;
            }
           
            function onInit()
            {
                trigger t=CreateTrigger();
                integer i=0;
                while(i<=11)
                {
                    TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null);
                    i+=1;
                }
                TriggerAddCondition(t,Filter(function onCast));
                t=null;
            }
        }
    }
   
//! endzinc
Contents

Frost Bite v1.0.2 (Map)

Level 14
Joined
Oct 19, 2014
Messages
187
Got daamn gentlemenss,, im very sorry i forgot the while of vacuum was while(i<vix) instead of while(i<=vix)

Edit: Done

Your spells are isane.Gj n keep up the great work !

Thanks maan, it is just I love watching chaotic spells XD

Just another Warcraft III map is an amazing title /sarcasm

For some reason, vJass short variable always annoys me, and confuse me as well. I'm referring to vacuumdata struct.
Anyway, nice spell
Hahaha classic title XD, about those variables XD I purposely meant them beacuse vacuum is just an extention of this spell XD
And thanks :D
 
Last edited:
Level 14
Joined
Oct 19, 2014
Messages
187
These look awesome, love the creativity.
Thanks maan :D stay tune for more.

Also make some preview gifs that are better than the one you use for an Icon!
@Mythic extended his gracious hand to recommend me Screentogif that is extremely useful, pair that with Ezgif.com and you can be scrupulous on the finer details.
Actaully I dont have legal internet, I used to hack internet with 10mb capping. XD
 
Last edited:
A simplistic spell concept pulled off with freezing aplomb. The wrath of the chilling frost bares down its fangs on any unsuspecting foe.
Beware the unrelenting bite of frost!
  • I'm not sure why the group object in the struct "data" is cleared out and reused for later iterations, when creating and destroying these group objects would be just as impactful as the current approach.

  • The names for the struct members should be made more verbose; at a first glance, their purpose is unclear to possible maintainers.

  • The filter function is usually a configurable function for the user. As such, I'd recommend moving it up to the configuration section of the library.

  • Manually registering the spell effect event to the list of players through a loop might not be convenient for differing versions of wc3. I would recommend using the BJ function in this case.
    JASS:
    TriggerRegisterAnyPlayerUnitEventBJ
 
Level 14
Joined
Oct 19, 2014
Messages
187
A simplistic spell concept pulled off with freezing aplomb. The wrath of the chilling frost bares down its fangs on any unsuspecting foe.
Beware the unrelenting bite of frost!
  • I'm not sure why the group object in the struct "data" is cleared out and reused for later iterations, when creating and destroying these group objects would be just as impactful as the current approach.

  • The names for the struct members should be made more verbose; at a first glance, their purpose is unclear to possible maintainers.

  • The filter function is usually a configurable function for the user. As such, I'd recommend moving it up to the configuration section of the library.

  • Manually registering the spell effect event to the list of players through a loop might not be convenient for differing versions of wc3. I would recommend using the BJ function in this case.
    JASS:
    TriggerRegisterAnyPlayerUnitEventBJ
Right after i recover my knowledge of this game 😌

i still lack of awareness when it comes to friendly users before but now I realized that we are creating spells not just for experienced map maker but also consider those new user instead, be more careful in making details and almost configurable features 😌 ty guys
 
Top