Rogue Legacy: More refactoring and clean up. (#1297)
* Rogue Legacy: More refactoring and clean up. * Also marked Blacksmith as Progression as it's used in a rule. * Remove extra newline. * Prevent divide by zero type error. * Scratch last commit, got the math mixed in my head. * Clarified name of rule regarding percentage of stat upgrades. * Move early vendors/architect creation into `create_items` logic. * Rename parameter in `create_region`. * Rename local var in `create_region`. * Removed accidental links in Markdown docs. * Refactor `create_region` signature and caller. * Remove redundant if-else. * Revert change to if-else, and moved item_pool to function instead of obj var. * Rename LegacyLogic to RLLogic. * Remove LogicMixin for rules.
This commit is contained in:
parent
2cc03d003a
commit
82444229be
|
@ -14,10 +14,6 @@ class RLItemData(NamedTuple):
|
||||||
max_quantity: int = 1
|
max_quantity: int = 1
|
||||||
weight: int = 1
|
weight: int = 1
|
||||||
|
|
||||||
@property
|
|
||||||
def is_event_item(self):
|
|
||||||
return self.code is None
|
|
||||||
|
|
||||||
|
|
||||||
def get_items_by_category(category: str) -> Dict[str, RLItemData]:
|
def get_items_by_category(category: str) -> Dict[str, RLItemData]:
|
||||||
item_dict: Dict[str, RLItemData] = {}
|
item_dict: Dict[str, RLItemData] = {}
|
||||||
|
@ -30,7 +26,7 @@ def get_items_by_category(category: str) -> Dict[str, RLItemData]:
|
||||||
|
|
||||||
item_table: Dict[str, RLItemData] = {
|
item_table: Dict[str, RLItemData] = {
|
||||||
# Vendors
|
# Vendors
|
||||||
"Blacksmith": RLItemData("Vendors", 90_000, ItemClassification.useful),
|
"Blacksmith": RLItemData("Vendors", 90_000, ItemClassification.progression),
|
||||||
"Enchantress": RLItemData("Vendors", 90_001, ItemClassification.progression),
|
"Enchantress": RLItemData("Vendors", 90_001, ItemClassification.progression),
|
||||||
"Architect": RLItemData("Vendors", 90_002, ItemClassification.useful),
|
"Architect": RLItemData("Vendors", 90_002, ItemClassification.useful),
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,6 @@ class RLLocationData(NamedTuple):
|
||||||
category: str
|
category: str
|
||||||
code: Optional[int] = None
|
code: Optional[int] = None
|
||||||
|
|
||||||
@property
|
|
||||||
def is_event_location(self):
|
|
||||||
return self.code is None
|
|
||||||
|
|
||||||
|
|
||||||
def get_locations_by_category(category: str) -> Dict[str, RLLocationData]:
|
def get_locations_by_category(category: str) -> Dict[str, RLLocationData]:
|
||||||
location_dict: Dict[str, RLLocationData] = {}
|
location_dict: Dict[str, RLLocationData] = {}
|
||||||
|
|
|
@ -1,31 +1,27 @@
|
||||||
from typing import Dict, List, NamedTuple, Optional
|
from typing import Dict, List, NamedTuple, Optional
|
||||||
|
|
||||||
from BaseClasses import MultiWorld, Region, RegionType, Entrance
|
from BaseClasses import MultiWorld, Region, RegionType, Entrance
|
||||||
from .Items import RLItem
|
|
||||||
from .Locations import RLLocation, location_table, get_locations_by_category
|
from .Locations import RLLocation, location_table, get_locations_by_category
|
||||||
|
|
||||||
|
|
||||||
class RLRegionData(NamedTuple):
|
class RLRegionData(NamedTuple):
|
||||||
locations: Optional[List[str]]
|
locations: Optional[List[str]]
|
||||||
exits: Optional[List[str]]
|
region_exits: Optional[List[str]]
|
||||||
|
|
||||||
|
|
||||||
def create_regions(multiworld: MultiWorld, player: int):
|
def create_regions(multiworld: MultiWorld, player: int):
|
||||||
regions: Dict[str, RLRegionData] = {
|
regions: Dict[str, RLRegionData] = {
|
||||||
"Menu": RLRegionData(None, ["Castle Hamson"]),
|
"Menu": RLRegionData(None, ["Castle Hamson"]),
|
||||||
"The Manor": RLRegionData([], []),
|
"The Manor": RLRegionData([], []),
|
||||||
"Castle Hamson": RLRegionData([], ["Forest Abkhazia",
|
"Castle Hamson": RLRegionData([], ["Forest Abkhazia", "The Maya", "Land of Darkness",
|
||||||
"The Maya",
|
"The Fountain Room", "The Manor"]),
|
||||||
"Land of Darkness",
|
|
||||||
"The Fountain Room",
|
|
||||||
"The Manor"]),
|
|
||||||
"Forest Abkhazia": RLRegionData([], []),
|
"Forest Abkhazia": RLRegionData([], []),
|
||||||
"The Maya": RLRegionData([], []),
|
"The Maya": RLRegionData([], []),
|
||||||
"Land of Darkness": RLRegionData([], []),
|
"Land of Darkness": RLRegionData([], []),
|
||||||
"The Fountain Room": RLRegionData([], None),
|
"The Fountain Room": RLRegionData([], None),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Diaries
|
# Artificially stagger diary spheres for progression.
|
||||||
for diary in range(0, 25):
|
for diary in range(0, 25):
|
||||||
region: str
|
region: str
|
||||||
if 0 <= diary < 6:
|
if 0 <= diary < 6:
|
||||||
|
@ -38,7 +34,6 @@ def create_regions(multiworld: MultiWorld, player: int):
|
||||||
region = "Land of Darkness"
|
region = "Land of Darkness"
|
||||||
else:
|
else:
|
||||||
region = "The Fountain Room"
|
region = "The Fountain Room"
|
||||||
|
|
||||||
regions[region].locations.append(f"Diary {diary + 1}")
|
regions[region].locations.append(f"Diary {diary + 1}")
|
||||||
|
|
||||||
# Manor & Special
|
# Manor & Special
|
||||||
|
@ -90,7 +85,7 @@ def create_regions(multiworld: MultiWorld, player: int):
|
||||||
|
|
||||||
# Set up the regions correctly.
|
# Set up the regions correctly.
|
||||||
for name, data in regions.items():
|
for name, data in regions.items():
|
||||||
multiworld.regions.append(create_region(multiworld, player, name, data.locations, data.exits))
|
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("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("The Manor", player).connect(multiworld.get_region("The Manor", player))
|
||||||
|
@ -100,24 +95,17 @@ def create_regions(multiworld: MultiWorld, player: int):
|
||||||
multiworld.get_entrance("The Fountain Room", player).connect(multiworld.get_region("The Fountain Room", player))
|
multiworld.get_entrance("The Fountain Room", player).connect(multiworld.get_region("The Fountain Room", player))
|
||||||
|
|
||||||
|
|
||||||
def create_region(multiworld: MultiWorld, player: int, name: str, locations=None, exits=None):
|
def create_region(multiworld: MultiWorld, player: int, name: str, data: RLRegionData):
|
||||||
ret = Region(name, RegionType.Generic, name, player)
|
region = Region(name, RegionType.Generic, name, player, multiworld)
|
||||||
ret.multiworld = multiworld
|
if data.locations:
|
||||||
if locations:
|
for loc_name in data.locations:
|
||||||
for loc_name in locations:
|
|
||||||
loc_data = location_table.get(loc_name)
|
loc_data = location_table.get(loc_name)
|
||||||
location = RLLocation(player, loc_name, loc_data.code if loc_data else None, ret)
|
location = RLLocation(player, loc_name, loc_data.code if loc_data else None, region)
|
||||||
|
region.locations.append(location)
|
||||||
|
|
||||||
# Special rule handling for fairy chests.
|
if data.region_exits:
|
||||||
if "Fairy" in loc_name:
|
for exit in data.region_exits:
|
||||||
location.access_rule = lambda state: state.has("Dragons", player) or (
|
entrance = Entrance(player, exit, region)
|
||||||
state.has("Enchantress", player) and (
|
region.exits.append(entrance)
|
||||||
state.has("Vault Runes", player) or
|
|
||||||
state.has("Sprint Runes", player) or
|
return region
|
||||||
state.has("Sky Runes", player)))
|
|
||||||
ret.locations.append(location)
|
|
||||||
if exits:
|
|
||||||
for exit in exits:
|
|
||||||
entrance = Entrance(player, exit, ret)
|
|
||||||
ret.exits.append(entrance)
|
|
||||||
return ret
|
|
||||||
|
|
|
@ -1,37 +1,61 @@
|
||||||
from BaseClasses import MultiWorld, CollectionState
|
from BaseClasses import MultiWorld, CollectionState
|
||||||
|
|
||||||
from ..AutoWorld import LogicMixin
|
|
||||||
from ..generic.Rules import set_rule
|
from ..generic.Rules import set_rule
|
||||||
|
|
||||||
|
|
||||||
class LegacyLogic(LogicMixin):
|
def get_upgrade_total(multiworld: MultiWorld, player: int) -> int:
|
||||||
def has_any_vendors(self: CollectionState, player: int) -> bool:
|
return int(multiworld.health_pool[player]) + int(multiworld.mana_pool[player]) + \
|
||||||
return self.has_any({"Blacksmith", "Enchantress"}, player)
|
int(multiworld.attack_pool[player]) + int(multiworld.magic_damage_pool[player])
|
||||||
|
|
||||||
def has_all_vendors(self: CollectionState, player: int) -> bool:
|
|
||||||
return self.has_all({"Blacksmith", "Enchantress"}, player)
|
|
||||||
|
|
||||||
def has_stat_upgrades(self, player: int, amount: int) -> bool:
|
def get_upgrade_count(state: CollectionState, player: int) -> int:
|
||||||
return self.stat_upgrade_count(player) >= amount
|
return state.item_count("Health Up", player) + state.item_count("Mana Up", player) + \
|
||||||
|
state.item_count("Attack Up", player) + state.item_count("Magic Damage Up", player)
|
||||||
|
|
||||||
def total_stat_upgrades_count(self, player: int) -> int:
|
|
||||||
return int(self.multiworld.health_pool[player]) + \
|
|
||||||
int(self.multiworld.mana_pool[player]) + \
|
|
||||||
int(self.multiworld.attack_pool[player]) + \
|
|
||||||
int(self.multiworld.magic_damage_pool[player])
|
|
||||||
|
|
||||||
def stat_upgrade_count(self: CollectionState, player: int) -> int:
|
def has_vendors(state: CollectionState, player: int) -> bool:
|
||||||
return self.item_count("Health Up", player) + self.item_count("Mana Up", player) + \
|
return state.has_all({"Blacksmith", "Enchantress"}, player)
|
||||||
self.item_count("Attack Up", player) + self.item_count("Magic Damage Up", player)
|
|
||||||
|
|
||||||
|
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, get_upgrade_total(state.multiworld, player) * (round(percentage) // 100))
|
||||||
|
|
||||||
|
|
||||||
|
def has_movement_rune(state: CollectionState, player: int) -> bool:
|
||||||
|
return state.has("Vault Runes", player) or state.has("Sprint Runes", player) or state.has("Sky Runes", player)
|
||||||
|
|
||||||
|
|
||||||
|
def has_fairy_progression(state: CollectionState, player: int) -> bool:
|
||||||
|
return state.has("Dragons", player) or (state.has("Enchantress", player) and has_movement_rune(state, player))
|
||||||
|
|
||||||
|
|
||||||
|
def has_defeated_castle(state: CollectionState, player: int) -> bool:
|
||||||
|
return state.has("Defeat Khidr", player) or state.has("Defeat Neo Khidr", player)
|
||||||
|
|
||||||
|
|
||||||
|
def has_defeated_forest(state: CollectionState, player: int) -> bool:
|
||||||
|
return state.has("Defeat Alexander", player) or state.has("Defeat Alexander IV", player)
|
||||||
|
|
||||||
|
|
||||||
|
def has_defeated_tower(state: CollectionState, player: int) -> bool:
|
||||||
|
return state.has("Defeat Ponce de Leon", player) or state.has("Defeat Ponce de Freon", player)
|
||||||
|
|
||||||
|
|
||||||
|
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(multiworld: MultiWorld, player: int):
|
||||||
# Vendors
|
# If 'vendors' are 'normal', then expect it to show up in the first half(ish) of the spheres.
|
||||||
if multiworld.vendors[player] == "normal":
|
if multiworld.vendors[player] == "normal":
|
||||||
set_rule(multiworld.get_location("Forest Abkhazia Boss Reward", player),
|
set_rule(multiworld.get_location("Forest Abkhazia Boss Reward", player),
|
||||||
lambda state: state.has_all_vendors(player))
|
lambda state: has_vendors(state, player))
|
||||||
|
|
||||||
# Scale each manor location.
|
# Gate each manor location so everything isn't dumped into sphere 1.
|
||||||
manor_rules = {
|
manor_rules = {
|
||||||
"Defeat Khidr" if multiworld.khidr[player] == "vanilla" else "Defeat Neo Khidr": [
|
"Defeat Khidr" if multiworld.khidr[player] == "vanilla" else "Defeat Neo Khidr": [
|
||||||
"Manor - Left Wing Window",
|
"Manor - Left Wing Window",
|
||||||
|
@ -65,22 +89,27 @@ def set_rules(multiworld: MultiWorld, player: int):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set rules for manor locations.
|
||||||
for event, locations in manor_rules.items():
|
for event, locations in manor_rules.items():
|
||||||
for location in locations:
|
for location in locations:
|
||||||
set_rule(multiworld.get_location(location, player), lambda state: state.has(event, player))
|
set_rule(multiworld.get_location(location, player), lambda state: state.has(event, player))
|
||||||
|
|
||||||
# Standard Zone Progression
|
# Set rules for fairy chests to decrease headache of expectation to find non-movement fairy chests.
|
||||||
multiworld.get_entrance("Forest Abkhazia", player).access_rule = \
|
for fairy_location in [location for location in multiworld.get_locations(player) if "Fairy" in location.name]:
|
||||||
(lambda state: state.has_stat_upgrades(player, 0.125 * state.total_stat_upgrades_count(player)) and
|
set_rule(fairy_location, lambda state: has_fairy_progression(state, player))
|
||||||
(state.has("Defeat Khidr", player) or state.has("Defeat Neo Khidr", player)))
|
|
||||||
multiworld.get_entrance("The Maya", player).access_rule = \
|
|
||||||
(lambda state: state.has_stat_upgrades(player, 0.25 * state.total_stat_upgrades_count(player)) and
|
|
||||||
(state.has("Defeat Alexander", player) or state.has("Defeat Alexander IV", player)))
|
|
||||||
multiworld.get_entrance("Land of Darkness", player).access_rule = \
|
|
||||||
(lambda state: state.has_stat_upgrades(player, 0.375 * state.total_stat_upgrades_count(player)) and
|
|
||||||
(state.has("Defeat Ponce de Leon", player) or state.has("Defeat Ponce de Freon", player)))
|
|
||||||
multiworld.get_entrance("The Fountain Room", player).access_rule = \
|
|
||||||
(lambda state: state.has_stat_upgrades(player, 0.5 * state.total_stat_upgrades_count(player)) and
|
|
||||||
(state.has("Defeat Herodotus", player) or state.has("Defeat Astrodotus", 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)
|
||||||
|
|
||||||
|
multiworld.get_entrance("The Maya", player).access_rule = \
|
||||||
|
lambda state: has_upgrades_percentage(state, player, 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)
|
||||||
|
|
||||||
|
multiworld.get_entrance("The Fountain Room", player).access_rule = \
|
||||||
|
lambda state: has_upgrades_percentage(state, player, 50) and has_defeated_dungeon(state, player)
|
||||||
|
|
||||||
|
# Win condition.
|
||||||
multiworld.completion_condition[player] = lambda state: state.has("Defeat The Fountain", player)
|
multiworld.completion_condition[player] = lambda state: state.has("Defeat The Fountain", player)
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
traits = [
|
|
||||||
"Color Blind",
|
|
||||||
"Gay",
|
|
||||||
"Near-Sighted",
|
|
||||||
"Far-Sighted",
|
|
||||||
"Dyslexia",
|
|
||||||
"Gigantism",
|
|
||||||
"Dwarfism",
|
|
||||||
"Baldness",
|
|
||||||
"Endomorph",
|
|
||||||
"Ectomorph",
|
|
||||||
"Alzheimers",
|
|
||||||
"Dextrocardia",
|
|
||||||
"Coprolalia",
|
|
||||||
"ADHD",
|
|
||||||
"O.C.D.",
|
|
||||||
"Hypergonadism",
|
|
||||||
"Muscle Wk.",
|
|
||||||
"Stereo Blind",
|
|
||||||
"I.B.S.",
|
|
||||||
"Vertigo",
|
|
||||||
"Tunnel Vision",
|
|
||||||
"Ambilevous",
|
|
||||||
"P.A.D.",
|
|
||||||
"Alektorophobia",
|
|
||||||
"Hypochondriac",
|
|
||||||
"Dementia",
|
|
||||||
"Flexible",
|
|
||||||
"Eid. Mem.",
|
|
||||||
"Nostalgic",
|
|
||||||
"C.I.P.",
|
|
||||||
"Savant",
|
|
||||||
"The One",
|
|
||||||
"Clumsy",
|
|
||||||
"EHS",
|
|
||||||
"Glaucoma",
|
|
||||||
"Adopted",
|
|
||||||
]
|
|
|
@ -30,7 +30,7 @@ class RLWorld(World):
|
||||||
you. Every child is unique. One child might be colorblind, another might have vertigo-- they could even be a dwarf.
|
you. Every child is unique. One child might be colorblind, another might have vertigo-- they could even be a dwarf.
|
||||||
But that's OK, because no one is perfect, and you don't have to be to succeed.
|
But that's OK, because no one is perfect, and you don't have to be to succeed.
|
||||||
"""
|
"""
|
||||||
game: str = "Rogue Legacy"
|
game = "Rogue Legacy"
|
||||||
option_definitions = rl_options
|
option_definitions = rl_options
|
||||||
topology_present = True
|
topology_present = True
|
||||||
data_version = 4
|
data_version = 4
|
||||||
|
@ -40,158 +40,154 @@ class RLWorld(World):
|
||||||
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
||||||
location_name_to_id = {name: data.code for name, data in location_table.items()}
|
location_name_to_id = {name: data.code for name, data in location_table.items()}
|
||||||
|
|
||||||
item_pool: List[RLItem] = []
|
# TODO: Replace calls to this function with "options-dict", once that PR is completed and merged.
|
||||||
|
def get_setting(self, name: str):
|
||||||
def setting(self, name: str):
|
|
||||||
return getattr(self.multiworld, name)[self.player]
|
return getattr(self.multiworld, name)[self.player]
|
||||||
|
|
||||||
def fill_slot_data(self) -> dict:
|
def fill_slot_data(self) -> dict:
|
||||||
return {option_name: self.setting(option_name).value for option_name in rl_options}
|
return {option_name: self.get_setting(option_name).value for option_name in rl_options}
|
||||||
|
|
||||||
def generate_early(self):
|
def generate_early(self):
|
||||||
# Check validation of names.
|
# Check validation of names.
|
||||||
additional_lady_names = len(self.setting("additional_lady_names").value)
|
additional_lady_names = len(self.get_setting("additional_lady_names").value)
|
||||||
additional_sir_names = len(self.setting("additional_sir_names").value)
|
additional_sir_names = len(self.get_setting("additional_sir_names").value)
|
||||||
if not self.setting("allow_default_names"):
|
if not self.get_setting("allow_default_names"):
|
||||||
# Check for max_quantity.
|
if additional_lady_names < int(self.get_setting("number_of_children")):
|
||||||
if additional_lady_names < int(self.setting("number_of_children")):
|
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"allow_default_names is off, but not enough names are defined in additional_lady_names. "
|
f"allow_default_names is off, but not enough names are defined in additional_lady_names. "
|
||||||
f"Expected {int(self.setting('number_of_children'))}, Got {additional_lady_names}")
|
f"Expected {int(self.get_setting('number_of_children'))}, Got {additional_lady_names}")
|
||||||
|
|
||||||
if additional_sir_names < int(self.setting("number_of_children")):
|
if additional_sir_names < int(self.get_setting("number_of_children")):
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"allow_default_names is off, but not enough names are defined in additional_sir_names. "
|
f"allow_default_names is off, but not enough names are defined in additional_sir_names. "
|
||||||
f"Expected {int(self.setting('number_of_children'))}, Got {additional_sir_names}")
|
f"Expected {int(self.get_setting('number_of_children'))}, Got {additional_sir_names}")
|
||||||
|
|
||||||
if self.setting("vendors") == "early":
|
def create_items(self):
|
||||||
self.multiworld.local_early_items[self.player]["Blacksmith"] = 1
|
item_pool: List[RLItem] = []
|
||||||
self.multiworld.local_early_items[self.player]["Enchantress"] = 1
|
total_locations = len(self.multiworld.get_unfilled_locations(self.player))
|
||||||
|
|
||||||
if self.setting("architect") == "early":
|
|
||||||
self.multiworld.local_early_items[self.player]["Architect"] = 1
|
|
||||||
|
|
||||||
def generate_basic(self):
|
|
||||||
self.item_pool = []
|
|
||||||
total_locations = 64 + (self.setting("chests_per_zone") * 4) + (self.setting("fairy_chests_per_zone") * 4)
|
|
||||||
|
|
||||||
# Add items to item pool. Anything with a "continue" will not be added to the item pool.
|
|
||||||
for name, data in item_table.items():
|
for name, data in item_table.items():
|
||||||
quantity = data.max_quantity
|
quantity = data.max_quantity
|
||||||
|
|
||||||
# Architect
|
# Architect
|
||||||
if name == "Architect":
|
if name == "Architect":
|
||||||
if self.setting("architect") == "disabled":
|
if self.get_setting("architect") == "disabled":
|
||||||
continue
|
continue
|
||||||
if self.setting("architect") == "start_unlocked":
|
if self.get_setting("architect") == "start_unlocked":
|
||||||
self.multiworld.push_precollected(self.create_item(name))
|
self.multiworld.push_precollected(self.create_item(name))
|
||||||
continue
|
continue
|
||||||
|
if self.get_setting("architect") == "early":
|
||||||
|
self.multiworld.local_early_items[self.player]["Architect"] = 1
|
||||||
|
continue
|
||||||
|
|
||||||
# Blacksmith and Enchantress
|
# Blacksmith and Enchantress
|
||||||
if name == "Blacksmith" or name == "Enchantress":
|
if name == "Blacksmith" or name == "Enchantress":
|
||||||
if self.setting("vendors") == "start_unlocked":
|
if self.get_setting("vendors") == "start_unlocked":
|
||||||
self.multiworld.push_precollected(self.create_item(name))
|
self.multiworld.push_precollected(self.create_item(name))
|
||||||
continue
|
continue
|
||||||
|
if self.get_setting("vendors") == "early":
|
||||||
|
self.multiworld.local_early_items[self.player]["Blacksmith"] = 1
|
||||||
|
self.multiworld.local_early_items[self.player]["Enchantress"] = 1
|
||||||
|
continue
|
||||||
|
|
||||||
# Haggling
|
# Haggling
|
||||||
if name == "Haggling" and self.setting("disable_charon"):
|
if name == "Haggling" and self.get_setting("disable_charon"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Blueprints
|
# Blueprints
|
||||||
if data.category == "Blueprints":
|
if data.category == "Blueprints":
|
||||||
# No progressive blueprints if progressive_blueprints are disabled.
|
# No progressive blueprints if progressive_blueprints are disabled.
|
||||||
if name == "Progressive Blueprints" and not self.setting("progressive_blueprints"):
|
if name == "Progressive Blueprints" and not self.get_setting("progressive_blueprints"):
|
||||||
continue
|
continue
|
||||||
# No distinct blueprints if progressive_blueprints are enabled.
|
# No distinct blueprints if progressive_blueprints are enabled.
|
||||||
elif name != "Progressive Blueprints" and self.setting("progressive_blueprints"):
|
elif name != "Progressive Blueprints" and self.get_setting("progressive_blueprints"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Classes
|
# Classes
|
||||||
if data.category == "Classes":
|
if data.category == "Classes":
|
||||||
if name == "Progressive Knights":
|
if name == "Progressive Knights":
|
||||||
if "Knight" not in self.setting("available_classes"):
|
if "Knight" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "knight":
|
if self.get_setting("starting_class") == "knight":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Progressive Mages":
|
if name == "Progressive Mages":
|
||||||
if "Mage" not in self.setting("available_classes"):
|
if "Mage" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "mage":
|
if self.get_setting("starting_class") == "mage":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Progressive Barbarians":
|
if name == "Progressive Barbarians":
|
||||||
if "Barbarian" not in self.setting("available_classes"):
|
if "Barbarian" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "barbarian":
|
if self.get_setting("starting_class") == "barbarian":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Progressive Knaves":
|
if name == "Progressive Knaves":
|
||||||
if "Knave" not in self.setting("available_classes"):
|
if "Knave" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "knave":
|
if self.get_setting("starting_class") == "knave":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Progressive Miners":
|
if name == "Progressive Miners":
|
||||||
if "Miner" not in self.setting("available_classes"):
|
if "Miner" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "miner":
|
if self.get_setting("starting_class") == "miner":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Progressive Shinobis":
|
if name == "Progressive Shinobis":
|
||||||
if "Shinobi" not in self.setting("available_classes"):
|
if "Shinobi" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "shinobi":
|
if self.get_setting("starting_class") == "shinobi":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Progressive Liches":
|
if name == "Progressive Liches":
|
||||||
if "Lich" not in self.setting("available_classes"):
|
if "Lich" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "lich":
|
if self.get_setting("starting_class") == "lich":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Progressive Spellthieves":
|
if name == "Progressive Spellthieves":
|
||||||
if "Spellthief" not in self.setting("available_classes"):
|
if "Spellthief" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.setting("starting_class") == "spellthief":
|
if self.get_setting("starting_class") == "spellthief":
|
||||||
quantity = 1
|
quantity = 1
|
||||||
if name == "Dragons":
|
if name == "Dragons":
|
||||||
if "Dragon" not in self.setting("available_classes"):
|
if "Dragon" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
if name == "Traitors":
|
if name == "Traitors":
|
||||||
if "Traitor" not in self.setting("available_classes"):
|
if "Traitor" not in self.get_setting("available_classes"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Skills
|
# Skills
|
||||||
if name == "Health Up":
|
if name == "Health Up":
|
||||||
quantity = self.setting("health_pool")
|
quantity = self.get_setting("health_pool")
|
||||||
elif name == "Mana Up":
|
elif name == "Mana Up":
|
||||||
quantity = self.setting("mana_pool")
|
quantity = self.get_setting("mana_pool")
|
||||||
elif name == "Attack Up":
|
elif name == "Attack Up":
|
||||||
quantity = self.setting("attack_pool")
|
quantity = self.get_setting("attack_pool")
|
||||||
elif name == "Magic Damage Up":
|
elif name == "Magic Damage Up":
|
||||||
quantity = self.setting("magic_damage_pool")
|
quantity = self.get_setting("magic_damage_pool")
|
||||||
elif name == "Armor Up":
|
elif name == "Armor Up":
|
||||||
quantity = self.setting("armor_pool")
|
quantity = self.get_setting("armor_pool")
|
||||||
elif name == "Equip Up":
|
elif name == "Equip Up":
|
||||||
quantity = self.setting("equip_pool")
|
quantity = self.get_setting("equip_pool")
|
||||||
elif name == "Crit Chance Up":
|
elif name == "Crit Chance Up":
|
||||||
quantity = self.setting("crit_chance_pool")
|
quantity = self.get_setting("crit_chance_pool")
|
||||||
elif name == "Crit Damage Up":
|
elif name == "Crit Damage Up":
|
||||||
quantity = self.setting("crit_damage_pool")
|
quantity = self.get_setting("crit_damage_pool")
|
||||||
|
|
||||||
# Ignore filler, it will be added in a later stage.
|
# Ignore filler, it will be added in a later stage.
|
||||||
if data.category == "Filler":
|
if data.category == "Filler":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.item_pool += [self.create_item(name) for _ in range(0, quantity)]
|
item_pool += [self.create_item(name) for _ in range(0, quantity)]
|
||||||
|
|
||||||
# Fill any empty locations with filler items.
|
# Fill any empty locations with filler items.
|
||||||
while len(self.item_pool) < total_locations:
|
while len(item_pool) < total_locations:
|
||||||
self.item_pool.append(self.create_item(self.get_filler_item_name()))
|
item_pool.append(self.create_item(self.get_filler_item_name()))
|
||||||
|
|
||||||
self.multiworld.itempool += self.item_pool
|
self.multiworld.itempool += item_pool
|
||||||
|
|
||||||
def get_filler_item_name(self) -> str:
|
def get_filler_item_name(self) -> str:
|
||||||
fillers = get_items_by_category("Filler")
|
fillers = get_items_by_category("Filler")
|
||||||
|
@ -219,7 +215,7 @@ class RLWorld(World):
|
||||||
self.create_event("Defeat The Fountain"))
|
self.create_event("Defeat The Fountain"))
|
||||||
|
|
||||||
# Khidr / Neo Khidr
|
# Khidr / Neo Khidr
|
||||||
if self.setting("khidr") == "vanilla":
|
if self.get_setting("khidr") == "vanilla":
|
||||||
self.multiworld.get_location("Castle Hamson Boss Room", self.player).place_locked_item(
|
self.multiworld.get_location("Castle Hamson Boss Room", self.player).place_locked_item(
|
||||||
self.create_event("Defeat Khidr"))
|
self.create_event("Defeat Khidr"))
|
||||||
else:
|
else:
|
||||||
|
@ -227,7 +223,7 @@ class RLWorld(World):
|
||||||
self.create_event("Defeat Neo Khidr"))
|
self.create_event("Defeat Neo Khidr"))
|
||||||
|
|
||||||
# Alexander / Alexander IV
|
# Alexander / Alexander IV
|
||||||
if self.setting("alexander") == "vanilla":
|
if self.get_setting("alexander") == "vanilla":
|
||||||
self.multiworld.get_location("Forest Abkhazia Boss Room", self.player).place_locked_item(
|
self.multiworld.get_location("Forest Abkhazia Boss Room", self.player).place_locked_item(
|
||||||
self.create_event("Defeat Alexander"))
|
self.create_event("Defeat Alexander"))
|
||||||
else:
|
else:
|
||||||
|
@ -235,7 +231,7 @@ class RLWorld(World):
|
||||||
self.create_event("Defeat Alexander IV"))
|
self.create_event("Defeat Alexander IV"))
|
||||||
|
|
||||||
# Ponce de Leon / Ponce de Freon
|
# Ponce de Leon / Ponce de Freon
|
||||||
if self.setting("leon") == "vanilla":
|
if self.get_setting("leon") == "vanilla":
|
||||||
self.multiworld.get_location("The Maya Boss Room", self.player).place_locked_item(
|
self.multiworld.get_location("The Maya Boss Room", self.player).place_locked_item(
|
||||||
self.create_event("Defeat Ponce de Leon"))
|
self.create_event("Defeat Ponce de Leon"))
|
||||||
else:
|
else:
|
||||||
|
@ -243,7 +239,7 @@ class RLWorld(World):
|
||||||
self.create_event("Defeat Ponce de Freon"))
|
self.create_event("Defeat Ponce de Freon"))
|
||||||
|
|
||||||
# Herodotus / Astrodotus
|
# Herodotus / Astrodotus
|
||||||
if self.setting("herodotus") == "vanilla":
|
if self.get_setting("herodotus") == "vanilla":
|
||||||
self.multiworld.get_location("Land of Darkness Boss Room", self.player).place_locked_item(
|
self.multiworld.get_location("Land of Darkness Boss Room", self.player).place_locked_item(
|
||||||
self.create_event("Defeat Herodotus"))
|
self.create_event("Defeat Herodotus"))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
## Where is the settings page?
|
## Where is the settings page?
|
||||||
|
|
||||||
The [player settings page for this game](../player-settings) contains most of the options you need to
|
The [player settings page for this game](../player-settings) contains most of the options you need to
|
||||||
configure and export a config file. Some settings can only be made via YAML, but an explaination can be found in the
|
configure and export a config file. Some settings can only be made in YAML, but an explanation can be found in the
|
||||||
[template yaml here](../../../static/generated/configs/Rogue%20Legacy.yaml).
|
[template yaml here](../../../static/generated/configs/Rogue%20Legacy.yaml).
|
||||||
|
|
||||||
## What does randomization do to this game?
|
## What does randomization do to this game?
|
||||||
|
@ -13,7 +13,6 @@ upgrade screen, bosses, and some special individual locations. The goal is to be
|
||||||
zone bosses and then defeat The Fountain.
|
zone bosses and then defeat The Fountain.
|
||||||
|
|
||||||
## What items and locations get shuffled?
|
## What items and locations get shuffled?
|
||||||
|
|
||||||
All the skill upgrades, class upgrades, runes packs, and equipment packs are shuffled in the manor upgrade screen, diary
|
All the skill upgrades, class upgrades, runes packs, and equipment packs are shuffled in the manor upgrade screen, diary
|
||||||
checks, chests and fairy chests, and boss rewards. Skill upgrades are also grouped in packs of 5 to make the finding of
|
checks, chests and fairy chests, and boss rewards. Skill upgrades are also grouped in packs of 5 to make the finding of
|
||||||
stats less of a chore. Runes and Equipment are also grouped together.
|
stats less of a chore. Runes and Equipment are also grouped together.
|
||||||
|
@ -24,7 +23,6 @@ Some additional locations that can contain items are the Jukebox, the Portraits,
|
||||||
|
|
||||||
Any of the items which can be shuffled may also be placed into another player's world. It is possible to choose to limit
|
Any of the items which can be shuffled may also be placed into another player's world. It is possible to choose to limit
|
||||||
certain items to your own world.
|
certain items to your own world.
|
||||||
|
|
||||||
## When the player receives an item, what happens?
|
## When the player receives an item, what happens?
|
||||||
|
|
||||||
When the player receives an item, your character will hold the item above their head and display it to the world. It's
|
When the player receives an item, your character will hold the item above their head and display it to the world. It's
|
||||||
|
|
|
@ -2,8 +2,14 @@
|
||||||
|
|
||||||
## Required Software
|
## Required Software
|
||||||
|
|
||||||
- Rogue Legacy Randomizer from
|
- Rogue Legacy Randomizer from the
|
||||||
the [Rogue Legacy Randomizer Releases Page](https://github.com/ThePhar/RogueLegacyRandomizer/releases)
|
[Rogue Legacy Randomizer Releases Page](https://github.com/ThePhar/RogueLegacyRandomizer/releases)
|
||||||
|
|
||||||
|
## Recommended Installation Instructions
|
||||||
|
|
||||||
|
Please read the README file on the
|
||||||
|
[Rogue Legacy Randomizer GitHub](https://github.com/ThePhar/RogueLegacyRandomizer/blob/master/README.md) page for
|
||||||
|
up-to-date installation instructions.
|
||||||
|
|
||||||
## Configuring your YAML file
|
## Configuring your YAML file
|
||||||
|
|
||||||
|
@ -27,9 +33,3 @@ provides an alternative one to the default values.
|
||||||
|
|
||||||
Once you have entered the required values, you go to Connect and then select Confirm on the "Ready to Start" screen. Now
|
Once you have entered the required values, you go to Connect and then select Confirm on the "Ready to Start" screen. Now
|
||||||
you're off to start your legacy!
|
you're off to start your legacy!
|
||||||
|
|
||||||
## Recommended Installation Instructions
|
|
||||||
|
|
||||||
Please read the README file on the
|
|
||||||
[Rogue Legacy Randomizer GitHub](https://github.com/ThePhar/RogueLegacyRandomizer/blob/master/README.md) page for up to
|
|
||||||
date installation instructions.
|
|
||||||
|
|
Loading…
Reference in New Issue