Skip to content

Commit

Permalink
Man I hate
Browse files Browse the repository at this point in the history
  • Loading branch information
Ehseezed committed Sep 26, 2024
1 parent 5c8e8cf commit 09fca08
Show file tree
Hide file tree
Showing 6 changed files with 307 additions and 178 deletions.
14 changes: 9 additions & 5 deletions worlds/am2r/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ class AM2RItemData(NamedTuple):
"Missile Launcher": AM2RItemData(ItemClassification.progression, 300, 0),

"Super Missile": AM2RItemData(ItemClassification.filler, 16, 0),
"Super Missile Launcher": AM2RItemData(ItemClassification.progression, 300, 0),
"Super Missile Launcher": AM2RItemData(ItemClassification.progression, 301, 0),

"Power Bomb": AM2RItemData(ItemClassification.filler, 18, 0),
"Power Bomb Launcher": AM2RItemData(ItemClassification.progression, 300, 0),
"Power Bomb Launcher": AM2RItemData(ItemClassification.progression, 302, 0),

"Energy Tank": AM2RItemData(ItemClassification.filler, 17, 0),

"Morph Ball": AM2RItemData(ItemClassification.progression, 300, 0),
"Power Grip": AM2RItemData(ItemClassification.progression, 300, 0),
"Morph Ball": AM2RItemData(ItemClassification.progression, 303, 0),
"Power Grip": AM2RItemData(ItemClassification.progression, 304, 0),
"Bombs": AM2RItemData(ItemClassification.progression, 0, 1),
"Spider Ball": AM2RItemData(ItemClassification.progression, 2, 1),
"Hi Jump": AM2RItemData(ItemClassification.progression, 4, 1),
Expand All @@ -38,7 +38,7 @@ class AM2RItemData(NamedTuple):
"Varia Suit": AM2RItemData(ItemClassification.progression, 5, 1),
"Gravity Suit": AM2RItemData(ItemClassification.progression, 9, 1),

"Arm Cannon": AM2RItemData(ItemClassification.progression, 300, 0),
"Arm Cannon": AM2RItemData(ItemClassification.progression, 305, 0),
"Charge Beam": AM2RItemData(ItemClassification.progression, 10, 1),
"Wave Beam": AM2RItemData(ItemClassification.useful, 12, 1),
"Spazer": AM2RItemData(ItemClassification.useful, 13, 1),
Expand All @@ -52,6 +52,10 @@ class AM2RItemData(NamedTuple):
"OHKO Trap": AM2RItemData(ItemClassification.trap, 25, 0),
"Touhou Trap": AM2RItemData(ItemClassification.trap, 26, 0),

"EMP": AM2RItemData(ItemClassification.event, None, 0), # todo: This will be made in init as a event not in items I just needed this down somewhere
"Tower Activation": AM2RItemData(ItemClassification.event, None, 0),
"Geothermal": AM2RItemData(ItemClassification.event, None, 0),

"Metroid": AM2RItemData(ItemClassification.progression_skip_balancing, 19, 0)

}
Expand Down
11 changes: 6 additions & 5 deletions worlds/am2r/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class AM2RLocationData(NamedTuple):
location_group: str = "region"


location_based_id = 8678000
location_based_id = 108678000

location_table: Dict[str, AM2RLocationData] = {
"Main Caves: Spider Ball Challenge Upper": AM2RLocationData("Main Caves", 53),
Expand Down Expand Up @@ -67,15 +67,16 @@ class AM2RLocationData(NamedTuple):
"Industrial Complex: Complex Side Tunnel": AM2RLocationData("Pre Industrial Complex", 200),
"Industrial Complex: Behind the Green Door": AM2RLocationData("Pre Industrial Complex", 212),
"Industrial Complex: Save Room": AM2RLocationData("Pre Industrial Complex", 203),
"Industrial Complex: Spazer Beam": AM2RLocationData("Pre Industrial Complex", 13),
"Industrial Complex: Sisyphus Spark": AM2RLocationData("Pre Industrial Complex", 204),
"Industrial Complex: Speed Booster": AM2RLocationData("Pre Industrial Complex", 7),

"Industrial Complex: Spazer Beam": AM2RLocationData("Complex Sand", 13),
"Industrial Complex: Sisyphus Spark": AM2RLocationData("Complex Sand", 204),
"Industrial Complex: Speed Booster": AM2RLocationData("Complex Sand", 7),

"Torizo Ascended: Boss": AM2RLocationData("Torizo Ascended", 6),

"Industrial Complex: Conveyor Belt Room": AM2RLocationData("Industrial Complex", 205),
"Industrial Complex: Doom Treadmill": AM2RLocationData("Industrial Complex", 201),
"Industrial Complex: Complex Hub Shinespark" AM2RLocationData("Industrial Complex", 208),
"Industrial Complex: Complex Hub Shinespark": AM2RLocationData("Industrial Complex", 208),
"Industrial Complex: Complex Hub in the Floor": AM2RLocationData("Industrial Complex", 207),
"Industrial Complex: Skippy Reward": AM2RLocationData("Industrial Complex", 206),

Expand Down
69 changes: 49 additions & 20 deletions worlds/am2r/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,45 @@
class LogicDificulty(Choice):
"""Easy: Assumes developer intended solutions and expects little to none trick knowledge and less than optimal use of ammos
Required Tricks: Simple single wall Wall-Jumps, Knowledge of the Low% Super Missile block in Distribution Center
Required Damage: Hydro Station Nest Vines with 2 E-Tanks
Expected Damage: Hydro Station Nest Vines with 2 E-Tanks
Normal: Assumes knowledge over the game and expects some trick knowledge
Required Tricks: Simple Morph Glides, tricky single wall Wall-Jumps, Knowledge of Shinesparks to reach areas
Required Damage: Hydro Nest Vines (1E), Doom Treadmill Spikes, Spikes to Patricia(A4 Right Side Zeta)"""
Expected Damage: Hydro Nest Vines (1E), Doom Treadmill Spikes, Spikes to Patricia (A4 Right Side Zeta)
Hard: Assumes great technical skill over the game and expects a lot of trick knowledge
Required Tricks:
Expected Damage: Any stated above, Various Spike wall-jumps, spike paths to the A4 gammas, A5 Spiky Trial
"""
display_name = "Logic Dificulty"
default = 0
option_easy = 0
option_normal = 1
option_hard = 2 # todo add hard mode definitions
# option_insane = 3 # Maybe someday (the druid difficulty)


class LocationSettings(Choice):
"""Chose what items you want in the pool
not including checks via the no_A6 will force them to be excluded
not adding Metroids will force them to be vanilla and will not randomize them into item locations
adding metroids but excluding A6 will leave the A6 and omega nest metroids vanilla but will leave the full amount in the pool"""
display_name = "Locations to Check"
default = 2
option_items_no_A6 = 0
option_items_and_A6 = 1
option_add_metroids_no_A6 = 2
option_add_metroids_and_A6 = 3


class AreaBehavior(Choice):
"""Chose how you want the areas to behave in the randomizer
Lava: Lava starts at the position allowing access to the Golden Temple with the lava going down upon receiving a percentage of the goal metroids
Standard: The only existing area blocker is the one preventing lab access
Area Randomizer: Enables the area randomizer behavior"""
display_name = "Area Behavior"
default = 1
option_lava = 0
option_standard = 1
option_area_rando = 2


class AmmoLogic(Choice):
Expand All @@ -29,6 +59,16 @@ class AmmoLogic(Choice):
alias_easy = 0


class ExpectedAmmoMultiplier(Range):
"""This value is used as a percentage based multiplier for the expected ammo count rounded up
100% is exactly enough ammo to kill an enemy without missing a shot
300% is 3 times the amount of ammo needed to kill an enemy"""
display_name = "Expected Ammo Multiplier"
range_start = 100
range_end = 250
default = 150


class MetroidsInPool(Range):
"""Chose how many Metroids are in the item pool"""
display_name = "Metroids in Pool"
Expand All @@ -45,19 +85,6 @@ class MetroidsRequired(Range):
default = 20


class LocationSettings(Choice):
"""Chose what items you want in the pool
not including checks via the no_A6 will force them to be excluded
not adding Metroids will force them to be vanilla and will not randomize them into item locations
adding metroids but excluding A6 will leave the A6 and omega nest metroids vanilla but will leave the full amount in the pool"""
display_name = "Locations to Check"
default = 2
option_items_no_A6 = 0
option_items_and_A6 = 1
option_add_metroids_no_A6 = 2
option_add_metroids_and_A6 = 3


class StartLocation(Toggle):
"""Randomize Starting Location"""
display_name = "Randomize Start Location"
Expand Down Expand Up @@ -124,12 +151,12 @@ class RemoveFloodTrap(Toggle):


class RemoveTossTrap(Toggle):
"""There is a pipebomb in your mailbox"""
"""Is there a pipebomb in your mailbox?"""
display_name = "Remove Toss Trap"


class RemoveShortBeam(Toggle):
"""Remove muscle memory trap"""
"""Remove short beam trap"""
display_name = "Remove Short Beam"


Expand All @@ -152,10 +179,12 @@ class RemoveOHKOTrap(Toggle):
class AM2ROptions(PerGameCommonOptions):
logic_dificulty: LogicDificulty
ammo_logic: AmmoLogic
metroids_required: MetroidsRequired
expected_ammo_multiplier: ExpectedAmmoMultiplier
location_settings: LocationSettings
start_location: StartLocation
area_rando: AreaRando
area_behavior: AreaBehavior
metroids_required: MetroidsRequired
# start_location: StartLocation
# area_rando: AreaRando
remove_power_grip: RemovePowerGrip
remove_morph_ball: RemoveMorphBall
remove_beam: RemoveBeam
Expand Down
157 changes: 25 additions & 132 deletions worlds/am2r/regions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Tuple, Dict, Set, Optional, Callable
from typing import Dict, Set


am2r_regions: Dict[str, Set[str]] = {
Expand All @@ -7,7 +7,9 @@
"GFS Thoth"},
"Lower Main Caves": {"The Tower", "Underwater Distribution Center", "Deep Caves"},
"GFS Thoth": {"Genesis"},
"Guardian": {"Golden Temple", "Golden Temple Nest"},
"Genesis": set(),
"Guardian": {"After Guardian"},
"After Guardian": {"Golden Temple", "Golden Temple Nest"},
"Golden Temple": set(),
"Golden Temple Nest": set(),
"First Alpha": set(),
Expand All @@ -16,7 +18,8 @@
"Arachnus": set(),
"Inner Hydro Station": set(),
"Industrial Complex Nest": {"Pre Industrial Complex"},
"Pre Industrial Complex": {"Industrial Complex", "Torizo Ascended"},
"Pre Industrial Complex": {"Complex Sand", "Torizo Ascended"},
"Complex Sand": {"Industrial Complex"}, # added sand region because of the new launchers option since beam only wont work to leave
"Torizo Ascended": set(),
"Industrial Complex": set(),
"Mines": set(),
Expand All @@ -25,133 +28,23 @@
"Tester Upper": {"Tester"},
"Tester": set(),
"Geothermal": set(),
""
"Underwater Distribution Center": {"EMP", "Serris", "Underwater Distro Connection"},
"EMP": {"Post EMP"},
"Post EMP": {"Pipe Hell BL"},
"Pipe Hell BL": {"Pipe Hell BR", "Pipe Hell L"},
"Pipe Hell BR": {"Pipe Hell L", "Pipe Hell R"},
"Pipe Hell L": {"Pipe Hell R", "Fast Travel"},
"Pipe Hell R": {"Screw Attack", "Underwater Distro Connection"},
"Serris": {"Ice Beam"},
"Ice Beam": set(),
"Underwater Distro Connection": {},
"Fast Travel": {"Golden Temple", "Complex Sand", "The Tower", "Gravity", "Underwater Distribution Center"},
"Gravity": {"Pipe Hell Outside"},
"Pipe Hell Outside": {"Pipe Hell R"},
"Screw Attack": set(),
"Deep Caves": {"Omega Nest"},
"Omega Nest": {"The Lab"},
"The Lab": {"Research Station"},
"Research Station": set()
}
# A5
connect(world, player, "Underwater Distribution Center", "EMP", logic.AM2R_can_bomb),
connect(world, player, "EMP", "Underwater Distribution Center", logic.AM2R_can_bomb),

connect(world, player, "Underwater Distribution Center", "Serris"),
connect(world, player, "Serris", "Underwater Distribution Center", lambda state: state.has("Gravity Suit", player)),

connect(world, player, "Ice Beam", "Serris"),
connect(world, player, "Serris", "Ice Beam", lambda state: state.has("Gravity Suit", player)),

# Pipe Hell Fuckery
connect(world, player, "EMP", "Pipe Hell BL"),
connect(world, player, "Pipe Hell BL", "EMP"),

connect(world, player, "Pipe Hell BL", "Pipe Hell BR"),
connect(world, player, "Pipe Hell BR", "Pipe Hell BL"),

connect(world, player, "Pipe Hell L", "Pipe Hell BL", lambda state: state.has("Screw Attack", player)),
connect(world, player, "Pipe Hell BL", "Pipe Hell L", lambda state: state.has("Screw Attack", player)),

connect(world, player, "Pipe Hell BR", "Pipe Hell L"),
connect(world, player, "Pipe Hell L", "Pipe Hell BR"),

connect(world, player, "Pipe Hell BR", "Pipe Hell R", lambda state: state.has("Screw Attack", player)),
connect(world, player, "Pipe Hell R", "Pipe Hell BR", lambda state: state.has("Screw Attack", player)),

connect(world, player, "Pipe Hell R", "Pipe Hell L", logic.AM2R_can_bomb),
connect(world, player, "Pipe Hell L", "Pipe Hell R", logic.AM2R_can_bomb),

connect(world, player, "Pipe Hell L", "Fast Travel", lambda state: state.has("Screw Attack", player)),
connect(world, player, "Fast Travel", "Pipe Hell L", lambda state: state.has("Screw Attack", player)),

connect(world, player, "Fast Travel", "Gravity", lambda state: state.has("Gravity Suit", player)), # one way transition due to crumbles

connect(world, player, "Fast Travel", "Underwater Distribution Center"),
connect(world, player, "Underwater Distribution Center", "Fast Travel", lambda state: state.can_reach("Fast Travel", "Region", player)),

connect(world, player, "Gravity", "Pipe Hell Outside", lambda state: state.has("Gravity Suit", player) and state.has("Space Jump", player)),
connect(world, player, "Pipe Hell Outside", "Gravity"),

connect(world, player, "Pipe Hell Outside", "Pipe Hell R", logic.AM2R_can_bomb),
connect(world, player, "Pipe Hell R", "Pipe Hell Outside", lambda state: state.can_reach("Pipe Hell Outside", "Region", player)),

connect(world, player, "Screw Attack", "Pipe Hell R", lambda state: state.has("Screw Attack", player) and logic.AM2R_can_schmove(state)),
connect(world, player, "Pipe Hell R", "Screw Attack", logic.AM2R_can_spider),

connect(world, player, "Underwater Distribution Center", "Underwater Distro Connection", lambda state: state.has("Ice Beam", player) or (state.has("Gravity Suit", player) and state.has("Speed Booster", player))),
connect(world, player, "Underwater Distro Connection", "Underwater Distribution Center", lambda state: state.has("Ice Beam", player) or (state.has("Gravity Suit", player) and state.has("Speed Booster", player))),

connect(world, player, "Underwater Distro Connection", "Pipe Hell R"),
connect(world, player, "Pipe Hell R", "Underwater Distro Connection", lambda state: state.has("Super Missile", player) or (state.has("Gravity Suit", player) and state.has("Speed Booster", player)))

connect(world, player, "Deep Caves", "Omega Nest")
connect(world, player, "Omega Nest", "Deep Caves")

connect(world, player, "Omega Nest", "The Lab", logic.AM2R_can_lab) # , logic.AM2R_can_lab
connect(world, player, "The Lab", "Omega Nest")

connect(world, player, "The Lab", "Research Station")


def throwIfAnyLocationIsNotAssignedToARegion(regions: List[Region], regionNames: Set[str]):
existingRegions: Set[str] = set()

for region in regions:
existingRegions.add(region.name)

if regionNames - existingRegions:
raise Exception(
"AM2R: the following regions are used in locations: {}, but no such region exists".format(
regionNames - existingRegions))


def create_location(player: int, location_data: LocationData, region: Region) -> Location:
location = Location(player, location_data.name, location_data.code, region)
location.access_rule = location_data.rule

if id is None:
location.event = True
location.locked = True

return location


def create_region(world: MultiWorld, player: int, locations_per_region: Dict[str, List[LocationData]],name: str) -> Region:
region = Region(name, player, world)

if name in locations_per_region:
for location_data in locations_per_region[name]:
location = create_location(player, location_data, region)
region.locations.append(location)

return region


def connect(world: MultiWorld, player: int, source: str, target: str,
rule: Optional[Callable[[CollectionState], bool]] = None):
sourceRegion = world.get_region(source, player)
targetRegion = world.get_region(target, player)

connection = Entrance(player, "", sourceRegion)

if rule:
connection.access_rule = rule

sourceRegion.exits.append(connection)
connection.connect(targetRegion)


def split_location_datas_per_region(locations: Tuple[LocationData, ...]) -> Dict[str, List[LocationData]]:
per_region: Dict[str, List[AM2RLocationData]] = {}

for location in locations:
per_region.setdefault(location.region, []).append(location)

return per_region

from typing import Dict, Set

snailiad_regions: Dict[str, Set[str]] = {
"Menu": {"Snail Town"},
"Snail Town": {"Mare Carelia", "Spiralis Silere", "Amastrida Abyssus", "Lux Lirata", "Shrine of Iris"},
"Mare Carelia": {"Spiralis Silere"},
"Spiralis Silere": {"Amastrida Abyssus"},
"Amastrida Abyssus": {"Lux Lirata"},
"Lux Lirata": set(),
"Shrine of Iris": set()
}
# todo: Have someone other than me verify this @(V)ariable
Loading

0 comments on commit 09fca08

Please sign in to comment.