annotate State.lua @ 79:7b8fcea357d2

Rolls are active
author John@Yosemite-PC
date Thu, 12 Apr 2012 23:50:56 -0400
parents 5b507f4125d4
children 40c882db34f8
rev   line source
John@71 1 local bsk=bsk
John@71 2 local _G=_G
John@71 3 local table=table
John@71 4 local pairs=pairs
John@71 5 local setmetatable=setmetatable
John@71 6 local ipairs=ipairs
John@71 7 local string=string
John@71 8 local sformat=string.format
John@71 9 local tostring=tostring
John@71 10 local type=type
John@71 11 local unpack=unpack
John@71 12 local getn=getn
John@71 13 setfenv(1,bsk)
John@71 14
John@71 15 -- simple state machine
John@71 16
John@71 17 --Begin loot
John@71 18 --Activate list ... only during looting?
John@71 19 --open bidding/rolling
John@71 20 --bid/roll occurred
John@71 21 --remove bid/roll
John@71 22 --close bidding
John@71 23 --remove item
John@71 24
John@71 25
John@71 26 -- we'll track state, but that may or may not result in a GUI change until down
John@71 27 -- the road
John@71 28
John@71 29 -- todo: transmit this all to only the raid, not the guild?
John@71 30
John@71 31 -- sample procedure
John@71 32 -- person B opens GUI.
John@71 33 -- person A begins looting, sets a list
John@71 34 -- person A begins bidding, transmists the state
John@71 35 -- person B goes into bidding state, their button activates
John@71 36 -- person B clicks the button. button changes state.
John@71 37 -- person B broadcasts their bid. if a bid, everyone just accepts it.
John@71 38 -- - if a roll, then the master does the roll and rebroadcasts
John@71 39
John@72 40 state = "neutral" -- states that are possible: neutral, looting, bidding
John@71 41 local looting = false
John@71 42 stateactive = nil
John@71 43 stateitem = nil
John@73 44 stateitemlist = {}
John@71 45 statebids = {}
John@71 46 staterolls = {}
John@78 47 staterollvalues = {}
John@73 48 stateactivelist = nil
John@71 49
John@76 50 -- todo: protect initiators to admin only
John@76 51
John@71 52 local rollListeners = {}
John@71 53 function RegisterListenerRolls(listener)
John@71 54 table.insert(rollListeners,listener)
John@71 55 end
John@71 56 function AlertRollListeners()
John@71 57 for i,v in pairs(rollListeners) do
John@71 58 print("roll out")
John@71 59 v["RollEvent"](v)
John@71 60 end
John@71 61 end
John@71 62
John@72 63 local listChangeListeners = {}
John@72 64 function RegisterListenerActiveListChanged(listener)
John@72 65 table.insert(listChangeListeners,listener)
John@72 66 end
John@72 67 function AlertActiveListChangedListeners()
John@72 68 for i,v in pairs(listChangeListeners) do
John@72 69 print("list out")
John@72 70 v["ActiveListEvent"](v)
John@72 71 end
John@72 72 end
John@72 73
John@72 74 local stateChangeListeners = {}
John@72 75 function RegisterListenerStateChange(listener)
John@72 76 table.insert(stateChangeListeners,listener)
John@72 77 end
John@72 78 function AlertStateChangeListeners()
John@72 79 for i,v in pairs(stateChangeListeners) do
John@72 80 print("state out")
John@72 81 v["StateEvent"](v)
John@72 82 end
John@72 83 end
John@72 84
John@73 85 local itemListListeners = {}
John@73 86 function RegisterItemListListener(listener)
John@73 87 table.insert(itemListListeners,listener)
John@73 88 end
John@73 89 function AlertItemListListeners()
John@73 90 for i,v in pairs(itemListListeners) do
John@73 91 print("item change")
John@73 92 v["ItemListEvent"](v)
John@73 93 end
John@73 94 end
John@73 95
John@73 96 function BeginLoot(packet)
John@73 97 local items, listValue = unpack(packet)
John@71 98 if state == "neutral" then
John@71 99 state = "looting"
John@73 100 stateactivelist = listValue
John@73 101 stateitemlist = items
John@73 102 AlertItemListListeners()
John@73 103 CreateGUI() -- todo: bad spot, but that's ok for now
John@71 104 else
John@71 105 _G.error("Bad state transition", state, "looting")
John@71 106 end
John@71 107 end
John@71 108
John@73 109 function InitiateBeginLoot(items,listValue)
John@73 110 if state == "neutral" then
John@73 111 Comm:SendStateChange("BL",items,listValue)
John@73 112 end
John@73 113 end
John@72 114
John@72 115 -- Activate List {{{
John@72 116 function ActivateList(packet) -- doesn't cause a transition, but we only enforce a list selection during certain times
John@72 117 local list = unpack(packet)
John@71 118 if state == "looting" then
John@72 119 stateactivelist = list
John@72 120 AlertActiveListChangedListeners()
John@71 121 end
John@71 122 end
John@71 123
John@72 124 function InitiateActivateList(list)
John@72 125 if state == "looting" then
John@72 126 Comm:SendStateChange("AL",list)
John@72 127 end
John@72 128 end
John@72 129 --}}}
John@72 130 -- Open Bidding {{{
John@71 131 function OpenBid(packet)
John@71 132 local item = unpack(packet)
John@73 133 if state == "looting" then
John@71 134 state = "bidding"
John@75 135 stateitem = item
John@73 136 AlertStateChangeListeners()
John@73 137 end
John@71 138 end
John@71 139
John@71 140 function InitiateOpenBid(item)
John@73 141 if state == "looting" then
John@73 142 Comm:SendStateChange("OB",item)
John@73 143 end
John@71 144 end
John@72 145 --}}}
John@72 146 -- Bid {{{
John@78 147 local function SortByList(lref,unordered)
John@78 148 local t = {}
John@78 149 for le in lref:OrderedListEntryIter() do
John@78 150 local lid = le:GetId()
John@78 151 for i,v in pairs(unordered) do
John@78 152 if v.value == lid then
John@78 153 print("Sort time: insert", lid)
John@78 154 table.insert(t,v)
John@78 155 table.remove(unordered,i)
John@78 156 break -- done with this inner iteration
John@78 157 end
John@78 158 end
John@78 159 end
John@78 160 if getn(t) > 0 then
John@78 161 for i,v in pairs(unordered) do
John@78 162 printf("Disregarding bid/roll from %s because they are not on the list", v.textPlain)
John@78 163 end
John@78 164 end
John@78 165 return t
John@78 166 end
John@79 167 local function SortByRoll(values,unordered)
John@79 168 local t = {}
John@79 169 for r = 100,1,-1 do -- 100:1
John@79 170 if values[r] then
John@79 171 for i,v in pairs(unordered) do
John@79 172 if v.value == values[r].value then
John@79 173 print("Sort time: insert", v.value, r)
John@79 174 table.insert(t,v)
John@79 175 table.remove(unordered,i)
John@79 176 break
John@79 177 end
John@79 178 end
John@79 179 end
John@79 180 end
John@79 181 if getn(t) > 0 then
John@79 182 for i,v in pairs(unordered) do
John@79 183 printf("Disregarding bid/roll from %s because they are not on the list", v.textPlain)
John@79 184 end
John@79 185 end
John@79 186 return t
John@79 187 end
John@71 188 function ReceivedBid(packet) -- no state transition, but only matters during one state
John@71 189 local person, roll = unpack(packet)
John@71 190
John@71 191 if state == "bidding" then
John@71 192 if roll then
John@79 193 print("RB: ",person.value,roll)
John@79 194 table.insert(staterolls,person)
John@79 195 staterollvalues[roll] = person
John@79 196 staterolls = SortByRoll(staterollvalues,staterolls)
John@78 197 else
John@79 198 local lref = LootLists:Select(stateactivelist)
John@79 199 table.insert(statebids,person)
John@78 200 statebids = SortByList(lref,statebids)
John@71 201 end
John@71 202 AlertRollListeners()
John@71 203 end
John@71 204
John@71 205 -- else ignore ...
John@71 206 end
John@71 207
John@71 208 function InitiateBid(person,roll)
John@71 209 if state == "bidding" then
John@78 210 if not person then
John@78 211 print("You cannot bid becuase you are not on the list")
John@78 212 return
John@78 213 end
John@71 214 for i,v in pairs(statebids) do
John@78 215 if person and person.value == v.value then
John@71 216 print(person.value .. " is already on the list")
John@71 217 return -- no double adds please
John@71 218 end
John@71 219 end
John@79 220 for i,v in pairs(staterolls) do
John@79 221 if person and person.value == v.value then
John@79 222 print(person.value .. " is already on the list")
John@79 223 return -- no double adds please
John@79 224 end
John@79 225 end
John@71 226 Comm:SendStateChange("RB",person,roll)
John@71 227 end
John@71 228 end
John@72 229 --}}}
John@72 230 -- Retration {{{
John@71 231 function ReceivedRetraction(packet)
John@71 232 local person = unpack(packet)
John@71 233 if state == "bidding" then
John@71 234 for i,v in pairs(statebids) do
John@71 235 if v.value == person.value then
John@71 236 table.remove(statebids,i)
John@71 237 AlertRollListeners()
John@71 238 return
John@71 239 end
John@71 240 end
John@79 241 for i,v in pairs(staterolls) do
John@79 242 if v.value == person.value then
John@79 243 table.remove(staterolls,i)
John@79 244 AlertRollListeners()
John@79 245 return
John@79 246 end
John@79 247 end
John@71 248 end
John@71 249 end
John@71 250
John@71 251 function InitiateRetract(person)
John@71 252 if state == "bidding" then
John@71 253 Comm:SendStateChange("RR",person,roll)
John@71 254 end
John@71 255 end
John@72 256 --}}}
John@72 257 -- Close Bidding {{{
John@72 258 function CloseBidding(packet)
John@72 259 local awardedTo = unpack(packet)
John@75 260 if state == "bidding" then
John@75 261 state = "looting"
John@75 262 AlertStateChangeListeners()
John@75 263 -- todo: remove the item from the window, record history
John@75 264 end
John@71 265 end
John@71 266
John@72 267 function InitiateCloseBidding(awardedTo)
John@75 268 if state == "bidding" then
John@75 269 Comm:SendStateChange("CB",awardedTo)
John@75 270 end
John@72 271 end
John@72 272 --}}}
John@73 273 -- Close Looting {{{
John@72 274 function CloseLooting(packet)
John@71 275 state = "neutral"
John@73 276 stateactive = nil
John@73 277 stateitem = nil
John@73 278 stateitemlist = {}
John@73 279 statebids = {}
John@73 280 staterolls = {}
John@78 281 staterollvalues = {}
John@73 282 AlertStateChangeListeners()
John@73 283 AlertItemListListeners()
John@71 284 end
John@72 285
John@72 286 function InitiateCloseLooting()
John@72 287 Comm:SendStateChange("CL")
John@72 288 end
John@73 289 --}}}
John@79 290 function RollRequest(packet)
John@79 291 local person = unpack(packet)
John@79 292
John@79 293 if state == "bidding" and admin then -- todo: admin should be ML
John@79 294 local roll
John@79 295 for i,v in pairs(staterollvalues) do
John@79 296 if v and v.value == person.value then
John@79 297 roll = i
John@79 298 break
John@79 299 end
John@79 300 end
John@79 301 if not roll then -- roll isn't on cache
John@79 302 repeat -- random until you find a good value
John@79 303 roll = _G.random(100)
John@79 304 until staterollvalues[roll] == nil
John@79 305 print("rolling! ", roll)
John@79 306 staterollvalues[roll] = person
John@79 307 end
John@79 308 InitiateBid(person,roll)
John@79 309 end
John@79 310 end
John@79 311 function InitiateRollRequest(person)
John@79 312 if state == "bidding" then
John@79 313 if not person then
John@79 314 print("You cannot bid becuase you are not on the list")
John@79 315 return
John@79 316 end
John@79 317 for i,v in pairs(staterolls) do
John@79 318 if person and person.value == v.value then
John@79 319 print(person.value .. " is already on the list")
John@79 320 return -- no double adds please
John@79 321 end
John@79 322 end
John@79 323 for i,v in pairs(statebids) do
John@79 324 if person and person.value == v.value then
John@79 325 print(person.value .. " is already on the list")
John@79 326 return -- no double adds please
John@79 327 end
John@79 328 end
John@79 329 Comm:SendStateChange("IR",person,roll)
John@79 330 end
John@79 331 end
John@72 332 function DispatchState(packet)
John@72 333 local state = table.remove(packet,1)
John@72 334 print("Dispatching", state)
John@72 335 if state == "RB" then
John@72 336 ReceivedBid(packet)
John@73 337 elseif state == "BL" then
John@73 338 BeginLoot(packet)
John@72 339 elseif state == "RR" then
John@72 340 ReceivedRetraction(packet)
John@72 341 elseif state == "OB" then
John@72 342 OpenBid(packet)
John@72 343 elseif state == "CB" then
John@72 344 CloseBidding(packet)
John@73 345 elseif state == "CL" then
John@72 346 CloseLooting(packet)
John@72 347 elseif state == "AL" then
John@72 348 ActivateList(packet)
John@79 349 elseif state == "IR" then
John@79 350 RollRequest(packet)
John@72 351 else -- todo ...
John@72 352
John@72 353 end
John@72 354 end
John@72 355
John@73 356 function InitializeState()
John@79 357 -- basically, find a value for stateactivelist. it really doesn't matter
John@79 358 -- which one, but I decided on trying to choose one that has entries on it
John@79 359 -- so the whole thing isn't all empty. stateactivelist being anything
John@79 360 -- besides a valid ID could trigger errors
John@73 361 local ltemp = 0
John@73 362 local lids = LootLists:GetAllIds()
John@73 363 for _,v in pairs(lids) do
John@73 364 local l = LootLists:Select(v)
John@73 365 if l:GetLength() > 0 then
John@73 366 if ltemp == 0 then
John@73 367 ltemp = l:GetId()
John@73 368 end
John@73 369 end
John@73 370 end
John@73 371 stateactivelist = ltemp
John@73 372 end
John@73 373