You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
13 KiB

--imports
local WIM = WIM;
local _G = _G;
local string = string;
local tostring = tostring;
local getn = getn;
-- needed for tutorials
local MAX_TUTORIAL_VERTICAL_TILE = 30;
local MAX_TUTORIAL_IMAGES = 3;
local MAX_TUTORIAL_KEYS = 4;
local TUTORIALFRAME_TOP_HEIGHT = 80;
local TUTORIALFRAME_MIDDLE_HEIGHT = 10;
local TUTORIALFRAME_BOTTOM_HEIGHT = 30;
local TUTORIALFRAME_WIDTH = 364;
--set namespace
setfenv(1, WIM);
db_defaults.shownTutorials = {};
local Tutorials = CreateModule("Tutorials", true);
local function varFriendly(var)
var = string.gsub(var, "[^%w_]", "_");
return var;
end
local theButton;
local _FlagTutorial = _G.FlagTutorial;
function _G.FlagTutorial(id)
local tut = string.match(tostring(id), "^WIM(.+)");
if(tut) then
if(tut ~= varFriendly(L["WIM Update Available!"])) then
db.shownTutorials[tut] = true;
end
else
_FlagTutorial(id);
end
end
local function setWIMorBlizzard(wim)
local alert = _G.TutorialFrameAlertButton;
if(wim) then
_G.TutorialFrameTop:SetTexture("Interface\\AddOns\\"..WIM.addonTocName.."\\Modules\\Textures\\UI-TUTORIAL-FRAME");
_G.TutorialFrameBottom:SetTexture("Interface\\AddOns\\"..WIM.addonTocName.."\\Modules\\Textures\\UI-TUTORIAL-FRAME");
alert:SetNormalTexture("Interface\\AddOns\\"..WIM.addonTocName.."\\Modules\\Textures\\UI-TUTORIAL-FRAME");
alert:SetHighlightTexture("Interface\\AddOns\\"..WIM.addonTocName.."\\Modules\\Textures\\UI-TUTORIAL-FRAME");
else
_G.TutorialFrameTop:SetTexture("Interface\\TutorialFrame\\UI-TUTORIAL-FRAME");
_G.TutorialFrameBottom:SetTexture("Interface\\TutorialFrame\\UI-TUTORIAL-FRAME");
alert:SetNormalTexture("Interface\\TutorialFrame\\UI-TUTORIAL-FRAME");
alert:SetHighlightTexture("Interface\\TutorialFrame\\UI-TUTORIAL-FRAME");
end
end
local function createChangelogButton()
local button = _G.CreateFrame("Button", "WIM_TutorialButtonChangeLog", _G.TutorialFrame, "UIPanelButtonTemplate");
local ok = _G.TutorialFrameOkayButton;
button:SetPoint("BOTTOM", 0, 40);
button:SetHeight(22);
button:SetNormalTexture("DialogButtonNormalTexture");
button:SetPushedTexture("DialogButtonPushedTexture");
button:SetHighlightTexture("DialogButtonHighlightTexture");
button:SetDisabledTexture("DialogButtonDisabledTexture");
_G.WIM_TutorialButtonChangeLogText:SetText(L["View Updates"]);
button:SetNormalFontObject("GameFontNormalSmall");
button:SetHighlightFontObject("GameFontNormalSmall");
button:SetDisabledFontObject("GameFontNormalSmall");
button:SetWidth(_G.WIM_TutorialButtonChangeLogText:GetStringWidth()+30)
button:Hide();
button:SetScript("OnClick", ShowChangeLog);
return button;
end
local function displayTutorial(title, tutorial)
local var = varFriendly(title);
if(not db.shownTutorials[var] or L["WIM Update Available!"] == title) then
db.shownTutorials[var] = true;
theButton = theButton or createChangelogButton();
_G["TUTORIAL_TITLEWIM"..var] = title;
_G["TUTORIALWIM"..var] = tutorial;
_G.TutorialFrame_NewTutorial("WIM"..var);
end
end
function Tutorials:OnEnable()
DisplayTutorial = displayTutorial;
end
function Tutorials:OnDisable()
-- to decrease table lookups, we can just define the function as such.
DisplayTutorial = function() end;
end
local _IsTutorialFlagged = _G.IsTutorialFlagged;
function _G.IsTutorialFlagged(id)
if(string.match(id, "^[0-9]+$")) then
--Blizzard Tutorial, resume...
return _IsTutorialFlagged(id);
else
-- WIM Tutorial
return false;
end
end
local ARROW_TYPES = {
"ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight",
"ArrowCurveUpRight", "ArrowCurveUpLeft", "ArrowCurveDownRight", "ArrowCurveDownLeft",
"ArrowCurveRightDown", "ArrowCurveRightUp", "ArrowCurveLeftDown", "ArrowCurveLeftUp",
}
local ARROW_SIZES = {
["ArrowUp"] = {x = 68, y = 89},
["ArrowDown"] = {x = 68, y = 89},
["ArrowLeft"] = {x = 89, y = 68},
["ArrowRight"] = {x = 89, y = 68},
["ArrowCurveUpRight"] = {x = 66, y = 81},
["ArrowCurveUpLeft"] = {x = 66, y = 81},
["ArrowCurveDownRight"] = {x = 66, y = 81},
["ArrowCurveDownLeft"] = {x = 66, y = 81},
["ArrowCurveRightDown"] = {x = 82, y = 66},
["ArrowCurveRightUp"] = {x = 82, y = 66},
["ArrowCurveLeftDown"] = {x = 82, y = 66},
["ArrowCurveLeftUp"] = {x = 82, y = 66},
}
local MOUSE_SIZE = { x = 76, y = 101}
local TUTORIAL_QUEST_ARRAY = {
["HUMAN"] = {questID = 7, displayNPC = 197},
["DWARF"] = {questID = 7},
["NIGHTELF"] = {questID = 7},
["GNOME"] = {questID = 7},
["DRAENEI"] = {questID = 7},
["WORGEN"] = {questID = 7},
["ORC"] = {questID = 7},
["SCOURGE"] = {questID = 7},
["TAUREN"] = {questID = 7},
["TROLL"] = {questID = 7},
["BLOODELF"] = {questID = 7},
["GOBLIN"] = {questID = 7},
};
local DISPLAY_DATA = {
["Base"] = {
tileHeight = 10,
anchorData = {align = "LEFT", xOff = 15, yOff = 30},
textBox = {topLeft_xOff = 33, topLeft_yOff = -75, bottomRight_xOff = -29, bottomRight_yOff = 35},
},
};
local TUTORIAL_HISTORY = {};
-- Tutorial Frame Hook used to implement WIM custom Tutorials.
local _TutorialFrame_Update = _G.TutorialFrame_Update;
function _G.TutorialFrame_Update(currentTutorial)
if(theButton) then
theButton:Hide();
end
WIM.addToTableUnique(TUTORIAL_HISTORY, currentTutorial);
if(string.match(currentTutorial, "^[0-9]+$")) then
--Blizzard Tutorial, resume...
dPrint("Blizzard Tutorial ID: "..currentTutorial);
setWIMorBlizzard(false);
_TutorialFrame_Update(currentTutorial);
else
-- WIM Tutorial
dPrint("WIM Tutorial ID: "..currentTutorial);
setWIMorBlizzard(true);
_G.FlagTutorial(currentTutorial);
_G.TutorialFrame.id = currentTutorial;
local displayData = DISPLAY_DATA[ currentTutorial ];
if ( not displayData ) then
displayData = DISPLAY_DATA["Base"];
end
-- setup the frame
_G.TutorialFrame_ClearTextures();
if (displayData.anchorData) then
local anchorData = displayData.anchorData;
_G.TutorialFrame:SetPoint( anchorData.align, _G.UIParent, anchorData.align, anchorData.xOff, anchorData.yOff );
end
if (displayData.tileHeight == 0) then
_G.TutorialFrameTop:Hide();
_G.TutorialFrameLeft1:Hide();
_G.TutorialFrameRight1:Hide();
_G.TutorialFrameBottom:Hide();
_G.TutorialFrameBackground:Hide();
_G.TutorialFrameCloseButton:Hide();
_G.TutorialFrameOkayButton:Hide();
_G.TutorialFramePrevButton:Hide();
_G.TutorialFrameNextButton:Hide();
_G.TutorialFrame:SetSize(1024, 768);
else
_G.TutorialFrameTop:Show();
_G.TutorialFrameLeft1:Show();
_G.TutorialFrameRight1:Show();
_G.TutorialFrameBottom:Show();
_G.TutorialFrameBackground:Show();
_G.TutorialFrameCloseButton:Show();
_G.TutorialFrameOkayButton:Show();
_G.TutorialFramePrevButton:Show();
_G.TutorialFrameNextButton:Show();
local anchorParentLeft = _G.TutorialFrameLeft1;
local anchorParentRight = _G.TutorialFrameRight1;
for i = 2, displayData.tileHeight do
local leftTexture = _G["TutorialFrameLeft"..i];
local rightTexture = _G["TutorialFrameRight"..i];
leftTexture:SetPoint("TOPLEFT", anchorParentLeft, "BOTTOMLEFT", 0, 0);
rightTexture:SetPoint("TOPRIGHT", anchorParentRight, "BOTTOMRIGHT", 0, 0);
leftTexture:Show();
rightTexture:Show();
anchorParentLeft = leftTexture;
anchorParentRight = rightTexture;
end
_G.TutorialFrameBottom:SetPoint("TOPLEFT", anchorParentLeft, "BOTTOMLEFT", 0, 0);
_G.TutorialFrameBottom:SetPoint("TOPRIGHT", anchorParentRight, "TOPRIGHT", 0, 0);
local height = TUTORIALFRAME_TOP_HEIGHT + (displayData.tileHeight * TUTORIALFRAME_MIDDLE_HEIGHT) + TUTORIALFRAME_BOTTOM_HEIGHT;
_G.TutorialFrame:SetSize(TUTORIALFRAME_WIDTH, height);
end
local _, className = _G.UnitClass("player");
local _, raceName = _G.UnitRace("player");
className = _G.strupper(className);
raceName = _G.strupper(raceName);
if (displayData.displayNPC) then
_G.TutorialNPCModel:SetCreature(TUTORIAL_QUEST_ARRAY[raceName].displayNPC);
_G.TutorialNPCModel:Show();
end
-- setup the text
-- check for class specific first, then race specific, then normal
local title = _G["TUTORIAL_TITLE"..currentTutorial.."_"..className];
if ( not title ) then
title = _G["TUTORIAL_TITLE"..currentTutorial.."_"..raceName];
if ( not title ) then
title = _G["TUTORIAL_TITLE"..currentTutorial];
end
end
local text = _G["TUTORIAL"..currentTutorial.."_"..className];
if ( not text ) then
text = _G["TUTORIAL"..currentTutorial.."_"..raceName];
if ( not text ) then
text = _G["TUTORIAL"..currentTutorial];
end
end
if (displayData.raidwarning) then
_G.RaidNotice_AddMessage(_G.RaidWarningFrame, text, _G.ChatTypeInfo["RAID_WARNING"]);
return;
end
if ( title and text) then
_G.TutorialFrameTitle:SetText(title);
_G.TutorialFrameText:SetText(text);
end
if ( displayData.textBox) then
_G.TutorialFrameTextScrollFrame:SetPoint("TOPLEFT", _G.TutorialFrame, "TOPLEFT", displayData.textBox.topLeft_xOff, displayData.textBox.topLeft_yOff);
_G.TutorialFrameTextScrollFrame:SetPoint("BOTTOMRIGHT", _G.TutorialFrame, "BOTTOMRIGHT", displayData.textBox.bottomRight_xOff, displayData.textBox.bottomRight_yOff);
end
-- setup the callout
local callOut = displayData.callOut;
if(callOut) then
_G.TutorialFrameCallOut:SetSize(callOut.width, callOut.height);
_G.TutorialFrameCallOut:SetPoint( callOut.align, callOut.parent, callOut.align, callOut.xOff, callOut.yOff );
_G.TutorialFrameCallOut:Show();
_G.TutorialFrameCallOutPulser:Play();
end
-- setup images
for i = 1, MAX_TUTORIAL_IMAGES do
local imageTexture = _G["TutorialFrameImage"..i];
local imageData = displayData["imageData"..i];
if(imageData and imageTexture) then
imageTexture:SetTexture(imageData.file);
imageTexture:SetPoint( imageData.align, _G.TutorialFrame, imageData.align, imageData.xOff, imageData.yOff );
if ( imageData.layer ) then
imageTexture:SetDrawLayer(imageData.layer);
end
imageTexture:Show();
elseif( imageTexture ) then
imageTexture:ClearAllPoints();
imageTexture:SetTexture("");
imageTexture:Hide();
end
end
-- setup mouse
local mouseData = displayData.mouseData;
if(mouseData) then
local mouseTexture = _G["TutorialFrameMouse"..mouseData.image];
mouseTexture:SetPoint( mouseData.align, TutorialFrame, mouseData.align, mouseData.xOff, mouseData.yOff );
local scale = 1.0;
if ( mouseData.scale ) then
scale = mouseData.scale;
end
mouseTexture:SetWidth( MOUSE_SIZE.x * scale );
mouseTexture:SetHeight( MOUSE_SIZE.y * scale );
if ( mouseData.layer ) then
mouseTexture:SetDrawLayer(mouseData.layer);
end
mouseTexture:Show();
end
-- setup keys
for i = 1, MAX_TUTORIAL_KEYS do
local keyTexture = _G["TutorialFrameKey"..i];
local keyString = _G["TutorialFrameKeyString"..i];
local keyData = displayData["keyData"..i];
if(keyTexture and keyString and keyData) then
keyTexture:SetPoint( keyData.align, TutorialFrame, keyData.align, keyData.xOff, keyData.yOff );
keyString:SetText( GetBindingText(GetBindingKey(keyData.command), "KEY_") );
if ( keyData.layer ) then
keyTexture:SetDrawLayer(keyData.layer);
keyString:SetDrawLayer(keyData.layer);
end
keyTexture:Show();
keyString:Show();
elseif ( keyTexture ) then
keyTexture:ClearAllPoints();
keyTexture:Hide();
keyString:Hide();
end
end
-- setup arrows
for i = 1, getn(ARROW_TYPES) do
local arrowData = displayData[ ARROW_TYPES[i] ];
local arrowTexture = _G[ "TutorialFrame"..ARROW_TYPES[i] ];
if ( arrowData and arrowTexture ) then
arrowTexture:SetPoint( arrowData.align, TutorialFrame, arrowData.align, arrowData.xOff, arrowData.yOff );
if ( arrowData.layer ) then
arrowTexture:SetDrawLayer(arrowData.layer);
end
local scale = arrowData.scale;
if ( not scale ) then
scale = 1.0;
end
arrowTexture:SetWidth( ARROW_SIZES[ARROW_TYPES[i]].x * scale );
arrowTexture:SetHeight( ARROW_SIZES[ARROW_TYPES[i]].y * scale );
arrowTexture:Show();
elseif ( arrowTexture ) then
arrowTexture:ClearAllPoints();
arrowTexture:Hide();
end
end
-- show
_G.TutorialFrame:Show();
_G.TutorialFrame_CheckNextPrevButtons();
end
end
local function getHistoryIndex(id)
for i=1, #TUTORIAL_HISTORY do
if(TUTORIAL_HISTORY[i] == id) then
return i;
end
end
return;
end
local _GetNextCompleatedTutorial = _G.GetNextCompleatedTutorial;
function _G.GetNextCompleatedTutorial(id)
if(string.match(id, "^[0-9]+$")) then
return _GetNextCompleatedTutorial(id);
else
local i = getHistoryIndex(id);
return i and TUTORIAL_HISTORY[i+1];
end
end
local _GetPrevCompleatedTutorial = _G.GetPrevCompleatedTutorial;
function _G.GetPrevCompleatedTutorial(id)
if(string.match(id, "^[0-9]+$")) then
return _GetPrevCompleatedTutorial(id);
else
local i = getHistoryIndex(id);
return i and TUTORIAL_HISTORY[i-1];
end
end
--Global to add tutorial
function DisplayTutorial(title, tutorial)
-- this function is defined when the module is enabled.
end
-- this is used to show tutorial even if Tutorials are disabled.
DisplayTutorialForce = displayTutorial;