mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
LADX: tarins gift improvement (#3970)
* add groups and a preset * formatting * pull zig's tarin's gift improvements * typing * alias groups for progressive items * change tarins gift option a bit * add bush breakers item group * fix typo * bush_breaker option, respect non_local_items * review suggestions * cleaner thx exempt * Update worlds/ladx/__init__.py Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> * fix gen failures for dungeon shuffle * exclude shovel based on entrance mapping --------- Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
This commit is contained in:
@@ -7,23 +7,12 @@ from ..roomEditor import RoomEditor
|
||||
|
||||
|
||||
class StartItem(DroppedKey):
|
||||
# We need to give something here that we can use to progress.
|
||||
# FEATHER
|
||||
OPTIONS = [SWORD, SHIELD, POWER_BRACELET, OCARINA, BOOMERANG, MAGIC_ROD, TAIL_KEY, SHOVEL, HOOKSHOT, PEGASUS_BOOTS, MAGIC_POWDER, BOMB]
|
||||
MULTIWORLD = False
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(0x2A3)
|
||||
self.give_bowwow = False
|
||||
|
||||
def configure(self, options):
|
||||
if options.bowwow != 'normal':
|
||||
# When we have bowwow mode, we pretend to be a sword for logic reasons
|
||||
self.OPTIONS = [SWORD]
|
||||
self.give_bowwow = True
|
||||
if options.randomstartlocation and options.entranceshuffle != 'none':
|
||||
self.OPTIONS.append(FLIPPERS)
|
||||
|
||||
def patch(self, rom, option, *, multiworld=None):
|
||||
assert multiworld is None
|
||||
|
||||
|
@@ -527,6 +527,20 @@ class InGameHints(DefaultOnToggle):
|
||||
display_name = "In-game Hints"
|
||||
|
||||
|
||||
class TarinsGift(Choice):
|
||||
"""
|
||||
[Local Progression] Forces Tarin's gift to be an item that immediately opens up local checks.
|
||||
Has little effect in single player games, and isn't always necessary with randomized entrances.
|
||||
[Bush Breaker] Forces Tarin's gift to be an item that can destroy bushes.
|
||||
[Any Item] Tarin's gift can be any item for any world
|
||||
"""
|
||||
display_name = "Tarin's Gift"
|
||||
option_local_progression = 0
|
||||
option_bush_breaker = 1
|
||||
option_any_item = 2
|
||||
default = option_local_progression
|
||||
|
||||
|
||||
class StabilizeItemPool(DefaultOffToggle):
|
||||
"""
|
||||
By default, rupees in the item pool may be randomly swapped with bombs, arrows, powders, or capacity upgrades. This option disables that swapping, which is useful for plando.
|
||||
@@ -565,6 +579,7 @@ ladx_option_groups = [
|
||||
OptionGroup("Miscellaneous", [
|
||||
TradeQuest,
|
||||
Rooster,
|
||||
TarinsGift,
|
||||
Overworld,
|
||||
TrendyGame,
|
||||
InGameHints,
|
||||
@@ -638,6 +653,7 @@ class LinksAwakeningOptions(PerGameCommonOptions):
|
||||
text_mode: TextMode
|
||||
no_flash: NoFlash
|
||||
in_game_hints: InGameHints
|
||||
tarins_gift: TarinsGift
|
||||
overworld: Overworld
|
||||
stabilize_item_pool: StabilizeItemPool
|
||||
|
||||
|
@@ -4,6 +4,7 @@ import os
|
||||
import pkgutil
|
||||
import tempfile
|
||||
import typing
|
||||
import logging
|
||||
import re
|
||||
|
||||
import bsdiff4
|
||||
@@ -206,6 +207,8 @@ class LinksAwakeningWorld(World):
|
||||
return Item(event, ItemClassification.progression, None, self.player)
|
||||
|
||||
def create_items(self) -> None:
|
||||
itempool = []
|
||||
|
||||
exclude = [item.name for item in self.multiworld.precollected_items[self.player]]
|
||||
|
||||
self.prefill_original_dungeon = [ [], [], [], [], [], [], [], [], [] ]
|
||||
@@ -265,9 +268,9 @@ class LinksAwakeningWorld(World):
|
||||
self.prefill_own_dungeons.append(item)
|
||||
self.pre_fill_items.append(item)
|
||||
else:
|
||||
self.multiworld.itempool.append(item)
|
||||
itempool.append(item)
|
||||
else:
|
||||
self.multiworld.itempool.append(item)
|
||||
itempool.append(item)
|
||||
|
||||
self.multi_key = self.generate_multi_key()
|
||||
|
||||
@@ -290,21 +293,52 @@ class LinksAwakeningWorld(World):
|
||||
# Properly fill locations within dungeon
|
||||
location.dungeon = r.dungeon_index
|
||||
|
||||
# For now, special case first item
|
||||
FORCE_START_ITEM = True
|
||||
if FORCE_START_ITEM:
|
||||
self.force_start_item()
|
||||
if self.options.tarins_gift != "any_item":
|
||||
self.force_start_item(itempool)
|
||||
|
||||
def force_start_item(self):
|
||||
|
||||
self.multiworld.itempool += itempool
|
||||
|
||||
def force_start_item(self, itempool):
|
||||
start_loc = self.multiworld.get_location("Tarin's Gift (Mabe Village)", self.player)
|
||||
if not start_loc.item:
|
||||
possible_start_items = [index for index, item in enumerate(self.multiworld.itempool)
|
||||
if item.player == self.player
|
||||
and item.item_data.ladxr_id in start_loc.ladxr_item.OPTIONS and not item.location]
|
||||
if possible_start_items:
|
||||
index = self.random.choice(possible_start_items)
|
||||
start_item = self.multiworld.itempool.pop(index)
|
||||
"""
|
||||
Find an item that forces progression or a bush breaker for the player, depending on settings.
|
||||
"""
|
||||
def is_possible_start_item(item):
|
||||
return item.advancement and item.name not in self.options.non_local_items
|
||||
|
||||
def opens_new_regions(item):
|
||||
collection_state = base_collection_state.copy()
|
||||
collection_state.collect(item)
|
||||
return len(collection_state.reachable_regions[self.player]) > reachable_count
|
||||
|
||||
start_items = [item for item in itempool if is_possible_start_item(item)]
|
||||
self.random.shuffle(start_items)
|
||||
|
||||
if self.options.tarins_gift == "bush_breaker":
|
||||
start_item = next((item for item in start_items if item.name in links_awakening_item_name_groups["Bush Breakers"]), None)
|
||||
|
||||
else: # local_progression
|
||||
entrance_mapping = self.ladxr_logic.world_setup.entrance_mapping
|
||||
# Tail key opens a region but not a location if d1 entrance is not mapped to d1 or d4
|
||||
# exclude it in these cases to avoid fill errors
|
||||
if entrance_mapping['d1'] not in ['d1', 'd4']:
|
||||
start_items = [item for item in start_items if item.name != 'Tail Key']
|
||||
# Exclude shovel unless starting in Mabe Village
|
||||
if entrance_mapping['start_house'] not in ['start_house', 'shop']:
|
||||
start_items = [item for item in start_items if item.name != 'Shovel']
|
||||
base_collection_state = CollectionState(self.multiworld)
|
||||
base_collection_state.update_reachable_regions(self.player)
|
||||
reachable_count = len(base_collection_state.reachable_regions[self.player])
|
||||
start_item = next((item for item in start_items if opens_new_regions(item)), None)
|
||||
|
||||
if start_item:
|
||||
itempool.remove(start_item)
|
||||
start_loc.place_locked_item(start_item)
|
||||
else:
|
||||
logging.getLogger("Link's Awakening Logger").warning(f"No {self.options.tarins_gift.current_option_name} available for Tarin's Gift.")
|
||||
|
||||
|
||||
def get_pre_fill_items(self):
|
||||
return self.pre_fill_items
|
||||
|
Reference in New Issue
Block a user