MultiServer: remove location hinting from !hint and /hint; add /hint_location
This commit is contained in:
parent
6a7e1d920a
commit
e74333cbd3
|
@ -543,7 +543,10 @@ async def on_client_joined(ctx: Context, client: Client):
|
|||
f"{ctx.get_aliased_name(client.team, client.slot)} (Team #{client.team + 1}) "
|
||||
f"{verb} {ctx.games[client.slot]} has joined. "
|
||||
f"Client({version_str}), {client.tags}).")
|
||||
|
||||
ctx.notify_client(client, "Now that you are connected, "
|
||||
"you can use !help to list commands to run via the server."
|
||||
"If your client supports it, "
|
||||
"you may have additional local commands you can list with /help.")
|
||||
ctx.client_connection_timers[client.team, client.slot] = datetime.datetime.now(datetime.timezone.utc)
|
||||
|
||||
|
||||
|
@ -1088,7 +1091,7 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
|||
self.output("Cheating is disabled.")
|
||||
return False
|
||||
|
||||
def get_hints(self, input_text: str, explicit_location: bool = False) -> bool:
|
||||
def get_hints(self, input_text: str, for_location: bool = False) -> bool:
|
||||
points_available = get_client_points(self.ctx, self.client)
|
||||
if not input_text:
|
||||
hints = {hint.re_check(self.ctx, self.client.team) for hint in
|
||||
|
@ -1100,20 +1103,21 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
|||
return True
|
||||
else:
|
||||
world = proxy_worlds[self.ctx.games[self.client.slot]]
|
||||
item_name, usable, response = get_intended_text(input_text,
|
||||
world.all_names if not explicit_location else world.location_names)
|
||||
names = world.location_names if for_location else world.all_item_and_group_names
|
||||
hint_name, usable, response = get_intended_text(input_text,
|
||||
names)
|
||||
if usable:
|
||||
if item_name in world.hint_blacklist:
|
||||
self.output(f"Sorry, \"{item_name}\" is marked as non-hintable.")
|
||||
if hint_name in world.hint_blacklist:
|
||||
self.output(f"Sorry, \"{hint_name}\" is marked as non-hintable.")
|
||||
hints = []
|
||||
elif item_name in world.item_name_groups and not explicit_location:
|
||||
elif not for_location and hint_name in world.item_name_groups: # item group name
|
||||
hints = []
|
||||
for item in world.item_name_groups[item_name]:
|
||||
for item in world.item_name_groups[hint_name]:
|
||||
hints.extend(collect_hints(self.ctx, self.client.team, self.client.slot, item))
|
||||
elif item_name in world.item_names and not explicit_location: # item name
|
||||
hints = collect_hints(self.ctx, self.client.team, self.client.slot, item_name)
|
||||
elif not for_location and hint_name in world.item_names: # item name
|
||||
hints = collect_hints(self.ctx, self.client.team, self.client.slot, hint_name)
|
||||
else: # location name
|
||||
hints = collect_hints_location(self.ctx, self.client.team, self.client.slot, item_name)
|
||||
hints = collect_hints_location(self.ctx, self.client.team, self.client.slot, hint_name)
|
||||
cost = self.ctx.get_hint_cost(self.client.slot)
|
||||
if hints:
|
||||
new_hints = set(hints) - self.ctx.hints[self.client.team, self.client.slot]
|
||||
|
@ -1175,8 +1179,8 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
|||
|
||||
@mark_raw
|
||||
def _cmd_hint(self, item_or_location: str = "") -> bool:
|
||||
"""Use !hint {item_name/location_name},
|
||||
for example !hint Lamp or !hint Link's House to get a spoiler peek for that location or item.
|
||||
"""Use !hint {item_name},
|
||||
for example !hint Lamp to get a spoiler peek for that item.
|
||||
If hint costs are on, this will only give you one new result,
|
||||
you can rerun the command to get more in that case."""
|
||||
return self.get_hints(item_or_location)
|
||||
|
@ -1511,23 +1515,44 @@ class ServerCommandProcessor(CommonCommandProcessor):
|
|||
self.output(response)
|
||||
return False
|
||||
|
||||
def _cmd_hint(self, player_name: str, *item_or_location: str) -> bool:
|
||||
"""Send out a hint for a player's item or location to their team"""
|
||||
def _cmd_hint(self, player_name: str, *item: str) -> bool:
|
||||
"""Send out a hint for a player's item to their team"""
|
||||
seeked_player, usable, response = get_intended_text(player_name, self.ctx.player_names.values())
|
||||
if usable:
|
||||
team, slot = self.ctx.player_name_lookup[seeked_player]
|
||||
item = " ".join(item_or_location)
|
||||
item = " ".join(item)
|
||||
world = proxy_worlds[self.ctx.games[slot]]
|
||||
item, usable, response = get_intended_text(item, world.all_names)
|
||||
item, usable, response = get_intended_text(item, world.all_item_and_group_names)
|
||||
if usable:
|
||||
if item in world.item_name_groups:
|
||||
hints = []
|
||||
for item in world.item_name_groups[item]:
|
||||
hints.extend(collect_hints(self.ctx, team, slot, item))
|
||||
elif item in world.item_names: # item name
|
||||
else: # item name
|
||||
hints = collect_hints(self.ctx, team, slot, item)
|
||||
else: # location name
|
||||
hints = collect_hints_location(self.ctx, team, slot, item)
|
||||
if hints:
|
||||
notify_hints(self.ctx, team, hints)
|
||||
else:
|
||||
self.output("No hints found.")
|
||||
return True
|
||||
else:
|
||||
self.output(response)
|
||||
return False
|
||||
|
||||
else:
|
||||
self.output(response)
|
||||
return False
|
||||
|
||||
def _cmd_hint_location(self, player_name: str, *location: str) -> bool:
|
||||
"""Send out a hint for a player's location to their team"""
|
||||
seeked_player, usable, response = get_intended_text(player_name, self.ctx.player_names.values())
|
||||
if usable:
|
||||
team, slot = self.ctx.player_name_lookup[seeked_player]
|
||||
item = " ".join(location)
|
||||
world = proxy_worlds[self.ctx.games[slot]]
|
||||
item, usable, response = get_intended_text(item, world.location_names)
|
||||
if usable:
|
||||
hints = collect_hints_location(self.ctx, team, slot, item)
|
||||
if hints:
|
||||
notify_hints(self.ctx, team, hints)
|
||||
else:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from __future__ import annotations
|
||||
from typing import Dict, Set, Tuple, List, Optional, TextIO
|
||||
from typing import Dict, Set, Tuple, List, Optional, TextIO, Any
|
||||
|
||||
from BaseClasses import MultiWorld, Item, CollectionState, Location
|
||||
from Options import Option
|
||||
|
@ -8,7 +8,7 @@ from Options import Option
|
|||
class AutoWorldRegister(type):
|
||||
world_types: Dict[str, World] = {}
|
||||
|
||||
def __new__(cls, name, bases, dct):
|
||||
def __new__(cls, name: str, bases, dct: Dict[str, Any]):
|
||||
# filter out any events
|
||||
dct["item_name_to_id"] = {name: id for name, id in dct["item_name_to_id"].items() if id}
|
||||
dct["location_name_to_id"] = {name: id for name, id in dct["location_name_to_id"].items() if id}
|
||||
|
@ -19,7 +19,7 @@ class AutoWorldRegister(type):
|
|||
# build rest
|
||||
dct["item_names"] = frozenset(dct["item_name_to_id"])
|
||||
dct["location_names"] = frozenset(dct["location_name_to_id"])
|
||||
dct["all_names"] = dct["item_names"] | dct["location_names"] | set(dct.get("item_name_groups", {}))
|
||||
dct["all_item_and_group_names"] = frozenset(dct["item_names"] | set(dct.get("item_name_groups", {})))
|
||||
|
||||
# construct class
|
||||
new_class = super().__new__(cls, name, bases, dct)
|
||||
|
@ -71,7 +71,7 @@ class World(metaclass=AutoWorldRegister):
|
|||
options: Dict[str, type(Option)] = {} # link your Options mapping
|
||||
game: str # name the game
|
||||
topology_present: bool = False # indicate if world type has any meaningful layout/pathing
|
||||
all_names: Set[str] = frozenset() # gets automatically populated with all item, item group and location names
|
||||
all_item_and_group_names: Set[str] = frozenset() # gets automatically populated with all item and item group names
|
||||
|
||||
# map names to their IDs
|
||||
item_name_to_id: Dict[str, int] = {}
|
||||
|
|
Loading…
Reference in New Issue