399 lines
12 KiB
Lua
Executable File
399 lines
12 KiB
Lua
Executable File
-- Support for the Extravaganza
|
|
--
|
|
-- Map support liberally borrowed from GuildMap, by Bru on Blackhand
|
|
|
|
FishingBuddy.Extravaganza = {};
|
|
|
|
local NUMMINIPOIS = 10;
|
|
local ICONPATH = "Interface\\AddOns\\FishingBuddy\\Icons\\";
|
|
local CLOSEENOUGH = 10.0;
|
|
|
|
-- the actual names don't matter, except to help make sure I've got 'em all
|
|
local ExtravaganzaFish = {};
|
|
ExtravaganzaFish[19807] = "Speckled Tastyfish";
|
|
ExtravaganzaFish[19806] = "Dezian Queenfish";
|
|
ExtravaganzaFish[19805] = "Keefer's Angelfish";
|
|
-- makes you wonder what item 19804 is, doesn't it...
|
|
ExtravaganzaFish[19803] = "Brownell's Blue Striped Racer";
|
|
|
|
local UPDATETIME_SCHOOLS = 0.1;
|
|
local UPDATETIME_COUNTER = 60.0;
|
|
local STVUpdateTimer = 0;
|
|
local numCaught = 0;
|
|
local tastyfish_id = 19807;
|
|
local tastyfish;
|
|
|
|
-- convert zone coords into minimap coords
|
|
local STVInfo = { scale = 0.18128603034401,
|
|
xoffset = 0.39145470225916, yoffset = 0.79412224886668 };
|
|
|
|
local ZoomScale = {};
|
|
ZoomScale[0] = { xscale = 10448.3, yscale = 7072.7 };
|
|
ZoomScale[1] = { xscale = 12160.5, yscale = 8197.8 };
|
|
ZoomScale[2] = { xscale = 14703.1, yscale = 9825.0 };
|
|
ZoomScale[3] = { xscale = 18568.7, yscale = 12472.2 };
|
|
ZoomScale[4] = { xscale = 24390.3, yscale = 15628.5 };
|
|
ZoomScale[5] = { xscale = 37012.2, yscale = 25130.6 };
|
|
|
|
local function GetSTVPosition()
|
|
local x, y = GetPlayerMapPosition("player");
|
|
x = (x * STVInfo.scale) + STVInfo.xoffset;
|
|
y = (y * STVInfo.scale) + STVInfo.yoffset;
|
|
return x, y;
|
|
end
|
|
|
|
-- stolen directly from GuildMap
|
|
local function GetAngleIcon(x, y)
|
|
local angle = asin(x / 57);
|
|
if (x <= 0 and y <= 0) then
|
|
angle = 180 - angle;
|
|
elseif (x <= 0 and y > 0) then
|
|
angle = 360 + angle;
|
|
elseif (x > 0 and y >= 0) then
|
|
angle = angle;
|
|
else
|
|
angle = 180 - angle;
|
|
end
|
|
local fileNumber = math.floor((angle / 10) + 0.5) * 10;
|
|
if (fileNumber == 360) then
|
|
fileNumber = 0;
|
|
end
|
|
return ICONPATH.."MiniMapArrow"..fileNumber;
|
|
end
|
|
|
|
local function PlotPOI(index, x, y)
|
|
local poi = getglobal("FishingExtravaganzaMini"..index);
|
|
if ( poi ) then
|
|
if ( x and y ) then
|
|
local tex = getglobal("FishingExtravaganzaMini"..index.."Texture");
|
|
local zoom = ZoomScale[Minimap:GetZoom()];
|
|
x = x * zoom.xscale;
|
|
y = y * zoom.yscale;
|
|
local dist = math.sqrt(x*x + y*y);
|
|
if ( dist > 56.5 ) then
|
|
x = x * 57 / dist;
|
|
y = y * 57 / dist;
|
|
tex:SetTexture(GetAngleIcon(x, y));
|
|
tex:SetTexCoord(0.0, 1.0, 0.0, 1.0);
|
|
else
|
|
tex:SetTexture("Interface\\Minimap\\ObjectIcons");
|
|
tex:SetTexCoord(0.0, 0.25, 0.25, 0.5);
|
|
end
|
|
poi:SetPoint("CENTER", "MinimapCluster", "TOPLEFT", 107 + x, y - 92);
|
|
poi:Show();
|
|
return true;
|
|
else
|
|
poi:Hide();
|
|
end
|
|
end
|
|
return false;
|
|
end
|
|
|
|
local function CloseEnough(x1, y1, x2, y2)
|
|
local zoom = Minimap:GetZoom();
|
|
local x = (x1 - x2) * ZoomScale[zoom].xscale;
|
|
local y = (y1 - y2) * ZoomScale[zoom].yscale;
|
|
if (sqrt( (x * x) + (y * y) ) > 56.5) then
|
|
return; -- false
|
|
end
|
|
return true;
|
|
end
|
|
|
|
local function GetMinimapDistance(x1, y1, x2, y2)
|
|
local zoom = ZoomScale[Minimap:GetZoom()];
|
|
local dx = (x1 - x2) * zoom.xscale;
|
|
local dy = (y1 - y2) * zoom.yscale;
|
|
return math.sqrt(dx*dx+dy*dy);
|
|
end
|
|
|
|
local function FindClosest(row, x, y)
|
|
local dist;
|
|
local didx;
|
|
for idx=1,table.getn(row) do
|
|
local t = row[idx];
|
|
local dx = (t.x - x);
|
|
local dy = (t.y - y);
|
|
local d = dx*dx + dy*dy;
|
|
if ( not dist ) then
|
|
dist = d;
|
|
didx = idx;
|
|
elseif ( d < dist ) then
|
|
dist = d;
|
|
didx = idx;
|
|
end
|
|
end
|
|
if ( dist and didx ) then
|
|
local t = row[didx];
|
|
dist = GetMinimapDistance(t.x, t.y, x, y);
|
|
end
|
|
return didx, dist;
|
|
end
|
|
|
|
local function GetNearestTen(x, y, dir)
|
|
local r = math.floor(y * 100);
|
|
local found = 1;
|
|
local limit = 10;
|
|
local locations = {};
|
|
if ( FishingBuddy_Info["Schools"] ) then
|
|
while ( r >=0 and r <100 ) do
|
|
local iy = string.format("%d", r);
|
|
local dist;
|
|
local row = FishingBuddy_Info["Schools"][iy];
|
|
if ( row ) then
|
|
local rowsize = table.getn(row);
|
|
if ( rowsize > 5 and limit < 11 ) then
|
|
limit = limit + rowsize - 5;
|
|
end
|
|
for idx=1,rowsize do
|
|
local t = row[idx];
|
|
local dist = GetMinimapDistance(t.x, t.y, x, y);
|
|
tinsert(locations, { dist = dist, x = t.x, y = t.y });
|
|
found = found + 1;
|
|
if ( found >= limit ) then
|
|
return locations;
|
|
end
|
|
end
|
|
end
|
|
r = r + dir;
|
|
end
|
|
end
|
|
return locations;
|
|
end
|
|
|
|
-- save a school location
|
|
local function MarkSchool()
|
|
if ( not FishingBuddy_Info["Schools"] ) then
|
|
FishingBuddy_Info["Schools"] = {};
|
|
end
|
|
local x, y = GetSTVPosition();
|
|
local iy = string.format("%d", y * 100);
|
|
if ( not FishingBuddy_Info["Schools"][iy] ) then
|
|
FishingBuddy_Info["Schools"][iy] = { { x = x, y = y } };
|
|
else
|
|
local idx, dist = FindClosest(FishingBuddy_Info["Schools"][iy], x, y);
|
|
if ( dist > CLOSEENOUGH ) then
|
|
tinsert(FishingBuddy_Info["Schools"][iy], { x = x, y = y });
|
|
STVUpdateTimer = 0;
|
|
else
|
|
-- average something? that will cascade, which might be okay
|
|
-- or do we store them all during the contest and average later?
|
|
-- i.e. store 'close ones' in a separate place and then clean up
|
|
-- later
|
|
end
|
|
end
|
|
end
|
|
|
|
-- let an external entity forcibly mark a school
|
|
FishingBuddy.Extravaganza.MarkSchool = function()
|
|
local zone, subzone = FishingBuddy.GetZoneInfo();
|
|
if ( zone == FishingBuddy.STVZONENAME ) then
|
|
MarkSchool();
|
|
end
|
|
end
|
|
|
|
-- Sunday, 2pm
|
|
local STVDay = "0";
|
|
local STVStartHour = 14;
|
|
|
|
-- Should we display the extravaganza message?
|
|
local function IsTime(activate)
|
|
local showit = false;
|
|
if ( FishingBuddy.IsLoaded() ) then
|
|
if ( FishingBuddy.GetSetting("STVTimer") == 1 ) then
|
|
local mhour = date("%H");
|
|
local hour,minute = GetGameTime();
|
|
local day = date("%w");
|
|
-- Is it Sunday?
|
|
if ( day == STVDay and
|
|
(hour >= (STVStartHour-2) and hour <(STVStartHour+2))) then
|
|
showit = true;
|
|
end
|
|
end
|
|
end
|
|
if ( showit ) then
|
|
if ( activate ) then
|
|
FishingExtravaganzaFrame:Show();
|
|
end
|
|
elseif ( FishingExtravaganzaFrame:IsVisible() or
|
|
FishingExtravaganzaMini1:IsVisible() ) then
|
|
FishingExtravaganzaFrame:Hide();
|
|
for idx=1,NUMMINIPOIS do
|
|
PlotPOI(idx);
|
|
end
|
|
end
|
|
return showit;
|
|
end
|
|
FishingBuddy.Extravaganza.IsTime = IsTime;
|
|
|
|
local function UpdatePOI()
|
|
local x, y = GetSTVPosition();
|
|
local loc1 = GetNearestTen(x, y, -1);
|
|
local loc2 = GetNearestTen(x, y+0.01, 1);
|
|
local func = function(a, b) return a.dist < b.dist; end;
|
|
for idx=1,table.getn(loc2) do
|
|
tinsert(loc1, loc2[idx]);
|
|
end
|
|
table.sort(loc1, func);
|
|
for idx=1,NUMMINIPOIS do
|
|
local t = loc1[idx];
|
|
if ( t ) then
|
|
PlotPOI(idx, t.x - x, y - t.y);
|
|
else
|
|
PlotPOI(idx);
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Check for mouse down event for dragging frame.
|
|
FishingBuddy.Extravaganza.OnDragStart = function(arg1)
|
|
if (arg1 == "LeftButton") then
|
|
FishingExtravaganzaFrame:StartMoving();
|
|
FishingExtravaganzaFrame.isMoving = true;
|
|
end
|
|
end
|
|
|
|
-- Check for drag stop event to stop dragging.
|
|
FishingBuddy.Extravaganza.OnDragStop = function(arg1)
|
|
if (arg1 == "LeftButton") then
|
|
FishingExtravaganzaFrame:StopMovingOrSizing();
|
|
FishingExtravaganzaFrame.isMoving = false;
|
|
end
|
|
end
|
|
|
|
-- Handle watching the loot
|
|
FishingBuddy.Extravaganza.OnLoad = function()
|
|
this:RegisterEvent("PLAYER_LOGIN");
|
|
this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
|
|
this:RegisterEvent("VARIABLES_LOADED");
|
|
|
|
this:RegisterForDrag("LeftButton");
|
|
this:Hide();
|
|
end
|
|
|
|
FishingBuddy.Extravaganza.OnEvent = function()
|
|
local zone, subzone = FishingBuddy.GetZoneInfo();
|
|
if ( event == "ZONE_CHANGED_NEW_AREA" or event == "PLAYER_LOGIN" ) then
|
|
if ( zone == FishingBuddy.STVZONENAME and IsTime() ) then
|
|
this:RegisterEvent("LOOT_OPENED");
|
|
this:RegisterEvent("MINIMAP_UPDATE_ZOOM");
|
|
else
|
|
this:UnregisterEvent("LOOT_OPENED");
|
|
this:UnregisterEvent("MINIMAP_UPDATE_ZOOM");
|
|
end
|
|
elseif ( event == "LOOT_OPENED" ) then
|
|
if ( IsFishingLoot()) then
|
|
for index = 1, GetNumLootItems(), 1 do
|
|
if (LootSlotIsItem(index)) then
|
|
local fishlink = GetLootSlotLink(index);
|
|
local _, id, _ = FishingBuddy.SplitFishLink(fishlink);
|
|
if ( ExtravaganzaFish[id] ) then
|
|
MarkSchool();
|
|
STVUpdateTimer = 0;
|
|
if ( id == tastyfish_id ) then
|
|
numCaught = numCaught + 1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
elseif ( event == "MINIMAP_UPDATE_ZOOM" ) then
|
|
if ( zone == FishingBuddy.STVZONENAME ) then
|
|
if ( FishingBuddy.GetSetting("STVTimer") == 1 ) then
|
|
UpdatePOI();
|
|
end
|
|
end
|
|
elseif ( event == "VARIABLES_LOADED" ) then
|
|
local _,_,_,_,_,n = FishingBuddy.GetFishie(tastyfish_id);
|
|
if ( n ) then
|
|
tastyfish = n;
|
|
else
|
|
tastyfish = FISH;
|
|
end
|
|
IsTime(true);
|
|
this:UnregisterEvent("VARIABLES_LOADED");
|
|
end
|
|
end
|
|
|
|
FishingBuddy.Extravaganza.OnUpdate = function(elapsed)
|
|
if ( IsTime() ) then
|
|
if ( not FishingExtravaganzaFrame:IsVisible() ) then
|
|
FishingExtravaganzaFrame:Show();
|
|
end
|
|
STVUpdateTimer = STVUpdateTimer - elapsed;
|
|
if ( STVUpdateTimer < 0 ) then
|
|
local hour,minute = GetGameTime();
|
|
local minleft;
|
|
local checkhour = STVStartHour;
|
|
local line;
|
|
if ( hour >= STVStartHour ) then
|
|
line = FishingBuddy.TIMELEFT;
|
|
checkhour = checkhour + 2;
|
|
else
|
|
line = FishingBuddy.TIMETOGO;
|
|
end
|
|
minleft = (checkhour - hour)*60 - minute;
|
|
if ( minleft > 0 ) then
|
|
FishingExtravaganzaFrameButtonText:SetTextColor(0.1, 1.0, 0.1);
|
|
if ( minleft < 10 ) then
|
|
FishingExtravaganzaFrameButtonText:SetTextColor(1.0, 0.1, 0.1);
|
|
end
|
|
line = string.format(line, minleft/60, math.mod(minleft, 60),
|
|
numCaught, tastyfish);
|
|
FishingExtravaganzaFrameButtonText:SetText(line);
|
|
local width = FishingExtravaganzaFrameButtonText:GetWidth();
|
|
FishingExtravaganzaFrame:SetWidth(width + 16);
|
|
UpdatePOI();
|
|
if ( FishingBuddy_Info["Schools"] ) then
|
|
STVUpdateTimer = UPDATETIME_SCHOOLS;
|
|
else
|
|
STVUpdateTimer = UPDATETIME_COUNTER;
|
|
end
|
|
end
|
|
end
|
|
else
|
|
FishingExtravaganzaFrame:Hide();
|
|
end
|
|
end
|
|
|
|
local function GetObjectCoords(poi, index, numcolumns, texturewidth)
|
|
local width = poi:GetWidth();
|
|
local xCoord1, xCoord2, yCoord1, yCoord2;
|
|
local coordIncrement = width / texturewidth;
|
|
xCoord1 = mod(index , numcolumns) * coordIncrement;
|
|
xCoord2 = xCoord1 + coordIncrement;
|
|
yCoord1 = floor(index / numcolumns) * coordIncrement;
|
|
yCoord2 = yCoord1 + coordIncrement;
|
|
return xCoord1, xCoord2, yCoord1, yCoord2;
|
|
end
|
|
|
|
local start = 0;
|
|
-- debugging routines
|
|
FishingBuddy.Extravaganza.Debug = function(day, hour, zone)
|
|
STVDay = day;
|
|
STVStartHour = hour;
|
|
if ( zone ) then
|
|
FishingBuddy.STVZONENAME = zone;
|
|
end
|
|
IsTime(true);
|
|
end
|
|
|
|
FishingBuddy.Extravaganza.Dump = function()
|
|
local x, y = GetSTVPosition();
|
|
local iy = string.format("%d", y * 100);
|
|
|
|
FishingBuddy.Print("Current location: %d - %f, %f", iy, x, y);
|
|
|
|
if ( FishingBuddy_Info["Schools"][iy] ) then
|
|
for idx=1,table.getn(FishingBuddy_Info["Schools"][iy]) do
|
|
local t = FishingBuddy_Info["Schools"][iy][idx];
|
|
local dist = GetMinimapDistance(t.x, t.y, x, y);
|
|
FishingBuddy.Print("Distance: %f", dist);
|
|
end
|
|
end
|
|
end
|
|
|
|
-- eventually, display what fish you caught here
|
|
FishingBuddy.Extravaganza.MiniMap_OnEnter = function()
|
|
end
|
|
|