mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
SA2B: v2.0 Content Update (#1294)
Changelog:
Features:
- Completely reworked mission progression system
- Control of which mission types can be active per-gameplay-style
- Control of how many missions are active per-gameplay-style
- Mission order shuffle
- Two new Chaos Emerald Hunt goals
- `Chaos Emerald Hunt` involves finding the seven Chaos Emeralds and beating Green Hill
- `FinalHazard Chaos Emerald Hunt` is the same, but with the FinalHazard fight at the end of Green Hill
- New optional Location Checks
- Keysanity (Chao Containers)
- Whistlesanity (Animal Pipes and hidden whistle spots)
- Beetlesanity (Destroying Gold Beetles)
- Option to require clearing all active Cannon's Core Missions for access to the Biolizard fight in `Biolizard` goal
- Hard Logic option
- More Music Options
- Option to use SADX music
- New `Singularity` music shuffle option
- Option to choose the Narrator theme
- New Traps
- Tiny Trap is now permanent within a level
- Gravity Trap
- Exposition Trap
Quality of Life:
- Significant revamp to Stage Select screen information conveyance
- Icons are displayed for:
- Relevant character's upgrades
- Which location checks are active/checked
- Chaos Emeralds found (if relevant)
- Gate and Cannon's Core emblem costs
- The above stage-specific info can also be viewed when paused in-level
- The current mission is also displayed when paused
- Emblem Symbol on Mission Select subscreen now only displays if a high enough rank has been gotten on that mission to send the location check
- Hints including SA2B locations will now specify which Gate that level is located in
- Save file now stores slot name to help prevent false location checks in the case of one player having multiple SA2B slots in the same seed
- Chao Intermediate and Expert race sets are now swapped, per player feedback
- Intermediate now includes Beginner + Challenge + Hero + Dark
- Expert now includes Beginner + Challenge + Hero + Dark + Jewel
- New mod config option for the color of the Message Queue text
Bug Fixes:
- Fixed bug where game stops properly tracking items after 127 have been received.
- Several logic fixes
- Game now refers to `Knuckles - Shovel Claws` correctly
- Minor AP World code cleanup
This commit is contained in:
@@ -3,6 +3,27 @@ import typing
|
||||
from Options import Choice, Range, Option, Toggle, DeathLink, DefaultOnToggle, OptionList
|
||||
|
||||
|
||||
class Goal(Choice):
|
||||
"""
|
||||
Determines the goal of the seed
|
||||
Biolizard: Finish Cannon's Core and defeat the Biolizard and Finalhazard
|
||||
Chaos Emerald Hunt: Find the Seven Chaos Emeralds and reach Green Hill Zone
|
||||
Finalhazard Chaos Emerald Hunt: Find the Seven Chaos Emeralds and reach Green Hill Zone, then defeat Finalhazard
|
||||
"""
|
||||
display_name = "Goal"
|
||||
option_biolizard = 0
|
||||
option_chaos_emerald_hunt = 1
|
||||
option_finalhazard_chaos_emerald_hunt = 2
|
||||
default = 0
|
||||
|
||||
|
||||
class MissionShuffle(Toggle):
|
||||
"""
|
||||
Determines whether missions order will be shuffled per level
|
||||
"""
|
||||
display_name = "Mission Shuffle"
|
||||
|
||||
|
||||
class BaseTrapWeight(Choice):
|
||||
"""
|
||||
Base Class for Trap Weights
|
||||
@@ -42,6 +63,27 @@ class TinyTrapWeight(BaseTrapWeight):
|
||||
display_name = "Tiny Trap Weight"
|
||||
|
||||
|
||||
class GravityTrapWeight(BaseTrapWeight):
|
||||
"""
|
||||
Likelihood of a receiving a trap which increases gravity
|
||||
"""
|
||||
display_name = "Gravity Trap Weight"
|
||||
|
||||
|
||||
class ExpositionTrapWeight(BaseTrapWeight):
|
||||
"""
|
||||
Likelihood of a receiving a trap which tells you the story
|
||||
"""
|
||||
display_name = "Exposition Trap Weight"
|
||||
|
||||
|
||||
class DarknessTrapWeight(BaseTrapWeight):
|
||||
"""
|
||||
Likelihood of a receiving a trap which makes the world dark
|
||||
"""
|
||||
display_name = "Darkness Trap Weight"
|
||||
|
||||
|
||||
class JunkFillPercentage(Range):
|
||||
"""
|
||||
Replace a percentage of non-required emblems in the item pool with random junk items
|
||||
@@ -78,11 +120,41 @@ class IncludeMissions(Range):
|
||||
default = 2
|
||||
|
||||
|
||||
class Keysanity(Toggle):
|
||||
"""
|
||||
Determines whether picking up Chao Keys grants checks
|
||||
"""
|
||||
display_name = "Keysanity"
|
||||
|
||||
|
||||
class Whistlesanity(Choice):
|
||||
"""
|
||||
Determines whether whistling at various spots grants checks
|
||||
None: No Whistle Spots grant checks
|
||||
Pipes: Whistling at Pipes grants checks
|
||||
Hidden: Whistling at Hidden Whistle Spots grants checks
|
||||
Both: Whistling at both Pipes and Hidden Whistle Spots grants checks
|
||||
"""
|
||||
display_name = "Whistlesanity"
|
||||
option_none = 0
|
||||
option_pipes = 1
|
||||
option_hidden = 2
|
||||
option_both = 3
|
||||
default = 0
|
||||
|
||||
|
||||
class Beetlesanity(Toggle):
|
||||
"""
|
||||
Determines whether destroying Gold Beetles grants checks
|
||||
"""
|
||||
display_name = "Beetlesanity"
|
||||
|
||||
|
||||
class EmblemPercentageForCannonsCore(Range):
|
||||
"""
|
||||
Allows logic to gate the final mission behind a number of Emblems
|
||||
"""
|
||||
display_name = "Emblem Percentage for Cannons Core"
|
||||
display_name = "Emblem Percentage for Cannon's Core"
|
||||
range_start = 0
|
||||
range_end = 75
|
||||
default = 50
|
||||
@@ -172,24 +244,280 @@ class ChaoRaceChecks(Choice):
|
||||
default = 0
|
||||
|
||||
|
||||
class RequiredCannonsCoreMissions(Choice):
|
||||
"""
|
||||
Determines how many Cannon's Core missions must be completed to unlock the Biolizard (for the "Biolizard" goal)
|
||||
First: Only the first mission must be completed
|
||||
All Active: All active Cannon's Core missions must be completed
|
||||
"""
|
||||
display_name = "Required Cannon's Core Missions"
|
||||
option_first = 0
|
||||
option_all_active = 1
|
||||
default = 0
|
||||
|
||||
|
||||
class BaseMissionCount(Range):
|
||||
"""
|
||||
Base class for mission count options
|
||||
"""
|
||||
range_start = 1
|
||||
range_end = 5
|
||||
default = 2
|
||||
|
||||
|
||||
class SpeedMissionCount(BaseMissionCount):
|
||||
"""
|
||||
The number of active missions to include for Sonic and Shadow stages
|
||||
"""
|
||||
display_name = "Speed Mission Count"
|
||||
|
||||
|
||||
class SpeedMission2(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Sonic and Shadow 100 rings missions should be included
|
||||
"""
|
||||
display_name = "Speed Mission 2"
|
||||
|
||||
|
||||
class SpeedMission3(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Sonic and Shadow lost chao missions should be included
|
||||
"""
|
||||
display_name = "Speed Mission 3"
|
||||
|
||||
|
||||
class SpeedMission4(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Sonic and Shadow time trial missions should be included
|
||||
"""
|
||||
display_name = "Speed Mission 4"
|
||||
|
||||
|
||||
class SpeedMission5(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Sonic and Shadow hard missions should be included
|
||||
"""
|
||||
display_name = "Speed Mission 5"
|
||||
|
||||
|
||||
class MechMissionCount(BaseMissionCount):
|
||||
"""
|
||||
The number of active missions to include for Tails and Eggman stages
|
||||
"""
|
||||
display_name = "Mech Mission Count"
|
||||
|
||||
|
||||
class MechMission2(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Tails and Eggman 100 rings missions should be included
|
||||
"""
|
||||
display_name = "Mech Mission 2"
|
||||
|
||||
|
||||
class MechMission3(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Tails and Eggman lost chao missions should be included
|
||||
"""
|
||||
display_name = "Mech Mission 3"
|
||||
|
||||
|
||||
class MechMission4(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Tails and Eggman time trial missions should be included
|
||||
"""
|
||||
display_name = "Mech Mission 4"
|
||||
|
||||
|
||||
class MechMission5(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Tails and Eggman hard missions should be included
|
||||
"""
|
||||
display_name = "Mech Mission 5"
|
||||
|
||||
|
||||
class HuntMissionCount(BaseMissionCount):
|
||||
"""
|
||||
The number of active missions to include for Knuckles and Rouge stages
|
||||
"""
|
||||
display_name = "Hunt Mission Count"
|
||||
|
||||
|
||||
class HuntMission2(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Knuckles and Rouge 100 rings missions should be included
|
||||
"""
|
||||
display_name = "Hunt Mission 2"
|
||||
|
||||
|
||||
class HuntMission3(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Knuckles and Rouge lost chao missions should be included
|
||||
"""
|
||||
display_name = "Hunt Mission 3"
|
||||
|
||||
|
||||
class HuntMission4(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Knuckles and Rouge time trial missions should be included
|
||||
"""
|
||||
display_name = "Hunt Mission 4"
|
||||
|
||||
|
||||
class HuntMission5(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Knuckles and Rouge hard missions should be included
|
||||
"""
|
||||
display_name = "Hunt Mission 5"
|
||||
|
||||
|
||||
class KartMissionCount(BaseMissionCount):
|
||||
"""
|
||||
The number of active missions to include for Route 101 and 280
|
||||
"""
|
||||
display_name = "Kart Mission Count"
|
||||
|
||||
|
||||
class KartMission2(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Route 101 and 280 100 rings missions should be included
|
||||
"""
|
||||
display_name = "Kart Mission 2"
|
||||
|
||||
|
||||
class KartMission3(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Route 101 and 280 avoid cars missions should be included
|
||||
"""
|
||||
display_name = "Kart Mission 3"
|
||||
|
||||
|
||||
class KartMission4(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Route 101 and 280 avoid walls missions should be included
|
||||
"""
|
||||
display_name = "Kart Mission 4"
|
||||
|
||||
|
||||
class KartMission5(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Route 101 and 280 hard missions should be included
|
||||
"""
|
||||
display_name = "Kart Mission 5"
|
||||
|
||||
|
||||
class CannonsCoreMissionCount(BaseMissionCount):
|
||||
"""
|
||||
The number of active missions to include for Cannon's Core
|
||||
"""
|
||||
display_name = "Cannon's Core Mission Count"
|
||||
|
||||
|
||||
class CannonsCoreMission2(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Cannon's Core 100 rings mission should be included
|
||||
"""
|
||||
display_name = "Cannon's Core Mission 2"
|
||||
|
||||
|
||||
class CannonsCoreMission3(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Cannon's Core lost chao mission should be included
|
||||
"""
|
||||
display_name = "Cannon's Core Mission 3"
|
||||
|
||||
|
||||
class CannonsCoreMission4(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Cannon's Core time trial mission should be included
|
||||
"""
|
||||
display_name = "Cannon's Core Mission 4"
|
||||
|
||||
|
||||
class CannonsCoreMission5(DefaultOnToggle):
|
||||
"""
|
||||
Determines if the Cannon's Core hard mission should be included
|
||||
"""
|
||||
display_name = "Cannon's Core Mission 5"
|
||||
|
||||
|
||||
class SADXMusic(Choice):
|
||||
"""
|
||||
Whether the randomizer will include Sonic Adventure DX Music in the music pool
|
||||
SA2B: Only SA2B music will be played
|
||||
SADX: Only SADX music will be played
|
||||
Both: Both SA2B and SADX music will be played
|
||||
NOTE: This option requires the player to own a PC copy of SADX and to follow the addition steps in the setup guide.
|
||||
"""
|
||||
display_name = "SADX Music"
|
||||
option_sa2b = 0
|
||||
option_sadx = 1
|
||||
option_both = 2
|
||||
default = 0
|
||||
|
||||
@classmethod
|
||||
def get_option_name(cls, value) -> str:
|
||||
if cls.auto_display_name and value != 2:
|
||||
return cls.name_lookup[value].upper()
|
||||
else:
|
||||
return cls.name_lookup[value]
|
||||
|
||||
|
||||
class MusicShuffle(Choice):
|
||||
"""
|
||||
What type of Music Shuffle is used
|
||||
Off: No music is shuffled.
|
||||
Levels: Level music is shuffled.
|
||||
Full: Level, Menu, and Additional music is shuffled.
|
||||
Singularity: Level, Menu, and Additional music is all replaced with a single random song.
|
||||
"""
|
||||
display_name = "Music Shuffle Type"
|
||||
option_none = 0
|
||||
option_levels = 1
|
||||
option_full = 2
|
||||
option_singularity = 3
|
||||
default = 0
|
||||
|
||||
|
||||
class Narrator(Choice):
|
||||
"""
|
||||
Which menu narrator is used
|
||||
"""
|
||||
display_name = "Narrator"
|
||||
option_default = 0
|
||||
option_shadow = 1
|
||||
option_rouge = 2
|
||||
option_eggman = 3
|
||||
option_maria = 4
|
||||
option_secretary = 5
|
||||
option_omochao = 6
|
||||
option_amy = 7
|
||||
option_tails = 8
|
||||
option_knuckles = 9
|
||||
option_sonic = 10
|
||||
default = 0
|
||||
|
||||
|
||||
class LogicDifficulty(Choice):
|
||||
"""
|
||||
What set of Upgrade Requirement logic to use
|
||||
Standard: The logic assumes the "intended" usage of Upgrades to progress through levels
|
||||
Hard: Some simple skips or sequence breaks may be required
|
||||
"""
|
||||
display_name = "Logic Difficulty"
|
||||
option_standard = 0
|
||||
option_hard = 1
|
||||
default = 0
|
||||
|
||||
|
||||
sa2b_options: typing.Dict[str, type(Option)] = {
|
||||
"include_missions": IncludeMissions,
|
||||
"goal": Goal,
|
||||
"mission_shuffle": MissionShuffle,
|
||||
"keysanity": Keysanity,
|
||||
"whistlesanity": Whistlesanity,
|
||||
"beetlesanity": Beetlesanity,
|
||||
"required_rank": RequiredRank,
|
||||
"emblem_percentage_for_cannons_core": EmblemPercentageForCannonsCore,
|
||||
"required_cannons_core_missions": RequiredCannonsCoreMissions,
|
||||
"number_of_level_gates": NumberOfLevelGates,
|
||||
"level_gate_distribution": LevelGateDistribution,
|
||||
"level_gate_costs": LevelGateCosts,
|
||||
@@ -202,6 +530,37 @@ sa2b_options: typing.Dict[str, type(Option)] = {
|
||||
"timestop_trap_weight": TimestopTrapWeight,
|
||||
"confusion_trap_weight": ConfusionTrapWeight,
|
||||
"tiny_trap_weight": TinyTrapWeight,
|
||||
"gravity_trap_weight": GravityTrapWeight,
|
||||
"exposition_trap_weight": ExpositionTrapWeight,
|
||||
#"darkness_trap_weight": DarknessTrapWeight,
|
||||
"sadx_music": SADXMusic,
|
||||
"music_shuffle": MusicShuffle,
|
||||
"narrator": Narrator,
|
||||
"logic_difficulty": LogicDifficulty,
|
||||
"speed_mission_count": SpeedMissionCount,
|
||||
"speed_mission_2": SpeedMission2,
|
||||
"speed_mission_3": SpeedMission3,
|
||||
"speed_mission_4": SpeedMission4,
|
||||
"speed_mission_5": SpeedMission5,
|
||||
"mech_mission_count": MechMissionCount,
|
||||
"mech_mission_2": MechMission2,
|
||||
"mech_mission_3": MechMission3,
|
||||
"mech_mission_4": MechMission4,
|
||||
"mech_mission_5": MechMission5,
|
||||
"hunt_mission_count": HuntMissionCount,
|
||||
"hunt_mission_2": HuntMission2,
|
||||
"hunt_mission_3": HuntMission3,
|
||||
"hunt_mission_4": HuntMission4,
|
||||
"hunt_mission_5": HuntMission5,
|
||||
"kart_mission_count": KartMissionCount,
|
||||
"kart_mission_2": KartMission2,
|
||||
"kart_mission_3": KartMission3,
|
||||
"kart_mission_4": KartMission4,
|
||||
"kart_mission_5": KartMission5,
|
||||
"cannons_core_mission_count": CannonsCoreMissionCount,
|
||||
"cannons_core_mission_2": CannonsCoreMission2,
|
||||
"cannons_core_mission_3": CannonsCoreMission3,
|
||||
"cannons_core_mission_4": CannonsCoreMission4,
|
||||
"cannons_core_mission_5": CannonsCoreMission5,
|
||||
"death_link": DeathLink,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user