- Joined
- Aug 19, 2008
- Messages
- 491
Basically this lets you retrieve the source unit of a TriggerRegisterUnitInRange event.
Quite simple, yes, but personally I find it useful since Blizzard never made such a native.
This was made by me a while, but then a horrible flaw was discovered and it's now recoded by Element of Water
Not wasting much time on a fancy header with advertising, I hereby present GetSourceUnit library:
Requires TimerUtils and Table
Quite simple, yes, but personally I find it useful since Blizzard never made such a native.
This was made by me a while, but then a horrible flaw was discovered and it's now recoded by Element of Water
Not wasting much time on a fancy header with advertising, I hereby present GetSourceUnit library:
Requires TimerUtils and Table
JASS:
//===========================================================================
//==
//== GetSourceUnit()
//==
//== This library lets you store and retrive the source
//== unit of a TriggerRegisterUnitInRange() event.
//== Especially useful for Auras.
//== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//==
//== How to use
//== ¯¯¯¯¯¯¯¯¯¯
//== function TriggerRegisterUnitInRangeWithSource takes trigger whichTrigger, unit whichUnit, real range, boolexpr filter returns event
//== - Just like the normal one, but saves whichUnit
//==
//== function GetSourceUnit takes trigger whichTrigger, unit triggerUnit returns unit
//== - Returns the source unit of the event
//==
//== function ClearSource takes trigger whichTrigger returns nothing
//== - Nullifies the source (just for cleanup)
//==
//==
//== Requirements
//== ¯¯¯¯¯¯¯¯¯¯¯¯
//== - WarCraft III 1.24 by Blizzard (duh)
//== - JassHelper by Vexorian
//== - TimerUtils by Vexorian
//== - Table by Vexorian
//==
//==
//== Important Notes
//== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//== - If two units (who are registered to the same trigger) are close together
//== when a unit triggers the event, it may return the wrong source.
//==
//== - If you want the GetSourceUnit() to null the source automatically
//== set ClearSourceTime larger than 0.
//==
//==
//== Version 2.1
//== ¯¯¯¯¯¯¯¯¯¯¯
//== Coded by Elements of Water
//== Inspired by Cheezeman
//==
//===========================================================================
library InRangeWithSource initializer Init requires Table, TimerUtils
globals
private constant integer MAX_INSTANCES = 408000
private constant integer MAX_UNITS = 100
private constant real OFFSET = 20.00
public real ClearSourceTime = 2.00
private HandleTable ht
endglobals
private struct Data [MAX_INSTANCES]
unit array registered[MAX_UNITS]
real array registered_dist[MAX_UNITS]
integer index = 0
unit currentSource = null
endstruct
function TriggerRegisterUnitInRangeWithSource takes trigger whichTrigger, unit whichUnit, real range, boolexpr filter returns event
local Data d
if ht.exists(whichTrigger) then
set d = ht[whichTrigger]
else
set d = Data.create()
set ht[whichTrigger] = d
endif
if d.index < MAX_UNITS then
set d.registered[d.index] = whichUnit
set d.registered_dist[d.index] = range + OFFSET
set d.index = d.index + 1
else
debug call BJDebugMsg("InRangeWithSource: Number of units registered to trigger exceeds MAX_UNITS. Please increase MAX_UNITS or register fewer units")
return null
endif
return TriggerRegisterUnitInRange(whichTrigger, whichUnit, range, filter)
endfunction
private function ClearSourceTimed takes nothing returns nothing
local timer t = GetExpiredTimer()
local Data d = GetTimerData(t)
set d.currentSource = null
call ReleaseTimer(t)
set t = null
endfunction
function ClearSource takes trigger whichTrigger returns nothing
local Data d = ht[whichTrigger]
set d.currentSource = null
endfunction
function GetSourceUnit takes trigger whichTrigger, unit triggerUnit returns unit
local Data d
local integer i = 0
local unit u
local real udist
local real dx
local real dy
local real dist
local timer t
if ht.exists(whichTrigger) then
set d = ht[whichTrigger]
else
debug call BJDebugMsg("InRangeWithSource: Attempt to call GetSourceUnit on an unregistered trigger. Please register this trigger using TriggerRegisterUnitInRangeWithSource or do not call GetSourceUnit on this trigger.")
return null
endif
if d.currentSource != null then
return d.currentSource
endif
loop
exitwhen i >= d.index
set u = d.registered[i]
set udist = d.registered_dist[i]
set dx = GetUnitX(u) - GetUnitX(triggerUnit)
set dy = GetUnitY(u) - GetUnitY(triggerUnit)
set dist = SquareRoot(dx * dx + dy * dy)
exitwhen dist <= udist
set i = i + 1
endloop
if i >= d.index then
debug call BJDebugMsg("InRangeWithSource: An unregistered unit fired a registered trigger. Please register this unit in the proper way.")
return null
endif
set d.currentSource = u
if ClearSourceTime > 0 then
set t = NewTimer()
call SetTimerData(t, d)
call TimerStart(t, ClearSourceTime, false, function ClearSourceTimed)
endif
return u
endfunction
private function Init takes nothing returns nothing
set ht = HandleTable.create()
endfunction
endlibrary
1.0 - Initial Release
2.0 - The Elemental Era
- Complete remake of the code for optimization and being able to save more than 1 unit to a trigger.
2.1 - The Optional Release
- Added the option to remove the source unit manually or automatically
- Tweaked the Header
2.0 - The Elemental Era
- Complete remake of the code for optimization and being able to save more than 1 unit to a trigger.
2.1 - The Optional Release
- Added the option to remove the source unit manually or automatically
- Tweaked the Header
Last edited: