1696 lines
52 KiB
Lua
Executable File
1696 lines
52 KiB
Lua
Executable File
-- FishingBuddy
|
|
--
|
|
-- Everything you wanted support for in your fishing endeavors
|
|
|
|
-- Information for the stylin' fisherman
|
|
local POLES = {
|
|
["Fishing Pole"] = "6256:0:0:0",
|
|
["Strong Fishing Pole"] = "6365:0:0:0",
|
|
["Darkwood Fishing Pole"] = "6366:0:0:0",
|
|
["Big Iron Fishing Pole"] = "6367:0:0:0",
|
|
["Driftwood Fishing Pole"] = "7010:0:0:0",
|
|
["Blump Family Fishing Pole"] = "12225:0:0:0",
|
|
["Nat Pagle's Extreme Angler FC-5000"] = "19022:0:0:0",
|
|
["Arcanite Fishing Pole"] = "19970:0:0:0",
|
|
["Crude Fishing Rod"] = "42096:0:0:0",
|
|
["Reliable Fishing Rod"] = "42105:0:0:0",
|
|
["Mastercraft Fishing Rod"] = "42123:0:0:0",
|
|
-- yeah, so you can't really use these (for now :-)
|
|
["Dwarven Fishing Pole"] = "3567:0:0:0",
|
|
["Goblin Fishing Pole"] = "4598:0:0:0",
|
|
}
|
|
|
|
local FISHINGLURES = {
|
|
[114] = "Simple Fishing Lure", -- 50 for 10 mins
|
|
[125] = "Spicy Fishing Lure", -- 75 for 10 mins
|
|
[133] = "Savory Fishing Lure", -- 100 for 5 mins
|
|
[145] = "Premium Fishing Lure", -- 125 for 5 mins
|
|
[6533] = "Aquadynamic Fish Attractor", -- 100 for 5 mins
|
|
[7307] = "Flesh Eating Worm", -- 75 for 10 mins
|
|
[6532] = "Bright Baubles", -- 75 for 10 mins
|
|
[6811] = "Aquadynamic Fish Lens", -- 50 for 10 mins
|
|
[6530] = "Nightcrawlers", -- 50 for 10 mins
|
|
[6529] = "Shiny Bauble", -- 25 for 10 mins
|
|
}
|
|
|
|
FishingBuddy.OPTIONS = {
|
|
["ShowNewFishies"] = {
|
|
["text"] = FishingBuddy.CONFIG_SHOWNEWFISHIES_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_SHOWNEWFISHIES_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 1 },
|
|
["WatchFishies"] = {
|
|
["text"] = FishingBuddy.CONFIG_FISHWATCH_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_FISHWATCH_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 1 },
|
|
["WatchCurrentSkill"] = {
|
|
["text"] = FishingBuddy.CONFIG_FISHWATCHSKILL_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_FISHWATCHSKILL_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 1,
|
|
["deps"] = { ["WatchFishies"] = "d" } },
|
|
["WatchCurrentZone"] = {
|
|
["text"] = FishingBuddy.CONFIG_FISHWATCHZONE_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_FISHWATCHZONE_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 0,
|
|
["deps"] = { ["WatchFishies"] = "d" } },
|
|
["WatchOnlyWhenFishing"] = {
|
|
["text"] = FishingBuddy.CONFIG_FISHWATCHONLY_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_FISHWATCHONLY_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 1,
|
|
["deps"] = { ["WatchFishies"] = "d" } },
|
|
["WatchFishPercent"] = {
|
|
["text"] = FishingBuddy.CONFIG_FISHWATCHPERCENT_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_FISHWATCHPERCENT_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 1,
|
|
["deps"] = { ["WatchFishies"] = "d" } },
|
|
["SortByPercent"] = {
|
|
["text"] = FishingBuddy.CONFIG_SORTBYPERCENT_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_SORTBYPERCENT_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 1 },
|
|
["SuitUpFirst"] = {
|
|
["text"] = FishingBuddy.CONFIG_SUITUPFIRST_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_SUITUPFIRST_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 0 },
|
|
["EasyCast"] = {
|
|
["text"] = FishingBuddy.CONFIG_EASYCAST_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_EASYCAST_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 1 },
|
|
["EasyLures"] = {
|
|
["text"] = FishingBuddy.CONFIG_EASYLURES_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_EASYLURES_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 0 },
|
|
["STVTimer"] = {
|
|
["text"] = FishingBuddy.CONFIG_STVTIMER_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_STVTIMER_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 0 },
|
|
["STVPoolsOnly"] = {
|
|
["text"] = FishingBuddy.CONFIG_STVPOOLSONLY_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_STVPOOLSONLY_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 0,
|
|
["deps"] = { ["STVTimer"] = "d", ["EasyCast"] = "d" } },
|
|
["UseButtonHole"] = {
|
|
["text"] = FishingBuddy.CONFIG_USEBUTTONHOLE_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_USEBUTTONHOLE_INFO,
|
|
["v"] = 1,
|
|
["default"] = 0,
|
|
["check"] = function () return ButtonHole ~= nil; end,
|
|
["checkfail"] = 0 },
|
|
["UseGatherer"] = {
|
|
["text"] = FishingBuddy.CONFIG_USEGATHERER_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_USEGATHERER_INFO,
|
|
["v"] = 1,
|
|
["default"] = 0,
|
|
["check"] = function () return Gatherer_OnLoad ~= nil; end,
|
|
["checkfail"] = 0 },
|
|
["MinimapButtonVisible"] = {
|
|
["tooltip"] = FishingBuddy.CONFIG_MINIMAPBUTTON_INFO,
|
|
["v"] = 1,
|
|
["default"] = 1,
|
|
["check"] = function () return not FishingBuddy.UseButtonHole(); end,
|
|
["checkfail"] = 0,
|
|
["update"] = function(checked)
|
|
local b = FishingBuddyOption_MinimapButtonVisible;
|
|
if ( b:GetChecked() ) then
|
|
b.text = "";
|
|
else
|
|
b.text = FishingBuddy.CONFIG_MINIMAPBUTTON_ONOFF;
|
|
end
|
|
FishingBuddyOption_MinimapButtonVisibleText:SetText(b.text);
|
|
end,
|
|
},
|
|
["EnhanceFishingSounds"] = {
|
|
["text"] = FishingBuddy.CONFIG_ENHANCESOUNDS_ONOFF,
|
|
["tooltip"] = FishingBuddy.CONFIG_ENHANCESOUNDS_INFO,
|
|
["v"] = 1,
|
|
["m"] = 1,
|
|
["default"] = 0 },
|
|
-- options not in a menu
|
|
["ShowLocationZones"] = {
|
|
["default"] = 1,
|
|
},
|
|
["GroupByLocation"] = {
|
|
["default"] = 1,
|
|
},
|
|
["TitanClickToSwitch"] = {
|
|
["default"] = 1,
|
|
},
|
|
["FubarClickToSwitch"] = {
|
|
["default"] = 1,
|
|
},
|
|
["InfoBarClickToSwitch"] = {
|
|
["default"] = 1,
|
|
},
|
|
["MinimapClickToSwitch"] = {
|
|
["default"] = 0,
|
|
},
|
|
["EasyCastKeys"] = {
|
|
["default"] = FishingBuddy.KEYS_NONE,
|
|
["deps"] = { ["EasyCast"] = "h" },
|
|
},
|
|
["SuitUpKeys"] = {
|
|
["default"] = FishingBuddy.KEYS_NONE,
|
|
},
|
|
["EnhanceSoundSoundVolume"] = {
|
|
["default"] = 1.0,
|
|
},
|
|
["EnhanceSoundMusicVolume"] = {
|
|
["default"] = 0.0,
|
|
},
|
|
["EnhanceSoundAmbienceVolume"] = {
|
|
["default"] = 0.0,
|
|
},
|
|
["MinimapButtonPosition"] = {
|
|
["default"] = FishingBuddy.DEFAULT_MINIMAP_POSITION,
|
|
},
|
|
["MinimapPosSlider"] = {
|
|
["deps"] = { ["MinimapButtonVisible"] = "h", },
|
|
},
|
|
["ClockOffset"] = {
|
|
["default"] = 0,
|
|
["deps"] = { ["STVTimer"] = "h" },
|
|
["visible"] = function()
|
|
if ( FishingBuddy.ClockOffsets ) then
|
|
return 1;
|
|
else
|
|
return 0;
|
|
end;
|
|
end,
|
|
},
|
|
["OutfitManager"] = {
|
|
["default"] = "OutfitDisplayFrame",
|
|
},
|
|
}
|
|
|
|
FishingBuddy.ByFishie = nil;
|
|
FishingBuddy.SortedFishies = nil;
|
|
|
|
local ActionStartTime = 0;
|
|
local ActionDoubleTime = 0;
|
|
local ACTIONDOWNWAIT = 0.2;
|
|
local ACTIONDOUBLEWAIT = 0.4;
|
|
local SavedAddMessage = nil;
|
|
|
|
FishingBuddy.SavedToggleMinimap = nil;
|
|
|
|
FishingBuddy.StartedFishing = nil;
|
|
|
|
local TestingLures = false;
|
|
local CastingNow = false;
|
|
local AddingLure = false;
|
|
local IsLooting = false;
|
|
|
|
local FishingSpellID = nil;
|
|
local FishingSkillName = nil;
|
|
|
|
local gotSetupDone = false;
|
|
local playerName = nil;
|
|
local realmName = nil;
|
|
local schooltipText = nil;
|
|
|
|
FishingBuddy.currentFishies = {};
|
|
|
|
local DEFAULT_MINIMAP_POSITION = 256;
|
|
|
|
local function GetDefault(setting)
|
|
local opt = FishingBuddy.OPTIONS[setting];
|
|
if ( opt ) then
|
|
if ( opt.check and opt.checkfail ) then
|
|
if ( not opt.check() ) then
|
|
return opt.checkfail;
|
|
end
|
|
end
|
|
return opt.default;
|
|
end
|
|
end
|
|
FishingBuddy.GetDefault = GetDefault;
|
|
|
|
local function GetSetting(setting)
|
|
if ( not FishingBuddy_Player or
|
|
not FishingBuddy_Player["Settings"] ) then
|
|
return;
|
|
end
|
|
local val = FishingBuddy_Player["Settings"][setting];
|
|
if ( val == nil ) then
|
|
val = GetDefault(setting);
|
|
end
|
|
return val;
|
|
end
|
|
FishingBuddy.GetSetting = GetSetting;
|
|
|
|
local function SetSetting(setting, value)
|
|
if ( FishingBuddy_Player and setting ) then
|
|
local val = GetDefault(setting);
|
|
if ( val == value ) then
|
|
FishingBuddy_Player["Settings"][setting] = nil;
|
|
else
|
|
FishingBuddy_Player["Settings"][setting] = value;
|
|
end
|
|
end
|
|
end
|
|
FishingBuddy.SetSetting = SetSetting;
|
|
|
|
local function SetClockOffset(offset)
|
|
if ( not FishingBuddy_Info["ClockOffsets"] ) then
|
|
FishingBuddy_Info["ClockOffsets"] = {};
|
|
end
|
|
if ( offset == 0 ) then
|
|
FishingBuddy_Info["ClockOffsets"][realmName] = nil;
|
|
else
|
|
FishingBuddy_Info["ClockOffsets"][realmName] = offset;
|
|
end
|
|
end
|
|
FishingBuddy.SetClockOffset = SetClockOffset;
|
|
|
|
local function GetClockOffset()
|
|
if ( not FishingBuddy_Info["ClockOffsets"] or
|
|
not FishingBuddy_Info["ClockOffsets"][realmName] ) then
|
|
return 0;
|
|
end
|
|
return FishingBuddy_Info["ClockOffsets"][realmName];
|
|
end
|
|
FishingBuddy.GetClockOffset = GetClockOffset;
|
|
|
|
-- We have to do this at PLAYER_ENTERING_WORLD or PLAYER_LOGIN
|
|
-- GetGameTime isn't correct at VARIABLES_LOADED
|
|
local function CheckClockOffset()
|
|
local hour,minute = GetGameTime();
|
|
local lhour = date("%H");
|
|
local lminute = date("%M");
|
|
local houroff;
|
|
houroff = hour - lhour;
|
|
if ( houroff ~= 0 ) then
|
|
local houroff24;
|
|
if ( houroff < 0 ) then
|
|
houroff24 = 24 + houroff;
|
|
else
|
|
houroff24 = houroff - 24;
|
|
end
|
|
local offsets = { houroff, houroff24 };
|
|
FishingBuddy.ClockOffsets = offsets;
|
|
local current = GetClockOffset();
|
|
-- don't change it if we've already got a good value
|
|
if ( current ~= houroff and current ~= houroff24 ) then
|
|
SetClockOffset(houroff);
|
|
end
|
|
else
|
|
FishingBuddy.ClockOffsets = nil;
|
|
SetClockOffset(0);
|
|
end
|
|
-- Set up the menu and such
|
|
FishingBuddy.OptionsFrame.SetClockValues(GetClockOffset());
|
|
end
|
|
|
|
-- look at tooltips
|
|
local function GetTooltipText()
|
|
local text = "";
|
|
if ( GameTooltip:IsVisible() ) then
|
|
text = getglobal("GameTooltipTextLeft1");
|
|
if ( text ) then
|
|
return text:GetText();
|
|
end
|
|
end
|
|
return nil;
|
|
end
|
|
FishingBuddy.GetTooltipText = GetTooltipText;
|
|
|
|
local function OnFishingBobber()
|
|
local text = GetTooltipText();
|
|
if ( text ) then
|
|
-- let a partial match work (for translations)
|
|
return ( text and string.find(text, FishingBuddy.BOBBER_NAME ) );
|
|
end
|
|
return false;
|
|
end
|
|
|
|
-- support finding the fishing skill
|
|
local function FindSpellID(thisone)
|
|
local id = 1;
|
|
local spellTexture = GetSpellTexture(id, BOOKTYPE_SPELL);
|
|
while (spellTexture) do
|
|
if (spellTexture and spellTexture == thisone) then
|
|
return id;
|
|
end
|
|
id = id + 1;
|
|
spellTexture = GetSpellTexture(id, BOOKTYPE_SPELL);
|
|
end
|
|
return nil;
|
|
end
|
|
|
|
local function GetFishingSpellID()
|
|
if ( not FishingSpellID or not FishingSkillName) then
|
|
FishingSpellID = FindSpellID(FishingBuddy.FISHINGTEXTURE);
|
|
end
|
|
if ( FishingSpellID and not FishingSkillName ) then
|
|
FishingSkillName = GetSpellName(FishingSpellID, BOOKTYPE_SPELL);
|
|
end
|
|
end
|
|
|
|
local function GetFishingSkillName()
|
|
GetFishingSpellID();
|
|
if ( not FishingSkillName ) then
|
|
return FishingBuddy.FISHINGSKILL;
|
|
else
|
|
return FishingSkillName;
|
|
end
|
|
end
|
|
FishingBuddy.GetFishingSkillName = GetFishingSkillName;
|
|
|
|
-- handle option keys for enabling casting
|
|
local key_actions = {
|
|
[FishingBuddy.KEYS_NONE] = function() return true; end,
|
|
[FishingBuddy.KEYS_SHIFT] = function() return IsShiftKeyDown(); end,
|
|
[FishingBuddy.KEYS_CTRL] = function() return IsControlKeyDown(); end,
|
|
[FishingBuddy.KEYS_ALT] = function() return IsAltKeyDown(); end,
|
|
}
|
|
local function CastingKeys()
|
|
local setting = GetSetting("EasyCastKeys");
|
|
if ( setting and key_actions[setting] ) then
|
|
return key_actions[setting]();
|
|
else
|
|
return true;
|
|
end
|
|
end
|
|
|
|
-- get our current fishing skill level
|
|
local lastSkillIndex = nil;
|
|
local function GetCurrentSkill()
|
|
if ( lastSkillIndex ) then
|
|
local name, _, _, rank, _, modifier = GetSkillLineInfo(lastSkillIndex);
|
|
if ( name == GetFishingSkillName() )then
|
|
return rank, modifier;
|
|
end
|
|
end
|
|
local n = GetNumSkillLines();
|
|
for i=1,n do
|
|
local name, _, _, rank, _, modifier = GetSkillLineInfo(i);
|
|
if ( name == GetFishingSkillName() ) then
|
|
lastSkillIndex = i;
|
|
return rank, modifier;
|
|
end
|
|
end
|
|
return 0, 0;
|
|
end
|
|
FishingBuddy.GetCurrentSkill = GetCurrentSkill;
|
|
|
|
-- handle dynamic event registration
|
|
local function EventRegistration(frame, events, reg)
|
|
for _,evt in events do
|
|
if ( reg ) then
|
|
frame:RegisterEvent(evt);
|
|
else
|
|
frame:UnregisterEvent(evt);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- handle the vagaries of zones and subzones
|
|
local function GetZoneInfo()
|
|
local zone = GetRealZoneText();
|
|
local subzone = GetSubZoneText();
|
|
if ( not zone or zone == "" ) then
|
|
zone = FishingBuddy.UNKNOWN;
|
|
end
|
|
if ( not subzone or subzone == "" ) then
|
|
subzone = zone;
|
|
end
|
|
return zone, subzone;
|
|
end
|
|
FishingBuddy.GetZoneInfo = GetZoneInfo;
|
|
|
|
local zonemapping;
|
|
local subzonemapping;
|
|
|
|
local function DumpMappings()
|
|
FishingBuddy.Debug("Zone mapping");
|
|
FishingBuddy.Dump(zonemapping);
|
|
FishingBuddy.Debug("SubZone mapping");
|
|
FishingBuddy.Dump(subzonemapping);
|
|
end
|
|
FishingBuddy.DumpMappings = DumpMappings;
|
|
|
|
local function GetZoneIndex(zone, subzone)
|
|
if ( not zone ) then
|
|
zone, subzone = GetZoneInfo();
|
|
end
|
|
if ( not zonemapping ) then
|
|
zonemapping = {};
|
|
for idx,z in FishingBuddy_Info["ZoneIndex"] do
|
|
zonemapping[z] = idx;
|
|
end
|
|
end
|
|
local zidx = zonemapping[zone];
|
|
if ( not subzonemapping ) then
|
|
subzonemapping = {};
|
|
for idx,_ in FishingBuddy_Info["ZoneIndex"] do
|
|
subzonemapping[idx] = {};
|
|
if ( FishingBuddy_Info["SubZones"][idx] ) then
|
|
for jdx,sz in FishingBuddy_Info["SubZones"][idx] do
|
|
subzonemapping[idx][sz] = jdx;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if ( not zidx ) then
|
|
return;
|
|
end
|
|
if ( not subzonemapping[zidx] ) then
|
|
subzonemapping[zidx] = {};
|
|
end
|
|
if ( not subzone or not subzonemapping[zidx][subzone] ) then
|
|
return zidx;
|
|
end
|
|
return zidx, subzonemapping[zidx][subzone];
|
|
end
|
|
FishingBuddy.GetZoneIndex = GetZoneIndex;
|
|
|
|
local function AddZoneIndex(zone, subzone)
|
|
if ( not zone ) then
|
|
zone, subzone = GetZoneInfo();
|
|
end
|
|
if ( type(zone) ~= "string" ) then
|
|
FishingBuddy.Debug("AddZoneIndex "..zone);
|
|
end
|
|
local zidx, sidx = GetZoneIndex(zone, subzone);
|
|
if ( not zidx ) then
|
|
tinsert(FishingBuddy_Info["ZoneIndex"], zone);
|
|
zidx = table.getn(FishingBuddy_Info["ZoneIndex"]);
|
|
zonemapping[zone] = zidx;
|
|
-- keep sort helpers up to date
|
|
if ( FishingBuddy.SortedZones ) then
|
|
tinsert(FishingBuddy.SortedZones, zone);
|
|
table.sort(FishingBuddy.SortedZones);
|
|
end
|
|
end
|
|
if ( not subzone ) then
|
|
return zidx;
|
|
end
|
|
if ( not subzonemapping[zidx] ) then
|
|
subzonemapping[zidx] = {};
|
|
end
|
|
if ( not subzonemapping[zidx][subzone] ) then
|
|
if ( not FishingBuddy_Info["SubZones"][zidx] ) then
|
|
FishingBuddy_Info["SubZones"][zidx] = {};
|
|
end
|
|
tinsert(FishingBuddy_Info["SubZones"][zidx], subzone);
|
|
subzonemapping[zidx][subzone] = table.getn(FishingBuddy_Info["SubZones"][zidx]);
|
|
-- keep sort helpers up to date
|
|
if ( FishingBuddy.SortedByZone ) then
|
|
FishingBuddy.SortedByZone[zone] = {};
|
|
tinsert(FishingBuddy.SortedByZone[zone], subzone);
|
|
table.sort(FishingBuddy.SortedByZone[zone]);
|
|
tinsert(FishingBuddy.SortedSubZones, subzone);
|
|
table.sort(FishingBuddy.SortedSubZones);
|
|
end
|
|
end
|
|
return zidx, subzonemapping[zidx][subzone];
|
|
end
|
|
FishingBuddy.AddZoneIndex = AddZoneIndex;
|
|
|
|
local function SetZoneLevel(zone, subzone, fishid)
|
|
local skill, mods = GetCurrentSkill();
|
|
local zidx, sidx = GetZoneIndex(zone, subzone);
|
|
local fs = FishingBuddy_Info["FishingSkill"];
|
|
if ( not fs[zidx] ) then
|
|
fs[zidx] = {};
|
|
end
|
|
local skillcheck = skill + mods;
|
|
if ( skillcheck > 0 ) then
|
|
if ( not fs[zidx][sidx] or skillcheck < fs[zidx][sidx] ) then
|
|
fs[zidx][sidx] = skillcheck;
|
|
end
|
|
if ( fishid ) then
|
|
if ( not FishingBuddy_Info["Fishies"][fishid].level or
|
|
skillcheck < FishingBuddy_Info["Fishies"][fishid].level ) then
|
|
FishingBuddy_Info["Fishies"][fishid].level = skillcheck;
|
|
FishingBuddy_Info["Fishies"][fishid].skill = skill;
|
|
FishingBuddy_Info["Fishies"][fishid].mods = mods;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
FishingBuddy.SetZoneLevel = SetZoneLevel;
|
|
|
|
local OldBindingKey;
|
|
local OldBindingKey2;
|
|
local function UpdateBindings(onoff)
|
|
if ( onoff ) then
|
|
if ( not OldKeyBinding ) then
|
|
OldKeyBinding, OldBindingKey2 = GetBindingKey("TURNORACTION");
|
|
if ( OldKeyBinding ) then
|
|
SetBinding(OldKeyBinding, "FISHINGBUDDY_PERFORMCAST");
|
|
if (OldBindingKey2) then
|
|
SetBinding(OldBindingKey2, "FISHINGBUDDY_PERFORMCAST");
|
|
end
|
|
else
|
|
FishingBuddy.UIError(FishingBuddy.TOOMANYFISHERMEN);
|
|
end
|
|
end
|
|
else
|
|
if ( OldKeyBinding ) then
|
|
SetBinding(OldKeyBinding, "TURNORACTION");
|
|
OldKeyBinding = nil;
|
|
if (OldBindingKey2) then
|
|
SetBinding(OldBindingKey2, "TURNORACTION");
|
|
OldBindingKey2 = nil;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
FishingBuddy.UpdateBindings = UpdateBindings;
|
|
|
|
-- Something else that should be in a library
|
|
local function SplitLink(link)
|
|
if ( link ) then
|
|
local _,_, color, item, name = string.find(link, "|c(%x+)|Hitem:(%d+:%d+:%d+:%d+)|h%[(.-)%]|h|r");
|
|
return color, item, name;
|
|
end
|
|
end
|
|
FishingBuddy.SplitLink = SplitLink;
|
|
|
|
local function SplitFishLink(link)
|
|
if ( link ) then
|
|
local _,_, color, id, name = string.find(link, "|c(%x+)|Hitem:(%d+):%d+:%d+:%d+|h%[(.-)%]|h|r");
|
|
return color, tonumber(id), name;
|
|
end
|
|
end
|
|
FishingBuddy.SplitFishLink = SplitFishLink;
|
|
|
|
local function IsLinkableItem(item)
|
|
local link = "item:"..item;
|
|
local n,l,_,_,_,_,_,_ = GetItemInfo(link);
|
|
return ( n and l );
|
|
end
|
|
FishingBuddy.IsLinkableItem = IsLinkableItem;
|
|
|
|
-- Shamelessly stolen from TackleBox
|
|
local function IsFishingPole()
|
|
-- Get the main hand item texture
|
|
local slot = GetInventorySlotInfo("MainHandSlot");
|
|
local itemTexture = GetInventoryItemTexture("player", slot);
|
|
-- If there is infact an item in the main hand, and it's texture
|
|
-- that matches the fishing pole texture, then we have a fishing pole
|
|
if ( itemTexture and string.find(itemTexture, "INV_Fishingpole") ) then
|
|
local link = GetInventoryItemLink("player", slot);
|
|
local _, id, _ = SplitLink(link);
|
|
-- Make sure it's not "Nat Pagle's Fish Terminator"
|
|
if ( not string.find(id, "^19944") ) then
|
|
return true;
|
|
end
|
|
end
|
|
return false;
|
|
end
|
|
FishingBuddy.API.IsFishingPole = IsFishingPole;
|
|
|
|
-- override the error message method (need an object as the first arg)
|
|
local function UIError_AddMessage( o, msg, a, r, g, b, hold )
|
|
-- If we should be hiding the can't use item error, then do so
|
|
if ( TestingLures and msg == ERR_CANT_USE_ITEM ) then
|
|
-- We have the can't use item error, so abort
|
|
return;
|
|
end
|
|
--Call the original
|
|
local obj = SavedAddMessage.obj;
|
|
local method = SavedAddMessage.method;
|
|
return method( obj, msg, a, r, g, b, hold );
|
|
end
|
|
FishingBuddy.AddMessage = UIError_AddMessage;
|
|
|
|
local function NormalHijackCheck()
|
|
if ( GetSetting("EasyCast") == 1 and
|
|
CastingKeys() and IsFishingPole() ) then
|
|
return true;
|
|
end
|
|
end
|
|
FishingBuddy.NormalHijackCheck = NormalHijackCheck;
|
|
|
|
local HijackCheck = NormalHijackCheck;
|
|
local function SetHijackCheck(func)
|
|
if ( not func ) then
|
|
func = NormalHijackCheck;
|
|
end
|
|
HijackCheck = func;
|
|
end
|
|
FishingBuddy.SetHijackCheck = SetHijackCheck;
|
|
|
|
local SavedWFOnMouseUp;
|
|
local SavedWFOnMouseDown;
|
|
-- handle mouse up and mouse down in the WorldFrame so that we can steal
|
|
-- the hardware events to implement 'Easy Cast'
|
|
-- Thanks to the Cosmos team for figuring this one out -- I didn't realize
|
|
-- that the mouse handler in the WorldFrame got everything first!
|
|
local function WF_OnMouseDown()
|
|
-- Only steal 'right clicks'
|
|
if ( arg1 == "RightButton" and HijackCheck() ) then
|
|
FishingBuddy.ActionStartCheck();
|
|
end
|
|
if ( SavedWFOnMouseDown ) then
|
|
SavedWFOnMouseDown();
|
|
end
|
|
end
|
|
|
|
-- disable click to move if we're fishing
|
|
local resetClickToMove = false;
|
|
local function WF_OnMouseUp()
|
|
local retval;
|
|
if ( SavedWFOnMouseUp ) then
|
|
retval = SavedWFOnMouseUp();
|
|
end
|
|
-- Only steal 'right clicks'
|
|
if ( arg1 == "RightButton" ) then
|
|
-- we fail if there are multiple modifier keys
|
|
if ( IsAltKeyDown() and ( IsShiftKeyDown() or IsControlKeyDown() ) ) then
|
|
return retval;
|
|
end
|
|
if ( IsShiftKeyDown() and IsControlKeyDown() ) then
|
|
return retval;
|
|
end
|
|
if ( HijackCheck() ) then
|
|
FishingBuddy.StopCastingCheck();
|
|
elseif ( resetClickToMove ) then
|
|
-- Re-enable Click-to-Move if we changed it
|
|
SetCVar("autointeract", "1");
|
|
resetClickToMove = nil;
|
|
end
|
|
end
|
|
return retval;
|
|
end
|
|
|
|
-- Find things in our inventory
|
|
local function FindItemByID(id)
|
|
if ( id ) then
|
|
local numSlots = 0;
|
|
-- check each of the bags on the player
|
|
for bag=0, NUM_BAG_FRAMES do
|
|
-- get the number of slots in the bag (0 if no bag)
|
|
numSlots = GetContainerNumSlots(bag);
|
|
if (numSlots > 0) then
|
|
-- check each slot in the bag
|
|
for slot=1, numSlots do
|
|
local link = GetContainerItemLink (bag,slot);
|
|
if (link) then
|
|
local c, check, n = SplitFishLink(link);
|
|
if ( check == id ) then
|
|
return bag, slot;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return nil, nil;
|
|
end
|
|
|
|
local function SafeHookMethod(object, method, newmethod)
|
|
local oldValue = object[method];
|
|
if ( oldValue ~= getglobal(newmethod) ) then
|
|
object[method] = newmethod;
|
|
return true;
|
|
end
|
|
return false;
|
|
end
|
|
|
|
local function SafeHookScript(frame, handlername, newscript)
|
|
local oldValue = frame:GetScript(handlername);
|
|
frame:SetScript(handlername, newscript);
|
|
return oldValue;
|
|
end
|
|
|
|
local function AddFishie(color, id, name, zone, subzone, texture, quantity, quality)
|
|
if ( not FishingBuddy_Info["Fishies"][id] ) then
|
|
FishingBuddy_Info["Fishies"][id] = { };
|
|
FishingBuddy_Info["Fishies"][id].name = name;
|
|
FishingBuddy_Info["Fishies"][id].texture = texture;
|
|
FishingBuddy_Info["Fishies"][id].quality = quality;
|
|
if ( color ~= "ffffffff" ) then
|
|
FishingBuddy_Info["Fishies"][id].color = color;
|
|
end
|
|
if ( FishingBuddy.SortedFishies ) then
|
|
tinsert(FishingBuddy.SortedFishies, { text = name, id = id });
|
|
FishingBuddy.FishSort(FishingBuddy.SortedFishies, true);
|
|
end
|
|
end
|
|
if ( name and not FishingBuddy_Info["Fishies"][id].name ) then
|
|
FishingBuddy_Info["Fishies"][id].name = name;
|
|
end
|
|
|
|
if ( not zone ) then
|
|
zone = FishingBuddy.UNKNOWN;
|
|
end
|
|
if ( not subzone ) then
|
|
subzone = zone;
|
|
end
|
|
local zidx, sidx = AddZoneIndex(zone, subzone);
|
|
|
|
if ( not FishingBuddy.currentFishies[sidx] ) then
|
|
FishingBuddy.currentFishies[sidx] = {};
|
|
end
|
|
if ( not FishingBuddy.currentFishies[sidx][id] ) then
|
|
FishingBuddy.currentFishies[sidx][id] = quantity;
|
|
else
|
|
FishingBuddy.currentFishies[sidx][id] = FishingBuddy.currentFishies[sidx][id] + quantity;
|
|
end
|
|
|
|
if( not FishingBuddy_Info["FishingHoles"][zidx] ) then
|
|
FishingBuddy_Info["FishingHoles"][zidx] = { };
|
|
end
|
|
if( not FishingBuddy_Info["FishingHoles"][zidx][sidx] ) then
|
|
FishingBuddy_Info["FishingHoles"][zidx][sidx] = { };
|
|
end
|
|
local fh = FishingBuddy_Info["FishingHoles"][zidx];
|
|
if ( not fh[sidx][id] ) then
|
|
fh[sidx][id] = quantity;
|
|
if ( GetSetting("ShowNewFishies") == 1 ) then
|
|
FishingBuddy.Print(FishingBuddy.ADDFISHIEMSG, name, subzone);
|
|
end
|
|
else
|
|
fh[sidx][id] = fh[sidx][id] + quantity;
|
|
end
|
|
|
|
if ( FishingBuddy.ByFishie ) then
|
|
if ( not FishingBuddy.ByFishie[id] ) then
|
|
FishingBuddy.ByFishie[id] = {};
|
|
end
|
|
if ( not FishingBuddy.ByFishie[id][subzone] ) then
|
|
FishingBuddy.ByFishie[id][sidx] = quantity;
|
|
else
|
|
FishingBuddy.ByFishie[id][sidx] = FishingBuddy.ByFishie[id][sidx] + quantity;
|
|
end
|
|
end
|
|
FishingBuddy.Locations.DataChanged(zone, subzone, fishie);
|
|
FishingBuddy.WatchUpdate();
|
|
end
|
|
FishingBuddy.AddFishie = AddFishie;
|
|
|
|
FishingBuddy.GetFishie = function(fishid)
|
|
if( FishingBuddy_Info["Fishies"][fishid] ) then
|
|
return string.format("%d:0:0:0", fishid),
|
|
FishingBuddy_Info["Fishies"][fishid].texture,
|
|
FishingBuddy_Info["Fishies"][fishid].color,
|
|
FishingBuddy_Info["Fishies"][fishid].quantity,
|
|
FishingBuddy_Info["Fishies"][fishid].quality,
|
|
FishingBuddy_Info["Fishies"][fishid].name;
|
|
end
|
|
end
|
|
|
|
local function ImportFish()
|
|
local oldShowNewFishies = GetSetting("ShowNewFishies");
|
|
SetSetting("ShowNewFishies");
|
|
if ( FishInfo2DataSub and FishingBuddy_Info["FishInfo2"] == 0 ) then
|
|
for toon in FishInfo2DataSub do
|
|
if ( not string.find(toon, "|User$") ) then
|
|
for fishie in FishInfo2DataSub[toon] do
|
|
local texture = FishInfo2DataSub[toon][fishie]["texture"];
|
|
local quality = FishInfo2DataSub[toon][fishie]["rarity"];
|
|
local fz = FishInfo2DataSub[toon][fishie]["zones"];
|
|
local link = FishInfo2DataSub[toon][fishie]["link"];
|
|
if ( link ) then
|
|
local _,_,id = string.find(link, "^(%d+):");
|
|
for zone in fz do
|
|
for subzone in fz[zone] do
|
|
local quantity = fz[zone][subzone];
|
|
AddFishie("ffffffff", id, fishie, zone, subzone, texture, quantity, quality)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
FishingBuddy_Info["FishInfo2"] = 1;
|
|
FishingBuddy.Print(FishingBuddy.IMPORTMSG, "FishInfo2");
|
|
-- elseif ( imppfishinfoDB and FishingBuddy_Info["ImppDBLoaded"] == 0 ) then
|
|
-- for subzone in imppfishinfoDB do
|
|
-- for item in imppfishinfoDB[subzone]["itemnames"] do
|
|
-- local quantity = imppfishinfoDB[subzone]["itemnames"][item].number;
|
|
-- local texture = imppfishinfoDB[subzone]["itemnames"][item].texture;
|
|
-- local quality = imppfishinfoDB[subzone]["itemnames"][item].quality;
|
|
-- AddFishie(color, id, name, subzone, texture, item, quantity, quality)
|
|
-- end
|
|
-- end
|
|
-- FishingBuddy_Info["ImppDBLoaded"] = 1;
|
|
-- FishingBuddy.Print(FishingBuddy.IMPORTMSG, "Impp's fishinfo");
|
|
-- elseif ( DataFishDB and FishingBuddy_Info["DataFish"] == 0 ) then
|
|
-- for fishie in DataFishDB["catches"] do
|
|
-- for zone in DataFishDB["catches"][fishie]["locnames"] do
|
|
-- for subzone in DataFishDB["catches"][fishie]["locnames"][zone] do
|
|
-- local dfl = DataFishDB["locations"][subzone]["itemnames"][fishie];
|
|
-- local quantity = dfl["number"];
|
|
-- local texture = dfl["texture"];
|
|
-- local quality = dfl["quality"];
|
|
-- AddFishie(color, id, name, zone, subzone, texture, quantity, quality)
|
|
-- end
|
|
-- end
|
|
-- end
|
|
-- FishingBuddy_Info["DataFish"] = 1;
|
|
-- FishingBuddy.Print(FishingBuddy.IMPORTMSG, "DataFish");
|
|
else
|
|
FishingBuddy.Message(FishingBuddy.NOIMPORTMSG);
|
|
end
|
|
SetSetting("ShowNewFishies", oldShowNewFishies);
|
|
end
|
|
|
|
local function InvokeFishing()
|
|
GetFishingSpellID();
|
|
if ( FishingSpellID ) then
|
|
CastSpell(FishingSpellID, BOOKTYPE_SPELL);
|
|
end
|
|
end
|
|
|
|
local ModeEventTable = {
|
|
"LOOT_OPENED",
|
|
"LOOT_CLOSED",
|
|
"SPELLS_CHANGED",
|
|
"SPELLCAST_CHANNEL_START",
|
|
"SPELLCAST_CHANNEL_STOP",
|
|
"SPELLCAST_START",
|
|
"SPELLCAST_STOP",
|
|
"SPELLCAST_INTERRUPTED",
|
|
"SPELLCAST_FAILED",
|
|
"SKILL_LINES_CHANGED",
|
|
};
|
|
|
|
-- do everything we think is necessary when we start fishing
|
|
-- even if we didn't do the switch to a fishing pole
|
|
local function StartFishingMode()
|
|
if ( not FishingBuddy.StartedFishing ) then
|
|
FishingBuddy.StartedFishing = GetTime();
|
|
FishingBuddy.EnhanceFishingSounds(true);
|
|
FishingBuddy.WatchUpdate();
|
|
EventRegistration(FishingBuddyRoot, ModeEventTable, true);
|
|
end
|
|
end
|
|
|
|
local function StopFishingMode()
|
|
if ( FishingBuddy.StartedFishing ) then
|
|
FishingBuddy.EnhanceFishingSounds(false);
|
|
FishingBuddy.WatchUpdate();
|
|
FishingBuddy.StartedFishing = nil;
|
|
EventRegistration(FishingBuddyRoot, ModeEventTable, false);
|
|
end
|
|
if ( resetClickToMove ) then
|
|
-- Re-enable Click-to-Move if we changed it
|
|
SetCVar("autointeract", "1");
|
|
resetClickToMove = nil;
|
|
end
|
|
end
|
|
|
|
local function FishingMode()
|
|
if ( IsFishingPole() ) then
|
|
StartFishingMode();
|
|
else
|
|
StopFishingMode();
|
|
end
|
|
end
|
|
FishingBuddy.API.FishingMode = FishingMode;
|
|
|
|
-- Easy lures (borrowed from Mugendai's excellent code)
|
|
local function UpdateLure()
|
|
-- if the pole has an enchantment, we can assume it's got a lure on it (so far, anyway)
|
|
if ( ( GetSetting("EasyLures") == 1 ) and not GetWeaponEnchantInfo() ) then
|
|
-- trap message handler if we haven't already
|
|
if ( not SavedAddMessage ) then
|
|
FishingBuddy.TrapUIErrors();
|
|
end
|
|
|
|
--Check for a lure in the bags, starting with the highest power one
|
|
local bag, slot;
|
|
for lure in FISHINGLURES do
|
|
--If we find this lure in the bag, then use it
|
|
bag, slot = FindItemByID(lure);
|
|
if (bag and slot) then
|
|
--We need to temporarily disable the cant use item error, incase this item is too high of a level to use
|
|
TestingLures = true;
|
|
--Temporarily disable error message sounds, incase this item is too high of a level to use
|
|
local soundState = GetCVar("EnableErrorSpeech");
|
|
if ( soundState == "1" ) then
|
|
SetCVar("EnableErrorSpeech", 0);
|
|
end
|
|
--Try to use the item
|
|
UseContainerItem(bag, slot);
|
|
-- re-enable the can't use item error message
|
|
TestingLures = false;
|
|
-- re-enable error message sounds
|
|
if ( soundState == "1" ) then
|
|
SetCVar("EnableErrorSpeech", 1);
|
|
end
|
|
-- if we have a targeting cursor, then we succesfully used the lure
|
|
if ( SpellIsTargeting() ) then
|
|
-- apply the lure to the fishing pole
|
|
local mainhandslot = GetInventorySlotInfo("MainHandSlot");
|
|
PickupInventoryItem(mainhandslot);
|
|
AddingLure = true;
|
|
return true;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return false;
|
|
end
|
|
|
|
FishingBuddy.ActionStartCheck = function()
|
|
-- Disable Click-to-Move if we're fishing
|
|
if ( GetCVar("autointeract") == "1" ) then
|
|
resetClickToMove = true;
|
|
SetCVar("autointeract", "0");
|
|
end
|
|
-- Don't interrupt putting on a lure, or if we're not fastcasting
|
|
if ( AddingLure ) then
|
|
ActionStartTime = 0;
|
|
else
|
|
ActionStartTime = GetTime();
|
|
end
|
|
end
|
|
|
|
-- add the double click checking in based on the code is Cosmos
|
|
FishingBuddy.StopCastingCheck = function()
|
|
if ( not ActionStartTime ) then
|
|
ActionStartTime = 0;
|
|
end
|
|
if ( not ActionDoubleTime ) then
|
|
ActionDoubleTime = 0;
|
|
end
|
|
local time = GetTime();
|
|
local pressTime = time - ActionStartTime;
|
|
local doubleTime = time - ActionDoubleTime;
|
|
-- if we're not putting on a lure
|
|
if ( not SpellIsTargeting() ) then
|
|
-- if the click was "short" enough that we're going to treat it
|
|
-- as a cast
|
|
if ( ActionStartTime > 0 and ACTIONDOWNWAIT >= pressTime) then
|
|
-- if we're already casting, enforce double click timing
|
|
if ( CastingNow and
|
|
( ActionDoubleTime == 0 or ACTIONDOUBLEWAIT < doubleTime ) ) then
|
|
ActionDoubleTime = GetTime();
|
|
else
|
|
ActionDoubleTime = 0;
|
|
-- rebind the mouse event
|
|
UpdateBindings(true);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
FishingBuddy.PerformCast = function()
|
|
-- We're stealing the mouse-up hardware event, make sure we exit MouseLook
|
|
if ( IsMouselooking() ) then
|
|
MouselookStop();
|
|
end
|
|
-- reset the TURNORACTION binding so that everything else works 'right'
|
|
UpdateBindings(false);
|
|
|
|
if ( not schooltipText or not OnFishingBobber() ) then
|
|
-- watch for fishing holes
|
|
schooltipText = GetTooltipText();
|
|
end
|
|
|
|
-- put on a lure if we need to
|
|
if ( not UpdateLure() ) then
|
|
InvokeFishing();
|
|
end
|
|
end
|
|
|
|
FishingBuddy.SuitUpAndGoFishing = function()
|
|
if ( IsFishingPole() ) then
|
|
-- put on a lure if we need to
|
|
if ( not UpdateLure() ) then
|
|
InvokeFishing();
|
|
end
|
|
elseif ( GetSetting("SuitUpFirst") == 1 ) then
|
|
FishingBuddy.OutfitManager.Switch();
|
|
end
|
|
end
|
|
|
|
|
|
FishingBuddy.TrapUIErrors = function()
|
|
local temp = {};
|
|
temp.obj= UIErrorsFrame;
|
|
temp.method = UIErrorsFrame["AddMessage"];
|
|
if ( SafeHookMethod(UIErrorsFrame, "AddMessage", FishingBuddy.AddMessage) ) then
|
|
SavedAddMessage = temp;
|
|
end
|
|
end
|
|
|
|
FishingBuddy.TrapWorldMouse = function()
|
|
SavedWFOnMouseUp = SafeHookScript(WorldFrame, "OnMouseUp", WF_OnMouseUp);
|
|
SavedWFOnMouseDown = SafeHookScript(WorldFrame, "OnMouseDown", WF_OnMouseDown);
|
|
end
|
|
|
|
-- we should collect these, but then they would be in the cache
|
|
local QuestItems = {};
|
|
QuestItems[6717] = 1; -- Gaffer Jack
|
|
QuestItems[6718] = 1; -- Electropeller
|
|
QuestItems[16970] = 1; -- Misty Reed Mahi Mahi
|
|
QuestItems[16968] = 1; -- Sar'theris Striker
|
|
QuestItems[16969] = 1; -- Savage Coast Blue
|
|
QuestItems[16967] = 1; -- Feralas Ahi
|
|
|
|
-- User interface handling
|
|
local function IsRareFish(id, forced)
|
|
-- always skip extravaganza fish
|
|
if ( FishingBuddy.Extravaganza.Fish[id] ) then
|
|
return true;
|
|
end
|
|
return ( not forced and QuestItems[id] );
|
|
end
|
|
|
|
FishingBuddy.Commands[FishingBuddy.UPDATEDB] = {};
|
|
FishingBuddy.Commands[FishingBuddy.UPDATEDB].help = FishingBuddy.UPDATEDB_HELP;
|
|
FishingBuddy.Commands[FishingBuddy.UPDATEDB].func =
|
|
function(what)
|
|
local ff = FishingBuddy_Info["Fishies"];
|
|
local forced;
|
|
if ( what and what == FishingBuddy.FORCE ) then
|
|
forced = true;
|
|
end
|
|
FishingOutfitTooltip:SetOwner(FishingBuddyFrame, "ANCHOR_RIGHT");
|
|
FishingOutfitTooltip:Show();
|
|
local count = 0;
|
|
for id,info in ff do
|
|
local item = id..":0:0:0";
|
|
if ( not IsLinkableItem(item) or not info.name ) then
|
|
if ( not IsRareFish(id, forced) ) then
|
|
local link = "item:"..item;
|
|
-- fetch the data (may disconnect)
|
|
FishingBuddy.Debug(link);
|
|
FishingOutfitTooltip:SetHyperlink(link);
|
|
-- now that we have it in our cache, get the name
|
|
local n,_,_,_,_,_,_,_ = GetItemInfo(link);
|
|
if ( n ) then
|
|
count = count + 1;
|
|
FishingBuddy_Info["Fishies"][id].name = n;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
FishingBuddy.Print(FishingBuddy.UPDATEDB_MSG, count);
|
|
return true;
|
|
end;
|
|
|
|
FishingBuddy.Commands[FishingBuddy.CURRENT] = {};
|
|
FishingBuddy.Commands[FishingBuddy.CURRENT].help = FishingBuddy.CURRENT_HELP;
|
|
FishingBuddy.Commands[FishingBuddy.CURRENT].func =
|
|
function(what)
|
|
if ( what and what == FishingBuddy.RESET) then
|
|
FishingBuddy.currentFishies = {};
|
|
FishingMode();
|
|
return true;
|
|
end
|
|
end;
|
|
FishingBuddy.Commands[FishingBuddy.IMPORT] = {};
|
|
FishingBuddy.Commands[FishingBuddy.IMPORT].help = FishingBuddy.IMPORT_HELP;
|
|
FishingBuddy.Commands[FishingBuddy.IMPORT].func =
|
|
function()
|
|
ImportFish();
|
|
return true;
|
|
end;
|
|
FishingBuddy.Commands[FishingBuddy.CLEANUP] = {};
|
|
FishingBuddy.Commands[FishingBuddy.CLEANUP].help = FishingBuddy.CLEANUP_HELP;
|
|
FishingBuddy.Commands[FishingBuddy.CLEANUP].func =
|
|
function(what)
|
|
local tabs = { "Settings", "Outfit", "WasWearing" };
|
|
local rnames = {};
|
|
local onames = {};
|
|
if ( not what or what == FishingBuddy.CHECK ) then
|
|
if ( FishingBuddy_Info["Settings"] ) then
|
|
for name in FishingBuddy_Info["Settings"] do
|
|
tinsert(onames, name);
|
|
end
|
|
end
|
|
if ( FishingBuddy_Info[realmName] ) then
|
|
local fs = FishingBuddy_Info[realmName]["Settings"];
|
|
if ( fs ) then
|
|
for name,info in fs do
|
|
tinsert(rnames, name);
|
|
end
|
|
end
|
|
end
|
|
if ( next(rnames) or next(onames) ) then
|
|
if ( next(rnames) ) then
|
|
FishingBuddy.Print(FishingBuddy.CLEANUP_WILLMSG, realmName,
|
|
FishingBuddy.EnglishList(rnames));
|
|
end
|
|
if ( next(onames) ) then
|
|
FishingBuddy.Print(FishingBuddy.CLEANUP_WILLMSG,
|
|
FishingBuddy.NOREALM,
|
|
FishingBuddy.EnglishList(onames));
|
|
end
|
|
else
|
|
FishingBuddy.Message(FishingBuddy.CLEANUP_NONEMSG);
|
|
end
|
|
return true;
|
|
else
|
|
if ( what == FishingBuddy.NOW ) then
|
|
if ( FishingBuddy_Info["Settings"] ) then
|
|
for name in FishingBuddy_Info["Settings"] do
|
|
tinsert(onames, name);
|
|
end
|
|
end
|
|
if ( FishingBuddy_Info[realmName] ) then
|
|
local fs = FishingBuddy_Info[realmName]["Settings"];
|
|
if ( fs ) then
|
|
for name,info in fs do
|
|
tinsert(rnames, name);
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if ( FishingBuddy_Info["Settings"] and FishingBuddy_Info["Settings"][what] ) then
|
|
tinsert(onames, what);
|
|
elseif ( FishingBuddy_Info[realmName] and
|
|
FishingBuddy_Info[realmName]["Settings"] and
|
|
FishingBuddy_Info[realmName]["Settings"][what] ) then
|
|
tinsert(rnames, what);
|
|
else
|
|
FishingBuddy.Print(FishingBuddy.CLEANUP_NOOLDMSG, what);
|
|
return true;
|
|
end
|
|
end
|
|
if ( next(rnames) or next(onames) ) then
|
|
if ( next(rnames) ) then
|
|
for _,name in rnames do
|
|
for _,tab in tabs do
|
|
if ( FishingBuddy_Info[realmName] and FishingBuddy_Info[realmName][tab] ) then
|
|
FishingBuddy_Info[realmName][tab][name] = nil;
|
|
if ( next(FishingBuddy_Info[realmName][tab]) == nil ) then
|
|
FishingBuddy_Info[realmName][tab] = nil;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if ( FishingBuddy_Info[realmName] and next(FishingBuddy_Info[realmName]) == nil ) then
|
|
FishingBuddy_Info[realmName] = nil;
|
|
end
|
|
FishingBuddy.Print(FishingBuddy.CLEANUP_DONEMSG, realmName,
|
|
FishingBuddy.EnglishList(rnames));
|
|
end
|
|
if ( next(onames) ) then
|
|
for _,name in onames do
|
|
for _,tab in tabs do
|
|
if ( FishingBuddy_Info[tab] ) then
|
|
FishingBuddy_Info[tab][name] = nil;
|
|
if ( next(FishingBuddy_Info[tab]) ) then
|
|
FishingBuddy_Info[tab] = nil;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
FishingBuddy.Print(FishingBuddy.CLEANUP_DONEMSG,
|
|
FishingBuddy.NOREALM,
|
|
FishingBuddy.EnglishList(onames));
|
|
end
|
|
else
|
|
FishingBuddy.Message(FishingBuddy.CLEANUP_NONEMSG);
|
|
end
|
|
return true;
|
|
end
|
|
end;
|
|
|
|
local function nextarg(msg, pattern)
|
|
if ( not msg or not pattern ) then
|
|
return nil, nil;
|
|
end
|
|
local s,e = string.find(msg, pattern);
|
|
if ( s ) then
|
|
local word = strsub(msg, s, e);
|
|
msg = strsub(msg, e+1);
|
|
return word, msg;
|
|
end
|
|
return nil, msg;
|
|
end
|
|
|
|
FishingBuddy.Command = function(msg)
|
|
if ( not msg ) then
|
|
return;
|
|
end
|
|
if ( FishingBuddy.IsLoaded() ) then
|
|
-- collect arguments (whee, lua string manipulation)
|
|
local cmd;
|
|
cmd, msg = nextarg(msg, "[%w]+");
|
|
|
|
-- the empty string gives us no args at all
|
|
if ( not cmd ) then
|
|
-- toggle window
|
|
if ( FishingBuddyFrame:IsVisible() ) then
|
|
HideUIPanel(FishingBuddyFrame);
|
|
else
|
|
ShowUIPanel(FishingBuddyFrame);
|
|
end
|
|
elseif ( cmd == FishingBuddy.HELP or cmd == "help" ) then
|
|
FishingBuddy.Output(FishingBuddy.WINDOW_TITLE);
|
|
FishingBuddy.PrintHelp(FishingBuddy.HELPMSG);
|
|
else
|
|
local command = FishingBuddy.Commands[cmd];
|
|
if ( command ) then
|
|
local args = {};
|
|
local goodargs = true;
|
|
if ( command.args ) then
|
|
for _,pat in command.args do
|
|
local w, msg = nextarg(msg, pat);
|
|
if ( not w ) then
|
|
goodargs = false;
|
|
break;
|
|
end
|
|
tinsert(args, w);
|
|
end
|
|
else
|
|
local a;
|
|
while ( msg ) do
|
|
a, msg = nextarg(msg, "[%w]+");
|
|
if ( not a ) then
|
|
break;
|
|
end
|
|
tinsert(args, a);
|
|
end
|
|
end
|
|
if ( not goodargs or not command.func(unpack(args)) ) then
|
|
if ( command.help ) then
|
|
FishingBuddy.PrintHelp(command.help);
|
|
else
|
|
FishingBuddy.Debug("command failed");
|
|
end
|
|
end
|
|
else
|
|
FishingBuddy.Command("help");
|
|
end
|
|
end
|
|
else
|
|
FishingBuddy.Error(FishingBuddy.FAILEDINIT);
|
|
end
|
|
end
|
|
|
|
FishingBuddy.TooltipBody = function(hintcheck)
|
|
local text = FishingBuddy.DESCRIPTION1.."\n"..FishingBuddy.DESCRIPTION2;
|
|
if ( hintcheck ) then
|
|
text = text.."\n".."|c"..FishingBuddy.Colors.GREEN;
|
|
text = text .. FishingBuddy.TOOLTIP_HINT.." ";
|
|
if (FishingBuddy.GetSetting(hintcheck) == 1) then
|
|
text = text..FishingBuddy.TOOLTIP_HINTSWITCH;
|
|
else
|
|
text = text..FishingBuddy.TOOLTIP_HINTTOGGLE;
|
|
end
|
|
text = text.."|r";
|
|
end
|
|
return text;
|
|
end
|
|
|
|
local IWEventTable = {
|
|
"ITEM_LOCK_CHANGED",
|
|
};
|
|
|
|
FishingBuddy.OnLoad = function()
|
|
this:RegisterEvent("PLAYER_ENTERING_WORLD");
|
|
this:RegisterEvent("PLAYER_LEAVING_WORLD");
|
|
|
|
this:RegisterEvent("PLAYER_LOGIN");
|
|
this:RegisterEvent("PLAYER_LOGOUT");
|
|
this:RegisterEvent("VARIABLES_LOADED");
|
|
|
|
this:RegisterEvent("MINIMAP_ZONE_CHANGED");
|
|
|
|
-- Set up command
|
|
SlashCmdList["fishingbuddy"] = FishingBuddy.Command;
|
|
SLASH_fishingbuddy1 = "/fishingbuddy";
|
|
SLASH_fishingbuddy2 = "/fb";
|
|
|
|
FishingBuddy.Output(FishingBuddy.WINDOW_TITLE.." loaded");
|
|
end
|
|
|
|
local IsZoning;
|
|
local ZoneEvents;
|
|
local function TrackZoneEvents(evt)
|
|
if ( IsZoning ) then
|
|
if ( not ZoneEvents ) then
|
|
ZoneEvents = {};
|
|
end
|
|
if ( ZoneEvents[evt] ) then
|
|
ZoneEvents[evt] = ZoneEvents[evt] + 1;
|
|
else
|
|
ZoneEvents[evt] = 1;
|
|
end
|
|
end
|
|
end
|
|
|
|
local function DumpZoneEvents()
|
|
FishingBuddy.Dump(ZoneEvents);
|
|
ZoneEvents = nil;
|
|
end
|
|
|
|
FishingBuddy.OnEvent = function()
|
|
local needUpdate = false;
|
|
-- TrackZoneEvents(event);
|
|
if ( event == "LOOT_OPENED" ) then
|
|
IsLooting = true;
|
|
if ( IsFishingLoot()) then
|
|
local zone, subzone = GetZoneInfo();
|
|
local check = FishingBuddy.Schools.CheckFishingHole;
|
|
for index = 1, GetNumLootItems(), 1 do
|
|
if (LootSlotIsItem(index)) then
|
|
local texture, fishie, quantity, quality = GetLootSlotInfo(index);
|
|
local link = GetLootSlotLink(index);
|
|
local color, id, name = SplitFishLink(link);
|
|
AddFishie(color, id, name, zone, subzone, texture, quantity, quality);
|
|
if ( FishingBuddy.AddTracking ) then
|
|
FishingBuddy.AddTracking(id, name);
|
|
end
|
|
check(schooltipText, id);
|
|
SetZoneLevel(zone, subzone, id);
|
|
end
|
|
end
|
|
if ( schooltipText ) then
|
|
schooltipText = nil;
|
|
end
|
|
end
|
|
elseif ( event == "LOOT_CLOSED" ) then
|
|
IsLooting = false;
|
|
elseif ( event == "MINIMAP_ZONE_CHANGED" ) then
|
|
if ( not FishingBuddy.IsLoaded() ) then
|
|
return;
|
|
end
|
|
FishingBuddy.currentFishies = {};
|
|
needUpdate = true;
|
|
elseif ( event == "SPELLS_CHANGED" ) then
|
|
-- Fishing might have moved, go look again
|
|
FishingSpellID = nil;
|
|
elseif ( event == "ITEM_LOCK_CHANGED" ) then
|
|
FishingMode();
|
|
elseif ( event == "SPELLCAST_CHANNEL_START" ) then
|
|
-- Mugendai is one sharp cookie (shamelessly stealing from TackleBox)
|
|
-- Keep up with whether or not we are casting
|
|
CastingNow = true;
|
|
elseif ( event == "SPELLCAST_CHANNEL_STOP" ) then
|
|
CastingNow = false;
|
|
elseif ( event == "SPELLCAST_START" ) then
|
|
-- AddingLure = true;
|
|
elseif ( event == "SPELLCAST_STOP" ) then
|
|
if ( AddingLure ) then
|
|
AddingLure = false;
|
|
-- update the skill line if we have one
|
|
if ( GetSetting("WatchCurrentSkill") == 1 ) then
|
|
needUpdate = true;
|
|
end
|
|
end
|
|
elseif ( ( event == "SPELLCAST_INTERRUPTED" ) or ( event == "SPELLCAST_FAILED" ) ) then
|
|
AddingLure = false;
|
|
elseif ( event == "SKILL_LINES_CHANGED" ) then
|
|
if ( GetSetting("WatchCurrentSkill") == 1 ) then
|
|
needUpdate = true;
|
|
end
|
|
elseif ( event == "PLAYER_LOGIN" ) then
|
|
-- set up outfit stuff
|
|
playerName = UnitName("player");
|
|
realmName = GetRealmName();
|
|
CheckClockOffset();
|
|
FishingBuddy.OutfitManager.Initialize();
|
|
FishingMode();
|
|
elseif ( event == "PLAYER_LOGOUT" ) then
|
|
-- reset the fishing sounds, if we need to
|
|
StopFishingMode();
|
|
FishingBuddy.SavePlayerInfo();
|
|
elseif ( event == "VARIABLES_LOADED" ) then
|
|
FishingBuddy.Initialize();
|
|
this:UnregisterEvent("VARIABLES_LOADED");
|
|
elseif ( event == "PLAYER_ENTERING_WORLD" ) then
|
|
IsZoning = nil;
|
|
-- DumpZoneEvents();
|
|
EventRegistration(this, IWEventTable, true);
|
|
elseif ( event == "PLAYER_LEAVING_WORLD") then
|
|
IsZoning = 1;
|
|
EventRegistration(this, IWEventTable, false);
|
|
end
|
|
FishingBuddy.Extravaganza.IsTime(true);
|
|
if ( needUpdate ) then
|
|
FishingBuddy.WatchUpdate();
|
|
end
|
|
end
|
|
|
|
FishingBuddy.PrintHelp = function(tab)
|
|
if ( tab ) then
|
|
if ( type(tab) == "table" ) then
|
|
for _,line in tab do
|
|
FishingBuddy.PrintHelp(line);
|
|
end
|
|
else
|
|
-- check for a reference to another help item
|
|
local _,_,w = string.find(tab, "^@([A-Z0-9_]+)$");
|
|
if ( w ) then
|
|
FishingBuddy.PrintHelp(FishingBuddy[w]);
|
|
else
|
|
FishingBuddy.Output(tab);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
FishingBuddy["EFSV"] = {};
|
|
FishingBuddy["EFSV"]["MusicVolume"] = tonumber(GetCVar("MusicVolume"));
|
|
FishingBuddy["EFSV"]["AmbienceVolume"] = tonumber(GetCVar("AmbienceVolume"));
|
|
FishingBuddy["EFSV"]["SoundVolume"] =tonumber(GetCVar("SoundVolume"));
|
|
local SoundWasEnhanced;
|
|
FishingBuddy.EnhanceFishingSounds = function(turniton)
|
|
if ( GetSetting("EnhanceFishingSounds") == 1 ) then
|
|
if ( turniton ) then
|
|
-- collect the current value
|
|
FishingBuddy["EFSV"]["MusicVolume"] = tonumber(GetCVar("MusicVolume"));
|
|
FishingBuddy["EFSV"]["AmbienceVolume"] = tonumber(GetCVar("AmbienceVolume"));
|
|
FishingBuddy["EFSV"]["SoundVolume"] =tonumber(GetCVar("SoundVolume"));
|
|
-- turn 'em off!
|
|
for setting in FishingBuddy["EFSV"] do
|
|
SetCVar(setting,
|
|
GetSetting("EnhanceSound"..setting));
|
|
end
|
|
SoundWasEnhanced = true;
|
|
else
|
|
if ( SoundWasEnhanced ) then
|
|
for setting, value in FishingBuddy["EFSV"] do
|
|
SetCVar(setting, value);
|
|
end
|
|
SoundWasEnhanced = false;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Drop-down menu support
|
|
FishingBuddy.ToggleSetting = function(setting)
|
|
local value = GetSetting(setting);
|
|
if ( not value ) then
|
|
value = 0;
|
|
end
|
|
SetSetting(setting, 1 - value);
|
|
FishingBuddy.WatchUpdate();
|
|
FishingBuddy.UpdateMinimap();
|
|
end
|
|
|
|
-- save some memory by keeping one copy of each one
|
|
local ToggleFunctions = {};
|
|
-- let's use closures
|
|
local function MakeToggle(name)
|
|
if ( not ToggleFunctions[name] ) then
|
|
local n = name;
|
|
ToggleFunctions[name] = function() FishingBuddy.ToggleSetting(n) end;
|
|
end
|
|
return ToggleFunctions[name];
|
|
end
|
|
FishingBuddy.MakeToggle = MakeToggle;
|
|
|
|
FishingBuddy.MakeDropDown = function(switchItem, switchSetting)
|
|
local info;
|
|
-- If no outfit frame, we can't switch outfits...
|
|
if ( FishingBuddy.OutfitManager.HasManager() ) then
|
|
info = {};
|
|
info.text = switchItem;
|
|
info.func = MakeToggle(switchSetting);
|
|
info.checked = (GetSetting(switchSetting) == 1);
|
|
info.keepShownOnClick = 1;
|
|
UIDropDownMenu_AddButton(info);
|
|
info = {};
|
|
info.disabled = 1;
|
|
UIDropDownMenu_AddButton(info);
|
|
end
|
|
|
|
for name,option in FishingBuddy.OPTIONS do
|
|
if ( option.m ) then
|
|
local addthis = true;
|
|
if ( option.check ) then
|
|
addthis = option.check();
|
|
end
|
|
if ( addthis ) then
|
|
info = {};
|
|
info.text = option.text;
|
|
info.func = MakeToggle(name);
|
|
info.checked = (GetSetting(name) == 1);
|
|
info.keepShownOnClick = 1;
|
|
UIDropDownMenu_AddButton(info);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- utility functions
|
|
FishingBuddy.AddTooltip = function(text, r, g, b)
|
|
if ( text ) then
|
|
if ( type(text) == "table" ) then
|
|
for _,l in text do
|
|
FishingBuddy.AddTooltip(l.text, l.r, l.g, l.b);
|
|
end
|
|
else
|
|
GameTooltip:AddLine(text, r, g, b);
|
|
end
|
|
end
|
|
end
|
|
|
|
FishingBuddy.ChatLink = function(item, name, color)
|
|
if( item and name and ChatFrameEditBox:IsVisible() ) then
|
|
if not color then
|
|
color = FishingBuddy.Colors.WHITE;
|
|
end
|
|
local link = "|c"..color.."|Hitem:"..item.."|h["..name.."]|h|r";
|
|
ChatFrameEditBox:Insert(link);
|
|
end
|
|
end
|
|
|
|
FishingBuddy.FishSort = function(tab, forcename)
|
|
if ( forcename or GetSetting("SortByPercent") == 0 ) then
|
|
table.sort(tab, function(a,b) return (a.index and b.index and a.index<b.index) or
|
|
(a.text and b.text and a.text<b.text); end);
|
|
else
|
|
table.sort(tab, function(a,b) return a.count and b.count and b.count<a.count; end);
|
|
end
|
|
end
|
|
|
|
FishingBuddy.StripRaw = function(fishie)
|
|
if ( fishie ) then
|
|
local s,e = string.find(fishie, FishingBuddy.RAW.." ");
|
|
if ( s ) then
|
|
if ( s > 1 ) then
|
|
fishie = string.sub(fishie, 1, s-1)..string.sub(fishie, e+1);
|
|
else
|
|
fishie = string.sub(fishie, e+1);
|
|
end
|
|
else
|
|
s,e = string.find(fishie, " "..FishingBuddy.RAW);
|
|
if ( s ) then
|
|
fishie = string.sub(fishie, 1, s-1)..string.sub(fishie, e+1);
|
|
end
|
|
end
|
|
return fishie;
|
|
end
|
|
-- this means an import failed somewhere
|
|
return FishingBuddy.UNKNOWN;
|
|
end
|
|
|
|
FishingBuddy.ToggleDropDownMenu = function(level, value, menu, anchor, xOffset, yOffset)
|
|
ToggleDropDownMenu(level, value, menu, anchor, xOffset, yOffset);
|
|
if (not level) then
|
|
level = 1;
|
|
end
|
|
local anchorName;
|
|
if ( type(anchor) == "string" ) then
|
|
anchorName = anchor;
|
|
else
|
|
anchorName = anchor:GetName();
|
|
end
|
|
local frame = getglobal("DropDownList"..level);
|
|
local uiScale = UIParent:GetScale()
|
|
if ( frame:GetRight() > ( GetScreenWidth()*uiScale ) ) then
|
|
if ( anchorName == "cursor" ) then
|
|
if ( not xOffset ) then
|
|
xOffset = 0;
|
|
end
|
|
if ( not yOffset ) then
|
|
yOffset = 0;
|
|
end
|
|
local cursorX, cursorY = GetCursorPosition();
|
|
xOffset = -cursorX + xOffset;
|
|
yOffset = cursorY + yOffset;
|
|
else
|
|
if ( not xOffset or not yOffset ) then
|
|
xOffset = 8;
|
|
yOffset = 22;
|
|
end
|
|
end
|
|
frame:ClearAllPoints();
|
|
frame:SetPoint("TOPRIGHT", anchorName, "BOTTOMLEFT", -xOffset, yOffset);
|
|
end
|
|
if ( frame:GetBottom() < 0 ) then
|
|
frame:ClearAllPoints();
|
|
frame:SetPoint("BOTTOMRIGHT", anchorName, "BOTTOMLEFT", -xOffset, yOffset);
|
|
end
|
|
end
|
|
|
|
FishingBuddy.EnglishList = function(list, conjunction)
|
|
if ( list ) then
|
|
local n = table.getn(list);
|
|
local str = "";
|
|
for idx=1,n do
|
|
local name = list[idx];
|
|
if ( idx == 1 ) then
|
|
str = name;
|
|
elseif ( idx == n ) then
|
|
str = str .. ", ";
|
|
if ( conjunction ) then
|
|
str = str .. conjunction;
|
|
else
|
|
str = str .. "and";
|
|
end
|
|
str = str .. " " .. name;
|
|
else
|
|
str = str .. ", " .. name;
|
|
end
|
|
end
|
|
return str;
|
|
end
|
|
end
|
|
|
|
FishingBuddy.Message = function(msg, r, g, b)
|
|
FishingBuddy.Output(FishingBuddy.NAME..": "..msg, r, g, b);
|
|
end
|
|
|
|
FishingBuddy.Print = function(...)
|
|
local msg = string.format(unpack(arg));
|
|
FishingBuddy.Message(msg);
|
|
end
|
|
|
|
FishingBuddy.Error = function(msg)
|
|
FishingBuddy.Output(FishingBuddy.NAME..": "..msg, 1.0, 0, 0);
|
|
end
|
|
|
|
FishingBuddy.UIError = function(msg)
|
|
-- Okay, this check is probably not necessary...
|
|
if ( UIErrorsFrame ) then
|
|
UIErrorsFrame:AddMessage(msg, 1.0, 0.1, 0.1, 1.0, UIERRORS_HOLD_TIME);
|
|
else
|
|
FishingBuddy.Error(msg);
|
|
end
|
|
end
|
|
|
|
FishingBuddy.Testing = function(line)
|
|
if ( not FishingBuddy_Info["Testing"] ) then
|
|
FishingBuddy_Info["Testing"] = {};
|
|
end
|
|
tinsert(FishingBuddy_Info["Testing"], line);
|
|
end
|