vanilla-wow-addons – Rev 1
?pathlinks?
--===========================================================================--
---------------------------- LootTracker by PNB ----------------------------
--===========================================================================--
-- LootTracker.lua
--
-- Primary entry points to the AddOn
--===========================================================================--
--===========================================================================--
-- Constants
--===========================================================================--
LT_Version = "1.5.1";
LT_MinTooltipMode = 1;
LT_MaxTooltipMode = 3;
LT_QualityColors = {
["-2"] = {r=0.00, g=0.88, b=1.00},
["-1"] = {r=0.89, g=0.82, b=0.39},
["0"] = {r=0.50, g=0.50, b=0.50},
["1"] = {r=1.00, g=1.00, b=1.00},
["2"] = {r=0.12, g=1.00, b=0.00},
["3"] = {r=0.00, g=0.44, b=0.87},
["4"] = {r=0.64, g=0.21, b=0.93},
["5"] = {r=1.00, g=1.00, b=1.00}
};
LT_MinQuality = -2
LT_MaxQuality = 5;
LT_MoneyColors = {
[0] = {r=0.89, g=0.82, b=0.39},
[1] = {r=0.71, g=0.71, b=0.71},
[2] = {r=0.66, g=0.33, b=0.11}
};
LT_White = {r=1.00, g=1.00, b=1.00};
--===========================================================================--
-- Saved Variables
-- These are the values that will be persisted from session to session.
--===========================================================================--
------------------------------------------------------------------------------
-- LT_Data holds all data on items, kills, and players for the current session
-- and for any other saved sessions.
-- TODO: Make this also forked per-character
------------------------------------------------------------------------------
LT_Data = { }
-- ["Realm - Player"]
-- ["SessionName"]
-- Items
-- ["ItemName"]
-- Name
-- Quality
-- Value
-- Zones (list)
-- TimesLooted (list)
-- Recipients (list)
-- Sources (list)
-- Kills
-- ["KillName"]
-- Name
-- Level
-- TimesKilled (list)
-- Drops (list)
-- Players
-- ["PlayerName"]
-- Name
-- Level
-- TimesKilled (list)
-- LootReceived (list)
-- Gear (list)
------------------------------------------------------------------------------
-- LT_Settings holds configuration values.
------------------------------------------------------------------------------
LT_Settings = { }
-- ["Realm - Player"]
-- CurrentSession
-- DebugLevel
-- JustMyLoot
-- ChatColor
-- QualityThreshold
-- TooltipShowItems
-- TooltipShowKills
-- TooltipShowPlayers
-- IgnoreCraftLoot
-- IgnoreQuestLoot
-- IgnoreVendorLoot
--===========================================================================--
-- Globals
-- These values are global, but not saved when the session ends.
--===========================================================================--
LT_RealmAndPlayer = "";
LT_ChangeListeners = nil;
------------------------------------------------------------------------------
-- LT_PendingLoot holds onto any items we've seen in a loot window, but
-- haven't yet linked to a recipient.
------------------------------------------------------------------------------
LT_PendingLoot = {};
-- ["ItemName"]
-- Name
-- Source
-- Quantity (sometimes)
-- Value (sometimes)
------------------------------------------------------------------------------
-- LT_PendingLootBySlot holds the same information as LT_PendingLoot, but its
-- indexed by the original loot slot index, and the table is cleared as soon
-- as the loot window is closed. This table is used to handle the LootRemoved
-- event.
------------------------------------------------------------------------------
LT_PendingLootBySlot = {};
-- ["Slot"]
------------------------------------------------------------------------------
-- LT_PendingTarget holds onto any units we've targeted.
------------------------------------------------------------------------------
LT_PendingTargets = {};
-- ["TargetName"]
-- Class
-- Level
--===========================================================================--
-- Frame Hooks
-- These are the functions linked from LootTracker.xml
--===========================================================================--
------------------------------------------------------------------------------
-- OnLoad
-- Invoked when the addon is loaded. Gives us a chance to register for any
-- events we might care about.
------------------------------------------------------------------------------
function LootTracker_OnLoad()
this:RegisterEvent("VARIABLES_LOADED");
this:RegisterEvent("ADDON_LOADED");
this:RegisterEvent("CHAT_MSG_LOOT");
this:RegisterEvent("CHAT_MSG_MONEY");
this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH");
this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH");
this:RegisterEvent("CHAT_MSG_SYSTEM");
this:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE");
this:RegisterEvent("CHAT_MSG_COMBAT_HONOR_GAIN");
this:RegisterEvent("CHAT_MSG_COMBAT_XP_GAIN");
this:RegisterEvent("CHAT_MSG_SKILL");
this:RegisterEvent("PLAYER_TARGET_CHANGED");
this:RegisterEvent("LOOT_OPENED");
this:RegisterEvent("LOOT_CLOSED");
this:RegisterEvent("LOOT_SLOT_CLEARED");
end
------------------------------------------------------------------------------
-- OnEvent
-- Invoked when any of our registered events are fired
------------------------------------------------------------------------------
function LootTracker_OnEvent(event, arg1)
if (event == "VARIABLES_LOADED") then
LT_OnStartup();
return;
end
if (event == "ADDON_LOADED") then
return;
end
if (event == "CHAT_MSG_LOOT") then
LT_OnLootMessage(arg1);
return;
end
if (event == "CHAT_MSG_MONEY") then
LT_OnMoneyMessage(arg1);
return;
end
if (event == "CHAT_MSG_COMBAT_FRIENDLY_DEATH") then
LT_OnFriendlyDeathMessage(arg1);
return;
end
if (event == "CHAT_MSG_COMBAT_HOSTILE_DEATH") then
LT_OnHostileDeathMessage(arg1);
return;
end
if (event == "CHAT_MSG_SYSTEM") then
LT_OnSystemMessage(arg1);
return;
end
if (event == "CHAT_MSG_COMBAT_FACTION_CHANGE") then
LT_OnFactionChange(arg1);
return;
end
if (event == "CHAT_MSG_COMBAT_HONOR_GAIN") then
LT_OnGainHonor(arg1);
return;
end
if (event == "CHAT_MSG_COMBAT_XP_GAIN") then
LT_OnGainExperience(arg1);
return;
end
if (event == "CHAT_MSG_SKILL") then
LT_OnSkillMessage(arg1);
return;
end
if (event == "LOOT_OPENED") then
LT_OnLootBegin();
return;
end
if (event == "LOOT_CLOSED") then
LT_OnLootEnd();
return;
end
if (event == "LOOT_SLOT_CLEARED") then
LT_OnLootSlotCleared(arg1);
return;
end
if (event == "PLAYER_TARGET_CHANGED") then
LT_OnTargetChanged();
return;
end
LT_DebugMessage(2, "Unexpected event: " .. event);
end
--===========================================================================--
-- Event Handlers
--===========================================================================--
------------------------------------------------------------------------------
-- OnStartup
------------------------------------------------------------------------------
function LT_OnStartup()
-- Hook into console commands
SlashCmdList["LT_"] = LT_OnSlashCommand;
-- Get realm and player names
local realm = GetCVar("realmName");
local player = UnitName("player");
LT_RealmAndPlayer = realm .. " - " .. player;
-- Initialize the LT_Settings structure
local settings = LT_GetSettings();
if (settings.CurrentSession == nil) then
settings.CurrentSession = LT_DEFAULT_SESSIONNAME;
end
if (settings.DebugLevel == nil) then
settings.DebugLevel = 0;
end
if (settings.JustMyLoot == nil) then
settings.JustMyLoot = false;
end
if (settings.ChatColor == nil) then
settings.ChatColor = {r=0.78,g=0.55,b=1.0};
else
-- Convert from 0-255 range to 0-1 range
if (settings.ChatColor.r > 1.0) then
settings.ChatColor.r = settings.ChatColor.r / 255;
end
if (settings.ChatColor.g > 1.0) then
settings.ChatColor.g = settings.ChatColor.g / 255;
end
if (settings.ChatColor.b > 1.0) then
settings.ChatColor.b = settings.ChatColor.b / 255;
end
end
if (settings.QualityThreshold == nil) then
settings.QualityThreshold = 2;
end
if (settings.TooltipMode == nil) then
settings.TooltipMode = LT_MinTooltipMode;
end
if (settings.TooltipShowItems == nil) then
settings.TooltipShowItems = true;
end
if (settings.TooltipShowKills == nil) then
settings.TooltipShowKills = true;
end
if (settings.TooltipShowPlayers == nil) then
settings.TooltipShowPlayers = false;
end
if (settings.IgnoreCraftLoot == nil) then
settings.IgnoreCraftLoot = true;
end
if (settings.IgnoreQuestLoot == nil) then
settings.IgnoreQuestLoot = false;
end
if (settings.IgnoreVendorLoot == nil) then
settings.IgnoreVendorLoot = true;
end
-- Initialize the LT_Data structure
if (LT_Data == nil) then
LT_Data = {};
end
-- Check the version
LT_ValidateSession();
-- Initialize the settings UI
-- TODO: Does this really do anything?
UIPanelWindows["LT_SettingsUI"] = {area = "center", pushable = 0};
-- Output a "We've loaded" message
-- TODO: Why isn't this appropriately colored?
LT_Message(string.format(LT_STARTUP, LT_Version));
end
------------------------------------------------------------------------------
-- OnLootMessage
-- There's been a loot message in chat - process it.
------------------------------------------------------------------------------
function LT_OnLootMessage(text)
LT_DebugMessage(4, "Raw Loot Message: " .. text);
local settings = LT_GetSettings();
-- SomeOtherPlayer receives loot: [Heavy Leather]
local beginMatch, endMatch, recipient, itemLink = string.find(text, LT_LOOT_RECEIVED);
if (beginMatch) then
LT_OnParsedLootMessage(recipient, itemLink);
return;
end
-- You receive loot: [Heavy Leather]
local beginMatch, endMatch, itemLink = string.find(text, LT_LOOT_RECEIVED_YOU);
if (beginMatch) then
LT_OnParsedLootMessage(LT_YOU, itemLink);
return;
end
-- You receive item: [Warlords Deck]
local beginMatch, endMatch, itemLink = string.find(text, LT_LOOT_ITEM);
if (beginMatch) then
if (not settings.IgnoreVendorLoot) then
-- This match covers both bought items and combined items (like Warlords Deck).
-- We need the setting to disable it for people who don't want to include
-- purchased ammo etc., but it'd be nice to be able to sort out true vendor
-- items from quest created items.
local item, player = LT_OnParsedLootMessage(LT_YOU, itemLink);
-- Mark the source as "Vendor"
LT_AddSource(item, LT_SOURCE_VENDOR, 1);
else
LT_DebugMessage(2, "Ignoring vendor loot.");
end
return;
end
-- "You create: [Copper Bar]"
local beginMatch, endMatch, itemLink = string.find(text, LT_LOOT_CREATED);
if (beginMatch) then
if (not settings.IgnoreCraftLoot) then
-- Keep processing the loot message
local item, player = LT_OnParsedLootMessage(LT_YOU, itemLink);
-- Mark the source as "Craft"
LT_AddSource(item, LT_SOURCE_CRAFT, 1);
else
LT_DebugMessage(2, "Ignoring craft loot.");
end
return;
end
-- "You won [Meaty Bat Wing]"
local beginMatch, endMatch, recipient, itemLink = string.find(text, LT_LOOT_WON);
if (beginMatch) then
-- TODO: Do something with this message
LT_DebugMessage(1, string.format("%s won %s", recipient, itemLink));
end
LT_DebugMessage(2, "Loot message did not match pattern: " .. text);
end
------------------------------------------------------------------------------
-- OnParsedLootMessage
-- Process a loot message.
------------------------------------------------------------------------------
function LT_OnParsedLootMessage(recipientName, itemLink)
-- This shouldn't happen, but validate that we got our out parameters.
if (recipientName == nil) then
LT_DebugMessage(2, "Recipient was nil");
return;
end
if (itemLink == nil) then
LT_DebugMessage(2, "Item link was nil");
return;
end
-- Map "You" to a player name
if (recipientName == LT_YOU) then
recipientName = UnitName("player");
else
-- If we're configured to only consider local loot, and this isn't
-- going to us, bail now.
if (LT_IsPlayerSolo()) then
LT_DebugMessage(2, "Ignoring loot going to another player.");
return;
end
end
-- Get the Id from the link
local itemId = LT_ExtractItemIDFromChatLink(itemLink);
LT_DebugMessage(4, "Extracted item id: " .. itemId);
local item, quantity = LT_CreateItem(itemId);
local player = LT_CreatePlayer(recipientName);
-- Bail out if we were unable to create either an item or player object.
if (item == nil) then
LT_DebugMessage(2, "Error creating item object");
return;
end
if (player == nil) then
LT_DebugMessage(2, "Error creating player object");
return;
end
for i = 1, quantity do
LT_AddLootToPlayer(item, player);
end
return item, player;
end
------------------------------------------------------------------------------
-- OnFriendlyDeathMessage
-- There's been a death message in chat - process it.
------------------------------------------------------------------------------
function LT_OnFriendlyDeathMessage(text)
LT_DebugMessage(4, "Raw (Friendly) Death Message: " .. text);
local beginMatch, endMatch, deceased = string.find(text, LT_FRIENDLY_DEATH);
if (beginMatch) then
-- This shouldn't happen, but validate that we got our out parameters.
if (deceased == nil) then
LT_DebugMessage(2, "Deceased was nil");
return;
end
local unitId = nil;
-- Map "You" to a player name
if (deceased == LT_YOU) then
deceased = UnitName("player");
unitId = "player";
else
unitId = LT_GetPlayerUnitID(deceased);
end
if (unitId == nil) then
LT_DebugMessage(2, "Unable to get UnitID for player: " .. deceased);
return;
end
-- We don't want to bother logging non-party deaths.
if (not UnitInParty(unitId) and not UnitInRaid(unitId)) then
LT_DebugMessage(2, "Ignoring death of non-party character: " .. deceased);
end
-- Create an entry for this player if there isn't one already.
local player = LT_CreatePlayer(deceased);
local timeOfDeath = date();
-- Log the time of death.
if (player.TimesKilled == nil) then
player.TimesKilled = { timeOfDeath };
else
table.insert(player.TimesKilled, timeOfDeath);
end
LT_DebugMessage(2, "Player died: " .. player.Name);
return;
else
LT_DebugMessage(3, "Friendly death message did not match pattern: " .. text);
end
end
------------------------------------------------------------------------------
-- OnHostileDeathMessage
-- There's been a death message in chat - process it.
------------------------------------------------------------------------------
function LT_OnHostileDeathMessage(text)
LT_DebugMessage(4, "Raw (Hostile) Death Message: " .. text);
local beginMatch, endMatch, deceased = string.find(text, LT_HOSTILE_DEATH);
if (beginMatch) then
-- This shouldn't happen, but validate that we got our out parameters.
if (deceased == nil) then
LT_DebugMessage(2, "Deceased was nil");
return;
end
-- TODO: If this kill did not come from our group, don't count it.
-- Use tapped state to detect this... somehow?
-- Log this kill
kill = LT_CreateKill(deceased);
return;
else
LT_DebugMessage(3, "Hostile death message did not match pattern: " .. text);
end
end
------------------------------------------------------------------------------
-- OnSystemMessage
-- There's been a system message in chat - process it.
------------------------------------------------------------------------------
function LT_OnSystemMessage(text)
LT_DebugMessage(4, "Raw System Message: " .. text);
-- Received item: [Super Duper Quest Reward]
local beginMatch, endMatch, itemLink = string.find(text, LT_RECEIVED_ITEM);
if (beginMatch) then
local settings = LT_GetSettings();
if (not settings.IgnoreQuestLoot) then
-- This shouldn't happen, but validate that we got our out parameters.
if (itemLink == nil) then
LT_DebugMessage(2, "Link was nil");
return;
end
-- Keep processing the loot message
local item, player = LT_OnParsedLootMessage(LT_YOU, itemLink);
-- Mark the source as "Quest"
LT_AddSource(item, LT_SOURCE_QUEST, 1);
else
LT_DebugMessage(2, "Ignoring quest loot.");
end
return;
end
-- Received 7 Silver.
local beginMatch, endMatch, amount = string.find(text, LT_RECEIVED_MONEY);
if (beginMatch) then
local settings = LT_GetSettings();
if (not settings.IgnoreQuestLoot) then
LT_DebugMessage(2, "Quest money reward: " .. tostring(amount));
local item = LT_OnMoneyLootText(amount, false);
-- Mark the source as "Quest"
LT_AddSource(item, LT_SOURCE_QUEST, 1);
else
LT_DebugMessage(2, "Ignoring quest money reward.");
end
return;
end
-- Discovered Ratchet: 105 experience gained
local beginMatch, endMatch, amount = string.find(text, LT_EXPERIENCE_GAINED_EXPLORE);
if (beginMatch) then
LT_OnGainExperienceAmount(tonumber(amount), LT_SOURCE_EXPLORATION);
return;
end
-- Experience gained: 1950
local beginMatch, endMatch, amount = string.find(text, LT_EXPERIENCE_GAINED_QUEST);
if (beginMatch) then
LT_OnGainExperienceAmount(tonumber(amount), LT_SOURCE_QUEST);
return;
end
LT_DebugMessage(4, "System message did not match pattern: " .. text);
end
------------------------------------------------------------------------------
-- OnFactionChange
-- There's been a faction message in chat - process it.
------------------------------------------------------------------------------
function LT_OnFactionChange(text)
LT_DebugMessage(4, "Raw faction change: " .. text);
-- Your reputation with Timbermaw Hold has very slightly increased (5 reputation gained)
local beginMatch, endMatch, faction = string.find(text, LT_REPUTATION_FACTION);
if (beginMatch) then
local beginMatch, endMatch, amount = string.find(text, LT_REPUTATION_GAINED);
if (beginMatch) then
amount = tonumber(amount);
LT_DebugMessage(2, string.format("Gained %d %s reputation", amount, faction));
LT_OnReputationChange(faction, amount)
return;
end
local beginMatch, endMatch, amount = string.find(text, LT_REPUTATION_LOST);
if (beginMatch) then
amount = tonumber(amount);
LT_DebugMessage(2, string.format("Lost %d %s reputation", amount, faction));
LT_OnReputationChange(faction, -amount)
end
end
-- You are now Neutral with Booty Bay
LT_DebugMessage(2, "Faction message did not match pattern: " .. text);
end
------------------------------------------------------------------------------
-- OnGainHonor
-- There's been an honor message in chat - process it.
------------------------------------------------------------------------------
function LT_OnGainHonor(text)
LT_DebugMessage(4, "Raw honor change: " .. text);
-- Rolbek dies, honorable kill Rank: Knight (Estimated Honor Points: 32)
local beginMatch, endMatch, amount = string.find(text, LT_HONOR_GAINED_KILL);
if (beginMatch) then
LT_OnGainHonorAmount(tonumber(amount), LT_SOURCE_KILL);
return;
end
-- You have been awarded 198 honor points.
local beginMatch, endMatch, amount = string.find(text, LT_HONOR_GAINED_AWARD);
if (beginMatch) then
LT_OnGainHonorAmount(tonumber(amount), nil);
return;
end
LT_DebugMessage(1, "Honor message did not match pattern: " .. text);
end
------------------------------------------------------------------------------
-- OnGainExperience
-- There's been an experience message in chat - process it.
------------------------------------------------------------------------------
function LT_OnGainExperience(text)
LT_DebugMessage(4, "Raw experience change: " .. text);
-- Greater Plainstrider dies, you gain 144 experience. (+72 Rested bonus)
local beginMatch, endMatch, amount = string.find(text, LT_EXPERIENCE_GAINED_KILL);
if (beginMatch) then
LT_OnGainExperienceAmount(tonumber(amount), LT_SOURCE_KILL);
return;
end
-- You gain 440 experience
local beginMatch, endMatch, amount = string.find(text, LT_EXPERIENCE_GAINED);
if (beginMatch) then
-- Ignore these and instead use the system message
LT_DebugMessage(2, "Ignoring duplicate experience message for " .. amount);
return;
end
LT_DebugMessage(1, "Experience message did not match pattern: " .. text);
end
------------------------------------------------------------------------------
-- OnSkillMessage
-- There's been an skill message in chat - process it.
------------------------------------------------------------------------------
function LT_OnSkillMessage(text)
LT_DebugMessage(4, "Raw skill message: " .. text);
-- Your skill in Staves has increased to 64
local beginMatch, endMatch, skill, value = string.find(text, LT_SKILL_GAINED);
if (beginMatch) then
value = tonumber(value);
-- We're assuming that skill changes always come in units of one.
-- If this isn't true we'll need to do more work and remember the old
-- skill value.
local amount = 1;
LT_DebugMessage(1, string.format("Skill change: %s, %d", skill, value));
-- Create a fake item entry to represent the experience
local rawItem = {};
rawItem.Quality = -2;
rawItem.Name = string.format(LT_SKILL_TYPE, skill);
rawItem.Class = LT_SKILL;
rawItem.SubClass = skill;
-- Create the real item entry
local item = LT_CreateItemFromRaw(rawItem, nil);
if (item ~= nil) then
local recipient = UnitName("player");
-- Add the receiving player to the item's Recipients list
if (item.Recipients == nil) then
item.Recipients = { };
end
LT_AddCountEntry(item.Recipients, recipient, amount);
return item;
end
return;
end
LT_DebugMessage(1, "Skill message did not match pattern: " .. text);
end
------------------------------------------------------------------------------
-- OnMoneyMessage
-- There's been a mmoney loot message in chat - process it.
------------------------------------------------------------------------------
function LT_OnMoneyMessage(text)
LT_DebugMessage(4, "Raw Money Message: " .. text);
-- "You loot 1 Silver, 10 Copper"
local beginMatch, endMatch, amount = string.find(text, LT_MONEY_LOOT);
if (beginMatch) then
-- This shouldn't happen, but validate that we got our out parameters.
if (amount == nil) then
LT_DebugMessage(2, "Amount was nil");
return;
end
-- Non-shared money
-- We ignore non-shared loot messages that come from chat if we're in
-- "solo" mode. We'll get a LT_OnLootSlotCleared event for those ones
-- consistently. We only get the chat message when it's a shift-click
-- loot.
if (not LT_IsPlayerSolo()) then
LT_OnMoneyLootText(amount, false);
else
LT_DebugMessage(2, "Ignoring loot chat message.");
end
return;
end
-- "Your share of the loot is 2 Silver, 21 Copper."
local beginMatch, endMatch, amount = string.find(text, LT_SHARED_MONEY_LOOT);
if (beginMatch) then
-- This shouldn't happen, but validate that we got our out parameters.
if (amount == nil) then
LT_DebugMessage(2, "Amount was nil");
return;
end
-- Shared money
LT_OnMoneyLootText(amount, true);
return;
end
LT_DebugMessage(2, "Money message did not match pattern: " .. text);
end
------------------------------------------------------------------------------
-- OnMoneyLootText
-- Parse and process cash loot
------------------------------------------------------------------------------
function LT_OnMoneyLootText(text, shared)
-- 1 Gold, 2 Silver, 21 Copper."
local value, gold, silver, copper = LT_ParseMoney(text);
local sharedString = "";
if (shared) then
sharedString = " (shared)"
end
LT_DebugMessage(2, "Looted Money" .. sharedString .. ": " .. tostring(gold) .. "g " .. tostring(silver) .. "s " .. tostring(copper) .. "c");
return LT_OnMoneyLoot(value, shared, nil);
end
------------------------------------------------------------------------------
-- OnMoneyLoot
-- Process cash loot
------------------------------------------------------------------------------
function LT_OnMoneyLoot(value, shared, source)
local rawItem = {};
rawItem.Name = LT_MONEY;
rawItem.Quality = -1;
rawItem.Class = LT_MONEY;
local item = LT_CreateItemFromRaw(rawItem, source);
if (item ~= nil) then
if (item.Value == nil) then
item.Value = 0;
end
-- The Value of the Money item is an average drop size.
-- Add this new loot value into the running average.
local oldValue = item.Value;
local newCount = getn(item.TimesLooted);
local oldTotalMoneyLooted = oldValue * (newCount - 1);
local newTotalMoneyLooted = oldTotalMoneyLooted + value;
local newAverage = newTotalMoneyLooted / newCount;
item.Value = newAverage;
-- If this is shared loot, go to "Everyone", otherwise go to the local player.
local recipient = LT_EVERYONE;
if (not shared) then
recipient = UnitName("player");
end
-- Add the receiving player to the item's Recipients list
if (item.Recipients == nil) then
item.Recipients = { };
end
LT_AddCountEntry(item.Recipients, recipient, 1);
return item;
end
end
------------------------------------------------------------------------------
-- OnReputationChange
-- There has been a reputation gain/loss.
------------------------------------------------------------------------------
function LT_OnReputationChange(faction, amount)
LT_DebugMessage(1, string.format("Faction gain: %s - %d", faction, amount));
-- Create a fake item entry to represent the reputation
local rawItem = {};
rawItem.Quality = -2;
-- Give separate names for gain/loss
local formatString = LT_REPUTATION_TYPE;
if (amount < 0) then
formatString = LT_REPUTATION_TYPELOST;
end
rawItem.Name = string.format(formatString, faction);
rawItem.Class = LT_REPUTATION;
rawItem.SubClass = faction;
-- Create the final item entry
local item = LT_CreateItemFromRaw(rawItem, nil);
if (item ~= nil) then
local recipient = UnitName("player");
-- Add the receiving player to the item's Recipients list
if (item.Recipients == nil) then
item.Recipients = { };
end
LT_AddCountEntry(item.Recipients, recipient, amount);
return item;
end
end
------------------------------------------------------------------------------
-- OnGainExperienceAmount
-- There's been an experience gain.
------------------------------------------------------------------------------
function LT_OnGainExperienceAmount(amount, source)
LT_DebugMessage(1, string.format("Experience gain: %d (%s)", amount, source));
-- Create a fake item entry to represent the experience
local rawItem = {};
rawItem.Quality = -2;
rawItem.Name = LT_EXPERIENCE;
rawItem.Class = LT_EXPERIENCE;
-- Create the real item entry
local item = LT_CreateItemFromRaw(rawItem, nil);
if (item ~= nil) then
local recipient = UnitName("player");
-- Add the receiving player to the item's Recipients list
if (item.Recipients == nil) then
item.Recipients = { };
end
LT_AddCountEntry(item.Recipients, recipient, amount);
if (source ~= nil) then
LT_AddSource(item, source, amount);
else
LT_DebugMessage(1, "Unspecified source for experience");
end
return item;
end
end
------------------------------------------------------------------------------
-- OnGainHonorAmount
-- There's been an honor gain.
------------------------------------------------------------------------------
function LT_OnGainHonorAmount(amount, source)
LT_DebugMessage(1, string.format("Honor gain: %d", amount));
-- Create a fake item entry to represent the honor
local rawItem = {};
rawItem.Quality = -2;
rawItem.Name = LT_HONOR;
rawItem.Class = LT_HONOR;
-- Create the real item entry
local item = LT_CreateItemFromRaw(rawItem, nil);
if (item ~= nil) then
local recipient = UnitName("player");
-- Add the receiving player to the item's Recipients list
if (item.Recipients == nil) then
item.Recipients = { };
end
LT_AddCountEntry(item.Recipients, recipient, amount);
if (source ~= nil) then
LT_AddSource(item, source, amount);
else
LT_DebugMessage(1, "Unspecified source for honor");
end
return item;
end
end
------------------------------------------------------------------------------
-- OnLootBegin
-- The current player has opened the loot window.
------------------------------------------------------------------------------
function LT_OnLootBegin()
LT_PendingLootBySlot = {};
-- Determine the target being looted
local source = UnitName("target");
if (source == nil) then
LT_DebugMessage(3, "Looting (Unknown)");
else
LT_DebugMessage(3, "Looting " .. source);
end
local lootCount = GetNumLootItems();
for slot = 1, lootCount, 1 do
-- Create a pending loot entry
LT_CreatePendingLoot(slot, source);
end
end
------------------------------------------------------------------------------
-- OnLootEnd
-- The current player has closed the loot window.
------------------------------------------------------------------------------
function LT_OnLootEnd()
LT_DebugMessage(3, "Done looting");
end
------------------------------------------------------------------------------
-- OnLootEnd
-- The current player has closed the loot window.
------------------------------------------------------------------------------
function LT_OnLootSlotCleared(slot)
LT_DebugMessage(3, "Slot looted: " .. slot);
if (LT_PendingLootBySlot == nil) then
LT_DebugMessage(2, "Invalid slot looting. Expected pending loot table to still be valid.");
return;
end
local loot = LT_PendingLootBySlot[slot];
if (loot == nil) then
LT_DebugMessage(2, "Invalid slot looting. Expected pending loot item to still be valid for slot " .. slot .. ".");
return;
end
LT_DebugMessage(4, "Loot cleared: " .. loot.Name .. " (slot " .. slot .. ")");
local settings = LT_GetSettings();
if (loot.Name == LT_MONEY) then
-- Disabling because we can't determine at this point if this will
-- end up being a shared (split) money drop or not. We will always
-- get this event for the local player, and so when solo-ing this is
-- the best event to hook (since the chat message is *not* always
-- sent). However, when in a group we don't want to think the local
-- player will receive 100% of the cash when in fact it will be split.
if (LT_IsPlayerSolo()) then
-- Non-shared loot
local item = LT_OnMoneyLoot(loot.Value, false, loot.Source);
end
LT_PendingLoot[loot.Name] = nil;
end
LT_PendingLootBySlot[slot] = nil;
end
------------------------------------------------------------------------------
-- OnTargetChanged
-- The current player has changed who they're targeting.
------------------------------------------------------------------------------
function LT_OnTargetChanged()
LT_CreatePendingTarget();
end
------------------------------------------------------------------------------
-- SlashCommand
-- Handles console commands.
------------------------------------------------------------------------------
function LT_OnSlashCommand(rawArgument)
local command, value = LT_GetCommandAndValue(rawArgument);
local settings = LT_GetSettings();
if (LT_StrIsNilOrEmpty(command)) then
command = LT_SLASHCOMMAND_SETTINGS;
end
if (command == LT_SLASHCOMMAND_DEBUG) then
if (value ~= nil) then
local level = tonumber(value);
if (level == nil) then
LT_Message(LT_SLASHCOMMAND_DEBUG_ERROR);
else
settings.DebugLevel = level;
end
end
LT_Message(string.format(LT_SLASHCOMMAND_DEBUG_QUERY, settings.DebugLevel));
return;
elseif (command == LT_SLASHCOMMAND_JUSTMYLOOT) then
if (value ~= nil) then
settings.JustMyLoot = value;
else
LT_Message(string.format(LT_SLASHCOMMAND_JUSTMYLOOT_QUERY, tostring(settings.JustMyLoot)));
end;
return;
elseif (command == LT_SLASHCOMMAND_SESSION) then
if (value ~= nil) then
LT_SetSession(value);
else
LT_Message(string.format(LT_SLASHCOMMAND_SESSION_QUERY, settings.CurrentSession));
end;
return;
elseif (command == LT_SLASHCOMMAND_SESSIONS) then
LT_Message(LT_SLASHCOMMAND_SESSIONS_QUERY);
LT_MessageIndent();
local sessions = LT_GetAvailableSessions();
foreach(sessions, function(k,v)
LT_Message(LT_FormatSessionName(v, true));
end);
LT_MessageUnindent();
return;
elseif (command == LT_SLASHCOMMAND_EXPORT) then
LT_ExportSession(value);
return;
elseif (command == LT_SLASHCOMMAND_SUMMARY) then
LT_OutputSummary(value);
return;
elseif (command == LT_SLASHCOMMAND_CHATCOLOR) then
if (value ~= nil) then
-- TODO: Validate that this parses comma separated RGB values as well as space values,
-- Because I don't think it does...
local beginMatch, endMatch, r, g, b = string.find(value, "(%d+)[%s,](%d+)[%s,](%d+)");
if (beginMatch) then
if ((r == nil) or (g == nil) or (b == nil)) then
LT_Message(LT_SLASHCOMMAND_CHATCOLOR_ERROR);
else
settings.ChatColor = {};
settings.ChatColor.r = r;
settings.ChatColor.g = g;
settings.ChatColor.b = b;
end
else
LT_Message(LT_SLASHCOMMAND_CHATCOLOR_ERROR);
end
end;
LT_Message(string.format(LT_SLASHCOMMAND_CHATCOLOR_QUERY, settings.ChatColor.r, settings.ChatColor.g, settings.ChatColor.b));
return;
elseif (command == LT_SLASHCOMMAND_THRESHOLD) then
if (value ~= nil) then
settings.QualityThreshold = tonumber(value);
LT_FireChange();
else
LT_Message(LT_SLASHCOMMAND_THRESHOLD_ERROR);
end
LT_Message(string.format(LT_SLASHCOMMAND_THRESHOLD_QUERY, settings.QualityThreshold));
return;
elseif (command == LT_SLASHCOMMAND_RESET) then
LT_ResetSession(value);
return;
elseif (command == LT_SLASHCOMMAND_UPDATE) then
if (value ~= nil) then
LT_UpdateObject(value);
else
LT_Message(LT_SLASHCOMMAND_UPDATE_ERROR);
end
return;
elseif (command == LT_SLASHCOMMAND_TRANSFER) then
if (value ~= nil) then
-- /lt transfer playerNameSource playerNameTarget itemName
local beginMatch, endMatch, playerNameSource, playerNameTarget, itemName = string.find(value, "([^%s]*)%s([^%s]*)%s(.*)");
if (beginMatch) then
LT_TransferItem(playerNameSource, playerNameTarget, itemName);
else
LT_Message(LT_SLASHCOMMAND_TRANSFER_ERROR);
end
end
return;
elseif (command == LT_SLASHCOMMAND_SETTINGS) then
if (LT_SettingsUI:IsShown()) then
HideUIPanel(LT_SettingsUI);
else
ShowUIPanel(LT_SettingsUI);
end
return;
elseif (command == LT_SLASHCOMMAND_HELP) then
-- Fall through to the help code below.
elseif (rawArgument ~= nil) then
LT_Message(string.format(LT_SLASHCOMMAND_ERROR, rawArgument));
end
-- Show the help
LT_Message(string.format(LT_HELPMESSAGE_1, LT_Version));
LT_Message(LT_HELPMESSAGE_2);
LT_Message(LT_HELPMESSAGE_3);
LT_Message(LT_HELPMESSAGE_4);
LT_Message(LT_HELPMESSAGE_5);
LT_Message(LT_HELPMESSAGE_6);
LT_Message(LT_HELPMESSAGE_7);
LT_Message(LT_HELPMESSAGE_8);
LT_Message(LT_HELPMESSAGE_9);
LT_Message(LT_HELPMESSAGE_10);
LT_Message(LT_HELPMESSAGE_11);
LT_Message(LT_HELPMESSAGE_12);
end
------------------------------------------------------------------------------
-- AddListener
------------------------------------------------------------------------------
function LT_AddListener(event)
if (LT_ChangeListeners == nil) then
LT_ChangeListeners = {};
end
tinsert(LT_ChangeListeners, event);
end
------------------------------------------------------------------------------
-- RemoveListener
------------------------------------------------------------------------------
function LT_RemoveListener(event)
if (LT_ChangeListeners == nil) then
return;
end
tremove(LT_ChangeListeners, LT_IndexOf(LT_ChangeListeners, event));
end
------------------------------------------------------------------------------
-- FireChange
------------------------------------------------------------------------------
function LT_FireChange()
if (LT_ChangeListeners ~= nil) then
foreach(LT_ChangeListeners, function(k,v)
v();
end);
end
end