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

[JASS] Timers and structs, how would you do this?

Status
Not open for further replies.
Level 7
Joined
Mar 24, 2008
Messages
184
So, i've got this spell where a unit creates another unit and this unit has to do ciclic actions when a timer expires. I'm new to vJass but i've tried with a lot of ways to make it work...
I'm posting the code, the first is the spell casted by the unit (removed useless code to make reading easier), the second is the struct attached to the created unit with the code that has to be executed when the timer expires, also the code to make the timer is missing because i was trying different things but i have a global array and a function that gives me the first available timer.
I already know what's the problem: the method that has to be executed cannot be set as static as it is now, so i cannot use it neither as trigger or as function to be executed when a trigger expires.
I would like to know if there's a way to make it work without implementing some kind of system or something like that


JASS:
scope Slicendice

private function Conditions takes nothing returns boolean
    return (GetSpellAbilityId() == 'A00V')== true
endfunction

private function Actions takes nothing returns nothing
    local unit SliceAndDiceCaster = GetTriggerUnit()
    local unit SliceAndDiceTarget = GetSpellTargetUnit()
    local unit SliceAndDiceDummy1
    local effect SliceAndDiceCasterSfx1
    local location SliceAndDiceTargetLoc
    local location SliceAndDiceCasterLoc
    local location SliceAndDiceCasterRandomLoc
    local effect SliceAndDiceCasterSfx2
    local effect SliceAndDiceTargetSfx
    local effect SliceAndDiceDummy1Sfx
    local integer in = 0
    local integer tim = getfirstavailable()
    local real angle1 
    local real angle2
    local real distance = 160
    local integer maxattacks = 170
    //local real damage = I2R(GetHeroStr(SliceAndDiceCaster, true) + GetHeroAgi(SliceAndDiceCaster, true))/2
    local real damage = 1
    local loopthingie stru 
    
    call PauseUnit(SliceAndDiceCaster, true)
    call PauseUnit(SliceAndDiceTarget, true)
    call SetUnitInvulnerable(SliceAndDiceCaster, true)
    set SliceAndDiceCasterSfx1 = AddSpecialEffectTarget("Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", SliceAndDiceCaster, "chest")
    call PlaySoundOnUnitBJ(gg_snd_DefendCaster, 100, SliceAndDiceCaster)
    call TriggerSleepAction(0.20)
    set SliceAndDiceTargetLoc = GetUnitLoc(SliceAndDiceTarget)
    set SliceAndDiceCasterLoc = GetUnitLoc(SliceAndDiceCaster)
    set angle1 = AngleBetweenPoints(SliceAndDiceTargetLoc, SliceAndDiceCasterLoc)
    set angle2 = angle1+180
    call SetUnitPathing(SliceAndDiceCaster, false)
    set SliceAndDiceCasterRandomLoc = PolarProjectionBJ(SliceAndDiceTargetLoc, distance, angle2)
    set SliceAndDiceDummy1 = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'e00G', SliceAndDiceCasterRandomLoc, angle2)
    set stru = loopthingie.create(SliceAndDiceTarget, SliceAndDiceDummy1, SliceAndDiceTarget, tim)
    call SetUnitUserData(SliceAndDiceDummy1, stru)
    set SliceAndDiceDummy1Sfx = AddSpecialEffectTarget("Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", SliceAndDiceDummy1, "chest")
    //USELESSS STUFF
endfunction

//===========================================================================
public function InitTrig takes nothing returns nothing
    local trigger SlicenDice = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(SlicenDice, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(SlicenDice, Condition( function Conditions))
    call TriggerAddAction(SlicenDice, function Actions)
endfunction
endscope


JASS:
scope Shadowloop

struct loopthingie
    public unit owner
    public unit shadow
    public unit target
    public trigger loopy = CreateTrigger()
    public integer itim
    public integer in = 0
    public real angle1 
    public real angle2
    public boolean attacca = true
    
public method slicedice takes nothing returns nothing
    local unit SliceAndDiceCaster=this.shadow
    local unit SliceAndDiceTarget=this.target
    local location SliceAndDiceTargetLoc
    local location SliceAndDiceCasterLoc
    local location SliceAndDiceCasterRandomLoc
    local effect SliceAndDiceTargetSfx
    local real distance = 160
    set SliceAndDiceTargetLoc = GetUnitLoc(SliceAndDiceTarget)
    set SliceAndDiceCasterLoc = GetUnitLoc(SliceAndDiceCaster)
    if (this.in==0) then
        set this.angle1 = AngleBetweenPoints(SliceAndDiceTargetLoc, SliceAndDiceCasterLoc)
        set this.angle2 = this.angle1+180
    endif
    if (ModuloReal(this.in, 2)==0) then
        set this.angle2=this.angle2-20
        set SliceAndDiceCasterRandomLoc = PolarProjectionBJ(SliceAndDiceTargetLoc, distance, this.angle2)
    else
        set this.angle1=this.angle1-20
        set SliceAndDiceCasterRandomLoc = PolarProjectionBJ(SliceAndDiceTargetLoc, distance, this.angle1)
    endif
    call SetUnitPositionLocFacingLocBJ(SliceAndDiceCaster, SliceAndDiceCasterRandomLoc, SliceAndDiceTargetLoc)                                                
    call SetUnitAnimation(SliceAndDiceCaster, "Attack")
    set SliceAndDiceTargetSfx = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", SliceAndDiceTarget, "origin")
    call SetUnitFacing(SliceAndDiceTarget, GetUnitFacing(SliceAndDiceTarget)+45)
    call DestroyEffect(SliceAndDiceTargetSfx)
    call RemoveLocation(SliceAndDiceCasterRandomLoc)
    call RemoveLocation(SliceAndDiceCasterLoc)
    call RemoveLocation(SliceAndDiceTargetLoc)
    set SliceAndDiceCaster = null
    set SliceAndDiceTarget = null
    set SliceAndDiceTargetLoc = null
    set SliceAndDiceCasterLoc = null
    set SliceAndDiceCasterRandomLoc = null
    set SliceAndDiceTargetSfx = null
    set this.in=this.in+1
    endmethod    
    
    method onDestroy takes nothing returns nothing
        call resettimer(this.itim)
        set this.shadow=null
        set this.owner=null
        set this.target=null
    endmethod
    
    static method create takes unit towner, unit tshadow, unit ttarget, integer titim returns loopthingie
        local loopthingie l = loopthingie.allocate()
        set l.owner = towner
        set l.shadow = tshadow
        set l.target = ttarget
        set l.itim = titim
        return l
endmethod   
endstruct
 
Last edited:
Level 11
Joined
Apr 6, 2008
Messages
760
Edit:

How i would do my "spell" trigger's (my frame)

JASS:
scope Spell initializer Init

globals
    private constant integer Abil_id = 'What ever'
endglobals

private struct Data

timer Time

    static method create takes nothing returns Data
        local Data dat = Data.allocate()        
        call TimerStart(Time,.035,true,function Data.Loop)
        return dat
    endmethod

    static method Loop takes nothing returns nothing
        local Data dat = GetTimerData(GetExpiredTimer())
    endmethod
endstruct

private function takes nothing returns boolean
    local Data dat

    if GetSpellAbilityId()==Abil_id then
        set dat = Data.create()
    endif

    return false
endfunction

private function Init takes nothing returns nothing
    local trigger Trig = CreateTrigger()
    local integer Index = 0

    loop
        call TriggerRegisterAnyPlayerUnitEvent(Trig,Player(0),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set Index = Index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop

    call TriggerAddCondition(Trig,Filter(function OnCast))

    set Trig = null
endfunction

endscope

This isnt very much help, but you can add my msn and we can talk more there if u like too

[email protected]
 
Last edited:
Status
Not open for further replies.
Top