diff --git a/Achievements/Duo.lua b/Achievements/Duo.lua index d493c99..543f727 100644 --- a/Achievements/Duo.lua +++ b/Achievements/Duo.lua @@ -188,12 +188,7 @@ end function duo_rules:Check() -- this code causes the rules checker to ignore all duo/trio rules at max level if Hardcore_Character.game_version ~= nil then - local max_level - if Hardcore_Character.game_version == "Era" or Hardcore_Character.game_version == "SoM" then - max_level = 60 - else -- if Hardcore_Character.game_version == "WotLK" or anything else - max_level = 80 - end + local max_level = Hardcore:GetMaxLevel() -- 25, 60 or 80 if UnitLevel("player") >= max_level then return end diff --git a/Achievements/Trio.lua b/Achievements/Trio.lua index b746091..bacdc36 100644 --- a/Achievements/Trio.lua +++ b/Achievements/Trio.lua @@ -235,12 +235,7 @@ end function trio_rules:Check() -- this code causes the rules checker to ignore all duo/trio rules at max level if Hardcore_Character.game_version ~= nil then - local max_level - if Hardcore_Character.game_version == "Era" or Hardcore_Character.game_version == "SoM" then - max_level = 60 - else -- if Hardcore_Character.game_version == "WotLK" or anything else - max_level = 80 - end + local max_level = Hardcore:GetMaxLevel() -- 25, 60 or 80 if UnitLevel("player") >= max_level then return end diff --git a/CharacterStatusScreen.lua b/CharacterStatusScreen.lua index c399783..0eb3a94 100644 --- a/CharacterStatusScreen.lua +++ b/CharacterStatusScreen.lua @@ -173,7 +173,7 @@ function extractDetails(str, ignoreKeys) str = str:gsub("^%s*%((.+)%)%s*$", "%1") local details_table = {} for key, value in str:gmatch("(%S+)=(%S+)") do - Hardcore:Print("extractDetails: " .. key .. " = " .. value) + -- Hardcore:Print("extractDetails: " .. key .. " = " .. value) -- Check if the current key is in the ignoreKeys array local ignore = false for _, ignoreKey in ipairs(ignoreKeys or {}) do @@ -289,15 +289,38 @@ function UpdateCharacterHC( version_name:SetFont("Fonts\\FRIZQT__.TTF", 10, "") character_meta_data_container:AddChild(version_name) + -- NOTE: _hardcore_character.endgame will be a boolean if it's you, or a string if it's not you + + -- Hardcore:Print("Value of endgame: !" .. _hardcore_character.endgame .. "!") + + -- local endgame_label = AceGUI:Create("HardcoreClassTitleLabel") + -- endgame_label:SetRelativeWidth(1.0) + -- endgame_label:SetHeight(60) + -- local endgame_status = "false" + -- if _hardcore_character.endgame ~= nil and tostring(_hardcore_character.endgame) == "true" then + -- endgame_status = "true" + -- end + -- endgame_label:SetText("Endgame status: " .. endgame_status) + -- endgame_label:SetFont("Fonts\\FRIZQT__.TTF", 10, "") + -- character_meta_data_container:AddChild(endgame_label) + -- SET UP FILTERING local filtered_status = _hardcore_character.verification_status local filtered_details = _hardcore_character.verification_details - --Hardcore:Print("Status: ".. _hardcore_character.verification_status) + -- Hardcore:Print("Status: ".. _hardcore_character.verification_status) + -- Hardcore:Print("Details: ".. _hardcore_character.verification_details) if _player_name ~= UnitName("player") then - -- Remove tracked_time and deaths entries - local ignoreKeys = {"tracked_time", "deaths", "appeals", "repeat_dung", "overlvl_dung"} + -- Remove tracked_time, deaths and appeals entries + local ignoreKeys = {"tracked_time", "deaths", "appeals"} -- "repeat_dung", "overlvl_dung" -- no longer exempt + + if _hardcore_character.endgame ~= nil and tostring(_hardcore_character.endgame) == "true" then + -- if endgame, also remove trades and repeat dungeons + table.insert(ignoreKeys, "trades") + table.insert(ignoreKeys, "repeat_dung") + end + local details_table = extractDetails(_hardcore_character.verification_details, ignoreKeys) filtered_details = formatDetails(details_table) @@ -311,6 +334,11 @@ function UpdateCharacterHC( else filtered_status = "|cff99ff99UNKNOWN|r\n(previous addon version)" end + + end + + if _hardcore_character.endgame ~= nil and tostring(_hardcore_character.endgame) == "true" then + filtered_status = filtered_status .. " (endgame)" end if _hardcore_character.hardcore_player_name ~= nil and _hardcore_character.hardcore_player_name ~= "" then diff --git a/Hardcore.lua b/Hardcore.lua index 514fc27..5f429ae 100644 --- a/Hardcore.lua +++ b/Hardcore.lua @@ -103,6 +103,7 @@ Hardcore_Character = { game_version = "", hardcore_player_name = "", custom_pronoun = false, + endgame = false, } Backup_Character_Data = {} @@ -406,12 +407,49 @@ local ALERT_STYLES = { }, } Hardcore_Alert_Frame:SetScale(0.7) +Hardcore_Frame:ApplyBackdrop() -- the big frame object for our addon +--- @class Hardcore : BackdropTemplate|Frame local Hardcore = CreateFrame("Frame", "Hardcore", nil, "BackdropTemplate") Hardcore.ALERT_STYLES = ALERT_STYLES -Hardcore_Frame:ApplyBackdrop() +--- VERSION CHECKS, stolen artlessly from Questie + +--- Addon is running on Classic Wotlk client +Hardcore.isWotlk = WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC + +--- Addon is running on Classic TBC client +Hardcore.isTBC = WOW_PROJECT_ID == WOW_PROJECT_BURNING_CRUSADE_CLASSIC + +--- Addon is running on Classic "Vanilla" client: Means Classic Era and its seasons like SoM +Hardcore.isClassic = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC + +--- Addon is running on Classic "Vanilla" client and on Era realm (non-seasonal) +Hardcore.isEra = Hardcore.isClassic and (not C_Seasons.HasActiveSeason()) + +--- Addon is running on Classic "Vanilla" client and on any Seasonal realm (see: https://wowpedia.fandom.com/wiki/API_C_Seasons.GetActiveSeason ) +Hardcore.isEraSeasonal = Hardcore.isClassic and C_Seasons.HasActiveSeason() + +--- Addon is running on Classic "Vanilla" client and on Season of Mastery realm specifically +Hardcore.isSoM = Hardcore.isClassic and C_Seasons.HasActiveSeason() and (C_Seasons.GetActiveSeason() == Enum.SeasonID.SeasonOfMastery) + +--- Addon is running on Classic "Vanilla" client and on Season of Discovery realm specifically +Hardcore.isSoD = Hardcore.isClassic and C_Seasons.HasActiveSeason() and (C_Seasons.GetActiveSeason() == 2) --- in the list as 'Placeholder' but it's actually SoD + +--- Addon is running on a HardCore realm specifically +Hardcore.isHardcore = C_GameRules and C_GameRules.IsHardcoreActive() + +function Hardcore:GetMaxLevel() + -- skipping non-active seasons/expansions + if Hardcore.isWotlk then + return 80 + elseif Hardcore.isSoD then + return 25 -- will be 40 soon, update checks then. maybe new season? + else + return 60 + end +end local function startXGuildChatMsgRelay(msg) local commMessage = COMM_COMMANDS[12] .. COMM_COMMAND_DELIM .. msg @@ -463,14 +501,7 @@ local function startXGuildDeathMsgRelay() end function FailureFunction(achievement_name) - local max_level = 60 - if - (Hardcore_Character.game_version ~= "") - and (Hardcore_Character.game_version ~= "Era") - and (Hardcore_Character.game_version ~= "SoM") - then - max_level = 80 - end + local max_level = Hardcore:GetMaxLevel() -- 25, 60 or 80 if UnitLevel("player") == max_level then return end @@ -550,6 +581,7 @@ local saved_variable_meta = { { key = "converted_time", initial_data = "" }, { key = "game_version", initial_data = "" }, { key = "hardcore_player_name", initial_data = "" }, + { key = "endgame", initial_data = false }, } local settings_saved_variable_meta = { @@ -769,18 +801,11 @@ end -- TradeFrameTradeButton:SetScript("OnClick", function() - local duo_trio_partner = false - local legacy_duo_support = #Hardcore_Character.trade_partners > 0 local target_trader = TradeFrameRecipientNameText:GetText() local level = UnitLevel("player") - local max_level = 60 - if - (Hardcore_Character.game_version ~= "") - and (Hardcore_Character.game_version ~= "Era") - and (Hardcore_Character.game_version ~= "SoM") - then - max_level = 80 - end + local max_level = Hardcore:GetMaxLevel() -- 25, 60 or 80 + local duo_trio_partner = false + if Hardcore_Character.team ~= nil then for _, name in ipairs(Hardcore_Character.team) do if target_trader == name then @@ -790,14 +815,28 @@ TradeFrameTradeButton:SetScript("OnClick", function() end end - if duo_trio_partner == true then + if duo_trio_partner == true then -- always allow with partner AcceptTrade() - elseif (level == max_level) or legacy_duo_support then + elseif (Hardcore_Character.endgame) then + if Hardcore_Character.verification_status ~= "PASS" then + Hardcore:Print("|cFFFF0000BLOCKED:|r You may only trade with a 'PASS' status") + return + end + if other_hardcore_character_cache[target_trader].verification_status ~= "PASS" then + Hardcore:Print("|cFFFF0000BLOCKED:|r You may only trade with other characters that have a 'PASS' status") + return + end + if tostring(other_hardcore_character_cache[target_trader].endgame) ~= "true" then + Hardcore:Print("|cFFFF0000BLOCKED:|r You may only trade with other valid endgame characters") + return + end + -- to reach here, both self and other are both valid endgame characters table.insert(Hardcore_Character.trade_partners, target_trader) Hardcore_Character.trade_partners = Hardcore_FilterUnique(Hardcore_Character.trade_partners) AcceptTrade() else - Hardcore:Print("|cFFFF0000BLOCKED:|r You may not trade outside of duos/trios.") + Hardcore:Print("|cFFFF0000BLOCKED:|r You may not trade outside of duos/trios or endgame") + return end end) @@ -822,6 +861,8 @@ end -- function Hardcore:PLAYER_LOGIN() + + Hardcore:HandleLegacyDeaths() Hardcore_Character.hardcore_player_name = Hardcore_Settings.hardcore_player_name or "" @@ -1258,6 +1299,7 @@ function Hardcore:INSPECT_READY(...) team = {}, first_recorded = -1, version = "?", + endgame = false, } ShowInspectHC(_default_hardcore_character, target_name, _default_hardcore_character.version) end @@ -2121,7 +2163,7 @@ function Hardcore:CHAT_MSG_ADDON(prefix, datastr, scope, sender) end if command == COMM_COMMANDS[4] then -- Received hc character data local name, _ = string.split("-", sender) - local version_str, creation_time, achievements_str, _, party_mode_str, _, _, team_str, hc_tag, passive_achievements_str, verif_status, verif_details = + local version_str, creation_time, achievements_str, _, party_mode_str, _, _, team_str, hc_tag, passive_achievements_str, verif_status, verif_details, endgame_status = string.split(COMM_FIELD_DELIM, data) local achievements_l = { string.split(COMM_SUBFIELD_DELIM, achievements_str) } other_achievements_ds = {} @@ -2161,7 +2203,9 @@ function Hardcore:CHAT_MSG_ADDON(prefix, datastr, scope, sender) hardcore_player_name = hc_tag, verification_status = verif_status, verification_details = verif_details, + endgame = endgame_status, } + hardcore_modern_menu_state.changeset[string.split("-", name)] = 1 return end @@ -3142,10 +3186,8 @@ function Hardcore:GenerateVerificationStatusStrings() -- Determine the end verdict. Any trades or deaths or bubs give a fail if - numTrades > 0 - or numDeaths > 0 + numDeaths > 0 or numBubs > 0 - or numRepRuns > 0 or numOverLevelRuns > 0 or (dataFileSecurity ~= "OK" and dataFileSecurity ~= "?") or ( @@ -3157,6 +3199,14 @@ function Hardcore:GenerateVerificationStatusStrings() else verdict = COLOR_GREEN .. "PASS" end + + if Hardcore_Character.endgame == false and + (numTrades > 0 + or numRepRuns > 0) + then + verdict = COLOR_YELLOW .. "FAIL (SEE DISCORD)" + end + verdict = COLOR_WHITE .. "Verification status: " .. verdict -- Group the green, orange and red because for some weird reason we can't switch colours too often in one line @@ -3169,7 +3219,7 @@ function Hardcore:GenerateVerificationStatusStrings() table.insert(reds, "appeals=" .. numAppeals) end - if numTrades > 0 then + if Hardcore_Character.endgame == false and numTrades > 0 then table.insert(reds, "trades=" .. numTrades) end @@ -3177,9 +3227,10 @@ function Hardcore:GenerateVerificationStatusStrings() table.insert(reds, "bub-hrth=" .. numBubs) end - if numRepRuns > 0 then + if Hardcore_Character.endgame == false and numRepRuns > 0 then table.insert(reds, "repeat_dung=" .. numRepRuns) end + if numOverLevelRuns > 0 then table.insert(reds, "overlvl_dung=" .. numOverLevelRuns) end @@ -3382,6 +3433,14 @@ function Hardcore:SendCharacterData(dest) commMessage = commMessage .. COMM_FIELD_DELIM commMessage = commMessage .. Hardcore_Character.verification_details + -- Add endgame status + local endgame_status = "false" + if Hardcore_Character.endgame ~= nil and Hardcore_Character.endgame then + endgame_status = "true" + end + commMessage = commMessage .. COMM_FIELD_DELIM + commMessage = commMessage .. (endgame_status or "nil") + CTL:SendAddonMessage("ALERT", COMM_NAME, commMessage, "WHISPER", dest) end end diff --git a/Hardcore_Classic.toc b/Hardcore_Classic.toc index ea4e03f..2664dd1 100644 --- a/Hardcore_Classic.toc +++ b/Hardcore_Classic.toc @@ -1,10 +1,10 @@ ## Interface: 11500 -## Title: Hardcore 0.11.48 +## Title: Hardcore 0.11.50a1 ## Notes: Supports Classic Hardcore ## Author: The Classic Hardcore team, Molikar (Sean Kennedy), Mark Rogaski as GreenWall author ## X-License: All Rights Reserved ## X-Category: Leveling,Guild -## Version: 0.11.48 +## Version: 0.11.50a1 ## DefaultState: enabled diff --git a/Hardcore_Wrath.toc b/Hardcore_Wrath.toc index 3b06a12..5afc4cc 100644 --- a/Hardcore_Wrath.toc +++ b/Hardcore_Wrath.toc @@ -1,10 +1,10 @@ ## Interface: 30403 -## Title: Hardcore 0.11.48 +## Title: Hardcore 0.11.50a1 ## Notes: Supports Classic Hardcore ## Author: The Classic Hardcore team, Molikar (Sean Kennedy), Mark Rogaski as GreenWall author ## X-License: All Rights Reserved ## X-Category: Leveling,Guild -## Version: 0.11.48 +## Version: 0.11.50a1 ## DefaultState: enabled diff --git a/MainMenu.lua b/MainMenu.lua index 5c48c06..7a673cc 100644 --- a/MainMenu.lua +++ b/MainMenu.lua @@ -666,6 +666,50 @@ local function DrawRulesTab(container) scroll_frame:AddChild(general_rules_description) end +local function confirmEndgameTransition() + + local function OnOkayClick() + Hardcore_Character.endgame = true + Hardcore:Print("Transition to Endgame Mode COMPLETE") + StaticPopup_Hide("ConfirmEndgameTransitionPopup") + end + + local function OnCancelClick() + Hardcore:Print("Transition to Endgame Mode CANCELLED") + StaticPopup_Hide("ConfirmEndgameTransitionPopup") + end + + local function OnShowEvent() + Hardcore_Frame:Hide() + hardcore_modern_menu:Hide() + end + + local text = + "Once your character has been |cffffcc00verified|r by the " .. + "|cffffcc00Classic Hardcore Challenge|r, " .. + "you may transition to Endgame Mode.\n\n" .. + "|cffff0000YOUR CHARACTER WILL BECOME INELIGABLE FOR FUTURE VERIFICATION BY CLASSIC HC|r\n" .. + "|cffff0000THIS CANNOT BE UNDONE|r\n" .. + "\n" .. + "\nTransition to Endgame Mode?" + + StaticPopupDialogs["ConfirmEndgameTransitionPopup"] = { + text = text, + button1 = OKAY, + button2 = CANCEL, + OnAccept = OnOkayClick, + OnCancel = OnCancelClick, + OnShow = OnShowEvent, + timeout = 0, + whileDead = true, + hideOnEscape = true, + showAlert = true, + exclusive = true, + } + + local dialog = StaticPopup_Show("ConfirmEndgameTransitionPopup") +end + local function DrawVerifyTab(container, _hardcore_character) local ATTRIBUTE_SEPARATOR = "_" local string_format_new = true @@ -747,14 +791,7 @@ local function DrawVerifyTab(container, _hardcore_character) scroll_frame:SetLayout("Flow") scroll_container:AddChild(scroll_frame) - local max_level = 60 - if - (Hardcore_Character.game_version ~= "") - and (Hardcore_Character.game_version ~= "Era") - and (Hardcore_Character.game_version ~= "SoM") - then - max_level = 80 - end + local max_level = Hardcore:GetMaxLevel() -- 25, 60 or 80 local first_menu_description_title = AceGUI:Create("Label") first_menu_description_title:SetWidth(500) @@ -790,53 +827,77 @@ local function DrawVerifyTab(container, _hardcore_character) character_and_level_label:SetFont("Fonts\\FRIZQT__.TTF", 14, "") scroll_frame:AddChild(character_and_level_label) - local extra_lines = "" + local character_status_label = AceGUI:Create("Label") + local statusString1, statusString2 = Hardcore:GenerateVerificationStatusStrings() + Hardcore:UpdateVerificationStatus() + local text = "\n" .. statusString1 .. "\n" .. statusString2 - local general_rules_description = AceGUI:Create("Label") - general_rules_description:SetWidth(600) - general_rules_description:SetText("\nTo get verified, copy the string below and visit the hardhead website.") - general_rules_description:SetFont("Fonts\\FRIZQT__.TTF", 12, "") - scroll_frame:AddChild(general_rules_description) + character_status_label:SetText(text) + character_status_label:SetWidth(500) + character_status_label:SetFontObject(GameFontHighlightMedium) + scroll_frame:AddChild(character_status_label) - local switch_format_button = AceGUI:Create("Button") - switch_format_button:SetText("Use new format") - switch_format_button:SetWidth(130) - scroll_frame:AddChild(switch_format_button) - switch_format_button:SetCallback("OnClick", function() - if string_format_new == false then - switch_format_button:SetText("Use old format") + local endgame_text = AceGUI:Create("Label") + + if Hardcore_Character.endgame == true then + text = "|cffffcc00END-GAME MODE IS ENABLED!|r\n" + elseif (level == max_level) or (level == 2) then + text = "|cffffcc00Once your levelling challenge success has been verified, you may transition to Endgame Mode.\nNote: YOU WILL BE UNABLE TO RETURN TO THE LEVELLING CHALLENGE|r\n" + else + text = "" + end + + if text ~= "" then + endgame_text:SetText(text) + endgame_text:SetWidth(520) + endgame_text:SetFontObject(GameFontHighlightNormal) + scroll_frame:AddChild(endgame_text) + end + + if (level == max_level) and (not Hardcore_Character.endgame) then + local engage_endgame_button = AceGUI:Create("Button") + engage_endgame_button:SetWidth(200) + if Hardcore_Character.verification_status == "PASS" then + engage_endgame_button:SetText("Transition to Endgame") + engage_endgame_button:SetCallback("OnClick", function() + confirmEndgameTransition() + end) else - switch_format_button:SetText("Use new format") + engage_endgame_button:SetText("|cffff0000INVALID CHARACTER|r") end - string_format_new = not string_format_new + scroll_frame:AddChild(engage_endgame_button) + end + + + if Hardcore_Character.endgame ~= true then + local how_to_verify = AceGUI:Create("Label") + how_to_verify:SetWidth(600) + how_to_verify:SetText("\nTo get verified, copy the string below and visit |cffffcc00hardhead.io|r or the |cffffcc00Classic Hardcore discord|r") + how_to_verify:SetFont("Fonts\\FRIZQT__.TTF", 12, "") + scroll_frame:AddChild(how_to_verify) + + string_format_new = true + + first_menu_description = AceGUI:Create("MultiLineEditBox") + first_menu_description.button:Hide() + first_menu_description:SetMaxLetters(0) + first_menu_description:SetHeight(850) + first_menu_description.button:SetPoint("BOTTOMLEFT", 0, -150) + first_menu_description:SetWidth(750) + first_menu_description:SetLabel("") first_menu_description:SetText(GenerateVerificationString()) - end) - - first_menu_description = AceGUI:Create("MultiLineEditBox") - first_menu_description.button:Hide() - first_menu_description:SetMaxLetters(0) - first_menu_description:SetHeight(850) - first_menu_description.button:SetPoint("BOTTOMLEFT", 0, -150) - first_menu_description:SetWidth(750) - first_menu_description:SetLabel("") - first_menu_description:SetText(GenerateVerificationString()) - scroll_frame:AddChild(first_menu_description) + scroll_frame:AddChild(first_menu_description) - local copy_tip_label = AceGUI:Create("Label") - local text = extra_lines .. "\n\n\n\n\n\n\n\n\n\n\n\n\nSelect All (Ctrl-A), Copy (Ctrl-C), and Paste (Ctrl-V)" + local extra_lines = "" - copy_tip_label:SetText(text) - copy_tip_label:SetWidth(700) - copy_tip_label:SetFontObject(GameFontHighlightSmall) - scroll_frame:AddChild(copy_tip_label) + local copy_tip_label = AceGUI:Create("Label") + local text = extra_lines .. "\n\n\n\n\n\n\n\n\n\n\n\n\nSelect All (Ctrl-A), Copy (Ctrl-C), and Paste (Ctrl-V)" - local character_status_label = AceGUI:Create("Label") - local statusString1, statusString2 = Hardcore:GenerateVerificationStatusStrings() - local text = "\n" .. statusString1 .. "\n" .. statusString2 - character_status_label:SetText(text) - character_status_label:SetWidth(700) - character_status_label:SetFontObject(GameFontHighlightMedium) - scroll_frame:AddChild(character_status_label) + copy_tip_label:SetText(text) + copy_tip_label:SetWidth(700) + copy_tip_label:SetFontObject(GameFontHighlightSmall) + scroll_frame:AddChild(copy_tip_label) + end end local function DrawDKTab(container, dk_button_function)