• 🏆 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] How to Separate Timers

Status
Not open for further replies.
Level 20
Joined
Aug 13, 2013
Messages
1,696
I have a question in my vJASS spell I don't know how to separate timers for each instance so they would not be synchronized. Need some help or tutorial to fix this.. :( because I want to approved this spell...
If you want to test it here is the link http://www.hiveworkshop.com/forums/spells-569/shock-frosts-vjass-v1-0-a-239618/
Here is the code of my Spell vJASS
JASS:
scope ShockOfFrosts initializer init

/*//////////////////////Shock of Frosts [vJASS] v1.1//////////////////////|
|Created by: jakeZinc                                                   //|
|Credits to THWS                                                        //|
|Thanks to the tutorial of @deathismyfriend Indexing tutorial           //|
|Features:                                                              //|
|Simple Frost Spell                                                     //| 
|Specially MUI (Multi-Unit-Instanceable)                                //|
|Easy to Configure                                                      //|
|Documented                                                             //|
|Leakless                                                               //|
|Lagless                                                                //|
|Useful                                                                 //| 
|Timed Ability                                                          //|
*/////////////////////////////////////////////////////////////////////////|
globals
    private constant integer abilityid = 'A000'// The RawCode of the Shock of Frosts Spell or Ability.
    private constant integer dummyabilityid = 'A001' // The RawCode of the Freeze Dummy Spell or Ability.
    private constant string orderid = "entanglingroots" // Base to the order id of the Freezing Dummmy Spell.
    private constant integer dummyid = 'u000' // The RawCode of the dummy unit that will cast the Freeze Spell.
    private constant string e = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl" //The special effect of shocks.
    private constant attacktype atc = ATTACK_TYPE_CHAOS // Attack Type of the damage.
    private constant damagetype dtn = DAMAGE_TYPE_NORMAL // Damage Type of the damage.
endglobals

globals
    private real BaseDamagePerShock = 10. // The damage per shock. Configurable.
    private real DamagePerShockLvl = 5. // The damage per shock per level increasement. Configurable.
    private real BaseFinalDamage = 100. // The final damage of the massive after shock. Configurable.
    private real BaseFinalDamageLvl = 50. // The final damage of the massive after shock per level increasement. Configurable.
    private integer TintedSfx = 4 // If you increase this value it wil tinted the sfx of the massive aftershock. Configurable.
    private integer TintedSfxLvl = 2 // If you increase this value it wil tinted the sfx of the massive aftershock increase per level. Configurable.
    private real Duration = 2.25 // The duration of the shocks
    private real DurationLvl = 1. // The duration of the shocks per level increasement.
    private real seconds = .50 // The seconds that occur the shocks.
    private real secondslvl = .10 // The shock's decreasement seconds per level
    private real array time
    private unit array caster
    private unit array target
    private integer MaxIndex = 0
    private integer TempInteger = 0
    private integer lvl
endglobals

private constant function TotalFinalDamage takes integer level returns real
    return BaseFinalDamage + ( level * BaseFinalDamageLvl) // The TotalFinalDamage Formula.
endfunction

private constant function TotalDamagePerShock takes integer level returns real
    return BaseDamagePerShock + ( level  * DamagePerShockLvl) // The TotalDamagePerShock Formula.
endfunction

private constant function TotalTintedSfx takes integer level returns integer
    return TintedSfx + ( level * TintedSfxLvl) // The TotalTintedSfx Formula.
endfunction

private constant function TotalDuration takes integer level returns real
    return Duration + (level * DurationLvl)
endfunction

private constant function TotalSeconds takes integer level returns real
    return seconds - (level * secondslvl)
endfunction

//----------------The Spell Core---------------//

private function Loop takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local real x
    local real y
    local unit dummy
    local integer SfxLoop
    set TempInteger = 1
    loop
        exitwhen TempInteger > MaxIndex
        set x = GetUnitX( target[ TempInteger ] )
        set y = GetUnitY( target[ TempInteger ] )
        call DestroyEffect( AddSpecialEffect ( e, x, y) )
        call UnitDamageTarget( caster [ TempInteger ], target [ TempInteger ], TotalDamagePerShock ( lvl ), true, false, atc, dtn, null )
        set time[TempInteger] = time[TempInteger] - TotalSeconds(lvl)
        if time[TempInteger] <= 0. or IsUnitType(target[TempInteger],UNIT_TYPE_DEAD) and not IsUnitIdType(0,UNIT_TYPE_DEAD) then // I dunno if my condition is right..
            call UnitDamageTarget(caster[TempInteger],target[TempInteger],TotalFinalDamage( lvl ),true,false,atc,dtn,null)
            set SfxLoop = 0
            loop
                exitwhen SfxLoop == TotalTintedSfx( lvl )
                call DestroyEffect(AddSpecialEffect(e,x,y))
                set SfxLoop = SfxLoop + 1
            endloop
            set dummy = CreateUnit(GetOwningPlayer(caster[TempInteger]),dummyid,x,y,0.)
            call UnitAddAbility(dummy,dummyabilityid)
            call SetUnitAbilityLevel(dummy,dummyabilityid,lvl)
            call IssueTargetOrder( dummy , orderid , target[ TempInteger ] )
            call UnitApplyTimedLife(dummy,'BTLF',1.)
            // Nulling variable handlers and Recycling.
            set dummy = null
            set caster[TempInteger] = caster[MaxIndex]
            set caster[MaxIndex] = null
            set target[TempInteger] = target[MaxIndex]
            set target[MaxIndex] = null
            set time[TempInteger] = time[MaxIndex]
            set time[MaxIndex] = 0.
            set MaxIndex = MaxIndex - 1
            set t = null
        endif
    set TempInteger = TempInteger + 1
    set t = null
    endloop
    if MaxIndex == 0 then
        call PauseTimer(t)
        call DestroyTimer(t)
        set t = null
    endif
    set t = null
endfunction

private function FrostActions takes nothing returns nothing
    local timer t = CreateTimer()   
    set MaxIndex = MaxIndex + 1
    set caster[MaxIndex] = GetTriggerUnit()
    set target[MaxIndex] = GetSpellTargetUnit()
    set lvl = GetUnitAbilityLevel( caster[ TempInteger ], abilityid )
    set time[MaxIndex] = TotalDuration(lvl) // You can set this time.
    if MaxIndex == 1 then
        call TimerStart(t,TotalSeconds(lvl),true,function Loop)
    else
        set t = null
    endif
    set t = null
endfunction

private function FrostConditions takes nothing returns boolean
    return GetSpellAbilityId() == abilityid
endfunction

private function init takes nothing returns nothing
    local trigger trg = CreateTrigger()
    local integer index 
    set index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(trg,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)     
        set index = index + 1
        exitwhen index == 16
    endloop
    call TriggerAddCondition(trg,Condition(function FrostConditions))
    call TriggerAddAction(trg,function FrostActions)
    call Preload(e)
    set bj_lastCreatedUnit = CreateUnit(Player(15),dummyid,0.,0.,0.)
    call UnitAddAbility(bj_lastCreatedUnit,dummyabilityid)
    call UnitRemoveAbility(bj_lastCreatedUnit,dummyabilityid)
    call RemoveUnit(bj_lastCreatedUnit)
    set bj_lastCreatedUnit = null
    set trg = null
endfunction
endscope
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
You could use TimerTools by Vexorian.

Maker is probably referring to TimerUtils. TimerTools is by Nestharus but afaik he said it is bugged at the moment so you shouldn't use it. But still, it would be the best timer library ever.

TimerUtils

@OP: your spell is quite weird because you are using global blocks (vJASS) but with functions for code execution (JASS) and indexed array method (GUI/JASS).

You may want to consider using structs. Check out the tutorial section for some helpful guides on utilizing structs for making spells :)

edit

Maker posted xD
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Maker is probably referring to TimerUtils. TimerTools is by Nestharus but afaik he said it is bugged at the moment so you shouldn't use it. But still, it would be the best timer library ever.

TimerUtils

@OP: your spell is quite weird because you are using global blocks (vJASS) but with functions for code execution (JASS) and indexed array method (GUI/JASS).

You may want to consider using structs. Check out the tutorial section for some helpful guides on utilizing structs for making spells :)

edit

Maker posted xD

Yes, I'm practicing structs right now, but I don't understand the purpose of this structs.
 
Status
Not open for further replies.
Top