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