Undertale: Doc updates and client bug fixes. (#1996)
This commit is contained in:
parent
191dcb505c
commit
889a4f4db9
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
import os
|
||||
import sys
|
||||
import asyncio
|
||||
import typing
|
||||
import bsdiff4
|
||||
|
@ -11,7 +12,7 @@ from NetUtils import NetworkItem, ClientStatus
|
|||
from worlds import undertale
|
||||
from MultiServer import mark_raw
|
||||
from CommonClient import CommonContext, server_loop, \
|
||||
gui_enabled, ClientCommandProcessor, get_base_parser
|
||||
gui_enabled, ClientCommandProcessor, logger, get_base_parser
|
||||
from Utils import async_start
|
||||
|
||||
|
||||
|
@ -105,6 +106,8 @@ class UndertaleContext(CommonContext):
|
|||
self.tem_armor = False
|
||||
self.completed_count = 0
|
||||
self.completed_routes = {"pacifist": 0, "genocide": 0, "neutral": 0}
|
||||
# self.save_game_folder: files go in this path to pass data between us and the actual game
|
||||
self.save_game_folder = os.path.expandvars(r"%localappdata%/UNDERTALE")
|
||||
|
||||
def patch_game(self):
|
||||
with open(os.getcwd() + "/Undertale/data.win", "rb") as f:
|
||||
|
@ -233,9 +236,11 @@ async def process_undertale_cmd(ctx: UndertaleContext, cmd: str, args: dict):
|
|||
f.close()
|
||||
filename = f"check.spot"
|
||||
with open(os.path.join(ctx.save_game_folder, filename), "a") as f:
|
||||
for ss in ctx.checked_locations:
|
||||
for ss in set(args["checked_locations"]):
|
||||
f.write(str(ss-12000)+"\n")
|
||||
f.close()
|
||||
message = [{"cmd": "LocationChecks", "locations": [79067]}]
|
||||
await ctx.send_msgs(message)
|
||||
elif cmd == "LocationInfo":
|
||||
for l in args["locations"]:
|
||||
locationid = l.location
|
||||
|
@ -359,7 +364,7 @@ async def process_undertale_cmd(ctx: UndertaleContext, cmd: str, args: dict):
|
|||
if "checked_locations" in args:
|
||||
filename = f"check.spot"
|
||||
with open(os.path.join(ctx.save_game_folder, filename), "a") as f:
|
||||
for ss in ctx.checked_locations:
|
||||
for ss in set(args["checked_locations"]):
|
||||
f.write(str(ss-12000)+"\n")
|
||||
f.close()
|
||||
|
||||
|
@ -430,7 +435,7 @@ async def game_watcher(ctx: UndertaleContext):
|
|||
lines = f.readlines()
|
||||
for l in lines:
|
||||
if ctx.server_locations.__contains__(int(l)+12000):
|
||||
sending = sending + [int(l)+12000]
|
||||
sending = sending + [int(l.rstrip('\n'))+12000]
|
||||
await ctx.send_msgs([{"cmd": "LocationScouts", "locations": sending,
|
||||
"create_as_hint": int(2)}])
|
||||
finally:
|
||||
|
@ -441,7 +446,7 @@ async def game_watcher(ctx: UndertaleContext):
|
|||
with open(root+"/"+file, "r") as f:
|
||||
lines = f.readlines()
|
||||
for l in lines:
|
||||
sending = sending+[(int(l))+12000]
|
||||
sending = sending+[(int(l.rstrip('\n')))+12000]
|
||||
message = [{"cmd": "LocationChecks", "locations": sending}]
|
||||
await ctx.send_msgs(message)
|
||||
finally:
|
||||
|
|
|
@ -77,6 +77,7 @@ advancement_table = {
|
|||
"True Lab Plot": AdvData(79063, "Hotland"),
|
||||
"Left New Home Key": AdvData(79064, "New Home"),
|
||||
"Right New Home Key": AdvData(79065, "New Home"),
|
||||
"Starting Key": AdvData(79067, "Hub"),
|
||||
"LOVE 2": AdvData(79902, "???"),
|
||||
"LOVE 3": AdvData(79903, "???"),
|
||||
"LOVE 4": AdvData(79904, "???"),
|
||||
|
|
|
@ -57,13 +57,13 @@ class NoEquips(Toggle):
|
|||
|
||||
|
||||
class RandomizeLove(Toggle):
|
||||
"""Adds LOVE to the pool. GENOCIDE ONLY!"""
|
||||
"""Adds LOVE to the pool. Only matters if your goal includes Genocide route"""
|
||||
display_name = "Randomize LOVE"
|
||||
default = 0
|
||||
|
||||
|
||||
class RandomizeStats(Toggle):
|
||||
"""Makes each stat increase from LV a separate item. GENOCIDE ONLY!
|
||||
"""Makes each stat increase from LV a separate item. Only matters if your goal includes Genocide route
|
||||
Warning: This tends to spam chat with sending out checks."""
|
||||
display_name = "Randomize Stats"
|
||||
default = 0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from worlds.generic.Rules import set_rule, add_rule
|
||||
from worlds.generic.Rules import set_rule, add_rule, add_item_rule
|
||||
from BaseClasses import MultiWorld, CollectionState
|
||||
|
||||
|
||||
|
@ -250,6 +250,10 @@ def set_rules(multiworld: MultiWorld, player: int):
|
|||
set_rule(multiworld.get_entrance("??? Exit", player), lambda state: state.has("FIGHT", player))
|
||||
set_rule(multiworld.get_location("Snowman", player),
|
||||
lambda state: state.can_reach("Snowdin Town", "Region", player))
|
||||
add_item_rule(multiworld.get_location("Starting Key", player), lambda item: item.name == "Ruins Key" or
|
||||
item.name == "Snowdin Key" or
|
||||
item.name == "Waterfall Key" or
|
||||
item.name == "Hotland Key")
|
||||
if _undertale_is_route(multiworld.state, player, 1):
|
||||
set_rule(multiworld.get_location("Donut Sale", player),
|
||||
lambda state: state.has("ACT", player) and state.has("MERCY", player))
|
||||
|
|
|
@ -47,13 +47,12 @@ class UndertaleWorld(World):
|
|||
"""
|
||||
game = "Undertale"
|
||||
option_definitions = undertale_options
|
||||
topology_present = True
|
||||
web = UndertaleWeb()
|
||||
|
||||
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
||||
location_name_to_id = {name: data.id for name, data in advancement_table.items()}
|
||||
|
||||
data_version = 5
|
||||
data_version = 6
|
||||
|
||||
def _get_undertale_data(self):
|
||||
return {
|
||||
|
@ -107,9 +106,6 @@ class UndertaleWorld(World):
|
|||
self.multiworld.push_precollected(self.create_item("ITEM"))
|
||||
self.multiworld.push_precollected(self.create_item("FIGHT"))
|
||||
self.multiworld.push_precollected(self.create_item("ACT"))
|
||||
chosen_key_start = self.multiworld.per_slot_randoms[self.player].choice(["Ruins Key", "Snowdin Key", "Waterfall Key", "Hotland Key"])
|
||||
self.multiworld.push_precollected(self.create_item(chosen_key_start))
|
||||
itempool.remove(chosen_key_start)
|
||||
self.multiworld.push_precollected(self.create_item("MERCY"))
|
||||
if self.multiworld.route_required[self.player] == "genocide":
|
||||
itempool = [item for item in itempool if item != "Popato Chisps" and item != "Stained Apron" and
|
||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ config file.
|
|||
## What is considered a location check in Undertale?
|
||||
|
||||
Location checks in Undertale are all the spots in the game where you can get an item. Exceptions are Dog Residue,
|
||||
the Nicecream bought in Hotland, and anything you cannot get in your chosen route.
|
||||
the Nicecream bought in Hotland, and anything you cannot get on your chosen route.
|
||||
|
||||
## When the player receives an item, what happens?
|
||||
|
||||
|
@ -18,4 +18,30 @@ wait until they do have space.
|
|||
## What is the victory condition?
|
||||
|
||||
Victory is achieved when the player completes their chosen route. If they chose `all_routes` then they need to complete
|
||||
every major route in the game, those being `Pacifist`, `Neutral`, and `Genocide`.
|
||||
every major route in the game, those being `Pacifist`, `Neutral`, and `Genocide`.
|
||||
|
||||
## What is different from the vanilla game?
|
||||
|
||||
There are some major differences between vanilla and the randomizer.
|
||||
|
||||
There are now doors to every major area in the underground located in the flower room (The first room of the game), those being Ruins, Snowdin, Waterfall, Hotland, and Core.
|
||||
Each door needs their respective key from the pool to enter.
|
||||
You start with one key for a random door. (Core will never be given to start with.)
|
||||
The rest of the keys will be in the item pool.
|
||||
|
||||
Genocide works a little differently in terms of the requirements.
|
||||
You now only need to get through Core and fight Mettaton NEO, and then beat Sans, to win.
|
||||
If you choose to fight other major bosses, you will still need to grind out the area before fighting them like normal.
|
||||
|
||||
Pacifist is mostly the same, except you are not required to go to the Ruins to spare Toriel,
|
||||
you only need to spare Papyrus, Undyne, and Mettaton EX. Although you still cannot kill anyone.
|
||||
You are also still required to do the date/hangout with Papyrus, the hangout with Undyne, and the date with Alphys,
|
||||
in that order, before entering the True Lab.
|
||||
|
||||
You now require custom items to Hangout with Papyrus, Undyne, to enter the True Lab, and to fight Mettaton EX/NEO.
|
||||
Those being `Complete Skeleton`, `Fish`, `DT Extractor`, and `Mettaton Plush`.
|
||||
|
||||
The Riverperson will only take you to locations you have actually seen the Riverperson at.
|
||||
Meaning they will only take you to, for example, Waterfall, if you have seen the Riverperson at Waterfall at least once.
|
||||
|
||||
If you press `W` while in the save menu, you will teleport back to the flower room, for quick access to the other areas.
|
|
@ -48,6 +48,12 @@ before connecting.
|
|||
When the console tells you that you have joined the room, you're all set. Congratulations on successfully joining a
|
||||
multiworld game!
|
||||
|
||||
### PLEASE READ!
|
||||
|
||||
Please read this page in its entirety before asking questions! Most importantly, there is a list of
|
||||
gameplay differences at the bottom.
|
||||
[Undertale Game Info Page](/games/Undertale/info/en)
|
||||
|
||||
### Where do I get a YAML file?
|
||||
|
||||
You can customize your settings by visiting the [Undertale Player Settings Page](/games/Undertale/player-settings)
|
||||
|
|
Loading…
Reference in New Issue