Hell Ice v1.2

This bundle is marked as approved. It works and satisfies the submission rules.
-------------------------------------------
**
**H E L L**
**
**I C E**
**

Sorry for my music in that video, i forgot to remove it =.=!
I/ Spell Information:
untitl55.jpg

II/ Spell Code:
JASS:
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
// H E L L  I C E
//                  By: Elphis
//          - Spell Information:
//                              - Use the power, call the ice jutting up from the ground, and attack the enemy
//                                when enemies close range around 100 range, ice will blown up enemies and takes 30/60/90/120 damages.
//                                Ice Count: 35/40/45/50
//          - Installation:
//                                - Import/copy the required libraries and Hell Ice code to your map
//                                - Export model Unleash the power and import it into your map
//                                - Import/copy the custom ability and unit to your map and change the SPELL_ID, DUMMY, FLY_ID if needed
//                                - You may view the raw ID of the objects by pressing CTRL+D in the object editor
//                                - You may play with the configurables below
//***********************************************************************************************************
//          - Credits:
//                    Unleash the Power Model - http://www.hiveworkshop.com/forums/models-530/unleash-power-243024/
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//***********************************************************************************************************
//
//
module init
    static method onInit takes nothing returns nothing
        call spellInit()
    endmethod
endmodule
//
//
//! zinc
library HellIce requires HellIcePlugin{


    //**********************************************************************************
    /**/        constant integer    SPELL_ID         =   'A000'; // Spell rawcode, change if needed
    /**/        constant integer    DUMMY            =   'e000'; // Dummy rawcode, change if needed
    /**/        constant integer    FLY_ID           =   'Amrf'; // Ability make unit fly, change if needed
    /**/        constant integer    ICE_COUNT        =   30; // Total count of ice springing up
    /**/        constant real       HEIGHT_PER_SCALE =   40.; //Height per scale increase
    /**/        constant real       PERIODIC         =   .031250000; // Timer Periodic
    /**/        constant real       AREA_OF_EFFECT   =   600.; // Area of ice springing up
    /**/        constant real       MAX_SCALE        =   1.5; // Max scaling of ice
    /**/        constant real       SCALE_INTEVAR    =   0.1; // Scale increase per period
    /**/        constant real       HIT_RADIUS       =   100.; // Radius ice hit enemies
    /**/        constant real       DAMAGE_BASE      =   30.; // Damage base of spell
    /**/        constant string     EFFECT_ICE       =   "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"; // Effect combine with Ice when it springing up
    /**/        constant string     EFFECT_FALL      =   "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"; // Effect when enemies fall and hit ground
    /**/        constant string     EFFECT_BLOOD     =   "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"; // Effect hit enemies
    /**/        constant string     EFFECT_DISAPEAR  =   "war3mapImported\\Unleash the power.mdx"; // Effect when ice disapear
    /**/        constant string     ATTACHMENT       =   "chest"; // Attach of effect when hitting enemies
    //**********************************************************************************
    /**/        constant attacktype ATTACK_TYPE      =   ATTACK_TYPE_HERO;
    /**/        constant damagetype DAMAGE_TYPE      =   DAMAGE_TYPE_COLD;
    /**/        constant weapontype WEAPON_TYPE      =   WEAPON_TYPE_METAL_HEAVY_BASH;
    //**********************************************************************************
    /**/
    /**/       constant  timer      TIMER            =   CreateTimer();
    /**/                 integer    MUI              =   0;
    /**/                 integer    S[];
    /**/
    
    
    struct HellIce {
        
        
        
        real intevar = 0;
        real damage;
        real tx;
        real ty;
        integer icecount = ICE_COUNT;
        unit caster;
        
        
        
        //Function period
        static method onPeriodic(){
            thistype this;
            real angle = GetRandomReal(0, 6.28319);
            real distance = GetRandomReal(0,AREA_OF_EFFECT);
            real cos = distance * Cos(angle);
            real sin = distance * Sin(angle);
            real x;
            real y;
            integer l;
            //
            for(0<l<=MUI)
            {
                //
                this = S[l];
                //
                x = tx + cos;
                y = ty + sin;
                //
                if(icecount > 0){
                    this.icecount = icecount - 1;
                    //Calling ice
                    HIP.add(caster,CreateUnit(Player(15),DUMMY,x,y,0.),damage,MAX_SCALE,SCALE_INTEVAR,HIT_RADIUS,HEIGHT_PER_SCALE,EFFECT_FALL,EFFECT_BLOOD,ATTACHMENT,EFFECT_DISAPEAR,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE,FLY_ID);
                    //Effect
                    DestroyEffect(AddSpecialEffect(EFFECT_ICE,x,y));
                }
                else{
                    S[l] = S[MUI];
                    S[MUI] = -1;
                    MUI = MUI - 1;
                    caster = null;
                    destroy();
                }
                //
            }
        }
        
        
        
        static method onCast() -> boolean {
            thistype this;
            integer level;
            //
            if(GetSpellAbilityId() == SPELL_ID){
                this = allocate();
                MUI = MUI + 1;
                S[MUI] = this;
                caster = GetTriggerUnit();
                level = GetUnitAbilityLevel(caster,SPELL_ID);
                damage = DAMAGE_BASE*level; // Damage settings
                icecount = icecount + 5 * level; // Ice count settings
                tx = GetSpellTargetX();
                ty = GetSpellTargetY();
                //
                if(MUI==1)
                    TimerStart(TIMER,PERIODIC,true,function thistype.onPeriodic);
                //
            }
            return false;
        }
        
        
        
        //Init
        static method spellInit() {
            trigger t = CreateTrigger();
            integer i;
            //
            for(-1 < i < bj_MAX_PLAYER_SLOTS) {
                TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null);
            }
            TriggerAddCondition(t,function thistype.onCast);
            t = null;
        }
        
        
        module init;
    }
}
//! endzinc
[/HIDDEN]
JASS:
//! zinc
//! zinc
library HellIcePlugin{
    
    constant real PERIOD = .031250000;
    constant timer MainTimer = CreateTimer();
    constant group GROUP = CreateGroup();
             integer StrucData[];
             integer MUI = 0;
    //
    public struct HIP{
    
    unit c;
    unit caster;
    unit dum = null;
    real dmg;
    real scale;
    real radius;
    real scaleintevar;
    real height;
    real minscale;
    real scl = 0.;
    real minh = 0.;
    attacktype att;
    damagetype dam;
    weapontype wea;
    integer fl;
    string effectice;
    string bl;
    string at;
    string dis;
    boolean b = false;
    
    static method allies(unit u,unit f) -> boolean{
        //
        return IsUnitEnemy(f,GetOwningPlayer(u)) && !(IsUnitType(u,UNIT_TYPE_DEAD) || GetUnitTypeId(u) == 0);
        //
    }
    
    static method onPeriodic(){
        thistype this;
        integer i;
        unit f;
        //
        for(0 < i <= MUI){
            
            this = StrucData[i];
            
            if(scl <= scale && !b){
                scl = scl + scaleintevar;
                minh = minh + height;
                //
                b = (scl >= minscale);
            }
            else{
                scl = scl - scaleintevar;
                minh = minh - height;
                //
                if(minh <= 0.){
                
                    StrucData[i] = StrucData[MUI];
                    StrucData[MUI] = -1;
                    MUI = MUI - 1;
                    
                    if(MUI == 0)
                        PauseTimer(MainTimer);
                
                    if(dum != null && GetUnitFlyHeight(dum) <= GetUnitDefaultFlyHeight(dum)+50)
                    {
                        UnitDamageTarget(caster,dum,dmg,true,false,att,dam,wea);
                        DestroyEffect(AddSpecialEffect(effectice,GetWidgetX(dum),GetWidgetY(dum)));
                        SetUnitFlyHeight(dum,GetUnitDefaultFlyHeight(dum),0.);
                    }
                    DestroyEffect(AddSpecialEffect(dis,GetWidgetX(c),GetWidgetY(c)));
                    RemoveUnit(c);
                    att = null;
                    dam = null;
                    wea = null;
                    c = null;
                    destroy();
                }
            }
            //
            SetUnitScale(c,scl,0.,0.);
            //
            if(IsUnitType(dum,UNIT_TYPE_DEAD) || GetUnitTypeId(dum) == 0){
                SetUnitFlyHeight(dum,GetUnitDefaultFlyHeight(dum),0.);
                dum = null;
            }
            else
                SetUnitFlyHeight(dum,minh,0.);
            //
            GroupEnumUnitsInRange(GROUP,GetWidgetX(c),GetWidgetY(c),radius,null);
            //
            if(dum == null){
                while(FirstOfGroup(GROUP) != null){
                    
                    f = FirstOfGroup(GROUP);
                    
                    if(allies(caster,f))
                        if(GetUnitFlyHeight(f) < minh){
                            if(UnitAddAbility(f,fl))
                                UnitRemoveAbility(f,fl);
                            dum = f;
                            UnitDamageTarget(caster,dum,dmg/2,true,false,att,dam,wea);
                            DestroyEffect(AddSpecialEffectTarget(bl,dum,at));
                            break;
                        }
                    
                    GroupRemoveUnit(GROUP,f);
                }
            }
        }
    }
    
    static method add(unit s,unit u,real d,real maxscale,real sclintevar,real hitradius,real h,string eff,string blood,string attach,string disa,attacktype a,damagetype dd,weapontype w,integer fly){
        thistype this = allocate();
        //
        MUI = MUI + 1;
        StrucData[MUI] = this;
        //
        if(MUI == 1){
            TimerStart(MainTimer,PERIOD,true,function thistype.onPeriodic);
        }
        //
        c = u;
        dis = disa;
        caster = s;
        dmg = d;
        effectice = eff;
        height = h;
        scale = maxscale;
        scaleintevar = sclintevar;
        minscale = scale - scaleintevar;
        radius = hitradius;
        fl = fly;
        at = attach;
        bl = blood;
        att = a;
        dam = dd;
        w = wea;
        //
    }
    }
}
//! endzinc
III/ Spell Look Like:

untitl54.jpg

untitl56.jpg


-------------------------------------------


v1.0: First release version.
v1.1: Optimized
v1.2: Removed TimerUtils, fixed bugs, optimized


Keywords:
ice
Contents

Hell Ice (Map)

Reviews
16:38, 17th Dec 2013 PurgeandFire: Approved. (old) Review: http://www.hiveworkshop.com/forums/2458210-post13.html

Moderator

M

Moderator

16:38, 17th Dec 2013
PurgeandFire: Approved.

(old) Review:
http://www.hiveworkshop.com/forums/2458210-post13.html
 
Originality: 5/5. Very original use of ice. I like that one!

Execution: 4/5. Some mistakes that I've pointed out:
  • Please follow JPAG while naming the variables. It makes the code more readable. You cannot name them like timer T. Use timer MainTimer instead.
  • Math operators should be organized like: 2*1 + 8/2 - 2*5/9. This way you can define the priority of the operation clearly. Thanks to Nestharus for the idea. You can see it inside JPAG too!
  • That's more optimized to use
    JASS:
                        b = (scl >= minscale);
    instead of
    JASS:
                    if(scl >= minscale)
                        b = true;
  • Action order: define local variables -> do your actions -> do removing functions -> do nulling handles -> destroy struct if needed. The example of good organized code:
    JASS:
        local integer firstNumber  = 1
        local integer secondNumber = 2
        local integer thirdNumber  = 3
        local unit    myUnit       = CreateUnit(Player(11),'n000',0.,0.,0.)
        // Your actions
    
        call RemoveUnit(myUnit)
    
        set myUnit = null
Nothing more bad noticed.

Effects: 5/5. Very blasting and beautiful icy spell. I max out this point cause it is very beautiful!

Overall: (5+4+5)/3=4.6/5=4/5. Fix the errors that I've pointed and you have 5/5 from me!

4/5: Recommended
 
Review:
  • This line:
    real angle = .0174533*GetRandomReal(0,360);
    Can just be:
    real angle = GetRandomReal(0, 6.28319)
    (or 2 * bj_PI)
    This is minor.
  • The dead check should be:
    JASS:
       static method allies(unit u,unit f) -> boolean{
            //
            return IsUnitEnemy(f,GetOwningPlayer(u)) && !(IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0);
            //
        }
    The GetUnitTypeId() will check to make sure the unit wasn't removed. (minor)
  • You should use a separate group. Don't use bj_lastCreatedGroup. If a GUI user destroys it, then the spell won't work.

The first two are minor. I would've probably approved it anyway. The third thing should be fixed because it can potentially break the spell. I'm going to move it to "Needs fix", but once you make those changes, it will be approvable.
 
Top