//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
EyBe_Config_Ability | abilcode | Yes | |
EyBe_Config_Ability_Order_ID | string | No | |
EyBe_Config_D_Type | unitcode | No | |
EyBe_Config_Damage | real | Yes | |
EyBe_Config_Damage_Bonus | real | Yes | |
EyBe_Config_Duration | real | Yes | |
EyBe_Config_Duration_Slow | real | Yes | |
EyBe_Config_Effect_Path | string | Yes | |
EyBe_Config_End_P_Offset | real | No | |
EyBe_Config_Height | real | Yes | |
EyBe_Config_Lightning_Type | lightningtype | No | |
EyBe_Config_Margin | real | No | |
EyBe_Config_Periodic | real | No | |
EyBe_Config_Range | real | No | |
EyBe_Config_Slow | real | Yes | |
EyBe_Config_Speed | real | Yes | |
EyBe_Config_Tick | real | No | |
EyBe_Config_Width | real | Yes | |
EyBe_Damage | real | Yes | |
EyBe_Duration | real | Yes | |
EyBe_Duration_Slow | real | Yes | |
EyBe_Index | integer | No | |
EyBe_Lightning | lightning | Yes | |
EyBe_Loop | integer | No | |
EyBe_LvL | integer | No | |
EyBe_MouseX | real | No | |
EyBe_MouseX_Prev | real | Yes | |
EyBe_MouseY | real | No | |
EyBe_MouseY_Prev | real | Yes | |
EyBe_Owner | player | Yes | |
EyBe_Point | location | Yes | |
EyBe_Point_Node | effect | Yes | |
EyBe_Point_Z_Height | real | Yes | |
EyBe_Real | real | Yes | |
EyBe_Slow | real | Yes | |
EyBe_Spef | effect | No | |
EyBe_Tar_Angle | real | No | |
EyBe_Tick | real | Yes | |
EyBe_Unit | unit | Yes | |
EyBe_Unit_Caster | unit | Yes | |
EyBe_Unit_Dummy | unit | No | |
EyBe_UnitC_Angle | real | Yes | |
EyBe_Width | real | Yes | |
EyBe_XYZ | real | Yes | |
EyBe_XYZ2 | real | Yes | |
Lightning | lightning | Yes | |
LSE_Destructable | destructable | Yes | |
LSE_DestructableCounter | integer | No | |
LSE_GetDestructables | trigger | No | |
LSE_GetItems | trigger | No | |
LSE_GetUnits | trigger | No | |
LSE_Group | group | No | |
LSE_Item | item | Yes | |
LSE_ItemCounter | integer | No | |
LSE_Loc_1 | location | No | |
LSE_Loc_2 | location | No | |
LSE_Offset | real | No | |
LSE_Rect | rect | No | |
Unit1 | unit | No | |
Unit2 | unit | No | |
ZZZ_Loop | integer | No | |
ZZZ_NtRq_Spite | boolean | No | |
ZZZ_NtRq_Split | boolean | No | |
ZZZ_NtRq_Unit | unit | Yes | |
ZZZ_NtRq_Zombie | boolean | No | |
ZZZ_Point | location | Yes |
library MouseUtils
/*
-------------------
MouseUtils
- MyPad
1.0.2.2
-------------------
----------------------------------------------------------------------------
A simple snippet that allows one to
conveniently use the mouse natives
as they were meant to be...
-------------------
| API |
-------------------
struct UserMouse extends array
static method operator [] (player p) -> thistype
- Returns the player's id + 1
static method getCurEventType() -> integer
- Returns the custom event that got executed.
method operator player -> player
- Returns Player(this - 1)
readonly real mouseX
readonly real mouseY
- Returns the current mouse coordinates.
readonly method operator isMouseClicked -> boolean
- Determines whether any mouse key has been clicked,
and will return true on the first mouse key.
method isMouseButtonClicked(mousebuttontype mouseButton)
- Returns true if the mouse button hasn't been
released yet.
method setMousePos(real x, y) (introduced in 1.0.2.2)
- Sets the mouse position for a given player.
static method registerCode(code c, integer ev) -> triggercondition
- Lets code run upon the execution of a certain event.
- Returns a triggercondition that can be removed later.
static method unregisterCallback(triggercondition trgHndl, integer ev)
- Removes a generated triggercondition from the trigger.
functions:
GetPlayerMouseX(player p) -> real
GetPlayerMouseY(player p) -> real
- Returns the coordinates of the mouse of the player.
OnMouseEvent(code func, integer eventId) -> triggercondition
- See UserMouse.registerCode
GetMouseEventType() -> integer
- See UserMouse.getCurEventType
UnregisterMouseCallback(triggercondition t, integer eventId)
- See UserMouse.unregisterCallback
SetUserMousePos(player p, real x, real y)
- See UserMouse.setMousePos
Unique Global Constants:
IMPL_LOCK (Introduced in v.1.0.2.2)
- Enables or disables the lock option
-------------------
| Credits |
-------------------
- Pyrogasm for pointing out a comparison logic flaw
in operator isMouseClicked.
- Illidan(Evil)X for the useful enum handles that
grant more functionality to this snippet.
- TriggerHappy for the suggestion to include
associated events and callbacks to this snippet.
- Quilnez for pointing out a bug related to the
method isMouseButtonClicked not working as intended
in certain situations.
----------------------------------------------------------------------------
*/
// Arbitrary constants
globals
constant integer EVENT_MOUSE_UP = 1024
constant integer EVENT_MOUSE_DOWN = 2048
constant integer EVENT_MOUSE_MOVE = 3072
private constant boolean IMPL_LOCK = false
endglobals
private module Init
private static method onInit takes nothing returns nothing
call thistype.init()
endmethod
endmodule
struct UserMouse extends array
static if IMPL_LOCK then
// Determines the minimum interval that a mouse move event detector
// will be deactivated. (Globally-based)
// You can configure it to any amount you like.
private static constant real INTERVAL = 0.031250000
// Determines how many times a mouse move event detector can fire
// before being deactivated. (locally-based)
// You can configure this to any integer value. (Preferably positive)
private static constant integer MOUSE_COUNT_MAX = 16
// Determines the amount to be deducted from mouseEventCount
// per INTERVAL. Runs independently of resetTimer
private static constant integer MOUSE_COUNT_LOSS = 8
private static constant boolean IS_INSTANT = INTERVAL <= 0.
endif
private static integer currentEventType = 0
private static integer updateCount = 0
private static trigger stateDetector = null
static if IMPL_LOCK and not IS_INSTANT then
private static timer resetTimer = null
endif
private static trigger array evTrigger
private static integer array mouseButtonStack
static if IMPL_LOCK and not IS_INSTANT then
private integer mouseEventCount
private timer mouseEventReductor
endif
private thistype next
private thistype prev
private thistype resetNext
private thistype resetPrev
private trigger posDetector
private integer mouseClickCount
readonly real mouseX
readonly real mouseY
// Converts the enum type mousebuttontype into an integer
private static method toIndex takes mousebuttontype mouseButton returns integer
return GetHandleId(mouseButton)
endmethod
static method getCurEventType takes nothing returns integer
return currentEventType
endmethod
static method operator [] takes player p returns thistype
if thistype(GetPlayerId(p) + 1).posDetector != null then
return GetPlayerId(p) + 1
endif
return 0
endmethod
method operator player takes nothing returns player
return Player(this - 1)
endmethod
method operator isMouseClicked takes nothing returns boolean
return .mouseClickCount > 0
endmethod
method isMouseButtonClicked takes mousebuttontype mouseButton returns boolean
return UserMouse.mouseButtonStack[(this - 1)*3 + UserMouse.toIndex(mouseButton)] > 0
endmethod
method setMousePos takes integer x, integer y returns nothing
if GetLocalPlayer() == this.player then
call BlzSetMousePos(x, y)
endif
endmethod
static if IMPL_LOCK then
private static method getMouseEventReductor takes timer t returns thistype
local thistype this = thistype(0).next
loop
exitwhen this.mouseEventReductor == t or this == 0
set this = this.next
endloop
return this
endmethod
private static method onMouseUpdateListener takes nothing returns nothing
local thistype this = thistype(0).resetNext
set updateCount = 0
loop
exitwhen this == 0
set updateCount = updateCount + 1
set this.mouseEventCount = 0
call EnableTrigger(this.posDetector)
set this.resetNext.resetPrev = this.resetPrev
set this.resetPrev.resetNext = this.resetNext
set this = this.resetNext
endloop
if updateCount > 0 then
static if not IS_INSTANT then
call TimerStart(resetTimer, INTERVAL, false, function thistype.onMouseUpdateListener)
else
call onMouseUpdateListener()
endif
else
static if not IS_INSTANT then
call TimerStart(resetTimer, 0.00, false, null)
call PauseTimer(resetTimer)
endif
endif
endmethod
private static method onMouseReductListener takes nothing returns nothing
local thistype this = getMouseEventReductor(GetExpiredTimer())
if this.mouseEventCount <= 0 then
call PauseTimer(this.mouseEventReductor)
else
set this.mouseEventCount = IMaxBJ(this.mouseEventCount - MOUSE_COUNT_LOSS, 0)
call TimerStart(this.mouseEventReductor, INTERVAL, false, function thistype.onMouseReductListener)
endif
endmethod
endif
private static method onMouseUpOrDown takes nothing returns nothing
local thistype this = thistype[GetTriggerPlayer()]
local integer index = (this - 1)*3 + UserMouse.toIndex(BlzGetTriggerPlayerMouseButton())
local boolean releaseFlag = false
if GetTriggerEventId() == EVENT_PLAYER_MOUSE_DOWN then
set this.mouseClickCount = IMinBJ(this.mouseClickCount + 1, 3)
set releaseFlag = UserMouse.mouseButtonStack[index] <= 0
set UserMouse.mouseButtonStack[index] = IMinBJ(UserMouse.mouseButtonStack[index] + 1, 1)
if releaseFlag then
set currentEventType = EVENT_MOUSE_DOWN
call TriggerEvaluate(evTrigger[EVENT_MOUSE_DOWN])
endif
else
set this.mouseClickCount = IMaxBJ(this.mouseClickCount - 1, 0)
set releaseFlag = UserMouse.mouseButtonStack[index] > 0
set UserMouse.mouseButtonStack[index] = IMaxBJ(UserMouse.mouseButtonStack[index] - 1, 0)
if releaseFlag then
set currentEventType = EVENT_MOUSE_UP
call TriggerEvaluate(evTrigger[EVENT_MOUSE_UP])
endif
endif
endmethod
private static method onMouseMove takes nothing returns nothing
local thistype this = thistype[GetTriggerPlayer()]
local boolean started = false
set this.mouseX = BlzGetTriggerPlayerMouseX()
set this.mouseY = BlzGetTriggerPlayerMouseY()
static if IMPL_LOCK then
set this.mouseEventCount = this.mouseEventCount + 1
if this.mouseEventCount <= 1 then
call TimerStart(this.mouseEventReductor, INTERVAL, false, function thistype.onMouseReductListener)
endif
endif
set currentEventType = EVENT_MOUSE_MOVE
call TriggerEvaluate(evTrigger[EVENT_MOUSE_MOVE])
static if IMPL_LOCK then
if this.mouseEventCount >= thistype.MOUSE_COUNT_MAX then
call DisableTrigger(this.posDetector)
if thistype(0).resetNext == 0 then
static if not IS_INSTANT then
call TimerStart(resetTimer, INTERVAL, false, function thistype.onMouseUpdateListener)
// Mouse event reductor should be paused
else
set started = true
endif
call PauseTimer(this.mouseEventReductor)
endif
set this.resetNext = 0
set this.resetPrev = this.resetNext.resetPrev
set this.resetPrev.resetNext = this
set this.resetNext.resetPrev = this
if started then
call onMouseUpdateListener()
endif
endif
endif
endmethod
private static method init takes nothing returns nothing
local thistype this = 1
local player p = this.player
static if IMPL_LOCK and not IS_INSTANT then
set resetTimer = CreateTimer()
endif
set stateDetector = CreateTrigger()
set evTrigger[EVENT_MOUSE_UP] = CreateTrigger()
set evTrigger[EVENT_MOUSE_DOWN] = CreateTrigger()
set evTrigger[EVENT_MOUSE_MOVE] = CreateTrigger()
call TriggerAddCondition( stateDetector, Condition(function thistype.onMouseUpOrDown))
loop
exitwhen integer(this) > bj_MAX_PLAYER_SLOTS
if GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
set this.next = 0
set this.prev = thistype(0).prev
set thistype(0).prev.next = this
set thistype(0).prev = this
set this.posDetector = CreateTrigger()
static if IMPL_LOCK and not IS_INSTANT then
set this.mouseEventReductor = CreateTimer()
endif
call TriggerRegisterPlayerEvent( this.posDetector, p, EVENT_PLAYER_MOUSE_MOVE )
call TriggerAddCondition( this.posDetector, Condition(function thistype.onMouseMove))
call TriggerRegisterPlayerEvent( stateDetector, p, EVENT_PLAYER_MOUSE_UP )
call TriggerRegisterPlayerEvent( stateDetector, p, EVENT_PLAYER_MOUSE_DOWN )
endif
set this = this + 1
set p = this.player
endloop
endmethod
static method registerCode takes code handlerFunc, integer eventId returns triggercondition
return TriggerAddCondition(evTrigger[eventId], Condition(handlerFunc))
endmethod
static method unregisterCallback takes triggercondition whichHandler, integer eventId returns nothing
call TriggerRemoveCondition(evTrigger[eventId], whichHandler)
endmethod
implement Init
endstruct
function GetPlayerMouseX takes player p returns real
return UserMouse[p].mouseX
endfunction
function GetPlayerMouseY takes player p returns real
return UserMouse[p].mouseY
endfunction
function OnMouseEvent takes code func, integer eventId returns triggercondition
return UserMouse.registerCode(func, eventId)
endfunction
function GetMouseEventType takes nothing returns integer
return UserMouse.getCurEventType()
endfunction
function UnregisterMouseCallback takes triggercondition whichHandler, integer eventId returns nothing
call UserMouse.unregisterCallback(whichHandler, eventId)
endfunction
function SetUserMousePos takes player p, integer x, integer y returns nothing
call UserMouse[p].setMousePos(x, y)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library LineSegmentEnumeration /* v2.1a -- hiveworkshop.com/threads/line-segment-enumeration-v1-1.286552/
Information
¯¯¯¯¯¯¯¯¯¯¯
Allows to enumerate widgets inside a line segment with an offset.
So basicly it will result in a rect, but which is also allowed to be rotated.
Mechanics
¯¯¯¯¯¯¯¯¯
(Issue:)
The problem with normal jass rects is that they aren't defined by 4 points, but only by 4 values: x/y -min/max.
The result is that a jass rect is never rotated, so it's always paralel to the x/y axis.
But when we draw a line from point A to point B we might also create a non-axix-parelel rect, and then
we can't use the normal rect natives from jass anymore to find out if a point is inside the rect.
(Solution:)
To solve this problem the system does following:
jass rect: rectangular defined by 4 values (axis paralel)
custom rect: the real rectangular that is defined by user (not axis parelel)
1. Create a big jass rect that is big enough so we can ensure to enum all widgets that are potentialy inside our custom rect. (Enum_Group)
This Enum_Group will contain all wanted units, but may also contain not wanted units.
2. We rotate the custom rect around Point B, by angle "theta", so it gets now a normal, non-rotated rect. (axis parelel)
3. We loop through Enum_Group, and rotate all widget's coordinates also by the same "theta" value around Point B.
4. Now what happened is that the custom rect was manipulated so it got axis parelel. And we also used the same maths
to manipulate the x/y coordinate of our widgets, so the relation between the custom rect and the widget is still the very same.
But what we can do now is to use native jass logics to check if the widget is within the bounds of the rotated custom rect
with only comparing it's x/y coordinates with the rect's x/y -min/max coodinates.
Note: this approach is not the most performant one, but it doesn't work with custom types. So if you already work with for example
struct rects or other polygons, and you care for trigomnomig orientation you can write straight forward functions to check if a point
is inside a quadrilateral, as standalone function.
*/
// --- API ---
//! novjass
struct LineSegment
static method EnumUnits takes group whichgroup, real ax, real ay, real bx, real by, real offset returns nothing
static method EnumDestructables takes real ax, real ay, real bx, real by, real offset returns nothing
// after enumerated destructables you have access to:
static integer DestructableCounter // starts with index "0"
static destructable array Destructable
static method EnumItems takes real ax, real ay, real bx, real by, real offset returns nothing
// after enumerated items you have access to:
static integer ItemCounter // starts with index "0"
static destructable array Item
//! endnovjass
// ==== End API ====
struct LineSegment extends array
private static constant rect RECT = Rect(0, 0, 0, 0)
private static constant group GROUP = CreateGroup()
public static method EnumUnits takes group whichgroup, real ax, real ay, real bx, real by, real offset returns nothing
local real angle = Atan2(by - ay, bx - ax)
local real theta = ModuloReal(angle, bj_PI/2)
local real thetaSin
local real thetaCos
local unit u
local real x
local real y
local real x_new
local real y_new
local real maxX
local real maxY
local real minX
local real minY
local real x1
local real y1
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
// Enum all potential units
if ax > bx then
set maxX = ax + offset
set minX = bx - offset
else
set maxX = bx + offset
set minX = ax - offset
endif
if ay > by then
set maxY = ay + offset
set minY = by - offset
else
set maxY = by + offset
set minY = ay - offset
endif
call SetRect(RECT, minX, minY, maxX, maxY)
call GroupEnumUnitsInRect(GROUP, RECT, null)
// Create and rotate rect around point B, so it gets unrotated
set angle = angle - theta
set angle = angle*-1
set thetaSin = Sin(-theta)
set thetaCos = Cos(-theta)
set x_new = (ax-bx)*thetaCos - (ay-by)*thetaSin + bx
set y_new = (ax-bx)*thetaSin + (ay-by)*thetaCos + by
set x1 = x_new + offset*Cos(angle - bj_PI*0.5)
set y1 = y_new + offset*Sin(angle - bj_PI*0.5)
set x2 = x_new + offset*Cos(angle + bj_PI*0.5)
set y2 = y_new + offset*Sin(angle + bj_PI*0.5)
set x3 = bx + offset*Cos(angle - bj_PI*0.5)
set y3 = by + offset*Sin(angle - bj_PI*0.5)
set x4 = bx + offset*Cos(angle + bj_PI*0.5)
set y4 = by + offset*Sin(angle + bj_PI*0.5)
// define max/min values of the new non-rotated rect
if x1 > x2 then
set maxX = RMaxBJ(x1, x3)
set minX = RMinBJ(x2, x4)
else
set maxX = RMaxBJ(x2, x4)
set minX = RMinBJ(x1, x3)
endif
if y1 > y2 then
set maxY = RMaxBJ(y1, y3)
set minY = RMinBJ(y2, y4)
else
set maxY = RMaxBJ(y2, y4)
set minY = RMinBJ(y1, y3)
endif
// enum through all tracked units, rotate it around B, and check if it's inside bounds
call GroupClear(whichgroup)
loop
set u = FirstOfGroup(GROUP)
exitwhen u == null
set x = GetUnitX(u)
set y = GetUnitY(u)
set x_new = (x-bx)*thetaCos - (y-by)*thetaSin + bx
set y_new = (x-bx)*thetaSin + (y-by)*thetaCos + by
if x_new >= minX and x_new <= maxX and y_new >= minY and y_new <= maxY then
call GroupAddUnit(whichgroup, u)
endif
call GroupRemoveUnit(GROUP, u)
endloop
endmethod
//! textmacro LSE_WIDGET takes TYPE, NAME
private static integer $NAME$Counter_p = -1
private static $TYPE$ array $NAME$_p
public static integer $NAME$Counter = -1
public static $TYPE$ array $NAME$
private static method on$NAME$Filter takes nothing returns nothing
set $NAME$Counter_p = $NAME$Counter_p + 1
set $NAME$_p[$NAME$Counter_p] = GetEnum$NAME$()
endmethod
public static method Enum$NAME$s takes real ax, real ay, real bx, real by, real offset returns nothing
local real angle = Atan2(by - ay, bx - ax)
local real theta = ModuloReal(angle, bj_PI/2)
local real thetaSin
local real thetaCos
local $TYPE$ t
local real x
local real y
local real x_new
local real y_new
local real maxX
local real maxY
local real minX
local real minY
local real x1
local real y1
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
// Enum all potential widgets
if ax > bx then
set maxX = ax + offset
set minX = bx - offset
else
set maxX = bx + offset
set minX = ax - offset
endif
if ay > by then
set maxY = ay + offset
set minY = by - offset
else
set maxY = by + offset
set minY = ay - offset
endif
call SetRect(RECT, minX, minY, maxX, maxY)
set $NAME$Counter_p = -1
call Enum$NAME$sInRect(RECT, null, function thistype.on$NAME$Filter)
// Create and rotate rect around point B, so it gets unrotated
set angle = angle - theta
set angle = angle*-1
set thetaSin = Sin(-theta)
set thetaCos = Cos(-theta)
set x_new = (ax-bx)*thetaCos - (ay-by)*thetaSin + bx
set y_new = (ax-bx)*thetaSin + (ay-by)*thetaCos + by
set x1 = x_new + offset*Cos(angle - bj_PI*0.5)
set y1 = y_new + offset*Sin(angle - bj_PI*0.5)
set x2 = x_new + offset*Cos(angle + bj_PI*0.5)
set y2 = y_new + offset*Sin(angle + bj_PI*0.5)
set x3 = bx + offset*Cos(angle - bj_PI*0.5)
set y3 = by + offset*Sin(angle - bj_PI*0.5)
set x4 = bx + offset*Cos(angle + bj_PI*0.5)
set y4 = by + offset*Sin(angle + bj_PI*0.5)
// define max/min values of the new non-rotated rect
if x1 > x2 then
set maxX = RMaxBJ(x1, x3)
set minX = RMinBJ(x2, x4)
else
set maxX = RMaxBJ(x2, x4)
set minX = RMinBJ(x1, x3)
endif
if y1 > y2 then
set maxY = RMaxBJ(y1, y3)
set minY = RMinBJ(y2, y4)
else
set maxY = RMaxBJ(y2, y4)
set minY = RMinBJ(y1, y3)
endif
// enum through all tracked widgets, rotate it around B, and check if it's inside bounds
set $NAME$Counter = -1
loop
exitwhen $NAME$Counter_p < 0
set t = $NAME$_p[$NAME$Counter_p]
set x = Get$NAME$X(t)
set y = Get$NAME$Y(t)
set x_new = (x-bx)*thetaCos - (y-by)*thetaSin + bx
set y_new = (x-bx)*thetaSin + (y-by)*thetaCos + by
if x_new >= minX and x_new <= maxX and y_new >= minY and y_new <= maxY then
set $NAME$Counter = $NAME$Counter + 1
set $NAME$[$NAME$Counter] = t
endif
set $NAME$_p[$NAME$Counter_p] = null
set $NAME$Counter_p = $NAME$Counter_p - 1
endloop
endmethod
//! endtextmacro
//! runtextmacro LSE_WIDGET("destructable", "Destructable")
//! runtextmacro LSE_WIDGET("item", "Item")
endstruct
endlibrary
//TESH.scrollpos=126
//TESH.alwaysfold=0
library LineSegmentEnumeration
globals
unit array units
private constant group GROUP = CreateGroup()
private constant rect RECT = Rect(0, 0, 0, 0)
endglobals
function EnumUnitsInLineSegment takes group whichgroup, real ax, real ay, real bx, real by, real offset returns nothing
local real angle = Atan2(by - ay, bx - ax)
local real theta = ModuloReal(angle, bj_PI/2)
local real thetaSin
local real thetaCos
local rect r
local unit u
local real x
local real y
local real x_new
local real y_new
local real maxX
local real maxY
local real minX
local real minY
local real x1
local real y1
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
if ax > bx then
set maxX = ax + offset
set minX = bx - offset
else
set maxX = bx + offset
set minX = ax - offset
endif
if ay > by then
set maxY = ay + offset
set minY = by - offset
else
set maxY = by + offset
set minY = ay - offset
endif
call SetRect(RECT, minX, minY, maxX, maxY)
call GroupEnumUnitsInRect(GROUP, RECT, null)
call SetUnitX(units[4], maxX)
call SetUnitY(units[4], maxY)
call SetUnitX(units[5], maxX)
call SetUnitY(units[5], minY)
call SetUnitX(units[6], minX)
call SetUnitY(units[6], maxY)
call SetUnitX(units[7], minX)
call SetUnitY(units[7], minY)
call ClearTextMessages()
call BJDebugMsg("angle: " + R2S(angle*bj_RADTODEG))
call BJDebugMsg("theta: " + R2S(theta*bj_RADTODEG))
set angle = angle - theta
set angle = angle*-1
set thetaSin = Sin(-theta)
set thetaCos = Cos(-theta)
call BJDebugMsg("angle fixed: " + R2S(angle*bj_RADTODEG))
set x_new = (ax-bx)*thetaCos - (ay-by)*thetaSin + bx
set y_new = (ax-bx)*thetaSin + (ay-by)*thetaCos + by
set x1 = x_new + offset*Cos(angle - bj_PI*0.5)
set y1 = y_new + offset*Sin(angle - bj_PI*0.5)
set x2 = x_new + offset*Cos(angle + bj_PI*0.5)
set y2 = y_new + offset*Sin(angle + bj_PI*0.5)
set x3 = bx + offset*Cos(angle - bj_PI*0.5)
set y3 = by + offset*Sin(angle - bj_PI*0.5)
set x4 = bx + offset*Cos(angle + bj_PI*0.5)
set y4 = by + offset*Sin(angle + bj_PI*0.5)
if x1 > x2 then
set maxX = RMaxBJ(x1, x3)
set minX = RMinBJ(x2, x4)
else
set maxX = RMaxBJ(x2, x4)
set minX = RMinBJ(x1, x3)
endif
if y1 > y2 then
set maxY = RMaxBJ(y1, y3)
set minY = RMinBJ(y2, y4)
else
set maxY = RMaxBJ(y2, y4)
set minY = RMinBJ(y1, y3)
endif
call SetUnitX(units[0], x1)
call SetUnitY(units[0], y1)
call SetUnitX(units[1], x2)
call SetUnitY(units[1], y2)
call SetUnitX(units[2], x3)
call SetUnitY(units[2], y3)
call SetUnitX(units[3], x4)
call SetUnitY(units[3], y4)
// ================== ===
call GroupClear(whichgroup)
loop
set u = FirstOfGroup(GROUP)
exitwhen u == null
if GetOwningPlayer(u) != GetLocalPlayer() then
set x = GetUnitX(u)
set y = GetUnitY(u)
set x_new = (x-bx)*thetaCos - (y-by)*thetaSin + bx
set y_new = (x-bx)*thetaSin + (y-by)*thetaCos + by
if x_new >= minX and x_new <= maxX and y_new >= minY and y_new <= maxY then
call GroupAddUnit(whichgroup, u)
endif
endif
call GroupRemoveUnit(GROUP, u)
endloop
endfunction
function Trig_LSE_Run_Units_Actions takes nothing returns nothing
call EnumUnitsInLineSegment(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_Offset)
endfunction
//===========================================================================
function InitTrig_LSE_backup takes nothing returns nothing
set gg_trg_LSE_backup = CreateTrigger( )
set units[0] = CreateUnit(GetLocalPlayer(), 'hfoo', 0, 0, 0)
set units[1] = CreateUnit(GetLocalPlayer(), 'hfoo', 0, 0, 0)
set units[2] = CreateUnit(GetLocalPlayer(), 'hfoo', 0, 0, 0)
set units[3] = CreateUnit(GetLocalPlayer(), 'hfoo', 0, 0, 0)
set units[4] = CreateUnit(GetLocalPlayer(), 'hpea', 0, 0, 0)
set units[5] = CreateUnit(GetLocalPlayer(), 'hpea', 0, 0, 0)
set units[6] = CreateUnit(GetLocalPlayer(), 'hpea', 0, 0, 0)
set units[7] = CreateUnit(GetLocalPlayer(), 'hpea', 0, 0, 0)
call UnitAddAbility(units[0], 'Aeth')
call UnitAddAbility(units[1], 'Aeth')
call UnitAddAbility(units[2], 'Aeth')
call UnitAddAbility(units[3], 'Aeth')
call UnitAddAbility(units[4], 'Aeth')
call UnitAddAbility(units[5], 'Aeth')
call UnitAddAbility(units[6], 'Aeth')
call UnitAddAbility(units[7], 'Aeth')
call TriggerAddAction( gg_trg_LSE_backup, function Trig_LSE_Run_Units_Actions )
endfunction
endlibrary
//TESH.scrollpos=5
//TESH.alwaysfold=0
library LineSegmentEnumerationGUI uses LineSegmentEnumeration /* v2.0
*/
private struct LineSegmentGUI extends array
private static method GetUnits takes nothing returns nothing
call LineSegment.EnumUnits(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_Offset)
endmethod
private static method GetDestructables takes nothing returns nothing
call LineSegment.EnumDestructables(GetLocationX(udg_LSE_Loc_1), GetLocationY(udg_LSE_Loc_1), GetLocationX(udg_LSE_Loc_2), GetLocationY(udg_LSE_Loc_2), udg_LSE_Offset)
set udg_LSE_DestructableCounter = -1
loop
exitwhen LineSegment.DestructableCounter < 0
set udg_LSE_DestructableCounter = udg_LSE_DestructableCounter + 1
set udg_LSE_Destructable[udg_LSE_DestructableCounter] = LineSegment.Destructable[LineSegment.DestructableCounter]
set LineSegment.DestructableCounter = LineSegment.DestructableCounter - 1
endloop
endmethod
private static method GetItems takes nothing returns nothing
call LineSegment.EnumItems(GetLocationX(udg_LSE_Loc_1), GetLocationY(udg_LSE_Loc_1), GetLocationX(udg_LSE_Loc_2), GetLocationY(udg_LSE_Loc_2), udg_LSE_Offset)
set udg_LSE_ItemCounter = -1
loop
exitwhen LineSegment.ItemCounter < 0
set udg_LSE_ItemCounter = udg_LSE_ItemCounter + 1
set udg_LSE_Item[udg_LSE_ItemCounter] = LineSegment.Item[LineSegment.ItemCounter]
set LineSegment.ItemCounter = LineSegment.ItemCounter - 1
endloop
endmethod
private static method onInit takes nothing returns nothing
set udg_LSE_GetUnits = CreateTrigger()
set udg_LSE_GetDestructables = CreateTrigger()
set udg_LSE_GetItems = CreateTrigger()
call TriggerAddAction(udg_LSE_GetUnits, function thistype.GetUnits)
call TriggerAddAction(udg_LSE_GetDestructables, function thistype.GetDestructables)
call TriggerAddAction(udg_LSE_GetItems, function thistype.GetItems)
endmethod
endstruct
endlibrary