forked from ArchipelagoMW/Archipelago
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
861 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
from typing import Dict | ||
from .items import item_table | ||
from .locations import get_location_datas, EventId | ||
from .regions import create_regions_and_locations | ||
from BaseClasses import Tutorial, Item | ||
from .options import AM2R_options | ||
from worlds.AutoWorld import World, WebWorld | ||
|
||
|
||
class AM2RWeb(WebWorld): | ||
theme = "partyTime" | ||
tutorials = [Tutorial( | ||
"Multiworld Setup Guide", | ||
"A guide to setting up the Archipelago AM2R software on your computer. This guide covers single-player, multiworld, and related software.", | ||
"English", | ||
"setup_en.md", | ||
"setup/en", | ||
["Zed"] | ||
)] | ||
|
||
|
||
class AM2RWorld(World): | ||
""" | ||
AM2R is a remake of the classic Metroid 2 game for the Game Boy that tries its best to keep the feel | ||
of the original as well as filling in some gaps to more closely tie into Metroid Fusion and brings some | ||
items from there as well. | ||
""" | ||
game = "AM2R" | ||
option_definitions = options.AM2R_options | ||
web = AM2RWeb() | ||
|
||
item_name_to_id = items.item_name_to_id | ||
location_name_to_id = {location.name: location.code for location in get_location_datas(None, None)} | ||
|
||
item_name_groups = items.item_name_groups | ||
data_version = 0 | ||
|
||
def fill_slot_data(self) -> Dict[str, object]: | ||
return {name: getattr(self.multiworld, name)[self.player].value for name in self.option_definitions} | ||
|
||
def create_regions(self) -> None: | ||
create_regions_and_locations(self.multiworld, self.player) | ||
|
||
def create_item(self, name: str) -> Item: | ||
return items.create_item(self.player, name) | ||
|
||
def create_items(self) -> None: | ||
self.multiworld.get_location("The Last Metroid is in Captivity", self.player).place_locked_item(self.create_item("The Galaxy is at Peace")) | ||
items.create_all_items(self.multiworld, self.player) | ||
|
||
def set_rules(self) -> None: | ||
self.multiworld.completion_condition[self.player] = lambda state: state.has("The Galaxy is at Peace", self.player) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# AM2R Multiworld Beta (Text Adventure) | ||
## How to use | ||
There currently is no client to use this with | ||
|
||
|
||
Download and install the latest version of [Archipelago](https://github.com/ArchipelagoMW/Archipelago/releases) the `AM2R.apworld` from below. | ||
Once you have installed Archipelago you can take the `AM2R.apworld` and put it inside the `/lib/worlds` portion of your Archipelago install. | ||
From there to get a generic `AM2R.yaml` open the Archipelago Launcher and click the **Generate Template settings** which will add it to the template yaml folder in `/Players/Templates`. | ||
### Things are subject to change at developer discretion | ||
### Seeds should be beatable but its possible there are still logical errors | ||
## Bug Reporting | ||
If you are playing this mod and are encountering bugs **DO NOT** report them to the Archipelago server this is not offical support from them, and they may or may not know what to do instead you can report them to the dedicated mod thread on the [AM2R Server](https://discord.gg/YTQnkAJ) or on the [Modding Server](https://discord.gg/Fdq3MSXEDb) and you can always open an issue on the github. | ||
### Help I found a problem with 100% trap fill playing on fusion mode | ||
Fuck you Abyss said it was possible, and I was there. | ||
|
||
## Randomizer Information | ||
### What is randomized? | ||
All items both majors and minors are randomized together in one pool with the option to add in the metroids as checks as well. | ||
### What is the goal? | ||
The goal of this AM2R randomizer implementation is to collect kill or collect the self specified number of metroids to reach the deep caves and then a few more to get into the lab and fight the queen metroid. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# AM2R Archipelago Setup Guide | ||
|
||
## Required Software | ||
[comment]: <> (Change this reference before release) | ||
- [AM2R Multiworld Mod](https://github.com/Ehseezed/Amalgam) | ||
- [AM2R Launcher](https://github.com/AM2R-Community-Developers/AM2RLauncher/releases) | ||
- Your copy of AM2R 1.1 for the launcher | ||
|
||
## Installation Process | ||
|
||
Download the latest release of [AM2R Launcher](https://github.com/AM2R-Community-Developers/AM2RLauncher/releases) and | ||
then using your AM2R 1.1 set up the launcher once the launcher is set up you can install the mod |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import itertools | ||
from collections import Counter | ||
from typing import Dict, List, NamedTuple, Set | ||
|
||
from BaseClasses import Item, ItemClassification, MultiWorld | ||
from .options import MetroidsAreChecks, MetroidsRequired, get_option_value | ||
|
||
|
||
class ItemData(NamedTuple): | ||
code: int | ||
group: str | ||
classification: ItemClassification = ItemClassification.progression | ||
required_num: int = 0 | ||
|
||
|
||
class AM2RItem(Item): | ||
game: str = "AM2R" | ||
|
||
|
||
def create_item(player: int, name: str) -> Item: | ||
item_data = item_table[name] | ||
return AM2RItem(name, item_data.classification, item_data.code, player) | ||
|
||
|
||
def create_fixed_item_pool() -> List[str]: | ||
required_items: Dict[str, int] = {name: data.required_num for name, data in item_table.items()} | ||
return list(Counter(required_items).elements()) | ||
|
||
|
||
def create_metroid_items(MetroidsRequired: MetroidsRequired, MetroidsAreChecks: MetroidsAreChecks) -> List[str]: | ||
metroid_count = 0 | ||
if MetroidsAreChecks == MetroidsAreChecks.option_include_A6: | ||
metroid_count = MetroidsRequired.value + 5 | ||
elif MetroidsAreChecks == MetroidsAreChecks.option_exclude_A6: | ||
metroid_count += MetroidsRequired.value | ||
return ["Metroid" for _ in range(metroid_count)] | ||
|
||
|
||
def create_trap_items(multiworld: MultiWorld, player: int, locations_to_trap: int) -> List[str]: | ||
trap_pool = trap_weights.copy() | ||
|
||
return multiworld.random.choices( | ||
population=list(trap_pool.keys()), | ||
weights=list(trap_pool.values()), | ||
k=locations_to_trap | ||
) | ||
|
||
|
||
def create_random_items(multiworld: MultiWorld, player: int, random_count: int) -> List[str]: | ||
filler_pool = filler_weights.copy() | ||
|
||
return multiworld.random.choices( | ||
population=list(filler_pool.keys()), | ||
weights=list(filler_pool.values()), | ||
k=random_count | ||
) | ||
|
||
|
||
def create_all_items(multiworld: MultiWorld, player: int) -> None: | ||
sum_locations = len(multiworld.get_unfilled_locations(player)) | ||
|
||
itempool = ( | ||
create_fixed_item_pool() | ||
+ create_metroid_items(multiworld.MetroidsRequired[player], multiworld.MetroidsAreChecks[player]) | ||
) | ||
|
||
trap_percentage = get_option_value(multiworld, player, "TrapFillPercentage") | ||
trap_fill = trap_percentage / 100 | ||
|
||
random_count = sum_locations - len(itempool) | ||
locations_to_trap = int(trap_fill * random_count) | ||
itempool += create_trap_items(multiworld, player, locations_to_trap) | ||
|
||
random_count = sum_locations - len(itempool) | ||
itempool += create_random_items(multiworld, player, random_count) | ||
|
||
multiworld.itempool += [create_item(player, name) for name in itempool] | ||
|
||
|
||
item_table: Dict[str, ItemData] = { | ||
"Missile": ItemData(8678000, "Ammo", ItemClassification.filler), | ||
"Super Missile": ItemData(8678001, "Ammo", ItemClassification.progression, 1), | ||
"Power Bomb": ItemData(8678002, "Ammo", ItemClassification.progression, 2), | ||
"Energy Tank": ItemData(8678003, "Ammo", ItemClassification.filler, 1), | ||
# "Arm Cannon": ItemData8678004, ("Equipment", ItemClassification.progression, 1), | ||
# "Morph Ball": ItemData8678005, ("Equipment", ItemClassification.progression, 1), | ||
# "Power Grip": ItemData8678006, ("Equipment", ItemClassification.progression, 1), | ||
"Bombs": ItemData(8678007, "Equipment", ItemClassification.progression, 1), | ||
"Spider Ball": ItemData(8678008, "Equipment", ItemClassification.progression, 1), | ||
"Hi Jump": ItemData(8678009, "Equipment", ItemClassification.progression, 1), | ||
"Spring Ball": ItemData(8678010, "Equipment", ItemClassification.progression, 1), | ||
"Space Jump": ItemData(8678011, "Equipment", ItemClassification.progression, 1), | ||
"Speed Booster": ItemData(8678012, "Equipment", ItemClassification.progression, 1), | ||
"Screw Attack": ItemData(8678013, "Equipment", ItemClassification.progression, 1), | ||
"Varia Suit": ItemData(8678014, "Equipment", ItemClassification.useful, 1), | ||
"Gravity Suit": ItemData(8678015, "Equipment", ItemClassification.progression, 1), | ||
"Charge Beam": ItemData(8678016, "Beam", ItemClassification.useful, 1), | ||
"Wave Beam": ItemData(8678017, "Beam", ItemClassification.useful, 1), | ||
"Spazer": ItemData(8678018, "Beam", ItemClassification.useful, 1), | ||
"Plasma Beam": ItemData(8678019, "Beam", ItemClassification.useful, 1), | ||
"Ice Beam": ItemData(8678020, "Beam", ItemClassification.progression, 1), | ||
"Equipment Trap": ItemData(8678021, "Trap", ItemClassification.trap), | ||
"Freeze Trap": ItemData(8678022, "Trap", ItemClassification.trap), | ||
"Short Beam": ItemData(8678023, "Trap", ItemClassification.trap), | ||
"EMP Trap": ItemData(8678024, "Trap", ItemClassification.trap), | ||
"Metroid": ItemData(8678025, "MacGuffin", ItemClassification.progression_skip_balancing), | ||
"The Galaxy is at Peace": ItemData(8678026, "Victory", ItemClassification.progression) | ||
|
||
} | ||
|
||
filler_weights: Dict[str, int] = { | ||
"Missile": 44, | ||
"Super Missile": 10, | ||
"Power Bomb": 10, | ||
"Energy Tank": 10 | ||
} | ||
trap_weights: Dict[str, int] = { | ||
"Equipment Trap": 1, | ||
"Freeze Trap": 1, | ||
"Short Beam": 1, | ||
"EMP Trap": 1 | ||
} | ||
|
||
|
||
def get_item_group(item_name: str) -> str: | ||
return item_table[item_name].group | ||
|
||
|
||
def item_is_filler(item_name: str) -> bool: | ||
return item_table[item_name].classification == ItemClassification.filler | ||
|
||
|
||
def item_is_trap(item_name: str) -> bool: | ||
return item_table[item_name].classification == ItemClassification.trap | ||
|
||
|
||
trap_items: List[str] = list(filter(item_is_trap, item_table.keys())) | ||
filler_items: List[str] = list(filter(item_is_filler, item_table.keys())) | ||
|
||
item_name_to_id: Dict[str, int] = {name: data.code for name, data in item_table.items()} | ||
|
||
item_name_groups: Dict[str, Set[str]] = { | ||
group: set(item_names) for group, item_names in itertools.groupby(item_table, get_item_group) | ||
} |
Oops, something went wrong.