System for netsyncing unlocks, inspired by but with nowhere near as many moving parts as (STJr/SRB2!1756).
* `gamedata->unlocked[MAXUNLOCKABLES]` is duplicated to `netUnlocked[MAXUNLOCKABLES]` (or all `true` in `dedicated`
* New `local` boolean for M_SecretUnlocked
* Removed last vestiges of SRB2 special stage token code because it occupied the spot in the netsave we wanted to use.
* Correct typing of multiple `m_cond` functions that returned `boolean` constants as `UINT8`s.
Completely clientside, unlike SECRET_SKIN. Followers have no gameplay function, and it saves us having to write even more to our demos/netsaves. Replaces SECRET_WARP.
Also:
- Now don't apply skins or followers from profiles if the skin is locked - instead, get the closest skin in stats. (Same function as from demos!)
- If you're looking at a profile and the skin or follower are locked, make them solid colour (TC_BLINK).
- Don't show the ring cursor before you've selected a profile.
Mammoth commit, sorry. I only realised halfway through writing it that SECRET_SKIN was only partially merged.
Ports from 2.2:
- Merge SECRET_SKIN (STJr/SRB2!1474)
- Default skin is now handled by checking all skins for unlock status, and I_Erroring if none are available
- Don't show skin names on game startup, to keep our secrets hidden
- Unlockables now have string variables zallocated.
- For skin names rather than numbers.
- Correctly clean up memory when freeing unlockables and emblems.
Bespoke code:
- For temporary testing. `unlocks.pk3`
- Using this for rapid testing gameboot SOC instead of patch.pk3 because of the intent to turn that into scripts.pk3
- Don't not save gamedata in DEVELOP builds, even if you've used cheats!
- `player->availabilities` is now an array of UINT8
- (MAXSKINS + 7)/8 entries, or 32 bytes.
- Included with XD_ADDPLAYER instead of XD_NAMEANDCOLOR.
- Simplifies a lot of logic with respect to demos, skin changes mid-game, etc.
- Seriously, there's a lot of random places in the code that just iterate over MAXSPLITSCREENPLAYERS and g_localplayers to update availabilities in real time in a way that's not particularly netsafe...
- Lines up with the plan for handling unlocks when returning to menus.
- Was included with XD_ADDBOT, but that actually overruns the netxcmd buffer at first mapload with 7 bots. We might need to consider expanding the size of the netxcmd buffer...
- In demos, can be interpreted as both relative to the original replay and the current skin list depending on boolean context provided to R_SkinUsable.
- Used for SF_IRONMAN (and will crash if all other skins are inaccessible).
- Grand Prix bot randomisation uses the host's unlocks.
- Don't show locked characters on the fancy new character select.
- DXD_JOINDATA for demos
- Replaces the dual-purpose behaviour of DXD_PLAYSTATE
- Contains availabilities
- Handles bot material in a different way
- Forceskin restrictions
- Won't run in demos, because it's assumed recorded DXD_SKIN will handle all the conversions the original match had
- Won't run if K_CanChangeRules says no
- Correctly set `mapvisited` on level visit, even in [fake gasp] MULTIPLAYER/NETGAMES!! 🥹
- Added updating unlockables and extra emblems on `mapvisited` update.
- Currently fails to produce the cecho, but that'll be stripped out entirely in a future commit so I'm not bothered.
Can be used to disable VFX, so it can only appear if its owner is a display player. If no owner is provided, then it will be removed entirely.
Applied to most things that Ivo asked for
- Fixes defaulting to follower id 0 (previously chao, currently hot robo) when joining a server without going through the menu flow
- No need to store TWO names for a follower, so save a little memory
- Should make it easier to add unlockable followers later
It's been used interchangably as "this is a singleplayer gameplay context" and "This is a no cvar changing context". This addition repairs some behaviour which might have been inconsistent between netgame and netreplay.
- Implementation details:
- grandprixinfo.eventmode is the reference point
- All bots have spectator applied and removed at map start depending on eventmode, and I've done my best to guard against side effects of not removing them entirely
- You shouldn't turn off grandprixinfo.gp when turning on things like specialStage.active or bossinfo.boss when pursuing eventmode behaviour
- Probably needs to be integrated into XD_MAP for any future netplay support, is currently disabled.
- You technically don't have to assign a Capsules map to be the bonus and a Special Stage to be the special. A Capsules map can be assigned to a Special Stage too, and a Boss can be assigned to either of them.
- Special Stages are still just as incomplete as they were before.
- Break the Capsules has special behaviour.
- Timelimit starts at 20 seconds.
- Earn 10 seconds (plus a little extra cheaty time) every capsule you destroy.
- WIN + extra life if you bust all the capsules, COOL if you get some but run out of time, LOSE if you lose your bumper or run out of time without breaking a single capsule.
- Supposed to also give you rings, but ran into a LOT of difficulty with this and didn't want to commit half-baked stuff, so it'll be a later project.
Also:
- Fix a long standing bug where totalring was reset between maps, preventing the sum from adding up across GP rounds and depriving you of extra lives you were owed.
- Fix an issue where Break the Capsules record attack was KARTSPEED_HARD.
- Send timelimitintics in savegames, since it's handled seperately now.
- exitcountdown is now used for both No Contest and regular exits
- Set in P_DoPlayerExit
- Handles sending XD_EXITLEVEL in P_Ticker
- player->exiting is now 0 or 1 (we can make it a bool or a new timer later)
- Fixes a longstanding bug where failing a GP round could restart multiple times
Also:
- Fix a possible waiting-in-the-wings issue where mapchanges would occour client-side in K_CheckBumpers
- Add `gptest` cheat - sets numlaps to 1 lap on mapload for quick but legitimate(ish) progression
- Make timelimitintics handled a bit more like gamespeed, encore, frantic, etc - update on mapload/starttime, not during gameplay
- Use default setting if can't change rules - this is a surprise tool that will help us later
- Have it properly update when adjusting gametype from the menu
- Cleaned up SV_StartSinglePlayerServer to do this
- Remove CV_SAVE to prevent time limit bruh moments