GFreak45
I didnt slap you, i high 5'd your face.
- Reaction score
- 130
Ok so the system i have been working on creates pathing blockers and destroys them after a duration, in a shape desired by the user, i have a problem with a few things:
System Pros:
Cons:
I will + rep for solving any of those:
Function Calls:
Code:
- The name is shitty (Path Blocker)
- I am having issues with the "death" method, it simply does not destroy the blocker as wanted
- I have not yet completed the "Around Path" function, its rather difficult as it consists of 2 half circles and 2 straight lines
- Not sure when i should submit this but i know at least not until the "death" method is working correctly
System Pros:
- I have not seen another system for blocking like this AFAIK
- It does not Itterate through the entire list when checking if there is another blocker there, only the ones who's rect (not a real rect just min/max x/y) overlap the new blocker - this is done using a linked list of the beginnings to other linked lists with nextb (nextBase), previousb (previousBase), next, previous, and baseInt (start integer identifier of the linked list since it is not 0)
- Capable of making complex shapes using multiple calls
- Options include: Sizes, Shapes, Blocker Sizes, Blocker Pathing Types (Air/Ground/Both), and Durations
- No High frequency timers so no need for T32 (unless you call it using a t32 based function etc)
- Unit Pathing/Game pathing does not hinder the pathing blocker creation or distort it in any way
Cons:
- Not Spammable (can hit the 8190 cap if spammed with rects circulars or any large pathing blocks
- Still a WIP and unreliable until further notice
- Common Spells do not create pathing blockers, may be needed for only 1 spell in the entire map
I will + rep for solving any of those:
Function Calls:
JASS:
/* function BlockRect takes real xa, real ya, real xb, real yb, real duration, boolean large, integer GroundPathing returns nothing //ground pathing is 1 for ground 2 for both air and ground, and 3 for ground
used via: call BlockRect(xa, ya, xb, yb, duration, bool size, 1 to 3)
Blocks a Rect (Rectangle) but it is defined via 2 locations and does not use or create a real rect
function BlockPath takes real xa, real ya, real xb, real yb, real duration, boolean large, integer GroundPathing returns nothing //ground pathing is 1 for ground 2 for both air and ground, and 3 for ground
used via: call BlockPath(xa, ya, xb, yb, duration, bool size, 1 to 3)
Blocks a pathway between points a and b
function BlockCircular takes real x, real y, real radius, real duration, boolean large, integer GroundPathing returns nothing //ground pathing is 1 for ground 2 for both air and ground, and 3 for ground
used via: call BlockPath(x, y, radius, duration, bool size, 1 to 3)
Blocks a Circular area, through and through
function BlockCircumfrence takes real x, real y, real radius, real duration, boolean large, integer GroundPathing returns nothing //ground pathing is 1 for ground 2 for both air and ground, and 3 for ground
used via: call BlockCirc(x, y, radius, duration, bool size, 1 to 3)
Blocks a Circular along the circumfrence of the circle, does not block the middle or outside of the circumfrence
function BlockPerimeter takes real xa, real ya, real xb, real yb, real duration, boolean large, integer GroundPathing returns nothing //ground pathing is 1 for ground 2 for both air and ground, and 3 for ground
used via: call BlockPerimeter(xa, ya, xb, yb, duration, bool size, 1 to 3)
Blocks the perimeter of a rect, the inside and outside are open for pathing
Soon to come:
function BlockAroundPath takes real xa, real ya, real xb, real yb, real width, real duration, boolean large, integer GroundPathing returns nothing //ground pathing is 1 for ground 2 for both air and ground, and 3 for ground
used via: call BlockAroundPath(xa, ya, xb,, yb, width, duration, bool size, 1 to 3)
Blocks an area around a straight path from point to point with a width, this will always create an oval but the width of that oval is dependant on the used width and the length of the straight parts is dependant on the width
Code:
JASS:
library PBU initializer OnInit
globals
private integer array LargeDest
private integer array SmallDest
endglobals
private struct PBULL extends array
real x //position x of destructable/pathing blocker
real y //position y of destructable/pathing blocker
destructable blocker //the actual destructable/pathing blocker
timer destroyTimer //the timer that destroys the destructable/pathing blocker
integer next //the next for the linked list of every grouping of destructables/pathing blockers
integer previous //the previous for the linked list of every grouping of destructables/pathing blockers
boolean base //if the current node is a base or not
integer nextb //the next node base for the linked list of bases
integer previousb //the previous node base for the linked list of bases
integer baseInt //the base node for this instance
real baseMinX //the minimum x for the entire grouping of a base node's pathing blocker list used in iteration for minimal calls
real baseMinY //the minimum y for the entire grouping of a base node's pathing blocker list used in iteration for minimal calls
real baseMaxX //the maximum x for the entire grouping of a base node's pathing blocker list used in iteration for minimal calls
real baseMaxY //the maximum y for the entire grouping of a base node's pathing blocker list used in iteration for minimal calls
private static integer array recycleList
private static integer lastRecycled
private static integer listCount
private static method Allocate takes nothing returns thistype
local thistype this = .recycleList[0]
if .recycleList[0] != 0 then
debug if .listCount > 8190 then
debug call BJDebugMsg("Travel Blocker ERROR: You have attempted to create too many blockers and no more can be created.")
debug return 0
debug endif
set .listCount = .listCount + 1
return .listCount
endif
set .recycleList[0] = .recycleList[this]
set .recycleList[this] = this
return this
endmethod
private static method deallocate takes thistype this returns nothing
set thistype(this.previous).next = this.next
set thistype(this.next).previous = this.previous
set thistype(this.nextb).previousb = this.previousb
set thistype(this.previousb).nextb = this.nextb
set .recycleList[.lastRecycled] = this
set .lastRecycled = this
endmethod
private static method death takes nothing returns nothing
local thistype a = thistype(0).previousb
local thistype b
loop
set a = a.previousb
exitwhen a.destroyTimer == GetExpiredTimer()
endloop
loop
call RemoveDestructable(a.blocker)
set a.blocker = null
set b = a
exitwhen a.next == a.baseInt
set a = a.next
call thistype.deallocate(b)
endloop
endmethod
static method register takes destructable dest, boolean base, real duration, integer baseInt returns thistype
local thistype this = thistype.Allocate()
set this.blocker = dest
set this.base = base
if baseInt != 0 then
set this.baseInt = baseInt
else
set this.destroyTimer = CreateTimer()
call TimerStart(this.destroyTimer, duration, false, function thistype.death)
set this.baseInt = this
endif
if base then
set thistype(thistype(0).previous).nextb = this
set thistype(0).previousb = this
set this.next = this
set this.previous = this
else
set this.next = this.baseInt
set this.previous = thistype(this.baseInt).previous
set thistype(this.previous).next = this
set thistype(this.baseInt).previous = this
endif
set this.x = GetDestructableX(dest)
set this.y = GetDestructableY(dest)
if this.x <= thistype(this.baseInt).baseMinX then
set thistype(this.baseInt).baseMinX = this.x
set this.baseMinX = this.x
elseif this.x >= thistype(this.baseInt).baseMaxX then
set thistype(this.baseInt).baseMinX = this.x
set this.baseMinY = this.y
endif
if this.y <= thistype(this.baseInt).baseMinY then
set thistype(this.baseInt).baseMinY = this.y
set this.baseMinY = this.y
elseif this.y >= thistype(this.baseInt).baseMaxY then
set thistype(this.baseInt).baseMaxY = this.y
set this.baseMaxY = this.y
endif
return this
endmethod
static method iteration takes real x, real y, thistype a returns boolean
local thistype this = thistype(0).previousb
local thistype i
loop
if this != a /*
*/and ((this.baseMaxX >= x /*
*/and this.baseMinX <= x) /*
*/and this.baseMaxY >= y /*
*/and this.baseMinY <= y) then
set i = this.next
loop
if SquareRoot(((x - i.x) * (x - i.x) + (y - i.y) * (y - i.y))) <= 100 then
return false
endif
set i = i.next
exitwhen i.next == i.baseInt
endloop
endif
exitwhen this.previousb == 0
set this = this.previousb
endloop
return true
endmethod
endstruct
function BlockRect takes real xa, real ya, real xb, real yb, real duration, boolean large, integer ground returns nothing
local integer x
local integer y
local integer register = 0
local real xc = xa
local real yc = ya
local destructable dest
local boolean base = true
local real Size
local integer DestID
if large then
set DestID = LargeDest[ground - 1]
set Size = 125.0
else
set DestID = SmallDest[ground - 1]
set Size = 62.5
endif
set x = R2I(SquareRoot((xa - xb) * (xa - xb)) / Size)
loop
exitwhen x == 0
set y = R2I(SquareRoot((ya - yb) * (ya - yb)) / Size)
loop
exitwhen y == 0
if PBULL.iteration(xc, yc, register)then
set dest = CreateDestructable(DestID , xc, yc, 0.0, 1.0, 0)
if base then
set register = PBULL.register(dest, base, duration, 0)
set base = false
else
call PBULL.register(dest, base, duration, register)
endif
endif
if ya >= yb then
set yc = yc - Size
else
set yc = yc + Size
endif
set y = y - 1
endloop
if xa >= xb then
set xc = xc - Size
else
set xc = xc + Size
endif
set x = x - 1
endloop
set dest = null
endfunction
function BlockPath takes real xa, real ya, real xb, real yb, real duration, boolean large, integer ground returns nothing
local real x = xa
local real y = ya
local integer register = 0
local destructable dest
local boolean base = true
local real Size
local integer DestID
local integer i
if large then
set DestID = LargeDest[ground - 1]
set Size = 125.0
else
set DestID = SmallDest[ground - 1]
set Size = 62.5
endif
set i = R2I(SquareRoot(Pow(xa - xb, 2) + Pow(ya - yb, 2)) / Size)
loop
if PBULL.iteration(x, y, register) then
set dest = CreateDestructable(DestID , x, y, 0.0, 1.0, 0)
if base then
set register = PBULL.register(dest, base, duration, 0)
set base = false
else
call PBULL.register(dest, base, duration, register)
endif
endif
set x = x + Size * Cos(Atan2(yb - ya, xb - xa))
set y = y + Size * Sin(Atan2(yb - ya, xb - xa))
set i = i - 1
exitwhen i == 0
endloop
endfunction
function BlockCircular takes real x, real y, real radius, real duration, boolean large, integer ground returns nothing
local real a = radius * Cos(bj_DEGTORAD * 45)
local real xa = x + a * Cos(135 * bj_DEGTORAD)
local real ya = y + a * Sin(135 * bj_DEGTORAD)
local real xb = x + a * Cos(315 * bj_DEGTORAD)
local real yb = y + a * Sin(315 * bj_DEGTORAD)
local integer register = 0
local integer xc
local integer yc
local destructable dest
local boolean base = true
local real Size
local integer DestID
if large then
set DestID = LargeDest[ground - 1]
set Size = 125.0
else
set DestID = SmallDest[ground - 1]
set Size = 62.5
endif
set xc = R2I(SquareRoot((xa - xb) * (xa - xb)) / Size)
loop
exitwhen xc == 0
set yc = R2I(SquareRoot((ya - yb) * (ya - yb)) / Size)
loop
exitwhen yc == 0
if SquareRoot((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb)) <= radius then
if PBULL.iteration(xa, ya, register) then
set dest = CreateDestructable(DestID , xa, ya, 0.0, 1.0, 1)
if base then
set register = PBULL.register(dest, base, duration, 0)
set base = false
else
call PBULL.register(dest, base, duration, register)
endif
endif
endif
if ya >= yb then
set ya = ya - Size
else
set ya = ya + Size
endif
set yc = yc - 1
endloop
if xa >= xb then
set xa = xa - Size
else
set xa = xa + Size
endif
set xc = xc - 1
endloop
set dest = null
endfunction
function BlockCircumfrence takes real x, real y, real radius, real duration, boolean large, integer ground returns nothing
local real a = radius * Cos(bj_DEGTORAD * 45)
local real xa = x + a * Cos(135 * bj_DEGTORAD)
local real ya = y + a * Sin(135 * bj_DEGTORAD)
local real xb = x + a * Cos(315 * bj_DEGTORAD)
local real yb = y + a * Sin(315 * bj_DEGTORAD)
local integer register = 0
local integer xc
local integer yc
local destructable dest
local boolean base = true
local real Size
local integer DestID
if large then
set DestID = LargeDest[ground - 1]
set Size = 125.0
else
set DestID = SmallDest[ground - 1]
set Size = 62.5
endif
set xc = R2I(SquareRoot((xa - xb) * (xa - xb)) / Size)
loop
exitwhen xc == 0
set yc = R2I(SquareRoot((ya - yb) * (ya - yb)) / Size)
loop
exitwhen yc == 0
if SquareRoot((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb)) <= radius + Size and SquareRoot((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb)) >= radius - Size then
if PBULL.iteration(xa, ya, register) then
set dest = CreateDestructable(DestID , xa, ya, 0.0, 1.0, 0)
if base then
set register = PBULL.register(dest, base, duration, 0)
set base = false
else
call PBULL.register(dest, base, duration, register)
endif
endif
endif
if ya >= yb then
set ya = ya - Size
else
set ya = ya + Size
endif
set yc = yc - 1
endloop
if xa >= xb then
set xa = xa - Size
else
set xa = xa + Size
endif
set xc = xc - 1
endloop
set dest = null
endfunction
function BlockPerimeter takes real xa, real ya, real xb, real yb, real duration, boolean large, integer ground returns nothing
local integer x
local integer y
local real xc = xa
local real yc = ya
local destructable dest
local integer register = 0
local boolean base = true
local real Size
local integer DestID
if large then
set DestID = LargeDest[ground - 1]
set Size = 125.0
else
set DestID = SmallDest[ground - 1]
set Size = 62.5
endif
set y = R2I(SquareRoot(Pow(((xa - xb) / Size),2)))
loop
if PBULL.iteration(xc, ya, register) then
set dest = CreateDestructable(DestID, xc, ya, 0.0, 1.0, 1)
if base then
set register = PBULL.register(dest, base, duration, 0)
set base = false
else
call PBULL.register(dest, base, duration, register)
endif
endif
if PBULL.iteration(xc, yb, register) then
set dest = CreateDestructable(DestID, xc, yb, 0.0, 1.0, 1)
call PBULL.register(dest, base, duration, register)
endif
if xa >= xb then
set xc = xc - Size
else
set xc = xc + Size
endif
exitwhen x == 0
set x = x - 1
endloop
set y = R2I(SquareRoot(Pow(((ya - yb) / Size),2))) - 2
loop
if PBULL.iteration(xa, yc, register) then
set dest = CreateDestructable(DestID, xc, ya, 0.0, 1.0, 1)
call PBULL.register(dest, base, duration, register)
endif
if PBULL.iteration(xb, yc, register) then
set dest = CreateDestructable(DestID, xc, yb, 0.0, 1.0, 1)
call PBULL.register(dest, base, duration, register)
endif
if ya >= yb then
set yc = yc - Size
else
set yc = yc + Size
endif
exitwhen x == 0
set x = x - 1
endloop
endfunction
function BlockAroundPath takes real xa, real ya, real xb, real yb, real width, real duration, boolean large, integer ground returns nothing
endfunction
private function OnInit takes nothing returns nothing
set LargeDest[0] = 039;YTpc039;
set LargeDest[1] = 039;YTfc039;
set LargeDest[2] = 039;YTac039;
set SmallDest[0] = 039;YTpb039;
set SmallDest[1] = 039;YTfb039;
set SmallDest[2] = 039;YTab039;
endfunction
endlibrary