CircleSector 120 degrees

This bundle is marked as pending. It has not been reviewed by a staff member yet.
Collection of 120 degrees (out from center, 240 degrees total), with 54 units inner radius (looks good on heroes imo).
Just place the effect on location of unit, setting the yaw to the facing of the unit (note that yaw uses radians, facing is degrees).
Getting units in the circle section (also known as "cone" in many games) is a bit more complex, depending on how detailed you want to go.

Naming is:
  • 54i = 54 units inner radius
  • 120 = 120 degrees out from center line (240 degrees total)
  • last 3 digits are outer radius
For 60 degrees, see: CircleSector 60 degrees

One method is just get units in range, then check if the degrees between the hit unit and casting unit is less than the degrees. There are many threads on how to do this on this website.
This has several disadvantages, so here is what I do:
set udg_MyGroup = GetUnitsInCircleSegmentInFrontOfUnit(udg_MyUnit1, 250.0, 60.0 * bj_DEGTORAD, 0.33) sets MyGroup (GUI unit-group-variable) to units infront of MyUnit1 (GUI unit variable) within 250 units, +/- 60 degrees (for 120 degrees total), where 33% of a units collision radius must be within the area.
Set last parameter to 1.0 to require 100% of unit collision radius to be within the area and 0.0 to require that the outline of the collision size to touch the area.

Afterwards you'd need to filter out relevant units (enemies of the "main unit" for example). This is will include the "casting units" too.

JASS:
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

Edit 2024-12-31: Updated provided code. Note that it uses the native UnitAlive that might already exist, if so, just remove it (first line).
Previews
Contents

CircleSector_54i_120deg_100 (Model)

CircleSector_54i_120deg_125 (Model)

CircleSector_54i_120deg_150 (Model)

CircleSector_54i_120deg_175 (Model)

CircleSector_54i_120deg_200 (Model)

CircleSector_54i_120deg_225 (Model)

CircleSector_54i_120deg_250 (Model)

CircleSector_54i_120deg_275 (Model)

CircleSector_54i_120deg_300 (Model)

CircleSector_54i_120deg_350 (Model)

CircleSector_54i_120deg_400 (Model)

CircleSector_54i_120deg_450 (Model)

CircleSector_54i_120deg_500 (Model)

CircleSector_54i_120deg_600 (Model)

Level 9
Joined
Jan 8, 2015
Messages
125
Probably could be good for the modern infantry units.

I could also see some enthusiast make a small scale tactical map like with SWAT units with this.
 
Top