Skip to content

Instantly share code, notes, and snippets.

@tesence
Last active April 16, 2022 08:21
Show Gist options
  • Save tesence/5ebbeb047a51b6684e5230764a44eebf to your computer and use it in GitHub Desktop.
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
-- 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