• 🏆 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!

[vJass] Gigant Critical 1.4

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
this is my frist spell in hiveworkshop...
in this spell the attacker have a persent to summon her soul by injury to the a attacked unit a bonus damage

JASS:
scope GigantCritical initializer Init
    globals
    /*  Ability Constants  *///////////////////////////////////////////////////////////////
        private constant integer     SpellId        = 'Agc0'              // It is the Spell Id to the caster
    /*  Timer, Hastable and Group Constants  *////////////////////////////////////////////
        private constant hashtable   Hash           = InitHashtable()     // this is to be operate the hash table
        private constant timer       GenTimer       = CreateTimer()       // it is a general timer created to loop the acctions
        private constant group       GenGroup       = CreateGroup()       // it is a group will be locate the dummys
    /*  Animation Constants  */////////////////////////////////////////////////////////////////
        private constant string      InitFx         = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
        private constant string      AnimationId    = "Attack 2"          // this is the animation to the dummy
        private constant real        AnimationSpd   = 5                   // The Speed Of the animation in the Dummy Unit(1 = 100%)
    /*  Time Constant  */////////////////////////////////////////////////////////////////////////////////    
        private constant real        TimeTotal      = 1                   // this is the time to be run the ability
    /*  Persent to cast Ability Constants  */////////////////////////////////////////////////////////////////        
        private constant real        InitPersent    = 5                   // Inital Persent to be the spell Run
        private constant real        PersentPerLvl  = 5                   // This Persent is multiplicated by the level of the Ability and sumate bt the PersentPerLvl
    /*  Scale Constants  */////////////////////////////////////////////////////////////////     
        private constant real        ScaleMax       = 2.5                 // Is the Max scale to the unit 
        private constant real        ScaleInt       = .01                 // The Inicial scale to the unit 
        private constant real        ScalePerTime   = .05                 // The Scale Added and Removed to the Dummy Unit
    /*  Transparency Constants  */////////////////////////////////////////////////////////////////        
        private constant real        TransparencyInt= 30                  // initial persent to the Dummy Unit
        private constant real        TransparencyMax= 80                  // Max Persent to the Dummy Unit
    /*  Damage Constants  *///////////////////////////////////////////////////////////////
        private constant damagetype  DmgTyp         = DAMAGE_TYPE_DIVINE  // the type of the damage caused to the ability
        private constant attacktype  AtkTyp         = ATTACK_TYPE_CHAOS   // the attack type of the ability damage
        private constant weapontype  WeaTyp         = WEAPON_TYPE_WHOKNOWS//the weapon utilized to the dummy in the ability
        private constant real        AoeDmg         = 200                 // The Area Of Effect to cause damage to any unit
        private constant real        DamagePerLvl   = 50                  // this is the damage per level to the buff(total of his is sumate by DAmageInt)
        private constant real        DamageInit     = 100                 // this is the initial damage to the Buff
    endglobals
///a system created by Zendo.ExE////////AutoSet Dummys////////////    
    globals
        constant hashtable AutoSetDummys__Hash = InitHashtable()
    endglobals
    function AutoSetDummys__SaveDummy takes integer Unitid, integer DummyId returns nothing
        call SaveInteger(AutoSetDummys__Hash, 0, Unitid, DummyId)
    endfunction
    
    function AutoSetDummys__LoadDummy takes integer Unitid returns integer
        return LoadInteger(AutoSetDummys__Hash, 0, Unitid)
    endfunction
// you need set all heroes will have this ability and her dummyes to work correctly
    function AutoSetDummys__SetUpDummy takes nothing returns nothing
        call AutoSetDummys__SaveDummy('H000', 'hdum')
        call AutoSetDummys__SaveDummy('H001', 'hdu2')
    endfunction
/////////////////////////////////////////////////////////////////
    private function TriggerCount takes nothing returns integer
        local integer Index = 0
        local real Scale = ScaleInt
        loop
            exitwhen Scale >= ScaleMax
            set Scale = Scale + ScalePerTime
            set Index = Index + 1
        endloop
        return Index * 2
    endfunction
    
    private function TimeOut takes nothing returns real
        return TimeTotal / TriggerCount()
    endfunction
    
    private function PersentPT takes nothing returns real
        return (TransparencyMax - TransparencyInt) / (TriggerCount() / 2)
    endfunction
    
    private function DamagePerTime takes real Lvl returns real
        return (DamageInit + (DamagePerLvl*Lvl)) / TriggerCount()
    endfunction
    
    private function Persent takes unit u, integer abil returns real
        return InitPersent + (GetUnitAbilityLevel(u, abil) * PersentPerLvl)
    endfunction

    private function Loop_Actions takes nothing returns nothing
        local unit      temp
        local unit      Hnd     = GetEnumUnit()
        local unit      Trg     = LoadUnitHandle (Hash, GetHandleId(Hnd), 1)
        local real      Tns     = LoadReal       (Hash, GetHandleId(Hnd), 2)
        local real      Scl     = LoadReal       (Hash, GetHandleId(Hnd), 3)
        local boolean   Bol     = LoadBoolean    (Hash, GetHandleId(Hnd), 4)
        local real      Lvl     = LoadReal       (Hash, GetHandleId(Hnd), 5)
        local group     Temp_G  = CreateGroup()
        local real      Trg_X   = GetUnitX(Trg)
        local real      Trg_Y   = GetUnitY(Trg)
        local real      Dgr     = GetUnitFacing(Trg)
        
        call SetUnitX(Hnd, Trg_X)
        call SetUnitY(Hnd, Trg_Y)
        call SetUnitFacing(Hnd, Dgr)
        
        call GroupEnumUnitsInRange(Temp_G, Trg_X, Trg_Y, AoeDmg, null)
        loop
            set temp = FirstOfGroup(Temp_G)
            exitwhen temp == null
            if  (IsUnitEnemy(temp, GetOwningPlayer(Trg)))/*
         */ and (GetUnitState(temp, UNIT_STATE_LIFE) > 0)/*
         */ then
                call UnitDamageTarget(Trg, temp, DamagePerTime(Lvl), true, false, AtkTyp, DmgTyp, WeaTyp)
            endif
            call GroupRemoveUnit(Temp_G, temp)
        endloop
        call DestroyGroup(Temp_G)
        
        if Scl < ScaleMax and Bol == true then
            call SaveReal(Hash, GetHandleId(Hnd), 2, Tns + PersentPT())
            call SaveReal(Hash, GetHandleId(Hnd), 3, Scl + ScalePerTime)
            call SetUnitVertexColor(Hnd, 255, 255, 255, R2I((100-Tns)*2.55))
            call SetUnitScale( Hnd, Scl, Scl, Scl )
        elseif Bol == true then
            call SaveBoolean(Hash, GetHandleId(Hnd), 4, false)
        elseif Scl > 1. and Bol == false then
            call SaveReal(Hash, GetHandleId(Hnd), 2, Tns - PersentPT())
            call SaveReal(Hash, GetHandleId(Hnd), 3, Scl - ScalePerTime)
            call SetUnitVertexColor(Hnd, 255, 255, 255, R2I((100-Tns)*2.55))
            call SetUnitScale( Hnd, Scl, Scl, Scl)
        else
            call FlushChildHashtable(Hash, GetHandleId(Hnd))
            call RemoveUnit(Hnd)
            call GroupRemoveUnit(GenGroup, Hnd)
        endif
        
        set Hnd         = null
        set Trg         = null
        set Temp_G      = null
        set temp        = null
    endfunction

    private function Actions takes nothing returns nothing
        local unit      Trg          = GetAttacker()
        local unit      Dum          = null
        local player    Pla          = GetOwningPlayer(Trg)
        local real      Drg          = GetUnitFacing(Trg)
        local real      Trg_Y        = GetUnitY(Trg)
        local real      Trg_X        = GetUnitX(Trg)
        local real      Index        = GetRandomInt(1, 100)
        local real      Lvl          = GetUnitAbilityLevel(Trg, SpellId)
        
        if Index <= Persent(Trg, SpellId) /*
    */  and GetUnitAbilityLevel(Trg, SpellId) > 0 then
        
            call DestroyEffect(AddSpecialEffect(InitFx, Trg_X, Trg_Y))
        
            set Dum = CreateUnit(GetOwningPlayer(Trg), AutoSetDummys__LoadDummy(GetUnitTypeId(Trg)), Trg_X, Trg_Y, Drg)
            call SetUnitColor(Dum, GetPlayerColor(Pla))
            call SetUnitVertexColor(Dum, 255, 255, 255, R2I((100-TransparencyInt)*2.55))

            call SetUnitTimeScale(Dum, AnimationSpd)
            call SetUnitScale(Dum, ScaleInt, ScaleInt, ScaleInt)
            call SetUnitAnimation(Dum, AnimationId)
            set Index = 1
            loop 
                exitwhen Index > 100
                call QueueUnitAnimation(Dum, AnimationId)
                set Index = Index + 1
            endloop
            
            call SaveUnitHandle(Hash, GetHandleId(Dum), 1, Trg)
            call SaveReal      (Hash, GetHandleId(Dum), 2, TransparencyInt)
            call SaveReal      (Hash, GetHandleId(Dum), 3, ScaleInt)
            call SaveBoolean   (Hash, GetHandleId(Dum), 4, true)
            call SaveReal      (Hash, GetHandleId(Dum), 5, Lvl)
            
            call GroupAddUnit(GenGroup, Dum)
        endif
        set Trg         = null
        set Dum         = null
        set Pla         = null
    endfunction

    //===========================================================================
    
    private function Group_Loop_Calls takes nothing returns nothing
        local unit u = FirstOfGroup(GenGroup)
        if u != null then
            call ForGroup(GenGroup, function Loop_Actions)
        endif
    endfunction
    
    private function Init takes nothing returns nothing
        local integer index = 0
        local trigger t = CreateTrigger()
        loop
            call TriggerRegisterPlayerUnitEvent(t, Player(index), EVENT_PLAYER_UNIT_ATTACKED, null)
            set index = index + 1
            exitwhen index == bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerAddAction(t, function Actions)
        call TimerStart(GenTimer, TimeOut(), true, function Group_Loop_Calls)
        call AutoSetDummys__SetUpDummy()
        set t = null
    endfunction
endscope


Keywords:
Vjass, Melle, gigant, Critical, Warcraft III, Warrior, Spell, Fight
Contents

Otro mapa de Warcraft III (Map)

Reviews
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected. 16 Nov 2011 Bribe: WEAPON_TYPE_WHOKNOWS -> null. You only need one hashtable, not 2. TriggerCount still should not be search-based. You are still creating groups locally which you...

Moderator

M

Moderator

12th Dec 2015
IcemanBo: Too long as NeedsFix. Rejected.


16 Nov 2011
Bribe: WEAPON_TYPE_WHOKNOWS -> null.

You only need one hashtable, not 2.

TriggerCount still should not be search-based.

You are still creating groups locally which you only use once.

You are still not using FirstOfGroup loop.

The EVENT_PLAYER_UNIT_ATTACKED event is abusable. You need to have this run from a Damage Detection System.

What is with all the "QueueUnitAnimation" spam?

You still have TriggerRegisterAnyUnitEventBJ inlined which adds unnecessary bloat to the code size. There is no reason for you to have inlined it, and if you care about efficiency, like I said, use SpellEffectEvent.
 
• Use "keyword", instead of StringHash, or integers to save/load values.
• Translate the comments in English.
• Use a damage detection system instead of on attack event (which can be abused with the "Stop" command).
• Use coordinates instead of locations, e.g. the function SetUnitPositionLoc() can be replaced with SetUnitPosition().
• You don't need to reset local reals/integers, only handles.
• Functions that take arguments do not need locals to declare the arguments all over again, e.g.:
JASS:
        local integer Abil = abil
just use the "abil" argument directly in the function.
• The "Persent" function is needed (it should be "Percent", by the way), just make the calculations needed within the main function.
• Index variable in the TriggerCount function could be Integer, there's no reason to make it real, when you increase it by 1 and then convert it to integer with R2I.
• Become familiar with timers, instead of creating timed triggers. T32 or TimerUtils would be the way to go.
 
CTL would be good too.

JASS:
        set Trg         = null
        set Attacked    = null
        set Dum         = null
        set Drg         = 0
        set Bol         = false
        set Tns         = 0
        set Trg_Loc     = null
        set Pla         = null
        set Trig        = null
        set Hnd         = null
        set Scl         = 0
        set Index       = 0
        set Lvl         = 0
        set IfUnitHaveGC=false

>_>

Here:

JASS:
        set Trg         = null
        set Attacked    = null
        set Dum         = null
        set Trg_Loc     = null
        set Pla         = null
        set Trig        = null
        set Hnd         = null
 
Top