mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 12:11:33 -06:00
Lingo: Rework Early Good Items (#4910)
This commit is contained in:

committed by
GitHub

parent
d5d56ede8b
commit
d309de2557
@@ -3,7 +3,7 @@ Archipelago init file for Lingo
|
|||||||
"""
|
"""
|
||||||
from logging import warning
|
from logging import warning
|
||||||
|
|
||||||
from BaseClasses import CollectionState, Item, ItemClassification, Tutorial
|
from BaseClasses import CollectionState, Item, ItemClassification, Tutorial, Location, LocationProgressType
|
||||||
from Options import OptionError
|
from Options import OptionError
|
||||||
from worlds.AutoWorld import WebWorld, World
|
from worlds.AutoWorld import WebWorld, World
|
||||||
from .datatypes import Room, RoomEntrance
|
from .datatypes import Room, RoomEntrance
|
||||||
@@ -80,10 +80,6 @@ class LingoWorld(World):
|
|||||||
for item in self.player_logic.real_items:
|
for item in self.player_logic.real_items:
|
||||||
state.collect(self.create_item(item), True)
|
state.collect(self.create_item(item), True)
|
||||||
|
|
||||||
# Exception to the above: a forced good item is not considered a "real item", but needs to be here anyway.
|
|
||||||
if self.player_logic.forced_good_item != "":
|
|
||||||
state.collect(self.create_item(self.player_logic.forced_good_item), True)
|
|
||||||
|
|
||||||
all_locations = self.multiworld.get_locations(self.player)
|
all_locations = self.multiworld.get_locations(self.player)
|
||||||
state.sweep_for_advancements(locations=all_locations)
|
state.sweep_for_advancements(locations=all_locations)
|
||||||
|
|
||||||
@@ -105,11 +101,6 @@ class LingoWorld(World):
|
|||||||
def create_items(self):
|
def create_items(self):
|
||||||
pool = [self.create_item(name) for name in self.player_logic.real_items]
|
pool = [self.create_item(name) for name in self.player_logic.real_items]
|
||||||
|
|
||||||
if self.player_logic.forced_good_item != "":
|
|
||||||
new_item = self.create_item(self.player_logic.forced_good_item)
|
|
||||||
location_obj = self.multiworld.get_location("Second Room - Good Luck", self.player)
|
|
||||||
location_obj.place_locked_item(new_item)
|
|
||||||
|
|
||||||
item_difference = len(self.player_logic.real_locations) - len(pool)
|
item_difference = len(self.player_logic.real_locations) - len(pool)
|
||||||
if item_difference:
|
if item_difference:
|
||||||
trap_percentage = self.options.trap_percentage
|
trap_percentage = self.options.trap_percentage
|
||||||
@@ -138,7 +129,7 @@ class LingoWorld(World):
|
|||||||
|
|
||||||
trap_counts = {name: int(weight * traps / total_weight)
|
trap_counts = {name: int(weight * traps / total_weight)
|
||||||
for name, weight in self.options.trap_weights.items()}
|
for name, weight in self.options.trap_weights.items()}
|
||||||
|
|
||||||
trap_difference = traps - sum(trap_counts.values())
|
trap_difference = traps - sum(trap_counts.values())
|
||||||
if trap_difference > 0:
|
if trap_difference > 0:
|
||||||
allowed_traps = [name for name in TRAP_ITEMS if self.options.trap_weights[name] > 0]
|
allowed_traps = [name for name in TRAP_ITEMS if self.options.trap_weights[name] > 0]
|
||||||
@@ -169,6 +160,30 @@ class LingoWorld(World):
|
|||||||
def set_rules(self):
|
def set_rules(self):
|
||||||
self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player)
|
self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player)
|
||||||
|
|
||||||
|
def place_good_item(self, progitempool: list[Item], fill_locations: list[Location]):
|
||||||
|
if len(self.player_logic.good_item_options) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
good_location = self.get_location("Second Room - Good Luck")
|
||||||
|
if good_location.progress_type == LocationProgressType.EXCLUDED or good_location not in fill_locations:
|
||||||
|
return
|
||||||
|
|
||||||
|
good_items = list(filter(lambda progitem: progitem.player == self.player and
|
||||||
|
progitem.name in self.player_logic.good_item_options, progitempool))
|
||||||
|
|
||||||
|
if len(good_items) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
good_item = self.random.choice(good_items)
|
||||||
|
good_location.place_locked_item(good_item)
|
||||||
|
|
||||||
|
progitempool.remove(good_item)
|
||||||
|
fill_locations.remove(good_location)
|
||||||
|
|
||||||
|
def fill_hook(self, progitempool: list[Item], usefulitempool: list[Item], filleritempool: list[Item],
|
||||||
|
fill_locations: list[Location]):
|
||||||
|
self.place_good_item(progitempool, fill_locations)
|
||||||
|
|
||||||
def fill_slot_data(self):
|
def fill_slot_data(self):
|
||||||
slot_options = [
|
slot_options = [
|
||||||
"death_link", "victory_condition", "shuffle_colors", "shuffle_doors", "shuffle_paintings", "shuffle_panels",
|
"death_link", "victory_condition", "shuffle_colors", "shuffle_doors", "shuffle_paintings", "shuffle_panels",
|
||||||
|
@@ -95,7 +95,7 @@ class LingoPlayerLogic:
|
|||||||
|
|
||||||
painting_mapping: Dict[str, str]
|
painting_mapping: Dict[str, str]
|
||||||
|
|
||||||
forced_good_item: str
|
good_item_options: List[str]
|
||||||
|
|
||||||
panel_reqs: Dict[str, Dict[str, AccessRequirements]]
|
panel_reqs: Dict[str, Dict[str, AccessRequirements]]
|
||||||
door_reqs: Dict[str, Dict[str, AccessRequirements]]
|
door_reqs: Dict[str, Dict[str, AccessRequirements]]
|
||||||
@@ -151,7 +151,7 @@ class LingoPlayerLogic:
|
|||||||
self.mastery_location = ""
|
self.mastery_location = ""
|
||||||
self.level_2_location = ""
|
self.level_2_location = ""
|
||||||
self.painting_mapping = {}
|
self.painting_mapping = {}
|
||||||
self.forced_good_item = ""
|
self.good_item_options = []
|
||||||
self.panel_reqs = {}
|
self.panel_reqs = {}
|
||||||
self.door_reqs = {}
|
self.door_reqs = {}
|
||||||
self.mastery_reqs = []
|
self.mastery_reqs = []
|
||||||
@@ -344,23 +344,23 @@ class LingoPlayerLogic:
|
|||||||
|
|
||||||
# Starting Room - Back Right Door gives access to OPEN and DEAD END.
|
# Starting Room - Back Right Door gives access to OPEN and DEAD END.
|
||||||
# Starting Room - Exit Door gives access to OPEN and TRACE.
|
# Starting Room - Exit Door gives access to OPEN and TRACE.
|
||||||
good_item_options: List[str] = ["Starting Room - Back Right Door", "Second Room - Exit Door"]
|
self.good_item_options = ["Starting Room - Back Right Door", "Second Room - Exit Door"]
|
||||||
|
|
||||||
if not color_shuffle:
|
if not color_shuffle:
|
||||||
if not world.options.enable_pilgrimage:
|
if not world.options.enable_pilgrimage:
|
||||||
# HOT CRUST and THIS.
|
# HOT CRUST and THIS.
|
||||||
good_item_options.append("Pilgrim Room - Sun Painting")
|
self.good_item_options.append("Pilgrim Room - Sun Painting")
|
||||||
|
|
||||||
if world.options.group_doors:
|
if world.options.group_doors:
|
||||||
# WELCOME BACK, CLOCKWISE, and DRAWL + RUNS.
|
# WELCOME BACK, CLOCKWISE, and DRAWL + RUNS.
|
||||||
good_item_options.append("Welcome Back Doors")
|
self.good_item_options.append("Welcome Back Doors")
|
||||||
else:
|
else:
|
||||||
# WELCOME BACK and CLOCKWISE.
|
# WELCOME BACK and CLOCKWISE.
|
||||||
good_item_options.append("Welcome Back Area - Shortcut to Starting Room")
|
self.good_item_options.append("Welcome Back Area - Shortcut to Starting Room")
|
||||||
|
|
||||||
if world.options.group_doors:
|
if world.options.group_doors:
|
||||||
# Color hallways access (NOTE: reconsider when sunwarp shuffling exists).
|
# Color hallways access (NOTE: reconsider when sunwarp shuffling exists).
|
||||||
good_item_options.append("Rhyme Room Doors")
|
self.good_item_options.append("Rhyme Room Doors")
|
||||||
|
|
||||||
# When painting shuffle is off, most Starting Room paintings give color hallways access. The Wondrous's
|
# When painting shuffle is off, most Starting Room paintings give color hallways access. The Wondrous's
|
||||||
# painting does not, but it gives access to SHRINK and WELCOME BACK.
|
# painting does not, but it gives access to SHRINK and WELCOME BACK.
|
||||||
@@ -376,30 +376,7 @@ class LingoPlayerLogic:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
pdoor = DOORS_BY_ROOM[painting_obj.required_door.room][painting_obj.required_door.door]
|
pdoor = DOORS_BY_ROOM[painting_obj.required_door.room][painting_obj.required_door.door]
|
||||||
good_item_options.append(pdoor.item_name)
|
self.good_item_options.append(pdoor.item_name)
|
||||||
|
|
||||||
# Copied from The Witness -- remove any plandoed items from the possible good items set.
|
|
||||||
for v in world.multiworld.plando_items[world.player]:
|
|
||||||
if v.get("from_pool", True):
|
|
||||||
for item_key in {"item", "items"}:
|
|
||||||
if item_key in v:
|
|
||||||
if type(v[item_key]) is str:
|
|
||||||
if v[item_key] in good_item_options:
|
|
||||||
good_item_options.remove(v[item_key])
|
|
||||||
elif type(v[item_key]) is dict:
|
|
||||||
for item, weight in v[item_key].items():
|
|
||||||
if weight and item in good_item_options:
|
|
||||||
good_item_options.remove(item)
|
|
||||||
else:
|
|
||||||
# Other type of iterable
|
|
||||||
for item in v[item_key]:
|
|
||||||
if item in good_item_options:
|
|
||||||
good_item_options.remove(item)
|
|
||||||
|
|
||||||
if len(good_item_options) > 0:
|
|
||||||
self.forced_good_item = world.random.choice(good_item_options)
|
|
||||||
self.real_items.remove(self.forced_good_item)
|
|
||||||
self.real_locations.remove("Second Room - Good Luck")
|
|
||||||
|
|
||||||
def randomize_paintings(self, world: "LingoWorld") -> bool:
|
def randomize_paintings(self, world: "LingoWorld") -> bool:
|
||||||
self.painting_mapping.clear()
|
self.painting_mapping.clear()
|
||||||
|
Reference in New Issue
Block a user