- Joined
- Jul 3, 2010
- Messages
- 536
READ FIRST:
PROBLEM:
I have created two functions:
By the way, no other triggers in my map ever move a unit, currently.
BACKGROUND:
I am fairly certain that the problem is not with these background functions. I am posting them so you can be sure they work and on the off chance the problem is with these functions.
globals:
Basically, all they do is recycle global declared timers so reals and the sort can be attached to them. This is so they can be used in a timer's callback function.
CODE
- These triggers use vanilla JASS. If that is unacceptable for you, please do not bother to post. I have my reasons for not wanting to switch to any other version of JASS and I will simply ignore any post along the lines of "You should switch to [whatever your favourite version of JASS is]".
- This problem requires a general understanding of Parallel Arrays and Recycled Timers.
- I will not use Hashtables.
PROBLEM:
I have created two functions:
- (1) moves a projectly unit at a constant real speed towards a fixed real angle a constant maximum distance.
- (2) moves a projectly unit at a constant real speed towards a target unit.
By the way, no other triggers in my map ever move a unit, currently.
BACKGROUND:
I am fairly certain that the problem is not with these background functions. I am posting them so you can be sure they work and on the off chance the problem is with these functions.
globals:
- boolean udg_SysTim_Boo[], arrayed with size 100.
- timer udg_SysTim_Timer[], arrayed with size 100.
JASS:
// (1)
function RecycleTimers_GetNewIndex takes nothing returns integer
local integer Index = 0
local integer ReturnIndex = 0
loop
set Index = Index + 1
if udg_SysTim_Boo[Index] == FALSE then
set ReturnIndex = Index
set udg_SysTim_Boo[Index] = TRUE
endif
exitwhen ReturnIndex != 0
endloop
return ReturnIndex
endfunction
// (2)
function RecycleTimers_GetCurrentIndex takes timer WhichTimer returns integer
local integer Index = 0
local integer ReturnIndex = 0
loop
set Index = Index + 1
if udg_SysTim_Timer[Index] == WhichTimer then
set ReturnIndex = Index
endif
exitwhen ReturnIndex != 0
endloop
return ReturnIndex
endfunction
// (3)
function RecycleTimers_RecycleIndex takes integer WhichIndex returns nothing
set udg_SysTim_Boo[WhichIndex] = FALSE
endfunction
// (4)
function IsUnitAlive takes unit WhichUnit returns boolean
return not IsUnitType(WhichUnit, UNIT_TYPE_DEAD) and (GetUnitTypeId(WhichUnit) != 0)
endfunction
CODE
- I swapped the order of the call trigger and the callback for clarity. This is of course done properly in WE.
- The real 0.04 is otherwise a decleared global that point to the real 0.04. I substituted it for clarity.
- You will probably notice that from right after the local declarations of (2) it is basically analogous to (1). It still doesn't work.
JASS:
function Projectly_LineMove takes real Distance, real Speed, real Angle, unit Projectly returns nothing
local integer Index = RecycleTimers_GetNewIndex()
set udg_SysTim_Save_Real_01[Index] = Distance
set udg_SysTim_Save_Real_02[Index] = Speed
set udg_SysTim_Save_Real_03[Index] = Angle
set udg_SysTim_Save_Unit_01[Index] = Projectly
set Projectly = null
call TimerStart(udg_SysTim_Timer[Index], 0.04, false, function Projectly_LineMove_Callback)
endfunction
function Projectly_LineMove_Callback takes nothing returns nothing
// LOCALS
local integer Index = RecycleTimers_GetCurrentIndex(GetExpiredTimer())
local real Distance = udg_SysTim_Save_Real_01[Index]
local real Speed = udg_SysTim_Save_Real_02[Index]
local real Angle = udg_SysTim_Save_Real_03[Index]
local unit Projectly = udg_SysTim_Save_Unit_01[Index]
local location TempPoint = GetUnitLoc(Projectly)
// MAIN
if Distance >= 0.04 * Speed then
call SetUnitX(Projectly, (GetLocationX(TempPoint) + Cos(Angle) * 0.04 * Speed))
call SetUnitY(Projectly, (GetLocationY(TempPoint) + Sin(Angle) * 0.04 * Speed))
set Distance = Distance - (0.04 * Speed)
else
call SetUnitX(Projectly, (GetLocationX(TempPoint) + Cos(Angle) * Distance))
call SetUnitY(Projectly, (GetLocationY(TempPoint) + Sin(Angle) * Distance))
set Distance = 0
endif
if Distance != 0 and IsUnitAlive(Projectly) == TRUE then
set udg_SysTim_Save_Real_01[Index] = Distance
call TimerStart(udg_SysTim_Timer[Index], 0.04, false, function Projectly_LineMove_Callback)
else
// END OF DISTANCE NULL
set udg_SysTim_Save_Real_01[Index] = 0.00
set udg_SysTim_Save_Real_02[Index] = 0.00
set udg_SysTim_Save_Real_03[Index] = 0.00
set udg_SysTim_Save_Unit_01[Index] = null
call RecycleTimers_RecycleIndex(Index)
if IsUnitAlive(Projectly) == FALSE then
call KillUnit(Projectly)
endif
endif
// NULL
set Projectly = null
call RemoveLocation(TempPoint)
endfunction
JASS:
function Projectly_ToUnitMove takes real Speed, unit Projectly, unit Target returns nothing
local integer Index = RecycleTimers_GetNewIndex()
set udg_SysTim_Save_Real_01[Index] = Speed
set udg_SysTim_Save_Unit_01[Index] = Projectly
set udg_SysTim_Save_Unit_02[Index] = Target
set Projectly = null
set Target = null
call TimerStart(udg_SysTim_Timer[Index], 0.04, false, function Projectly_ToUnitMove_Callback)
endfunction
function Projectly_ToUnitMove_Callback takes nothing returns nothing
// LOCALS
local integer Index = RecycleTimers_GetCurrentIndex(GetExpiredTimer())
local real Speed = udg_SysTim_Save_Real_01[Index]
local unit Projectly = udg_SysTim_Save_Unit_01[Index]
local unit Target = udg_SysTim_Save_Unit_02[Index]
local location TempPoint_Proc = GetUnitLoc(Projectly)
local location TempPoint_Targ = GetUnitLoc(Target)
local real Angle = AngleBetweenPoints(TempPoint_Proc, TempPoint_Targ)
local real Distance = DistanceBetweenPoints(TempPoint_Proc, TempPoint_Targ)
// MAIN
if Distance >= 0.04 * Speed then
call SetUnitX(Projectly, (GetLocationX(TempPoint_Proc) + Cos(Angle) * 0.04 * Speed))
call SetUnitY(Projectly, (GetLocationY(TempPoint_Proc) + Sin(Angle) * 0.04 * Speed))
else
call SetUnitX(Projectly, (GetLocationX(TempPoint_Proc) + Cos(Angle) * Distance))
call SetUnitY(Projectly, (GetLocationY(TempPoint_Proc) + Sin(Angle) * Distance))
endif
if IsUnitAlive(Projectly) == TRUE then
call TimerStart(udg_SysTim_Timer[Index], 0.04, false, function Projectly_ToUnitMove_Callback)
else
set udg_SysTim_Save_Real_01[Index] = 0.00
set udg_SysTim_Save_Unit_01[Index] = null
set udg_SysTim_Save_Unit_02[Index] = null
endif
// NULL
set Projectly = null
set Target = null
call RemoveLocation(TempPoint_Proc)
call RemoveLocation(TempPoint_Targ)
endfunction