diff --git a/RaidBrowser/RaidBrowser.toc b/RaidBrowser/RaidBrowser.toc index 8f86251..55c855f 100644 --- a/RaidBrowser/RaidBrowser.toc +++ b/RaidBrowser/RaidBrowser.toc @@ -1,6 +1,6 @@ ## Interface: 30300 ## Title: Raid Browser -## Version: v1.3.0 +## Version: v1.4.0-DEV ## Notes: A raid finder that parses chat channel text and displays any found raids in the raid browser LFR frame. ## Author: Act/Horsebreed@Warmane ## SavedVariablesPerCharacter: RaidBrowserCharacterRaidsets, RaidBrowserCharacterCurrentRaidset diff --git a/RaidBrowser/core.lua b/RaidBrowser/core.lua index 7874560..806f1c7 100644 --- a/RaidBrowser/core.lua +++ b/RaidBrowser/core.lua @@ -3,7 +3,7 @@ RaidBrowser = LibStub('AceAddon-3.0'):NewAddon('RaidBrowser', 'AceConsole-3.0') --[[ Parsing and pattern matching ]] -- -- Separator characters -local sep_chars = '%s-_,.<>%*)(/#+&x' +local sep_chars = '%s-_,.<>%*)(/#+&x\\[' -- Whitespace separator local sep = '[' .. sep_chars .. ']'; @@ -130,6 +130,7 @@ local raid_list = { patterns = { 'icc' .. csep .. '10' .. csep .. 'm?a?n?' .. csep .. 'repu?t?a?t?i?o?n?' .. csep, 'icc' .. csep .. 'repu?t?a?t?i?o?n?' .. csep .. '10', + 'icc' .. csep .. '10' .. csep .. 'repu?t?a?t?i?o?n?', 'icc' .. csep .. '10' .. csep .. 'nm?' .. csep .. 'farm', 'icc' .. csep .. 'nm?' .. csep .. 'farm', 'icc' .. csep .. 'repu?t?a?t?i?o?n?', @@ -726,6 +727,8 @@ local role_patterns = { 'm[dp][dp]s' .. meta_or_sep, 'r[dp][dp]s', 'dps', + 'melee', + 'ranged', }, healer = { @@ -753,6 +756,7 @@ local role_patterns = { 'ta*n+a?k+s?', -- NEED TANKS 'b[ea][ea]+rs?', 'prote?c?t?i?o?n?', -- NEED PROT PALA/WARRI + 'fr?o?s?t? ?dk', -- frost DK }, } @@ -769,6 +773,7 @@ local gearscore_patterns = { local guild_recruitment_patterns = { 'recrui?ti?n?g?', + 'reclutan?d?o?', 'we' .. csep .. 'raid', 'we' .. csep .. 'are' .. csep .. 'raidi?n?g?', '[<({-][%a%s]+[-})>]' .. csep .. 'is' .. csep .. 'a?', -- ( is a) pve guild looking for @@ -779,6 +784,8 @@ local guild_recruitment_patterns = { 'active' .. csep .. 'raiders?', 'is' .. csep .. 'a' .. csep .. '[%a]*' .. csep .. '[pvep][pvep][pvep]' .. csep .. 'guild', 'lf' .. sep .. 'members', + 'new' .. sep .. 'members', + 'Apply' .. sep .. 'here', }; local trade_message_patterns = { @@ -840,7 +847,7 @@ local lfm_patterns = { lfm .. non_meta .. meta_raid, meta_raid .. non_meta .. meta_role, - 'new' .. csep .. 'run' .. meta_raid, + 'new' .. csep .. 'run' .. csep .. meta_raid, } local guild_recruitment_metapatterns = { @@ -1094,12 +1101,27 @@ function RaidBrowser.lex_and_extract(message, debug) -- Get the raid_info from the message local raid_info, raid_lexed_message, num_unique_raids = RaidBrowser.lex_raid_info(message, debug); - if not raid_info or not raid_lexed_message or not num_unique_raids then return end + if not raid_info or not raid_lexed_message or not num_unique_raids then + if debug then + RaidBrowser:Print("No valid raid found."); + end + return + end - if has_guild_recruitment_production(raid_lexed_message) then return end + if has_guild_recruitment_production(raid_lexed_message) then + if debug then + RaidBrowser:Print("Raid message was guild invite..."); + end + return + end -- If there are multiple distinct raids, then it is most likely a recruitment message. - if num_unique_raids > 1 then return end + if num_unique_raids > 1 then + if debug then + RaidBrowser:Print("found mulitple raids, could be recruiting..."); + end + return + end raid_lexed_message = lex_achievements(raid_lexed_message); @@ -1133,10 +1155,20 @@ function RaidBrowser.raid_info(message, debug) if not lexed_message then return end -- Any message that is lexed out to be an lfg is excluded (unfortunately near the end). - if is_lfg_message(lexed_message, debug) then return end + if is_lfg_message(lexed_message, debug) then + if debug then + RaidBrowser:Print("message was lfg: " .. lexed_message); + end + return + end -- Parse symbols to determine if the message is valid - if not is_lfm_message(lexed_message, debug) then return end + if not is_lfm_message(lexed_message, debug) then + if debug then + RaidBrowser:Print("message was not lfm: " .. lexed_message); + end + return + end return raid_info, roles, gs or ' '; end @@ -1149,6 +1181,7 @@ end RaidBrowserLfmChannelListeners = { ['CHAT_MSG_CHANNEL'] = {}, ['CHAT_MSG_YELL'] = {}, + ['CHAT_MSG_SAY'] = {}, }; local channel_listeners = {}; @@ -1157,7 +1190,7 @@ local channel_listeners = {}; ---@return boolean ---@nodiscard local function is_lfm_channel(channel) - return channel == 'CHAT_MSG_CHANNEL' or channel == 'CHAT_MSG_YELL'; + return channel == 'CHAT_MSG_CHANNEL' or channel == 'CHAT_MSG_YELL' or channel == 'CHAT_MSG_SAY'; end ---@diagnostic disable-next-line: unused-local @@ -1223,7 +1256,7 @@ function RaidBrowser:OnEnable() table.insert(channel_listeners, RaidBrowser.add_event_listener(channel, event_handler)) end - RaidBrowser.gui.raidset.initialize(); + RaidBrowser.check_button() end function RaidBrowser:OnDisable() diff --git a/RaidBrowser/gui.lua b/RaidBrowser/gui.lua index 6ffb299..79f9a5a 100644 --- a/RaidBrowser/gui.lua +++ b/RaidBrowser/gui.lua @@ -53,8 +53,10 @@ local function set_sort(column) end end ----@return table ----@nodiscard +function RaidBrowser.set_sort(column) + set_sort(column) +end + local function get_sorted_messages() local keys = {} for _, info in pairs(RaidBrowser.lfm_messages) do @@ -205,10 +207,12 @@ local function assign_lfr_button(button, host_name, lfm_info, index) button.damageIcon:SetTexture("Interface\\LFGFrame\\LFGRole"); button.partyIcon:SetTexture("Interface\\LFGFrame\\LFGRole"); - button:SetScript('OnEnter', - function(lfr_button) - GameTooltip:SetOwner(lfr_button, 'ANCHOR_RIGHT'); +button:SetScript("OnDoubleClick", on_join) + button:SetScript('OnEnter', + function(lfr_button) + GameTooltip:SetOwner(lfr_button, 'ANCHOR_RIGHT'); + local seconds = time() - lfr_button.lfm_info.time; local last_sent = string.format('Last sent: %d seconds ago', seconds); GameTooltip:AddLine(lfr_button.lfm_info.message, 1, 1, 1, true); diff --git a/RaidBrowser/raidset_frame.lua b/RaidBrowser/raidset_frame.lua index a078232..5ca5c17 100644 --- a/RaidBrowser/raidset_frame.lua +++ b/RaidBrowser/raidset_frame.lua @@ -21,12 +21,36 @@ local function is_secondary_selected(_) return 'Secondary' == current_selection; end +local function is_both_selected(option) + return ('Both' == current_selection); +end + ---@param selection 'Active'|'Primary'|'Secondary' local function set_selection(selection) local text = ''; - if selection == 'Active' then - text = 'Active'; + if selection == 'Both' then + local spec1, gs1 = RaidBrowser.stats.get_raidset('Primary') + local spec2, gs2 = RaidBrowser.stats.get_raidset('Secondary') + + + if spec1 and gs1 then + gs1 = math.floor(gs1 / 100) / 10 + text = text .. gs1 .. ' ' .. spec1 + else + text = text .. '-' + end + text = text .. ' / ' + if spec2 and gs2 then + gs2 = math.floor(gs2 / 100) / 10 + text = text .. gs2 .. ' ' .. spec2 + else + text = text .. '-' + end + if not (spec1 or spec2) then + text = 'Set any spec first'; + end + else ---@diagnostic disable-next-line: param-type-mismatch local spec, gs = RaidBrowser.stats.get_raidset(selection) @@ -34,6 +58,8 @@ local function set_selection(selection) text = 'Free slot'; elseif not gs then text = spec; + else + text = gs..' '..spec end end @@ -44,16 +70,25 @@ end local function on_active() set_selection('Active'); RaidBrowser.stats.select_current_raidset('Active'); + RaidBrowser.check_button() end local function on_primary() set_selection('Primary'); RaidBrowser.stats.select_current_raidset('Primary'); + RaidBrowser.check_button() end local function on_secondary() set_selection('Secondary'); RaidBrowser.stats.select_current_raidset('Secondary'); + RaidBrowser.check_button() +end + +local function on_both() + set_selection('Both'); + RaidBrowser.stats.select_current_raidset('Both'); + RaidBrowser.check_button() end local menu = { @@ -74,18 +109,49 @@ local menu = { func = on_secondary, checked = is_secondary_selected, }, + + { + text = "Both", + func = on_both, + checked = is_both_selected, + } } -- Get the menu option text ----@param option 'Primary'|'Secondary' ----@return string +local function get_option_active(option) + local spec, gs = RaidBrowser.stats.get_active_raidset() + return (option .. ': ' .. gs .. ' ' .. spec) +end + +-- Get the menu option text local function get_option_text(option) - local spec, _ = RaidBrowser.stats.get_raidset(option); + local spec, gs = RaidBrowser.stats.get_raidset(option); if not spec then return option .. ': Free slot'; end + + return (option .. ': ' .. gs .. ' ' .. spec); +end + +-- Get the menu option texts +local function get_option_texts(option) + local spec1, gs1 = RaidBrowser.stats.get_raidset('Primary'); + local spec2, gs2 = RaidBrowser.stats.get_raidset('Secondary'); + if not spec1 then + return (option .. ': Open'); + end - return option .. ': ' .. spec; + if not (spec1 or spec2) then + return (option .. ': Set any spec first') + elseif (spec1 and spec2) then + return (option .. ': ' .. gs1 .. ' ' .. spec1 .. ' / ' .. gs2 .. ' ' .. spec2) + elseif spec1 then + return (option .. ': ' .. gs1 .. ' ' .. spec1 .. ' / ' .. '-') + elseif spec2 then + return (option .. ': ' .. '-' .. ' / ' .. gs2 .. ' ' .. spec2) + end + + return (option .. ': ' .. gs1 .. ' ' .. spec1 .. ' / ' .. gs2 .. ' ' .. spec2); end -- Setup dropdown menu for the raidset selection @@ -93,9 +159,11 @@ frame:SetPoint("CENTER", LFRBrowseFrame, "CENTER", 30, 165) UIDropDownMenu_Initialize(frame, EasyMenu_Initialize, nil, nil, menu); local function show_menu() + menu[1].text = get_option_text('Active'); menu[2].text = get_option_text('Primary'); menu[3].text = get_option_text('Secondary'); - ToggleDropDownMenu(1, nil, frame, frame, 25, 10, menu); + menu[4].text = get_option_texts('Both'); + ToggleDropDownMenu(1, nil, frame, frame, 25, 10, menu); end RaidBrowserRaidSetMenuButton:SetScript('OnClick', show_menu) @@ -119,6 +187,43 @@ function RaidBrowser.gui.raidset.initialize() set_selection(RaidBrowserCharacterCurrentRaidset); end +local function check_button(button) + if is_active_selected() or is_both_selected() then + button:Disable() + else + button:Enable() + end +end + +function RaidBrowser.check_button() + if is_active_selected() or is_both_selected() then + RaidBrowserRaidSetSaveButton:Disable() + RaidBrowserRaidSetSaveButton:SetText("Select spec first") + RaidBrowserRaidSetSaveButton:Hide() + else + RaidBrowserRaidSetSaveButton:Enable() + RaidBrowserRaidSetSaveButton:SetText("Save gear+spec") + RaidBrowserRaidSetSaveButton:Show() + end +end + +local function onEvent(this, event, arg1) + if event == "PLAYER_EQUIPMENT_CHANGED" or "PLAYER_SPECIALIZATION_CHANGED" then + RaidBrowser.gui.raidset.initialize() + end +end + +local function onShow(this) + -- update displayed Spec + GS in selection onShow + RaidBrowser.gui.raidset.initialize() +end + +frame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") +frame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") +frame:SetScript("OnEvent", onEvent) +frame:SetScript("onShow", onShow) + + -- Create raidset save button local button = CreateFrame("BUTTON", "RaidBrowserRaidSetSaveButton", LFRBrowseFrame, "OptionsButtonTemplate") button:SetPoint("CENTER", LFRBrowseFrame, "CENTER", -53, 168) @@ -129,3 +234,4 @@ button:SetText("Save Raid Gear"); button:SetWidth(110); button:SetScript("OnClick", on_raidset_save); button:Show(); +check_button(button); diff --git a/RaidBrowser/stats.lua b/RaidBrowser/stats.lua index 3f5597f..3198a98 100644 --- a/RaidBrowser/stats.lua +++ b/RaidBrowser/stats.lua @@ -6,6 +6,14 @@ if GetLocale() ~= "enUS" then end local raid_achievements = { + + rs = { + 4817, -- The Twilight Destroyer 10 + 4815, -- The Twilight Destroyer 25 + 4818, -- The Twilight Destroyer 10 HC + 4816, -- The Twilight Destroyer 25 HC + }, + icc = { 4531, -- Storming the Citadel 10-man 4604, -- Storming the Citadel 25-man @@ -24,24 +32,95 @@ local raid_achievements = { 4631, -- The Frostwing Halls 10-man HC 4635, -- The Frostwing Halls 25-man HC 4530, -- The Frozen Throne (LK10 NM) + 4532, -- Fall of the Lich King (10 NM) 4597, -- The Frozen Throne (LK25 NM) + 4608, -- Fall of the Lich King (25 NM) 4583, -- Bane of the Fallen King (LK10 HC) + 4636, -- Heroic: Fall of the Lich King (10 HC) + 4602, -- Glory of the Icecrown Raider 10 4584, -- The Light of Dawn (LK25 HC) + 4637, -- Heroic: Fall of the Lich King (25 HC) + 4603, -- Glory of the Icecrown Raider 25 + 4576, -- Realm First! Fall of the Lich King (25 HC) }, toc = { 3917, -- Call of the Crusade 10-man 3916, -- Call of the Crusade 25-man 3918, -- Call of the Grand Crusade (10 HC) + 3810, -- A Tribute to Insanity (10 HC) 3812, -- Call of the Grand Crusade (25 HC) + 3819, -- A Tribute to Insanity (25 HC) + 4080, -- A Tribute to Dedicated Insanity (10 HC) + 4079, -- A Tribute to Immortality (25 HC Horde) + 4156, -- A Tribute to Immortality (25 HC Alliance) + 4078, -- Realm First! Grand Crusader }, - - rs = { - 4817, -- The Twilight Destroyer 10 - 4815, -- The Twilight Destroyer 25 - 4818, -- The Twilight Destroyer 10 HC - 4816, -- The Twilight Destroyer 25 HC + + ulduar = { + 2894, -- The Secrets of Ulduar 10 + 2895, -- The Secrets of Ulduar 25 + 3036, -- Observed 10 + 3037, -- Observed 25 + 3141, -- Two Lights in the Darkness 10 + 3158, -- One Light in the Darkness 10 + 3159, -- Alone in the Darkness 10 + 3162, -- Two Lights in the Darkness 25 + 3163, -- One Light in the Darkness 25 + 3004, -- He Feeds on your Tears 10 + 3005, -- He Feeds on your Tears 25 + 2957, -- Glory of the Ulduar Raider 10 + 3316, -- Herald of the Titans + 3164, -- Alone in the Darkness 25 + 2958, -- Glory of the Ulduar Raider 25 + 3259, -- Realm First! Celestial Defender + 3117, -- Realm First! Death's Demise }, + + eoe = { + 622, -- Spellweaver 10 + 1874, -- You don't have an eternity 10 + 623, -- Spellweaver 25 + 1875, -- You don't have an eternity 25 + 1400, -- Realm First! Magic Seeker + }, + + os = { + 1876, -- Besting the Black Dragonflight 10 + 2049, -- Twilight Assist 10 + 2050, -- Twilight Duo 10 + 625, -- Besting the Black Dragonflight 25 + 2052, -- Twilight Assist 25 + 2051, -- Twilight Zone 10 + 2053, -- Twilight Duo 25 + 2054, -- Twilight Zone 25 + 456, -- Realm First! Obsidian Slayer + }, + + naxx = { + 574, -- Kel'Thuzad's Defeat 10 + 575, -- Kel'Thuzad's Defeat 25 + 576, -- The Fall of Naxxramas 10 + 577, -- The Fall of Naxxramas 25 + 578, -- The Dedicated Few 10 + 579, -- The Dedicated Few 25 + 2187, -- The Undying 10 + 2186, -- The Immortal 25 + 2137, -- Glory of the Raider 10 + 2138, -- Glory of the Raider 25 + 1402, -- Realm First! Conqueror of Naxxramas + }, + + --voa = { + -- 1722, -- Archavon the Stone Watcher 10 + -- 3136, -- Emalon the Storm Watcher 10 + -- 3836, -- Koralon the Flame Watcher 10 + -- 4585, -- Toravon the Ice Watcher 10 + -- 1721, -- Archavon the Stone Watcher 25 + -- 3137, -- Emalon the Storm Watcher 25 + -- 3837, -- Koralon the Flame Watcher 25 + -- 4586, -- Toravon the Ice Watcher 25 + --} }; local spec_names = { @@ -106,13 +185,13 @@ local spec_names = { PaladinProtection = "Prot Pala", PaladinCombat = "Retri Pala", - HunterBeastMastery = "BM Hunt", - HunterMarksmanship = "MM Hunt", - HunterSurvival = "Surv Hunt", + HunterBeastMastery = "BM Hunter", + HunterMarksmanship = "MM Hunter", + HunterSurvival = "Svl Hunter", - RogueAssassination = "Assa Rog", - RogueCombat = "Combat Rog", - RogueSubtlety = "Sub Rog", + RogueAssassination = "Assa Rogue", + RogueCombat = "Cmbt Rogue", + RogueSubtlety = "Sub Rogue", PriestDiscipline = "Disco Heal", PriestHoly = "Holy Priest", @@ -160,11 +239,17 @@ local function find_best_achievement(raid) -- Find the highest ranking completed achievement criterion for i, id in ipairs(ids) do + local fully_completed for j = 1, GetAchievementNumCriteria(id) do local _, _, completed = GetAchievementCriteriaInfo(id, j) - if completed and (not max_achievement or max_achievement[1] <= i) then - max_achievement = { i, id }; + if not completed then + fully_completed = false + break end + fully_completed = true + end + if fully_completed and (not max_achievement or max_achievement[1] <= i) then + max_achievement = {i, id}; end end @@ -190,25 +275,40 @@ function RaidBrowser.stats.active_spec_index() return i; end ----@return string ----@nodiscard function RaidBrowser.stats.active_spec() local active_tab = RaidBrowser.stats.active_spec_index() local _, _, _, spec_name = GetTalentTabInfo(active_tab); + local _, class = UnitClass("player"); + -- TODO: make config to toggle using full or short spec names + local readable_spec_name = spec_names["short"][spec_name] or spec_name; + -- If we're a feral druid, then we need to distinguish between tank and cat feral. if spec_name == 'DruidFeralCombat' then local protector_of_pack_talent = 22; - local _, _, _, _, points = GetTalentInfo(active_tab, protector_of_pack_talent) - if points > 0 then - return 'Feral Druid (Bear)' + local thick_hide_talent = 5; + local _, _, _, _, points = GetTalentInfo(active_tab, thick_hide_talent) + if points > 1 then + return readable_spec_name .. ' (Tank)' else - return 'Feral Druid (Cat)' + return readable_spec_name .. ' (DPS)' + end + end + + -- If we're a death knight, then we need to distinguish between tank and dps. + if class == 'DEATHKNIGHT' then + local toughness_talent = 3; + local blade_barrier_talent = 3; + local _, _, _, _, points = GetTalentInfo(2, toughness_talent) + local _, _, _, _, points2 = GetTalentInfo(1, blade_barrier_talent) + if points > 3 and points2 > 3 then + return readable_spec_name .. ' (Tank)' + else + return readable_spec_name .. ' (DPS)' end end - -- TODO: make config to toggle using full or short spec names - return spec_names["full"][spec_name] or spec_name; + return readable_spec_name end ---Return if the given raid is locked, and if so its reset time left (in seconds) @@ -262,16 +362,33 @@ end ---@return string?, integer? ---@nodiscard function RaidBrowser.stats.get_raidset(set) + if set == 'Active' then + return RaidBrowser.stats.get_active_raidset() + end local raidset = RaidBrowserCharacterRaidsets[set]; if not raidset then return end return raidset.spec, raidset.gs; end ----@return string?, integer? +function RaidBrowser.stats.get_raidsets() + local raidset1 = RaidBrowserCharacterRaidsets['Primary'] or nil; + local raidset2 = RaidBrowserCharacterRaidsets['Secondary'] or nil; + if not (raidset1 or raidset2) then + return + elseif (raidset1 and raidset2) then + return raidset1.spec , raidset1.gs , raidset2.spec , raidset2.gs + elseif raidset1 then + return raidset1.spec, raidset1.gs + elseif raidset2 then + return raidset2.spec, raidset2.gs + end +end + function RaidBrowser.stats.current_raidset() - local x = 0 if RaidBrowserCharacterCurrentRaidset == 'Active' then return RaidBrowser.stats.get_active_raidset(); + elseif RaidBrowserCharacterCurrentRaidset == 'Both' then + return RaidBrowser.stats.get_raidsets(); end ---@diagnostic disable-next-line: param-type-mismatch @@ -298,10 +415,19 @@ end ---@return string ---@nodiscard function RaidBrowser.stats.build_join_message(raid_name) - local spec, gs = RaidBrowser.stats.current_raidset(); - - -- local message = 'inv ' .. gs .. 'gs ' .. spec; - local message = 'inv for ' .. raid_name .. " - " .. gs .. 'gs ' .. spec; + local message = 'inv for ' .. raid_name .. " - "; + local class = UnitClass("player"); + + local spec1, gs1, spec2, gs2 = RaidBrowser.stats.current_raidset(); + if spec1 and gs1 then + message = message .. gs1 .. 'gs ' .. spec1 + end + if spec1 and gs1 and spec2 and gs2 then + message = message .. ' / ' + end + if spec2 and gs2 then + message = message .. gs2 .. 'gs ' .. spec2 + end -- Remove difficulty and raid_name size from the string raid_name = RaidBrowser.get_short_raid_name(raid_name) diff --git a/tests/lfm_tests.lua b/tests/lfm_tests.lua index f59dcce..b04d784 100644 --- a/tests/lfm_tests.lua +++ b/tests/lfm_tests.lua @@ -1,3 +1,5 @@ +-- to run enter /run RaidBrowser.test() + local test_cases = { { message = 'ICC 25N ALT LK RUN @LK NEED Only 1Rshaman/Tank 5.6K GS ++ REQ KS OR NO [INV] (B+P+SFS RESS) [The Light of Dawn]', @@ -803,6 +805,15 @@ local test_cases = { gs = ' ' }, + { + message = 'LFM ICC [REP FARM] need all (all loot reserved)', + should_fail = false, + raid = 'icc10rep', + roles = { 'dps', 'tank', 'healer' }, + gs = ' ' + }, + + { message = ' LFM ICC 25 n/hcNEED boom gs+5.9[Heroic: The Frostwing Halls (25 player)]no achi no [inv]', should_fail = false, @@ -1324,14 +1335,14 @@ local test_cases = { }, { - message = 'Die "Deutsche Wehrmacht" rekrutiert ab sofort neue deutschsprachige Mitglieder. Wöchtenlich ICC 10 und 25, bei genug Mitgliedern gerne auch Alt-Runs. TS und Discord ist verfügbar. Wir heißen jegliche Spieler aus dem deutschen Sprachraum herzlich willko', + message = 'Die "Deutschen Pannemänner" rekrutiert ab sofort neue deutschsprachige Mitglieder. Wöchtenlich ICC 10 und 25, bei genug Mitgliedern gerne auch Alt-Runs. TS und Discord ist verfügbar. Wir heißen jegliche Spieler aus dem deutschen Sprachraum herzlich willko', should_fail = true, }, { message = 'NEW RUN [Sartharion Must Die!] 25er w me info !!', should_fail = false, - raid = 'os25wq', + raid = 'os10wq', roles = { 'tank', 'dps', 'healer' }, gs = ' ', }, @@ -1463,6 +1474,23 @@ local test_cases = { roles = { 'dps', 'tank' }, gs = ' ', }, + + { + message = 'Newly formed, end game raiding guild led by a group of experienced raiders is looking for new members. Progress ICC 25 HC 12/12 . Req 6.2+ gs and end game exp. DKP system RT 5 pm ST . Apply here [https://discord.gg/6USp2QAbWV]', + should_fail = true, + }, + { + message = '[RU] PvE Guild Nabiraet igrokov (FWAR, SP/DISCO, BOOMIE/RDUDU, DEMON,HUNT) ot 5k gs. DKP system. RT 19:00. Haw progress: LOD, BANE. 4 ICC v nedelu, 1 LOD, 2 11/12 HC, 3,4-8-10/12 HC. Za info /w me.', + should_fail = true, + }, + + { + message = ' LFM RS 25 NM NEED ALL 5K9 GS /W GS / XP / ACH ( Only NECK ARPEN RES ) LFM RS 25 NM NEED ALL 5K9 GS /W GS / XP / ACH ( Only NECK ARPEN RES ) LFM RS 25 NM NEED ALL 5K9 GS /W GS / XP / ACH ( Only NECK ARPEN RES ) LFM RS 25 NM NEED ALL 5K9 GS /W GS /', + should_fail = false, + raid = 'rs25nm', + roles = { 'healer', 'tank', 'dps' }, + gs = '5.9', + }, } local function array_contains(t, element) @@ -1575,6 +1603,7 @@ end RaidBrowser.test = function(m) if m == nil then + RaidBrowser:Print('Start test run of predefined test cases (lfm_tests.lua)'); -- Run all the test cases local test_results = std.algorithm.transform(test_cases, run_test_case);