vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
NUM_SLOTS = 120;

-------------------------------------------------------------------------------
-- tab management code, credits to guim author
-------------------------------------------------------------------------------

SA_SUBFRAMES = { "SABasicOptionsFrame", "SAListOptionsFrame", "SAAdvancedOptionsFrame", "SmartActionsOptionsFrame" };

function SA_ToggleDialog(tab)
        local subFrame = getglobal(tab);
        if ( subFrame ) then
                PanelTemplates_SetTab(SAOptionsFrame, subFrame:GetID());
                if ( SAOptionsFrame:IsVisible() ) then
                        PlaySound("igCharacterInfoTab");
                else
                        ShowUIPanel(SAOptionsFrame);
                end
                SA_ShowSubFrame(tab);
        end
end

function SA_ShowSubFrame(frameName)
        for index, value in SA_SUBFRAMES do
                if ( value == frameName ) then
                        getglobal(value):Show();
                else
                        getglobal(value):Hide();        
                end     
        end 
end

function SA_Tab_OnClick()
        local id = this:GetID();
        local tab = SA_SUBFRAMES[id];
        local subFrame = getglobal(tab);
        PanelTemplates_SetTab(SAOptionsFrame, id);
        SA_ShowSubFrame(tab);
        PlaySound("igCharacterInfoTab");
end

-------------------------------------------------------------------------------
-- spell & action drag hookups
-------------------------------------------------------------------------------

local SA_DRAGSPELL = nil;
local SA_DRAGSLOT = nil;
local SA_DRAGNAME = nil;

function SA_ClearDragData()
        SA_DRAGSPELL = nil;
        SA_DRAGSLOT = nil;
        SA_DRAGNAME = nil;
end
 
-- hook to spellbook pickup routine
local SA_BasePickupSpell = PickupSpell;
function PickupSpell(id, bookType)
        SA_ClearDragData();
        local result = SA_BasePickupSpell(id, bookType);
        --SA_Debug("picked up spell id="..id.." bookType="..bookType);
        if (CursorHasSpell()) then
                local name, rank = GetSpellName(id, bookType);
                local texture = GetSpellTexture(id, bookType);
                SA_DRAGSPELL = {};
                SA_DRAGSPELL.Id = id;
                SA_DRAGSPELL.Texture = texture;
                SA_DRAGSPELL.Name = name;
                SA_DRAGSPELL.BookType = bookType;
                SA_DRAGNAME = name;
        end
        return result;
end

local SA_BasePickupAction = PickupAction;
function PickupAction(slot)
        SA_ClearDragData();
        SA_Debug("picked up spell from slot "..slot);
        -- set drag slot
        SA_DRAGSLOT = slot;
        SA_DRAGNAME = SA_GetSlotName(slot);
        SA_Debug("SA_DRAGNAME="..tostring(SA_DRAGNAME));
        return SA_BasePickupAction(slot);
end

-------------------------------------------------------------------------------
-- smart assist configuration dialog
-------------------------------------------------------------------------------

function SA_Options_Init()
end

function SA_Options_OnHide()
end

function SA_Options_OnLoad()
        tinsert(UISpecialFrames, "SAOptionsFrame");
        -- Tab Handling code
        PanelTemplates_SetNumTabs(this, 4);
        PanelTemplates_SetTab(this, 1);
end

-- todo: this update is not anymore good since we have divided optiosn across several tabs ...
function SA_Options_OnShow()
        SAPriorizeHealthCB:SetChecked(SA_OPTIONS.PriorizeHealth);
        SAAssistOnEmoteCB:SetChecked(SA_OPTIONS.AssistOnEmote);
        SAVisualWarningCB:SetChecked(SA_OPTIONS.VisualWarning);
        SAFallbackTargetNearestCB:SetChecked(SA_OPTIONS.FallbackTargetNearest);
        SACheckNearestCB:SetChecked(SA_OPTIONS.CheckNearest);
        SANearestMustBePvPCB:SetChecked(SA_OPTIONS.NearestMustBePvP);
        SANearestMustBeTargetingCB:SetChecked(SA_OPTIONS.NearestMustBeTargetting);
        SAAutoAssistCB:SetChecked(SA_OPTIONS.AutoAssist);

        SAAutoPetAttackCB:SetChecked(SA_OPTIONS.AutoPetAttack);
        SAAutoPetAttackBusyCB:SetChecked(SA_OPTIONS.AutoPetAttackBusy);
        
        SA_Options_UpdatePullerText();
                
        if (SA_OPTIONS.AutoAssistTexture) then
                SAAssistText:SetText(SA_OPTIONS.AutoAssistName);
                SA_Debug("setting button texture to="..SA_OPTIONS.AutoAssistTexture);
                SetItemButtonTexture(SAAssistWithSlot, SA_OPTIONS.AutoAssistTexture);
        end
        SA_Options_UpdateClassOrder();
        
        -- set health slider value & update text
        SAHealthSlider:SetValue(SA_OPTIONS.PriorizeHealthValue);
        SA_Options_UpdateHealthSlider();
end

-------------------------------------------------------------------------------
-- Update list options tab
-------------------------------------------------------------------------------

function SA_Options_VariablesLoaded()
        SA_Options_AddIconPositions("SAClassIconMode");
        SA_Options_AddIconPositions("SATargetIconMode");
        SA_Options_AddIconPositions("SAHuntersMarkIconMode");
end

function SA_Options_AddIconPositions(name)
        local c = getglobal(name);
        for i=1, table.getn(SA_ICONPOS) do
                Selection_AddSelection(c, i, SA_ICONPOS[i].name);
        end
end

function SA_Options_OnShowListOptions()
        SAAudioWarningCB:SetChecked(SA_OPTIONS.AudioWarning);
        SALostAudioWarningCB:SetChecked(SA_OPTIONS.LostAudioWarning);
        
        SAVerboseAcquiredAggroCB:SetChecked(SA_OPTIONS.VerboseAcquiredAggro);
        SAVerboseLostAggroCB:SetChecked(SA_OPTIONS.VerboseLostAggro);
        
        SAShowAvailableCB:SetChecked(SA_OPTIONS.ShowAvailable);
        SAPreservedOrderCB:SetChecked(SA_OPTIONS.PreservedOrder);
        SATankModeCB:SetChecked(SA_OPTIONS.TankMode);
        SAAddMyTargetCB:SetChecked(SA_OPTIONS.AddMyTarget);
        SAOutOfCombatCB:SetChecked(SA_OPTIONS.OutOfCombat);
        SAHideTBYCB:SetChecked(SA_OPTIONS.HideTBY);
        SAHideTitleCB:SetChecked(SA_OPTIONS.HideTitle);
        
        SAListWidthSlider:SetValue(SA_OPTIONS.ListWidth);
        SAListScaleSlider:SetValue(SA_OPTIONS.ListScale);

        SAListSpacingSlider:SetValue(SA_OPTIONS.ListSpacing);
        SAListHorizontalCB:SetChecked(SA_OPTIONS.ListHorizontal);
        SAListTwoRowCB:SetChecked(SA_OPTIONS.ListTwoRow);
        
        SA_Options_UpdateListWidthSlider();
        SA_Options_UpdateListSpacingSlider();
        
        Selection_SetSelectedValue(SAClassIconMode, SA_OPTIONS.ClassIconMode);
        Selection_SetSelectedValue(SATargetIconMode, SA_OPTIONS.TargetIconMode);
        Selection_SetSelectedValue(SAHuntersMarkIconMode, SA_OPTIONS.HuntersMarkIconMode);
        
        SA_Options_DisplayList(true);
end

function SA_Options_OnHideListOptions()
        SA_Options_DisplayList(false);
end

function SA_Options_DisplayList(display)
        if (display) then
                SA_List_SetTitleButton(MODE_NORMAL);
        else
                SA_List_SetTitleButton(MODE_OOC);
        end
        for i=1, 10 do
                local box = getglobal("Target"..i);
                if (display) then
                        box:Show();
                else
                        box:Hide();
                end;
        end
end

function SA_Options_UpdateListWidthSlider()
        SA_OPTIONS.ListWidth = SAListWidthSlider:GetValue();
        SA_List_UpdateAppearance();
end

function SA_Options_UpdateListScaleSlider()
        SA_OPTIONS.ListScale = SAListScaleSlider:GetValue();
        SAListFrameScaler:SetScale(SA_OPTIONS.ListScale);
        local s = string.sub(tostring(SA_OPTIONS.ListScale),0,4);
        SAListScaleSliderText:SetText("list scale "..s);
end

function SA_Options_UpdateListSpacingSlider()
        SA_OPTIONS.ListSpacing = SAListSpacingSlider:GetValue();
        SA_List_UpdateAppearance();
end

function SA_Options_UpdateListSpacingSliderText()
        if (SA_OPTIONS.ListHorizontal) then
                SAListSpacingSliderHigh:SetText("right");
                SAListSpacingSliderLow:SetText("left");
        else
                SAListSpacingSliderHigh:SetText("up");
                SAListSpacingSliderLow:SetText("down");
        end
end

-- callback from SmartSelection
function SA_Options_ClassIcon(value)
        SA_OPTIONS["ClassIconMode"] = value;
        SA_List_UpdateAppearance();
end

-- callback from SmartSelection
function SA_Options_TargetIcon(value)
        SA_OPTIONS["TargetIconMode"] = value;
        SA_List_UpdateAppearance();
end

function SA_Options_HuntersMarkIcon(value)
        SA_OPTIONS["HuntersMarkIconMode"] = value;
        SA_List_UpdateAppearance();
end

-------------------------------------------------------------------------------
-- Update advanced options tab
-------------------------------------------------------------------------------

function SA_Options_OnShowAdvanced()
        
        -- update the dropdown Select Modifier
        UIDropDownMenu_SetSelectedID(SASelectModifierDD, SA_OPTIONS.AssistKeyMode);
        SASelectModifierDDText:SetText(SELECT_MODIFIER_TEXTS[SA_OPTIONS.AssistKeyMode]);
        if (SA_OPTIONS.AssistKeyMode == 4) then
                SASelectModifierDDInfo:SetText("selecting does not assist");
        else
                SASelectModifierDDInfo:SetText("assists player");
        end
        -- update the dropdown Assist Modifier
        UIDropDownMenu_SetSelectedID(SAAssistModifierDD, SA_OPTIONS.DisableAutoCastKeyMode);
        SAAssistModifierDDText:SetText(ASSIST_MODIFIER_TEXTS[SA_OPTIONS.DisableAutoCastKeyMode]);
                
        -- set disable slider value & update text
        SADisableSlider:SetValue(SA_OPTIONS.DisableSliderValue);
        SA_Options_UpdateDisableSlider();

        SAPauseResetsOrderCB:SetChecked(SA_OPTIONS.PauseResetsOrder);
        SADisableTargetNearestCB:SetChecked(SA_OPTIONS.DisableTargetNearest);
        SADisablePriorityHealthCB:SetChecked(SA_OPTIONS.DisablePriorityHealth);
                        
        SAVerboseAssistCB:SetChecked(SA_OPTIONS.VerboseAssist);
        SAVerboseIncomingCB:SetChecked(SA_OPTIONS.VerboseIncoming);
        SAVerboseNearestCB:SetChecked(SA_OPTIONS.VerboseNearest);
        SAVerboseUnableToAssistCB:SetChecked(SA_OPTIONS.VerboseUnableToAssist);
        
        SADisableAssistWithoutPullerCB:SetChecked(SA_OPTIONS.DisableAssistWithoutPuller);
end

function SA_Options_UpdatePullerText()
        local candidates,_ = SA_GetCandidates();
        --SA_RefreshPuller(candidates); -- causes infinite loop and stack overflow because this method is called from refresh path also!
        if (SA_OPTIONS["puller"]==nil) then
                SACurrentPuller:SetText("Puller: none / pet when available");
        else
                SACurrentPuller:SetText("Puller: "..SA_OPTIONS["puller"]);
        end
end

----------------------------------------------------------------------------------
-- displays list of all available members in order of current assist configuration
----------------------------------------------------------------------------------

function SA_PullerText_OnEnter(arg)
        local text = "Current assist order:\n\n";
        local candidates, members = SA_GetCandidates(false);
        if (members > 0) then
                table.sort(candidates, function(a,b) return SA_SortCandidate(a,b,members) end);
                for _,candidate in candidates do
                        -- colorize text by class
                        local cv = RAID_CLASS_COLORS[string.upper(candidate["class"])];
                        local color = "";
                        if (not cv) then
                                color = "|cff888888";
                        else
                                color = SA_ToTextCol(cv.r, cv.g, cv.b);
                        end
                        text = text .. color..candidate.unitName .. "|r" .. "\n";
                end
        else
                text = text .. "- no members";
        end
        GameTooltip:SetOwner(arg, "ANCHOR_LEFT");
        GameTooltip:SetText(text,1,1,1,1,1);
end

function SA_PullerText_OnLeave(arg)
        GameTooltip:Hide();
end

-------------------------------------------------------------------------------
-- togle a boolean option, play a tick sound
-------------------------------------------------------------------------------

function SA_ToggleOption(option)
        if (SA_OPTIONS[option]==nil or SA_OPTIONS[option]==false) then
                SA_OPTIONS[option] = true;
                PlaySound("igMainMenuOptionCheckBoxOff");
        else
                SA_OPTIONS[option] = false;
                PlaySound("igMainMenuOptionCheckBoxOn");
        end
end

function SA_ToggleAvailable()
        SA_ToggleOption("ShowAvailable");
        if (SA_OPTIONS.ShowAvailable) then
                printInfo("Enabling available assist list and related features");
                SAListFrame:Show();
        else
                printInfo("Disabling available assist list and related features");
                SAListFrame:Hide();
        end
        SA_Options_OnShow();
end

-------------------------------------------------------------------------------
-- auto cast on assist slot
-------------------------------------------------------------------------------

function SA_SpellSlot_OnReceiveDrag()
        SA_Debug("Received drag");
        
        -- enable whining again, incase user has Auto Attack enabled which will screw the cast
        SA_OPTIONS.AutoAttackWhineIgnored = false;
        
        if (CursorHasSpell() and not SA_DRAGSLOT) then
                SA_OPTIONS.AutoAssist = true;
                SA_OPTIONS.AutoAssistTexture = SA_DRAGSPELL.Texture;
                SA_OPTIONS.AutoAssistName = SA_DRAGSPELL.Name;

                -- drop icon
                PickupSpell(SA_DRAGSPELL.Id, SA_DRAGSPELL.BookType);
                
                -- update the config window             
                SA_Options_OnShow();
        else
                SpellBookFrame:Show();
        end
end

-------------------------------------------------------------------------------
-- updates classorder view
-------------------------------------------------------------------------------

function SA_Options_UpdateClassOrder()
        for k,v in SA_OPTIONS.ClassOrder do
                getglobal("ClassOrderFrameClass" .. k .. "Text"):SetText(v);
        end
end

-------------------------------------------------------------------------------
-- update disable target
-------------------------------------------------------------------------------

function SA_Options_UpdateDisableSlider()
        SA_OPTIONS.DisableSliderValue = SADisableSlider:GetValue();
        SADisableSliderText:SetText("members > "..SA_OPTIONS.DisableSliderValue);
end

-------------------------------------------------------------------------------
-- updates health slider TEXT (not value)
-------------------------------------------------------------------------------

function SA_Options_UpdateHealthSlider()
        SA_OPTIONS.PriorizeHealthValue = SAHealthSlider:GetValue();
        SAHealthSliderText:SetText("Priority health ("..SA_OPTIONS.PriorizeHealthValue.." %)");
end

-------------------------------------------------------------------------------
-- class order routines
-------------------------------------------------------------------------------

function SA_ClassOrderMove(move)
        local text = getglobal(this:GetParent():GetName() .. "Text"):GetText()
        -- where is our text in table, also check for boundaries
        local index = SA_TableIndex(SA_OPTIONS.ClassOrder, text);
        -- move the element in our list 
        local moving = SA_OPTIONS.ClassOrder[index];
        table.remove(SA_OPTIONS.ClassOrder, index);
        table.insert(SA_OPTIONS.ClassOrder, index+move, moving);
        SA_Options_UpdateClassOrder();
end

-------------------------------------------------------------------------------
-- initialize dropdown (thanks to atlas)
-------------------------------------------------------------------------------

SELECT_MODIFIER_TEXTS = {"Shift - select", "Ctrl - select", "Alt - select", "Disabled" };
function SASelectModifierDD_Initialize()
        local info;
        for _,value in SELECT_MODIFIER_TEXTS do
                info = {
                        text = value;
                        func = SASelectModifierDDButton_OnClick;
                };
                UIDropDownMenu_AddButton(info);
        end
end

function SASelectModifierDD_OnLoad()
        UIDropDownMenu_Initialize(SASelectModifierDD, SASelectModifierDD_Initialize);
        UIDropDownMenu_SetSelectedID(SASelectModifierDD, 1);
        UIDropDownMenu_SetWidth(90);
end

function SASelectModifierDDButton_OnClick()
        local oldID = UIDropDownMenu_GetSelectedID(SASelectModifierDD);
        if(oldID ~= this:GetID()) then
                SA_OPTIONS["AssistKeyMode"]=this:GetID()
                SA_Options_OnShowAdvanced();
        end
end

-------------------------------------------------------------------------------

ASSIST_MODIFIER_TEXTS = {"Shift", "Ctrl ", "Alt", "None" };
function SAAssistModifierDD_Initialize()
        local info;
        for _,value in ASSIST_MODIFIER_TEXTS do
                info = {
                        text = value;
                        func = SAAssistModifierDDButton_OnClick;
                };
                UIDropDownMenu_AddButton(info);
        end
end

function SAAssistModifierDD_OnLoad()
        UIDropDownMenu_Initialize(SAAssistModifierDD, SAAssistModifierDD_Initialize);
        UIDropDownMenu_SetSelectedID(SAAssistModifierDD, 1);
        UIDropDownMenu_SetWidth(90);
end

function SAAssistModifierDDButton_OnClick()
        local oldID = UIDropDownMenu_GetSelectedID(SAAssistModifierDD);
        if(oldID ~= this:GetID()) then
                SA_OPTIONS["DisableAutoCastKeyMode"]=this:GetID()
                SA_Options_OnShowAdvanced();
        end
end

-------------------------------------------------------------------------------
-- smart spell configuration methods
-------------------------------------------------------------------------------

function SA_Options_SmartActions_OnShow()
        SATriggerAssistCB:SetChecked(SA_OPTIONS.TriggerAssist);
        SA_RefreshSlots();
end

function SA_RefreshSlots()

        local i = 0;
        for _,spell in SA_OPTIONS.AssistSpells do
                i = i + 1;
                local slot = getglobal("SAAssistSlot"..i);
                local texture = SA_GetTextureForSpell(spell);
                if (texture) then
                        SetItemButtonTexture(slot, texture);
                else
                        SA_Debug("unknown texture for spell "..tostring(spell));
                        SetItemButtonTexture(slot, "Interface\\Icons\\INV_Misc_QuestionMark");
                end
        end

        -- clear old textures   
        for c = i+1, 20 do 
                local slot = getglobal("SAAssistSlot"..c);
                SetItemButtonTexture(slot, nil);
        end
        
end

function SA_SmartActionSlot_OnEnter(arg)
        if (SA_DRAGSLOT or SA_DRAGSPELL) then return; end;
        local text = SA_OPTIONS.AssistSpells[this:GetID()];
        if (text) then
                GameTooltip:SetOwner(arg, "ANCHOR_RIGHT");
                GameTooltip:SetText(text,1,1,1,1,1);
        end
end

function SA_SmartActionSlot_OnClick()
        if (CursorHasSpell()) then
                printInfo("This is drag instead of click!");
                SA_SmartActionSlot_OnReceiveDrag();
                return;
        end
        
        -- remove selected spell & update table element id's (why doesn't lua do this =P)
        if (SA_OPTIONS.AssistSpells[this:GetID()]) then
                table.remove(SA_OPTIONS.AssistSpells, this:GetID());
                local temp = {};
                for _,v in SA_OPTIONS.AssistSpells do
                        table.insert(temp, v);
                end
                SA_OPTIONS.AssistSpells = temp;
        end
        
        SA_Options_SmartActions_OnShow();
end

function SA_SmartActionSlot_OnReceiveDrag()
        -- get spell name and release drag, Todo: separate to function?
        local spell = SA_DRAGNAME;
        if (SA_DRAGSLOT) then
                PickupAction(SA_DRAGSLOT);
        elseif (SA_DRAGSPELL) then
                PickupSpell(SA_DRAGSPELL.Id, SA_DRAGSPELL.BookType);
        else
                printInfo("bug #5933");
        end
        SA_ClearDragData();
        
        if (not spell) then
                printInfo("Problem: Unable to get spell name");
                return;
        end
        
        if (SA_TableIndex(SA_OPTIONS.AssistSpells, spell) ~= -1) then
                printInfo("Spell already exists in list");
                return;
        end
        
        SA_Debug("Adding spell "..tostring(spell));
        table.insert(SA_OPTIONS.AssistSpells, spell);

        -- refresh the view
        SA_Options_SmartActions_OnShow()
end

-------------------------------------------------------------------------------
-- reset all smartactions
-------------------------------------------------------------------------------

function SA_ResetSmartActions()
        SA_OPTIONS.AssistSpells = {};
        -- refresh the view
        SA_Options_SmartActions_OnShow()
end

-------------------------------------------------------------------------------
-- try to autoconfigure smart actions
-------------------------------------------------------------------------------

function SA_AutoConfigureSmartActions()
        local found = 0;
        for slot = 1, NUM_SLOTS do
                local spell = SA_GetSlotName(slot);
                if (spell) then
                        if (AUTOCONF_ATTACKS[spell]) then
                                if (SA_TableIndex(SA_OPTIONS.AssistSpells, spell) == -1) then 
                                        SA_Debug("found attack "..spell);
                                        table.insert(SA_OPTIONS.AssistSpells, spell);
                                        found = found + 1;
                                end
                        end
                end
        end
        if (found>0) then
                printInfo("Auto configured "..found.." actions.");
        else
                printInfo("Auto configure was unable to find any actions. This is most likelly because your class does not (yet) have predefined set of spells or you are using non-english client.");
        end
        
        -- refresh the view
        SA_Options_SmartActions_OnShow();
end

-------------------------------------------------------------------------------
-- slot & spell utilities
-------------------------------------------------------------------------------

function SA_GetTextureForSpell(name)
        local id = SA_FindSlotByName(name);
        if (id==nil) then return nil; end;
        return GetActionTexture(id);
end

function SA_FindSlotByName(name)
        local textName;
        for slot = 1, NUM_SLOTS do
                slotName = SA_GetSlotName(slot);
                if (slotName == name) then
                        return slot;
                end             
        end
        return nil;
end

function SA_GetSlotName(slot)
        SAActionTip:SetAction(slot);
        return SAActionTipTextLeft1:GetText();
end