Casting spells ... first, is donkey head
Spells can affect a characters speech and their appearance. All spells should create attributes with a 'effect' category, and spell scripts will clean up after they are stopped.
This commit is contained in:
parent
0a955fe2b6
commit
951d35356d
8 changed files with 411 additions and 247 deletions
|
|
@ -21,7 +21,7 @@ from evennia.contrib.rpg.rpsystem import RPSystemCmdSet
|
|||
from evennia.contrib.rpg.character_creator.character_creator import ContribChargenCmdSet
|
||||
from commands.sittables import CmdNoSitStand
|
||||
from commands.everyone import CmdTake, CmdThink, CmdSay, CmdWhisper
|
||||
from commands.wizards import CmdGM, CmdGMTrigger
|
||||
from commands.wizards import CmdGM, CmdSpell, CmdGMTrigger
|
||||
|
||||
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||
"""
|
||||
|
|
@ -46,6 +46,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
|||
self.add(CmdSay)
|
||||
self.add(CmdWhisper)
|
||||
self.add(CmdGM)
|
||||
self.add(CmdSpell)
|
||||
self.add(CmdGMTrigger)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,29 @@ 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
|
||||
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):
|
||||
|
|
@ -146,12 +168,19 @@ class CmdSay(MuxCommand):
|
|||
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}, \"{speech}\""
|
||||
full_speech = f"You {adverb}{verb}{to_whom}, \"{for_me}\""
|
||||
self.caller.msg(full_speech, from_obj=self.caller)
|
||||
|
||||
# English is weird...
|
||||
|
|
@ -160,7 +189,7 @@ class CmdSay(MuxCommand):
|
|||
|
||||
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}, \"{speech}\""
|
||||
full_speech = f"/Me {adverb}{verb}s{to_whom}, \"{for_others}\""
|
||||
send_emote(self.caller, targets, full_speech, msg_type="say", anonymous_add=None, quiet=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
from re import match
|
||||
|
||||
from evennia import CmdSet
|
||||
from evennia import CmdSet, create_script
|
||||
from evennia.utils import delay, logger
|
||||
from evennia.commands.default.muxcommand import MuxCommand
|
||||
from evennia.contrib.rpg.rpsystem import send_emote
|
||||
|
||||
from .command import Command
|
||||
from typeclasses.scripts import DonkeyHeadSpell
|
||||
from utils.word_list import routput
|
||||
|
||||
class CmdFly(Command):
|
||||
|
|
@ -65,8 +67,42 @@ class CmdGM(MuxCommand):
|
|||
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}")
|
||||
|
||||
class CmdSpell(Command):
|
||||
key = "spell"
|
||||
aliases = ['cast']
|
||||
locks = "cmd:perm(gm) or perm(Admin)"
|
||||
|
||||
def parse(self):
|
||||
self.spell = None
|
||||
self.target = None
|
||||
|
||||
m = match(r"([^ ]+)( +on +(.+))?", self.args.strip())
|
||||
if m:
|
||||
self.spell = m.group(1)
|
||||
self.target = m.group(3)
|
||||
|
||||
def func(self):
|
||||
caster = self.caller
|
||||
if not self.spell:
|
||||
caster.msg('Usage: cast <spell> [on <target>]')
|
||||
return
|
||||
|
||||
char = None
|
||||
if self.target:
|
||||
char = caster.search(self.target)
|
||||
if not char:
|
||||
return
|
||||
|
||||
if self.spell == 'donkey' and char:
|
||||
create_script(key="donkey_head",
|
||||
typeclass=DonkeyHeadSpell,
|
||||
interval=130,
|
||||
start_delay=True,
|
||||
attributes=[("target", char)])
|
||||
caster.msg(f"You cast |wHead of Donkey|n on {char}")
|
||||
else:
|
||||
caster.msg(f"You fail to cast {self.spell}")
|
||||
|
||||
class CmdGMTrigger(Command):
|
||||
"""The trigger command kicks off a series of named events.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ creation commands.
|
|||
|
||||
"""
|
||||
|
||||
from re import match
|
||||
from re import match, compile
|
||||
|
||||
from evennia.contrib.game_systems.gendersub import GenderCharacter
|
||||
from evennia.contrib.rpg.rpsystem import ContribRPCharacter
|
||||
|
|
@ -16,7 +16,7 @@ from evennia.contrib.rpg.rpsystem import send_emote
|
|||
from evennia.prototypes.spawner import spawn
|
||||
from evennia.utils import delay # , logger
|
||||
|
||||
from utils.word_list import routput
|
||||
from utils.word_list import routput, choices
|
||||
from .objects import Object
|
||||
from .tutorial import TutorBird, TutorialState
|
||||
|
||||
|
|
@ -115,6 +115,51 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
|||
|
||||
self.msg(f"{victim.key} doesn't have a {to_take} you can take.")
|
||||
|
||||
def pronoun_subjective(self, uppercase=False):
|
||||
gender = self.attributes.get('gender')
|
||||
if gender == "male":
|
||||
results = 'He'
|
||||
elif gender == "female":
|
||||
results = 'She'
|
||||
elif gender == "neutral":
|
||||
results = 'It'
|
||||
else:
|
||||
results = 'They'
|
||||
|
||||
return results if uppercase else results.lower()
|
||||
|
||||
def gendered_text(self, text):
|
||||
"""
|
||||
Replace entries, like |s and |p with pronouns.
|
||||
Like 'he' and 'her'
|
||||
"""
|
||||
gender_rx = compile(r"(?<!\|)\|(?!\|)[sSoOpPaA]")
|
||||
return gender_rx.sub(lambda x: self._get_pronoun(x), text)
|
||||
|
||||
def return_appearance(self, looker, **kwargs):
|
||||
"""
|
||||
Can be overridden or appended with an effect.
|
||||
Does the looker affect this?
|
||||
"""
|
||||
# To replace, temporarily, a description:
|
||||
# @set woman/temp_desc:effect = "They fade away from view."
|
||||
new_desc = self.attributes.get(category="effect",
|
||||
key="temp_desc")
|
||||
if new_desc:
|
||||
return self.gendered_text(new_desc)
|
||||
|
||||
pre_desc = self.attributes.get(category="effect",
|
||||
key="pre_desc") or ""
|
||||
post_desc = self.attributes.get(category="effect",
|
||||
key="post_desc") or ""
|
||||
reg_desc = super().return_appearance(looker)
|
||||
|
||||
pronoun = self.pronoun_subjective(True)
|
||||
return self.gendered_text(pre_desc + \
|
||||
reg_desc.replace('|wYou see:|n',
|
||||
'|S has') + \
|
||||
post_desc)
|
||||
|
||||
def at_pre_move(self, destination, *args, **kwargs):
|
||||
"""
|
||||
Called by self.move_to when trying to move somewhere. If this returns
|
||||
|
|
|
|||
|
|
@ -551,7 +551,7 @@ class BHB(Friendly):
|
|||
self.adjust_character(feeder, 40)
|
||||
feeder.has('berries').delete()
|
||||
else:
|
||||
msg = f"{noun} doesn't appear interesting in anything you have."
|
||||
msg = f"{noun} doesn't appear interested in anything you have."
|
||||
|
||||
feeder.msg(msg)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Puppet(Character):
|
|||
puppeting this Object.
|
||||
|
||||
"""
|
||||
self.msg("\nYou are puppeting |c{name}|n.\n".format(name=self.key))
|
||||
self.msg("\nYou are puppeting |c{name}|n.".format(name=self.key))
|
||||
self.msg((self.at_look(self.location), {"type": "look"}), options=None)
|
||||
|
||||
def at_post_unpuppet(self, account=None, session=None, **kwargs):
|
||||
|
|
|
|||
|
|
@ -145,3 +145,28 @@ Well, by sticky, we mean, wizardly-sticky...an absolutely amazing looking stick.
|
|||
})[0]
|
||||
stick.location = woods
|
||||
|
||||
|
||||
class Spell(Script):
|
||||
"""
|
||||
A script to clean up the effects of a spell.
|
||||
"""
|
||||
def at_stop(self, **kwargs):
|
||||
target = self.attributes.get("target")
|
||||
target.attributes.clear(category="effect")
|
||||
self.delete()
|
||||
|
||||
class DonkeyHeadSpell(Spell):
|
||||
def at_start(self, **kwargs):
|
||||
target = self.attributes.get("target")
|
||||
target.attributes.add(
|
||||
"donkied",
|
||||
"Heehaw! ;; Heehaw, heehaw!",
|
||||
category="effect")
|
||||
target.attributes.add(
|
||||
"post_desc",
|
||||
"\nOh, and |s has a donkey's head!",
|
||||
category="effect")
|
||||
target.msg("You suddenly feel quite peculiar.")
|
||||
|
||||
def at_repeat(self, **kwargs):
|
||||
self.stop()
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue