Better 'say' command
That is easier to use.
This commit is contained in:
parent
d28b993e71
commit
6cea0e122a
1 changed files with 136 additions and 105 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from random import random
|
||||
from re import split, sub, MULTILINE
|
||||
from re import match, split, sub, MULTILINE
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from evennia.commands.default.general import CmdGet, NumberedTargetCommand
|
||||
|
|
@ -251,160 +251,191 @@ class CmdWhisper(MuxCommand):
|
|||
self.caller.msg(full_speech, from_obj=self.caller)
|
||||
|
||||
|
||||
class CmdSay(MuxCommand):
|
||||
"""
|
||||
Say something to the characters in the same area.
|
||||
class CmdSay(Command):
|
||||
"""Say something to the characters in the same area.
|
||||
|
||||
For instance:
|
||||
Usage:
|
||||
|
||||
|gsay Good evening!|n
|
||||
|gsay [[<adverb>] [to] [<character>],] <message>|n
|
||||
|
||||
However, you can use an alias and simply type:
|
||||
This command has many optional strings. You see, the text within
|
||||
brackets, [...] are optional, while text in <...> are to be
|
||||
replaced, and this technical jargon probably means little, so
|
||||
perhaps examples would be better:
|
||||
|
||||
|g"Good evening!
|
||||
|gsay Good evening.|n
|
||||
|wYou say, "Good evening."|n
|
||||
|
||||
Or:
|
||||
|
||||
|g'Good evening!
|
||||
|gsay loudly, Good evening!|n
|
||||
|wYou loudly exclaim, "Good evening!"|n
|
||||
|
||||
Creatures and objects in this game can sometimes respond to what you say.
|
||||
In the second example, the exclamation point changes the 'say' to
|
||||
an 'exclaim'. A question mark changes 'say' to 'ask'.
|
||||
|
||||
Usage:
|
||||
say phrase
|
||||
say/to char1 [, char2 ...] = phrase
|
||||
say[/switches] phrase
|
||||
Also, you gave an |wadverb|n that ends in -ly, as well as a comma.
|
||||
The comma is important, as it triggers |wprocessing|n. Without
|
||||
the comma, you would see:
|
||||
|
||||
Where switches can be any of the following:
|
||||
|gs loudly Good evening!
|
||||
|wYou exclaim, "loudly Good evening!"|n
|
||||
|
||||
- exclaim : To replace 'says' with 'exclaims'
|
||||
- yell : To replace 'says' with 'yells'
|
||||
- scream : To replace 'says' with 'screams'
|
||||
- ask : To replace 'says' with 'asks'
|
||||
- to : Directs phrase to one or more characters
|
||||
in the same area. Note others can still hear
|
||||
the statement (see the 'whisper' command).
|
||||
- adverb : Any adverb-like word that ends in '-ly'
|
||||
is added to the say command, for instance:
|
||||
You can also direct your message to a particular person (or thing),
|
||||
as in:
|
||||
|
||||
say/quietly Hi there.
|
||||
|gsay to heron, How do you do?
|
||||
|wYou ask the purple heron, "How do you do?"|n
|
||||
"What can I do for you?" asks the purple heron.
|
||||
|
||||
Shows as:
|
||||
Again, the comma is important, otherwise, you will see:
|
||||
|
||||
|gsay to heron How do you do?
|
||||
|wYou ask, "to heron How do you do?"|n
|
||||
The purple heron questions, "Uhm. I'm not sure how to respond."
|
||||
|
||||
You can replace the 'say' command with any of the following:
|
||||
|
||||
- shout
|
||||
- scream
|
||||
- respond
|
||||
- reply
|
||||
- yell
|
||||
- ask
|
||||
|
||||
Because this command is so common, you can also use ", as in:
|
||||
|
||||
|g"What's going on?|n
|
||||
|
||||
You quietly say, "Hi there."
|
||||
"""
|
||||
|
||||
key = "say"
|
||||
verb = "say"
|
||||
aliases = ["says", "speak", "shout", "yell", "exclaim", "scream", "ask",
|
||||
"reply", "respond", "\"", "'"]
|
||||
priority = 0
|
||||
"reply", "respond", '"', "'"]
|
||||
locks = "cmd:all()"
|
||||
rhs_split = ("=")
|
||||
# don't require a space after `say/'/"`
|
||||
arg_regex = None
|
||||
adverb = None
|
||||
target = None
|
||||
|
||||
def parse(self):
|
||||
"""Parse the input into speech parts."""
|
||||
self.phrase = self.args.strip()
|
||||
|
||||
m = match(r".+\?.*", self.phrase)
|
||||
if m:
|
||||
self.verb = "ask"
|
||||
m = match(r".+!.*", self.phrase)
|
||||
if m:
|
||||
self.verb = "exclaim"
|
||||
|
||||
# Final quotes can be trimmed:
|
||||
self.phrase = self.phrase.strip('"').strip("'")
|
||||
|
||||
m = match(r"(.*) *, *(.+)", self.phrase)
|
||||
if m:
|
||||
self.phrase = m.group(2)
|
||||
for word in split(r" +", m.group(1)):
|
||||
if word.endswith("ly") and not self.adverb:
|
||||
self.adverb = word
|
||||
elif word == "to":
|
||||
pass
|
||||
else:
|
||||
self.target = self.caller.search(word)
|
||||
|
||||
def func(self):
|
||||
"""Implement the new 'say' command with switches."""
|
||||
speaker = self.caller
|
||||
|
||||
if not self.args:
|
||||
if not self.phrase or self.phrase == "":
|
||||
speaker.msg("Say what?")
|
||||
return
|
||||
|
||||
if 'to' in self.switches and not self.rhs:
|
||||
speaker.msg(paragraph("""
|
||||
When attempting to say something to one or more
|
||||
characters, use the '=' character to identify what you
|
||||
want to say.
|
||||
For instance, |gsay/to elf = Hi there.|n """))
|
||||
return
|
||||
|
||||
if self.rhs:
|
||||
speech = self.rhs
|
||||
else:
|
||||
speech = self.args
|
||||
|
||||
# If speech is empty, stop here
|
||||
if not speaker.at_pre_say(speech):
|
||||
if not speaker.at_pre_say(self.phrase):
|
||||
return
|
||||
|
||||
adverb = ''
|
||||
for switch in self.switches:
|
||||
if switch.endswith('ly'):
|
||||
adverb = switch + ' '
|
||||
|
||||
if 'scream' in self.switches or self.cmdstring == 'scream':
|
||||
verb = 'scream'
|
||||
elif 'shout' in self.switches or self.cmdstring == 'shout':
|
||||
verb = 'shout'
|
||||
elif 'respond' in self.switches or self.cmdstring == 'respond':
|
||||
verb = 'respond'
|
||||
elif 'reply' in self.switches or self.cmdstring == 'reply':
|
||||
verb = 'reply'
|
||||
elif 'yell' in self.switches or self.cmdstring == 'yell':
|
||||
verb = 'yell'
|
||||
elif 'exclaim' in self.switches or self.cmdstring == 'exclaim' or speech.endswith('!'):
|
||||
verb = 'exclaim'
|
||||
elif 'ask' in self.switches or self.cmdstring == 'ask' or speech.endswith('?'):
|
||||
verb = 'ask'
|
||||
else:
|
||||
verb = "say"
|
||||
if self.cmdstring == 'scream':
|
||||
self.verb = 'scream'
|
||||
elif self.cmdstring == 'shout':
|
||||
self.verb = 'shout'
|
||||
elif self.cmdstring == 'respond':
|
||||
self.verb = 'respond'
|
||||
elif self.cmdstring == 'reply':
|
||||
self.verb = 'reply'
|
||||
elif self.cmdstring == 'yell':
|
||||
self.verb = 'yell'
|
||||
elif self.cmdstring == 'ask':
|
||||
self.verb = 'ask'
|
||||
|
||||
for_me, for_others, verb = \
|
||||
speech_effect(speech, verb,
|
||||
speaker,
|
||||
speech_effect(self.phrase, self.verb, speaker,
|
||||
speaker.attributes.get(category="effect",
|
||||
return_obj=True,
|
||||
return_list=True))
|
||||
self.to_puppets(speaker, for_others, self.target)
|
||||
self.to_you(speaker, verb, for_me)
|
||||
self.to_others(speaker, verb, for_others)
|
||||
|
||||
to_who = to_whom = ''
|
||||
|
||||
if 'to' not in self.switches:
|
||||
for char in speaker.location.contents:
|
||||
if hasattr(char, 'other_say') and callable(char.other_say):
|
||||
char.other_say(speaker, for_others)
|
||||
else:
|
||||
# Send the message to 'puppets' that have the special 'other_sayto'
|
||||
# method (if they are the object of the message):
|
||||
targets = split(r" *, *", self.lhs)
|
||||
to_chars = [speaker.search(c, quiet=True) for c in targets]
|
||||
to_chars = [c[0] for c in to_chars if len(c) > 0]
|
||||
|
||||
if to_chars == []:
|
||||
speaker.msg(f"No match for {', '.join(targets)}")
|
||||
return
|
||||
|
||||
for char in to_chars:
|
||||
if hasattr(char, 'other_sayto') and callable(char.other_sayto):
|
||||
logger.info(f"Found {char.key}: {for_others}")
|
||||
char.other_sayto(speaker, for_others)
|
||||
|
||||
who = iter_to_str([c.get_display_name(speaker)
|
||||
if isinstance(c, Character) else c
|
||||
for c in to_chars])
|
||||
whom = iter_to_str([f"/{c}" for c in targets])
|
||||
def to_you(self, speaker, verb, phrase):
|
||||
"""Send 'say' message to the speaker.
|
||||
|
||||
The `send_emote` is _global_, so if we want to say to 'Bob',
|
||||
'You say ...', we have to both send him a message with the
|
||||
'You' as well as everyone else with the 'send_emote'.
|
||||
"""
|
||||
to_who = ""
|
||||
if self.target:
|
||||
who = self.target.get_display_name(speaker)
|
||||
if verb == "ask":
|
||||
to_who = " " + who
|
||||
to_whom = " " + whom
|
||||
else:
|
||||
to_who = " to " + who
|
||||
to_whom = " to " + whom
|
||||
|
||||
# The `send_emote` is _global_, so if we want to say to 'Bob',
|
||||
# 'You say ...', we have to both send him a message with the
|
||||
# 'You' as well as everyone else with the 'send_emote'.
|
||||
full_speech = f"You {adverb}{verb}{to_who}, \"{for_me}\""
|
||||
adverb = self.adverb + " " if self.adverb else ""
|
||||
|
||||
full_speech = f"You {adverb}{verb}{to_who}, \"{phrase}\""
|
||||
speaker.msg(full_speech, from_obj=speaker)
|
||||
|
||||
# English is weird...
|
||||
if verb == 'reply':
|
||||
verb = 'replie'
|
||||
def to_others(self, speaker, verb, phrase):
|
||||
"""Use the 'send_emote' to have speaker 'say' something to others.
|
||||
|
||||
We use /me to be replaced by the user's appearance to others.
|
||||
We also need to deal with weird English usage.
|
||||
"""
|
||||
to_whom = ""
|
||||
if self.target:
|
||||
whom = f"/{self.target.key}"
|
||||
if verb == "ask":
|
||||
to_whom = " " + whom
|
||||
else:
|
||||
to_whom = " to " + whom
|
||||
|
||||
adverb = self.adverb + " " if self.adverb else ""
|
||||
# English is weird...
|
||||
verb = 'replie' if verb == 'reply' else verb
|
||||
targets = [item for item in speaker.location.contents
|
||||
if item != speaker]
|
||||
full_speech = f"/me {adverb}{verb}s{to_whom}, \"{for_others}\""
|
||||
|
||||
full_speech = f"/me {adverb}{verb}s{to_whom}, \"{phrase}\""
|
||||
send_emote(speaker, targets, full_speech, msg_type="say",
|
||||
anonymous_add=None)
|
||||
|
||||
def to_puppets(self, speaker, phrase, target=None):
|
||||
"""Send phrase to puppet, target.
|
||||
|
||||
If target is None, then send to all puppets.
|
||||
"""
|
||||
# Speak to everyone in the room:
|
||||
if not target:
|
||||
for char in speaker.location.contents:
|
||||
if hasattr(char, 'other_say') and callable(char.other_say):
|
||||
char.other_say(speaker, phrase)
|
||||
else:
|
||||
if hasattr(target, 'other_sayto') and callable(target.other_sayto):
|
||||
logger.info(f"Found {target.key}: {phrase}")
|
||||
target.other_sayto(speaker, phrase)
|
||||
|
||||
|
||||
class CmdThink(Command):
|
||||
"""Think a thought out loud.
|
||||
|
|
|
|||
Loading…
Reference in a new issue