Skip to content

Commit

Permalink
In Locations: added a general locations table that just combines all …
Browse files Browse the repository at this point in the history
…the existing ones.

In Logic: Added rudimentary combat logic.
In Options: Added final boss choice.
In Regions: Added Credits and edited victory requirements for non-Prime required seeds.
In Rules: Applied combat logic to Flaaghra, Thardus, and Omega Pirate.
Created init and added methods to generate item and location pools.
  • Loading branch information
Electro1512 committed Feb 27, 2024
1 parent 3ecb55d commit a31c234
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 12 deletions.
8 changes: 8 additions & 0 deletions worlds/metroidprime/Locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,11 @@ class MetroidPrimeLocation(Location):
'MC Plasma Processing': 5031198,
'MC Magmoor Workstation': 5031199
}

every_location = {
**chozo_location_table,
**phen_location_table,
**tallon_location_table,
**mines_location_table,
**magmoor_location_table
}
6 changes: 5 additions & 1 deletion worlds/metroidprime/Logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def prime_has_missiles(self, world: MultiWorld, player: int) -> bool:
def prime_has_missile_count(self, world: MultiWorld, player: int) -> int:
count = 0
if self.has({'Main Missile'}, player):
count = 1
count = 5
count += self.prog_items['Missile Expansion', player] * 5
return count

Expand All @@ -23,6 +23,10 @@ def prime_artifact_count(self, world: MultiWorld, player: int) -> int:
count += 1
return count

def prime_etank_count(self, world: MultiWorld, player: int) -> int:
count = 0
count += self.prog_items['Energy Tank', player]
return count
def prime_can_bomb(self, world: MultiWorld, player: int) -> bool:
return self.has({'Morph Ball', 'Morph Ball Bombs'})

Expand Down
18 changes: 15 additions & 3 deletions worlds/metroidprime/PrimeOptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import typing
from Options import Option, Toggle, Range, ItemDict, StartInventoryPool
from Options import Option, Toggle, Range, ItemDict, StartInventoryPool, Choice


class SpringBall(Toggle):
Expand All @@ -18,14 +18,26 @@ class RequiredArtifacts(Range):

class ExcludeItems(ItemDict):
"""Replaces the following items with filler. INPUT AT YOUR OWN RISK. I cannot promise that removing
progression items will not break logic."""
progression items will not break logic. (for now please leave the default starting items in)"""
verify_item_name = True
display_name = "Exclude Items"


class FinalBosses(Choice):
"""Determines the final bosses required to beat the seed. Choose from Meta Ridley, Metroid Prime,
both, or neither."""
display_name = "Final Boss Select"
option_both = 0
option_ridley = 1
option_prime = 2
option_none = 3
default = 0


metroidprime_options: typing.Dict[str, type(Option)] = {
"start_inventory_from_pool": StartInventoryPool,
"spring_ball": SpringBall,
"required_artifacts": RequiredArtifacts,
"exclude_items": ExcludeItems
"exclude_items": ExcludeItems,
"final_bosses": FinalBosses
}
31 changes: 26 additions & 5 deletions worlds/metroidprime/Regions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from Logic import MetroidPrimeLogic as logic
from BaseClasses import Region
import PrimeOptions
import Locations


Expand Down Expand Up @@ -31,6 +32,9 @@ def create_regions(self):
impact_crater = Region("Impact Crater", self.player, self.multiworld)
self.multiworld.regions.append(impact_crater)

mission_complete = Region("Mission Complete", self.player, self.multiworld)
self.multiworld.regions.append(mission_complete)

# entrances
menu.connect(tallon_overworld)

Expand All @@ -40,11 +44,24 @@ def create_regions(self):
logic.prime_can_heat(state, self.multiworld, self.player)))
tallon_overworld.connect(phazon_mines, "East Mines Elevator", lambda state: (
logic.prime_frigate(state, self.multiworld, self.player)))
tallon_overworld.connect(impact_crater, "Crater Access", lambda state: (
logic.prime_has_missiles(state, self.multiworld, self.player) and
(logic.prime_artifact_count(state, self.multiworld, self.player) == 12) and
state.has({"Wave Beam", "Ice Beam", "Plasma Beam", "Thermal Visor", "X-Ray Visor", "Phazon Suit",
"Space Jump Boots"}, self.player)))
if (PrimeOptions.metroidprime_options['final_bosses'] == 0 or
PrimeOptions.metroidprime_options['final_bosses'] == 2):
tallon_overworld.connect(impact_crater, "Crater Access", lambda state: (
logic.prime_has_missiles(state, self.multiworld, self.player) and
(logic.prime_artifact_count(state, self.multiworld, self.player) == 12) and
state.has({"Wave Beam", "Ice Beam", "Plasma Beam", "Thermal Visor", "X-Ray Visor", "Phazon Suit",
"Space Jump Boots"}, self.player) and
logic.prime_etank_count(state, self.multiworld, self.player) >= 8))
elif PrimeOptions.metroidprime_options['final_bosses'] == 1:
tallon_overworld.connect(mission_complete, "Mission Complete", lambda state: (
logic.prime_has_missiles(state, self.multiworld, self.player) and
(logic.prime_artifact_count(state, self.multiworld, self.player) == 12) and
(state.has({"Plasma Beam"}, self.player) or logic.prime_can_super(state, self.multiworld, self.player)) and
logic.prime_etank_count(state, self.multiworld, self.player) >= 8))
elif PrimeOptions.metroidprime_options['final_bosses'] == 3:
tallon_overworld.connect(mission_complete, "Mission Complete", lambda state: (
logic.prime_has_missiles(state, self.multiworld, self.player) and
(logic.prime_artifact_count(state, self.multiworld, self.player) == 12)))

chozo_ruins.connect(magmoor_caverns, "North Magmoor Elevator", lambda state: (
logic.prime_has_missiles(state, self.multiworld, self.player) and
Expand All @@ -56,3 +73,7 @@ def create_regions(self):
logic.prime_late_magmoor(state, self.multiworld, self.player)))
magmoor_caverns.connect(phazon_mines, "West Mines Elevator", lambda state: (
logic.prime_late_magmoor(state, self.multiworld, self.player) and state.has({"Ice Beam"}, self.player)))

if (PrimeOptions.metroidprime_options['final_bosses'] == 0 or
PrimeOptions.metroidprime_options['final_bosses'] == 2):
impact_crater.connect(mission_complete)
9 changes: 6 additions & 3 deletions worlds/metroidprime/Rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def set_rules(multiworld, player):
(logic.prime_can_bomb(state, multiworld, player) or
logic.prime_can_pb(state, multiworld, player))),
'CR Sunchamber - Flaaghra': lambda state: (logic.prime_has_missiles(state, multiworld, player) and
logic.prime_can_bomb(state, multiworld, player)),
logic.prime_can_bomb(state, multiworld, player) and
logic.prime_etank_count(state, multiworld, player) >= 1),
'CR Sunchamber - Ghosts': lambda state: (logic.prime_can_super(state, multiworld, player) and
logic.prime_can_bomb(state, multiworld, player) and
logic.prime_can_spider(state, multiworld, player)),
Expand Down Expand Up @@ -117,7 +118,8 @@ def set_rules(multiworld, player):
state.has({'Space Jump Boots'}, player))),
'PD Quarantine Cave': lambda state: (logic.prime_quarantine_cave(state, multiworld, player) and
logic.prime_can_spider(state, multiworld, player) and
state.has({'Thermal Visor'}, player)),
state.has({'Thermal Visor'}, player) and
logic.prime_etank_count(state, multiworld, player) >= 3),
'PD Research Lab Hydra': lambda state: (logic.prime_labs(state, multiworld, player) and
logic.prime_can_super(state, multiworld, player)),
'PD Quarantine Monitor': lambda state: (logic.prime_quarantine_cave(state, multiworld, player) and
Expand Down Expand Up @@ -236,7 +238,8 @@ def set_rules(multiworld, player):
'PM Processing Center Access': lambda state: (logic.prime_lower_mines(state, multiworld, player) and
state.has({'X-Ray Visor'}, player)),
'PM Elite Quarters': lambda state: (logic.prime_lower_mines(state, multiworld, player) and
state.has({'X-Ray Visor'}, player)),
state.has({'X-Ray Visor'}, player) and
logic.prime_etank_count(state, multiworld, player) >= 7),
'PM Central Dynamo': lambda state: (logic.prime_upper_mines(state, multiworld, player) and
logic.prime_can_bomb(state, multiworld, player) and
logic.prime_can_pb(state, multiworld, player) and
Expand Down
87 changes: 87 additions & 0 deletions worlds/metroidprime/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from BaseClasses import Item, MultiWorld, Tutorial, ItemClassification
from .Items import MetroidPrimeItem, suit_upgrade_table, artifact_table, item_table
from .PrimeOptions import metroidprime_options
from .Locations import every_location
from .Regions import create_regions
from worlds.AutoWorld import World

class MetroidPrimeWorld(World):
"""
Metroid Prime is a first-person action-adventure game originally for the Gamecube. Play as
the bounty hunter Samus Aran as she traverses the planet Tallon IV and uncovers the plans
of the Space Pirates.
"""
game: str = "Metroid Prime"
option_definitions = metroidprime_options
item_name_to_id = {name: data.code for name, data in item_table.items()}
location_name_to_id = location_name_to_id = {loc_data.name: loc_data.id for loc_data in every_location}

def generate_early(self):
reqarts = self.option_definitions['required_artifacts']
# starting inventory
self.multiworld.precollected_items += [self.create_item("Power Beam")]
self.multiworld.precollected_items += [self.create_item("Scan Visor")]
self.multiworld.precollected_items += [self.create_item("Combat Visor")]
self.multiworld.precollected_items += [self.create_item("Power Suit")]
artcount = 12
for i in artifact_table:
if artcount <= reqarts:
self.multiworld.precollected_items += [self.create_item(i)]
artcount -= 1

def create_regions(self) -> None:
create_regions(self)

def create_item(self, name: str) -> "Item":
createdthing = item_table[name]
return MetroidPrimeItem(name, createdthing.progression, createdthing.code, self.player)

def create_items(self) -> None:
# add remaining artifacts
reqarts = self.option_definitions['required_artifacts']
artcount = 12
for i in artifact_table:
if artcount >= reqarts:
self.multiworld.itempool += [self.create_item(i)]
artcount -= 1
excluded = self.option_definitions['excluded_items']
spring = self.option_definitions['spring_ball']
items_added = 0
for i in suit_upgrade_table:
if i == "Power Beam" or i == "Scan Visor" or i == "Power Suit" or i == "Combat Visor":
continue
elif i in excluded.keys():
continue
elif i == "Spring Ball" and spring:
self.multiworld.itempool += [self.create_item("Spring Ball")]
items_added += 1
continue
elif i == "Missile Expansion":
if spring:
self.multiworld.itempool += [self.create_item("Missile Expansion") for i in range(0, 49)]
items_added += 49
else:
self.multiworld.itempool += [self.create_item("Missile Expansion") for i in range(0, 50)]
items_added += 50
continue
elif i == "Energy Tank":
self.multiworld.itempool += [self.create_item("Energy Tank") for i in range(0, 14)]
items_added += 14
continue
elif i == "Ice Trap":
continue
elif i == "Power Bomb Expansion":
self.multiworld.itempool += [self.create_item("Power Bomb Expansion") for i in range(0, 4)]
items_added += 4
else:
self.multiworld.itempool += [self.create_item(i)]
items_added += 1
# add missiles as extra filler
while 100 - items_added > 0:
self.multiworld.itempool += [self.create_item("Missile Expansion")]






0 comments on commit a31c234

Please sign in to comment.