//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
Lightning | lightning | No | |
LSE_Ax | real | No | |
LSE_Ay | real | No | |
LSE_Bx | real | No | |
LSE_By | real | No | |
LSE_Counter | integer | No | |
LSE_Destructable | destructable | Yes | |
LSE_Group | group | No | |
LSE_Loc_1 | location | No | |
LSE_Loc_2 | location | No | |
LSE_MaxUnitCollision | real | No | |
LSE_Rect | rect | No | |
LSE_Trigger_GetDestructables | trigger | No | |
LSE_Trigger_GetUnits | trigger | No | |
LSE_Width | real | No | |
LSE_xMax | real | No | |
LSE_xMin | real | No | |
LSE_yMax | real | No | |
LSE_yMin | real | No | |
RandomLoc | location | No | |
Unit1 | unit | No | |
Unit2 | unit | No |
//TESH.scrollpos=32
//TESH.alwaysfold=0
// The distance function is from LineSegment - by Ammorth
function LSE_GetSegmentDistance takes real Ax, real Ay, real Bx, real By, real Cx, real Cy returns real
local real r
local real dx = Bx-Ax
local real dy = By-Ay
local real L = ((dx)*(dx) + (dy)*(dy)) // Get quasi length
if L == 0 then // seg is actually a point so lets return the distance to the point
return SquareRoot((Cx-Ax)*(Cx-Ax)+(Cy-Ay)*(Cy-Ay))
endif
set r = ((Cx-Ax)*(dx) + (Cy-Ay)*(dy))/(L) // get the ratio
if r > 1 then // closests point is past seg, so return distance to point B
return SquareRoot((Cx-Bx)*(Cx-Bx)+(Cy-By)*(Cy-By))
elseif r < 0 then // same as B, but at A instead
return SquareRoot((Cx-Ax)*(Cx-Ax)+(Cy-Ay)*(Cy-Ay))
endif // In the middle of A and B so use the ratio to find the point
set Ax = Ax+r*(dx)
set Ay = Ay+r*(dy)
return SquareRoot((Cx-Ax)*(Cx-Ax)+(Cy-Ay)*(Cy-Ay))
endfunction
// Will write the picked dstructable into the array if condition is met
function LSE_Filter takes nothing returns nothing
set bj_lastCreatedDestructable = GetEnumDestructable()
if LSE_GetSegmentDistance(udg_LSE_Ax, udg_LSE_Ay, udg_LSE_Bx, udg_LSE_By, GetWidgetX(bj_lastCreatedDestructable), GetWidgetY(bj_lastCreatedDestructable)) < udg_LSE_Width then
set udg_LSE_Counter = udg_LSE_Counter + 1
set udg_LSE_Destructable[udg_LSE_Counter] = bj_lastCreatedDestructable
endif
endfunction
// Set up rect and pick all destructables inside, run filter
function Trig_LSE_Run_Destructables_Actions takes nothing returns nothing
loop
exitwhen udg_LSE_Counter < 1
set udg_LSE_Destructable[udg_LSE_Counter] = null
set udg_LSE_Counter = udg_LSE_Counter - 1
endloop
set udg_LSE_Ax = GetLocationX(udg_LSE_Loc_1)
set udg_LSE_Bx = GetLocationX(udg_LSE_Loc_2)
set udg_LSE_Ay = GetLocationY(udg_LSE_Loc_1)
set udg_LSE_By = GetLocationY(udg_LSE_Loc_2)
if udg_LSE_Ax > udg_LSE_Bx then
set udg_LSE_xMax = udg_LSE_Ax
set udg_LSE_xMin = udg_LSE_Bx
else
set udg_LSE_xMax = udg_LSE_Bx
set udg_LSE_xMin = udg_LSE_Ax
endif
if udg_LSE_Ay > udg_LSE_By then
set udg_LSE_yMax = udg_LSE_Ay
set udg_LSE_yMin = udg_LSE_By
else
set udg_LSE_yMax = udg_LSE_By
set udg_LSE_yMin = udg_LSE_Ay
endif
call SetRect(udg_LSE_Rect, udg_LSE_xMin, udg_LSE_yMin, udg_LSE_xMax, udg_LSE_yMax)
call EnumDestructablesInRect(udg_LSE_Rect, null, function LSE_Filter)
endfunction
function InitTrig_LSE_Get_Destructables takes nothing returns nothing
set gg_trg_LSE_Get_Destructables = CreateTrigger( )
set udg_LSE_Rect = Rect(0, 0, 0, 0)
call TriggerAddAction( gg_trg_LSE_Get_Destructables, function Trig_LSE_Run_Destructables_Actions )
endfunction
//TESH.scrollpos=6
//TESH.alwaysfold=0
function LSE_GroupEnumUnitsInRangeOfSegment takes group whichgroup, real Ax, real Ay, real Bx, real By, real distance returns nothing
local real dx = Bx-Ax
local real dy = By-Ay
local real L = ((dx)*(dx) + (dy)*(dy)) // Get quasi length
local real r = SquareRoot(dx*dx+dy*dy)/2+distance + udg_LSE_MaxUnitCollision // replace 400.0 with the max collision size in your map
local unit u
local group g = CreateGroup()
call GroupClear(whichgroup)
call GroupEnumUnitsInRange(g, Ax+(dx/2), Ay+(dy/2), r, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if L == 0 and IsUnitInRangeXY(u, Ax, Ay, distance) then // seg is actually a point so lets return the point
call GroupAddUnit(whichgroup, u)
else
set r = ((GetUnitX(u)-Ax)*(dx) + (GetUnitY(u)-Ay)*(dy))/(L) // get the ratio
if r > 1 then // split if/thens so that it exists properly
if IsUnitInRangeXY(u, Bx, By, distance) then // closests point is past seg, so return end point B
call GroupAddUnit(whichgroup, u)
endif
elseif r < 0 then
if IsUnitInRangeXY(u, Ax, Ay, distance) then // same as B, but at A instead
call GroupAddUnit(whichgroup, u)
endif
elseif IsUnitInRangeXY(u, Ax+r*(dx), Ay+r*(dy), distance) then // In the middle of A and B so use the ratio to find the point
call GroupAddUnit(whichgroup, u)
endif
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
endfunction
function Trig_LSE_Run_Units_Actions takes nothing returns nothing
call LSE_GroupEnumUnitsInRangeOfSegment(udg_LSE_Group, GetLocationX(udg_LSE_Loc_1), GetLocationY(udg_LSE_Loc_1), GetLocationX(udg_LSE_Loc_2), GetLocationY(udg_LSE_Loc_2), udg_LSE_Width)
endfunction
//===========================================================================
function InitTrig_LSE_Get_Units takes nothing returns nothing
set gg_trg_LSE_Get_Units = CreateTrigger( )
call TriggerAddAction( gg_trg_LSE_Get_Units, function Trig_LSE_Run_Units_Actions )
endfunction