Notable new features:
- Guaranteed native compatibility with SF_IRONMAN even with differing # of skins
- Bots (todo: can still desync midway through round)
Implementation details:
- Demo code (skins):
- Instead of writing a skin name string, and the player's kartspeed, kartweight, and charflags for each player in the initial player-interpreting loop...
- Write a skinlist of EVERY skin's name string, kartspeed, kartweight, and flags next to the file list, to be read into `demo.skinlist`.
- If the skin name isn't loaded, find the skin with (in order)
- SF_IRONMAN if your skin had SF_IRONMAN, since that's more important to signal
- the closest stats otherwise (as per previous implementation)
- Just as tolerant to stats AND the number of base skins changing between versions (the bonuschars aegis situation)
- Not tolerant to restat, but we can add a DXD or EZT later if we want to natively support that kind of mod
- In the initial loop and DXD_SKIN, just write an index that can be used for `demo.skinlist`, and store it in `demo.currentskinid[p]`
- The player's skin is now encoded as EZT_IRONMAN for ghosts (and just in case RNG sync fails for unrelated reasons)
- In the SF_IRONMAN code when demo.playback is true
- everywhere where `skins[player->skin]` is referenced instead uses an index into `demo.skinlist`
- SetRandomFakePlayerSkin uses the `demo.skinlist` to build a table to ensure exact random call parity
- Also means it no longer double rejection-samples.
- `player->fakeskin` and `lastfakeskin` are always == their original recording values, a skin id which can be used into `demo.skinlist`
- Demo code (playstate, initial player setup loop):
- Add bot flag (`DXD_PST_ISBOT`, `DEMO_BOT`)
- Add in-between-level botvars (difficulty, diffincrease, rival)
- Don't rely on `PF_WANTSTOJOIN` to activate
Additional bugfixes:
- Followerskin set to -1 in CL_ClearPlayer so a bad follower isn't recorded on player join without name and color change arriving immediately
- Accomodate new joiners in demo code even if they're not on DXD_PST_SPECTATING for one reason or another
- Demo extra file list saving is now its own function for code cleanliness
- Actually only modify players relevant to the demo at the end of G_DoPlayDemo, not all 16 by supplying and overwriting garbage values (POSSIBLE MEMORY CORRUPTION FIX, mobj_t pointer was previously dereferenced)
Originally written by x.organic, flattened rewrite due to massive changes between RR and SRB2Kart codebase
Notable changes:
- p_adding_file has been reworked into partadd_earliestfile to allow for final setup to use
- much like the public version required removing TEXTURE SOCs, this one required removing Flats support from ANIMDEFS
- Use `SpeedPad` to set the strength. Intended to be scaled like Trick Panels, so 1 for yellow, 2 for red, so on. Can use floating point.
- Use `SpeedPadAngle` to rotate the thrust direction. This is in the same system as map angles, so east is 0, north is 90, west is 180, and south is 270. Also accepts floating point.
- Speed Pad angle accounts for the flat alignment itself, as well.
- Like Sneaker and Trick Panels, the sector / line special are now deprecated.
- Uses args instead of texture offsets.
- Compares tag lists, instead of thing angle.
- Made the arguments accept 0 as a "catch-all" option (args[0] == 0 means don't care what type it is; line tag == 0 means don't care what tags they have)
- Auto accel
- 800% acceleration
- 110% top speed
- Infinite tether like Lightning Shield
- Resists going upward on slopes
- Less friction
- Can always turn your sprite
- Turning speed does not get weaker at high speeds
- Turning speed is normal underwater
- Keeps moving in momentum direction, regardless of how
you turn
- Releasing a drift redirects all your momentum in that
direction
- Floats over bananas, damage sectors and offroad
- No stair janking while floating
- Hold drift for extra gravity. Not only does this fast
fall (this stacks with true fast falling), it builds
momentum down slopes too!
- Parries Big Players (Grow), Invincibility, Flame Shield
and, of course, other Tops -- all except if you're
grinding
- Wipes out anyone you touch
- Infinite weight like Bubble Shield
- Does not water skip
- Does not water run while holding drift
* Instead of doing constant G_MapNumbers when finding the relationship between maps and cups...
* Add a cache of level IDs to cups, to go with the strings.
* Add a cache of the cup pointer to maps, so we don't have to search through all cups to find our map. (done in P_InitMapData)
* Pre-emptive work: G_IsSpecialStage and P_GetNextEmerald now reference cup data instead of a hardcoded ID set.
* Remove a bunch of old stuff from mapheaderinfo_t/associated, and reorder what stays
* Countdowntimer? 💥
* Startrings? 💥
* sstimer/ssspheres? 💥
* forcecharacter? 💥 (distinct from forceskin)
* interscreen? 💥
* sstage_start/end and smpstage_start/end? 💥💥💥💥
* You've been blocked
* G_MapNumber now returns a special NEXTMAP_INVALID if not found, for more consistent reference.
* Incorporate a good chunk of the `edit-headers` branch. Can't clear maps individually because of the new restrictions on sequential mapheaders, but we can add a "disable in vote screen, not even for map hell/archive" flag to a map at some future juncture for equivalent functionality...