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
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;
|
|
|