constant native UnitAlive takes unit whichUnit returns boolean
function Dot takes real x1, real y1, real x2, real y2 returns real
return x1 * x2 + y1 * y2
endfunction
//Normal x,y defines the plane, together with plane_distance (how much offset it is)
//ux, uy is the coord currently being analysed. Margin is if the coord should be treated as infront with this extra margin (E.G. CollisionSize)
function IsCoordInFrontOfPlane takes real normx, real normy, real px, real py, real ux, real uy, real margin returns boolean
local real newx = ux - px
local real newy = uy - py
local real result = (Dot(newx, newy, normx, normy) + margin)
//call BJDebugMsg("Norm: " + R2S(normx) + ", " + R2S(normy) + " - pos: " + R2S(ux) + ", " + R2S(uy) + ". result=" + R2S(result))
return result > 0
endfunction
function GetUnitsInCircleSegment takes real x, real y, real centerDirection, real radius, real segmentRadians, real collisionRadiusPercent returns group
local group g = CreateGroup()
local group result = CreateGroup()
local unit u
local real tx = x + radius * Cos(centerDirection + segmentRadians)
local real ty = y + radius * Sin(centerDirection + segmentRadians)
local real diffX = x - tx
local real diffY = y - ty
local real diffLength = SquareRoot(diffX * diffX + diffY * diffY)
local real normLeftX = -diffY / diffLength //Swap of X, Y is intentional!
local real normLeftY = diffX / diffLength //Swap of X, Y is intentional!
local real normRightX
local real normRightY
local real unitCollitionRadius
local real radiusToRemove
set tx = x + radius * Cos(centerDirection - segmentRadians)
set ty = y + radius * Sin(centerDirection - segmentRadians)
set diffX = tx - x
set diffY = ty - y
set diffLength = SquareRoot(diffX * diffX + diffY * diffY)
set normRightX = -diffY / diffLength //Swap of X, Y is intentional!
set normRightY = diffX / diffLength //Swap of X, Y is intentional!
//set bx1 = (x + tx) / 2.0 + normRightX * 40
//set by1 = (y + ty) / 2.0 + normRightY * 40
call GroupEnumUnitsInRange(g, x, y, radius + 100.0, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
set tx = GetUnitX(u)
set ty = GetUnitY(u)
set unitCollitionRadius = BlzGetUnitCollisionSize(u)
set radiusToRemove = unitCollitionRadius * (1.0 - collisionRadiusPercent)
//set angleFromStartToUnit = RAbsBJ(Atan2(GetUnitY(u) - y, GetUnitX(u) - x))
//call SetUnitVertexColor(u, 255, 255, 255, 255)
//set r = 255
//set gr = 255
//set b = 255
if UnitAlive(u) and IsUnitInRangeXY(u, x, y, radius - unitCollitionRadius * collisionRadiusPercent) then
//set r = 64
//set gr = 64
//set b = 64
//call BJDebugMsg("Is in range: " + GetUnitName(u))
//if IsCoordInFrontOfPlane(normLeftX, normLeftY, x, y, tx, ty, BlzGetUnitCollisionSize(u)) then
// call BJDebugMsg("In front of left: " + GetUnitName(u))
// set b = 255
//endif
//if IsCoordInFrontOfPlane(normRightX, normRightY, x, y, tx, ty, BlzGetUnitCollisionSize(u)) then
// call BJDebugMsg("In front of Right: " + GetUnitName(u))
// set r = 255
//endif
if IsCoordInFrontOfPlane(normLeftX, normLeftY, x, y, tx, ty, unitCollitionRadius - radiusToRemove) and IsCoordInFrontOfPlane(normRightX, normRightY, x, y, tx, ty, unitCollitionRadius - radiusToRemove) then
//call BJDebugMsg("HIT: " + GetUnitName(u))
call GroupAddUnit(result, u)
endif
//call BJDebugMsg(" ")
endif
//call SetUnitVertexColor(u, r, gr, b, 255)
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
return result
endfunction
function GetUnitsInCircleSegmentInFrontOfUnit takes unit caster, real radius, real segmentRadians, real collisionRadiusPercent returns group
return GetUnitsInCircleSegment(GetUnitX(caster), GetUnitY(caster), bj_DEGTORAD * GetUnitFacing(caster), radius, segmentRadians, collisionRadiusPercent)
endfunction