- Joined
- Jan 28, 2012
- Messages
- 266
As stated in the title, I would appreciate help for improving the API of this system.
JASS:
library Behaviors
globals
public behavior EVAL_BEHAVIOR = 0
public boolean END_IT = false
public integer RETURN = 0
endglobals
struct BEHAVIOR extends array
private thistype recycle
private static integer total = 0
private static thistype HEAD = 0
readonly thistype next
readonly thistype prev
boolexpr eval
real data1
real data2
real data3
real data4
real data5
real data6
real data7
real data8
integer sinstance
integer myherd
static method allocate takes nothing returns thistype
local thistype this = HEAD.recycle
if this == 0 then
set total = total+1
set this = total
else
set HEAD.recycle = this.recycle
endif
return this
endmethod
method deallocate takes nothing returns nothing
set .recycle = HEAD.recycle
set HEAD.recycle = this
endmethod
static method createHead takes boolexpr b,herdtype h returns thistype
local thistype this = allocate()
set .eval = b
set .next = this
set .prev = this
return this
endmethod
method addNode takes boolexpr b returns nothing
local thistype head = this
set this = allocate()
set .eval = b
set .next = head
set .prev = head.prev
set .prev.next = this
set head.prev = this
endmethod
endstruct
struct behavior extends array
private thistype recycle
private static integer total = 0
private static thistype HEAD = 0
//private static force EVAL = bj_FORCE_PLAYER[0]
static force EVAL
readonly thistype next
readonly thistype prev
boolexpr eval
real data1
real data2
real data3
real data4
real data5
real data6
real data7
real data8
integer sinstance
integer myherd
boolean running
boolean initialized
static method allocate takes nothing returns thistype
local thistype this = HEAD.recycle
if this == 0 then
set total = total+1
set this = total
else
set HEAD.recycle = this.recycle
endif
return this
endmethod
method deallocate takes nothing returns nothing
set .recycle = HEAD.recycle
set .next.prev = .prev
set .prev.next = .next
set initialized = false
set HEAD.recycle = this
endmethod
static method createHead takes BEHAVIOR b,herd h returns thistype
local thistype this = allocate()
set .eval = b.eval
set .next = this
set .prev = this
set data1 = b.data1
set data2 = b.data2
set data3 = b.data3
set data4 = b.data4
set data5 = b.data5
set data6 = b.data6
set data7 = b.data7
set data8 = b.data8
set running = false
set myherd = h
set sinstance = 0
return this
endmethod
method addNode takes BEHAVIOR b,herd h returns nothing
local thistype head = this
set this = allocate()
set .eval = b.eval
set .next = head
set .prev = head.prev
set .prev.next = this
set head.prev = this
set data1 = b.data1
set data2 = b.data2
set data3 = b.data3
set data4 = b.data4
set data5 = b.data5
set data6 = b.data6
set data7 = b.data7
set data8 = b.data8
set running = false
set myherd = h
set sinstance = 0
endmethod
method operator[]= takes integer i, real data returns nothing
if i > 4 then
if i > 6 then
if i == 7 then
set data7 = data
else
set data8 = data
endif
else
if i == 5 then
set data5 = data
else
set data6 = data
endif
endif
else
if i > 2 then
if i == 3 then
set data3 = data
else
set data4 = data
endif
else
if i == 2 then
set data2 = data
else
set data1 = data
endif
endif
endif
endmethod
method operator[] takes integer i returns real
if i > 4 then
if i > 6 then
if i == 7 then
return data7
else
return data8
endif
else
if i == 5 then
return data5
else
return data6
endif
endif
else
if i > 2 then
if i == 3 then
return data3
else
return data4
endif
else
if i == 2 then
return data2
else
return data1
endif
endif
endif
call BJDebugMsg("INDEX OUT OF RANGE")
return -200000000.0000
endmethod
method run takes boolean end returns integer
set END_IT = end
set EVAL_BEHAVIOR = this
//call DisplayTextToPlayer(Player(0),0,0,"RunningBehavior "+I2S(this))
call ForceEnumPlayersCounted(EVAL, eval, 1)
//call ForceEnumPlayersCounted(EVAL, Filter(function roam.main), 1)
return RETURN
endmethod
method stop takes nothing returns nothing
set running = false
set data1 = 0
set data2 = 0
set data3 = 0
set data4 = 0
set data5 = 0
set data6 = 0
set data7 = 0
set data8 = 0
set sinstance = 0
endmethod
endstruct
//struct behaviorN extends behavior
//private integer some
//endstruct
module BehaviorTopOfCode
local herd h =EVAL_BEHAVIOR.myherd
local member this = h.leader
local member leader = this
local unit u = this.data
local boolean allowexit = true
endmodule
module ForLeader
set u = this.data
endmodule
module EndForLeader
set this = h.cycleNext(this)
endmodule
module BehaviorForMemberInHerd
set h.tx = 0
set h.ty = 0
set u = this.data
loop
if this.refresh() then
endmodule
module BehaviorForDead
else
set allowexit = not (this == h.leader and this.next != this)
call h.removeMember(this)
endmodule
module BehaviorEndForMember
endif
set this = h.cycleNext(this)
exitwhen this == leader and allowexit
set allowexit = true
set u = this.data
endloop
set u = null
call h.calculateXYPos()
endmodule
function GetEvalBehavior takes nothing returns behavior
return EVAL_BEHAVIOR
endfunction
function GetShouldEnd takes nothing returns boolean
return END_IT
endfunction
function ReturnWhat takes integer returnwhat returns nothing
set RETURN = returnwhat
endfunction
endlibrarya
JASS:
library HERD
globals
real HERD_EVENT = 0.00
constant real EVENT_HERD_DEATH = 1.00
herd TRIGGER_HERD
//constant real EVENT_HERD_UNIT_DIES = 2.00
//constant real EVENT_HERD_ATTACKED = 4.00
constant real EVENT_HERD_FAILED_BEHAVIOR = 3.00
behavior TRIGGER_BEHAVIOR
endglobals
native UnitAlive takes unit u returns boolean
struct herdtype extends array
private thistype recycle
private static integer total = 0
private static thistype HEAD = 0
BEHAVIOR head
integer bcount
integer unitId
integer redMin
integer redMax
integer blueMin
integer blueMax
integer greenMin
integer greenMax
integer alphaMin
integer alphaMax
real sizeMin
real sizeMax
boolean destroyWhenNoHerds
integer currentInstances
integer maxMembers
method AddBehavior takes boolexpr b returns integer
call head.addNode(b)
set bcount = bcount+1
return bcount
endmethod
static method allocate takes nothing returns thistype
local thistype this = HEAD.recycle
if this == 0 then
set total = total+1
set this = total
else
set HEAD.recycle = this.recycle
endif
return this
endmethod
method deallocate takes nothing returns nothing
//set .next.prev = .prev
//sset .prev.next = .next
set .recycle = HEAD.recycle
set HEAD.recycle = this
endmethod
static method create takes boolexpr initial, integer unitId,boolean destroyed returns thistype
local thistype this = allocate()
set head = BEHAVIOR.createHead(initial,this)
set .unitId = unitId
set destroyWhenNoHerds = destroyed
set redMin = 255
set redMax = 255
set blueMin = 255
set blueMax = 255
set greenMin = 255
set greenMax = 255
set alphaMin = 255
set alphaMax = 255
set sizeMin = 1
set sizeMax= 1
return this
endmethod
method destroy takes nothing returns nothing
loop
exitwhen .head.next == .head
call .head.deallocate()
set .head = .head.next
endloop
call .head.deallocate()
call deallocate()
endmethod
method removeHerd takes nothing returns boolean
set .currentInstances = .currentInstances-1
if destroyWhenNoHerds and .currentInstances<=0 then
call destroy()
return false
endif
return true
endmethod
method addHerd takes nothing returns integer
set currentInstances = currentInstances+1
return currentInstances
endmethod
endstruct
struct member extends array
private thistype recycle
private static integer total = 0
private static thistype HEAD = 0
private static integer TICKSTOAGE = R2I(120/.0325)
readonly thistype next
readonly thistype prev
readonly unit data
integer r
integer b
integer g
integer alph
real size
integer tick
integer age
real x
real y
static method allocate takes nothing returns thistype
local thistype this = HEAD.recycle
if this == 0 then
set total = total+1
set this = total
else
set HEAD.recycle = this.recycle
endif
return this
endmethod
static method createHead takes unit u returns thistype
local thistype this = allocate()
set .next = this
set .prev = this
set .data = u
return this
endmethod
method addNode takes unit u returns thistype
local thistype head = this
set this = thistype.allocate()
set .data = u
set .next = head
set .prev = head.prev
set .prev.next = this
set head.prev = this
return this
endmethod
method deallocate takes nothing returns nothing
set .next.prev = .prev
set .prev.next = .next
set .recycle = HEAD.recycle
set HEAD.recycle = this
endmethod
method destroy takes nothing returns nothing
call .deallocate()
set b = 0
set r = 0
set g = 0
set alph = 0
set size = 0
set data = null
endmethod
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
set .b = blue
set .r = red
set .g = green
set .alph = alpha
call SetUnitVertexColor(.data,red,green,blue,alpha)
endmethod
method setScale takes real scale returns nothing
set .size = scale
call SetUnitScale(.data,scale,scale,scale)
endmethod
method refresh takes nothing returns boolean
if not UnitAlive(data) then
return false
endif
set tick = tick+1
if tick ==TICKSTOAGE then
set age = age+1
set tick = 0
endif
return true
endmethod
endstruct
struct herd extends array
private thistype next
private thistype prev
private thistype recycle
private static integer total = 0
private static thistype HEAD = 0
private static timer TIMER = CreateTimer()
private static real PERODIC = 2.0
private static integer MAX_WAITS = R2I(1200/PERODIC)
readonly herdtype htype
private behavior head
behavior current
integer waits
readonly member leader
readonly integer flockSize
real cx
real cy
real x
real y
real tx
real ty
private static method allocate takes nothing returns thistype
local thistype this = HEAD.recycle
if this == 0 then
set total = total+1
set this = total
else
set HEAD.recycle = .recycle
endif
set .next = HEAD.next
set .prev = HEAD
set .next.prev = this
set HEAD.next = this
return this
endmethod
private method deallocate takes nothing returns nothing
set .next.prev = .prev
set .prev.next = .next
set .recycle = HEAD.recycle
set HEAD.recycle = this
endmethod
method destroy takes nothing returns nothing
call deallocate()
loop
exitwhen leader.next == leader
call leader.destroy()
set leader = leader.next
endloop
call leader.destroy()
call htype.removeHerd()
endmethod
method addMember takes unit whichu returns member
local member u = leader.addNode(whichu)
call u.setColor(GetRandomInt(htype.redMin,htype.redMax),GetRandomInt(htype.greenMin,htype.greenMax),GetRandomInt(htype.blueMin,htype.blueMax),GetRandomInt(htype.alphaMin,htype.alphaMax))
call u.setScale(GetRandomReal(htype.sizeMin,htype.sizeMax))
set flockSize = flockSize+1
return u
endmethod
method removeMember takes member whichone returns nothing
set flockSize = flockSize-1
if whichone == .leader then
set .leader = whichone.next
endif
call whichone.destroy()
endmethod
method GetType takes nothing returns herdtype
return .htype
endmethod
method GetHerdX takes nothing returns real
return x
endmethod
method GetHerdY takes nothing returns real
return y
endmethod
method calculateXYPos takes nothing returns nothing
set x = tx/I2R(flockSize)
set y = ty/I2R(flockSize)
endmethod
method cycleNext takes member u returns member
set u = u.next
set u.x = GetUnitX(u.data)
set u.y = GetUnitY(u.data)
set tx = tx+u.x
set ty = ty+u.y
return u
endmethod
static method perodic takes nothing returns nothing
local thistype this = HEAD.next
local integer return_code
local boolean moveon
//call DisplayTextToPlayer(Player(0),0,0,"PERODIC RUNNING")
if this != 0 then
loop
set moveon = waits>=MAX_WAITS
set return_code = current.run(moveon)
if return_code == 3 then
set current = current.next
set waits = 0
else
if return_code == 5 then
set TRIGGER_HERD = this
set TRIGGER_BEHAVIOR = current
set HERD_EVENT =EVENT_HERD_FAILED_BEHAVIOR
set HERD_EVENT = 0
endif
set waits = waits + return_code
endif
if flockSize < 1 then
set TRIGGER_HERD = this
set HERD_EVENT = EVENT_HERD_DEATH
set HERD_EVENT = 0
call this.destroy()
endif
set this = this.next
exitwhen HEAD == this
endloop
call TimerStart(TIMER,PERODIC,false,function thistype.perodic)
endif
endmethod
static method create takes herdtype herdId, player pid,real x, real y,integer tostart returns thistype
local thistype this
local integer i = 0
local integer unitId = herdId.unitId
local behavior cur
local BEHAVIOR bc
local BEHAVIOR bh
//call DisplayTextToPlayer(Player(0),0,0,"allocating")
set this = allocate()
set htype = herdId
set .cx =x
set .cy = y
//call DisplayTextToPlayer(Player(0),0,0,"CreatingLeader")
set leader = member.createHead(CreateUnit(pid,unitId,x,y,GetRandomReal(0,360)))
call leader.setColor(GetRandomInt(htype.redMin,htype.redMax),GetRandomInt(htype.greenMin,htype.greenMax),GetRandomInt(htype.blueMin,htype.blueMax),GetRandomInt(htype.alphaMin,htype.alphaMax))
call leader.setScale(htype.sizeMax)
//call DisplayTextToPlayer(Player(0),0,0,"CreatingUnits")
loop
exitwhen i >= tostart
set i = i+1
call addMember(CreateUnit(pid,unitId,GetRandomReal(0,120)+x,GetRandomReal(0,120)+y,GetRandomReal(0,360)))
endloop
set bh = herdId.head
//call DisplayTextToPlayer(Player(0),0,0,"BEHAVIOR ="+I2S(bh))
set bc = bh.next
set .head = behavior.createHead(bh,this)
set .current = .head
//call DisplayTextToPlayer(Player(0),0,0,".head ="+I2S(.head))
set cur=head
loop
exitwhen bc == bh
call DisplayTextToPlayer(Player(0),0,0,"ADDING BEHAVIORS")
call head.addNode(bc,this)
set bc = bc.next
endloop
if HEAD.prev == this then
call TimerStart(TIMER,PERODIC,false,function thistype.perodic)
endif
return this
endmethod
endstruct
function TriggerRegisterHerdEvent takes trigger t, real herdevent returns event
return TriggerRegisterVariableEvent( t, "HERD_HERD_EVENT", EQUAL, herdevent )
endfunction
//module ForHerdHeader
//endmodule
//module ForEnumHerd
//loop
//endmodule
//module EndForEnumHerd
//endloop
//endmodule
endlibrary
JASS:
library Example initializer init
globals
public BEHAVIOR ROAM
public BEHAVIOR BREED
public BEHAVIOR STAND
public herdtype ZOMBIES
public herdtype FEL_STALKER
public herdtype FEL_BEAST
public herdtype SHEEP
public real MIN_X =GetRectMinX(bj_mapInitialPlayableArea)
public real MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea)
public real MIN_Y = GetRectMinY(bj_mapInitialPlayableArea)
public real MAX_X = GetRectMaxX(bj_mapInitialPlayableArea)
private constant integer CONTINUE = 3
private constant integer FAIL = 5
private constant integer WAIT = 1
constant integer ORDER_MOVE = 851986
endglobals
struct roam extends array
static method main takes nothing returns boolean
local behavior b = GetEvalBehavior()
local real x
local real y
local real d
local real angle
implement BehaviorTopOfCode
//call DisplayTextToPlayer(Player(0),0,0,"RunningRoam")
if Behaviors_END_IT then
set b.running = false
set Behaviors_RETURN = CONTINUE
else
if not b.initialized then
//call DisplayTextToPlayer(Player(0),0,0,"Initializing")
set b.data7= SquareRoot((b.data1)*(b.data1)+(b.data2)*(b.data2))
set b.data5 = h.cx - b.data1
if b.data5 < MIN_X then
set b.data5 = MIN_X+500
endif
set b.data6 = h.cy-b.data2
if b.data6 < MIN_Y then
set b.data6 = MIN_Y+500
endif
set b.data1 = h.cx + b.data1
if b.data1 > MAX_X then
set b.data1 = MAX_X-500
endif
set b.data2 = h.cy+b.data2
if b.data2 > MAX_Y then
set b.data2 = MAX_Y+500
endif
set b.initialized = false
endif
//call DisplayTextToPlayer(Player(0),0,0,"RunningRoam not End_IT")
if not b.running then
//call DisplayTextToPlayer(Player(0),0,0,"b.running")
set b.running = true
//loop
//set b.data3 = GetRandomReal(b.data5,b.data1)
//set b.data4 = GetRandomReal(b.data6,b.data2)
set x = h.x-h.cx
set y = h.y-h.cy
//call DisplayTextToPlayer(Player(0),0,0,"DoinAtan")
set angle =Atan2(y,x)+6.28318+GetRandomReal(-3.14159,3.14159)
//call DisplayTextToPlayer(Player(0),0,0,"Calculating D")
set d = SquareRoot((y)*(y)+(x)*(x))
//call DisplayTextToPlayer(Player(0),0,0,"GettingRandomValue")
//call DisplayTextToPlayer(Player(0),0,0,R2S(b.data7))
set d = GetRandomReal(b.data7/(d+.01)-400,b.data7)
//call DisplayTextToPlayer(Player(0),0,0,"GotRandomValue")
set x = Cos(angle)*d+h.cx
set y = Sin(angle)*d+h.cy
if x > b.data1 then
set x = b.data1
elseif x<b.data5 then
set x = b.data5
endif
if y > b.data2 then
set y = b.data2
elseif y<b.data6 then
set y = b.data6
endif
set b.data3 = x
set b.data4 = y
//call DisplayTextToPlayer(Player(0),0,0,R2S(x))
//exitwhen (b.data3-h.x)*(b.data3-h.x) > 1440000 or (b.data4-h.y)*(b.data4-h.y) > 1440000
//endloop
else
if (b.data3-h.x)*(b.data3-h.x) < 360000 or (b.data4-h.y)*(b.data4-h.y) < 360000 then
set b.running = false
set Behaviors_RETURN = CONTINUE
return false
endif
endif
set x = b.data3
set y = b.data4
//call DisplayTextToPlayer(Player(0),0,0,"targetX ="+R2S(b.data3))
implement BehaviorForMemberInHerd
//call KillUnit(u)
if (GetUnitCurrentOrder(u) != ORDER_MOVE) then
//call DisplayTextToPlayer(Player(0),0,0,"IssuedOrder"+I2S(OrderId("move")))
call IssuePointOrderById(u,ORDER_MOVE,GetRandomReal(x-500,x+500),GetRandomReal(y-500,y+500))
//call IssuePointOrder(u,"move",GetRandomReal(x-500,x+500),GetRandomReal(y-500,y+500))
endif
implement BehaviorForDead
implement BehaviorEndForMember
endif
set Behaviors_RETURN = WAIT
return true
endmethod
endstruct
private function init takes nothing returns nothing
local herd this
set behavior.EVAL = CreateForce()
set MIN_X =GetRectMinX(bj_mapInitialPlayableArea)
set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea)
set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea)
set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea)
//call DisplayTextToPlayer(Player(0),0,0,"CreatingHtypeZomb")
set ZOMBIES = herdtype.create(Filter(function roam.main), 'nzom',false)
set ZOMBIES.head.data1 = 8000
set ZOMBIES.head.data2 = 8000
set ZOMBIES.head.data7 = 10000
set ZOMBIES.alphaMin = 50
set ZOMBIES.alphaMax = 103
//call DisplayTextToPlayer(Player(0),0,0,"CreatingHerd")
set this = herd.create(ZOMBIES, Player(0),0,0,12)
//call DisplayTextToPlayer(Player(0),0,0,"HerdCreated")
set FEL_STALKER = herdtype.create(Filter(function roam.main),'nfel',false)
set FEL_STALKER.head.data1 = 10000
set FEL_STALKER.head.data2 = 10000
set FEL_STALKER.sizeMin =.7
set FEL_STALKER.greenMin =120
set FEL_STALKER.blueMin =120
//set this = herd.create(FEL_STALKER,Player(1),3000,0,15)
set FEL_BEAST = herdtype.create(Filter(function roam.main),'npfl',false)
set FEL_BEAST.head.data1 = 8000
set FEL_BEAST.head.data2 = 8000
set FEL_BEAST.sizeMin = 1.2
set FEL_BEAST.sizeMax = 1.5
set FEL_BEAST.alphaMin = 200
set FEL_BEAST.blueMin = 100
//set this = herd.create(FEL_BEAST,Player(2),-3000,0,14)
endfunction
endlibrary
Last edited: