Mercurial > wow > breuesk
view State.lua @ 78:5b507f4125d4
Finalized bid handling
author | John@Yosemite-PC |
---|---|
date | Thu, 12 Apr 2012 22:19:15 -0400 |
parents | 39be9328acd0 |
children | 7b8fcea357d2 |
line wrap: on
line source
local bsk=bsk local _G=_G local table=table local pairs=pairs local setmetatable=setmetatable local ipairs=ipairs local string=string local sformat=string.format local tostring=tostring local type=type local unpack=unpack local getn=getn setfenv(1,bsk) -- simple state machine --Begin loot --Activate list ... only during looting? --open bidding/rolling --bid/roll occurred --remove bid/roll --close bidding --remove item -- we'll track state, but that may or may not result in a GUI change until down -- the road -- todo: transmit this all to only the raid, not the guild? -- sample procedure -- person B opens GUI. -- person A begins looting, sets a list -- person A begins bidding, transmists the state -- person B goes into bidding state, their button activates -- person B clicks the button. button changes state. -- person B broadcasts their bid. if a bid, everyone just accepts it. -- - if a roll, then the master does the roll and rebroadcasts state = "neutral" -- states that are possible: neutral, looting, bidding local looting = false stateactive = nil stateitem = nil stateitemlist = {} statebids = {} staterolls = {} staterollvalues = {} stateactivelist = nil -- todo: protect initiators to admin only local rollListeners = {} function RegisterListenerRolls(listener) table.insert(rollListeners,listener) end function AlertRollListeners() for i,v in pairs(rollListeners) do print("roll out") v["RollEvent"](v) end end local listChangeListeners = {} function RegisterListenerActiveListChanged(listener) table.insert(listChangeListeners,listener) end function AlertActiveListChangedListeners() for i,v in pairs(listChangeListeners) do print("list out") v["ActiveListEvent"](v) end end local stateChangeListeners = {} function RegisterListenerStateChange(listener) table.insert(stateChangeListeners,listener) end function AlertStateChangeListeners() for i,v in pairs(stateChangeListeners) do print("state out") v["StateEvent"](v) end end local itemListListeners = {} function RegisterItemListListener(listener) table.insert(itemListListeners,listener) end function AlertItemListListeners() for i,v in pairs(itemListListeners) do print("item change") v["ItemListEvent"](v) end end function BeginLoot(packet) local items, listValue = unpack(packet) if state == "neutral" then state = "looting" stateactivelist = listValue stateitemlist = items AlertItemListListeners() CreateGUI() -- todo: bad spot, but that's ok for now else _G.error("Bad state transition", state, "looting") end end function InitiateBeginLoot(items,listValue) if state == "neutral" then Comm:SendStateChange("BL",items,listValue) end end -- Activate List {{{ function ActivateList(packet) -- doesn't cause a transition, but we only enforce a list selection during certain times local list = unpack(packet) if state == "looting" then stateactivelist = list AlertActiveListChangedListeners() end end function InitiateActivateList(list) if state == "looting" then Comm:SendStateChange("AL",list) end end --}}} -- Open Bidding {{{ function OpenBid(packet) local item = unpack(packet) if state == "looting" then state = "bidding" stateitem = item AlertStateChangeListeners() end end function InitiateOpenBid(item) if state == "looting" then Comm:SendStateChange("OB",item) end end --}}} -- Bid {{{ local function SortByList(lref,unordered) local t = {} for le in lref:OrderedListEntryIter() do local lid = le:GetId() for i,v in pairs(unordered) do if v.value == lid then print("Sort time: insert", lid) table.insert(t,v) table.remove(unordered,i) break -- done with this inner iteration end end end if getn(t) > 0 then for i,v in pairs(unordered) do printf("Disregarding bid/roll from %s because they are not on the list", v.textPlain) end end return t end function ReceivedBid(packet) -- no state transition, but only matters during one state local person, roll = unpack(packet) if state == "bidding" then local lref = LootLists:Select(stateactivelist) if roll then table.insert(statebids,person) -- todo: keep sorted else table.insert(statebids,person) -- todo: statebids = SortByList(lref,statebids) end AlertRollListeners() end -- else ignore ... end function InitiateBid(person,roll) if state == "bidding" then if not person then print("You cannot bid becuase you are not on the list") return end for i,v in pairs(statebids) do if person and person.value == v.value then print(person.value .. " is already on the list") return -- no double adds please end end Comm:SendStateChange("RB",person,roll) end end --}}} -- Retration {{{ function ReceivedRetraction(packet) local person = unpack(packet) if state == "bidding" then for i,v in pairs(statebids) do if v.value == person.value then table.remove(statebids,i) AlertRollListeners() return end end end end function InitiateRetract(person) if state == "bidding" then Comm:SendStateChange("RR",person,roll) end end --}}} -- Close Bidding {{{ function CloseBidding(packet) local awardedTo = unpack(packet) if state == "bidding" then state = "looting" AlertStateChangeListeners() -- todo: remove the item from the window, record history end end function InitiateCloseBidding(awardedTo) if state == "bidding" then Comm:SendStateChange("CB",awardedTo) end end --}}} -- Close Looting {{{ function CloseLooting(packet) state = "neutral" stateactive = nil stateitem = nil stateitemlist = {} statebids = {} staterolls = {} staterollvalues = {} AlertStateChangeListeners() AlertItemListListeners() end function InitiateCloseLooting() Comm:SendStateChange("CL") end --}}} function DispatchState(packet) local state = table.remove(packet,1) print("Dispatching", state) if state == "RB" then ReceivedBid(packet) elseif state == "BL" then BeginLoot(packet) elseif state == "RR" then ReceivedRetraction(packet) elseif state == "OB" then OpenBid(packet) elseif state == "CB" then CloseBidding(packet) elseif state == "CL" then CloseLooting(packet) elseif state == "AL" then ActivateList(packet) else -- todo ... end end function InitializeState() local ltemp = 0 local lids = LootLists:GetAllIds() for _,v in pairs(lids) do local l = LootLists:Select(v) if l:GetLength() > 0 then if ltemp == 0 then ltemp = l:GetId() end end end stateactivelist = ltemp end