JASS:
library RetsuDashLib requires TimerUtils, SpellEffectEvent, PauseUnitEx, RegisterPlayerUnitEvent
scope RetsuDashScope
struct RetsuDash
static timer periodic = null
static timer timeOut = null
static unit u = null
static real duration = 0.
static boolean ready2dash = false
static trigger RetsuDashLearn = CreateTrigger()
static method RetsuDashTimeOut takes nothing returns nothing // Reset the ability and unit if in stance for 2 seconds
if ready2dash == true then
call PauseUnitEx(u, false)
call BJDebugMsg("Timeout")
set ready2dash = false
endif
call ReleaseTimer(timeOut)
set timeOut = null
endmethod
static method RetsuDaskClick takes nothing returns nothing // If in stance, next right click will dash the unit
if ready2dash == true and BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
call PauseUnitEx(u, false)
set ready2dash = false
call BJDebugMsg("Dashed")
endif
endmethod
static method actRetsuDashLearn takes nothing returns nothing // Create one event for right mouse up for the unit owner when they learn the ability
local trigger t = CreateTrigger()
if GetLearnedSkill() == 'A003' then
call TriggerRegisterPlayerEvent(t, GetOwningPlayer(GetLearningUnit()), EVENT_PLAYER_MOUSE_UP)
call TriggerAddAction(t, function thistype.RetsuDaskClick)
call DestroyTrigger(RetsuDashLearn)
endif
endmethod
static method GetOppositeFacing takes unit Caster returns real // Get the opposite facing angle of the unit
local real facing = GetUnitFacing(Caster)
local real oppositeFacing = facing + 180
if oppositeFacing >= 360 then
set oppositeFacing = oppositeFacing - 360
endif
return oppositeFacing
endmethod
static method StartTimeOut takes nothing returns nothing // Starts the timeout timer, I had this in other places, but no matter where I place this, the bug remains
set timeOut = CreateTimer() // The bug is "onPeriod" running twice and TimeOut functions for some reason not properly updating variable.
call TimerStart(timeOut, 2, false, function thistype.RetsuDashTimeOut)
endmethod
static method onPeriod takes nothing returns nothing // Pushes the unit backwards for 0.2s, and setting dash variable to true (dash ready)
local real oppositeAngle = GetOppositeFacing(u)
local real x_fadeaway = NewX(GetUnitX(u), 20, oppositeAngle)
local real y_fadeaway = NewY(GetUnitY(u), 20, oppositeAngle)
if duration > 0.2 then
set duration = 0
set ready2dash = true
call ReleaseTimer(periodic)
set periodic = null
else
call SetUnitX(u, x_fadeaway)
call SetUnitY(u, y_fadeaway)
set duration = duration + 0.03
endif
endmethod
static method onCast takes nothing returns nothing // When ability is cast
set periodic = CreateTimer()
set u = GetTriggerUnit()
call SetUnitAnimationByIndex(u, 4)
call SetUnitTimeScalePercent(u, 150)
call PauseUnitEx(u, true)
call TimerStart(periodic, 0.03, true, function thistype.onPeriod)
call thistype.StartTimeOut() // Culprit, this line causes onPeriod to run twice
endmethod
static method onInit takes nothing returns nothing // Init
call RegisterSpellEffectEvent('A003', function thistype.onCast)
call TriggerRegisterAnyUnitEventBJ(RetsuDashLearn, EVENT_PLAYER_HERO_SKILL)
call TriggerAddAction(RetsuDashLearn, function thistype.actRetsuDashLearn)
endmethod
endstruct
endscope
endlibrary
Read the code from bottom to up
The issue comes from "call thistype.StartTimeOut()". What happens with this line being in the code is, after its timer (timeOut) runs the function "onPeriod" for some reason runs again (meaning the unit position gets changed again, its what onPeriod does). If I comment out "call thistype.StartTimeOut()", everything works properly (effectively meaning I don't use "StartTimeOut()" function). By working, the unit fades backwards (onPeriod runs once, not twice), and next time they right click "Dashed" runs.
However, I want "call thistype.StartTimeOut()" in the code so that in the event the player does nothing after this timer runs out (meaning bool ready2dash == true after 2 seconds), it'll reset the boolean to false and unpause the unit "effectively resetting the ability/unit". The ability works so when they cast it, they get pushed backwards and enters a stance, afterwards the next time they right click they will trigger the dash function, but they can only hold it for ~2 seconds (due to timeOut timer, which is currently bugging for me). Can you see why I encounter this bug?
I noticed that even if RetsuDashTimeOut() runs and executes its code, I can still right click to dash, meaning the boolean variable "ready2dash" is not even properly updated in the RetsuDashTimeOut(). However, it is updated in RetsuDaskClick() (meaning when you right click in the stance setting its bool value to false. But without the timer timeOut the stance is up permanently).
Eg. Printing "Timeout" first, I can still print out "Dashed" (improper). Afterwards, to do another print I have to use the ability again. Printing "Dashed" first can not print "Timeout" (proper). Printing "Timeout" first, should make printing "Dashed" impossible due to "TimeOut" setting bool to false (does not work).
TLDR:
OnPeriod runs twice when it should run once with "call thistype.StartTimeOut()" in the code (without this code, it runs once and everything works properly). Variable ready2dash not properly updating in RetsuDashTimeOut().
Last edited: