diff --git a/shuffler-src/setupform.lua b/shuffler-src/setupform.lua index 722ca3a..898ba2e 100644 --- a/shuffler-src/setupform.lua +++ b/shuffler-src/setupform.lua @@ -244,7 +244,7 @@ function module.initial_setup(callback) end local SWAP_MODES_DEFAULT = 'Random Order (Default)' - local SWAP_MODES = {[SWAP_MODES_DEFAULT] = -1, ['Fixed Order'] = 0} + local SWAP_MODES = {[SWAP_MODES_DEFAULT] = -1, ['Random (Boost Unpicked)'] = -2, ['Fixed Order'] = 0} -- I believe none of these conflict with default Bizhawk hotkeys local HOTKEY_OPTIONS = { @@ -282,6 +282,13 @@ function module.initial_setup(callback) config.hk_complete = (forms.gettext(hk_complete) or 'Ctrl+Shift+End'):match("[^%s]+") config.completed_games = {} + if config.shuffle_index == -2 then + config.game_weights = {} + for _,game in pairs(get_games_list()) do + config.game_weights[game] = 0 + end + end + config.plugins = {} for _,plugin in ipairs(plugins) do if plugin._enabled then diff --git a/shuffler.lua b/shuffler.lua index 3a59c0b..607f61f 100644 --- a/shuffler.lua +++ b/shuffler.lua @@ -253,11 +253,17 @@ function get_next_game() all_games = get_games_list(true) end - -- shuffle_index == -1 represents fully random shuffle order + -- shuffle_index < 0 represents random shuffle order types if config.shuffle_index < 0 then -- remove the currently loaded game and see if there are any other options table_subtract(all_games, { prev }) if #all_games == 0 then return prev end + -- shuffle_index == -2 indicates games should be given multiple entries based on + -- their weight in config.game_weights + if config.shuffle_index == -2 then + if prev ~= nil then config.game_weights[prev] = 0 end + pad_games_list(all_games) + end return all_games[math.random(#all_games)] else -- manually select the next one @@ -267,6 +273,27 @@ function get_next_game() end end +function pad_games_list(games) + -- copy the games list so we're not iterating over an ever-expanding list + local initial_games = {} + for _,game in pairs(games) do + table.insert(initial_games, game) + end + -- actual padding + for _,game in pairs(initial_games) do + -- accounting for new games + if config.game_weights[game] ~= nil then + -- pad the games list with (weight) copies of the game + for i = 0, config.game_weights[game] do + table.insert(games, game) + end + else + config.game_weights[game] = 0 + end + config.game_weights[game] = config.game_weights[game] + 1 + end +end + -- save current game's savestate, backup config, and load new game function swap_game(next_game) -- if a swap has already happened, don't call again @@ -393,6 +420,10 @@ end function mark_complete() -- mark the game as complete in the config file rather than moving files around table.insert(config.completed_games, config.current_game) + -- purge it from game_weights if necessary + if config.game_weights ~= nil then + table.remove(config.game_weights, config.current_game) + end log_message(config.current_game .. ' marked complete') for _,plugin in ipairs(plugins) do if plugin.on_complete ~= nil then