Skip to content

Commit

Permalink
Ror2: Add progressive stages option (ArchipelagoMW#2813)
Browse files Browse the repository at this point in the history
  • Loading branch information
kindasneaki authored and qwint committed Jun 24, 2024
1 parent 8c07ce9 commit cfc89fc
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 22 deletions.
27 changes: 21 additions & 6 deletions worlds/ror2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class RiskOfRainWorld(World):
}
location_name_to_id = item_pickups

data_version = 8
required_client_version = (0, 4, 4)
data_version = 9
required_client_version = (0, 4, 5)
web = RiskOfWeb()
total_revivals: int

Expand Down Expand Up @@ -91,6 +91,17 @@ def create_items(self) -> None:
# only mess with the environments if they are set as items
if self.options.goal == "explore":

# check to see if the user doesn't want to use stages, and to figure out what type of stages are being used.
if not self.options.require_stages:
if not self.options.progressive_stages:
self.multiworld.push_precollected(self.multiworld.create_item("Stage 1", self.player))
self.multiworld.push_precollected(self.multiworld.create_item("Stage 2", self.player))
self.multiworld.push_precollected(self.multiworld.create_item("Stage 3", self.player))
self.multiworld.push_precollected(self.multiworld.create_item("Stage 4", self.player))
else:
for _ in range(4):
self.multiworld.push_precollected(self.multiworld.create_item("Progressive Stage", self.player))

# figure out all available ordered stages for each tier
environment_available_orderedstages_table = environment_vanilla_orderedstages_table
if self.options.dlc_sotv:
Expand Down Expand Up @@ -121,8 +132,12 @@ def create_items(self) -> None:
total_locations = self.options.total_locations.value
else:
# explore mode
# Add Stage items for logic gates
itempool += ["Stage 1", "Stage 2", "Stage 3", "Stage 4"]

# Add Stage items to the pool
if self.options.require_stages:
itempool += ["Stage 1", "Stage 2", "Stage 3", "Stage 4"] if not self.options.progressive_stages else \
["Progressive Stage"] * 4

total_locations = len(
get_locations(
chests=self.options.chests_per_stage.value,
Expand Down Expand Up @@ -206,8 +221,8 @@ def fill_slot_data(self) -> Dict[str, Any]:
options_dict = self.options.as_dict("item_pickup_step", "shrine_use_step", "goal", "victory", "total_locations",
"chests_per_stage", "shrines_per_stage", "scavengers_per_stage",
"scanner_per_stage", "altars_per_stage", "total_revivals",
"start_with_revive", "final_stage_death", "death_link",
casing="camel")
"start_with_revive", "final_stage_death", "death_link", "require_stages",
"progressive_stages", casing="camel")
return {
**options_dict,
"seed": "".join(self.random.choice(string.digits) for _ in range(16)),
Expand Down
1 change: 0 additions & 1 deletion worlds/ror2/docs/en_Risk of Rain 2.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ options apply, so each Risk of Rain 2 player slot in the multiworld needs to be
for example, have two players trade off hosting and making progress on each other's player slot, but a single co-op
instance can't make progress towards multiple player slots in the multiworld.

Explore mode is untested in multiplayer and will likely not work until a later release.

## What Risk of Rain items can appear in other players' worlds?

Expand Down
2 changes: 1 addition & 1 deletion worlds/ror2/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class RiskOfRainItemData(NamedTuple):
"Stage 2": RiskOfRainItemData("Stage", 2 + stage_offset, ItemClassification.progression),
"Stage 3": RiskOfRainItemData("Stage", 3 + stage_offset, ItemClassification.progression),
"Stage 4": RiskOfRainItemData("Stage", 4 + stage_offset, ItemClassification.progression),

"Progressive Stage": RiskOfRainItemData("Stage", 5 + stage_offset, ItemClassification.progression),
}

item_table = {**upgrade_table, **other_table, **filler_table, **trap_table, **stage_table}
Expand Down
13 changes: 13 additions & 0 deletions worlds/ror2/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,17 @@ class DLC_SOTV(Toggle):
display_name = "Enable DLC - SOTV"


class RequireStages(DefaultOnToggle):
"""Add Stage items to the pool to block access to the next set of environments."""
display_name = "Require Stages"


class ProgressiveStages(DefaultOnToggle):
"""This will convert Stage items to be a progressive item. For example instead of "Stage 2" it would be
"Progressive Stage" """
display_name = "Progressive Stages"


class GreenScrap(Range):
"""Weight of Green Scraps in the item pool.
Expand Down Expand Up @@ -378,6 +389,8 @@ class ROR2Options(PerGameCommonOptions):
start_with_revive: StartWithRevive
final_stage_death: FinalStageDeath
dlc_sotv: DLC_SOTV
require_stages: RequireStages
progressive_stages: ProgressiveStages
death_link: DeathLink
item_pickup_step: ItemPickupStep
shrine_use_step: ShrineUseStep
Expand Down
23 changes: 10 additions & 13 deletions worlds/ror2/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ def has_entrance_access_rule(multiworld: MultiWorld, stage: str, region: str, pl
entrance.access_rule = rule


def has_stage_access_rule(multiworld: MultiWorld, stage: str, amount: int, region: str, player: int) -> None:
rule = lambda state: state.has(region, player) and \
(state.has(stage, player) or state.count("Progressive Stage", player) >= amount)
for entrance in multiworld.get_region(region, player).entrances:
entrance.access_rule = rule


def has_all_items(multiworld: MultiWorld, items: Set[str], region: str, player: int) -> None:
rule = lambda state: state.has_all(items, player) and state.has(region, player)
for entrance in multiworld.get_region(region, player).entrances:
Expand Down Expand Up @@ -43,15 +50,6 @@ def check_location(state, environment: str, player: int, item_number: int, item_
return state.can_reach(f"{environment}: {item_name} {item_number - 1}", "Location", player)


# unlock event to next set of stages
def get_stage_event(multiworld: MultiWorld, player: int, stage_number: int) -> None:
if stage_number == 4:
return
rule = lambda state: state.has(f"Stage {stage_number + 1}", player)
for entrance in multiworld.get_region(f"OrderedStage_{stage_number + 1}", player).entrances:
entrance.access_rule = rule


def set_rules(ror2_world: "RiskOfRainWorld") -> None:
player = ror2_world.player
multiworld = ror2_world.multiworld
Expand Down Expand Up @@ -124,8 +122,7 @@ def set_rules(ror2_world: "RiskOfRainWorld") -> None:
for newt in range(1, newts + 1):
has_location_access_rule(multiworld, environment_name, player, newt, "Newt Altar")
if i > 0:
has_entrance_access_rule(multiworld, f"Stage {i}", environment_name, player)
get_stage_event(multiworld, player, i)
has_stage_access_rule(multiworld, f"Stage {i}", i, environment_name, player)

if ror2_options.dlc_sotv:
for i in range(len(environment_sotv_orderedstages_table)):
Expand All @@ -143,10 +140,10 @@ def set_rules(ror2_world: "RiskOfRainWorld") -> None:
for newt in range(1, newts + 1):
has_location_access_rule(multiworld, environment_name, player, newt, "Newt Altar")
if i > 0:
has_entrance_access_rule(multiworld, f"Stage {i}", environment_name, player)
has_stage_access_rule(multiworld, f"Stage {i}", i, environment_name, player)
has_entrance_access_rule(multiworld, "Hidden Realm: A Moment, Fractured", "Hidden Realm: A Moment, Whole",
player)
has_entrance_access_rule(multiworld, "Stage 1", "Hidden Realm: Bazaar Between Time", player)
has_stage_access_rule(multiworld, "Stage 1", 1, "Hidden Realm: Bazaar Between Time", player)
has_entrance_access_rule(multiworld, "Hidden Realm: Bazaar Between Time", "Void Fields", player)
has_entrance_access_rule(multiworld, "Stage 5", "Commencement", player)
has_entrance_access_rule(multiworld, "Stage 5", "Hidden Realm: A Moment, Fractured", player)
Expand Down
4 changes: 3 additions & 1 deletion worlds/ror2/test/test_mithrix_goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

class MithrixGoalTest(RoR2TestBase):
options = {
"victory": "mithrix"
"victory": "mithrix",
"require_stages": "true",
"progressive_stages": "false"
}

def test_mithrix(self) -> None:
Expand Down

0 comments on commit cfc89fc

Please sign in to comment.