LADX: use custom collect/remove to keep track of logical rupee counts instead of LogixMixin

May contain some pep8, sorry
This commit is contained in:
Fabian Dill 2023-05-29 01:17:30 +02:00 committed by Fabian Dill
parent 845502ad39
commit b04b105bd8
3 changed files with 45 additions and 30 deletions

View File

@ -32,12 +32,16 @@ class DungeonItemData(ItemData):
s = self.ladxr_id[:-1] s = self.ladxr_id[:-1]
return DungeonItemType.__dict__[s] return DungeonItemType.__dict__[s]
class TradeItemData(ItemData): class TradeItemData(ItemData):
vanilla_location = None vanilla_location = None
def __new__(cls, item_name, ladxr_id, classification, vanilla_location): def __new__(cls, item_name, ladxr_id, classification, vanilla_location):
self = super(ItemData, cls).__new__(cls, (item_name, ladxr_id, classification)) self = super(ItemData, cls).__new__(cls, (item_name, ladxr_id, classification))
self.vanilla_location = vanilla_location self.vanilla_location = vanilla_location
return self return self
class LinksAwakeningItem(Item): class LinksAwakeningItem(Item):
game: str = Common.LINKS_AWAKENING 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) super().__init__(item_data.item_name, classification, Common.BASE_ID + item_data.item_id, player)
self.item_data = item_data self.item_data = item_data
# TODO: use _NAMES instead? # TODO: use _NAMES instead?
class ItemName: class ItemName:
POWER_BRACELET = "Progressive Power Bracelet" POWER_BRACELET = "Progressive Power Bracelet"

View File

@ -1,12 +1,11 @@
from BaseClasses import Region, Entrance, Location from BaseClasses import Region, Entrance, Location, CollectionState
from worlds.AutoWorld import LogicMixin
from .LADXR.checkMetadata import checkMetadataTable from .LADXR.checkMetadata import checkMetadataTable
from .Common import * from .Common import *
from worlds.generic.Rules import add_item_rule from worlds.generic.Rules import add_item_rule
from .Items import ladxr_item_to_la_item_name, ItemName, LinksAwakeningItem from .Items import ladxr_item_to_la_item_name
from .LADXR.locations.tradeSequence import TradeRequirements, TradeSequenceItem
prefilled_events = ["ANGLER_KEYHOLE", "RAFT", "MEDICINE2", "CASTLE_BUTTON"] prefilled_events = ["ANGLER_KEYHOLE", "RAFT", "MEDICINE2", "CASTLE_BUTTON"]
@ -80,27 +79,19 @@ class LinksAwakeningLocation(Location):
add_item_rule(self, filter_item) 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) 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 # 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)) return has_free_weapon(state, player) and (state.has("Can Play Trendy Game", player=player) or state.has("RAFT", player=player))
class LinksAwakeningLogic(LogicMixin): def get_credits(state: CollectionState, player: int):
rupees = { if can_farm_rupees(state, player):
ItemName.RUPEES_20: 0, return 999999999
ItemName.RUPEES_50: 0, return state.prog_items["RUPEES", player]
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())
class LinksAwakeningRegion(Region): class LinksAwakeningRegion(Region):
@ -137,7 +128,7 @@ class GameStateAdapater:
def get(self, item, default): def get(self, item, default):
if item == "RUPEES": if item == "RUPEES":
return self.state.get_credits(self.player) return get_credits(self.state, self.player)
elif item.endswith("_USED"): elif item.endswith("_USED"):
return 0 return 0
else: else:

View File

@ -1,6 +1,5 @@
import binascii import binascii
import bsdiff4 import bsdiff4
import itertools
import os import os
import pkgutil import pkgutil
import tempfile import tempfile
@ -12,7 +11,7 @@ from worlds.AutoWorld import WebWorld, World
from .Common import * from .Common import *
from .Items import (DungeonItemData, DungeonItemType, LinksAwakeningItem, TradeItemData, from .Items import (DungeonItemData, DungeonItemType, LinksAwakeningItem, TradeItemData,
ladxr_item_to_la_item_name, links_awakening_items, 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 import generator
from .LADXR.itempool import ItemPool as LADXRItemPool from .LADXR.itempool import ItemPool as LADXRItemPool
from .LADXR.logic import Logic as LAXDRLogic from .LADXR.logic import Logic as LAXDRLogic
@ -29,6 +28,7 @@ from .Rom import LADXDeltaPatch
DEVELOPER_MODE = False DEVELOPER_MODE = False
class LinksAwakeningWebWorld(WebWorld): class LinksAwakeningWebWorld(WebWorld):
tutorials = [Tutorial( tutorials = [Tutorial(
"Multiworld Setup Guide", "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. 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! 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() web = LinksAwakeningWebWorld()
option_definitions = links_awakening_options # options the player can set option_definitions = links_awakening_options # options the player can set
@ -82,6 +82,14 @@ class LinksAwakeningWorld(World):
player_options = None 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): def convert_ap_options_to_ladxr_logic(self):
self.player_options = { self.player_options = {
option: getattr(self.multiworld, option)[self.player] for option in self.option_definitions 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_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() self.ladxr_itempool = LADXRItemPool(self.ladxr_logic, self.laxdr_options, self.multiworld.random).toDict()
def create_regions(self) -> None: def create_regions(self) -> None:
# Initialize # Initialize
self.convert_ap_options_to_ladxr_logic() self.convert_ap_options_to_ladxr_logic()
@ -401,9 +408,6 @@ class LinksAwakeningWorld(World):
return "TRADING_ITEM_LETTER" return "TRADING_ITEM_LETTER"
def generate_output(self, output_directory: str): def generate_output(self, output_directory: str):
# copy items back to locations # copy items back to locations
for r in self.multiworld.get_regions(self.player): 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) bsdiff4.file_patch_inplace(out_path, title_patch.name)
os.unlink(title_patch.name) os.unlink(title_patch.name)
patch = LADXDeltaPatch(os.path.splitext(out_path)[0]+LADXDeltaPatch.patch_file_ending, player=self.player, 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() patch.write()
if not DEVELOPER_MODE: if not DEVELOPER_MODE:
os.unlink(out_path) 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') return bytearray(self.multiworld.random.getrandbits(8) for _ in range(10)) + self.player.to_bytes(2, 'big')
def modify_multidata(self, multidata: dict): def modify_multidata(self, multidata: dict):
multidata["connect_names"][binascii.hexlify(self.multi_key).decode()] = multidata["connect_names"][self.multiworld.player_name[self.player]] 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