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"{ctx.get_aliased_name(client.team, client.slot)} (Team #{client.team + 1}) "
|
||||||
f"{verb} {ctx.games[client.slot]} has joined. "
|
f"{verb} {ctx.games[client.slot]} has joined. "
|
||||||
f"Client({version_str}), {client.tags}).")
|
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)
|
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.")
|
self.output("Cheating is disabled.")
|
||||||
return False
|
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)
|
points_available = get_client_points(self.ctx, self.client)
|
||||||
if not input_text:
|
if not input_text:
|
||||||
hints = {hint.re_check(self.ctx, self.client.team) for hint in
|
hints = {hint.re_check(self.ctx, self.client.team) for hint in
|
||||||
|
@ -1100,20 +1103,21 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
world = proxy_worlds[self.ctx.games[self.client.slot]]
|
world = proxy_worlds[self.ctx.games[self.client.slot]]
|
||||||
item_name, usable, response = get_intended_text(input_text,
|
names = world.location_names if for_location else world.all_item_and_group_names
|
||||||
world.all_names if not explicit_location else world.location_names)
|
hint_name, usable, response = get_intended_text(input_text,
|
||||||
|
names)
|
||||||
if usable:
|
if usable:
|
||||||
if item_name in world.hint_blacklist:
|
if hint_name in world.hint_blacklist:
|
||||||
self.output(f"Sorry, \"{item_name}\" is marked as non-hintable.")
|
self.output(f"Sorry, \"{hint_name}\" is marked as non-hintable.")
|
||||||
hints = []
|
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 = []
|
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))
|
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
|
elif not for_location and hint_name in world.item_names: # item name
|
||||||
hints = collect_hints(self.ctx, self.client.team, self.client.slot, item_name)
|
hints = collect_hints(self.ctx, self.client.team, self.client.slot, hint_name)
|
||||||
else: # location 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)
|
cost = self.ctx.get_hint_cost(self.client.slot)
|
||||||
if hints:
|
if hints:
|
||||||
new_hints = set(hints) - self.ctx.hints[self.client.team, self.client.slot]
|
new_hints = set(hints) - self.ctx.hints[self.client.team, self.client.slot]
|
||||||
|
@ -1175,8 +1179,8 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
||||||
|
|
||||||
@mark_raw
|
@mark_raw
|
||||||
def _cmd_hint(self, item_or_location: str = "") -> bool:
|
def _cmd_hint(self, item_or_location: str = "") -> bool:
|
||||||
"""Use !hint {item_name/location_name},
|
"""Use !hint {item_name},
|
||||||
for example !hint Lamp or !hint Link's House to get a spoiler peek for that location or item.
|
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,
|
If hint costs are on, this will only give you one new result,
|
||||||
you can rerun the command to get more in that case."""
|
you can rerun the command to get more in that case."""
|
||||||
return self.get_hints(item_or_location)
|
return self.get_hints(item_or_location)
|
||||||
|
@ -1511,23 +1515,44 @@ class ServerCommandProcessor(CommonCommandProcessor):
|
||||||
self.output(response)
|
self.output(response)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _cmd_hint(self, player_name: str, *item_or_location: str) -> bool:
|
def _cmd_hint(self, player_name: str, *item: str) -> bool:
|
||||||
"""Send out a hint for a player's item or location to their team"""
|
"""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())
|
seeked_player, usable, response = get_intended_text(player_name, self.ctx.player_names.values())
|
||||||
if usable:
|
if usable:
|
||||||
team, slot = self.ctx.player_name_lookup[seeked_player]
|
team, slot = self.ctx.player_name_lookup[seeked_player]
|
||||||
item = " ".join(item_or_location)
|
item = " ".join(item)
|
||||||
world = proxy_worlds[self.ctx.games[slot]]
|
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 usable:
|
||||||
if item in world.item_name_groups:
|
if item in world.item_name_groups:
|
||||||
hints = []
|
hints = []
|
||||||
for item in world.item_name_groups[item]:
|
for item in world.item_name_groups[item]:
|
||||||
hints.extend(collect_hints(self.ctx, team, slot, 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)
|
hints = collect_hints(self.ctx, team, slot, item)
|
||||||
else: # location name
|
if hints:
|
||||||
hints = collect_hints_location(self.ctx, team, slot, item)
|
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:
|
if hints:
|
||||||
notify_hints(self.ctx, team, hints)
|
notify_hints(self.ctx, team, hints)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from __future__ import annotations
|
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 BaseClasses import MultiWorld, Item, CollectionState, Location
|
||||||
from Options import Option
|
from Options import Option
|
||||||
|
@ -8,7 +8,7 @@ from Options import Option
|
||||||
class AutoWorldRegister(type):
|
class AutoWorldRegister(type):
|
||||||
world_types: Dict[str, World] = {}
|
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
|
# filter out any events
|
||||||
dct["item_name_to_id"] = {name: id for name, id in dct["item_name_to_id"].items() if id}
|
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}
|
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
|
# build rest
|
||||||
dct["item_names"] = frozenset(dct["item_name_to_id"])
|
dct["item_names"] = frozenset(dct["item_name_to_id"])
|
||||||
dct["location_names"] = frozenset(dct["location_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
|
# construct class
|
||||||
new_class = super().__new__(cls, name, bases, dct)
|
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
|
options: Dict[str, type(Option)] = {} # link your Options mapping
|
||||||
game: str # name the game
|
game: str # name the game
|
||||||
topology_present: bool = False # indicate if world type has any meaningful layout/pathing
|
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
|
# map names to their IDs
|
||||||
item_name_to_id: Dict[str, int] = {}
|
item_name_to_id: Dict[str, int] = {}
|
||||||
|
|
Loading…
Reference in New Issue