//modified a bit to show only the relevant aspects
//uses Table;TimerUtils;Alloc (Alloc is not essential)
struct fair extends array
static constant integer MAXIMUM_STOCK = 10
static constant real PHASE_TIME = 60
static Table FT
unit u
Table List
Table Stocked
integer id
integer itemCount //items currently on the list
integer itemStocked //items already stocked, stocked is mutually exclusive with listed.
integer phase
timer t
implement Alloc
method destroy takes nothing returns nothing
call this.List.flush()
call this.Stocked.flush()
call FT.remove(GetHandleId(this.u))
call this.deallocate()
endmethod
method registerToList takes integer id, integer stock returns nothing
set this.itemCount = this.itemCount + 1
set this.List[this.itemCount] = id
if stock > 0 then
set this.List[id] = stock
endif
endmethod
method registerMarket takes nothing returns nothing
call this.registerToList(ITEM_TO_ADD,STOCK_CLASS) //1 = 1, 2 = 2-5, could be changed tho
......
endmethod
method registerCaravan takes nothing returns nothing
call this.registerToList(ITEM_TO_ADD,STOCK_CLASS)
.......
endmethod
method rollItem takes nothing returns nothing //gives an item from the list, the listed item will be now stocked and delisted.
local integer count
local integer ran
local integer stock = 0
if this.itemStocked <= MAXIMUM_STOCK then
set count = this.itemCount
set ran = GetRandomInt(1, this.itemCount)
if this.List[this.List[ran]] == 1 then
set stock = 1
elseif this.List[this.List[ran]] >= 2 then
set stock = GetRandomInt(2, 5)
endif
call AddItemToStock(u, this.List[ran], stock, stock)
set this.itemStocked = this.itemStocked + 1
set this.Stocked[this.itemStocked] = this.List[ran]
set this.itemCount = this.itemCount - 1
if ran != count then
set this.List[ran] = this.List[count]
else
call this.List.remove(count)
endif
endif
endmethod
static method periodic takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local integer i = 1
if this.phase == 2 then //phase 2 is restock
set this.phase = 0 //why no loop? don't know
call this.rollItem()
call this.rollItem()
call this.rollItem()
call this.rollItem()
call this.rollItem()
call this.rollItem()
call this.rollItem()
call this.rollItem()
call this.rollItem()
call this.rollItem()
elseif this.phase == 1 then //phase 1 is liquidation of all items
loop
exitwhen this.itemStocked == 0
call RemoveItemFromStock(this.u, this.Stocked[i])
call AddResourceAmount(this.u, GetRandomInt(1,20 + GetRandomInt(3,10))) // just to give some UI info as i used the gold mine ability for markets
call this.registerToList(this.Stocked[i],-1)
set this.itemStocked = this.itemStocked - 1
endloop
call PingMinimap(GetUnitX(this.u), GetUnitY(this.u), 5.)
set this.phase = 2
elseif this.phase <= 0 then
set this.phase = 1
endif
endmethod
static method create takes unit u returns thistype
local thistype this = fair.allocate()
local integer n = GetRandomInt(1,10)
set total = total + 1
set this.u = u
set this.List = Table.create()
set this.Stocked = Table.create()
set this.itemCount = 0
set this.itemStocked = 0
set this.id = total
set this.phase = 2
if GetUnitTypeId(u) == 'MRKT' then
set this.t = NewTimerEx(this)
call this.registerFair()
call TimerStart(this.t, PHASE_TIME, true, function thistype.periodic)
else
call this.registerCaravan()
endif
set FT[GetHandleId(u)] = this
return this
endmethod
endstruct
static method onInit takes nothing returns nothing
set FT = Table.create()
endmethod