I would've liked to make it use a single allocate function to do this very cleanly, but these cases were very clearly not meant to be standardized and use wildly different methods to allocate & free...
This caused some scary issues with P_SaveNetGame the other day, and it's making ACS net sync harder. Let's just cut this off right now.
Also fixed some scary mix-ups in some of the Lua archiving code.
An effectively useless global scope boolean that literally checks for the presence of a finish line, created in and used only by things we inherited from vanilla SRB2
* Battle-like item box respawn handling inverse of GTR_CIRCUIT
* Make battle fullscreen overlay forbid GTR_CIRCUIT
* Make GTR_ITEMARROWS actually do something
* Make everything related to points actually use GTR_POINTLIMIT
* Fobid sphere addition without GTR_SPHERES, to mirror ring addition forbidding
- Add "Gametype" toggle option to pause menu for admins
- A/Confirm button on any gametype other than current to do random map in new gametype
- C/Extra button to return to current gametype
- A/Confirm button on current gametype does a funny noise and nothing else right now, idk what to do
- `randomlevel` supports the same `-gametype` parameter as `map`
- Both `randomlevel` and `map`'s `-gametype` parameter prohibits `GTR_FORBIDMP` mask gametype changes in netgames
- `randomlevel` properly sets encore based on `cv_kartencore`'s value (and permitting `GTR_ENCORE`)
- Split out `menugametype` change functions
- `yellowmap` now remaps all intermediary shades of grey to match funny pause menu remaps
- Introduce `menugametype`
- Controlled by IT_KEYHANDLER/M_HandleMenuGametype
- Excludes gametypes that do not support multiplayer by default
- GTR_CAPSULES and GTR_BOSS for now, but also user-specifiable GTR_NOMP
- Remove gametype_cons_t and G_UpdateGametypeSelections, an obstacle in the way of infinitely allocatable custom gametypes
* The existing structs are now exclusively for handling extra data.
* `specialStage` has been renamed to `specialstageinfo`, to reflect that it is not the sole arbiter.
* `specialstageinfo.valid` and `bossinfo.valid` are what must be checked before grabbing data from either struct.
* These are turned on when the gametype extra data is successfully initialised, not on map start.
* `K_InitBossHealthBar(...)` for `bossinfo.valid`
* `K_InitSpecialStage(void)` for `specialstageinfo.valid`
* `K_CanChangeRules(...)` no longer checks these
* No longer uses duplicate encore information.
* The map command (and -warp) now guesses gametype using a general `G_GuessGametypeByTOL(UINT32)` function
* Grabs the first gametype with an overlap between the requested TOL and the gametype's TOL.
* The cool Versus-specific intro is now checked via `K_CheckBossIntro()`.
Controlled three things: Vintage SRB2 cutscenes, a certain type of reset on map commands, and whether to go to ceremony/evaluation/credits. All three should be controlled by grandprixinfo.gp instead, since that persists cross-gametype.
- New array of pointers to structures in memory (currently mixing static for base-game and Callocated for custom)
- Centralises a metric-ton of previously seperately handled properties into one struct
- Gametype_Names[]
- Gametype_ConstantNames[]
- gametypetol[]
- timelimits[]
- pointlimits[]
- gametypedefaultrules[]
- Don't attempt to guess custom gametype in Replay Hut (requires more work to make custom gametypes behave across the entire experience)
- I_Error if invalid gametype set
- gametyperules is deprecated since it will never be modified seperately from gametype (temporarily a #define, don't wanna bloat this commit too much)
New:
- GTR_POWERSTONES
- Handles spawning in Battle Emeralds (currently only works stacked with GTR_PAPERITEMS)
- GTR_ENCORE
- Codifies that Race can use Encore and Battle can't.
- GTR_CLOSERPLAYERS
- A gametype where players are encouraged/expected to be closer together. (All of the following was GT_BATTLE specific)
- Drafting/tether has increased strength/effective distance
- Spindashing is stronger
- Invincibility chaining has less effect
- Grow has a lower total duration
- Flame shield is more uncontrollable
Extra functionality
- GTR_CAPSULES
- Prevents usage of lives in Grand Prix (so Race, and the upcoming Special and Boss gametypes, can have 'em)
- GTR_CIRCUIT
- When not present, Flame Shield has perma-full meter
- When not present, overrides gamespeed with KARTSPEED_EASY
- Presence of Best Lap sticker in Time Attack menu
- Seperation between Time Attack and Break The Capsules modeattacking roulettes
- GTR_POINTLIMIT
- Handles the switch between a gametype recording/displaying Times and Scores in a few places
- Handles displaying "WANTED" players on the minimap
Missing simple substitutions
- A whole bunch of cases where player->bumpers was checked with gametype == GT_BATTLE rather than GTR_BUMPER
- GTR_OVERTIME handles the overtime special icon on the minimap
- GTR_BATTLESTARTS is honoured in K_DoIngamerespawn
- The Replay hut is closer to supporting custom gametypes
Removals
- GTR_LIVES
- GTR_SPECIALBOTS
- Given that grand prix persists between modes, these are special game-controlled features and not gametype-specific.
- GTR_WANTED
- WANTED as it existed is functionally dead
- Handle mismatched gametypes for client and server on voting screen
- I_Error when running out of gametypes
- Reduce gametype freeslots slightly to avoid colliding with VOTEMODIFIER_ENCORE
* The consensus has moved against gametype changes in voting, so strip it out
* Encorescramble already independently controls setting Encore, so don't keep the outdated randomisation method
Done in this branch because it uses gametype constants directly, both in a cvar and function, and I want to get rid of as many of those as possible
The roulette contains NO (non-seeded) RNG anymore. You manually stop it at any time.
Still needs the visual of the items scrolling, to make it not blind.
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