Mercurial > wow > breuesk
comparison Lists.lua @ 42:72055fc7e115
A lot of work to reign in namespacing (inspiration: WIM)
author | John@Doomsday |
---|---|
date | Thu, 15 Mar 2012 08:47:41 -0400 |
parents | dc9bfacca238 |
children | 4109683c3172 |
comparison
equal
deleted
inserted
replaced
41:dc9bfacca238 | 42:72055fc7e115 |
---|---|
60 -- * actually, fuck it. I'll give them an unlock command and | 60 -- * actually, fuck it. I'll give them an unlock command and |
61 -- let them screw over their lists :) | 61 -- let them screw over their lists :) |
62 --}}} | 62 --}}} |
63 | 63 |
64 -- there are some dep chains here. for instance, to have a raidIdP value, a | 64 -- there are some dep chains here. for instance, to have a raidIdP value, a |
65 -- person must have a bsk.persons value which leads to a personName2id which | 65 -- person must have a persons value which leads to a personName2id which |
66 -- leads to a raidIdP | 66 -- leads to a raidIdP |
67 | 67 local bsk = bsk |
68 bsk.lists = {} | 68 local _G=_G |
69 bsk.persons = {} | 69 local table=table |
70 | 70 local string=string |
71 bsk.raidNameP = {} -- "name" is present in raid | |
72 bsk.raidIdP = {} -- "id" is present in raid | |
73 bsk.reserveIdP = {} -- "reserve id present" | |
74 local personName2id = {} -- given "name" get that person's id | |
75 | |
76 local tinsert = table.insert | 71 local tinsert = table.insert |
77 local sformat = string.format | 72 local sformat = string.format |
78 local getn = table.getn | 73 local getn = table.getn |
79 | 74 local wipe = wipe |
80 function bsk:SelfDestruct() | 75 local pairs=pairs |
81 bsk.lists = {} | 76 local ipairs=ipairs |
82 bsk.persons = {} | 77 local tonumber=tonumber |
83 bsk.db.profile.persons = {} | 78 local tostring=tostring |
84 bsk.db.profile.changes = {} | 79 local time=time |
85 bsk.db.profile.lists = {} | 80 local date=date |
86 bsk.raidNameP = {} | 81 local math=math |
87 bsk.raidIdP = {} | 82 local type=type |
88 bsk.reserveIdP = {} | 83 local assert=assert |
84 local getmetatable=getmetatable | |
85 local setmetatable=setmetatable | |
86 setfenv(1,bsk) | |
87 | |
88 lists = {} | |
89 persons = {} | |
90 | |
91 raidNameP = {} -- "name" is present in raid | |
92 raidIdP = {} -- "id" is present in raid | |
93 reserveIdP = {} -- "reserve id present" | |
94 local personName2id = {} -- given "name" get that person's id | |
95 | |
96 | |
97 function SelfDestruct() | |
98 lists = {} | |
99 persons = {} | |
100 db.profile.persons = {} | |
101 db.profile.changes = {} | |
102 db.profile.lists = {} | |
103 raidNameP = {} | |
104 raidIdP = {} | |
105 reserveIdP = {} | |
89 personName2id = {} | 106 personName2id = {} |
90 end | 107 end |
91 function bsk:tcopy(to, from) | 108 function tcopy(to, from) |
92 for k,v in pairs(from) do | 109 for k,v in pairs(from) do |
93 if(type(v)=="table") then | 110 if(type(v)=="table") then |
94 to[k] = {} | 111 to[k] = {} |
95 bsk:tcopy(to[k], v); | 112 tcopy(to[k], v); |
96 else | 113 else |
97 to[k] = v; | 114 to[k] = v; |
98 end | 115 end |
99 end | 116 end |
100 end | 117 end |
103 for k, v in pairs(t) do u[k] = v end | 120 for k, v in pairs(t) do u[k] = v end |
104 return setmetatable(u, getmetatable(t)) | 121 return setmetatable(u, getmetatable(t)) |
105 end | 122 end |
106 | 123 |
107 -- Debugging {{{ | 124 -- Debugging {{{ |
108 function bsk:PrettyPrintList(listIndex) | 125 function PrettyPrintList(listIndex) |
109 local list = bsk.lists[listIndex] | 126 local list = lists[listIndex] |
110 bsk:Print("List: " .. list.name .. " (" .. listIndex .. ") - last modified " .. date("%m/%d/%y %H:%M:%S", list.time) .. " (",list.time,")" ) | 127 bsk:Print("List: " .. list.name .. " (" .. listIndex .. ") - last modified " .. date("%m/%d/%y %H:%M:%S", list.time) .. " (",list.time,")" ) |
111 for i = 1,#list do | 128 for i = 1,#list do |
112 bsk:Print(" " .. i .. " - " .. bsk.persons[list[i].id].main) | 129 bsk:Print(" " .. i .. " - " .. persons[list[i].id].main) |
113 end | 130 end |
114 end | 131 end |
115 function bsk:PrettyPrintLists() | 132 function PrettyPrintLists() |
116 for i,_ in pairs(bsk.lists) do | 133 for i,_ in pairs(lists) do |
117 bsk:PrettyPrintList(i) | 134 PrettyPrintList(i) |
118 end | 135 end |
119 end | 136 end |
120 function bsk:PrintLists() | 137 function PrintLists() |
121 bsk:PrintTable(bsk.lists) | 138 PrintTable(lists) |
122 end | 139 end |
123 function bsk:PrintChanges() | 140 function PrintChanges() |
124 bsk:PrintTable(bsk.db.profile.changes) | 141 PrintTable(db.profile.changes) |
125 end | 142 end |
126 function bsk:PrintPersons() | 143 function PrintPersons() |
127 bsk:PrintTable(bsk.persons) | 144 PrintTable(persons) |
128 end | 145 end |
129 function bsk:PrintAPI(object) | 146 function PrintAPI(object) |
130 for i,v in pairs(object) do | 147 for i,v in pairs(object) do |
131 if type(v) == "function" then | 148 if type(v) == "function" then |
132 bsk:Print("function "..i.."()") | 149 bsk:Print("function "..i.."()") |
133 end | 150 end |
134 end | 151 end |
135 end | 152 end |
136 function bsk:PrintTable(table, depth) | 153 function PrintTable(table, depth) |
137 depth = depth or "" | 154 depth = depth or "" |
138 if not table then return end | 155 if not table then return end |
139 if #depth > 3*5 then self:Print(depth.."Recursion too deep - stopping"); return end | 156 if #depth > 3*5 then bsk:Print(depth.."Recursion too deep - stopping"); return end |
140 for i,v in pairs(table) do | 157 for i,v in pairs(table) do |
141 if( type(v) == "string" ) then | 158 if( type(v) == "string" ) then |
142 self:Print(depth .. i .. " - " .. v) | 159 bsk:Print(depth .. i .. " - " .. v) |
143 elseif( type(v) == "number" ) then | 160 elseif( type(v) == "number" ) then |
144 self:Print(depth .. i .. " - " .. tostring(v)) | 161 bsk:Print(depth .. i .. " - " .. tostring(v)) |
145 elseif( type(v) == "table" ) then | 162 elseif( type(v) == "table" ) then |
146 self:Print(depth .. i .." - ") | 163 bsk:Print(depth .. i .." - ") |
147 self:PrintTable(v,depth.." ") | 164 PrintTable(v,depth.." ") |
148 elseif( type(v) == "boolean" ) then | 165 elseif( type(v) == "boolean" ) then |
149 self:Print(depth .. i .. " - " .. tostring(v)) | 166 bsk:Print(depth .. i .. " - " .. tostring(v)) |
150 elseif( type(v) == "function" ) then | 167 elseif( type(v) == "function" ) then |
151 self:Print(depth .. "function " .. i .. "()") | 168 bsk:Print(depth .. "function " .. i .. "()") |
152 else | 169 else |
153 self:Print(depth .. i .. " - not sure how to print type: " .. type(v) ) | 170 bsk:Print(depth .. i .. " - not sure how to print type: " .. type(v) ) |
154 end | 171 end |
155 end | 172 end |
156 end | 173 end |
157 | 174 |
158 function bsk:PrintRaidAndReserve() | 175 function PrintRaidAndReserve() |
159 bsk:Print("RaidNameP") | 176 bsk:Print("RaidNameP") |
160 bsk:PrintTable(bsk.raidNameP) | 177 PrintTable(raidNameP) |
161 bsk:Print("RaidIdP") | 178 bsk:Print("RaidIdP") |
162 bsk:PrintTable(bsk.raidIdP) | 179 PrintTable(raidIdP) |
163 bsk:Print("ReserveP") | 180 bsk:Print("ReserveP") |
164 bsk:PrintTable(bsk.reserveIdP) | 181 PrintTable(reserveIdP) |
165 bsk:Print("personName2id") | 182 bsk:Print("personName2id") |
166 bsk:PrintTable(personName2id) | 183 PrintTable(personName2id) |
167 end | 184 end |
168 --}}} | 185 --}}} |
169 | 186 |
170 function bsk:UpdatePersonsReverse() | 187 function UpdatePersonsReverse() |
171 for i,v in pairs(bsk.persons) do | 188 for i,v in pairs(persons) do |
172 if i ~= "time" then | 189 if i ~= "time" then |
173 personName2id[v.main] = i | 190 personName2id[v.main] = i |
174 end | 191 end |
175 end | 192 end |
176 end | 193 end |
177 | 194 |
178 -- Change processing {{{ | 195 -- Czohange processing {{{ |
179 function bsk:CreateWorkingStateFromChanges(changes) | 196 function CreateWorkingStateFromChanges(changes) |
180 local personsBase = self.db.profile.persons | 197 local personsBase = db.profile.persons |
181 local lists = self.db.profile.lists | 198 local lists = db.profile.lists |
182 | 199 |
183 -- copy the base to the working state | 200 -- copy the base to the working state |
184 wipe(bsk.lists) | 201 wipe(lists) |
185 wipe(bsk.persons) | 202 wipe(persons) |
186 wipe(personName2id) | 203 wipe(personName2id) |
187 | 204 |
188 bsk:tcopy(bsk.lists,lists) | 205 tcopy(lists,lists) |
189 bsk:tcopy(bsk.persons,personsBase) | 206 tcopy(persons,personsBase) |
190 | 207 |
191 -- now just go through the changes list applying each | 208 -- now just go through the changes list applying each |
192 for i,v in ipairs(changes) do | 209 for i,v in ipairs(changes) do |
193 bsk:ProcessChange(v) | 210 ProcessChange(v) |
194 end | 211 end |
195 | 212 |
196 -- update the persons reverse list | 213 -- update the persons reverse list |
197 bsk:UpdatePersonsReverse() | 214 UpdatePersonsReverse() |
198 end | 215 end |
199 | 216 |
200 function bsk:CreateChange(change) | 217 function CreateChange(change) |
201 -- sanity | 218 -- sanity |
202 assert(change) | 219 assert(change) |
203 assert(change.action) | 220 assert(change.action) |
204 assert(change.arg) | 221 assert(change.arg) |
205 | 222 |
206 bsk:StartChange(change) | 223 StartChange(change) |
207 bsk:CommitChange(change) | 224 CommitChange(change) |
208 end | 225 end |
209 | 226 |
210 function bsk:StartChange(change) | 227 function StartChange(change) |
211 local changes = self.db.profile.changes | 228 local changes = db.profile.changes |
212 change.time = time() | 229 change.time = time() |
213 local n = getn(changes) | 230 local n = getn(changes) |
214 if n > 0 then | 231 if n > 0 then |
215 if changes[n].time >= change.time then | 232 if changes[n].time >= change.time then |
216 change.time = changes[n].time + 1 | 233 change.time = changes[n].time + 1 |
217 end | 234 end |
218 end | 235 end |
219 end | 236 end |
220 | 237 |
221 function bsk:CommitChange(change) | 238 function CommitChange(change) |
222 local changes = self.db.profile.changes | 239 local changes = db.profile.changes |
223 tinsert(changes,change) | 240 tinsert(changes,change) |
224 -- TODO: broadcast change | 241 -- TODO: broadcast change |
225 end | 242 end |
226 | 243 |
227 function bsk:ProcessChange(change) | 244 function ProcessChange(change) |
228 if change.action == "AddPerson" then | 245 if change.action == "AddPerson" then |
229 bsk:DoAddPerson(change) | 246 DoAddPerson(change) |
230 elseif change.action == "RenameList" then | 247 elseif change.action == "RenameList" then |
231 bsk:DoRenameList(change) | 248 DoRenameList(change) |
232 elseif change.action == "CreateList" then | 249 elseif change.action == "CreateList" then |
233 bsk:DoCreateList(change) | 250 DoCreateList(change) |
234 elseif change.action == "DeleteList" then | 251 elseif change.action == "DeleteList" then |
235 bsk:DoDeleteList(change) | 252 DoDeleteList(change) |
236 elseif change.action == "AddToListEnd" then | 253 elseif change.action == "AddToListEnd" then |
237 bsk:DoAddPersonToListEnd(change) | 254 DoAddPersonToListEnd(change) |
238 elseif change.action == "AddToListRand" then | 255 elseif change.action == "AddToListRand" then |
239 bsk:DoAddPersonToListRandom(change) | 256 DoAddPersonToListRandom(change) |
240 elseif change.action == "RemovePerson" then | 257 elseif change.action == "RemovePerson" then |
241 bsk:DoRemovePerson(change) | 258 DoRemovePerson(change) |
242 elseif change.action == "RemovePersonFromList" then | 259 elseif change.action == "RemovePersonFromList" then |
243 bsk:DoRemovePersonFromList(change) | 260 DoRemovePersonFromList(change) |
244 elseif change.action == "SuicidePerson" then | 261 elseif change.action == "SuicidePerson" then |
245 bsk:DoSuicidePerson(change) | 262 DoSuicidePerson(change) |
246 else | 263 else |
247 bsk:Print("Unknown message encountered") | 264 bsk:Print("Unknown message encountered") |
248 bsk:PrintTable(change) | 265 PrintTable(change) |
249 assert(false) | 266 assert(false) |
250 end | 267 end |
251 end | 268 end |
252 | 269 |
253 --}}} | 270 --}}} |
271 -- | |
254 -- holy crap long winded {{{ | 272 -- holy crap long winded {{{ |
255 -- timestamp logic: | 273 -- timestamp logic: |
256 -- use time() for comparisons - local clients use date() to make it pretty. only | 274 -- use time() for comparisons - local clients use date() to make it pretty. only |
257 -- dowisde - we can't have a server timestamp. Which kind of sucks, but it turns | 275 -- dowisde - we can't have a server timestamp. Which kind of sucks, but it turns |
258 -- out you can change timezones when you enter an instance server, so you really | 276 -- out you can change timezones when you enter an instance server, so you really |
284 | 302 |
285 -- Action and DoAction defs {{{ | 303 -- Action and DoAction defs {{{ |
286 -- Action Discussion {{{ | 304 -- Action Discussion {{{ |
287 -- The actual actions for changes start here | 305 -- The actual actions for changes start here |
288 -- | 306 -- |
289 -- Each action occurs as a pair of functions. The bsk:Action() function is from | 307 -- Each action occurs as a pair of functions. The Action() function is from |
290 -- a list admin's point of view. Each will check for admin status, then create a | 308 -- a list admin's point of view. Each will check for admin status, then create a |
291 -- change bundle, call the handler for that change (ie the DoAction func), and | 309 -- change bundle, call the handler for that change (ie the DoAction func), and |
292 -- then record/transmist the bundle. These are simple and repetitive functions. | 310 -- then record/transmist the bundle. These are simple and repetitive functions. |
293 -- | 311 -- |
294 -- The bsk:DoAction() function is tasked with executing the bundle and is what | 312 -- The DoAction() function is tasked with executing the bundle and is what |
295 -- non-admins and admins alike will call to transform their working state via a | 313 -- non-admins and admins alike will call to transform their working state via a |
296 -- change packet. Each Do() function will accept *only* a change packet, and | 314 -- change packet. Each Do() function will accept *only* a change packet, and |
297 -- it's assumed that the change has been vetted elsewhere. These are very blunt | 315 -- it's assumed that the change has been vetted elsewhere. These are very blunt |
298 -- routines. | 316 -- routines. |
299 -- | 317 -- |
300 -- Note that "undo" has no special voodoo to it. It's basically a change that | 318 -- Note that "undo" has no special voodoo to it. It's basically a change that |
301 -- reverses the prior change on the stack.--}}} | 319 -- reverses the prior change on the stack.--}}} |
302 function bsk:DoAddPerson(change)--{{{ | 320 function DoAddPerson(change)--{{{ |
303 assert(change) | 321 assert(change) |
304 assert(change.arg.id) | 322 assert(change.arg.id) |
305 -- require admin | 323 -- require admin |
306 local persons = bsk.persons | 324 local persons = persons |
307 local name = change.arg.name | 325 local name = change.arg.name |
308 local id = change.arg.id | 326 local id = change.arg.id |
309 assert(persons[id]==nil) | 327 assert(persons[id]==nil) |
310 persons[id] = {main=name,class=change.arg.class} | 328 persons[id] = {main=name,class=change.arg.class} |
311 persons.time=change.time | 329 persons.time=change.time |
312 personName2id[name] = id | 330 personName2id[name] = id |
313 return true | 331 return true |
314 end--}}} | 332 end--}}} |
315 function bsk:AddPerson(name)--{{{ | 333 function AddPerson(name)--{{{ |
316 local persons = bsk.persons | 334 local persons = persons |
317 local guid = UnitGUID(name) | 335 local guid = _G.UnitGUID(name) |
318 -- TODO: check guid to be sure it's a player | 336 -- TODO: check guid to be sure it's a player |
319 if not guid then | 337 if not guid then |
320 self:Print(sformat("Could not add player %s - they must be in range or group",name)) | 338 bsk:Print(sformat("Could not add player %s - they must be in range or group",name)) |
321 return | 339 return |
322 end | 340 end |
323 local _,englishClass = UnitClass(name) | 341 local _,englishClass = _G.UnitClass(name) |
324 --bsk:Print("Person " .. name .. " is class " .. englishClass) | 342 --bsk:Print("Person " .. name .. " is class " .. englishClass) |
325 local id = string.sub(guid,6) -- skip at least 0x0580 ... | 343 local id = string.sub(guid,6) -- skip at least 0x0580 ... |
326 id = id:gsub("^0*(.*)","%1") -- nom all leading zeroes remaining | 344 id = id:gsub("^0*(.*)","%1") -- nom all leading zeroes remaining |
327 | 345 |
328 if persons[id] and persons[id] ~= name then | 346 if persons[id] and persons[id] ~= name then |
329 self:Print(sformat("Namechange detected for %s - new is %s, please rename the existing entry", persons[id].main, name)) | 347 bsk:Print(sformat("Namechange detected for %s - new is %s, please rename the existing entry", persons[id].main, name)) |
330 return | 348 return |
331 end | 349 end |
332 if persons[id] ~= nil then | 350 if persons[id] ~= nil then |
333 self:Print(sformat("%s is already in the persons list; disregarding", name)) | 351 bsk:Print(sformat("%s is already in the persons list; disregarding", name)) |
334 return | 352 return |
335 end | 353 end |
336 local change = {action="AddPerson",arg={name=name,id=id,class=englishClass}} | 354 local change = {action="AddPerson",arg={name=name,id=id,class=englishClass}} |
337 if bsk:DoAddPerson(change) then | 355 if DoAddPerson(change) then |
338 bsk:CreateChange(change) | 356 CreateChange(change) |
339 end | 357 end |
340 end--}}} | 358 end--}}} |
341 function bsk:DoCreateList(change)--{{{ | 359 function DoCreateList(change)--{{{ |
342 --if bsk:GetListIndex(change.arg.name) then | 360 --if GetListIndex(change.arg.name) then |
343 -- self:Print(sformat("List %s already exists",v.name)) | 361 -- bsk:Print(sformat("List %s already exists",v.name)) |
344 -- return false | 362 -- return false |
345 --end | 363 --end |
346 bsk.lists[change.arg.id]={name=change.arg.name,time=change.time} | 364 lists[change.arg.id]={name=change.arg.name,time=change.time} |
347 return true | 365 return true |
348 end--}}} | 366 end--}}} |
349 function bsk:CreateList(name)--{{{ | 367 function CreateList(name)--{{{ |
350 -- require admin | 368 -- require admin |
351 local change={action="CreateList",arg={name=name}} | 369 local change={action="CreateList",arg={name=name}} |
352 bsk:StartChange(change) | 370 StartChange(change) |
353 change.arg.id=change.time -- use the creation timestamp as the list's index. it's as unique as anything... | 371 change.arg.id=change.time -- use the creation timestamp as the list's index. it's as unique as anything... |
354 self:Print("Creating ... " .. name) | 372 bsk:Print("Creating ... " .. name) |
355 if bsk:DoCreateList(change) then | 373 if DoCreateList(change) then |
356 bsk:CommitChange(change) | 374 CommitChange(change) |
357 end | 375 end |
358 end--}}} | 376 end--}}} |
359 function bsk:DoAddPersonToListEnd(change)--{{{ | 377 function DoAddPersonToListEnd(change)--{{{ |
360 local list = bsk.lists[change.arg.listIndex] | 378 local list = lists[change.arg.listIndex] |
361 local index | 379 local index |
362 if getn(list) > 0 then | 380 if getn(list) > 0 then |
363 index = list[#list].index + 0.1 | 381 index = list[#list].index + 0.1 |
364 else | 382 else |
365 index = 0.1 | 383 index = 0.1 |
370 list.time = change.time | 388 list.time = change.time |
371 list.closedRandom = true | 389 list.closedRandom = true |
372 | 390 |
373 return true | 391 return true |
374 end--}}} | 392 end--}}} |
375 function bsk:AddPersonToListEnd(name,listName)--{{{ | 393 function AddPersonToListEnd(name,listName)--{{{ |
376 -- require admin | 394 -- require admin |
377 local listIndex = bsk:GetListIndex(listName) | 395 local listIndex = GetListIndex(listName) |
378 local id = personName2id[name] | 396 local id = personName2id[name] |
379 if bsk:IdIsInList(id,bsk.lists[listIndex]) then | 397 if IdIsInList(id,lists[listIndex]) then |
380 bsk:Print(sformat("Person %s is already on the reqeuested list",name)) | 398 bsk:Print(sformat("Person %s is already on the reqeuested list",name)) |
381 return false | 399 return false |
382 end | 400 end |
383 bsk:Print(sformat("Adding %s (%s) to list %s (%s)", name, id, listName, listIndex)) | 401 bsk:Print(sformat("Adding %s (%s) to list %s (%s)", name, id, listName, listIndex)) |
384 local change = {action="AddToListEnd",arg={id=id,listIndex=listIndex}} | 402 local change = {action="AddToListEnd",arg={id=id,listIndex=listIndex}} |
385 bsk:StartChange(change) | 403 StartChange(change) |
386 if bsk:DoAddPersonToListEnd(change) then | 404 if DoAddPersonToListEnd(change) then |
387 bsk:CommitChange(change) | 405 CommitChange(change) |
388 end | 406 end |
389 end--}}} | 407 end--}}} |
390 function bsk:DoAddPersonToListRandom(change)--{{{ | 408 function DoAddPersonToListRandom(change)--{{{ |
391 local list = bsk.lists[change.arg.listIndex] | 409 local list = lists[change.arg.listIndex] |
392 local entry = {index=change.arg.roll, id=change.arg.id} | 410 local entry = {index=change.arg.roll, id=change.arg.id} |
393 | 411 |
394 tinsert(list,entry) | 412 tinsert(list,entry) |
395 table.sort(list,function(a,b) return a.index < b.index end) | 413 table.sort(list,function(a,b) return a.index < b.index end) |
396 list.time = change.time | 414 list.time = change.time |
397 | 415 |
398 return true | 416 return true |
399 end--}}} | 417 end--}}} |
400 function bsk:AddPersonToListRandom(name,listName)--{{{ | 418 function AddPersonToListRandom(name,listName)--{{{ |
401 -- require admin | 419 -- require admin |
402 local listIndex = bsk:GetListIndex(listName) | 420 local listIndex = GetListIndex(listName) |
403 if bsk.lists[listIndex].closedRandom then | 421 if lists[listIndex].closedRandom then |
404 self:Print("Cannot add person to list by random roll because an add-to-end operation has already occurred") | 422 bsk:Print("Cannot add person to list by random roll because an add-to-end operation has already occurred") |
405 return false | 423 return false |
406 end | 424 end |
407 local id = personName2id[name] | 425 local id = personName2id[name] |
408 if bsk:IdIsInList(id,bsk.lists[listIndex]) then | 426 if IdIsInList(id,lists[listIndex]) then |
409 bsk:Print(sformat("Person %s is already on the reqeuested list",name)) | 427 bsk:Print(sformat("Person %s is already on the reqeuested list",name)) |
410 return false | 428 return false |
411 end | 429 end |
412 local roll = math.random() | 430 local roll = math.random() |
413 bsk:Print(sformat("Adding %s (%s) to list %s (%s) with roll (%f)", name, id, listName, listIndex, roll)) | 431 bsk:Print(sformat("Adding %s (%s) to list %s (%s) with roll (%f)", name, id, listName, listIndex, roll)) |
414 local change = {action="AddToListRand",arg={id=id,listIndex=listIndex,roll=roll}} | 432 local change = {action="AddToListRand",arg={id=id,listIndex=listIndex,roll=roll}} |
415 bsk:StartChange(change) | 433 StartChange(change) |
416 if bsk:DoAddPersonToListRandom(change) then | 434 if DoAddPersonToListRandom(change) then |
417 bsk:CommitChange(change) | 435 CommitChange(change) |
418 end | 436 end |
419 end--}}} | 437 end--}}} |
420 function bsk:DoRemovePerson(change)--{{{ | 438 function DoRemovePerson(change)--{{{ |
421 local person = bsk.persons[change.arg.id] | 439 local person = persons[change.arg.id] |
422 personName2id[person.main] = nil | 440 personName2id[person.main] = nil |
423 bsk.persons[change.arg.id] = nil | 441 persons[change.arg.id] = nil |
424 bsk.persons.time = change.time | 442 persons.time = change.time |
425 return true | 443 return true |
426 end--}}} | 444 end--}}} |
427 function bsk:RemovePerson(name)--{{{ | 445 function RemovePerson(name)--{{{ |
428 local id = personName2id[name] | 446 local id = personName2id[name] |
429 if not id then | 447 if not id then |
430 bsk:Print(sformat("%s is not in the persons list, please check your spelling", name)) | 448 bsk:Print(sformat("%s is not in the persons list, please check your spelling", name)) |
431 return false | 449 return false |
432 end | 450 end |
433 local listsTheyreOn = {} | 451 local listsTheyreOn = {} |
434 -- check if they're active on any loot list | 452 -- check if they're active on any loot list |
435 for i,v in pairs(bsk.lists) do | 453 for i,v in pairs(lists) do |
436 if bsk:IdIsInList(id,v) then | 454 if IdIsInList(id,v) then |
437 tinsert(listsTheyreOn,v.name) | 455 tinsert(listsTheyreOn,v.name) |
438 break | 456 break |
439 end | 457 end |
440 end | 458 end |
441 if getn(listsTheyreOn) > 0 then | 459 if getn(listsTheyreOn) > 0 then |
442 self:Print(sformat("Cannot remove person %s because they are on one or more lists (%s)",name,table.concat(listsTheyreOn,", "))) | 460 bsk:Print(sformat("Cannot remove person %s because they are on one or more lists (%s)",name,table.concat(listsTheyreOn,", "))) |
443 return false | 461 return false |
444 end | 462 end |
445 local change = {action="RemovePerson",arg={id=id}} | 463 local change = {action="RemovePerson",arg={id=id}} |
446 bsk:StartChange(change) | 464 StartChange(change) |
447 if bsk:DoRemovePerson(change) then | 465 if DoRemovePerson(change) then |
448 bsk:CommitChange(change) | 466 CommitChange(change) |
449 end | 467 end |
450 end--}}} | 468 end--}}} |
451 function bsk:DoSuicidePerson(change)--{{{ | 469 function DoSuicidePerson(change)--{{{ |
452 local list = bsk.lists[change.arg.listIndex] | 470 local list = lists[change.arg.listIndex] |
453 local affected = shallowCopy(change.arg.affect) | 471 local affected = shallowCopy(change.arg.affect) |
454 -- the goal here is to rotate the suicide list by 1 | 472 -- the goal here is to rotate the suicide list by 1 |
455 -- then we can just mash it on top of the intersection between the original | 473 -- then we can just mash it on top of the intersection between the original |
456 -- list and the working copy | 474 -- list and the working copy |
457 | 475 |
458 local replacement = shallowCopy(change.arg.affect) | 476 local replacement = shallowCopy(change.arg.affect) |
459 local temp = table.remove(replacement,1) -- pop | 477 local temp = table.remove(replacement,1) -- pop |
460 tinsert(replacement,temp) -- push_back | 478 tinsert(replacement,temp) -- push_back |
461 --bsk:Print(sformat("Before suicide of %s on list %s",slist[1],list.name)) | 479 --bsk:Print(sformat("Before suicide of %s on list %s",slist[1],list.name)) |
462 --bsk:PrintTable(list) | 480 --PrintTable(list) |
463 for i = 1, #list do | 481 for i = 1, #list do |
464 if list[i].id == affected[1] then | 482 if list[i].id == affected[1] then |
465 table.remove(affected,1) | 483 table.remove(affected,1) |
466 list[i].id = replacement[1] | 484 list[i].id = replacement[1] |
467 table.remove(replacement,1) | 485 table.remove(replacement,1) |
468 end | 486 end |
469 end | 487 end |
470 list.time=change.time | 488 list.time=change.time |
471 return true | 489 return true |
472 end--}}} | 490 end--}}} |
473 function bsk:SuicidePerson(name,listName)--{{{ | 491 function SuicidePerson(name,listName)--{{{ |
474 -- require admin | 492 -- require admin |
475 bsk:PopulateRaidList() | 493 PopulateRaidList() |
476 local listIndex = bsk:GetListIndex(listName) | 494 local listIndex = GetListIndex(listName) |
477 local id = personName2id[name] | 495 local id = personName2id[name] |
478 local affect=bsk:GetSuicideList(id,bsk.lists[listIndex]) | 496 local affect=GetSuicideList(id,lists[listIndex]) |
479 local change = {action="SuicidePerson",arg={affect=affect,listIndex=listIndex}} | 497 local change = {action="SuicidePerson",arg={affect=affect,listIndex=listIndex}} |
480 bsk:StartChange(change) | 498 StartChange(change) |
481 if bsk:DoSuicidePerson(change) then | 499 if DoSuicidePerson(change) then |
482 bsk:CommitChange(change) | 500 CommitChange(change) |
483 end | 501 end |
484 end--}}} | 502 end--}}} |
485 function bsk:DoRenameList(change)--{{{ | 503 function DoRenameList(change)--{{{ |
486 bsk.lists[change.arg.listIndex].name = change.arg.name | 504 lists[change.arg.listIndex].name = change.arg.name |
487 bsk.lists[change.arg.listIndex].time = change.time | 505 lists[change.arg.listIndex].time = change.time |
488 return true | 506 return true |
489 end--}}} | 507 end--}}} |
490 function bsk:RenameList(listName,newListName)--{{{ | 508 function RenameList(listName,newListName)--{{{ |
491 -- require admin | 509 -- require admin |
492 local listIndex = bsk:GetListIndex(listName) | 510 local listIndex = GetListIndex(listName) |
493 local change = {action="RenameList",arg={listIndex=listIndex,name=newListName}} | 511 local change = {action="RenameList",arg={listIndex=listIndex,name=newListName}} |
494 bsk:StartChange(change) | 512 StartChange(change) |
495 if bsk:DoRenameList(change) then | 513 if DoRenameList(change) then |
496 bsk:CommitChange(change) | 514 CommitChange(change) |
497 end | 515 end |
498 end--}}} | 516 end--}}} |
499 function bsk:DoDeleteList(change)--{{{ | 517 function DoDeleteList(change)--{{{ |
500 bsk.lists[change.arg.listIndex] = nil | 518 lists[change.arg.listIndex] = nil |
501 return true | 519 return true |
502 end--}}} | 520 end--}}} |
503 function bsk:DeleteList(listName)--{{{ | 521 function DeleteList(listName)--{{{ |
504 local listIndex = bsk:GetListIndex(listName) | 522 local listIndex = GetListIndex(listName) |
505 local change = {action="DeleteList",arg={listIndex=listIndex}} | 523 local change = {action="DeleteList",arg={listIndex=listIndex}} |
506 bsk:StartChange(change) | 524 StartChange(change) |
507 if bsk:DoDeleteList(change) then | 525 if DoDeleteList(change) then |
508 bsk:CommitChange(change) | 526 CommitChange(change) |
509 end | 527 end |
510 end--}}} | 528 end--}}} |
511 function bsk:DoRemovePersonFromList(change)--{{{ | 529 function DoRemovePersonFromList(change)--{{{ |
512 local list = bsk.lists[change.arg.listIndex] | 530 local list = lists[change.arg.listIndex] |
513 | 531 |
514 for i,v in ipairs(list) do | 532 for i,v in ipairs(list) do |
515 if v.id == change.arg.id then | 533 if v.id == change.arg.id then |
516 table.remove(list,i) | 534 table.remove(list,i) |
517 break | 535 break |
519 end | 537 end |
520 table.sort(list,function(a,b) return a.index < b.index end) | 538 table.sort(list,function(a,b) return a.index < b.index end) |
521 list.time = change.time | 539 list.time = change.time |
522 return true | 540 return true |
523 end--}}} | 541 end--}}} |
524 function bsk:RemovePersonFromList(name,listName)--{{{ | 542 function RemovePersonFromList(name,listName)--{{{ |
525 local listIndex = bsk:GetListIndex(listName) | 543 local listIndex = GetListIndex(listName) |
526 local pid = personName2id[name] | 544 local pid = personName2id[name] |
527 -- todo: check that they're on the list in the first place | 545 -- todo: check that they're on the list in the first place |
528 local change = {action="RemovePersonFromList",arg={id=pid,listIndex=listIndex}} | 546 local change = {action="RemovePersonFromList",arg={id=pid,listIndex=listIndex}} |
529 bsk:StartChange(change) | 547 StartChange(change) |
530 if bsk:DoRemovePersonFromList(change) then | 548 if DoRemovePersonFromList(change) then |
531 bsk:CommitChange(change) | 549 CommitChange(change) |
532 end | 550 end |
533 end | 551 end |
534 --}}} | 552 --}}} |
535 --}}} | 553 --}}} |
536 -- Higher order actions (ie calls other standard actions){{{ | 554 -- Higher order actions (ie calls other standard actions){{{ |
537 | 555 |
538 function bsk:TrimLists(time) | 556 function TrimLists(time) |
539 if not bsk:CheckListCausality() then | 557 if not CheckListCausality() then |
540 self:Print("Unable to trim changelist due to violated causality") | 558 bsk:Print("Unable to trim changelist due to violated causality") |
541 return false | 559 return false |
542 end | 560 end |
543 | 561 |
544 if type(time) ~= "number" then | 562 if type(time) ~= "number" then |
545 time = tonumber(time) | 563 time = tonumber(time) |
546 end | 564 end |
547 | 565 |
548 -- bisect the changes list by "time" | 566 -- bisect the changes list by "time" |
549 local before = {} | 567 local before = {} |
550 for i,v in ipairs(self.db.profile.changes) do | 568 for i,v in ipairs(db.profile.changes) do |
551 if v.time <= time then | 569 if v.time <= time then |
552 tinsert(before,v) | 570 tinsert(before,v) |
553 else | 571 else |
554 break | 572 break |
555 end | 573 end |
556 end | 574 end |
557 | 575 |
558 -- apply first half | 576 -- apply first half |
559 bsk:CreateWorkingStateFromChanges(before) | 577 CreateWorkingStateFromChanges(before) |
560 | 578 |
561 -- save this state permanently; trim the changes permanently | 579 -- save this state permanently; trim the changes permanently |
562 bsk:tcopy(bsk.db.profile.persons,bsk.persons) | 580 tcopy(db.profile.persons,persons) |
563 bsk:tcopy(bsk.db.profile.lists,bsk.lists) | 581 tcopy(db.profile.lists,lists) |
564 while bsk.db.profile.changes ~= nil and bsk.db.profile.changes[1] ~= nil and bsk.db.profile.changes[1].time <= time do | 582 while db.profile.changes ~= nil and db.profile.changes[1] ~= nil and db.profile.changes[1].time <= time do |
565 table.remove(bsk.db.profile.changes,1) | 583 table.remove(db.profile.changes,1) |
566 end | 584 end |
567 | 585 |
568 -- using the trimmed list and the new bases, recreate the working state | 586 -- using the trimmed list and the new bases, recreate the working state |
569 bsk:CreateWorkingStateFromChanges(bsk.db.profile.changes) | 587 CreateWorkingStateFromChanges(db.profile.changes) |
570 end | 588 end |
571 | 589 |
572 function bsk:AddMissingPersons() | 590 function AddMissingPersons() |
573 bsk:PopulateRaidList() | 591 PopulateRaidList() |
574 local t = {} | 592 local t = {} |
575 for id,_ in pairs(bsk.persons) do | 593 for id,_ in pairs(persons) do |
576 t[id] = true | 594 t[id] = true |
577 end | 595 end |
578 for name,_ in pairs(bsk.raidNameP) do | 596 for name,_ in pairs(raidNameP) do |
579 if personName2id[name] == nil then | 597 if personName2id[name] == nil then |
580 bsk:Print(sformat("Person %s is missing from the persons list - adding",name)) | 598 bsk:Print(sformat("Person %s is missing from the persons list - adding",name)) |
581 bsk:AddPerson(name) | 599 AddPerson(name) |
582 end | 600 end |
583 end | 601 end |
584 -- TODO: batch into a single op - no need to spam 25 messages in a row | 602 -- TODO: batch into a single op - no need to spam 25 messages in a row |
585 end | 603 end |
586 | 604 |
587 function bsk:PopulateListRandom(listIndex) | 605 function PopulateListRandom(listIndex) |
588 -- difference (raid+reserve)-list, then random shuffle that, then add | 606 -- difference (raid+reserve)-list, then random shuffle that, then add |
589 bsk:PopulateRaidList() | 607 PopulateRaidList() |
590 local list = bsk.lists[listIndex] | 608 local list = lists[listIndex] |
591 | 609 |
592 local t = {} -- after loops, contains intersection of IDs present between raid and reserve | 610 local t = {} -- after loops, contains intersection of IDs present between raid and reserve |
593 for i,v in pairs(bsk.raidIdP) do | 611 for i,v in pairs(raidIdP) do |
594 if v then t[i] = true end | 612 if v then t[i] = true end |
595 end | 613 end |
596 for i,v in pairs(bsk.reserveIdP) do | 614 for i,v in pairs(reserveIdP) do |
597 if v then t[i] = true end | 615 if v then t[i] = true end |
598 end | 616 end |
599 | 617 |
600 -- now remove from t all of the people already present on the list | 618 -- now remove from t all of the people already present on the list |
601 if list then | 619 if list then |
607 end | 625 end |
608 | 626 |
609 -- add all remaining | 627 -- add all remaining |
610 for i,v in pairs(t) do | 628 for i,v in pairs(t) do |
611 if v then | 629 if v then |
612 bsk:AddPersonToListRandom(bsk.persons[i].main,list.name) -- TODO: APTLR keys off of string names. probably need to change this. | 630 AddPersonToListRandom(persons[i].main,list.name) -- TODO: APTLR keys off of string names. probably need to change this. |
613 end | 631 end |
614 end | 632 end |
615 end | 633 end |
616 | 634 |
617 function bsk:NukePerson(name) -- delete from all lists and then from persons | 635 function NukePerson(name) -- delete from all lists and then from persons |
618 local pid = personName2id[name] | 636 local pid = personName2id[name] |
619 for i,v in pairs(bsk.lists) do | 637 for i,v in pairs(lists) do |
620 bsk:RemovePersonFromList(name,v.name) | 638 RemovePersonFromList(name,v.name) |
621 end | 639 end |
622 bsk:RemovePerson(name) | 640 RemovePerson(name) |
623 end | 641 end |
624 --}}} | 642 --}}} |
625 -- "Soft" actions- ie things that cause nonpermanent state {{{ | 643 -- "Soft" actions- ie things that cause nonpermanent state {{{ |
626 | 644 |
627 -- reserves | 645 -- reserves |
628 function bsk:AddReserve(name) | 646 function AddReserve(name) |
629 bsk.reserveIdP[personName2id[name]]=true | 647 bsk:Print("Reserving" .. name) |
648 reserveIdP[personName2id[name]]=true | |
630 -- TODO: communicate to others. don't store this in any way. | 649 -- TODO: communicate to others. don't store this in any way. |
631 end | 650 end |
632 | 651 |
633 function bsk:RemoveReserve(name) | 652 function RemoveReserve(name) |
634 bsk.reserveIdP[personName2id[name]]=false | 653 reserveIdP[personName2id[name]]=false |
635 -- TODO: communicate to others. don't store this in any way. | 654 -- TODO: communicate to others. don't store this in any way. |
636 end | 655 end |
637 | 656 |
638 | 657 |
639 --function bsk:GetActiveList() | 658 --function GetActiveList() |
640 -- return bsk.lists[1] -- todo! | 659 -- return lists[1] -- todo! |
641 --end | 660 --end |
642 | 661 |
643 --}}} | 662 --}}} |
644 | 663 |
645 -- The following (adapted) code is from Xinhuan (wowace forum member) | 664 -- The following (adapted) code is from Xinhuan (wowace forum member) |
646 -- Pre-create the unitID strings we will use | 665 -- Pre-create the unitID strings we will use |
647 local pID = {} | 666 local pID = {} |
648 local rID = {} | 667 local rID = {} |
649 for i = 1, 4 do | 668 for i = 1, 4 do |
650 pID[i] = format("party%d", i) | 669 pID[i] = sformat("party%d", i) |
651 end | 670 end |
652 for i = 1, 40 do | 671 for i = 1, 40 do |
653 rID[i] = format("raid%d", i) | 672 rID[i] = sformat("raid%d", i) |
654 end | 673 end |
655 function bsk:PopulateRaidList() | 674 function PopulateRaidList() |
656 local inParty = GetNumPartyMembers() | 675 local inParty = _G.GetNumPartyMembers() |
657 local inRaid = GetNumRaidMembers() | 676 local inRaid = _G.GetNumRaidMembers() |
658 local add = function(unitNameArg) | 677 local add = function(unitNameArg) |
659 local name = UnitName(unitNameArg) | 678 local name = _G.UnitName(unitNameArg) |
660 bsk.raidNameP[name]=true | 679 raidNameP[name]=true |
661 if personName2id[name] ~= nil then | 680 if personName2id[name] ~= nil then |
662 bsk.raidIdP[personName2id[name]]=true | 681 raidIdP[personName2id[name]]=true |
663 end | 682 end |
664 end | 683 end |
665 | 684 |
666 wipe(bsk.raidNameP) | 685 wipe(raidNameP) |
667 wipe(bsk.raidIdP) | 686 wipe(raidIdP) |
668 if inRaid > 0 then | 687 if inRaid > 0 then |
669 for i = 1, inRaid do | 688 for i = 1, inRaid do |
670 add(rID[i]) | 689 add(rID[i]) |
671 end | 690 end |
672 elseif inParty > 0 then | 691 elseif inParty > 0 then |
677 add("player") | 696 add("player") |
678 else | 697 else |
679 -- You're alone | 698 -- You're alone |
680 add("player") | 699 add("player") |
681 end | 700 end |
682 --bsk:PrintTable(bsk.raidNameP) | 701 --PrintTable(raidNameP) |
683 end | 702 end |
684 | 703 |
685 -- undo rules! | 704 -- undo rules! |
686 -- only the most recent event can be undone | 705 -- only the most recent event can be undone |
687 -- ^^^ on a given list? | 706 -- ^^^ on a given list? |
689 -- just find A,B,C in the list and replace in order from the s message | 708 -- just find A,B,C in the list and replace in order from the s message |
690 -- while undo is allowed *per-list*, certain events in the stream will | 709 -- while undo is allowed *per-list*, certain events in the stream will |
691 -- prevent proper undo, such as add/delete player or add/delete list | 710 -- prevent proper undo, such as add/delete player or add/delete list |
692 | 711 |
693 | 712 |
694 function bsk:GetSuicideList(id,list) | 713 function GetSuicideList(id,list) |
695 --self:Print("Calculating changeset for "..name.." from list -") | 714 --bsk:Print("Calculating changeset for "..name.." from list -") |
696 --self:PrintTable(list) | 715 --PrintTable(list) |
697 local t = {} | 716 local t = {} |
698 local ret = {} | 717 local ret = {} |
699 local pushing = false | 718 local pushing = false |
700 for i = 1, #list do | 719 for i = 1, #list do |
701 if list[i].id == id then | 720 if list[i].id == id then |
702 pushing = true | 721 pushing = true |
703 end | 722 end |
704 if pushing and (bsk.raidIdP[list[i].id] or bsk.reserveIdP[list[i].id]) then | 723 if pushing and (raidIdP[list[i].id] or reserveIdP[list[i].id]) then |
705 tinsert(ret,list[i].id) | 724 tinsert(ret,list[i].id) |
706 end | 725 end |
707 end | 726 end |
708 --bsk:Print("GSL") | 727 --bsk:Print("GSL") |
709 --bsk:PrintTable(ret) | 728 --PrintTable(ret) |
710 --bsk:Print("GSL") | 729 --bsk:Print("GSL") |
711 return ret | 730 return ret |
712 end | 731 end |
713 | 732 |
714 function bsk:IdIsInList(id,listRef) | 733 function IdIsInList(id,listRef) |
715 for i = 1,#listRef do | 734 for i = 1,#listRef do |
716 if id == listRef[i].id then | 735 if id == listRef[i].id then |
717 return true | 736 return true |
718 end | 737 end |
719 end | 738 end |
720 return false | 739 return false |
721 end | 740 end |
722 | 741 |
723 -- returns true if the events in the list are in time order | 742 -- returns true if the events in the list are in time order |
724 function bsk:CheckListCausality() | 743 function CheckListCausality() |
725 local t = nil | 744 local t = nil |
726 for i,v in ipairs(bsk.db.profile.changes) do | 745 for i,v in ipairs(db.profile.changes) do |
727 if t ~= nil then | 746 if t ~= nil then |
728 if v.time <= t then | 747 if v.time <= t then |
729 return false | 748 return false |
730 end | 749 end |
731 end | 750 end |
734 return true | 753 return true |
735 end | 754 end |
736 | 755 |
737 -- Support functions | 756 -- Support functions |
738 | 757 |
739 function bsk:GetListIndex(name) | 758 function GetListIndex(name) |
740 for i,v in pairs(bsk.lists) do | 759 for i,v in pairs(lists) do |
741 if v.name == name then | 760 if v.name == name then |
742 return i | 761 return i |
743 end | 762 end |
744 end | 763 end |
745 return nil | 764 return nil |
746 end | 765 end |
747 | 766 |
748 local shuffleArray = function(array) | 767 |
749 local arrayCount = #array | |
750 for i = arrayCount, 2, -1 do | |
751 local j = math.random(1, i) | |
752 array[i], array[j] = array[j], array[i] | |
753 end | |
754 return array | |
755 end | |
756 |