Hints now contain ER info
This commit is contained in:
parent
11678fa20b
commit
b2e20be077
|
@ -3957,3 +3957,11 @@ exit_ids = {'Links House Exit': (0x01, 0x00),
|
|||
'Skull Woods First Section (Right)': 0x78,
|
||||
'Skull Woods First Section (Top)': 0x76,
|
||||
'Pyramid': 0x7B}
|
||||
|
||||
exit_id_to_name = {}
|
||||
for name, addresses in exit_ids.items():
|
||||
if type(addresses) == int:
|
||||
exit_id_to_name[addresses] = name
|
||||
else:
|
||||
for address in addresses:
|
||||
exit_id_to_name[address] = name
|
||||
|
|
21
Main.py
21
Main.py
|
@ -236,6 +236,24 @@ def main(args, seed=None):
|
|||
for future in futures:
|
||||
rom_name = future.result()
|
||||
rom_names.append(rom_name)
|
||||
|
||||
def get_entrance_to_region(region: Region):
|
||||
for entrance in region.entrances:
|
||||
if entrance.parent_region.type in (RegionType.DarkWorld, RegionType.LightWorld):
|
||||
return entrance
|
||||
for entrance in region.entrances: # BFS might be better here, trying DFS for now.
|
||||
return get_entrance_to_region(entrance.parent_region)
|
||||
|
||||
# collect ER hint info
|
||||
er_hint_data = {player: {} for player in range(1, world.players + 1) if world.shuffle[player] != "vanilla"}
|
||||
from Regions import RegionType
|
||||
for region in world.regions:
|
||||
if region.player in er_hint_data and region.locations:
|
||||
main_entrance = get_entrance_to_region(region)
|
||||
for location in region.locations:
|
||||
if type(location.address) == int: # skips events and crystals
|
||||
er_hint_data[region.player][location.address] = main_entrance.name
|
||||
|
||||
multidata = zlib.compress(json.dumps({"names": parsed_names,
|
||||
"roms": rom_names,
|
||||
"remote_items": [player for player in range(1, world.players + 1) if
|
||||
|
@ -244,7 +262,8 @@ def main(args, seed=None):
|
|||
(location.item.code, location.item.player))
|
||||
for location in world.get_filled_locations() if
|
||||
type(location.address) is int],
|
||||
"server_options": get_options()["server_options"]
|
||||
"server_options": get_options()["server_options"],
|
||||
"er_hint_data": er_hint_data,
|
||||
}).encode("utf-8"), 9)
|
||||
if args.jsonout:
|
||||
jsonout["multidata"] = list(multidata)
|
||||
|
|
|
@ -764,9 +764,11 @@ async def process_server_cmd(ctx : Context, cmd, args):
|
|||
'yellow' if hint.finding_player != ctx.slot else 'magenta')
|
||||
player_recvd = color(ctx.player_names[hint.receiving_player],
|
||||
'yellow' if hint.receiving_player != ctx.slot else 'magenta')
|
||||
logging.info(f"[Hint]: {player_recvd}'s {item} can be found "
|
||||
f"at {get_location_name_from_address(hint.location)} in {player_find}'s World." +
|
||||
(" (found)" if hint.found else ""))
|
||||
text = f"[Hint]: {player_recvd}'s {item} can be found " \
|
||||
f"at {color(get_location_name_from_address(hint.location), 'blue_bg')} in {player_find}'s World"
|
||||
if hint.entrance:
|
||||
text += " at " + color(hint.entrance, 'cyan_bg')
|
||||
logging.info(text + (". (found)" if hint.found else "."))
|
||||
elif cmd == "AliasUpdate":
|
||||
ctx.player_names = {p: n for p, n in args}
|
||||
elif cmd == 'Print':
|
||||
|
|
|
@ -88,6 +88,7 @@ class Context:
|
|||
self.running = True
|
||||
self.client_activity_timers = {}
|
||||
self.client_game_state: typing.Dict[typing.Tuple[int, int], int] = collections.defaultdict(int)
|
||||
self.er_hint_data: typing.Dict[int, typing.Dict[int, str]] = {}
|
||||
self.commandprocessor = ServerCommandProcessor(self)
|
||||
|
||||
def get_save(self) -> dict:
|
||||
|
@ -198,14 +199,14 @@ def notify_hints(ctx: Context, team: int, hints: typing.List[Utils.Hint]):
|
|||
texts = [['Print', format_hint(ctx, team, hint)] for hint in hints]
|
||||
for _, text in texts:
|
||||
logging.info("Notice (Team #%d): %s" % (team + 1, text))
|
||||
texts = json.dumps(texts)
|
||||
for client in ctx.clients:
|
||||
if client.auth and client.team == team:
|
||||
if "Berserker" in client.tags:
|
||||
if "Berserker" in client.tags and client.version >= [2, 2, 1]:
|
||||
payload = cmd
|
||||
asyncio.create_task(send_json_msgs(client, payload))
|
||||
else:
|
||||
payload = texts
|
||||
asyncio.create_task(send_msgs(client, payload))
|
||||
asyncio.create_task(send_json_msgs(client, payload))
|
||||
|
||||
|
||||
def update_aliases(ctx: Context, team: int, client: typing.Optional[Client] = None):
|
||||
|
@ -383,7 +384,11 @@ def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[
|
|||
if receiving_player == slot and item_id == seeked_item_id:
|
||||
location_id, finding_player = check
|
||||
found = location_id in ctx.location_checks[team, finding_player]
|
||||
hints.append(Utils.Hint(receiving_player, finding_player, location_id, item_id, found))
|
||||
entrance = ""
|
||||
if finding_player in ctx.er_hint_data:
|
||||
if location_id in ctx.er_hint_data[finding_player]:
|
||||
entrance = ctx.er_hint_data[finding_player][location_id]
|
||||
hints.append(Utils.Hint(receiving_player, finding_player, location_id, item_id, found, entrance))
|
||||
|
||||
return hints
|
||||
|
||||
|
@ -396,17 +401,24 @@ def collect_hints_location(ctx: Context, team: int, slot: int, location: str) ->
|
|||
if finding_player == slot and location_id == seeked_location:
|
||||
item_id, receiving_player = result
|
||||
found = location_id in ctx.location_checks[team, finding_player]
|
||||
hints.append(Utils.Hint(receiving_player, finding_player, location_id, item_id, found))
|
||||
entrance = ""
|
||||
if finding_player in ctx.er_hint_data:
|
||||
if location_id in ctx.er_hint_data[finding_player]:
|
||||
entrance = ctx.er_hint_data[finding_player][location_id]
|
||||
hints.append(Utils.Hint(receiving_player, finding_player, location_id, item_id, found, entrance))
|
||||
break # each location has 1 item
|
||||
return hints
|
||||
|
||||
|
||||
def format_hint(ctx: Context, team: int, hint: Utils.Hint) -> str:
|
||||
return f"[Hint]: {ctx.player_names[team, hint.receiving_player]}'s " \
|
||||
text = f"[Hint]: {ctx.player_names[team, hint.receiving_player]}'s " \
|
||||
f"{Items.lookup_id_to_name[hint.item]} can be found " \
|
||||
f"at {get_location_name_from_address(hint.location)} " \
|
||||
f"in {ctx.player_names[team, hint.finding_player]}'s World." \
|
||||
+ (" (found)" if hint.found else "")
|
||||
f"in {ctx.player_names[team, hint.finding_player]}'s World"
|
||||
|
||||
if hint.entrance:
|
||||
text += f" at {hint.entrance}"
|
||||
return text + (". (found)" if hint.found else ".")
|
||||
|
||||
|
||||
def get_intended_text(input_text: str, possible_answers: typing.Iterable[str]= console_names) -> typing.Tuple[str, bool, str]:
|
||||
|
@ -1051,6 +1063,9 @@ async def main(args: argparse.Namespace):
|
|||
ctx.rom_names = {tuple(rom): (team, slot) for slot, team, rom in jsonobj['roms']}
|
||||
ctx.remote_items = set(jsonobj['remote_items'])
|
||||
ctx.locations = {tuple(k): tuple(v) for k, v in jsonobj['locations']}
|
||||
if "er_hint_data" in jsonobj:
|
||||
ctx.er_hint_data = {int(player): {int(address): name for address, name in loc_data.items()}
|
||||
for player, loc_data in jsonobj["er_hint_data"].items()}
|
||||
except Exception as e:
|
||||
logging.exception('Failed to read multiworld data (%s)' % e)
|
||||
return
|
||||
|
|
10
Utils.py
10
Utils.py
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
__version__ = "2.2.0"
|
||||
__version__ = "2.2.1"
|
||||
_version_tuple = tuple(int(piece, 10) for piece in __version__.split("."))
|
||||
|
||||
import os
|
||||
|
@ -159,17 +159,21 @@ class Hint(typing.NamedTuple):
|
|||
location: int
|
||||
item: int
|
||||
found: bool
|
||||
entrance: str = ""
|
||||
|
||||
def re_check(self, ctx, team) -> Hint:
|
||||
if self.found:
|
||||
return self
|
||||
found = self.location in ctx.location_checks[team, self.finding_player]
|
||||
if found:
|
||||
return Hint(self.receiving_player, self.finding_player, self.location, self.item, found)
|
||||
return Hint(self.receiving_player, self.finding_player, self.location, self.item, found, self.entrance)
|
||||
return self
|
||||
|
||||
def as_legacy(self) -> tuple:
|
||||
return self.receiving_player, self.finding_player, self.location, self.item, self.found
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.receiving_player, self.finding_player, self.location, self.item))
|
||||
return hash((self.receiving_player, self.finding_player, self.location, self.item, self.entrance))
|
||||
|
||||
def get_public_ipv4() -> str:
|
||||
import socket
|
||||
|
|
Loading…
Reference in New Issue