comparison Lists.lua @ 17:71fc79846a5d

nuke db without having to exit game printouts for more things populate random is working killing bugs
author John@Doomsday
date Fri, 09 Mar 2012 13:26:56 -0500
parents 16b7e6390f42
children bf3e94bc3bf5
comparison
equal deleted inserted replaced
16:16b7e6390f42 17:71fc79846a5d
7 -- A separate user list is held - lists index into this 7 -- A separate user list is held - lists index into this
8 8
9 9
10 -- TODO: rename player 10 -- TODO: rename player
11 -- TODO: list trimming 11 -- TODO: list trimming
12 -- TODO: lists allow double-add
13 -- TODO: collapse slists into delimited strings for space 12 -- TODO: collapse slists into delimited strings for space
14 13 -- TODO: list-of-lists must not use int indices. those will lead to peril.
14 -- holy crap long notes {{{
15 -- notes on list storage: 15 -- notes on list storage:
16 -- Using names as keys as I do now is atrocious. 16 -- Using names as keys as I do now is atrocious.
17 -- It prevents insertions (twss) to the middle of the list because then it acts 17 -- It prevents insertions (twss) to the middle of the list because then it acts
18 -- as a side effect onto all the others. ie ABCD -> AXBCD would be phrased as 18 -- as a side effect onto all the others. ie ABCD -> AXBCD would be phrased as
19 -- "insert X and shift down B,C,D" which sucks. BCD haven't really been affected 19 -- "insert X and shift down B,C,D" which sucks. BCD haven't really been affected
54 -- * if a stream contains a random-add after an add-to-end 54 -- * if a stream contains a random-add after an add-to-end
55 -- it is declared invalid. tough tits. it's just not a fair 55 -- it is declared invalid. tough tits. it's just not a fair
56 -- distribution at that point. 56 -- distribution at that point.
57 -- * actually, fuck it. I'll give them an unlock command and 57 -- * actually, fuck it. I'll give them an unlock command and
58 -- let them screw over their lists :) 58 -- let them screw over their lists :)
59 59 --}}}
60 -- todo: list-of-lists must not use int indices. those will lead to peril. 60 -- there are some dep chains here. for instance, to have a raidIdP value, a
61 -- person must have a bsk.persons value which leads to a personName2id which
62 -- leads to a raidIdP
63
61 bsk.lists = {} 64 bsk.lists = {}
62 bsk.persons = {} 65 bsk.persons = {}
63 66
64 local raidNameP = {} -- "name" is present in raid 67 local raidNameP = {} -- "name" is present in raid
65 local raidIdP = {} -- "id" is present in raid 68 local raidIdP = {} -- "id" is present in raid
69 72
70 local tinsert = table.insert 73 local tinsert = table.insert
71 local sformat = string.format 74 local sformat = string.format
72 local getn = table.getn 75 local getn = table.getn
73 76
77 function bsk:SelfDestruct()
78 bsk.lists = {}
79 bsk.persons = {}
80 bsk.db.profile.persons = {}
81 bsk.db.profile.changes = {}
82 bsk.db.profile.listBase = {}
83 raidNameP = {}
84 raidIdP = {}
85 reserveIdP = {}
86 personName2id = {}
87 end
74 function bsk:tcopy(to, from) 88 function bsk:tcopy(to, from)
75 for k,v in pairs(from) do 89 for k,v in pairs(from) do
76 if(type(v)=="table") then 90 if(type(v)=="table") then
77 to[k] = {} 91 to[k] = {}
78 bsk:tcopy(to[k], v); 92 bsk:tcopy(to[k], v);
126 self:Print(depth .. i .. " - not sure how to print type: " .. type(v) ) 140 self:Print(depth .. i .. " - not sure how to print type: " .. type(v) )
127 end 141 end
128 end 142 end
129 end 143 end
130 144
145 function bsk:PrintRaidAndReserve()
146 bsk:Print("RaidNameP")
147 bsk:PrintTable(raidNameP)
148 bsk:Print("RaidIdP")
149 bsk:PrintTable(raidIdP)
150 bsk:Print("ReserveP")
151 bsk:PrintTable(reserveIdP)
152 bsk:Print("personName2id")
153 bsk:PrintTable(personName2id)
154 end
131 --}}} 155 --}}}
132 156
133 function bsk:UpdatePersonsReverse() 157 function bsk:UpdatePersonsReverse()
134 for i,v in pairs(bsk.persons) do 158 for i,v in pairs(bsk.persons) do
135 if i ~= "time" then 159 if i ~= "time" then
280 end 304 end
281 local id = string.sub(guid,6) -- skip at least 0x0580 ... 305 local id = string.sub(guid,6) -- skip at least 0x0580 ...
282 id = id:gsub("^0*(.*)","%1") -- nom all leading zeroes remaining 306 id = id:gsub("^0*(.*)","%1") -- nom all leading zeroes remaining
283 307
284 if persons[id] and persons[id] ~= name then 308 if persons[id] and persons[id] ~= name then
285 self:Print(sformat("Namechange detected for %s - new is %s, please rename the existing entry", persons[id], name)) 309 self:Print(sformat("Namechange detected for %s - new is %s, please rename the existing entry", persons[id].main, name))
286 return 310 return
287 end 311 end
288 if persons[id] ~= nil then 312 if persons[id] ~= nil then
289 self:Print(sformat("%s is already in the persons list; disregarding", name)) 313 self:Print(sformat("%s is already in the persons list; disregarding", name))
290 return 314 return
334 -- require admin 358 -- require admin
335 local listIndex = bsk:GetListIndex(listName) 359 local listIndex = bsk:GetListIndex(listName)
336 local id = personName2id[name] 360 local id = personName2id[name]
337 if bsk:IdIsInList(id,bsk.lists[listIndex]) then 361 if bsk:IdIsInList(id,bsk.lists[listIndex]) then
338 bsk:Print(sformat("Person %s is already on the reqeuested list",name)) 362 bsk:Print(sformat("Person %s is already on the reqeuested list",name))
339 return 363 return false
340 end 364 end
341 bsk:Print(sformat("Adding %s (%s) to list %s (%s)", name, id, listName, listIndex)) 365 bsk:Print(sformat("Adding %s (%s) to list %s (%s)", name, id, listName, listIndex))
342 local change = {action="AddToListEnd",arg={id=id,listIndex=listIndex}} 366 local change = {action="AddToListEnd",arg={id=id,listIndex=listIndex}}
343 bsk:StartChange(change) 367 bsk:StartChange(change)
344 if bsk:DoAddPersonToListEnd(change) then 368 if bsk:DoAddPersonToListEnd(change) then
362 local listIndex = bsk:GetListIndex(listName) 386 local listIndex = bsk:GetListIndex(listName)
363 if bsk.lists[listIndex].closedRandom then 387 if bsk.lists[listIndex].closedRandom then
364 self:Print("Cannot add person to list by random roll because an add-to-end operation has already occurred") 388 self:Print("Cannot add person to list by random roll because an add-to-end operation has already occurred")
365 return false 389 return false
366 end 390 end
391 local id = personName2id[name]
367 if bsk:IdIsInList(id,bsk.lists[listIndex]) then 392 if bsk:IdIsInList(id,bsk.lists[listIndex]) then
368 bsk:Print(sformat("Person %s is already on the reqeuested list",name)) 393 bsk:Print(sformat("Person %s is already on the reqeuested list",name))
369 return 394 return false
370 end 395 end
371 local id = personName2id[name]
372 local roll = math.random() 396 local roll = math.random()
373 bsk:Print(sformat("Adding %s (%s) to list %s (%s) with roll (%f)", name, id, listName, listIndex, roll)) 397 bsk:Print(sformat("Adding %s (%s) to list %s (%s) with roll (%f)", name, id, listName, listIndex, roll))
374 local change = {action="AddToListRand",arg={id=id,listIndex=listIndex,roll=roll}} 398 local change = {action="AddToListRand",arg={id=id,listIndex=listIndex,roll=roll}}
375 bsk:StartChange(change) 399 bsk:StartChange(change)
376 if bsk:DoAddPersonToListRandom(change) then 400 if bsk:DoAddPersonToListRandom(change) then
391 local list = bsk.lists[change.arg.listIndex] 415 local list = bsk.lists[change.arg.listIndex]
392 local affected = shallowCopy(change.arg.affect) 416 local affected = shallowCopy(change.arg.affect)
393 -- the goal here is to rotate the suicide list by 1 417 -- the goal here is to rotate the suicide list by 1
394 -- then we can just mash it on top of the intersection between the original 418 -- then we can just mash it on top of the intersection between the original
395 -- list and the working copy 419 -- list and the working copy
420
396 local replacement = shallowCopy(change.arg.affect) 421 local replacement = shallowCopy(change.arg.affect)
397 local temp = table.remove(replacement,1) -- pop 422 local temp = table.remove(replacement,1) -- pop
398 tinsert(replacement,temp) -- push_back 423 tinsert(replacement,temp) -- push_back
399 --bsk:Print(sformat("Before suicide of %s on list %s",slist[1],list.name)) 424 --bsk:Print(sformat("Before suicide of %s on list %s",slist[1],list.name))
400 --bsk:PrintTable(list) 425 --bsk:PrintTable(list)
401 for i = 1, #list do 426 for i = 1, #list do
402 if list[i].id == affect[1] then 427 if list[i].id == affected[1] then
403 table.remove(affect,1) 428 table.remove(affected,1)
404 list[i].id = replacement[1] 429 list[i].id = replacement[1]
405 table.remove(replacement,1) 430 table.remove(replacement,1)
406 end 431 end
407 end 432 end
408 list.time=change.time 433 list.time=change.time
409 return true 434 return true
410 end 435 end
411 436
412 function bsk:SuicidePerson(name,list) 437 function bsk:SuicidePerson(name,listName)
413 -- require admin 438 -- require admin
414 bsk:PopulateRaidList() 439 bsk:PopulateRaidList()
415 local listIndex = bsk:GetListIndex(listName) 440 local listIndex = bsk:GetListIndex(listName)
416 local id = personName2id[name] 441 local id = personName2id[name]
417 local affect=bsk:GetSuicideList(id,bsk.lists[listIndex]) 442 local affect=bsk:GetSuicideList(id,bsk.lists[listIndex])
418 local change = {action="SuicidePerson",arg={affect=affect,listIndex=listIndex}} 443 local change = {action="SuicidePerson",arg={affect=affect,listIndex=listIndex}}
419 bsk:PrintTable(change)
420 bsk:StartChange(change) 444 bsk:StartChange(change)
421 if bsk:DoSuicidePerson(change) then 445 if bsk:DoSuicidePerson(change) then
422 bsk:CommitChange(change) 446 bsk:CommitChange(change)
423 end 447 end
424 end 448 end
425 449
426 function bsk:TrimLists(time) 450 function bsk:TrimLists(time)
427 if not bsk:CheckListCausality() then 451 if not bsk:CheckListCausality() then
428 self:Print("Unable to trim lists due to violated causality") 452 self:Print("Unable to trim lists due to violated causality")
429
430 return false 453 return false
431 end 454 end
432 455
433 if type(time) ~= "number" then 456 if type(time) ~= "number" then
434 time = tonumber(time) 457 time = tonumber(time)
457 -- using the trimmed list and the new bases, recreate the working state 480 -- using the trimmed list and the new bases, recreate the working state
458 bsk:CreateWorkingStateFromChanges(bsk.db.profile.changes) 481 bsk:CreateWorkingStateFromChanges(bsk.db.profile.changes)
459 end 482 end
460 483
461 --}}} 484 --}}}
462 -- Higher order actions (ie calls other Doers){{{ 485 -- Higher order actions (ie calls other standard actions){{{
463 function bsk:AddMissingPersons() 486 function bsk:AddMissingPersons()
464 bsk:PopulateRaidList() 487 bsk:PopulateRaidList()
465 local t = {} 488 local t = {}
466 for i,_ in pairs(bsk.persons) do 489 for id,_ in pairs(bsk.persons) do
467 t[i] = true 490 t[id] = true
468 end 491 end
469 for i,_ in pairs(raidNameP) do 492 for name,_ in pairs(raidNameP) do
470 if t[i] == nil then 493 if personName2id[name] == nil then
471 bsk:Print(sformat("Person %s is missing from the persons list - adding",i)) 494 bsk:Print(sformat("Person %s is missing from the persons list - adding",name))
472 bsk:AddPerson(i) 495 bsk:AddPerson(name)
473 end 496 end
474 end 497 end
475 -- TODO: batch into a single op - no need to spam 25 messages in a row 498 -- TODO: batch into a single op - no need to spam 25 messages in a row
476 end 499 end
477 function bsk:PopulateListRandom(index) 500 function bsk:PopulateListRandom(listIndex)
478 -- difference (raid+reserve)^list, then random shuffle that, then add 501 -- difference (raid+reserve)-list, then random shuffle that, then add
479 bsk:PopulateRaidList() 502 bsk:PopulateRaidList()
480 local list = bsk.lists[index] 503 local list = bsk.lists[listIndex]
481 504
482 local t = {} 505 local t = {} -- after loops, contains intersection of IDs present between raid and reserve
483 --for i = 1,#list do 506 for i,v in pairs(raidIdP) do
484 -- if not (raidNameP(list[i]) or reserveIdP(list[i])) then 507 if v then t[i] = true end
485 -- tinsert(t,) 508 end
486 -- end 509 for i,v in pairs(reserveIdP) do
487 --end 510 if v then t[i] = true end
511 end
512
513 -- now remove from t all of the people already present on the list
514 for i = 1,#list do
515 if t[list[i].id] then
516 t[list[i].id] = false
517 end
518 end
519
520 -- add all remaining
521 for i,v in pairs(t) do
522 if v then
523 bsk:AddPersonToListRandom(bsk.persons[i].main,list.name) -- TODO: APTLR keys off of string names. probably need to change this.
524 end
525 end
488 end 526 end
489 --}}} 527 --}}}
490 -- "Soft" actions- ie things that cause nonpermanent state {{{ 528 -- "Soft" actions- ie things that cause nonpermanent state {{{
491 529
492 -- reserves 530 -- reserves
505 -- return bsk.lists[1] -- todo! 543 -- return bsk.lists[1] -- todo!
506 --end 544 --end
507 545
508 --}}} 546 --}}}
509 547
510 -- The following code is from Xinhuan (wowace forum member) 548 -- The following (adapted) code is from Xinhuan (wowace forum member)
511 -- Pre-create the unitID strings we will use 549 -- Pre-create the unitID strings we will use
512 local pID = {} 550 local pID = {}
513 local rID = {} 551 local rID = {}
514 for i = 1, 4 do 552 for i = 1, 4 do
515 pID[i] = format("party%d", i) 553 pID[i] = format("party%d", i)
518 rID[i] = format("raid%d", i) 556 rID[i] = format("raid%d", i)
519 end 557 end
520 function bsk:PopulateRaidList() 558 function bsk:PopulateRaidList()
521 local inParty = GetNumPartyMembers() 559 local inParty = GetNumPartyMembers()
522 local inRaid = GetNumRaidMembers() 560 local inRaid = GetNumRaidMembers()
523 local add = function(name) raidNameP[name]=true; if personName2id[id] == nil then end end 561 local add = function(unitNameArg)
562 local name = UnitName(unitNameArg)
563 raidNameP[name]=true
564 if personName2id[name] ~= nil then
565 raidIdP[personName2id[name]]=true
566 end
567 end
524 568
525 wipe(raidNameP) 569 wipe(raidNameP)
526 wipe(raidIdP) 570 wipe(raidIdP)
527 if inRaid > 0 then 571 if inRaid > 0 then
528 for i = 1, inRaid do 572 for i = 1, inRaid do
529 local name = UnitName(rID[i]) 573 add(rID[i])
530 raidNameP[name]=true
531 raidIdP[personName2id[name]]=true
532 end 574 end
533 elseif inParty > 0 then 575 elseif inParty > 0 then
534 for i = 1, inParty do 576 for i = 1, inParty do
535 local name = UnitName(pID[i]) 577 add(pID[i])
536 raidNameP[name]=true
537 raidIdP[personName2id[name]]=true
538 end 578 end
539 -- Now add yourself as the last party member 579 -- Now add yourself as the last party member
540 local name = UnitName("player") 580 add("player")
541 raidNameP[name]=true
542 raidIdP[personName2id[name]]=true
543 else 581 else
544 -- You're alone 582 -- You're alone
545 local name = UnitName("player") 583 add("player")
546 raidNameP[name]=true 584 end
547 raidIdP[personName2id[name]]=true 585 bsk:PrintTable(raidNameP)
548 end
549 end 586 end
550 587
551 -- undo rules! 588 -- undo rules!
552 -- only the most recent event can be undone 589 -- only the most recent event can be undone
553 -- ^^^ on a given list? 590 -- ^^^ on a given list?
606 for i,v in pairs(bsk.lists) do 643 for i,v in pairs(bsk.lists) do
607 if v.name == name then 644 if v.name == name then
608 return i 645 return i
609 end 646 end
610 end 647 end
611 assert(false) 648 return nil
612 end 649 end
613 650
614 local shuffleArray = function(array) 651 local shuffleArray = function(array)
615 local arrayCount = #array 652 local arrayCount = #array
616 for i = arrayCount, 2, -1 do 653 for i = arrayCount, 2, -1 do