Add option to show player roles. Add option to automatically track +1 on MS rolls. Update MC bosslist

This commit is contained in:
Sica 2025-08-18 00:43:37 +02:00
parent 246b31ea79
commit 409dca83b2
22 changed files with 220 additions and 52 deletions

View File

@ -1,7 +1,7 @@
## Interface: 11200
## Title: RollFor
## Author: Obszczymucha
## Version: 4.7.12
## Version: 4.8.0
## Notes: An automated item roller with soft ressing support via raidres.fly.dev.
## SavedVariables: RollForDb
## SavedVariablesPerCharacter: RollForCharDb

View File

@ -9,8 +9,10 @@ local M = {}
local getn = m.getn
local info = m.pretty_print
local hl = m.colors.highlight
local hl, white, grey, green, red = m.colors.highlight, m.colors.white, m.colors.grey, m.colors.green, m.colors.red
local RollSlashCommand = m.Types.RollSlashCommand
local RollType = m.Types.RollType
local RollingStrategy = m.Types.RollingStrategy
_RollFor = M
BINDING_HEADER_ROLLFOR = "RollFor"
@ -274,8 +276,7 @@ local function create_components()
)
---@type LootAwardCallback
M.loot_award_callback = m.LootAwardCallback.new( M.awarded_loot, M.roll_controller, M.winner_tracker, M.group_roster, M.softres )
M.loot_award_callback = m.LootAwardCallback.new( M.awarded_loot, M.roll_controller, M.winner_tracker, M.group_roster, M.softres, M.confirm_popup, M.config)
---@type MasterLoot
M.master_loot = m.MasterLoot.new(
M.master_loot_candidates,
@ -376,7 +377,8 @@ local function create_components()
M.winner_tracker,
M.config,
M.softres,
M.player_info
M.player_info,
M.awarded_loot
)
---@type RollingLogic
@ -739,6 +741,69 @@ local function on_reset_dropped_loot_announce_command()
M.dropped_loot_announce.reset()
end
local function plus_ones_command( args )
local function print_usage()
M.chat.info(string.format( "%s - %s", hl( "/pl" ), white( "List +1's" ) ) )
M.chat.info(string.format( "%s %s %s - %s", hl( "/pl add " ), grey( "<player>" ), grey( "<item>" ), white( "Add item to players +1's" ) ) )
M.chat.info(string.format( "%s %s %s - %s", hl( "/pl rm" ), grey( "<player>" ), grey( "<item>" ), white( "Remove item from players +1's" ) ) )
end
local loot = M.awarded_loot.get_winners()
local players = {}
for _, award in ipairs(loot) do
if award ~= nil then
if not players[award.player_name] then
players[award.player_name] = { award }
else
table.insert(players[award.player_name], award)
end
end
end
if args == "" then
local plus_ones_exist = false
for player_name, awards in pairs(players) do
local plus_ones = m.filter(awards, (function(a) return a.plus_one end))
if getn(plus_ones) > 0 then
plus_ones_exist = true
local item_list = table.concat(m.map(plus_ones, (function (a) return a.item_link end)), " ")
local colored_player_name = m.colorize_player_by_class( player_name, awards[1].player_class ) or grey( player_name )
M.chat.info( colored_player_name .. green(" MS +" .. getn(plus_ones)) .. ": " .. item_list)
end
end
if not plus_ones_exist then
M.chat.info("There are no +1's yet")
end
else
local action, player_name, item_link = string.match(args, "^(%S+) (%S+) (|%w+|Hitem.+|r)$")
local item_id = item_link and M.item_utils.get_item_id( item_link )
local group_players = M.group_roster.get_all_players_in_my_group()
local player = player_name and m.filter(group_players, (function (p) return string.lower(p.name) == string.lower(player_name) end))[1]
if action == nil and player_name == nil and item_link == nil then
M.chat.info(red("Invalid usage"))
print_usage()
elseif action ~= "add" and action ~= "rm" and action ~= "remove" then
M.chat.info(red("Invalid action"))
print_usage()
elseif (player == nil) then
M.chat.info(red("Player not found in group"))
print_usage()
elseif item_link == nil or item_id == nil then
M.chat.info(red("Invalid item"))
print_usage()
elseif action == "add" then
M.chat.info("Gave " .. (m.colorize_player_by_class( player.name, player.class ) or m.colors.grey( player.name )) .. " a +1 for " .. item_link )
local roll_data = { player_name = player.name, player_class = player.class, roll_type = RollType.MainSpec, roll = 0, plus_ones = 0 }
M.awarded_loot.award( player.name, item_id, roll_data, RollingStrategy.NormalRoll, item_link, player.class, nil, true)
elseif action == "rm" or action == "remove" then
if M.awarded_loot.has_item_been_awarded( player.name, item_id ) then
M.unaward_item( player.name, item_id, item_link )
else
M.chat.info(red(player.name .. " doesn't have a +1 for " .. item_link))
end
end
end
end
local function setup_slash_commands()
-- Roll For commands
SLASH_RF1 = RollSlashCommand.NormalRoll
@ -778,6 +843,10 @@ local function setup_slash_commands()
SLASH_RFT1 = "/rft"
M.api().SlashCmdList[ "RFT" ] = M.sandbox.run
SLASH_PL1 = "/pl"
M.api().SlashCmdList[ "PL"] = plus_ones_command
--SLASH_DROPPED1 = "/DROPPED"
--M.api().SlashCmdList[ "DROPPED" ] = simulate_loot_dropped
end
@ -790,6 +859,8 @@ function M.on_player_login()
info( string.format( "Loaded (%s).", hl( string.format( "v%s", version.str ) ) ) )
M.version_broadcast.broadcast()
M.import_encoded_softres_data( M.softres_db.data )
M.softres_gui.load( M.softres_db.data )

View File

@ -8,7 +8,7 @@ local M = m.Module.new( "AwardedLoot" )
local getn = m.getn
---@class AwardedLoot
---@field award fun( player_name: string, item_id: number, roll_data: RollData?, rolling_strategy: RollingStrategyType?, item_link: ItemLink?, player_class: PlayerClass?, sr_plus: number? )
---@field award fun( player_name: string, item_id: number, roll_data: RollData?, rolling_strategy: RollingStrategyType?, item_link: ItemLink?, player_class: PlayerClass?, sr_plus: number?, plus_one: boolean? )
---@field unaward fun( player_name: string, item_id: number )
---@field get_winners fun()
---@field update_item fun( index: number, data: table )
@ -31,7 +31,8 @@ function M.new( db, group_roster, config )
---@param item_link ItemLink?
---@param player_class PlayerClass?
---@param sr_plus number?
local function award( player_name, item_id, roll_data, rolling_strategy, item_link, player_class, sr_plus )
---@param plus_one boolean?
local function award( player_name, item_id, roll_data, rolling_strategy, item_link, player_class, sr_plus, plus_one )
M.debug.add( "award" )
if not player_class then
if roll_data and roll_data.player_class then
@ -55,7 +56,8 @@ function M.new( db, group_roster, config )
rolling_strategy = rolling_strategy,
roll_type = roll_data and roll_data.roll_type,
winning_roll = roll_data and roll_data.roll,
sr_plus = sr_plus
sr_plus = sr_plus,
plus_one = plus_one
} )
end

View File

@ -53,6 +53,9 @@ M.zones = {
"Ossirian the Unscarred"
},
[ "Molten Core" ] = {
"Incindis",
"Basalthar",
"Sorcerer-Thane Thaurissan",
"Lucifron",
"Magmadar",
"Gehennas",
@ -77,7 +80,7 @@ M.zones = {
[ "Onyxia's Lair" ] = {
"Onyxia"
},
[ "Temple of Ahn'Qiraj" ] = {
[ "Ahn'Qiraj" ] = {
"The Prophet Skeram",
"Vem",
"Lord Kri",

View File

@ -38,6 +38,7 @@ function M.new( ace_timer, player_info, rolling_popup, config )
pn = "player_name",
pc = "player_class",
rt = "roll_type",
pl = "plus_ones",
r = "roll",
n = "name",
c = "class",
@ -307,7 +308,7 @@ function M.new( ace_timer, player_info, rolling_popup, config )
return
end
roll_tracker.add( data.player_name, data.player_class, data.roll_type, data.roll )
roll_tracker.add( data.player_name, data.player_class, data.player_role, data.roll_type, data.roll, data.plus_ones or 0 )
if data.player_name == player_info.get_name() then
player_can_roll = false
end

View File

@ -151,13 +151,14 @@ function M.new( roll_controller, softres, config )
} )
end
---@param data { player_name: PlayerName, player_class: PlayerClass, roll_type: RollType, roll: Roll }
---@param data { player_name: PlayerName, player_class: PlayerClass, roll_type: RollType, roll: Roll, plus_ones: number }
local function on_roll( data )
broadcast( "ROLL", {
pn = data.player_name,
pc = data.player_class,
rt = data.roll_type,
r = data.roll
r = data.roll,
pl = data.plus_ones
} )
end

View File

@ -24,6 +24,8 @@ function M.new( db, event_bus )
local callbacks = {}
local toggles = {
[ "auto_loot" ] = { cmd = "auto-loot", display = "Auto-loot", help = "toggle auto-loot" },
[ "handle_plus_ones"] = { cmd = "Handle-plus-ones", display = "handle-plus-ones", help = "Toggle +1 handling for main-spec rolls." },
[ "plus_one_prompt"] = { cmd = "plus-one-prompt", display = "Plus-one-prompt", help = "Prompt the user for whether the award should give a +1" },
[ "superwow_auto_loot_coins" ] = { cmd = "superwow-auto-loot-coins", display = "Auto-loot coins with SuperWoW", help = "toggle auto-loot coins with SuperWoW" },
[ "auto_loot_messages" ] = { cmd = "auto-loot-messages", display = "Auto-loot messages", help = "toggle auto-loot messages" },
[ "auto_loot_announce" ] = { cmd = "auto-loot-announce", display = "Announce auto-looted items", help = "toggle announcements of auto-loot items" },
@ -35,6 +37,7 @@ function M.new( db, event_bus )
[ "auto_master_loot" ] = { cmd = "auto-master-loot", display = "Auto master loot", help = "toggle auto master loot" },
[ "rolling_popup_lock" ] = { cmd = "rolling-popup-lock", display = "Rolling popup lock", help = "toggle rolling popup lock" },
[ "raid_roll_again" ] = { cmd = "raid-roll-again", display = string.format( "%s button", hl( "Raid roll again" ) ), help = string.format( "toggle %s button", hl( "Raid roll again" ) ) },
[ "show_player_roles"] = { cmd = "show-player-roles", display = "Show player roles", help="toggle player roles showing in rolling popup" },
[ "loot_frame_cursor" ] = { cmd = "loot-frame-cursor", display = "Display loot frame at cursor position", help = "toggle displaying loot frame at cursor position" },
[ "classic_look" ] = { cmd = "classic-look", display = "Classic look", help = "toggle classic look", requires_reload = true },
[ "client_auto_hide_popup" ] = { cmd = "auto-hide", display = "Hide popup when rolling is complete", help = "toggle hiding of roll popup", client = true },
@ -65,6 +68,8 @@ function M.new( db, event_bus )
if db.master_loot_frame_rows == nil then db.master_loot_frame_rows = 5 end
if db.auto_master_loot == nil then db.auto_master_loot = true end
if db.auto_loot == nil then db.auto_loot = true end
if db.handle_plus_ones == nil then db.handle_plus_ones = false end
if db.plus_one_prompt == nil then db.plus_one_prompt = false end
if db.auto_loot_announce == nil then db.auto_loot_announce = true end
if db.loot_frame_cursor == nil then db.loot_frame_cursor = false end
if db.client_show_roll_popup == nil then db.client_show_roll_popup = "Off" end

View File

@ -4,6 +4,7 @@ local m = RollFor
if m.LootAwardCallback then return end
local getn = m.getn
local RollType = m.Types.RollType
local M = m.Module.new( "LootAwardCallback" )
@ -15,7 +16,9 @@ local M = m.Module.new( "LootAwardCallback" )
---@param winner_tracker WinnerTracker
---@param group_roster GroupRoster
---@param softres GroupAwareSoftRes
function M.new( awarded_loot, roll_controller, winner_tracker, group_roster, softres )
---@param confirm_popup ConfirmPopup
---@param config Config
function M.new( awarded_loot, roll_controller, winner_tracker, group_roster, softres, confirm_popup, config )
---@param item_id number
---@param item_link string
---@param player_name string
@ -43,16 +46,17 @@ function M.new( awarded_loot, roll_controller, winner_tracker, group_roster, sof
class = player and player.class or nil
end
awarded_loot.award(
player_name,
item_id,
roll_data,
rolling_strategy,
item_link,
player_class or class,
sr_player and sr_player.sr_plus
)
awarded_loot.award(
player_name,
item_id,
roll_data,
rolling_strategy,
item_link,
player_class or class,
sr_player and sr_player.sr_plus,
false
)
if is_trade then return end
if player_class then
@ -62,8 +66,22 @@ function M.new( awarded_loot, roll_controller, winner_tracker, group_roster, sof
end
winner_tracker.untrack( player_name, item_link )
end
local function on_confirm_plus_one(plus_one)
awarded_loot.update_item(getn(awarded_loot.get_winners()), { plus_one = plus_one })
end
if config.handle_plus_ones() and roll_data ~= nil and roll_data.roll_type == RollType.MainSpec then
if config.plus_one_prompt() then
local colorized_player_name = m.colorize_player_by_class(player_name, player_class or class) or m.colors.grey( player_name )
confirm_popup.show( { "Should " .. colorized_player_name .. " get a +1 for " .. item_link .. "?" }, on_confirm_plus_one)
else
on_confirm_plus_one(true)
end
else
on_confirm_plus_one(false)
end
end
---@type LootAwardCallback
return {
on_loot_awarded = on_loot_awarded,
@ -72,3 +90,5 @@ end
m.LootAwardCallback = M
return M

View File

@ -104,10 +104,15 @@ function M.new( api, db, manage_softres_fn, winners_popup_fn, options_popup_fn,
api().GameTooltip:AddLine( string.format( "%s - %s", hl( "/rfr" ), white( "reset loot announce" ) ) )
api().GameTooltip:AddLine( string.format( "%s - %s", hl( "/cr" ), white( "cancel rolling in progress" ) ) )
api().GameTooltip:AddLine( string.format( "%s - %s", hl( "/fr" ), white( "finish rolling early" ) ) )
api().GameTooltip:AddLine( string.format( "%s - %s", hl( "/pl" ), white( "List +1's" ) ) )
api().GameTooltip:AddLine( string.format( "%s %s %s - %s", hl( "/pl add " ), grey( "<player>" ), grey( "<item>" ), white( "Add item to players +1's" ) ) )
api().GameTooltip:AddLine( string.format( "%s %s %s - %s", hl( "/pl rm" ), grey( "<player>" ), grey( "<item>" ), white( "Remove item from players +1's" ) ) )
api().GameTooltip:AddLine( string.format( "%s - %s", hl( "/rf config" ), white( "show configuration" ) ) )
api().GameTooltip:AddLine( string.format( "%s - %s", hl( "/rf config help" ), white( "show configuration help" ) ) )
api().GameTooltip:AddLine( " " )
api().GameTooltip:AddLine( "Click to manage softres." )
api().GameTooltip:AddLine( "Ctlr+Click for settings." )
api().GameTooltip:AddLine( "Shift+Click for winner overview." )
if icon_color == ColorType.Green then
api().GameTooltip:AddLine( " " )

View File

@ -66,6 +66,9 @@ function M.new(
local function sort_rolls()
local f = function( a, b )
if a.roll_type == RollType.MainSpec and a.player.plus_ones ~= b.player.plus_ones then
return a.player.plus_ones < b.player.plus_ones
end
if a.roll == b.roll then
return a.player.name < b.player.name
else
@ -135,12 +138,14 @@ function M.new(
local result = {}
local last_roll
local last_type
local last_plus_ones
for _, roll in ipairs( all_rolls ) do
if not last_roll or last_roll ~= roll.roll or last_type ~= roll.roll_type then
if not last_roll or last_roll ~= roll.roll or last_type ~= roll.roll_type or roll.roll_type == RollType.MainSpec and last_plus_ones ~= roll.player.plus_ones then
table.insert( result, { roll } )
last_roll = roll.roll
last_type = roll.roll_type
last_plus_ones = roll.player.plus_ones
else
table.insert( result[ getn( result ) ], roll )
end
@ -186,7 +191,7 @@ function M.new(
player.rolls = player.rolls - 1
local t = ms_roll and mainspec_rolls or os_roll and offspec_rolls or tmog_rolls
table.insert( t, make_roll( player, roll_type, roll ) )
controller.roll_was_accepted( player.name, player.class, roll_type, roll )
controller.roll_was_accepted( player.name, player.class, roll_type, roll, player.plus_ones )
if have_all_rolls_been_exhausted() then find_winner() end
end

View File

@ -145,6 +145,9 @@ function M.new( popup_builder, awarded_loot, version_broadcast, event_bus, confi
this.changelog.content.parent = this.changelog
local changelog = {
{ ver = "4.8.0", text = "Added +1 handling" },
{ ver = "4.7.13", text = "Add option to show player roles in rolling popup." },
{ ver = "4.7.13", text = "Fix wrong zone name for Temple of Ahn'Qiraj." },
{ ver = "4.7.12", text = "Fix trade bug outside raid. Fix minor bug in options window." },
{ ver = "4.7.11", text = "Fix bug in winners popup." },
{ ver = "4.7.10", text = "/src a[nnounce] command now supports /src aw for raid warning." },
@ -310,8 +313,20 @@ function M.new( popup_builder, awarded_loot, version_broadcast, event_bus, confi
e.create_gui_entry( "Rolling", frames, function()
e.create_config( "Roll settings", nil, "header" )
e.create_config( "Default rolling time", "default_rolling_time_seconds", "number|min=4|max=15", "Value must be between 4 and 15 seconds." )
this.handle_plus_ones = e.create_config( "Handle +1's on MS rolls", "handle_plus_ones", "checkbox", nil, function( value )
if value then
this:GetParent():GetParent().plus_one_prompt.input.enable()
else
this:GetParent():GetParent().plus_one_prompt.input.disable()
end
end )
this.plus_one_prompt = e.create_config("Always prompt for +1's", "plus_one_prompt", "checkbox" )
if not this.handle_plus_ones.input:GetChecked() then
this.plus_one_prompt.input.disable()
end
e.create_config( "Rolling popup lock", "rolling_popup_lock", "checkbox", "Locks the rolling popup position.", notify )
e.create_config( "Show Raid roll again button", "raid_roll_again", "checkbox", nil, notify )
e.create_config( "Show player roles", "show_player_roles", "checkbox", "Show player roles in rolling popup" )
e.create_config( "MainSpec rolling threshold", "ms_roll_threshold", "number" )
e.create_config( "OffSpec rolling threshold", "os_roll_threshold", "number" )
this.tmog_rolling_enabled = e.create_config( "Enable transmog rolling", "tmog_rolling_enabled", "checkbox", nil, function( value )

View File

@ -14,7 +14,7 @@ local hl = m.colors.hl
---@class RollControllerFacade
---@field roll_was_ignored fun( player_name: string, player_class: string?, roll_type: RollType, roll: number, reason: string )
---@field roll_was_accepted fun( player_name: string, player_class: string, roll_type: RollType, roll: number )
---@field roll_was_accepted fun( player_name: string, player_class: string, roll_type: RollType, roll: number, plus_ones: number )
---@field tick fun( seconds_left: number )
---@field winners_found fun( item: Item, item_count: number, winners: Winner[], strategy: RollingStrategyType )
---@field finish fun()
@ -857,10 +857,11 @@ function M.new(
preview_sr_items_not_equal_to_item_count( soft_ressers, item, item_count, dropped_item, buttons, candidate_count, candidates )
end
local function on_roll( player_name, player_class, roll_type, roll )
local function on_roll( player_name, player_class, roll_type, roll, plus_ones )
M.debug.add( string.format( "on_roll( %s, %s, %s, %s )", player_name, player_class, roll_type, roll ) )
local roll_tracker = get_roll_tracker( currently_displayed_item and currently_displayed_item.id )
roll_tracker.add( player_name, player_class, roll_type, roll )
local roller = m.find( player_name, softres.get_all_rollers(), "name")
roll_tracker.add( player_name, player_class, roller and roller.role, roll_type, roll, plus_ones )
local data, current_iteration = roll_tracker.get()
local strategy_type = current_iteration and current_iteration.rolling_strategy
@ -869,8 +870,10 @@ function M.new(
notify_subscribers( "roll", {
player_name = player_name,
player_class = player_class,
player_role = roller and roller.role,
roll_type = roll_type,
roll = roll
plus_ones = plus_ones,
roll = roll,
} )
end

View File

@ -18,7 +18,9 @@ local S = m.Types.RollingStatus
---@class RollData
---@field player_name string
---@field player_class string
---@field player_role string
---@field roll_type RollType
---@field plus_ones number
---@field roll number?
---@class RollIteration
@ -52,7 +54,7 @@ local S = m.Types.RollingStatus
---@field rolling_canceled fun()
---@field tie fun( required_rolling_players: RollingPlayer[], roll_type: RollType, roll: number )
---@field tie_start fun()
---@field add fun( player_name: string, player_class: string, roll_type: RollType, roll: number )
---@field add fun( player_name: string, player_class: string, player_role: string, roll_type: RollType, roll: number, plus_ones: number )
---@field add_ignored fun( player_name: string, roll_type: RollType, roll: number, reason: string )
---@field get fun(): RollTrackerData, RollIteration
---@field tick fun( seconds_left: number )
@ -89,7 +91,12 @@ function M.new( item_on_roll )
local function sort( rolls )
table.sort( rolls, function( a, b )
if a.roll_type ~= b.roll_type then return a.roll_type < b.roll_type end
if a.roll_type ~= b.roll_type then
return a.roll_type < b.roll_type
end
if a.roll_type == RT.MainSpec and a.plus_ones ~= b.plus_ones then
return a.plus_ones < b.plus_ones
end
if a.roll and b.roll then
if a.roll == b.roll then
@ -111,12 +118,12 @@ function M.new( item_on_roll )
end )
end
local function add( player_name, player_class, roll_type, roll )
local function add( player_name, player_class, player_role, roll_type, roll, plus_ones )
if current_iteration == 0 then return end
M.debug.add( "add" )
---@type RollData
local data = { player_name = player_name, player_class = player_class, roll_type = roll_type, roll = roll }
local data = { player_name = player_name, player_class = player_class, player_role = player_role, roll_type = roll_type, roll = roll, plus_ones = plus_ones }
local iteration = iterations[ current_iteration ]
if roll and (iteration.rolling_strategy == RS.SoftResRoll or iteration.rolling_strategy == RS.TieRoll) then
@ -135,7 +142,7 @@ function M.new( item_on_roll )
for _, player in ipairs( players ) do
for _ = 1, player.rolls do
---@type RollData
local data = { player_name = player.name, player_class = player.class, roll_type = RT.SoftRes }
local data = { player_name = player.name, player_class = player.class, player_role = player.role, roll_type = RT.SoftRes, plus_ones = player.plus_ones }
table.insert( result, data )
end
end
@ -166,7 +173,7 @@ function M.new( item_on_roll )
for _, player in ipairs( soft_ressers or {} ) do
for _ = 1, player.rolls or 1 do
add( player.name, player.class, RT.SoftRes )
add( player.name, player.class, player.role, RT.SoftRes, player.plus_ones )
end
end
end
@ -200,7 +207,7 @@ function M.new( item_on_roll )
for _, player in ipairs( required_rolling_players or {} ) do
for _ = 1, player.rolls or 1 do
add( player.name, player.class, rolling_strategy == RS.SoftResRoll and RT.SoftRes or RS.TieRoll )
add( player.name, player.class, player.role, rolling_strategy == RS.SoftResRoll and RT.SoftRes or RS.TieRoll, player.plus_ones )
end
end
end
@ -245,7 +252,7 @@ function M.new( item_on_roll )
} )
for _, player in ipairs( players or {} ) do
add( player.name, player.class, roll_type )
add( player.name, player.class, player.role, roll_type, nil, player.plus_ones )
end
end

View File

@ -21,7 +21,7 @@ end
---@param roller RollingPlayer
function M.copy_roller( roller )
return make_rolling_player( roller.name, roller.class, roller.online, roller.rolls )
return make_rolling_player( roller.name, roller.class, roller.role, roller.online, roller.rolls, roller.plus_ones )
end
---@param rollers RollingPlayer[]

View File

@ -6,6 +6,7 @@ if m.RollingPopup then return end
local getn = m.getn
local c = m.colorize_player_by_class
local blue = m.colors.blue
local RollType = m.Types.RollType
local button_defaults = {
width = 80,
@ -180,8 +181,17 @@ function M.new( popup_builder, content_transformer, db, config )
elseif type == "icon_text" then
frame:SetText( v.value )
elseif type == "roll" then
frame.roll_type:SetText( m.roll_type_color( v.roll_type, m.roll_type_abbrev( v.roll_type ) ) )
frame.player_name:SetText( c( v.player_name, v.player_class ) )
local roll_type_text = m.roll_type_abbrev( v.roll_type )
if v.roll_type == RollType.MainSpec and v.plus_ones > 0 then
roll_type_text = roll_type_text .. " +" .. v.plus_ones
end
frame.roll_type:SetText( m.roll_type_color( v.roll_type, roll_type_text ) )
local show_player_roles = config.show_player_roles()
frame:SetWidth( config.show_player_roles() and 200 or 170 )
local player_role = show_player_roles and v.player_role and string.format( " (%s)", string.gsub( v.player_role, v.player_class, "" ) ) or ""
frame.player_name:SetText( string.format( "%s%s", c( v.player_name, v.player_class ), player_role ) )
if v.roll then
frame.roll:SetText( blue( v.roll ) )

View File

@ -105,10 +105,12 @@ function M.new( config )
table.insert( result, {
type = "roll",
roll_type = roll.roll_type,
player_name = roll.player_name,
plus_ones = roll.plus_ones,
player_name = roll.player_name,
player_class = roll.player_class,
player_role = roll.player_role,
roll = roll.roll,
padding = i == 1 and top_padding or nil
padding = i == 1 and top_padding or nil,
} )
end
end

View File

@ -4,6 +4,7 @@ local m = RollFor
if m.RollingStrategyFactory then return end
local M = {}
local RollType = m.Types.RollType
local getn = m.getn
---@type MakeRollingPlayerFn
@ -43,7 +44,8 @@ function M.new(
winner_tracker,
config,
softres,
player_info
player_info,
awarded_loot
)
---@param item Item
---@param item_count number
@ -54,7 +56,13 @@ function M.new(
local function normal_roll( item, item_count, message, seconds, on_rolling_finished, roll_controller_facade )
local players = group_roster.get_all_players_in_my_group()
local rollers = m.map( players, function( player )
return make_rolling_player( player.name, player.class, player.online, 1 )
local plus_ones = 0
if config.handle_plus_ones() then
plus_ones = getn(m.filter(awarded_loot.get_winners(), (function (p)
return p ~= nil and p.player_name == player.name and p.plus_one
end)))
end
return make_rolling_player( player.name, player.class, player.role, player.online, 1, plus_ones )
end )
return m.NonSoftResRollingLogic.new(
@ -133,7 +141,7 @@ function M.new(
local rollers = m.map( players,
---@param player RollingPlayer
function( player )
return make_rolling_player( player.name, player.class, player.online, 1 )
return make_rolling_player( player.name, player.class, player.role, player.online, 1, player.plus_ones )
end
)

View File

@ -24,6 +24,7 @@ local make_roller = m.Types.make_roller
---@class RaidResSoftResEntry
---@field name string -- Player name.
---@field role string
---@field items RaidResSoftRessedItem[]
---@class RaidResSoftRessedItem
@ -62,6 +63,7 @@ function M.transform( data )
for _, sr in ipairs( soft_reserves or {} ) do
local roller_name = sr.name
local roller_role = sr.role
local item_ids = sr.items or {}
for _, item in ipairs( item_ids ) do
@ -78,6 +80,7 @@ function M.transform( data )
if not roller then
roller = make_roller( roller_name, 1 )
roller.sr_plus = tonumber( item.sr_plus )
roller.role = roller_role
table.insert( sr_result[ item_id ].rollers, roller )
else
roller.rolls = roller.rolls + 1

View File

@ -210,7 +210,7 @@ function M.new(
player.rolls = player.rolls - 1
table.insert( rolls, make_roll( player, roll_type, roll ) )
controller.roll_was_accepted( player.name, player.class, roll_type, roll )
controller.roll_was_accepted( player.name, player.class, roll_type, roll, player.plus_ones )
find_winner( State.AfterRoll )
end

View File

@ -143,7 +143,7 @@ function M.new( chat, players, item, item_count, on_rolling_finished, roll_type,
player.rolls = player.rolls - 1
table.insert( rolls, make_roll( player, roll_type, roll ) )
controller.roll_was_accepted( roller.name, player.class, roll_type, roll )
controller.roll_was_accepted( roller.name, player.class, roll_type, roll, player.plus_ones )
if have_all_rolls_been_exhausted() then find_winner() end
end

View File

@ -180,30 +180,37 @@ end
---@class RollingPlayer
---@field name string
---@field class string
---@field role string
---@field online boolean
---@field rolls number
---@field sr_plus number
---@field plus_ones number
---@field type "RollingPlayer"
---@alias MakeRollingPlayerFn fun(
--- name: string,
--- class: PlayerClass,
--- role: string,
--- online: boolean,
--- rolls: number ): RollingPlayer
--- rolls: number,
--- plus_ones: number ): RollingPlayer
---@type MakeRollingPlayerFn
---@param name string
---@param class PlayerClass
---@param role string
---@param online boolean
---@param rolls number
---@return RollingPlayer
function M.make_rolling_player( name, class, online, rolls )
function M.make_rolling_player( name, class, role, online, rolls, plus_ones )
return {
name = name,
class = class,
role = role,
online = online,
rolls = rolls,
type = PlayerType.RollingPlayer
type = PlayerType.RollingPlayer,
plus_ones = plus_ones
}
end

View File

@ -9,7 +9,7 @@ function IsInGroup() return IsInParty() or IsInRaid() end
if not string.gmatch then string.gmatch = string.gfind end
---@diagnostic disable-next-line: duplicate-set-field
string.match = string.match or function( str, pattern )
string.match = function( str, pattern )
if not str then return nil end
local _, _, r1, r2, r3, r4, r5, r6, r7, r8, r9 = string.find( str, pattern )