The 'say' command works with the webclient Unplugging from the game makes you stand Trying to sit on someone else's character, now uses the RP system The fish now gets the right phrasing.
261 lines
8.3 KiB
Python
Executable file
261 lines
8.3 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
from random import random
|
|
from re import split
|
|
|
|
from commands.command import Command
|
|
from evennia.commands.default.general import NumberedTargetCommand
|
|
from evennia.commands.default.muxcommand import MuxCommand
|
|
from evennia.contrib.rpg.rpsystem import send_emote
|
|
from evennia.utils import iter_to_str, logger
|
|
|
|
from utils.word_list import routput, paragraph, choices
|
|
|
|
def speech_effect(speech, verb, target, effects):
|
|
"""
|
|
Returns a tuple for what a user thinks he said, and what
|
|
others actually here. If no effect, just return speech twice.
|
|
|
|
Effects:
|
|
- mute ... can't talk
|
|
- donkied ... target and others hear the value of effect
|
|
- sloshed ... slurred speech
|
|
|
|
To administer:
|
|
|
|
@set woman/donkied:effect = "Heehaw! ;; Heehaw, heehaw!"
|
|
"""
|
|
for effect in effects:
|
|
if effect:
|
|
if effect.db_key == 'donkied':
|
|
msg = choices(effect.value)
|
|
return (msg, msg, "bray")
|
|
|
|
return (speech, speech, verb)
|
|
|
|
|
|
class CmdWhisper(MuxCommand):
|
|
"""
|
|
Speak privately as your character to another
|
|
|
|
Usage:
|
|
whisper <character> = <message>
|
|
whisper <char1>, <char2> = <message>
|
|
|
|
Talk privately to one or more characters in your current location, without
|
|
others in the room being informed.
|
|
"""
|
|
key = "whisper"
|
|
priority = 0
|
|
locks = "cmd:all()"
|
|
rhs_split = ("=")
|
|
|
|
def func(self):
|
|
"""
|
|
Implements the new 'whisper' command.
|
|
"""
|
|
if not self.args:
|
|
self.caller.msg("What are you whispering?")
|
|
return
|
|
|
|
if not self.rhs:
|
|
self.caller.msg("Usage: whisper <character> = <message>")
|
|
return
|
|
|
|
targets = [self.caller.search(target) for target in split(r" *, *", self.lhs)]
|
|
full_speech = f"/Me whispers to you, \"{self.rhs}\""
|
|
send_emote(self.caller, targets, full_speech, msg_type="say", anonymous_add=None, quiet=True)
|
|
|
|
to_list = [target.get_display_name(self) for target in targets]
|
|
full_speech = f"You whisper to {iter_to_str(to_list, endsep='and')}, \"{self.rhs}\""
|
|
self.caller.msg(full_speech, from_obj=self.caller)
|
|
|
|
|
|
class CmdSay(MuxCommand):
|
|
"""
|
|
Say something to the characters in the same area.
|
|
|
|
Usage:
|
|
say phrase
|
|
say/to char1, [char2 ...] = phrase
|
|
say[/switches] phrase
|
|
|
|
Where switches can be any of the following:
|
|
|
|
- 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:
|
|
|
|
say/quietly Hi there.
|
|
|
|
Shows as:
|
|
|
|
You quietly say, "Hi there."
|
|
"""
|
|
|
|
key = "say"
|
|
aliases = ["speak", "yell", "exclaim", "scream", "ask", "reply", "respond", "\"", "'"]
|
|
priority = 0
|
|
locks = "cmd:all()"
|
|
rhs_split = ("=")
|
|
arg_regex = None
|
|
|
|
def func(self):
|
|
"""
|
|
Implements the new 'say' command with switches.
|
|
"""
|
|
def charname(name):
|
|
try:
|
|
results = self.caller.search(name, quiet=True)
|
|
return results.get_display_name(self)
|
|
except:
|
|
return name
|
|
|
|
def chars_for_self(chars):
|
|
return [charname(c) for c in split(r"[ ,]+", chars)]
|
|
|
|
def chars_for_others(chars):
|
|
return [c if c.startswith('/') else '/'+c for c in split(r"[ ,]+", chars)]
|
|
|
|
def chars_list(chars, verb, for_rp=True):
|
|
char_lst = chars_for_others(chars) if for_rp else chars_for_self(chars)
|
|
return (' to ' if verb == 'say' else ' ') + \
|
|
iter_to_str(char_lst, endsep='and')
|
|
|
|
# logger.info(f"CmdSayIt: {self.cmdstring} lhs={self.lhs} switches={self.switches}")
|
|
|
|
if not self.args:
|
|
self.caller.msg("Say what?")
|
|
return
|
|
|
|
if 'to' in self.switches and not self.rhs:
|
|
self.caller.msg(paragraph("""
|
|
When attempting to say something to one or more
|
|
characters, use the '=' character to identify what you
|
|
want to say.
|
|
"""))
|
|
return
|
|
|
|
if self.rhs:
|
|
speech = self.rhs
|
|
else:
|
|
speech = self.args
|
|
|
|
# If speech is empty, stop here
|
|
if not self.caller.at_pre_say(speech):
|
|
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 '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"
|
|
|
|
for_me, for_others, verb = \
|
|
speech_effect(speech, verb,
|
|
self.caller,
|
|
self.caller.attributes.get(category="effect",
|
|
return_obj=True,
|
|
return_list=True))
|
|
|
|
# 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_whom = chars_list(self.lhs, verb, for_rp=False) if 'to' in self.switches else ''
|
|
full_speech = f"You {adverb}{verb}{to_whom}, \"{for_me}\""
|
|
self.caller.msg(full_speech, from_obj=self.caller)
|
|
|
|
# English is weird...
|
|
if verb == 'reply':
|
|
verb = 'replie'
|
|
|
|
targets = [item for item in self.caller.location.contents if item != self.caller]
|
|
to_whom = chars_list(self.lhs, verb) if 'to' in self.switches else ''
|
|
full_speech = f"/Me {adverb}{verb}s{to_whom}, \"{for_others}\""
|
|
send_emote(self.caller, targets, full_speech, msg_type="say", anonymous_add=None)
|
|
|
|
|
|
|
|
|
|
class CmdThink(Command, NumberedTargetCommand):
|
|
"""Think a thought out loud.
|
|
|
|
Usage:
|
|
think <message>
|
|
|
|
Similar to the 'say' or 'pose' commands, this communicates an
|
|
inner monologue to other characters in the same area.
|
|
"""
|
|
key = "think"
|
|
aliases = ["thinks", "("]
|
|
arg_regex = None
|
|
|
|
def func(self):
|
|
"""
|
|
Implements the think out loud command.
|
|
"""
|
|
if not self.args:
|
|
self.caller.msg("What do you want to think out loud?")
|
|
else:
|
|
thought = self.args.strip()
|
|
if (self.caller.db.thinking_count or 0) < 3 or random() < 0.4:
|
|
msg = routput(
|
|
f"""{self.caller.name}
|
|
<< thinks ^ wonders >> << out loud ^ aloud >>
|
|
o O ( {thought} )
|
|
"""
|
|
)
|
|
else:
|
|
msg = f"{self.caller.name} . o O ( {thought} )"
|
|
self.caller.db.thinking_count = (self.caller.db.thinking_count or 0) + 1
|
|
|
|
self.caller.location.msg_contents(msg)
|
|
|
|
|
|
class CmdTake(Command, NumberedTargetCommand):
|
|
"""
|
|
Take an object from another character or NPC.
|
|
|
|
Usage:
|
|
take <thing> from <character>
|
|
|
|
Note that only some things can be stolen.
|
|
For instance, the brass ring from the door knocker.
|
|
"""
|
|
key = "take"
|
|
aliases = ["steal"]
|
|
rhs_split = ("=", " from ")
|
|
|
|
def func(self):
|
|
"""
|
|
Implements the take command. Since this command is designed
|
|
to work on the object, we operate only on self.obj.
|
|
"""
|
|
if not self.args:
|
|
self.caller.msg("What do you want to take?")
|
|
elif not self.rhs:
|
|
self.caller.msg(f"You want to take {self.lhs}, but from whom?")
|
|
else:
|
|
self.caller.do_take(self.lhs, self.rhs)
|