Skip to content

Commit

Permalink
Rogue Legacy: Update to Options API (ArchipelagoMW#3755)
Browse files Browse the repository at this point in the history
* fix deprecation

* multiworld.random -> world.random

* Various small fixes

---------

Co-authored-by: Exempt-Medic <[email protected]>
Co-authored-by: Exempt-Medic <[email protected]>
  • Loading branch information
3 people authored Sep 8, 2024
1 parent 05b257a commit 6d6d35d
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 133 deletions.
78 changes: 40 additions & 38 deletions worlds/rogue_legacy/Options.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Dict
from Options import Choice, Range, Toggle, DeathLink, DefaultOnToggle, OptionSet, PerGameCommonOptions

from Options import Choice, Range, Option, Toggle, DeathLink, DefaultOnToggle, OptionSet
from dataclasses import dataclass


class StartingGender(Choice):
Expand Down Expand Up @@ -336,42 +336,44 @@ class AvailableClasses(OptionSet):
The upgraded form of your starting class will be available regardless.
"""
display_name = "Available Classes"
default = {"Knight", "Mage", "Barbarian", "Knave", "Shinobi", "Miner", "Spellthief", "Lich", "Dragon", "Traitor"}
default = frozenset(
{"Knight", "Mage", "Barbarian", "Knave", "Shinobi", "Miner", "Spellthief", "Lich", "Dragon", "Traitor"}
)
valid_keys = {"Knight", "Mage", "Barbarian", "Knave", "Shinobi", "Miner", "Spellthief", "Lich", "Dragon", "Traitor"}


rl_options: Dict[str, type(Option)] = {
"starting_gender": StartingGender,
"starting_class": StartingClass,
"available_classes": AvailableClasses,
"new_game_plus": NewGamePlus,
"fairy_chests_per_zone": FairyChestsPerZone,
"chests_per_zone": ChestsPerZone,
"universal_fairy_chests": UniversalFairyChests,
"universal_chests": UniversalChests,
"vendors": Vendors,
"architect": Architect,
"architect_fee": ArchitectFee,
"disable_charon": DisableCharon,
"require_purchasing": RequirePurchasing,
"progressive_blueprints": ProgressiveBlueprints,
"gold_gain_multiplier": GoldGainMultiplier,
"number_of_children": NumberOfChildren,
"free_diary_on_generation": FreeDiaryOnGeneration,
"khidr": ChallengeBossKhidr,
"alexander": ChallengeBossAlexander,
"leon": ChallengeBossLeon,
"herodotus": ChallengeBossHerodotus,
"health_pool": HealthUpPool,
"mana_pool": ManaUpPool,
"attack_pool": AttackUpPool,
"magic_damage_pool": MagicDamageUpPool,
"armor_pool": ArmorUpPool,
"equip_pool": EquipUpPool,
"crit_chance_pool": CritChanceUpPool,
"crit_damage_pool": CritDamageUpPool,
"allow_default_names": AllowDefaultNames,
"additional_lady_names": AdditionalNames,
"additional_sir_names": AdditionalNames,
"death_link": DeathLink,
}
@dataclass
class RLOptions(PerGameCommonOptions):
starting_gender: StartingGender
starting_class: StartingClass
available_classes: AvailableClasses
new_game_plus: NewGamePlus
fairy_chests_per_zone: FairyChestsPerZone
chests_per_zone: ChestsPerZone
universal_fairy_chests: UniversalFairyChests
universal_chests: UniversalChests
vendors: Vendors
architect: Architect
architect_fee: ArchitectFee
disable_charon: DisableCharon
require_purchasing: RequirePurchasing
progressive_blueprints: ProgressiveBlueprints
gold_gain_multiplier: GoldGainMultiplier
number_of_children: NumberOfChildren
free_diary_on_generation: FreeDiaryOnGeneration
khidr: ChallengeBossKhidr
alexander: ChallengeBossAlexander
leon: ChallengeBossLeon
herodotus: ChallengeBossHerodotus
health_pool: HealthUpPool
mana_pool: ManaUpPool
attack_pool: AttackUpPool
magic_damage_pool: MagicDamageUpPool
armor_pool: ArmorUpPool
equip_pool: EquipUpPool
crit_chance_pool: CritChanceUpPool
crit_damage_pool: CritDamageUpPool
allow_default_names: AllowDefaultNames
additional_lady_names: AdditionalNames
additional_sir_names: AdditionalNames
death_link: DeathLink
31 changes: 17 additions & 14 deletions worlds/rogue_legacy/Regions.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
from typing import Dict, List, NamedTuple, Optional
from typing import Dict, List, NamedTuple, Optional, TYPE_CHECKING

from BaseClasses import MultiWorld, Region, Entrance
from .Locations import RLLocation, location_table, get_locations_by_category

if TYPE_CHECKING:
from . import RLWorld


class RLRegionData(NamedTuple):
locations: Optional[List[str]]
region_exits: Optional[List[str]]


def create_regions(multiworld: MultiWorld, player: int):
def create_regions(world: "RLWorld"):
regions: Dict[str, RLRegionData] = {
"Menu": RLRegionData(None, ["Castle Hamson"]),
"The Manor": RLRegionData([], []),
Expand Down Expand Up @@ -56,9 +59,9 @@ def create_regions(multiworld: MultiWorld, player: int):
regions["The Fountain Room"].locations.append("Fountain Room")

# Chests
chests = int(multiworld.chests_per_zone[player])
chests = int(world.options.chests_per_zone)
for i in range(0, chests):
if multiworld.universal_chests[player]:
if world.options.universal_chests:
regions["Castle Hamson"].locations.append(f"Chest {i + 1}")
regions["Forest Abkhazia"].locations.append(f"Chest {i + 1 + chests}")
regions["The Maya"].locations.append(f"Chest {i + 1 + (chests * 2)}")
Expand All @@ -70,9 +73,9 @@ def create_regions(multiworld: MultiWorld, player: int):
regions["Land of Darkness"].locations.append(f"Land of Darkness - Chest {i + 1}")

# Fairy Chests
chests = int(multiworld.fairy_chests_per_zone[player])
chests = int(world.options.fairy_chests_per_zone)
for i in range(0, chests):
if multiworld.universal_fairy_chests[player]:
if world.options.universal_fairy_chests:
regions["Castle Hamson"].locations.append(f"Fairy Chest {i + 1}")
regions["Forest Abkhazia"].locations.append(f"Fairy Chest {i + 1 + chests}")
regions["The Maya"].locations.append(f"Fairy Chest {i + 1 + (chests * 2)}")
Expand All @@ -85,14 +88,14 @@ def create_regions(multiworld: MultiWorld, player: int):

# Set up the regions correctly.
for name, data in regions.items():
multiworld.regions.append(create_region(multiworld, player, name, data))

multiworld.get_entrance("Castle Hamson", player).connect(multiworld.get_region("Castle Hamson", player))
multiworld.get_entrance("The Manor", player).connect(multiworld.get_region("The Manor", player))
multiworld.get_entrance("Forest Abkhazia", player).connect(multiworld.get_region("Forest Abkhazia", player))
multiworld.get_entrance("The Maya", player).connect(multiworld.get_region("The Maya", player))
multiworld.get_entrance("Land of Darkness", player).connect(multiworld.get_region("Land of Darkness", player))
multiworld.get_entrance("The Fountain Room", player).connect(multiworld.get_region("The Fountain Room", player))
world.multiworld.regions.append(create_region(world.multiworld, world.player, name, data))

world.get_entrance("Castle Hamson").connect(world.get_region("Castle Hamson"))
world.get_entrance("The Manor").connect(world.get_region("The Manor"))
world.get_entrance("Forest Abkhazia").connect(world.get_region("Forest Abkhazia"))
world.get_entrance("The Maya").connect(world.get_region("The Maya"))
world.get_entrance("Land of Darkness").connect(world.get_region("Land of Darkness"))
world.get_entrance("The Fountain Room").connect(world.get_region("The Fountain Room"))


def create_region(multiworld: MultiWorld, player: int, name: str, data: RLRegionData):
Expand Down
50 changes: 27 additions & 23 deletions worlds/rogue_legacy/Rules.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from BaseClasses import CollectionState, MultiWorld
from BaseClasses import CollectionState
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from . import RLWorld

def get_upgrade_total(multiworld: MultiWorld, player: int) -> int:
return int(multiworld.health_pool[player]) + int(multiworld.mana_pool[player]) + \
int(multiworld.attack_pool[player]) + int(multiworld.magic_damage_pool[player])

def get_upgrade_total(world: "RLWorld") -> int:
return int(world.options.health_pool) + int(world.options.mana_pool) + \
int(world.options.attack_pool) + int(world.options.magic_damage_pool)


def get_upgrade_count(state: CollectionState, player: int) -> int:
Expand All @@ -19,8 +23,8 @@ def has_upgrade_amount(state: CollectionState, player: int, amount: int) -> bool
return get_upgrade_count(state, player) >= amount


def has_upgrades_percentage(state: CollectionState, player: int, percentage: float) -> bool:
return has_upgrade_amount(state, player, round(get_upgrade_total(state.multiworld, player) * (percentage / 100)))
def has_upgrades_percentage(state: CollectionState, world: "RLWorld", percentage: float) -> bool:
return has_upgrade_amount(state, world.player, round(get_upgrade_total(world) * (percentage / 100)))


def has_movement_rune(state: CollectionState, player: int) -> bool:
Expand All @@ -47,15 +51,15 @@ def has_defeated_dungeon(state: CollectionState, player: int) -> bool:
return state.has("Defeat Herodotus", player) or state.has("Defeat Astrodotus", player)


def set_rules(multiworld: MultiWorld, player: int):
def set_rules(world: "RLWorld", player: int):
# If 'vendors' are 'normal', then expect it to show up in the first half(ish) of the spheres.
if multiworld.vendors[player] == "normal":
multiworld.get_location("Forest Abkhazia Boss Reward", player).access_rule = \
if world.options.vendors == "normal":
world.get_location("Forest Abkhazia Boss Reward").access_rule = \
lambda state: has_vendors(state, player)

# Gate each manor location so everything isn't dumped into sphere 1.
manor_rules = {
"Defeat Khidr" if multiworld.khidr[player] == "vanilla" else "Defeat Neo Khidr": [
"Defeat Khidr" if world.options.khidr == "vanilla" else "Defeat Neo Khidr": [
"Manor - Left Wing Window",
"Manor - Left Wing Rooftop",
"Manor - Right Wing Window",
Expand All @@ -66,7 +70,7 @@ def set_rules(multiworld: MultiWorld, player: int):
"Manor - Left Tree 2",
"Manor - Right Tree",
],
"Defeat Alexander" if multiworld.alexander[player] == "vanilla" else "Defeat Alexander IV": [
"Defeat Alexander" if world.options.alexander == "vanilla" else "Defeat Alexander IV": [
"Manor - Left Big Upper 1",
"Manor - Left Big Upper 2",
"Manor - Left Big Windows",
Expand All @@ -78,7 +82,7 @@ def set_rules(multiworld: MultiWorld, player: int):
"Manor - Right Big Rooftop",
"Manor - Right Extension",
],
"Defeat Ponce de Leon" if multiworld.leon[player] == "vanilla" else "Defeat Ponce de Freon": [
"Defeat Ponce de Leon" if world.options.leon == "vanilla" else "Defeat Ponce de Freon": [
"Manor - Right High Base",
"Manor - Right High Upper",
"Manor - Right High Tower",
Expand All @@ -90,24 +94,24 @@ def set_rules(multiworld: MultiWorld, player: int):
# Set rules for manor locations.
for event, locations in manor_rules.items():
for location in locations:
multiworld.get_location(location, player).access_rule = lambda state: state.has(event, player)
world.get_location(location).access_rule = lambda state: state.has(event, player)

# Set rules for fairy chests to decrease headache of expectation to find non-movement fairy chests.
for fairy_location in [location for location in multiworld.get_locations(player) if "Fairy" in location.name]:
for fairy_location in [location for location in world.multiworld.get_locations(player) if "Fairy" in location.name]:
fairy_location.access_rule = lambda state: has_fairy_progression(state, player)

# Region rules.
multiworld.get_entrance("Forest Abkhazia", player).access_rule = \
lambda state: has_upgrades_percentage(state, player, 12.5) and has_defeated_castle(state, player)
world.get_entrance("Forest Abkhazia").access_rule = \
lambda state: has_upgrades_percentage(state, world, 12.5) and has_defeated_castle(state, player)

multiworld.get_entrance("The Maya", player).access_rule = \
lambda state: has_upgrades_percentage(state, player, 25) and has_defeated_forest(state, player)
world.get_entrance("The Maya").access_rule = \
lambda state: has_upgrades_percentage(state, world, 25) and has_defeated_forest(state, player)

multiworld.get_entrance("Land of Darkness", player).access_rule = \
lambda state: has_upgrades_percentage(state, player, 37.5) and has_defeated_tower(state, player)
world.get_entrance("Land of Darkness").access_rule = \
lambda state: has_upgrades_percentage(state, world, 37.5) and has_defeated_tower(state, player)

multiworld.get_entrance("The Fountain Room", player).access_rule = \
lambda state: has_upgrades_percentage(state, player, 50) and has_defeated_dungeon(state, player)
world.get_entrance("The Fountain Room").access_rule = \
lambda state: has_upgrades_percentage(state, world, 50) and has_defeated_dungeon(state, player)

# Win condition.
multiworld.completion_condition[player] = lambda state: state.has("Defeat The Fountain", player)
world.multiworld.completion_condition[player] = lambda state: state.has("Defeat The Fountain", player)
Loading

0 comments on commit 6d6d35d

Please sign in to comment.