PDA

View Full Version : DasLoot - My new mod has bugs I can't kill!!


Kjasi
09-10-2006, 12:21 AM
Hi! I'm working on a new mod that will track item drops from mobs, and record the information. (Basically, it's MobInfo2, except only for Loot, and with (I feel) a better database.)

The problem is, the code seems to run perfectly, (according to the debug msgs) but when I reload the UI to save the data, the data is all wrong. Every mob gets all the info! Every item, the total count of items looted listed per item, and all the money info is saved to every mob! The Item database gets fraked up too! All the items are listed as the same thing, even though they have the proper itemID headers...

I can't seem to get it to work correctly from a blank database. If the item & mob are already in the database, it works perfectly after a UI reload, but with a blank DB or unknown mob/item, I keep getting this error!

I could REALLY use some help here!

Here is the intended database hierachy:

DasLoot_Mobs
- [Faction] (Alliance or Horde)
-- [MobName]
--- [MobLevel]
---- ["loots"] (The number of times this mob has been looted)
---- ["emptyloots"] (the number if times you have looted this mob and nothing has been on it.)
---- ["items"]
----- [Item_ID] (The ItemID for this item)
------ ["looted"] (the Number of times this item has been looted from this Mob)
------ ["num_found"]
------- [num_count] = Times_Looted (The count number found, and how many times this number has been found.)
---- ["locations"]
----- [Locale] (What locale version is being played. Done for different location names in different locales)
------ Location_Names (The locations this mob has been when it has been killed &/or looted. IE: Wetlands, Durotar, Felwood)
---- ["money"]
----- [Money_Amount] = Times_Looted (The number of times we have see this particular money count from this Mob)

DasLoot_Loot
- [Item_ID]
-- ["name"]
--- [Locale] (What locale version is being played. Done for different item names in different locales)
---- [itemname] (Name of the item)
-- ["link"] (The link of the item)
-- ["rarity"] (How rare is the item)
-- ["minlvl"] (Minimum Level requirement for the item)
-- ["type"] (What type is it?)
-- ["subtype"] (What's it's subtype?)
-- ["stack"] (How many can be stacked together)
-- ["equipt"] (If equip-able, where?)
-- ["icon"] (The graphic icon for this item)
-- ["Mobs"] (Backwards compatible list of mobs that carry this item.)
--- [MobName]
---- [MobLevel]


Final note: This addon is also going to be tracking quest items, but I'm not going to get that working until the database records the info correctly!

My next post has the code.

Kjasi
09-10-2006, 12:26 AM
The code, edited for length. (I removed functions that aren't called, and a bunched of command-line stuff.)

-- Globals
DasLoot_Version = "0.250"; -- Use this to register that DasLoot is present!
local WoW_Version = "11200";
local DasLoot_Date = "October 5th, 2006"; -- Release Date
local DasLoot_Color1 = "|CFF00AA00";
local DasLoot_Color2 = "|CFF55AAFF";
local DasLoot_Corpses = {};

-- Defaults
local DasDefaults = {
-- Option defaults. Used for controlling DasLoot
["Options"] = {
["UseDatabase"] = true,
["UseImports"] = false,
["autocloseemptycorpse"] = true,
["Refresh"] = false,
["debug"] = false,
["version"] = DasLoot_Version,
},
-- The basic layout for the first tier of the Mob Database
["base_mobdb_layout"] = {
["loots"] = 0,
["emptyloots"] = 0,
["items"] = {},
["locations"] = {},
["money"] = {},
},
-- The basic layout for the items in the Mob Database
["base_mobdb_item_layout"] = {
["num_found"] = {},
},
-- The basic layout for items in the Item Database
["base_itemdb_layout"] = {
["name"] = {},
["link"] = 0,
["rarity"] = 0,
["minlvl"] = 0,
["type"] = 0,
["subtype"] = 0,
["stack"] = 0,
["equipt"] = 0,
["icon"] = 0,
["mobs"] = {},
},
};

-- Event List
local DasLoot_Events = {
"LOOT_OPENED",
"CHAT_MSG_COMBAT_HOSTILE_DEATH",
"PLAYER_TARGET_CHANGED",
};

-- Details for other addons (such as myAddOns) goes here
local DasLoot_Details = {
["myAddon"] = {
name = "DasLoot",
version = DasLoot_Version,
releaseDate = DasLoot_Date,
author = "Kjasi",
email = "sephiroth3d@gmx.net",
website = "None Yet",
notes = "This monitors and records loot drops, chances of a drop, and which mobs drop them.",
optionsframe = "None",
category = MYADDONS_CATEGORY_OTHERS,
},
};

-- Debug Message Output
function DasLoot_Debug (msg)
if (DasLoot_Options["debug"] == true) then
DEFAULT_CHAT_FRAME:AddMessage(DasLoot_Color1.."DasLoot"..DasLoot_Color2.." Debug Info: |r"..msg);
end
end

-- Things to register or start during loading
function DasLoot_Load ()
DEFAULT_CHAT_FRAME:AddMessage(DasLoot_Color1.."DasLoot |rloading database and variables...");

-- Single Registers
this:RegisterEvent("VARIABLES_LOADED");
-- Event Registers
for x=1, getn(DasLoot_Events),1 do
this:RegisterEvent(DasLoot_Events[x]);
end

SLASH_DL1 = "/dasloot";
SLASH_DL2 = "/dl";
SlashCmdList["DL"] = DasLoot_commandline;

--myAddOns support
if (myAddOnsFrame_Register) then
myAddOnsFrame_Register(DasLoot_Details["myAddon"]);
end
end

-- Post-Loading functions. Finishs the loading process.
function DasLoot_Loaded()
if (not DasLoot_Options) then
DasLoot_Options = DasDefaults["Options"];
DEFAULT_CHAT_FRAME:AddMessage(DasLoot_Color1.."DasLoot |rOptions Database not found. Generating...");
end

if (DasLoot_Options["version"] < DasLoot_Version) then
DasLoot_Options_temp = DasDefaults["Options"];
for k,v in DasLoot_Options do
if (DasDefaults["Options"][k]) then
DasLoot_Options_temp[k] = v;
end
end
DasLoot_Options_temp["version"] = DasLoot_Version;
DasLoot_Options = DasLoot_Options_temp;
end

DasLoot_Faction = UnitFactionGroup("player");
this_locale = GetLocale();

if (not DasLoot_Mobs) then
DasLoot_Mobs = {};
DEFAULT_CHAT_FRAME:AddMessage(DasLoot_Color1.."DasLoot |rMob Database not found. Generating...");
end
if (not DasLoot_Loot) then
DasLoot_Loot = {};
DEFAULT_CHAT_FRAME:AddMessage(DasLoot_Color1.."DasLoot |rLoot Database not found. Generating...");
end

DEFAULT_CHAT_FRAME:AddMessage(DasLoot_Color1.."DasLoot"..DasLoot_Color2.." v"..DasLoot_Version.."."..WoW_Version.." |rLoaded!");
end

-- Get the full Item ID from an item link
local function DasLoot_getitemID(i)
if (i~=nil) then
local k = strfind(i,"item:",0)+5;
local j = strfind(i,"\124h",k)-1;
local itemid = strsub(i,k,j);
DasLoot_Debug("Item ID for "..i.." is "..itemid.." taken from "..gsub(i, "\124", "\124\124"));
return tostring(itemid);
end
end

-- Get just the Item ID for an item link
local function DasLoot_getitemID2(i)
if (i~=nil) then
local k = strfind(i,"item:",0)+5;
local j = strfind(i,":",k)-1;
local itemid = strsub(i,k,j);
DasLoot_Debug("Item ID 2 for "..i.." is "..itemid.." taken from "..gsub(i, "\124", "\124\124"));
return tostring(itemid);
end
end

-- Check to see if the specified mob is already in our database. If not, insert the basic setup for it.
local function DasLoot_checkformob(mob,lvl)
DasLoot_Debug("Checking for the following Mob: "..mob..", level "..lvl..".");
if (not DasLoot_Mobs) then
DasLoot_Mobs = {};
end
if (not DasLoot_Mobs[DasLoot_Faction]) then
DasLoot_Mobs[DasLoot_Faction] = {};
end
if (not DasLoot_Mobs[DasLoot_Faction][mob]) then
DasLoot_Mobs[DasLoot_Faction][mob] = {};
end
if (not DasLoot_Mobs[DasLoot_Faction][mob][lvl]) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl] = {
["recorded"] = DasDefaults["base_mobdb_layout"],
};
end
end

-- Checks to see if the specified item has been looted from this mob before. If not, add the base info for it.
local function DasLoot_checkforitem(mob, lvl, item_link, quantity)
local itemid, itemid2, itemName, itemLink, rarity, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture = nil;
itemid = DasLoot_getitemID(item_link);
itemid2 = DasLoot_getitemID2(item_link);
itemName, itemLink, rarity, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture = GetItemInfo(itemid2);
local run_script = false;

-- Generate Info if not found.
if (not DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["items"][itemid]) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["items"][itemid] = DasDefaults["base_mobdb_item_layout"];
DasLoot_Debug("Item not found for this Mob. Adding MobDB item layout.");
end
if (not DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["items"][itemid]["num_found"][quantity]) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["items"][itemid]["num_found"][quantity] = 0;
DasLoot_Debug("Item quantity not found. Adding and setting to 0.");
end

-- Determine if the script should be ran
-- if this itemid is not found...
if (not DasLoot_Loot[itemid]) then
DasLoot_Loot[itemid] = DasDefaults["base_itemdb_layout"];
DasLoot_Debug("Adding Item Layout for itemid: "..itemid.."...");
run_script = true;
end
-- if we are refreshing with every loot...
if (DasLoot_Options["Refresh"] == true) then
run_script = true;
end

-- if this locale's item name is not found. THIS WILL NOT CAUSE THE SCRIPT TO RUN!!
if (not DasLoot_Loot[itemid]["name"][this_locale]) then
DasLoot_Loot[itemid]["name"][this_locale] = itemName;
end

if (run_script == true) then
DasLoot_Debug("Running Item Info script...");

DasLoot_Loot[itemid]["name"][this_locale] = itemName; -- In here just in case.
DasLoot_Loot[itemid]["link"] = itemLink;
DasLoot_Loot[itemid]["rarity"] = rarity;
DasLoot_Loot[itemid]["minlvl"] = itemMinLevel;
DasLoot_Loot[itemid]["type"] = itemType;
DasLoot_Loot[itemid]["subtype"] = itemSubType;
DasLoot_Loot[itemid]["stack"] = itemStackCount;
DasLoot_Loot[itemid]["equipt"] = itemEquipLoc;
DasLoot_Loot[itemid]["icon"] = itemTexture;

DasLoot_Debug("Check for Item script complete.");
end

-- Backwards compatible listing of which Mobs carry this item.
if (not DasLoot_Loot[itemid]["mobs"][DasLoot_Faction]) then
DasLoot_Loot[itemid]["mobs"][DasLoot_Faction] = {};
end
if (not DasLoot_Loot[itemid]["mobs"][DasLoot_Faction][mob]) then
DasLoot_Loot[itemid]["mobs"][DasLoot_Faction][mob] = {};
end
if (not DasLoot_Loot[itemid]["mobs"][DasLoot_Faction][mob][lvl]) then
DasLoot_Loot[itemid]["mobs"][DasLoot_Faction][mob][lvl] = true;
end
end

local function DasLoot_checkformoney(mob,lvl,money)
money2 = string.gsub(money,"\n"," ");
if (not DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["money"][money2]) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["money"][money2] = 0;
end
end

-- Stuff to do when our target Mob dies.
local function DasLoot_TargetDeath(mob,lvl)
DasLoot_checkformob(mob,lvl);
local thiszone = GetZoneText();
local thissubzone = GetSubZoneText();
if (thissubzone == "" or nil) then thissubzone = "None"; end

if (not DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["locations"][this_locale]) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["locations"][this_locale] = {};
end
if (not DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["locations"][this_locale][thiszone]) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["locations"][this_locale][thiszone] = {};
end
if (not DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["locations"][this_locale][thiszone][thissubzone]) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["locations"][this_locale][thiszone][thissubzone] = true;
DasLoot_Debug("Recorded a new location for "..mob..", level "..lvl.." at "..thissubzone.." in "..thiszone.." for the "..this_locale.." locale.");
else
DasLoot_Debug("The location for "..mob..", level "..lvl.." at "..thissubzone.." in "..thiszone.." for the "..this_locale.." locale, has previously been recorded.");
end
end

-- Check to see if we've already opened this corpse. Return false if we've never seen it before. Else, add to our list of opened corpses.
local function DasLoot_CheckCorpse(CorpseID)
local Reopen = false;

if (not CorpseID == false) then
DasLoot_Debug("Checking Corpse, Corpse ID: "..CorpseID);
if (DasLoot_Corpses[CorpseID]) then
Reopen = true;
DasLoot_Debug("Already found CorpseID "..CorpseID);
else
DasLoot_Corpses[CorpseID] = true;
DasLoot_Debug("Remembering CorpseID "..CorpseID);
end
else
DasLoot_Debug("Checking Corpse, Corpse ID: False");
end
return Reopen;
end

-- Generate a unique ID for the corpse.
local function DasLoot_CorpseID(mob,lvl)
local TempID = mob..lvl;
local numitems = GetNumLootItems();

if (numitems > 0) then
for item=1, numitems, 1 do
local lootIcon, lootName, quantity, rarity = GetLootSlotInfo(item);
if (LootSlotIsCoin(item)) then
TempID = TempID..lootName;
else
TempID = TempID..DasLoot_getitemID(GetLootSlotLink(item))..quantity;
end
end
DasLoot_Debug("Generating CorpseID for "..mob..", lvl "..lvl.." of "..TempID);
return TempID;
else
DasLoot_Debug("Not enough items to generate a CorpseID");
return false;
end
end

local function DasLoot_RecordLoot(this_mob, this_lvl, this_item_link, this_quantity)
DasLoot_checkformob(this_mob, this_lvl);
DasLoot_checkforitem(this_mob, this_lvl, this_item_link, this_quantity);

local itemid = DasLoot_getitemID(this_item_link);
local r_quantity = DasLoot_Mobs[DasLoot_Faction][this_mob][this_lvl]["recorded"]["items"][itemid]["num_found"][this_quantity] or 0;

DasLoot_Mobs[DasLoot_Faction][this_mob][this_lvl]["recorded"]["items"][itemid]["num_found"][this_quantity] = r_quantity + 1;

end

local function DasLoot_RecordMoney(that_mob, that_lvl, that_item_name)
DasLoot_checkformob(that_mob, that_lvl);
DasLoot_checkformoney(that_mob, that_lvl, that_item_name);
local money2 = string.gsub(that_item_name,"\n"," ");

local r_money = DasLoot_Mobs[DasLoot_Faction][that_mob][that_lvl]["recorded"]["money"][money2];

DasLoot_Mobs[DasLoot_Faction][that_mob][that_lvl]["recorded"]["money"][money2] = r_money + 1;

end

-- The Primary Corpse Code!
local function DasLoot_LootCorpse(mob,lvl)
-- Clear all previous data
local CorpseID, Reopen, loot_total, loot_count = nil;

-- Generate New data

DasLoot_checkformob(mob,lvl);
CorpseID = DasLoot_CorpseID(mob,lvl);
Reopen = DasLoot_CheckCorpse(CorpseID);
if (not CorpseID == false) then
DasLoot_Debug("Loot Corpse, Corpse ID: "..CorpseID..", Is Reopening: "..tostring(Reopen));
else
DasLoot_Debug("Loot Corpse, Corpse ID: False, Is Reopening: "..tostring(Reopen));
end

if (Reopen == false) then
loot_total = GetNumLootItems();
loot_count = DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["loots"];
if (loot_total == 0 or nil) then
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["emptyloots"] = DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["emptyloots"] + 1;
if (DasLoot_Options["autocloseemptycorpse"] == true) then
CloseLoot();
end
DasLoot_Debug("Empty Loot Recorded for "..mob.." level "..lvl..".");
else
for slot=1,loot_total,1 do
local item_link, loot_icon, loot_name, loot_quantity, loot_rarity = nil;
if (LootSlotIsCoin(slot)) then
loot_icon, loot_name, loot_quantity, loot_rarity = GetLootSlotInfo(slot);
DasLoot_RecordMoney(mob, lvl, loot_name);
DasLoot_Debug("Found the following money: "..string.gsub(loot_name,"\n"," ")..".");
else
loot_icon, loot_name, loot_quantity, loot_rarity = GetLootSlotInfo(slot);
item_link = GetLootSlotLink(slot);
DasLoot_RecordLoot(mob, lvl, item_link, loot_quantity);
DasLoot_Debug("Found "..loot_quantity.." of the following item: "..loot_name..".");
end
end
end
DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["loots"] = DasLoot_Mobs[DasLoot_Faction][mob][lvl]["recorded"]["loots"] + 1;
end
end

-- Event Handler!!
function DasLoot_EventScan(event,arg1)
if (event == "VARIABLES_LOADED") then
DasLoot_Loaded();
end
if (event == "LOOT_OPENED") then
if (UnitExists("target")) and (UnitIsDead("target")) then
local mob = UnitName("target");
local lvl = UnitLevel("target");
DasLoot_LootCorpse(mob,lvl);
mob, lvl = nil;
end
end
if (event == "CHAT_MSG_COMBAT_HOSTILE_DEATH") then
if (UnitIsDead("target")) and (UnitIsPlayer("target") == (false or nil)) then
local mob = UnitName("target");
local lvl = UnitLevel("target");
DasLoot_TargetDeath(mob,lvl);
mob, lvl = nil;
end
end
if (event == "PLAYER_TARGET_CHANGED") then
if (UnitExists("target") == true) and (UnitIsPlayer("target") == (false or nil)) then
local mob = UnitName("target");
local lvl = UnitLevel("target");
DasLoot_ChangeTarget(mob,lvl);
mob, lvl = nil;
end
end
end

-- Display Command-line messages
function DasLoot_CmdLine (msg)
DEFAULT_CHAT_FRAME:AddMessage(DasLoot_Color1.."DasLoot: "..DasLoot_Color2..msg);
end

-- Command Line handler
function DasLoot_commandline(cmd)
DasLoot_Debug("Current Command line: "..cmd);
-- Option Commands
-- Refresh Item Data on next loot
if (cmd == "refresh on") then
DasLoot_Options["Refresh"] = true;
DasLoot_CmdLine("Item data will now refresh your database every time you loot it.");
elseif (cmd == "refresh off") then
DasLoot_Options["Refresh"] = false;
DasLoot_CmdLine("Item data will now only record item data the first time you loot it.");

-- Debug messages
elseif (cmd == "debug on") then
DasLoot_Options["debug"] = true;
DasLoot_CmdLine("Debug messages will now be shown.");
elseif (cmd == "debug off") then
DasLoot_Options["debug"] = false;
DasLoot_CmdLine("Debug messages will no longer be shown.");

-- Delete Database Command, Shortened for testing only!
elseif (cmd == "delete") then
DasLoot_Options["UseDatabase"] = false;
DasLoot_Options["UseImports"] = false;
DasLoot_Mobs = {};
DasLoot_Loot = {};
DasLoot_CmdLine("Database Deleted. Please logout of WoW, or reload the UI to complete the process. Good luck rebuilding it!");

-- Catch All
else
DasLoot_CmdLine("Help:");
DEFAULT_CHAT_FRAME:AddMessage(" Database Delete - Delete the Mob and Item Databases. Start from scratch.");
DEFAULT_CHAT_FRAME:AddMessage(" Debug (on|off) - Turn on or off the DasLoot Debug messages.");
DEFAULT_CHAT_FRAME:AddMessage(" Itemid [Item_Link] - Run the itemID code.");
end
end


Any suggestions on how to fix this?

Flymo
09-10-2006, 08:28 AM
Could do with seeing your .toc file to see which variables are saved when you refresh the UI

Kjasi
10-10-2006, 02:48 AM
My TOC saved vars are:
## SavedVariables: DasLoot_Options, DasLoot_Mobs, DasLoot_Loot