Last active
April 16, 2022 08:21
-
-
Save tesence/5ebbeb047a51b6684e5230764a44eebf to your computer and use it in GitHub Desktop.
An OBS lua script that loads a seed file for Ori and the Blind Forest DE Randomizer and displays its options
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Setup: | |
-- * Load the script in OBS under "Tools > Scripts > (+)" | |
-- * Create a Text Source on the scene you want the seed options to be displayed | |
-- * Select the created source as the "Text Source" in the script options | |
-- * Set the "Path to randomizer.dat file" option by browsing the location where the seed files are copied | |
-- * Check off the box if you want the item pool to be displayed on the seperate line | |
-- * Define "Alt + L" as "Reload Seed" hotkey under "Settings > Hotkeys" | |
obs = obslua | |
source_name = "" | |
file_location = "" | |
item_pool = false | |
hotkey_id = obs.OBS_INVALID_HOTKEY_ID | |
local LOGIC_MODES = { | |
"Casual", "Standard", "Expert", "Master", "Glitched", "Custom" | |
} | |
local GOAL_MODES = { | |
"ForceTrees", "WorldTour=[0-9]+", "ForceMaps", "Frags/[0-9]+/[0-9]+", "Bingo" | |
} | |
local KEY_MODES = { | |
"Default", "Shards", "LimitKeys", "Clues", "Free" | |
} | |
local VARIATIONS = { | |
"Starved", "OHKO", "0XP", "ClosedDungeons", "OpenWorld", | |
"DoubleSkills", "StrictMapstones", "TPStarved", "GoalModeFinish", | |
"WallStarved", "GrenadeStarved", | |
-- Special variations that regular seed file might not include | |
"Race", -- "Race" is a tourney thing and doesn't get shown | |
"StompTriggers", -- "StompTriggers" probably makes kill plane and kuro cs behave as in vanilla | |
"NoExtraExp" -- "NoExtraExp" is like 0EXP except pickups still grant experience. It's a plando thing | |
} | |
local ITEM_POOLS = { | |
"pool=(Competitive)", "pool=(Extra Bonus)", "pool=(Bonus Lite)", "pool=(Hard)" | |
} | |
function get_matching(flags, reference_list) | |
-- Find the intersection between a list of flags and a list used as reference | |
local res = {} | |
for _, flag in pairs(flags) do | |
for _, value in pairs(reference_list) do | |
if string.match(flag, "^" .. value .. "$") then res[#res + 1] = string.match(flag, value) end | |
end | |
end | |
return res | |
end | |
function read_file(f) | |
-- Check if path exists, otherwise return "Seed File Not Found" | |
local fb = io.open(f, "r") | |
if fb then | |
fb:close() | |
else | |
return "Seed File Not Found" | |
end | |
-- Load file content and close the file right away | |
local file = io.open(f) | |
local content = file:read() | |
file:close() | |
-- Default seed format: | |
-- [Sync<ID>.<PlayerID>,]<LogicMode>,<KeyMode>,<GoalMode>,balanced|<SeedName> | |
-- | |
-- e.g: | |
-- Sync28467.1,Standard,Clues,ForceTrees,balanced|214465254 | |
local raw_flags, seed_name = string.match(content, "(.*)|(.*)") | |
local flags = {} | |
for flag in string.gmatch(raw_flags, "([^,]+)") do | |
flags[#flags + 1] = flag | |
end | |
-- Try to find a matching logic mode | |
local logic_modes = get_matching(flags, LOGIC_MODES) | |
-- Try to find a matching key mode | |
local key_modes = get_matching(flags, KEY_MODES) | |
-- Try to find all the matching goal modes | |
local goal_modes = get_matching(flags, GOAL_MODES) | |
-- Try to find all the matching variations | |
local variations = get_matching(flags, VARIATIONS) | |
-- Try to find a matching item pool, use "Standard" otherwise | |
local item_pools = get_matching(flags, ITEM_POOLS) | |
-- Build the output string | |
res = "Seed: " .. seed_name .. "\n" | |
res = res .. table.concat(logic_modes, " ") .. " " | |
.. table.concat(key_modes, " ") .. " " | |
.. table.concat(goal_modes, " ") | |
if next(variations) then res = res .. " " .. table.concat(variations, " ") end | |
if itempool_bool then | |
if not next(item_pools) then item_pools = {"Standard"} end | |
res = res .. "\nItem Pool: " .. table.concat(item_pools, " ") | |
else | |
res = res .. " " .. table.concat(item_pools, " ") | |
end | |
return res | |
end | |
function load_seed() | |
local source = obs.obs_get_source_by_name(source_name) | |
local text = read_file(file_location) | |
if source ~= nil then | |
local settings = obs.obs_data_create() | |
obs.obs_data_set_string(settings, "text", text) | |
obs.obs_source_update(source, settings) | |
obs.obs_data_release(settings) | |
obs.obs_source_release(source) | |
end | |
end | |
function script_properties() | |
local props = obs.obs_properties_create() | |
local p = obs.obs_properties_add_list(props, "source", "Text Source", | |
obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING) | |
local f = obs.obs_properties_add_path(props, "path", "Path to randomizer.dat file", | |
obs.OBS_PATH_FILE, | |
"Randomizer seed file (*.dat)", "C:/Program Files (x86)/Steam/steamapps/common/Ori DE") | |
local b = obs.obs_properties_add_bool(props, "itempool_bool", "Display item pool on a seperate line") | |
local sources = obs.obs_enum_sources() | |
if sources ~= nil then | |
for _, source in ipairs(sources) do | |
source_id = obs.obs_source_get_id(source) | |
if source_id == "text_gdiplus" or source_id == "text_ft2_source" then | |
local name = obs.obs_source_get_name(source) | |
obs.obs_property_list_add_string(p, name, name) | |
end | |
end | |
end | |
obs.source_list_release(sources) | |
return props | |
end | |
function script_description() | |
return "Reads the `randomizer.dat` file for Ori and the Blind Forest DE Randomizer and outputs the name and options of the seed." | |
end | |
function script_update(settings) | |
source_name = obs.obs_data_get_string(settings, "source") | |
file_location = obs.obs_data_get_string(settings, "path") | |
itempool_bool = obs.obs_data_get_bool(settings, "itempool_bool") | |
load_seed() | |
end | |
function script_defaults(settings) | |
end | |
function script_save(settings) | |
local hotkey_save_array = obs.obs_hotkey_save(hotkey_id) | |
obs.obs_data_set_array(settings, "load_hotkey", hotkey_save_array) | |
obs.obs_data_array_release(hotkey_save_array) | |
end | |
function script_load(settings) | |
local sh = obs.obs_get_signal_handler() | |
obs.signal_handler_connect(sh, "source_activate", source_activated) | |
obs.signal_handler_connect(sh, "source_deactivate", source_deactivated) | |
hotkey_id = obs.obs_hotkey_register_frontend("load_seed_name", "Reload Seed", load_seed) | |
local hotkey_save_array = obs.obs_data_get_array(settings, "load_hotkey") | |
obs.obs_hotkey_load(hotkey_id, hotkey_save_array) | |
obs.obs_data_array_release(hotkey_save_array) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment