Witness: Bugfixes in response to beta tests (#1473)
* Make all Keep Pressure Plates logically required for the Laser Panel * Added more Tutorial checks * Added the remaining two Shipwreck Boat EPs to the exclude list for normal * Improved itempool filling system, added warning if usefuls had to be eaten * Moved creation of said warning string to utils * Fixed logic bug causing broken seeds on Mountain Floor 2 * Hints system change * Expert Logic Fix * Fixed typo * Better wording * Added missing games to junk hints * Made sure Entrance names are unique * Fixed missing Obelisk Side * Disable Non Randomized + EP Shuffle fix * Fixed disable_non_randomized precompleted EPs being 'disabled' instead of 'precompleted' * Fixed if/elif error * Tutorial Gate Open local symbol item becomes local_early_item in expert instead * Bump required client version. There is a beta client that sends 0.3.9. * Removed print statement, oops * Fixed itempool manipulation in pre_fill * Replaced string concats with fstrings * Improved make_warning_string function signature Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com> * Improved performance on removing multiple items from multiworld itempool * Comment * Fixed errors with the code * Made removal from itempool not fail unit test for multiple references * Moved all item creation to create_items, got rid of itempool modifying system * Colored Squares is no longer a good item, that's outdated * Removed double if * React to from_pool: false by removing a junk item * Fixed warning if only Fnc Brain was removed * Make use of string truthiness instead * Made reading of plandoed items safer --------- Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
This commit is contained in:
parent
0cf8206660
commit
805f33c39e
|
@ -411,7 +411,7 @@ Keep Tower (Keep) - Keep - 0x04F8F:
|
|||
158206 - 0x0361B (Tower Shortcut Panel) - True - True
|
||||
Door - 0x04F8F (Tower Shortcut) - 0x0361B
|
||||
158704 - 0x0360E (Laser Panel Hedges) - 0x01A0F & 0x019E7 & 0x019DC & 0x00139 - True
|
||||
158705 - 0x03317 (Laser Panel Pressure Plates) - 0x01D3F - Shapers & Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol & Dots
|
||||
158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Shapers & Black/White Squares & Colored Squares & Stars & Stars + Same Colored Symbol & Dots
|
||||
Laser - 0x014BB (Laser) - 0x0360E | 0x03317
|
||||
159240 - 0x033BE (Pressure Plates 1 EP) - 0x033EA - True
|
||||
159241 - 0x033BF (Pressure Plates 2 EP) - 0x01BE9 - True
|
||||
|
@ -909,7 +909,7 @@ Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near -
|
|||
158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Colored Squares & Symmetry & Colored Dots
|
||||
Door - 0x09FFB (Staircase Near) - 0x09FD8
|
||||
|
||||
Mountain Floor 2 Blue Bridge (Mountain Floor 2) - Mountain Floor 2 Beyond Bridge - TrueOneWay - Mountain Floor 2 At Door - TrueOneWay:
|
||||
Mountain Floor 2 Blue Bridge (Mountain Floor 2) - Mountain Floor 2 Beyond Bridge - TrueOneWay - Mountain Floor 2 At Door - 0x09ED8:
|
||||
|
||||
Mountain Floor 2 At Door (Mountain Floor 2) - Mountain Floor 2 Elevator Room - 0x09EDD:
|
||||
Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86
|
||||
|
@ -1113,8 +1113,9 @@ Obelisks (EPs) - Entry - True:
|
|||
159735 - 0xFFE35 (River Obelisk Side 6) - 0x035CB & 0x035CF - True
|
||||
159740 - 0xFFE40 (Quarry Obelisk Side 1) - 0x28A7B & 0x005F6 & 0x00859 & 0x17CB9 & 0x28A4A - True
|
||||
159741 - 0xFFE41 (Quarry Obelisk Side 2) - 0x334B6 & 0x00614 & 0x0069D & 0x28A4C - True
|
||||
159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 & 0x33692 - True
|
||||
159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x03E77 & 0x03E7C - True
|
||||
159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 - True
|
||||
159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x33692 - True
|
||||
159744 - 0xFFE44 (Quarry Obelisk Side 5) - 0x03E77 & 0x03E7C - True
|
||||
159750 - 0xFFE50 (Town Obelisk Side 1) - 0x035C7 - True
|
||||
159751 - 0xFFE51 (Town Obelisk Side 2) - 0x01848 & 0x03D06 & 0x33530 & 0x33600 & 0x28A2F & 0x28A37 & 0x334A3 & 0x3352F - True
|
||||
159752 - 0xFFE52 (Town Obelisk Side 3) - 0x33857 & 0x33879 & 0x03C19 - True
|
||||
|
|
|
@ -270,7 +270,7 @@ Door - 0x0368A (Stairs) - 0x03677
|
|||
159413 - 0x00614 (Lift EP) - 0x275FF & 0x03675 - True
|
||||
|
||||
Quarry Boathouse (Quarry Boathouse) - Quarry - True - Quarry Boathouse Upper Front - 0x03852 - Quarry Boathouse Behind Staircase - 0x2769B:
|
||||
158146 - 0x034D4 (Intro Left) - True - Stars & Eraser
|
||||
158146 - 0x034D4 (Intro Left) - True - Stars & Stars + Same Colored Symbol + Eraser
|
||||
158147 - 0x021D5 (Intro Right) - True - Shapers & Eraser
|
||||
158148 - 0x03852 (Ramp Height Control) - 0x034D4 & 0x021D5 - Rotated Shapers
|
||||
158166 - 0x17CA6 (Boat Spawn) - True - Boat
|
||||
|
@ -411,7 +411,7 @@ Keep Tower (Keep) - Keep - 0x04F8F:
|
|||
158206 - 0x0361B (Tower Shortcut Panel) - True - True
|
||||
Door - 0x04F8F (Tower Shortcut) - 0x0361B
|
||||
158704 - 0x0360E (Laser Panel Hedges) - 0x01A0F & 0x019E7 & 0x019DC & 0x00139 - True
|
||||
158705 - 0x03317 (Laser Panel Pressure Plates) - 0x01BE9 - Shapers & Rotated Shapers & Triangles & Stars & Stars + Same Colored Symbol & Colored Squares & Black/White Squares
|
||||
158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Shapers & Rotated Shapers & Triangles & Stars & Stars + Same Colored Symbol & Colored Squares & Black/White Squares
|
||||
Laser - 0x014BB (Laser) - 0x0360E | 0x03317
|
||||
159240 - 0x033BE (Pressure Plates 1 EP) - 0x033EA - True
|
||||
159241 - 0x033BF (Pressure Plates 2 EP) - 0x01BE9 - True
|
||||
|
@ -909,7 +909,7 @@ Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near -
|
|||
158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Stars & Stars + Same Colored Symbol & Rotated Shapers & Eraser
|
||||
Door - 0x09FFB (Staircase Near) - 0x09FD8
|
||||
|
||||
Mountain Floor 2 Blue Bridge (Mountain Floor 2) - Mountain Floor 2 Beyond Bridge - TrueOneWay - Mountain Floor 2 At Door - TrueOneWay:
|
||||
Mountain Floor 2 Blue Bridge (Mountain Floor 2) - Mountain Floor 2 Beyond Bridge - TrueOneWay - Mountain Floor 2 At Door - 0x09ED8:
|
||||
|
||||
Mountain Floor 2 At Door (Mountain Floor 2) - Mountain Floor 2 Elevator Room - 0x09EDD:
|
||||
Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86
|
||||
|
@ -1113,8 +1113,9 @@ Obelisks (EPs) - Entry - True:
|
|||
159735 - 0xFFE35 (River Obelisk Side 6) - 0x035CB & 0x035CF - True
|
||||
159740 - 0xFFE40 (Quarry Obelisk Side 1) - 0x28A7B & 0x005F6 & 0x00859 & 0x17CB9 & 0x28A4A - True
|
||||
159741 - 0xFFE41 (Quarry Obelisk Side 2) - 0x334B6 & 0x00614 & 0x0069D & 0x28A4C - True
|
||||
159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 & 0x33692 - True
|
||||
159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x03E77 & 0x03E7C - True
|
||||
159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 - True
|
||||
159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x33692 - True
|
||||
159744 - 0xFFE44 (Quarry Obelisk Side 5) - 0x03E77 & 0x03E7C - True
|
||||
159750 - 0xFFE50 (Town Obelisk Side 1) - 0x035C7 - True
|
||||
159751 - 0xFFE51 (Town Obelisk Side 2) - 0x01848 & 0x03D06 & 0x33530 & 0x33600 & 0x28A2F & 0x28A37 & 0x334A3 & 0x3352F - True
|
||||
159752 - 0xFFE52 (Town Obelisk Side 3) - 0x33857 & 0x33879 & 0x03C19 - True
|
||||
|
|
|
@ -411,7 +411,7 @@ Keep Tower (Keep) - Keep - 0x04F8F:
|
|||
158206 - 0x0361B (Tower Shortcut Panel) - True - True
|
||||
Door - 0x04F8F (Tower Shortcut) - 0x0361B
|
||||
158704 - 0x0360E (Laser Panel Hedges) - 0x01A0F & 0x019E7 & 0x019DC & 0x00139 - True
|
||||
158705 - 0x03317 (Laser Panel Pressure Plates) - 0x01D3F - Shapers & Black/White Squares & Rotated Shapers
|
||||
158705 - 0x03317 (Laser Panel Pressure Plates) - 0x033EA & 0x01BE9 & 0x01CD3 & 0x01D3F - Shapers & Black/White Squares & Rotated Shapers
|
||||
Laser - 0x014BB (Laser) - 0x0360E | 0x03317
|
||||
159240 - 0x033BE (Pressure Plates 1 EP) - 0x033EA - True
|
||||
159241 - 0x033BF (Pressure Plates 2 EP) - 0x01BE9 - True
|
||||
|
@ -909,7 +909,7 @@ Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near -
|
|||
158430 - 0x09FD8 (Near Row 5) - 0x09FD7 - Colored Squares & Symmetry
|
||||
Door - 0x09FFB (Staircase Near) - 0x09FD8
|
||||
|
||||
Mountain Floor 2 Blue Bridge (Mountain Floor 2) - Mountain Floor 2 Beyond Bridge - TrueOneWay - Mountain Floor 2 At Door - TrueOneWay:
|
||||
Mountain Floor 2 Blue Bridge (Mountain Floor 2) - Mountain Floor 2 Beyond Bridge - TrueOneWay - Mountain Floor 2 At Door - 0x09ED8:
|
||||
|
||||
Mountain Floor 2 At Door (Mountain Floor 2) - Mountain Floor 2 Elevator Room - 0x09EDD:
|
||||
Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86
|
||||
|
@ -1113,8 +1113,9 @@ Obelisks (EPs) - Entry - True:
|
|||
159735 - 0xFFE35 (River Obelisk Side 6) - 0x035CB & 0x035CF - True
|
||||
159740 - 0xFFE40 (Quarry Obelisk Side 1) - 0x28A7B & 0x005F6 & 0x00859 & 0x17CB9 & 0x28A4A - True
|
||||
159741 - 0xFFE41 (Quarry Obelisk Side 2) - 0x334B6 & 0x00614 & 0x0069D & 0x28A4C - True
|
||||
159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 & 0x33692 - True
|
||||
159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x03E77 & 0x03E7C - True
|
||||
159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 - True
|
||||
159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x33692 - True
|
||||
159744 - 0xFFE44 (Quarry Obelisk Side 5) - 0x03E77 & 0x03E7C - True
|
||||
159750 - 0xFFE50 (Town Obelisk Side 1) - 0x035C7 - True
|
||||
159751 - 0xFFE51 (Town Obelisk Side 2) - 0x01848 & 0x03D06 & 0x33530 & 0x33600 & 0x28A2F & 0x28A37 & 0x334A3 & 0x3352F - True
|
||||
159752 - 0xFFE52 (Town Obelisk Side 3) - 0x33857 & 0x33879 & 0x03C19 - True
|
||||
|
|
|
@ -14,7 +14,7 @@ from .items import WitnessItem, StaticWitnessItems, WitnessPlayerItems
|
|||
from .rules import set_rules
|
||||
from .regions import WitnessRegions
|
||||
from .Options import is_option_enabled, the_witness_options, get_option_value
|
||||
from .utils import best_junk_to_add_based_on_weights, get_audio_logs
|
||||
from .utils import best_junk_to_add_based_on_weights, get_audio_logs, make_warning_string
|
||||
from logging import warning
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ class WitnessWorld(World):
|
|||
"""
|
||||
game = "The Witness"
|
||||
topology_present = False
|
||||
data_version = 12
|
||||
data_version = 13
|
||||
|
||||
static_logic = StaticWitnessLogic()
|
||||
static_locat = StaticWitnessLocations()
|
||||
|
@ -52,7 +52,7 @@ class WitnessWorld(World):
|
|||
location_name_to_id = StaticWitnessLocations.ALL_LOCATIONS_TO_ID
|
||||
item_name_groups = StaticWitnessItems.ITEM_NAME_GROUPS
|
||||
|
||||
required_client_version = (0, 3, 8)
|
||||
required_client_version = (0, 3, 9)
|
||||
|
||||
def _get_slot_data(self):
|
||||
return {
|
||||
|
@ -93,13 +93,13 @@ class WitnessWorld(World):
|
|||
self.items = WitnessPlayerItems(self.locat, self.multiworld, self.player, self.player_logic)
|
||||
self.regio = WitnessRegions(self.locat)
|
||||
|
||||
def create_regions(self):
|
||||
self.regio.create_regions(self.multiworld, self.player, self.player_logic)
|
||||
|
||||
def generate_basic(self):
|
||||
self.log_ids_to_hints = dict()
|
||||
self.junk_items_created = {key: 0 for key in self.items.JUNK_WEIGHTS.keys()}
|
||||
|
||||
def create_regions(self):
|
||||
self.regio.create_regions(self.multiworld, self.player, self.player_logic)
|
||||
|
||||
def create_items(self):
|
||||
# Generate item pool
|
||||
pool = []
|
||||
for item in self.items.ITEM_TABLE:
|
||||
|
@ -109,22 +109,12 @@ class WitnessWorld(World):
|
|||
pool.append(witness_item)
|
||||
self.items_by_name[item] = witness_item
|
||||
|
||||
less_junk = 0
|
||||
|
||||
dog_check = self.multiworld.get_location(
|
||||
"Town Pet the Dog", self.player
|
||||
)
|
||||
|
||||
dog_check.place_locked_item(self.create_item("Puzzle Skip"))
|
||||
|
||||
less_junk += 1
|
||||
|
||||
for precol_item in self.multiworld.precollected_items[self.player]:
|
||||
if precol_item.name in self.items_by_name: # if item is in the pool, remove 1 instance.
|
||||
item_obj = self.items_by_name[precol_item.name]
|
||||
|
||||
if item_obj in pool:
|
||||
pool.remove(item_obj) # remove one instance of this pre-collected item if it exists
|
||||
pool.remove(item_obj) # remove one instance of this pre-collected item if it exists
|
||||
|
||||
for item in self.player_logic.STARTING_INVENTORY:
|
||||
self.multiworld.push_precollected(self.items_by_name[item])
|
||||
|
@ -132,15 +122,8 @@ class WitnessWorld(World):
|
|||
|
||||
for item in self.items.EXTRA_AMOUNTS:
|
||||
for i in range(0, self.items.EXTRA_AMOUNTS[item]):
|
||||
if len(pool) < len(self.locat.CHECK_LOCATION_TABLE) - len(self.locat.EVENT_LOCATION_TABLE) - less_junk:
|
||||
witness_item = self.create_item(item)
|
||||
pool.append(witness_item)
|
||||
|
||||
# Put in junk items to fill the rest
|
||||
junk_size = len(self.locat.CHECK_LOCATION_TABLE) - len(pool) - len(self.locat.EVENT_LOCATION_TABLE) - less_junk
|
||||
|
||||
for i in range(0, junk_size):
|
||||
pool.append(self.create_item(self.get_filler_item_name()))
|
||||
witness_item = self.create_item(item)
|
||||
pool.append(witness_item)
|
||||
|
||||
# Tie Event Items to Event Locations (e.g. Laser Activations)
|
||||
for event_location in self.locat.EVENT_LOCATION_TABLE:
|
||||
|
@ -150,27 +133,108 @@ class WitnessWorld(World):
|
|||
location_obj = self.multiworld.get_location(event_location, self.player)
|
||||
location_obj.place_locked_item(item_obj)
|
||||
|
||||
self.multiworld.itempool += pool
|
||||
# Find out how much empty space there is for junk items. -1 for the "Town Pet the Dog" check
|
||||
itempool_difference = len(self.locat.CHECK_LOCATION_TABLE) - len(self.locat.EVENT_LOCATION_TABLE) - 1
|
||||
itempool_difference -= len(pool)
|
||||
|
||||
def pre_fill(self):
|
||||
# Put good item on first check if there are any of the designated "good items" in the pool
|
||||
# Place two locked items: Good symbol on Tutorial Gate Open, and a Puzzle Skip on "Town Pet the Dog"
|
||||
good_items_in_the_game = []
|
||||
plandoed_items = set()
|
||||
|
||||
for v in self.multiworld.plando_items[self.player]:
|
||||
if v.get("from_pool", True):
|
||||
plandoed_items.update({self.items_by_name[i] for i in v.get("items", dict()).keys()
|
||||
if i in self.items_by_name})
|
||||
if "item" in v and v["item"] in self.items_by_name:
|
||||
plandoed_items.add(self.items_by_name[v["item"]])
|
||||
|
||||
for symbol in self.items.GOOD_ITEMS:
|
||||
item = self.items_by_name[symbol]
|
||||
if item in self.multiworld.itempool: # Only do this if the item is still in item pool (e.g. after plando)
|
||||
if item in pool and item not in plandoed_items:
|
||||
# for now, any item that is mentioned in any plando option, even if it's a list of items, is ineligible.
|
||||
# Hopefully, in the future, plando gets resolved before create_items.
|
||||
# I could also partially resolve lists myself, but this could introduce errors if not done carefully.
|
||||
good_items_in_the_game.append(symbol)
|
||||
|
||||
if good_items_in_the_game:
|
||||
random_good_item = self.multiworld.random.choice(good_items_in_the_game)
|
||||
|
||||
first_check = self.multiworld.get_location(
|
||||
"Tutorial Gate Open", self.player
|
||||
)
|
||||
item = self.items_by_name[random_good_item]
|
||||
|
||||
first_check.place_locked_item(item)
|
||||
self.multiworld.itempool.remove(item)
|
||||
if get_option_value(self.multiworld, self.player, "puzzle_randomization") == 1:
|
||||
self.multiworld.local_early_items[self.player][random_good_item] = 1
|
||||
else:
|
||||
first_check = self.multiworld.get_location(
|
||||
"Tutorial Gate Open", self.player
|
||||
)
|
||||
|
||||
first_check.place_locked_item(item)
|
||||
pool.remove(item)
|
||||
|
||||
dog_check = self.multiworld.get_location(
|
||||
"Town Pet the Dog", self.player
|
||||
)
|
||||
|
||||
dog_check.place_locked_item(self.create_item("Puzzle Skip"))
|
||||
|
||||
# Fill rest of item pool with junk if there is room
|
||||
if itempool_difference > 0:
|
||||
for i in range(0, itempool_difference):
|
||||
self.multiworld.itempool.append(self.create_item(self.get_filler_item_name()))
|
||||
|
||||
# Remove junk, Functioning Brain, useful items (non-door), useful door items in that order until there is room
|
||||
if itempool_difference < 0:
|
||||
junk = [
|
||||
item for item in pool
|
||||
if item.classification in {ItemClassification.filler, ItemClassification.trap}
|
||||
and item.name != "Functioning Brain"
|
||||
]
|
||||
|
||||
f_brain = [item for item in pool if item.name == "Functioning Brain"]
|
||||
|
||||
usefuls = [
|
||||
item for item in pool
|
||||
if item.classification == ItemClassification.useful
|
||||
and item.name not in StaticWitnessLogic.ALL_DOOR_ITEMS_AS_DICT
|
||||
]
|
||||
|
||||
removable_doors = [
|
||||
item for item in pool
|
||||
if item.classification == ItemClassification.useful
|
||||
and item.name in StaticWitnessLogic.ALL_DOOR_ITEMS_AS_DICT
|
||||
]
|
||||
|
||||
self.multiworld.per_slot_randoms[self.player].shuffle(junk)
|
||||
self.multiworld.per_slot_randoms[self.player].shuffle(usefuls)
|
||||
self.multiworld.per_slot_randoms[self.player].shuffle(removable_doors)
|
||||
|
||||
removed_junk = False
|
||||
removed_usefuls = False
|
||||
removed_doors = False
|
||||
|
||||
for i in range(itempool_difference, 0):
|
||||
if junk:
|
||||
pool.remove(junk.pop())
|
||||
removed_junk = True
|
||||
elif f_brain:
|
||||
pool.remove(f_brain.pop())
|
||||
elif usefuls:
|
||||
pool.remove(usefuls.pop())
|
||||
removed_usefuls = True
|
||||
elif removable_doors:
|
||||
pool.remove(removable_doors.pop())
|
||||
removed_doors = True
|
||||
|
||||
warn = make_warning_string(
|
||||
removed_junk, removed_usefuls, removed_doors, not junk, not usefuls, not removable_doors
|
||||
)
|
||||
|
||||
if warn:
|
||||
warning(f"This Witness world has too few locations to place all its items."
|
||||
f" In order to make space, {warn} had to be removed.")
|
||||
|
||||
# Finally, add the generated pool to the overall itempool
|
||||
self.multiworld.itempool += pool
|
||||
|
||||
def set_rules(self):
|
||||
set_rules(self.multiworld, self.player, self.player_logic, self.locat)
|
||||
|
|
|
@ -2,96 +2,96 @@ from BaseClasses import MultiWorld
|
|||
from .Options import is_option_enabled, get_option_value
|
||||
|
||||
joke_hints = [
|
||||
("Quaternions", "break", "my brain"),
|
||||
("Eclipse", "has nothing", "but you should do it anyway"),
|
||||
("", "Beep", ""),
|
||||
("Putting in custom subtitles", "shouldn't have been", "as hard as it was..."),
|
||||
("BK mode", "is right", "around the corner"),
|
||||
("", "You can do it!", ""),
|
||||
("", "I believe in you!", ""),
|
||||
("The person playing", "is", "cute <3"),
|
||||
("dash dot, dash dash dash", "dash, dot dot dot dot, dot dot", "dash dot, dash dash dot"),
|
||||
("When you think about it,", "there are actually a lot of", "bubbles in a stream"),
|
||||
("Never gonna give you up", "Never gonna let you down", "Never gonna run around and desert you"),
|
||||
("Thanks to", "the Archipelago developers", "for making this possible."),
|
||||
("Have you tried ChecksFinder?", "If you like puzzles,", "you might enjoy it!"),
|
||||
("Have you tried Dark Souls III?", "A tough game like this", "feels better when friends are helping you!"),
|
||||
("Have you tried Donkey Kong Country 3?", "A legendary game", "from a golden age of platformers!"),
|
||||
("Have you tried Factorio?", "Alone in an unknown multiworld.", "Sound familiar?"),
|
||||
("Have you tried Final Fantasy?", "Experience a classic game", "improved to fit modern standards!"),
|
||||
("Have you tried Hollow Knight?", "Another independent hit", "revolutionising a genre!"),
|
||||
("Have you tried A Link to the Past?", "The Archipelago game", "that started it all!"),
|
||||
("Have you tried Meritous?", "You should know that obscure games", "are often groundbreaking!"),
|
||||
("Have you tried Ocarine of Time?", "One of the biggest randomizers,", "big inspiration for this one's features!"),
|
||||
("Have you tried Raft?", "Haven't you always wanted to explore", "the ocean surrounding this island?"),
|
||||
("Have you tried Risk of Rain 2?", "I haven't either.", "But I hear it's incredible!"),
|
||||
("Have you tried Rogue Legacy?", "After solving so many puzzles", "it's the perfect way to rest your brain."),
|
||||
("Have you tried Secret of Evermore?", "I haven't either", "But I hear it's great!"),
|
||||
("Have you tried Slay the Spire?", "Experience the thrill of combat", "without needing fast fingers!"),
|
||||
("Have you tried SMZ3?", "Why play one incredible game", "when you can play 2 at once?"),
|
||||
("Have you tried Starcraft 2?", "Use strategy and management", "to crush your enemies!"),
|
||||
("Have you tried Super Mario 64?", "3-dimensional games like this", "owe everything to that game."),
|
||||
("Have you tried Super Metroid?", "A classic game", "that started a whole genre."),
|
||||
("Have you tried Timespinner?", "Everyone who plays it", "ends up loving it!"),
|
||||
("Have you tried VVVVVV?", "Experience the essence of gaming", "distilled into its purest form!"),
|
||||
("Have you tried The Witness?", "Oh. I guess you already have.", " Thanks for playing!"),
|
||||
("Have you tried Super Mario World?", "I don't think I need to tell you", "that it is beloved by many."),
|
||||
("Have you tried Overcooked 2?", "When you're done relaxing with puzzles,",
|
||||
"use your energy to yell at your friends."),
|
||||
("Have you tried Zillion?", "Me neither. But it looks fun.", "So, let's try something new together?"),
|
||||
("Have you tried Hylics 2?", "Stop motion might just be", "the epitome of unique art styles."),
|
||||
("Have you tried Pokemon Red&Blue?", "A cute pet collecting game", "that fascinated an entire generation."),
|
||||
("Waiting to get your items?", "Try BK Sudoku!", "Make progress even while stuck."),
|
||||
("One day I was fascinated", "by the subject of", "generation of waves by wind"),
|
||||
("I don't like sandwiches", "Why would you think I like sandwiches?", "Have you ever seen me with a sandwich?"),
|
||||
("Where are you right now?", "I'm at soup!", "What do you mean you're at soup?"),
|
||||
("Remember to ask", "in the Archipelago Discord", "what the Functioning Brain does."),
|
||||
("", "Don't use your puzzle skips", "you might need them later"),
|
||||
("", "For an extra challenge", "Try playing blindfolded"),
|
||||
("Go to the top of the mountain", "and see if you can see", "your house"),
|
||||
("Yellow = Red + Green", "Cyan = Green + Blue", "Magenta = Red + Blue"),
|
||||
("", "Maybe that panel really is unsolvable", ""),
|
||||
("", "Did you make sure it was plugged in?", ""),
|
||||
("", "Do not look into laser with remaining eye", ""),
|
||||
("", "Try pressing Space to jump", ""),
|
||||
("The Witness is a Doom clone.", "Just replace the demons", "with puzzles"),
|
||||
("", "Test Hint please ignore", ""),
|
||||
("Shapers can never be placed", "outside the panel boundaries", "even if subtracted."),
|
||||
("", "The Keep laser panels use", "the same trick on both sides!"),
|
||||
("Can't get past a door? Try going around.", "Can't go around? Try building a", "nether portal."),
|
||||
("", "We've been trying to reach you", "about your car's extended warranty"),
|
||||
("I hate this game. I hate this game.", "I hate this game.", "-chess player Bobby Fischer"),
|
||||
("Dear Mario,", "Please come to the castle.", "I've baked a cake for you!"),
|
||||
("Have you tried waking up?", "", "Yeah, me neither."),
|
||||
("Why do they call it The Witness,", "when wit game the player view", "play of with the game."),
|
||||
("", "THE WIND FISH IN NAME ONLY", "FOR IT IS NEITHER"),
|
||||
("Like this game? Try The Wit.nes,", "Understand, INSIGHT, Taiji", "What the Witness?, and Tametsi."),
|
||||
("", "In a race", "It's survival of the Witnesst"),
|
||||
("", "This hint has been removed", "We apologize for your inconvenience."),
|
||||
("", "O-----------", ""),
|
||||
("Circle is draw", "Square is separate", "Line is win"),
|
||||
("Circle is draw", "Star is pair", "Line is win"),
|
||||
("Circle is draw", "Circle is copy", "Line is win"),
|
||||
("Circle is draw", "Dot is eat", "Line is win"),
|
||||
("Circle is start", "Walk is draw", "Line is win"),
|
||||
("Circle is start", "Line is win", "Witness is you"),
|
||||
("Can't find any items?", "Consider a relaxing boat trip", "around the island"),
|
||||
("", "Don't forget to like, comment, and subscribe", ""),
|
||||
("Ah crap, gimme a second.", "[papers rustling]", "Sorry, nothing."),
|
||||
("", "Trying to get a hint?", "Too bad."),
|
||||
("", "Here's a hint:", "Get good at the game."),
|
||||
("", "I'm still not entirely sure", "what we're witnessing here."),
|
||||
("Have you found a red page yet?", "No?", "Then have you found a blue page?"),
|
||||
(
|
||||
"And here we see the Witness player,",
|
||||
"seeking answers where there are none-",
|
||||
"Did someone turn on the loudspeaker?"
|
||||
),
|
||||
(
|
||||
"Hints suggested by:",
|
||||
"IHNN, Beaker, MrPokemon11, Ember, TheM8, NewSoupVi,",
|
||||
"KF, Yoshi348, Berserker, BowlinJim, oddGarrett, Pink Switch."
|
||||
),
|
||||
"Quaternions break my brain",
|
||||
"Eclipse has nothing, but you should do it anyway.",
|
||||
"Beep",
|
||||
"Putting in custom subtitles shouldn't have been as hard as it was...",
|
||||
"BK mode is right around the corner.",
|
||||
"You can do it!",
|
||||
"I believe in you!",
|
||||
"The person playing is cute. <3",
|
||||
"dash dot, dash dash dash, dash, dot dot dot dot, dot dot, dash dot, dash dash dot",
|
||||
"When you think about it, there are actually a lot of bubbles in a stream.",
|
||||
"Never gonna give you up\nNever gonna let you down\nNever gonna run around and desert you",
|
||||
"Thanks to the Archipelago developers for making this possible.",
|
||||
"Have you tried ChecksFinder?\nIf you like puzzles, you might enjoy it!",
|
||||
"Have you tried Dark Souls III?\nA tough game like this feels better when friends are helping you!",
|
||||
"Have you tried Donkey Kong Country 3?\nA legendary game from a golden age of platformers!",
|
||||
"Have you tried Factorio?\nAlone in an unknown multiworld. Sound familiar?",
|
||||
"Have you tried Final Fantasy?\nExperience a classic game improved to fit modern standards!",
|
||||
"Have you tried Hollow Knight?\nAnother independent hit revolutionising a genre!",
|
||||
"Have you tried A Link to the Past?\nThe Archipelago game that started it all!",
|
||||
"Have you tried Meritous?\nYou should know that obscure games are often groundbreaking!",
|
||||
"Have you tried Ocarina of Time?\nOne of the biggest randomizers, big inspiration for this one's features!",
|
||||
"Have you tried Raft?\nHaven't you always wanted to explore the ocean surrounding this island?",
|
||||
"Have you tried Risk of Rain 2?\nI haven't either. But I hear it's incredible!",
|
||||
"Have you tried Rogue Legacy?\nAfter solving so many puzzles it's the perfect way to rest your brain.",
|
||||
"Have you tried Secret of Evermore?\nI haven't either But I hear it's great!",
|
||||
"Have you tried Slay the Spire?\nExperience the thrill of combat without needing fast fingers!",
|
||||
"Have you tried SMZ3?\nWhy play one incredible game when you can play 2 at once?",
|
||||
"Have you tried Starcraft 2?\nUse strategy and management to crush your enemies!",
|
||||
"Have you tried Super Mario 64?\n3-dimensional games like this owe everything to that game.",
|
||||
"Have you tried Super Metroid?\nA classic game, yet still one of the best in the genre.",
|
||||
"Have you tried Timespinner?\nEveryone who plays it ends up loving it!",
|
||||
"Have you tried VVVVVV?\nExperience the essence of gaming distilled into its purest form!",
|
||||
"Have you tried The Witness?\nOh. I guess you already have. Thanks for playing!",
|
||||
"Have you tried Super Mario World?\nI don't think I need to tell you that it is beloved by many.",
|
||||
"Have you tried Overcooked 2?\nWhen you're done relaxing with puzzles, use your energy to yell at your friends.",
|
||||
"Have you tried Zillion?\nMe neither. But it looks fun. So, let's try something new together?",
|
||||
"Have you tried Hylics 2?\nStop motion might just be the epitome of unique art styles.",
|
||||
"Have you tried Pokemon Red&Blue?\nA cute pet collecting game that fascinated an entire generation.",
|
||||
"Have you tried Lufia II?\nRoguelites are not just a 2010s phenomenon, turns out.",
|
||||
"Have you tried Minecraft?\nI have recently learned this is a question that needs to be asked.",
|
||||
"Have you tried Subnautica?\nIf you like this game's lonely atmosphere, I would suggest you try it.",
|
||||
|
||||
"Have you tried Sonic Adventure 2?\nIf the silence on this island is getting to you, "
|
||||
"there aren't many games more energetic.",
|
||||
|
||||
"Waiting to get your items?\nTry BK Sudoku! Make progress even while stuck.",
|
||||
"One day I was fascinated by the subject of generation of waves by wind.",
|
||||
"I don't like sandwiches. Why would you think I like sandwiches? Have you ever seen me with a sandwich?",
|
||||
"Where are you right now?\nI'm at soup!\nWhat do you mean you're at soup?",
|
||||
"Remember to ask in the Archipelago Discord what the Functioning Brain does.",
|
||||
"Don't use your puzzle skips, you might need them later.",
|
||||
"For an extra challenge, try playing blindfolded.",
|
||||
"Go to the top of the mountain and see if you can see your house.",
|
||||
"Yellow = Red + Green\nCyan = Green + Blue\nMagenta = Red + Blue",
|
||||
"Maybe that panel really is unsolvable.",
|
||||
"Did you make sure it was plugged in?",
|
||||
"Do not look into laser with remaining eye.",
|
||||
"Try pressing Space to jump.",
|
||||
"The Witness is a Doom clone.\nJust replace the demons with puzzles",
|
||||
"Test Hint please ignore",
|
||||
"Shapers can never be placed outside the panel boundaries, even if subtracted.",
|
||||
"The Keep laser panels use the same trick on both sides!",
|
||||
"Can't get past a door? Try going around. Can't go around? Try building a nether portal.",
|
||||
"We've been trying to reach you about your car's extended warranty.",
|
||||
"I hate this game. I hate this game. I hate this game.\n- Chess player Bobby Fischer",
|
||||
"Dear Mario,\nPlease come to the castle. I've baked a cake for you!",
|
||||
"Have you tried waking up?\nYeah, me neither.",
|
||||
"Why do they call it The Witness, when wit game the player view play of with the game.",
|
||||
"THE WIND FISH IN NAME ONLY, FOR IT IS NEITHER",
|
||||
"Like this game?\nTry The Wit.nes, Understand, INSIGHT, Taiji What the Witness?, and Tametsi.",
|
||||
"In a race, It's survival of the Witnesst.",
|
||||
"This hint has been removed. We apologize for your inconvenience.",
|
||||
"O-----------",
|
||||
"Circle is draw\nSquare is separate\nLine is win",
|
||||
"Circle is draw\nStar is pair\nLine is win",
|
||||
"Circle is draw\nCircle is copy\nLine is win",
|
||||
"Circle is draw\nDot is eat\nLine is win",
|
||||
"Circle is start\nWalk is draw\nLine is win",
|
||||
"Circle is start\nLine is win\nWitness is you",
|
||||
"Can't find any items?\nConsider a relaxing boat trip around the island!",
|
||||
"Don't forget to like, comment, and subscribe.",
|
||||
"Ah crap, gimme a second.\n[papers rustling]\nSorry, nothing.",
|
||||
"Trying to get a hint? Too bad.",
|
||||
"Here's a hint: Get good at the game.",
|
||||
"I'm still not entirely sure what we're witnessing here.",
|
||||
"Have you found a red page yet? No? Then have you found a blue page?",
|
||||
"And here we see the Witness player, seeking answers where there are none-\nDid someone turn on the loudspeaker?",
|
||||
|
||||
"Hints suggested by:\nIHNN, Beaker, MrPokemon11, Ember, TheM8, NewSoupVi,"
|
||||
"KF, Yoshi348, Berserker, BowlinJim, oddGarrett, Pink Switch.",
|
||||
]
|
||||
|
||||
|
||||
|
@ -186,7 +186,7 @@ def make_hint_from_item(multiworld: MultiWorld, player: int, item: str):
|
|||
if location_obj.player != player:
|
||||
location_name += " (" + multiworld.get_player_name(location_obj.player) + ")"
|
||||
|
||||
return location_name, item, location_obj.address if(location_obj.player == player) else -1
|
||||
return location_name, item, location_obj.address if (location_obj.player == player) else -1
|
||||
|
||||
|
||||
def make_hint_from_location(multiworld: MultiWorld, player: int, location: str):
|
||||
|
@ -196,7 +196,7 @@ def make_hint_from_location(multiworld: MultiWorld, player: int, location: str):
|
|||
if item_obj.player != player:
|
||||
item_name += " (" + multiworld.get_player_name(item_obj.player) + ")"
|
||||
|
||||
return location, item_name, location_obj.address if(location_obj.player == player) else -1
|
||||
return location, item_name, location_obj.address if (location_obj.player == player) else -1
|
||||
|
||||
|
||||
def make_hints(multiworld: MultiWorld, player: int, hint_amount: int):
|
||||
|
@ -258,9 +258,9 @@ def make_hints(multiworld: MultiWorld, player: int, hint_amount: int):
|
|||
|
||||
for loc, item in always_hint_pairs.items():
|
||||
if item[1]:
|
||||
hints.append((item[0], "can be found at", loc, item[2]))
|
||||
hints.append((f"{item[0]} can be found at {loc}.", item[2]))
|
||||
else:
|
||||
hints.append((loc, "contains", item[0], item[2]))
|
||||
hints.append((f"{loc} contains {item[0]}.", item[2]))
|
||||
|
||||
multiworld.per_slot_randoms[player].shuffle(hints) # shuffle always hint order in case of low hint amount
|
||||
|
||||
|
@ -279,9 +279,9 @@ def make_hints(multiworld: MultiWorld, player: int, hint_amount: int):
|
|||
del priority_hint_pairs[loc]
|
||||
|
||||
if item[1]:
|
||||
hints.append((item[0], "can be found at", loc, item[2]))
|
||||
hints.append((f"{item[0]} can be found at {loc}.", item[2]))
|
||||
else:
|
||||
hints.append((loc, "contains", item[0], item[2]))
|
||||
hints.append((f"{loc} contains {item[0]}.", item[2]))
|
||||
continue
|
||||
|
||||
if next_random_hint_is_item:
|
||||
|
@ -290,10 +290,10 @@ def make_hints(multiworld: MultiWorld, player: int, hint_amount: int):
|
|||
continue
|
||||
|
||||
hint = make_hint_from_item(multiworld, player, prog_items_in_this_world.pop())
|
||||
hints.append((hint[1], "can be found at", hint[0], hint[2]))
|
||||
hints.append((f"{hint[1]} can be found at {hint[0]}.", hint[2]))
|
||||
else:
|
||||
hint = make_hint_from_location(multiworld, player, locations_in_this_world.pop())
|
||||
hints.append((hint[0], "contains", hint[1], hint[2]))
|
||||
hints.append((f"{hint[0]} contains {hint[1]}.", hint[2]))
|
||||
|
||||
next_random_hint_is_item = not next_random_hint_is_item
|
||||
|
||||
|
@ -301,4 +301,4 @@ def make_hints(multiworld: MultiWorld, player: int, hint_amount: int):
|
|||
|
||||
|
||||
def generate_joke_hints(multiworld: MultiWorld, player: int, amount: int):
|
||||
return [(x, y, z, -1) for (x, y, z) in multiworld.per_slot_randoms[player].sample(joke_hints, amount)]
|
||||
return [(x, -1) for x in multiworld.per_slot_randoms[player].sample(joke_hints, amount)]
|
||||
|
|
|
@ -205,13 +205,10 @@ class WitnessPlayerItems:
|
|||
]
|
||||
|
||||
if is_option_enabled(multiworld, player, "shuffle_discarded_panels"):
|
||||
if is_option_enabled(multiworld, player, "shuffle_discarded_panels"):
|
||||
if get_option_value(multiworld, player, "puzzle_randomization") == 1:
|
||||
self.GOOD_ITEMS.append("Arrows")
|
||||
else:
|
||||
self.GOOD_ITEMS.append("Triangles")
|
||||
if not is_option_enabled(multiworld, player, "disable_non_randomized_puzzles"):
|
||||
self.GOOD_ITEMS.append("Colored Squares")
|
||||
if get_option_value(multiworld, player, "puzzle_randomization") == 1:
|
||||
self.GOOD_ITEMS.append("Arrows")
|
||||
else:
|
||||
self.GOOD_ITEMS.append("Triangles")
|
||||
|
||||
self.GOOD_ITEMS = [
|
||||
StaticWitnessLogic.ITEMS_TO_PROGRESSIVE.get(item, item) for item in self.GOOD_ITEMS
|
||||
|
|
|
@ -13,13 +13,10 @@ class StaticWitnessLocations:
|
|||
"""
|
||||
ID_START = 158000
|
||||
|
||||
EXTRA_LOCATIONS = {
|
||||
GENERAL_LOCATIONS = {
|
||||
"Tutorial Front Left",
|
||||
"Tutorial Back Left",
|
||||
"Tutorial Back Right",
|
||||
}
|
||||
|
||||
GENERAL_LOCATIONS = {
|
||||
"Tutorial Gate Open",
|
||||
|
||||
"Outside Tutorial Vault Box",
|
||||
|
@ -302,6 +299,7 @@ class StaticWitnessLocations:
|
|||
"Quarry Obelisk Side 2",
|
||||
"Quarry Obelisk Side 3",
|
||||
"Quarry Obelisk Side 4",
|
||||
"Quarry Obelisk Side 5",
|
||||
"Town Obelisk Side 1",
|
||||
"Town Obelisk Side 2",
|
||||
"Town Obelisk Side 3",
|
||||
|
@ -338,6 +336,7 @@ class StaticWitnessLocations:
|
|||
"Quarry Obelisk Side 2",
|
||||
"Quarry Obelisk Side 3",
|
||||
"Quarry Obelisk Side 4",
|
||||
"Quarry Obelisk Side 5",
|
||||
"Town Obelisk Side 1",
|
||||
"Town Obelisk Side 2",
|
||||
"Town Obelisk Side 3",
|
||||
|
|
|
@ -433,7 +433,6 @@ class WitnessPlayerLogic:
|
|||
self.ADDED_CHECKS = set()
|
||||
self.VICTORY_LOCATION = "0x0356B"
|
||||
self.EVENT_ITEM_NAMES = {
|
||||
"0x01A0F": "Keep Laser Panel (Hedge Mazes) Activates",
|
||||
"0x09D9B": "Monastery Shutters Open",
|
||||
"0x193A6": "Monastery Laser Panel Activates",
|
||||
"0x00037": "Monastery Branch Panels Activate",
|
||||
|
@ -442,8 +441,11 @@ class WitnessPlayerLogic:
|
|||
"0x00139": "Keep Hedges 1 Knowledge",
|
||||
"0x019DC": "Keep Hedges 2 Knowledge",
|
||||
"0x019E7": "Keep Hedges 3 Knowledge",
|
||||
"0x01D3F": "Keep Laser Panel (Pressure Plates) Activates",
|
||||
"0x01BE9": "Keep Laser Panel (Pressure Plates) Activates - Expert",
|
||||
"0x01A0F": "Keep Hedges 4 Knowledge",
|
||||
"0x033EA": "Pressure Plates 1 Knowledge",
|
||||
"0x01BE9": "Pressure Plates 2 Knowledge",
|
||||
"0x01CD3": "Pressure Plates 3 Knowledge",
|
||||
"0x01D3F": "Pressure Plates 4 Knowledge",
|
||||
"0x09F7F": "Mountain Access",
|
||||
"0x0367C": "Quarry Laser Stoneworks Requirement Met",
|
||||
"0x009A1": "Swamp Between Bridges Far 1 Activates",
|
||||
|
@ -492,11 +494,9 @@ class WitnessPlayerLogic:
|
|||
"0x17D02": "Windmill Blades Spinning",
|
||||
"0x0A0C9": "Cargo Box EP completable",
|
||||
"0x09E39": "Pink Light Bridge Extended",
|
||||
"0x01CD3": "Pressure Plates 3 EP available",
|
||||
"0x17CC4": "Rails EP available",
|
||||
"0x2896A": "Bridge Underside EP available",
|
||||
"0x00064": "First Tunnel EP visible",
|
||||
"0x033EA": "Pressure Plates 1 EP available",
|
||||
"0x03553": "Tutorial Video EPs availble",
|
||||
"0x17C79": "Bunker Door EP available",
|
||||
"0x275FF": "Stoneworks Light EPs available",
|
||||
|
|
|
@ -27,20 +27,18 @@ class WitnessRegions:
|
|||
)
|
||||
|
||||
def connect(self, world: MultiWorld, player: int, source: str, target: str, player_logic: WitnessPlayerLogic,
|
||||
panel_hex_to_solve_set=frozenset({frozenset()})):
|
||||
panel_hex_to_solve_set=frozenset({frozenset()}), backwards: bool = False):
|
||||
"""
|
||||
connect two regions and set the corresponding requirement
|
||||
"""
|
||||
source_region = world.get_region(source, player)
|
||||
target_region = world.get_region(target, player)
|
||||
|
||||
#print(source_region)
|
||||
#print(target_region)
|
||||
#print("---")
|
||||
backwards = " Backwards" if backwards else ""
|
||||
|
||||
connection = Entrance(
|
||||
player,
|
||||
source + " to " + target,
|
||||
source + " to " + target + backwards,
|
||||
source_region
|
||||
)
|
||||
|
||||
|
@ -92,10 +90,18 @@ class WitnessRegions:
|
|||
self.connect(world, player, region_name, connection[0], player_logic, frozenset({frozenset()}))
|
||||
continue
|
||||
|
||||
backwards_connections = set()
|
||||
|
||||
for subset in connection[1]:
|
||||
if all({panel in player_logic.DOOR_ITEMS_BY_ID for panel in subset}):
|
||||
if all({reference_logic.CHECKS_BY_HEX[panel]["id"] is None for panel in subset}):
|
||||
self.connect(world, player, connection[0], region_name, player_logic, frozenset({subset}))
|
||||
backwards_connections.add(subset)
|
||||
|
||||
if backwards_connections:
|
||||
self.connect(
|
||||
world, player, connection[0], region_name, player_logic,
|
||||
frozenset(backwards_connections), True
|
||||
)
|
||||
|
||||
self.connect(world, player, region_name, connection[0], player_logic, connection[1])
|
||||
|
||||
|
|
|
@ -114,15 +114,17 @@ Disabled Locations:
|
|||
|
||||
0x17CAA (River Garden Entry Panel)
|
||||
|
||||
0x034A7 (Left Shutter EP)
|
||||
0x034AD (Middle Shutter EP)
|
||||
0x034AF (Right Shutter EP)
|
||||
0x339B6 (Eclipse EP) - 0x03549 - True
|
||||
0x33A29 (Window EP) - 0x03553 - True
|
||||
0x33A2A (Door EP) - 0x03553 - True
|
||||
0x33B06 (Church EP) - 0x0354E - True
|
||||
0x3352F (Gate EP)
|
||||
0x33600 (Patio Flowers EP)
|
||||
0x035F5 (Tinted Door EP)
|
||||
0x000D3 (Green Room Flowers EP)
|
||||
0x33A20 (Theater Flowers EP)
|
||||
Precompleted Locations:
|
||||
0x034A7
|
||||
0x034AD
|
||||
0x034AF
|
||||
0x339B6
|
||||
0x33A29
|
||||
0x33A2A
|
||||
0x33B06
|
||||
0x3352F
|
||||
0x33600
|
||||
0x035F5
|
||||
0x000D3
|
||||
0x33A20
|
||||
0x03BE2
|
|
@ -9,4 +9,6 @@ Precompleted Locations:
|
|||
0x33857
|
||||
0x33879
|
||||
0x016B2
|
||||
0x036CE
|
||||
0x036CE
|
||||
0x03B25
|
||||
0x28B2A
|
|
@ -3,6 +3,42 @@ from Utils import cache_argsless
|
|||
from itertools import accumulate
|
||||
from typing import *
|
||||
from fractions import Fraction
|
||||
from collections import Counter
|
||||
|
||||
|
||||
def make_warning_string(any_j: bool, any_u: bool, any_d: bool, all_j: bool, all_u: bool, all_d: bool) -> str:
|
||||
warning_string = ""
|
||||
|
||||
if any_j:
|
||||
if all_j:
|
||||
warning_string += "all "
|
||||
else:
|
||||
warning_string += "some "
|
||||
|
||||
warning_string += "junk"
|
||||
|
||||
if any_u or any_d:
|
||||
if warning_string:
|
||||
warning_string += " and "
|
||||
|
||||
if all_u:
|
||||
warning_string += "all "
|
||||
else:
|
||||
warning_string += "some "
|
||||
|
||||
warning_string += "usefuls"
|
||||
|
||||
if any_d:
|
||||
warning_string += ", including "
|
||||
|
||||
if all_d:
|
||||
warning_string += "all "
|
||||
else:
|
||||
warning_string += "some "
|
||||
|
||||
warning_string += "non-essential door items"
|
||||
|
||||
return warning_string
|
||||
|
||||
|
||||
def best_junk_to_add_based_on_weights(weights: Dict[Any, Fraction], created_junk: Dict[Any, int]):
|
||||
|
|
Loading…
Reference in New Issue