Locked skins now are a specific unlockable type, instead of being tied to the skin's properties.
This has plagued custom gamedata since 2.2 launch. It's extremely obnoxious having to set aside random numbers as dummy unlockables just to ensure that Amy Fang & Metal are unlocked from the start in a custom map pack.
Other changes made to accommodate this:
- R_GetSkinAvailabilities is now created from the list of unlockables set to skin type. (1st skin unlockable defined is (1), 2nd skin unlockable defined is (1 << 1), etc...)
- The "Added skin x" print shows up when loading addons but not at all for the base game, because the previous behavior of hiding based on if the skin was locked would now require iterating unlockables, which felt wrong to do during that stage of the loading process
- I noticed in my test wad that Sonic&Tails would give you Sonic&Sonic out if Tails was locked. I fixed that by making both skins required to show the character select option.
Mods that reserved empty dummy unlockables for Amy Fang and Metal won't have to do anything. Mods that wanted to re-lock them behind different requirements will have to update, but in the future they will not have to be in specific slots. Additionally, now Sonic Tails and Knuckles can also be locked for mods.
- Can now apply to normal stages, simply defaults to "false" in normal stages.
- Post-level cutscenes are now always skipped when the stage was failed.
- Exposed the boolean as a Lua read+write global.
Desired for SUGOI, as it allows for visited flags not be updated, and level completion emblems to not be awarded. Which means a lot less crappy non-ideal workarounds.
Normal stage intermission currently does not reflect failure state at all. Maybe it could always skip, never award score bonuses, have different text... etc. Probably would leave that up to vanilla dev opinion.
* Hooks are no longer a mess of lua boiler plate. Helper functions reduce hooks
to, at the most basic level, only two calls.
* Lua tables (the array part) are used to index hooks. Such tables contain only
hooks of the same type.
* Hook types are defined in one place so you no longer need to sync up the enum
and name array.