Create new dynamic say command
This also includes a 'gm' command that should make GMing a game better.
This commit is contained in:
parent
600542b0d4
commit
6b8a9e946b
10 changed files with 374 additions and 264 deletions
|
|
@ -19,7 +19,8 @@ from evennia.contrib.grid import extended_room
|
||||||
from evennia.contrib.game_systems.gendersub import SetGender
|
from evennia.contrib.game_systems.gendersub import SetGender
|
||||||
from evennia.contrib.rpg.rpsystem import RPSystemCmdSet
|
from evennia.contrib.rpg.rpsystem import RPSystemCmdSet
|
||||||
from commands.sittables import CmdNoSitStand
|
from commands.sittables import CmdNoSitStand
|
||||||
from commands.everyone import CmdTake, CmdThink
|
from commands.everyone import CmdTake, CmdThink, CmdSay
|
||||||
|
from commands.wizards import CmdGM
|
||||||
|
|
||||||
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||||
"""
|
"""
|
||||||
|
|
@ -41,6 +42,8 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||||
self.add(SetGender())
|
self.add(SetGender())
|
||||||
self.add(RPSystemCmdSet())
|
self.add(RPSystemCmdSet())
|
||||||
self.add(extended_room.ExtendedRoomCmdSet)
|
self.add(extended_room.ExtendedRoomCmdSet)
|
||||||
|
self.add(CmdSay())
|
||||||
|
self.add(CmdGM)
|
||||||
|
|
||||||
|
|
||||||
class AccountCmdSet(default_cmds.AccountCmdSet):
|
class AccountCmdSet(default_cmds.AccountCmdSet):
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,92 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from random import random
|
from random import random
|
||||||
|
from re import split
|
||||||
|
|
||||||
from commands.command import Command
|
from commands.command import Command
|
||||||
from evennia.commands.default.general import NumberedTargetCommand
|
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
|
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):
|
class CmdThink(Command, NumberedTargetCommand):
|
||||||
"""Think a thought out loud.
|
"""Think a thought out loud.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from .command import Command
|
|
||||||
from evennia import CmdSet
|
from evennia import CmdSet
|
||||||
|
from evennia.utils import logger
|
||||||
|
from evennia.commands.default.muxcommand import MuxCommand
|
||||||
|
|
||||||
|
from .command import Command
|
||||||
|
|
||||||
|
|
||||||
class CmdFly(Command):
|
class CmdFly(Command):
|
||||||
|
|
@ -18,12 +21,46 @@ class CmdFly(Command):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
key = "^fly"
|
key = "^fly"
|
||||||
|
locks = "call:all()"
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
self.caller.do_fly(self.args.strip())
|
self.caller.do_fly(self.args.strip())
|
||||||
|
|
||||||
|
|
||||||
class CmdSetWizardSpells(CmdSet):
|
class CmdSetWand(CmdSet):
|
||||||
|
"""
|
||||||
|
All wizard spells are tied to a 'wand' that might be flavored.
|
||||||
|
"""
|
||||||
|
key = "Wand"
|
||||||
|
|
||||||
def at_cmdset_creation(self):
|
def at_cmdset_creation(self):
|
||||||
super().at_cmdset_creation()
|
super().at_cmdset_creation()
|
||||||
self.add(CmdFly)
|
self.add(CmdFly)
|
||||||
|
|
||||||
|
|
||||||
|
class CmdGM(MuxCommand):
|
||||||
|
"""
|
||||||
|
The gm command allows anything to be emoted into a room.
|
||||||
|
|
||||||
|
"""
|
||||||
|
key = "gm"
|
||||||
|
aliases = ["#"]
|
||||||
|
locks = "cmd:perm(gm) or perm(Admin)"
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
send_to = []
|
||||||
|
for switch in self.switches:
|
||||||
|
o = self.caller.search(switch, global_search=True)
|
||||||
|
if o:
|
||||||
|
send_to = send_to + [o]
|
||||||
|
|
||||||
|
if not send_to:
|
||||||
|
send_to = [self.caller.location]
|
||||||
|
|
||||||
|
for o in send_to:
|
||||||
|
if o.is_typeclass('typeclasses.rooms.Room'):
|
||||||
|
o.msg_contents(self.args)
|
||||||
|
elif o.is_typeclass('typeclasses.characters.Character'):
|
||||||
|
o.msg(self.args)
|
||||||
|
|
||||||
|
logger.info(f"switches = {self.switches} lhs={self.lhs} rhs={self.rhs} / args={self.args}")
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,11 @@ creation commands.
|
||||||
|
|
||||||
from re import match
|
from re import match
|
||||||
|
|
||||||
from evennia.objects.objects import DefaultCharacter
|
|
||||||
from evennia.contrib.game_systems.gendersub import GenderCharacter
|
from evennia.contrib.game_systems.gendersub import GenderCharacter
|
||||||
from evennia.contrib.rpg.rpsystem import ContribRPCharacter
|
from evennia.contrib.rpg.rpsystem import ContribRPCharacter
|
||||||
from evennia.prototypes.spawner import spawn
|
from evennia.prototypes.spawner import spawn
|
||||||
from evennia.utils import delay, logger
|
from evennia.utils import delay # , logger
|
||||||
|
|
||||||
from commands.wizards import CmdSetWizardSpells
|
|
||||||
from utils.word_list import routput
|
from utils.word_list import routput
|
||||||
from .objects import Object
|
from .objects import Object
|
||||||
from .tutorial import TutorBird, TutorialState
|
from .tutorial import TutorBird, TutorialState
|
||||||
|
|
@ -95,6 +93,9 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
||||||
letter.db.inside = READ_LETTER.format(self.name.capitalize())
|
letter.db.inside = READ_LETTER.format(self.name.capitalize())
|
||||||
letter.location = self
|
letter.location = self
|
||||||
|
|
||||||
|
def get_display_things(self, looker, *args, **kwargs):
|
||||||
|
return super().get_display_things(looker, pose=False)
|
||||||
|
|
||||||
def do_take(self, to_take, from_whom):
|
def do_take(self, to_take, from_whom):
|
||||||
"""
|
"""
|
||||||
A character has a _steal_command. What are the limitations?
|
A character has a _steal_command. What are the limitations?
|
||||||
|
|
@ -112,7 +113,7 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
||||||
|
|
||||||
self.msg(f"{victim.key} doesn't have a {to_take} you can take.")
|
self.msg(f"{victim.key} doesn't have a {to_take} you can take.")
|
||||||
|
|
||||||
def at_pre_move(self, destination, **kwargs):
|
def at_pre_move(self, destination, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Called by self.move_to when trying to move somewhere. If this returns
|
Called by self.move_to when trying to move somewhere. If this returns
|
||||||
False, the move is immediately canceled.
|
False, the move is immediately canceled.
|
||||||
|
|
@ -181,19 +182,7 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
||||||
# function call.
|
# function call.
|
||||||
return super().at_look(target)
|
return super().at_look(target)
|
||||||
|
|
||||||
class Wizard(Character):
|
def spell_sequence(self, location, messages, time_delay=1):
|
||||||
"""
|
|
||||||
Upgrade a character with the following features:
|
|
||||||
|
|
||||||
@update self = typeclasses.character.Wizard
|
|
||||||
"""
|
|
||||||
def at_object_creation(self):
|
|
||||||
"""
|
|
||||||
Called when character is getting promoted to wizardy.
|
|
||||||
"""
|
|
||||||
self.cmdset.add(CmdSetWizardSpells)
|
|
||||||
|
|
||||||
def spell_sequence(self, location, messages, time_delay):
|
|
||||||
"""
|
"""
|
||||||
Send one or more messages to 'location' with a delay.
|
Send one or more messages to 'location' with a delay.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ from evennia.commands.command import Command
|
||||||
from evennia.utils import utils
|
from evennia.utils import utils
|
||||||
|
|
||||||
from .objects import ObjectParent
|
from .objects import ObjectParent
|
||||||
|
from utils.word_list import choices
|
||||||
from commands.misc import CmdSetKnock
|
from commands.misc import CmdSetKnock
|
||||||
|
|
||||||
MOVE_DELAY = {"stroll": 6, "walk": 4, "run": 2, "sprint": 1}
|
MOVE_DELAY = {"stroll": 6, "walk": 4, "run": 2, "sprint": 1}
|
||||||
|
|
@ -56,7 +57,7 @@ class Exit(ObjectParent, DefaultExit):
|
||||||
if pre_check:
|
if pre_check:
|
||||||
moving = SPEED_DESCS[move_speed]
|
moving = SPEED_DESCS[move_speed]
|
||||||
if self.db.traverse_msg:
|
if self.db.traverse_msg:
|
||||||
msg = f"\n{self.db.traverse_msg}\n".format(move_speed, moving)
|
msg = choices(f"\n{self.db.traverse_msg}\n", move_speed, moving)
|
||||||
else:
|
else:
|
||||||
if self.key in ['north', 'south', 'east', 'west']:
|
if self.key in ['north', 'south', 'east', 'west']:
|
||||||
msg = f"You start {moving} {self.key}."
|
msg = f"You start {moving} {self.key}."
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
from evennia import gametime
|
|
||||||
from evennia.utils import delay, logger
|
|
||||||
from evennia.contrib.rpg.rpsystem import ContribRPObject
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Object
|
Object
|
||||||
|
|
||||||
|
|
@ -15,8 +8,8 @@ Use the ObjectParent class to implement common features for *all* entities
|
||||||
with a location in the game world (like Characters, Rooms, Exits).
|
with a location in the game world (like Characters, Rooms, Exits).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from evennia.contrib.rpg.rpsystem.rpsystem import ContribRPObject
|
||||||
from evennia.objects.objects import DefaultObject
|
from evennia.utils import delay
|
||||||
# from evennia.utils import delay, logger, search
|
# from evennia.utils import delay, logger, search
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,6 +23,8 @@ class ObjectParent:
|
||||||
take precedence.
|
take precedence.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
def get_display_footer(self, _, **kwargs):
|
||||||
|
return "\n"
|
||||||
|
|
||||||
|
|
||||||
class Object(ObjectParent, ContribRPObject):
|
class Object(ObjectParent, ContribRPObject):
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,6 @@ class Pet(Object):
|
||||||
TICKER_HANDLER.add(interval=60, callback=self.update_state)
|
TICKER_HANDLER.add(interval=60, callback=self.update_state)
|
||||||
super().at_object_creation()
|
super().at_object_creation()
|
||||||
|
|
||||||
|
|
||||||
def hunger(self):
|
def hunger(self):
|
||||||
if self.db.hunger_level < Hunger.RAVENOUS.value:
|
if self.db.hunger_level < Hunger.RAVENOUS.value:
|
||||||
return Hunger.RAVENOUS
|
return Hunger.RAVENOUS
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,13 @@ class Room(ObjectParent, ExtendedRoom, ContribRPRoom):
|
||||||
def get_display_characters(self, looker, *args, **kwargs):
|
def get_display_characters(self, looker, *args, **kwargs):
|
||||||
num_chars = len(self.contents_get(content_type="character"))
|
num_chars = len(self.contents_get(content_type="character"))
|
||||||
char_list = super().get_display_characters(looker, pose=True)
|
char_list = super().get_display_characters(looker, pose=True)
|
||||||
|
if len(self.filter_visible(self.contents_get(content_type="object"), looker, **kwargs)) > 0:
|
||||||
|
also = 'also '
|
||||||
|
else:
|
||||||
|
also = ''
|
||||||
|
|
||||||
if num_chars > 2:
|
if num_chars > 2:
|
||||||
return "You notice the following characters:\n" + char_list
|
return f"You {also}see the following characters:\n" + char_list
|
||||||
if num_chars > 1:
|
if num_chars > 1:
|
||||||
character = char_list.strip()
|
character = char_list.strip()
|
||||||
if character.startswith('|'):
|
if character.startswith('|'):
|
||||||
|
|
@ -74,15 +79,19 @@ class Room(ObjectParent, ExtendedRoom, ContribRPRoom):
|
||||||
comp_char = character.lower()
|
comp_char = character.lower()
|
||||||
|
|
||||||
if match(r"an? |the ", comp_char):
|
if match(r"an? |the ", comp_char):
|
||||||
return "You notice " + character
|
return f"You {also}see {character}"
|
||||||
elif match(r"[aeiou]", comp_char):
|
elif match(r"[aeiou]", comp_char):
|
||||||
return "You notice an " + character
|
return f"You {also}see an {character}"
|
||||||
else:
|
else:
|
||||||
return "You notice a " + character
|
return f"You {also}see a {character}"
|
||||||
|
return ''
|
||||||
|
|
||||||
def get_display_things(self, looker, *args, **kwargs):
|
def get_display_things(self, looker, *args, **kwargs):
|
||||||
return super().get_display_things(looker, pose=False)
|
std_msg = super().get_display_things(looker, pose=False)
|
||||||
|
if std_msg:
|
||||||
|
return std_msg.replace('|wYou see:|n', 'You notice')
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
class DabblersRoom(Room):
|
class DabblersRoom(Room):
|
||||||
def get_display_desc(self, looker):
|
def get_display_desc(self, looker):
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from evennia import create_script
|
||||||
from evennia.utils import logger, delay
|
from evennia.utils import logger, delay
|
||||||
|
|
||||||
from commands.misc import CmdSetPuddle, CmdSetStick, CmdSetKnock
|
from commands.misc import CmdSetPuddle, CmdSetStick, CmdSetKnock
|
||||||
|
from commands.wizards import CmdSetWand
|
||||||
from utils.word_list import routput, choices
|
from utils.word_list import routput, choices
|
||||||
from .scripts import KnockScript
|
from .scripts import KnockScript
|
||||||
from .objects import Object
|
from .objects import Object
|
||||||
|
|
@ -168,6 +169,11 @@ class Stick(Object):
|
||||||
thrower.msg("I think you should be outside or a place with more room before you throw that stick around.")
|
thrower.msg("I think you should be outside or a place with more room before you throw that stick around.")
|
||||||
|
|
||||||
|
|
||||||
|
class Wand(Stick):
|
||||||
|
def at_object_creation(self):
|
||||||
|
self.cmdset.add_default(CmdSetWand)
|
||||||
|
|
||||||
|
|
||||||
class Puddle(Object):
|
class Puddle(Object):
|
||||||
def at_object_creation(self):
|
def at_object_creation(self):
|
||||||
self.cmdset.add_default(CmdSetPuddle)
|
self.cmdset.add_default(CmdSetPuddle)
|
||||||
|
|
@ -430,7 +436,7 @@ class Knocker(Object):
|
||||||
curr_state = Knocker_Convo(talker.db.knocker_conversation_state or 0)
|
curr_state = Knocker_Convo(talker.db.knocker_conversation_state or 0)
|
||||||
# message will be on the form `<Person> says, "say_text"`
|
# message will be on the form `<Person> says, "say_text"`
|
||||||
# we want to get only say_text without the quotes and any spaces
|
# we want to get only say_text without the quotes and any spaces
|
||||||
message = message.split('says, ')[1].strip(' "')
|
message = message.split('"')[1].strip()
|
||||||
|
|
||||||
# Let's see if a keyword gives a good response:
|
# Let's see if a keyword gives a good response:
|
||||||
for [regex, convo_state, responses, new_state] in self.all_responses:
|
for [regex, convo_state, responses, new_state] in self.all_responses:
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue