vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --===========================================================================--
2 ---------------------------- LootTracker by PNB ----------------------------
3 --===========================================================================--
4 -- LootTrackerObjects.lua
5 --
6 -- Access methods for root level objects.
7 --===========================================================================--
8  
9 ------------------------------------------------------------------------------
10 -- GetCurrentSession
11 -- Gets the current session.
12 ------------------------------------------------------------------------------
13  
14 function LT_GetCurrentSession()
15  
16 local settings = LT_GetSettings();
17  
18 local sessionName = settings.CurrentSession;
19 if (sessionName == nil) then
20 sessionName = LT_DEFAULT_SESSIONNAME;
21 end
22  
23 return LT_GetSession(sessionName, true);
24 end
25  
26  
27 ------------------------------------------------------------------------------
28 -- GetSession
29 -- Gets a session.
30 ------------------------------------------------------------------------------
31  
32 function LT_GetSession(sessionName, createIfNil)
33  
34 if (createIfNil == nil) then
35 createIfNil = true;
36 end
37  
38 local userData = LT_Data[LT_RealmAndPlayer];
39 if (userData == nil) then
40 userData = {}
41 LT_Data[LT_RealmAndPlayer] = userData;
42 end
43  
44 local session = userData[sessionName];
45  
46 if ((session == nil) and createIfNil) then
47 session = {};
48 userData[sessionName] = session;
49 end
50  
51 return session;
52 end
53  
54  
55 ------------------------------------------------------------------------------
56 -- GetAvailableSessions
57 -- Gets a list of all valid session names.
58 ------------------------------------------------------------------------------
59  
60 function LT_GetAvailableSessions()
61  
62 local userData = LT_Data[LT_RealmAndPlayer];
63 local validSessions = {};
64 foreach(userData, function(k,v)
65 tinsert(validSessions, k);
66 end);
67  
68 return validSessions;
69  
70 end
71  
72  
73 ------------------------------------------------------------------------------
74 -- GetSettings
75 -- Gets the current settings.
76 ------------------------------------------------------------------------------
77  
78 function LT_GetSettings()
79  
80 if (LT_Settings == nil) then
81 LT_Settings = {};
82 end
83  
84 local settings = LT_Settings[LT_RealmAndPlayer];
85 if (settings == nil) then
86 settings = {};
87 LT_Settings[LT_RealmAndPlayer] = settings;
88 end
89  
90 return settings;
91  
92 end
93  
94  
95 ------------------------------------------------------------------------------
96 -- GetPendingLoot
97 -- Gets the current pending loot table.
98 ------------------------------------------------------------------------------
99  
100 function LT_GetPendingLoot()
101  
102 if (LT_PendingLoot == nil) then
103 LT_PendingLoot = {};
104 end
105  
106 return LT_PendingLoot;
107  
108 end
109  
110  
111 ------------------------------------------------------------------------------
112 -- GetPendingTargets
113 -- Gets the current pending target table.
114 ------------------------------------------------------------------------------
115  
116 function LT_GetPendingTargets()
117  
118 if (LT_PendingTargets == nil) then
119 LT_PendingTargets = {};
120 end
121  
122 return LT_PendingTargets;
123  
124 end
125  
126  
127 ------------------------------------------------------------------------------
128 -- GetItems
129 -- Gets the current item table.
130 ------------------------------------------------------------------------------
131  
132 function LT_GetItems()
133  
134 local session = LT_GetCurrentSession();
135 if (session.Items == nil) then
136 session.Items = {};
137 end
138  
139 return session.Items;
140  
141 end
142  
143  
144 ------------------------------------------------------------------------------
145 -- GetItemsByQuality
146 -- Gets a table of the items, but instead of being indexed by name, they're
147 -- indexed by their quality.
148 ------------------------------------------------------------------------------
149  
150 function LT_GetItemsByQuality()
151  
152 local items = LT_GetItems();
153  
154 -- Put the items into quality buckets
155 local itemsByQuality = {};
156  
157 foreach(items, function(itemName, item)
158  
159 -- If this is the first item, create a new table
160 if (not LT_TableHasKey(itemsByQuality, item.Quality)) then
161 itemsByQuality[item.Quality] = { };
162 end
163  
164 -- Add the item to the table
165 tinsert(itemsByQuality[item.Quality], item);
166  
167 end);
168  
169 return itemsByQuality;
170  
171 end
172  
173  
174 ------------------------------------------------------------------------------
175 -- GetKills
176 -- Gets the current kill table.
177 ------------------------------------------------------------------------------
178  
179 function LT_GetKills()
180  
181 local session = LT_GetCurrentSession();
182 if (session.Kills == nil) then
183 session.Kills = {};
184 end
185  
186 return session.Kills;
187  
188 end
189  
190  
191 ------------------------------------------------------------------------------
192 -- GetPlayers
193 -- Gets the current player table.
194 ------------------------------------------------------------------------------
195  
196 function LT_GetPlayers()
197  
198 local session = LT_GetCurrentSession();
199 if (session.Players == nil) then
200 session.Players = {};
201 end
202  
203 return session.Players;
204  
205 end
206  
207  
208 ------------------------------------------------------------------------------
209 -- SetSession
210 -- Changes the session.
211 ------------------------------------------------------------------------------
212  
213 function LT_SetSession(value)
214  
215 local settings = LT_GetSettings();
216 settings.CurrentSession = value;
217 LT_Message(string.format(LT_SLASHCOMMAND_SESSION_CHANGED, settings.CurrentSession));
218  
219 LT_ValidateSession();
220  
221 LT_FireChange();
222  
223 end
224  
225  
226 ------------------------------------------------------------------------------
227 -- ValidateSession
228 -- Validates that the session version is not out of date.
229 ------------------------------------------------------------------------------
230  
231 function LT_ValidateSession()
232  
233 local session = LT_GetCurrentSession();
234  
235 if (session.Version == nil) then
236 session.Version = LT_Version;
237 elseif (session.Version ~= LT_Version) then
238 LT_Message(LT_VERSION_WARNING);
239 end
240  
241 end
242  
243 ------------------------------------------------------------------------------
244 -- ResetSession
245 -- Resets the session data.
246 ------------------------------------------------------------------------------
247  
248 function LT_ResetSession(sessionToReset)
249  
250 local settings = LT_GetSettings();
251 if (sessionToReset == nil) then
252 sessionToReset = settings.CurrentSession;
253 end
254  
255 local userData = LT_Data[LT_RealmAndPlayer];
256  
257 if (not (LT_TableHasKey(userData, sessionToReset))) then
258 LT_Message(string.format(LT_SLASHCOMMAND_RESET_ERROR, sessionToReset));
259 else
260 LT_Message(string.format(LT_SLASHCOMMAND_RESET_CHANGED, sessionToReset));
261 userData[sessionToReset] = nil;
262 LT_FireChange();
263 end
264  
265 end
266  
267  
268 ------------------------------------------------------------------------------
269 -- ExportSession
270 -- Exports the current session data to a new name.
271 ------------------------------------------------------------------------------
272  
273 function LT_ExportSession(exportTarget)
274  
275 if (LT_StrIsNilOrEmpty(exportTarget)) then
276 LT_Message(LT_SLASHCOMMAND_EXPORT_ERROR);
277 end
278  
279 -- Take the current session and move it to a new place
280 local settings = LT_GetSettings();
281 local userData = LT_Data[LT_RealmAndPlayer];
282 local session = LT_GetCurrentSession();
283 userData[exportTarget] = session;
284 userData[settings.CurrentSession] = {};
285  
286 LT_Message(string.format(LT_SLASHCOMMAND_EXPORT_CHANGED, settings.CurrentSession, exportTarget));
287  
288 LT_FireChange();
289  
290 end
291  
292  
293 ------------------------------------------------------------------------------
294 -- CreatePendingLoot
295 -- Creates a pending loot entry.
296 ------------------------------------------------------------------------------
297  
298 function LT_CreatePendingLoot(slot, source)
299  
300 -- Obtain the loot slot data from the WoW APIs
301 local link = GetLootSlotLink(slot);
302 local lootIcon, lootName, lootQuantity, lootQuality = GetLootSlotInfo(slot);
303  
304 -- Create the loot item
305 local loot = {};
306 loot.Name = lootName;
307 loot.Source = source;
308  
309 if ((lootQuantity ~= nil) and (lootQuantity > 1)) then
310 loot.Quantity = lootQuantity;
311 end
312  
313 -- If this is a money drop, set the Name to "Money"
314 if (LT_IsMoneyString(lootName)) then
315 LT_DebugMessage(3, "Detected a money drop");
316 loot.Name = LT_MONEY;
317 loot.Value = LT_ParseMoney(lootName);
318 end
319  
320 -- Trace out the state
321 LT_DebugMessage(3, "Created pending loot: " .. lootName);
322 local settings = LT_GetSettings();
323 if (settings.DebugLevel >= 3) then
324 LT_FormatMessage(loot);
325 end
326  
327 -- Store the loot in the slot indexed data store
328 if (LT_PendingLootBySlot == nil) then
329 LT_PendingLootBySlot = {}
330 end
331 LT_PendingLootBySlot[slot] = loot;
332  
333 -- Store the loot in the general data store
334 local pendingLoot = LT_GetPendingLoot();
335 pendingLoot[loot.Name] = loot
336 return loot;
337  
338 end
339  
340  
341 ------------------------------------------------------------------------------
342 -- CreatePendingTarget
343 -- Creates a pending target entry.
344 ------------------------------------------------------------------------------
345  
346 function LT_CreatePendingTarget()
347  
348 local unitId = "target";
349  
350 -- Get the name of whoever the player is currently targetting.
351 local name = UnitName(unitId);
352 if (name == nil) then
353 -- No target
354 return;
355 end
356  
357 -- Ignore friendly (non-killable) targets
358 if (UnitIsFriend("player", unitId)) then
359 return;
360 end
361  
362 local kills = LT_GetKills();
363 local kill = kills[name];
364 if (kill ~= nil) then
365 LT_DebugMessage(4, "Repeat target of kill: " .. name);
366 return;
367 end
368  
369 -- Create a new unit info blob
370 local unit = LT_CreateRawUnitInfo(unitId);
371  
372 -- Store the item in the data store
373 LT_DebugMessage(3, "New target: " .. name);
374 local pendingTargets = LT_GetPendingTargets();
375 pendingTargets[name] = unit;
376  
377 end
378  
379  
380 ------------------------------------------------------------------------------
381 -- CreateRawUnitInfo
382 -- Gets lots of relevant information using the Unit APIs and puts it into a
383 -- table.
384 ------------------------------------------------------------------------------
385  
386 function LT_CreateRawUnitInfo(unitId)
387  
388 -- Create a new unit info blob
389 local unit = {};
390 unit.Level = UnitLevel(unitId);
391 unit.Class = UnitClass(unitId);
392 unit.CreatureFamily = UnitCreatureFamily(unitId);
393 unit.CreatureType = UnitCreatureType(unitId);
394 unit.Race = UnitRace(unitId);
395  
396 if (UnitIsPlusMob(unitId)) then
397 unit.Elite = true;
398 end
399  
400 if (UnitIsCivilian(unitId)) then
401 unit.Civilian = true;
402 end
403  
404 local classification = UnitClassification(unitId);
405 if (classification == "rare" or classification == "rareelite") then
406 unit.Rare = true;
407 end
408 if (classification == "worldboss") then
409 unit.Boss = true;
410 end
411  
412 local gender = UnitSex(unitId);
413 if (gender == 0) then
414 unit.Gender = "Male";
415 elseif (gender == 1) then
416 unit.Gender = "Female";
417 end
418  
419 return unit;
420  
421 end
422  
423  
424 ------------------------------------------------------------------------------
425 -- CreateItem
426 -- Creates an item entry if none already existed and adds it to the global
427 -- item table. If one already existed, its information is updated.
428 ------------------------------------------------------------------------------
429  
430 function LT_CreateItem(itemId)
431  
432 local rawItem = LT_GetItem(itemId);
433  
434 if (rawItem == nil) then
435 LT_DebugMessage(2, "Unable to create item info from reference: " .. itemId);
436 return nil;
437 end
438  
439 local item, quantity = LT_CreateItemFromRaw(rawItem);
440  
441 return item, quantity;
442  
443 end
444  
445  
446 ------------------------------------------------------------------------------
447 -- CreateItemFromRaw
448 -- Creates an item entry if none already existed and adds it to the global
449 -- item table. If one already existed, its information is updated.
450 ------------------------------------------------------------------------------
451  
452 function LT_CreateItemFromRaw(rawItem, source)
453  
454 local items = LT_GetItems();
455  
456 local zoneText = LT_GetZoneString();
457 local currentTime = date();
458 LT_OnSessionEvent(currentTime);
459  
460 -- If we've already looted this item, use the existing entry
461 local item = items[rawItem.Name];
462 local new = false;
463 if (item ~= nil) then
464  
465 -- Add the zone, but don't include duplicates
466 LT_AddIfNotPresent(item.Zones, zoneText);
467  
468 -- Add another "time looted", even if its a duplicate
469 tinsert(item.TimesLooted, currentTime);
470  
471 -- Trace out the results of the update
472 local settings = LT_GetSettings();
473 if (settings.DebugLevel >= 3) then
474 LT_FormatMessage(item);
475 end
476 else
477 new = true;
478  
479 -- Create a new item
480 item = {};
481 item.Name = rawItem.Name;
482 item.Quality = rawItem.Quality;
483 item.Zones = { zoneText };
484 item.TimesLooted = { currentTime };
485 item.Link = rawItem.Link;
486 item.MinLevel = rawItem.MinLevel;
487 item.Class = rawItem.Class;
488 item.SubClass = rawItem.SubClass;
489 item.MaxStack = rawItemMaxStack;
490 item.EquipLoc = rawItem.EquipLoc;
491 item.Texture = rawItem.Texture;
492  
493 -- Update extended metadata
494 LT_UpdateItem(item);
495  
496 -- Store the item in the data store
497 items[item.Name] = item;
498 end
499  
500 LT_FireChange();
501  
502 local quantity = 1;
503  
504 -- Check any pending loot for matches
505 local pendingLoot = LT_GetPendingLoot();
506 local pendingLootMatch = pendingLoot[item.Name];
507 if (pendingLootMatch ~= nil) then
508 if (source == nil) then
509 -- Get the source from the pending loot
510 source = pendingLootMatch.Source;
511 if (source ~= nil) then
512 LT_DebugMessage(3, "Matched to pending loot from " .. source);
513 end
514 end
515  
516 if (LT_IsPlayerSolo() and pendingLootMatch.Quantity ~= nil) then
517 quantity = pendingLootMatch.Quantity;
518 end
519  
520 -- Remove the pending loot
521 pendingLoot[item.Name] = nil;
522 end
523  
524 if (source ~= nil) then
525 -- Add this source to the sources list
526 if (item.Sources == nil) then
527 item.Sources = {};
528 end
529 LT_AddCountEntry(item.Sources, source, quantity);
530  
531 -- Add this loot to the matching kill's Loot list
532 local kills = LT_GetKills();
533 if (LT_TableHasKey(kills, source)) then
534 local kill = kills[source];
535  
536 if (kill.Drops == nil) then
537 kill.Drops = {};
538 end
539 LT_AddCountEntry(kill.Drops, item.Name, quantity);
540 end
541  
542 else
543 LT_DebugMessage(3, "Source unknown");
544 end
545  
546  
547 local trace = "Repeat item";
548 local traceLevel = 2;
549 if (new) then
550 trace = "New item";
551 traceLevel = 1;
552 end
553  
554 if (quantity > 1) then
555 trace = string.format("%s (x%d): ", trace, quantity);
556 else
557 trace = trace .. ": "
558 end
559  
560 LT_DebugMessage(traceLevel, trace .. LT_GetItemSummary(item));
561  
562  
563 -- Trace out the initial state of the item
564 if (new) then
565 local settings = LT_GetSettings();
566 if (settings.DebugLevel >= 3) then
567 LT_FormatMessage(item);
568 end
569 end
570  
571 LT_FireChange();
572 return item, quantity;
573  
574 end
575  
576  
577 ------------------------------------------------------------------------------
578 -- UpdateItem
579 ------------------------------------------------------------------------------
580  
581 function LT_UpdateItem(item)
582  
583 if (item.Link == nil) then
584 return;
585 end
586  
587 local itemId = LT_ExtractItemIDFromLink(item.Link);
588  
589  
590 local totalValues = 0;
591 local totalValueSources = 0;
592  
593 -- This code uses the Auctioner APIs:
594 --
595 -- Auctioneer_GetVendorSellPrice(itemId)
596 --
597 -- This function gets the sell price (how much it the player will get if they sell it)
598 -- from Auctioneer's database of item prices.
599 -- @param itemId The ID portion of the item link (the first of the four numbers).
600 -- @returns A price if known (may be 0 if known to have no price) or nil if unknown.
601 --
602 -- Auctioneer is an optional dependency, so we must check for nil here.
603  
604 if (Auctioneer_GetVendorSellPrice ~= nil) then
605  
606 LT_DebugMessage(4, "Scrounging for item info using " .. item.Link);
607  
608 if (itemId ~= nil) then
609  
610 local value = Auctioneer_GetVendorSellPrice(itemId);
611  
612 if (value ~= nil) then
613 LT_DebugMessage(3, "Auctioneer reported value for " .. item.Name .. ": " .. tostring(value));
614 totalValues = totalValues + value;
615 totalValueSources = totalValueSources + 1;
616 else
617 LT_DebugMessage(3, "Auctioneer had no value for " .. itemId);
618 end
619 else
620 LT_DebugMessage(2, "Unable to parse link: " .. item.Link);
621 end
622 else
623 LT_DebugMessage(3, "Auctioneer not loaded, unable to get value");
624 end
625  
626  
627 -- PriceMaster
628  
629 if (CompletePrices ~= nil) then
630 local priceEntry = CompletePrices[itemId];
631 if (priceEntry ~= nil) then
632 local value = priceEntry.p;
633 if (value ~= nil) then
634 LT_DebugMessage(3, "PriceMaster reported value for " .. item.Name .. ": " .. tostring(value));
635 totalValues = totalValues + value;
636 totalValueSources = totalValueSources + 1;
637 else
638 LT_DebugMessage(3, "PriceMaster had no value for " .. itemId);
639 end
640 else
641 LT_DebugMessage(3, "PriceMaster had no entry for " .. itemId);
642 end
643 end
644  
645 if (totalValueSources > 0) then
646 averageValue = totalValues / totalValueSources;
647 LT_DebugMessage(3, "Averaged value from " .. totalValueSources .. " for " .. item.Name .. ": " .. averageValue);
648  
649 if (averageValue > 0) then
650 item.Value = averageValue;
651 end
652 end
653  
654 end
655  
656  
657 ------------------------------------------------------------------------------
658 -- CreatePlayer
659 -- Creates a player entry if none already existed and adds it to the global
660 -- player table.
661 ------------------------------------------------------------------------------
662  
663 function LT_CreatePlayer(name)
664  
665 local players = LT_GetPlayers();
666 LT_OnSessionEvent();
667  
668 -- We've already logged this player - no modifications are necessary
669 local existingEntry = players[name];
670 if (existingEntry ~= nil) then
671 return existingEntry;
672 end;
673  
674 -- Create a new player object
675 local player = { };
676 player.Name = name;
677  
678 -- Update unit information
679 LT_UpdatePlayer(player);
680  
681 -- Trace out the initial state of the player
682 LT_DebugMessage(1, "New player: " .. LT_GetPlayerSummary(player));
683  
684 local settings = LT_GetSettings();
685 if (settings.DebugLevel >= 3) then
686 LT_FormatMessage(player);
687 end
688  
689 -- Store the player in the data store
690 players[name] = player;
691 LT_FireChange();
692  
693 return player;
694  
695 end
696  
697  
698 ------------------------------------------------------------------------------
699 -- UpdatePlayer
700 -- Updates the unit information on the given player object.
701 ------------------------------------------------------------------------------
702  
703 function LT_UpdatePlayer(player)
704  
705 local unitId = LT_GetPlayerUnitID(player.Name);
706  
707 if (unitId == nil) then
708 LT_DebugMessage(2, "Unable to get unit ID for player \"" .. player.Name .. "\"");
709 return false;
710 end
711  
712 local unitInfo = LT_CreateRawUnitInfo(unitId);
713  
714 player.Level = unitInfo.Level;
715 player.Class = unitInfo.Class;
716 player.Race = unitInfo.Race;
717 player.Gender = unitInfo.Gender;
718  
719 player.Gear = LT_GetGear(unitId);
720  
721 return true;
722  
723 end
724  
725  
726 ------------------------------------------------------------------------------
727 -- CreateKill
728 -- Creates a kill entry if none already existed and adds it to the global
729 -- kill table. If one already existed, its count is updated.
730 ------------------------------------------------------------------------------
731  
732 function LT_CreateKill(name)
733  
734 local kills = LT_GetKills();
735  
736 local zoneText = LT_GetZoneString();
737 local currentTime = date();
738 LT_OnSessionEvent(currentTime);
739  
740 -- If we've already killed this mob, use the existing entry
741 local existingEntry = kills[name]
742 if (existingEntry ~= nil) then
743  
744 LT_DebugMessage(2, "Repeat kill: " .. name);
745  
746 -- Add the zone, but don't include duplicates
747 LT_AddIfNotPresent(existingEntry.Zones, zoneText);
748  
749 -- Add another "time killed", even if its a duplicate
750 tinsert(existingEntry.TimesKilled, currentTime);
751  
752 -- Trace out the results of the update
753  
754 local settings = LT_GetSettings();
755 if (settings.DebugLevel >= 3) then
756 LT_FormatMessage(existingEntry);
757 end
758  
759 LT_FireChange();
760 return;
761 end
762  
763 -- Create a new kill entry
764 local kill = { };
765 kill.Name = name;
766 kill.Zones = { zoneText };
767 kill.TimesKilled = { currentTime };
768  
769 -- Update unit information
770 LT_UpdateKill(kill);
771  
772 -- Trace out the initial state of the kill
773 LT_DebugMessage(1, "New kill: " .. LT_GetKillSummary(kill));
774  
775 local settings = LT_GetSettings();
776 if (settings.DebugLevel >= 3) then
777 LT_FormatMessage(kill);
778 end
779  
780 -- Store the kill in the data store
781 kills[name] = kill;
782 LT_FireChange();
783  
784 return kill;
785  
786 end
787  
788  
789 ------------------------------------------------------------------------------
790 -- UpdateKill
791 -- Updates the unit information on the given kill object.
792 ------------------------------------------------------------------------------
793  
794 function LT_UpdateKill(kill)
795  
796 local pendingTargets = LT_GetPendingTargets();
797 local pendingTarget = pendingTargets[kill.Name];
798  
799 if (pendingTarget == nil) then
800 LT_DebugMessage(3, "Unable to get target info for kill \"" .. kill.Name .. "\"");
801 return false;
802 end
803  
804 LT_DebugMessage(3, "Found pending target info for kill \"" .. kill.Name .. "\"");
805  
806 kill.Level = pendingTarget.Level;
807 kill.Class = pendingTarget.Class;
808 kill.CreatureFamily = pendingTarget.CreatureFamily;
809 kill.CreatureType = pendingTarget.CreatureType;
810 kill.Race = pendingTarget.Race;
811  
812 kill.Elite = pendingTarget.Elite;
813 kill.Rare = pendingTarget.Rare;
814 kill.Boss = pendingTarget.Boss;
815 kill.Civilian = pendingTarget.Civilian;
816 kill.Gender = pendingTarget.Gender;
817  
818 -- Remove the pending entry
819 pendingTargets[kill.Name] = nil;
820  
821 return false;
822  
823 end
824  
825  
826 ------------------------------------------------------------------------------
827 -- UpdateObject
828 -- Updates the data on an item, kill, or player.
829 ------------------------------------------------------------------------------
830  
831 function LT_UpdateObject(name)
832  
833 local items = LT_GetItems();
834 local kills = LT_GetKills();
835 local players = LT_GetPlayers();
836  
837 if (LT_TableHasKey(items, name)) then
838  
839 LT_DebugMessage(1, "Updating item: " .. name);
840 LT_UpdateItem(items[name]);
841  
842 elseif (LT_TableHasKey(kills, name)) then
843  
844 LT_DebugMessage(1, "Updating kill: " .. name);
845 LT_UpdateKill(kills[name]);
846  
847 elseif (LT_TableHasKey(players, name)) then
848  
849 LT_DebugMessage(1, "Updating player: " .. name);
850 LT_UpdatePlayer(players[name]);
851  
852 elseif (name == "items") then
853  
854 -- Update all items
855 foreach(items, function(k,v)
856 LT_DebugMessage(1, "Updating item: " .. k);
857 LT_UpdateItem(v);
858 end);
859  
860 elseif (name == "kills") then
861  
862 -- Update all items
863 foreach(kills, function(k,v)
864 LT_DebugMessage(1, "Updating kill: " .. k);
865 LT_UpdateKill(v);
866 end);
867  
868 elseif (name == "players") then
869  
870 -- Update all items
871 foreach(players, function(k,v)
872 LT_DebugMessage(1, "Updating player: " .. k);
873 LT_UpdatePlayer(v);
874 end);
875  
876 else
877 LT_Message(string.format(LT_SLASHCOMMAND_UPDATE_ERROR2, name));
878  
879 end
880  
881 end
882  
883  
884 ------------------------------------------------------------------------------
885 -- TransferItem
886 -- Move an item from one player to another.
887 ------------------------------------------------------------------------------
888  
889 function LT_TransferItem(playerNameSource, playerNameTarget, itemName)
890  
891 local playerSource = LT_CreatePlayer(playerNameSource);
892 local playerTarget = LT_CreatePlayer(playerNameTarget);
893  
894 local items = LT_GetItems();
895 local item = items[itemName];
896 if (item ~= nil) then
897 local removedSuccessfully = LT_RemoveLootFromPlayer(item, playerSource);
898  
899 if (removedSuccessfully) then
900 LT_AddLootToPlayer(item, playerTarget);
901 else
902 -- Item does not exist on player
903 LT_Message(string.format(LT_SLASHCOMMAND_TRANSFER_ERROR3, playerNameSource));
904 return;
905 end
906 else
907 -- Item does not exist
908 LT_Message(string.format(LT_SLASHCOMMAND_TRANSFER_ERROR2, itemName));
909 return;
910 end
911  
912 LT_Message(string.format(LT_SLASHCOMMAND_TRANSFER_MSG, itemName, playerNameSource, playerNameTarget));
913  
914 end
915  
916  
917 ------------------------------------------------------------------------------
918 -- AddLootToPlayer
919 -- Link this item and player together.
920 ------------------------------------------------------------------------------
921  
922 function LT_AddLootToPlayer(item, player)
923  
924 -- Add this player to the item's Recipients list
925 if (item.Recipients == nil) then
926 item.Recipients = { };
927 end
928 LT_AddCountEntry(item.Recipients, player.Name, 1);
929  
930 -- Add this loot to the player's Loot list
931 if (player.Loot == nil) then
932 player.Loot = { };
933 end
934 LT_AddCountEntry(player.Loot, item.Name, 1);
935  
936 end
937  
938  
939 ------------------------------------------------------------------------------
940 -- RemoveLootFromPlayer
941 -- Unlink this item and player.
942 ------------------------------------------------------------------------------
943  
944 function LT_RemoveLootFromPlayer(item, player)
945  
946 if (item.Recipients == nil) then
947 return false;
948 end
949  
950 if (player.Loot == nil) then
951 return false;
952 end
953  
954 local removedFromRecipients = LT_AddCountEntry(item.Recipients, player.Name, -1);
955 local removedFromLoot = LT_AddCountEntry(player.Loot, item.Name, -1);
956  
957 return (removedFromRecipients and removedFromLoot);
958  
959 end
960  
961  
962 ------------------------------------------------------------------------------
963 -- AddNameCountDupleEntry
964 -- Add a [Name]=Count style entry to the given table. If an
965 -- entry already exists of this name, increment the count.
966 ------------------------------------------------------------------------------
967  
968 function LT_AddCountEntry(t, name, add)
969  
970 local existing = t[name];
971 if (existing == nil) then
972 existing = 0;
973 end
974  
975 t[name] = existing + add;
976 return (existing > 0);
977  
978 end
979  
980  
981 ------------------------------------------------------------------------------
982 -- LT_AddSource
983 -- Adds a source entry to the given item.
984 ------------------------------------------------------------------------------
985  
986 function LT_AddSource(item, source, amount)
987  
988 if (item == nil) then
989 return;
990 end
991  
992 LT_DebugMessage(3, string.format("Marking source as \"%s\"", source));
993 if (item.Sources == nil) then
994 item.Sources = {};
995 end
996 LT_AddCountEntry(item.Sources, source, amount);
997  
998 end
999  
1000  
1001 ------------------------------------------------------------------------------
1002 -- OnSessionEvent
1003 -- Logs the time of the event to get a good idea of when the session really
1004 -- started and ended.
1005 ------------------------------------------------------------------------------
1006  
1007 function LT_OnSessionEvent(currentDate, session)
1008  
1009 local currentTime = time();
1010  
1011 if (currentDate == nil) then
1012 currentDate = date(nil, currentTime);
1013 end
1014  
1015 if (session == nil) then
1016 session = LT_GetCurrentSession();
1017 end
1018  
1019 -- First event
1020 if (session.FirstEvent == nil) then
1021 LT_DebugMessage(2, "First session event: " .. currentDate);
1022 session.FirstEvent = currentDate;
1023 session.FirstEventTime = currentTime;
1024 end
1025  
1026 -- Last event
1027 session.MostRecentEvent = currentDate;
1028 session.MostRecentEventTime = currentTime;
1029  
1030 end
1031