diff --git a/worlds/ladx/Items.py b/worlds/ladx/Items.py index e36a589c..d52eb771 100644 --- a/worlds/ladx/Items.py +++ b/worlds/ladx/Items.py @@ -32,12 +32,16 @@ class DungeonItemData(ItemData): s = self.ladxr_id[:-1] return DungeonItemType.__dict__[s] + class TradeItemData(ItemData): vanilla_location = None + def __new__(cls, item_name, ladxr_id, classification, vanilla_location): self = super(ItemData, cls).__new__(cls, (item_name, ladxr_id, classification)) self.vanilla_location = vanilla_location return self + + class LinksAwakeningItem(Item): game: str = Common.LINKS_AWAKENING @@ -49,6 +53,7 @@ class LinksAwakeningItem(Item): super().__init__(item_data.item_name, classification, Common.BASE_ID + item_data.item_id, player) self.item_data = item_data + # TODO: use _NAMES instead? class ItemName: POWER_BRACELET = "Progressive Power Bracelet" diff --git a/worlds/ladx/Locations.py b/worlds/ladx/Locations.py index 69eb78dd..61e46fc0 100644 --- a/worlds/ladx/Locations.py +++ b/worlds/ladx/Locations.py @@ -1,12 +1,11 @@ -from BaseClasses import Region, Entrance, Location -from worlds.AutoWorld import LogicMixin +from BaseClasses import Region, Entrance, Location, CollectionState from .LADXR.checkMetadata import checkMetadataTable from .Common import * from worlds.generic.Rules import add_item_rule -from .Items import ladxr_item_to_la_item_name, ItemName, LinksAwakeningItem -from .LADXR.locations.tradeSequence import TradeRequirements, TradeSequenceItem +from .Items import ladxr_item_to_la_item_name + prefilled_events = ["ANGLER_KEYHOLE", "RAFT", "MEDICINE2", "CASTLE_BUTTON"] @@ -80,27 +79,19 @@ class LinksAwakeningLocation(Location): add_item_rule(self, filter_item) -def has_free_weapon(state: "CollectionState", player: int) -> bool: +def has_free_weapon(state: CollectionState, player: int) -> bool: return state.has("Progressive Sword", player) or state.has("Magic Rod", player) or state.has("Boomerang", player) or state.has("Hookshot", player) + # If the player has access to farm enough rupees to afford a game, we assume that they can keep beating the game -def can_farm_rupees(state: "CollectionState", player: int) -> bool: +def can_farm_rupees(state: CollectionState, player: int) -> bool: return has_free_weapon(state, player) and (state.has("Can Play Trendy Game", player=player) or state.has("RAFT", player=player)) -class LinksAwakeningLogic(LogicMixin): - rupees = { - ItemName.RUPEES_20: 0, - ItemName.RUPEES_50: 0, - ItemName.RUPEES_100: 100, - ItemName.RUPEES_200: 200, - ItemName.RUPEES_500: 500, - } - - def get_credits(self, player: int): - if can_farm_rupees(self, player): - return 999999999 - return sum(self.count(item_name, player) * amount for item_name, amount in self.rupees.items()) +def get_credits(state: CollectionState, player: int): + if can_farm_rupees(state, player): + return 999999999 + return state.prog_items["RUPEES", player] class LinksAwakeningRegion(Region): @@ -137,7 +128,7 @@ class GameStateAdapater: def get(self, item, default): if item == "RUPEES": - return self.state.get_credits(self.player) + return get_credits(self.state, self.player) elif item.endswith("_USED"): return 0 else: diff --git a/worlds/ladx/__init__.py b/worlds/ladx/__init__.py index b30919a8..e45d9c01 100644 --- a/worlds/ladx/__init__.py +++ b/worlds/ladx/__init__.py @@ -1,6 +1,5 @@ import binascii import bsdiff4 -import itertools import os import pkgutil import tempfile @@ -12,7 +11,7 @@ from worlds.AutoWorld import WebWorld, World from .Common import * from .Items import (DungeonItemData, DungeonItemType, LinksAwakeningItem, TradeItemData, ladxr_item_to_la_item_name, links_awakening_items, - links_awakening_items_by_name) + links_awakening_items_by_name, ItemName) from .LADXR import generator from .LADXR.itempool import ItemPool as LADXRItemPool from .LADXR.logic import Logic as LAXDRLogic @@ -29,6 +28,7 @@ from .Rom import LADXDeltaPatch DEVELOPER_MODE = False + class LinksAwakeningWebWorld(WebWorld): tutorials = [Tutorial( "Multiworld Setup Guide", @@ -45,7 +45,7 @@ class LinksAwakeningWorld(World): After a previous adventure, Link is stranded on Koholint Island, full of mystery and familiar faces. Gather the 8 Instruments of the Sirens to wake the Wind Fish, so that Link can go home! """ - game: str = LINKS_AWAKENING # name of the game/world + game = LINKS_AWAKENING # name of the game/world web = LinksAwakeningWebWorld() option_definitions = links_awakening_options # options the player can set @@ -82,6 +82,14 @@ class LinksAwakeningWorld(World): player_options = None + rupees = { + ItemName.RUPEES_20: 0, + ItemName.RUPEES_50: 0, + ItemName.RUPEES_100: 100, + ItemName.RUPEES_200: 200, + ItemName.RUPEES_500: 500, + } + def convert_ap_options_to_ladxr_logic(self): self.player_options = { option: getattr(self.multiworld, option)[self.player] for option in self.option_definitions @@ -95,7 +103,6 @@ class LinksAwakeningWorld(World): self.ladxr_logic = LAXDRLogic(configuration_options=self.laxdr_options, world_setup=world_setup) self.ladxr_itempool = LADXRItemPool(self.ladxr_logic, self.laxdr_options, self.multiworld.random).toDict() - def create_regions(self) -> None: # Initialize self.convert_ap_options_to_ladxr_logic() @@ -401,9 +408,6 @@ class LinksAwakeningWorld(World): return "TRADING_ITEM_LETTER" - - - def generate_output(self, output_directory: str): # copy items back to locations for r in self.multiworld.get_regions(self.player): @@ -464,9 +468,8 @@ class LinksAwakeningWorld(World): bsdiff4.file_patch_inplace(out_path, title_patch.name) os.unlink(title_patch.name) - patch = LADXDeltaPatch(os.path.splitext(out_path)[0]+LADXDeltaPatch.patch_file_ending, player=self.player, - player_name=self.multiworld.player_name[self.player], patched_path=out_path) + player_name=self.multiworld.player_name[self.player], patched_path=out_path) patch.write() if not DEVELOPER_MODE: os.unlink(out_path) @@ -475,4 +478,20 @@ class LinksAwakeningWorld(World): return bytearray(self.multiworld.random.getrandbits(8) for _ in range(10)) + self.player.to_bytes(2, 'big') def modify_multidata(self, multidata: dict): - multidata["connect_names"][binascii.hexlify(self.multi_key).decode()] = multidata["connect_names"][self.multiworld.player_name[self.player]] \ No newline at end of file + multidata["connect_names"][binascii.hexlify(self.multi_key).decode()] = multidata["connect_names"][self.multiworld.player_name[self.player]] + + def collect(self, state, item: Item) -> bool: + change = super().collect(state, item) + if change: + rupees = self.rupees.get(item.name, 0) + state.prog_items["RUPEES", item.player] += rupees + + return change + + def remove(self, state, item: Item) -> bool: + change = super().remove(state, item) + if change: + rupees = self.rupees.get(item.name, 0) + state.prog_items["RUPEES", item.player] -= rupees + + return change