#!/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 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: - yell : To replace 'says' with 'yells' - scream : To replace 'says' with 'screams' - ask : To replace 'says' with 'asks' - to : Takes one or more characters in the same area, and directs the statement to them. Note that 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", "scream", "ask"] priority = 0 locks = "cmd:all()" rhs_split = (",", "=") def func(self): """ Implements the new 'say' command with switches. """ def characters(chars): return [c if c.startswith('/') else '/'+c for c in split(r"[ ,]+", chars)] if not self.args: self.caller.msg("Say what?") 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 logger.info(f"CmdSayIt: {self.cmdstring}") adverb = '' for switch in self.switches: if switch.endswith('ly'): adverb = switch + ' ' if 'yell' in self.switches or self.cmdstring == 'yell' or speech.endswith('!'): omsg_type = adverb + 'yells' elif 'scream' in self.switches or self.cmdstring == 'scream': omsg_type = adverb + 'screams' elif 'ask' in self.switches or self.cmdstring == 'ask' or speech.endswith('?'): omsg_type = adverb + 'asks' else: omsg_type = adverb + "says" if 'to' in self.switches: to_whom = ' to ' if omsg_type.endswith('says') else ' ' + \ iter_to_str(characters(self.lhs), endsep='and') else: to_whom = '' full_speech = f"/Me {omsg_type}{to_whom}, \"{speech}\"" targets = self.caller.location.contents send_emote(self.caller, targets, full_speech, msg_type="say", anonymous_add=None) class CmdThink(Command, NumberedTargetCommand): """Think a thought out loud. Usage: think 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 from 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)