All courses are restricted in Match Race/Time Attack/Online if not visited in GP UNLESS:
- It is the first Race Course of a Cup
- Course has "NoVisitNeeded = True`
- The Controls Tutorial and Test Run are the only two stages that will need this
The above replaces:
- A lot of restricted courses having to be marked with `FinishNeeded = True`
- Hidden Palace
- Sealed Stars 1-14
- Once Special Mode is unlocked, it will now be possible to practice Sealed Stars before rematching them in GP
- Almost all Tutorial-specific behaviour, since it was heinously hacky
HOWEVER, `FinishNeeded = True` was left in specifically for future releases, and I reserve the right to use it on Adventure Example again before launch.
New condition for tracking multiple cups' windata.
`Condition1 = AllCupRecords RR_Egg Bronze`
- All cups up to Egg Cup must be completed at Bronze or better
`Condition1 = AllCupRecords`
- All cups in the game must be completed
`Condition1 = AllCupRecords All Any Master`
- All cups in the game must be completed on Master mode`
- Go to a MainCfg-specified map on its guessed gametype
- `TutorialChallengeMap = RR_ZonedCity`
- Some unique settings
- K_CanChangeRules() == false
- If GTR_CIRCUIT, make it Hard Speed
- If GTR_BUMPERS, die in one hit
- If GTR_BOTS, make them all difficulty 13 of the default bot skin
- No Medals or Spray Cans during the Tutorial Challenge
- Complete the stage in 1st place or don't bother at all
- Has the "Give up" menu option available, but no "Try Again"
- Condition for successfully completing the Tutorial Skip
- `Condition1 = TutorialSkip`
Related bugfixes:
- Correctly wipe skipstats when returning to the Title/menus
- Typing of `ultimatemode` (hey this isn't accessible by anything right now I wonder)
- Gametypes have "GPpic" and "GPpicMini" parameters
- These are shown in contexts where a Round Number would be shown in GP, but an eventmode is under way.
- Instead of having different rules to show up on the pause menu, titlecard, and tally/intermission...
- Pause Menu Roundqueue, Tally, and Intermission have all been aligned to the same rules.
- As long as the titlecard is standard, it will show the GP Pic per those rules. (GTR_SPECIALSTART and GTR_BOSS still have their unique behaviour here)
If you're hypothetically gating a Character behind 100% of Characters unlocked... that'll never come true!
To that end, allow a fudge value to be specified.
It's added to the unlock count before comparing it against the percentage.
`Condition1 = TotalTumbleTime 30*TICRATE
"tumble through the air for 30:00"
Also makes all the time-based non-playing Conditions use get_number so TICRATE can be provided
You have to destroy all objects of a certain list of types.
UNLIKE OTHER CHALLENGES, this is dependent on a mapheader parameter!!
The author of this commit just didn't want to create too laggy a condition check.
- `Condition1 = MapDestroyObjects RR_ESPRESSOLANE tables & chairs
- Map RR_ESPRESSOLANE
- DestroyObjectsForChallenges = MT_ESPTABLE,MT_ESPCHAIR
"hit a racer drafting off you while looking back at them"
Self-explanatory set of conditions
Wrote a commented out more compicated check for valid angles between player and target, but lastdraft probably is good enough for these purpses
Insta-Whip another racer while you yourself are invisible from Hyuudoro, it's shrimple
Also updates the phrasing used for UCRP_TRIPWIREHYUU to match ("afflicted by Hyudoro")
- `Condition1 = Faulted Yes`
- `FAULT during POSITION`
- for example, combine with "& finish in 1st"
- `Condition1 = Faulted No`
- `don't FAULT during POSITION`
- Removed all old dev title screen remainders that were interfering with titlemaps.
- F_VersionDrawer displays on all title screen types
- SA2 intro sound only plays whenever there's am actual title card to show (before it checked for not GS_CEREMONY?)
- Removed redundant customversionstring check in menus (F_VersionDrawer already handles customversionstring)
"when cursed with Eggmark, blow up the racer responsible"
Just a simple condition. Either it happens or it doesn't.
MT_SPBEXPLOSION now tracks whether it was made by KITEM_EGGMAN or KITEM_SPB, too!
Break a target (Prison Egg/UFO) using exactly one Gachabom again and again
Becomes invalid if an Insta-Whip collides with a target, or you throw two at the same time
`Condition1 = UfoAttackMethod [type]`
- "smash a UFO Catcher using only [type]"
- Combine with `Prefix_SealedStar` or `Prefix_IsMap [special stage stage]`
- Shows up as "???"
- Types supported:
- `Boost` - "boost power" (sneakers)
- `Whip` - "Insta-Whip"
- `Banana` - "Bananas"
- `Orbinaut`- "Orbinauts"
- `Jawz` - "Jawz"
- `SPB` - "Self Propelled Bombs"
- Other types could be added on request, these were just the easy ones
In addition, the prototype for P_MobjWasRemoved was moved to `p_mobj.h`.
It's EXTREMELY important that we're able to safely check mobj pointers anywhere a mobj_t is possible to observe, without including the full `p_local.h`...
A series of 100 booleans on the roundconditions struct, one per possible lap.
Allows for a full suite of track hazard touching conditions - see the following examples.
- `Condition1 = Prefix_IsMap RR_MOTOBUGMOTORWAY
- `Condition1 = TrackHazard No`
- `Condition1 = IsMap RR_MOTOBUGMOTORWAY`
- "MOTOBUG MOTORWAY: Don't touch any track hazard"
- `Condition1 = Prefix_GrandPrix`
- `Condition1 = IsMap RR_HARDBOILEDSTADIUM`
- `Condition1 = TrackHazard Yes`
- `Condition1 = And`
- `Condition1 = FinishPlace 1`
- "GRAND PRIX: On HARD-BOILED STADIUM, touch a track hazard every lap & finish in 1st"
- `Condition1 = Prefix IsMap RR_DEATHEGG`
- `Condition1 = Trackhazard No 8`
- "DEATH EGG ZONE: Don't touch any track hazard on lap 8"
- `Condition1 = Prefix_IsMap RR_SPEEDHIGHWAY
- `Condition1 = TrackHazard No Final`
- "SPEED HIGHWAY: Don't touch any track hazard on the final lap"
- `UnlockPercent 40 AltMusic` - "Get 40% of alternate music"
- `UnlockPercent 1 Color` - "Get 1% of Spray Cans"
- `UnlockPercent 20 Map` - "Get 20% of Courses"
- `UnlockPercent 55 Cup` - "Get 55% of Cups"
- `UnlockPercent 100` - "Get 100% completion"
- Provide a percentage and, optionally, an Unlockable type
- This only works for Unlockable Types where there are expected to be more than one per board
- "DescriptionOverride" (new!)
- Provide a full description in place of the params and this will be used
- Any conditions that are before it will not be wiped, so you can prefix it if you need to
- Can be used with any other set of Conditions
- `Condition1 = DescriptionOverride Complete the sentence: "ring racers (???)"`
- "Password"
- Now supports passwords that contain spaces
- `Condition1 = Password race as a ring!`
- "WetPlayer"
- Now supports liquids that contain spaces
- HOWEVER, it comes with the following caveats as part of the change:
- The strictness level must be provided first.
- You can't leave the strictness out. The previous default behaviour now requires STANDARD to be explicitly written.
- `Condition1 = WetPlayer Standard Mega Mack` can be used, now.
Gamedata minor version was updated again.
(God this was a weirdly big amount of work and it's not even polished.)
- Condition1 = PrisonEggCD [Level that has to be unlocked]
- Approximately every 30 Prison Eggs destroyed, you get a shot at a Prison Egg Drop.
- The only Prison Egg Drop implemented right now is an Alt Music CD.
- Your [Wild Prize] is guaranteed to be selected only from conditions associated with levels that are unlocked!
- Only spawns in Grand Prix Bonus Rounds, for netsync and game design.
- The number is fuzzed. If you start the level with 0 Prison Eggs to destroy, it selects a random number of Prisons in the level to bust.
- If you miss the pickup (such as into a deathpit), you'll get another shot in the immediate next Bonus Round you play.
Also:
- The number of Chao Keys you start your gamedata with is now part of the header file, not buried in the wiping function.
- Removed the ACTUAL last object definition vestiges of the Emerald Hunt gamemode.
- `Condition1 = MakeRetire Eggrobo`
- Fires when:
- Not a cooperative context
- You've finished in good standing
- Another player has both
- PF_NOCONTEST
- The skin specified in the condition
Also makes rivalname-handling for K_InitGrandPrixBots `const char *`, since the author of this commit had to reference that code.
Just in case I don't get to do a major pass on adding a ton of extra unlockable conditions later, this is an easy, quick add featuring a stat gamedata and the statistics menu has been tracking for a while.
Instead of being specific to each level, Spray Cans are stored in a list on gamedata that will be stepped along each Spray Can you collect.
They are only assigned to a level on collection - which prevents you from farming the same easy location for every colour in the game.
In addition, this new system is one step short of dehardcoding them entirely. Now only Spray Cans specifically asked for by the existence of UC_SPRAYCAN will be put in the list, and if a secondary parameter is either "Yes" or "True", it will be put at the head of the list. This could technically support custom skincolours one day, but the author of this commit doesn't care to do the last bit of work necessary to make it happen.
There's a slight extra overhead in that skincolor_t now also holds a `cache_spraycan` (renamed from `cachedcan`, which maps had previously)
Currently, there's no safeguard against grabbing it on a custom course - you'll lose the Spray Can as soon as you load a fresh game again - but I consider that easy to fix (tomorrow) and necessary before merger, because the author of this commit does NOT want complaints on release because we forgot to protect users who keep on losing their skincolors.