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 evennia.contrib.rpg.character_creator.character_creator import ContribChargenCmdSet
|
||||||
from commands.sittables import CmdNoSitStand
|
from commands.sittables import CmdNoSitStand
|
||||||
from commands.everyone import CmdTake, CmdThink, CmdSay, CmdWhisper
|
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):
|
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||||
"""
|
"""
|
||||||
|
|
@ -46,6 +46,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||||
self.add(CmdSay)
|
self.add(CmdSay)
|
||||||
self.add(CmdWhisper)
|
self.add(CmdWhisper)
|
||||||
self.add(CmdGM)
|
self.add(CmdGM)
|
||||||
|
self.add(CmdSpell)
|
||||||
self.add(CmdGMTrigger)
|
self.add(CmdGMTrigger)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,29 @@ from evennia.commands.default.muxcommand import MuxCommand
|
||||||
from evennia.contrib.rpg.rpsystem import send_emote
|
from evennia.contrib.rpg.rpsystem import send_emote
|
||||||
from evennia.utils import iter_to_str, logger
|
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):
|
class CmdWhisper(MuxCommand):
|
||||||
|
|
@ -146,12 +168,19 @@ class CmdSay(MuxCommand):
|
||||||
else:
|
else:
|
||||||
verb = "say"
|
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',
|
# 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 say ...', we have to both send him a message with the
|
||||||
# 'You' as well as everyone else with the 'send_emote'.
|
# '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 ''
|
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)
|
self.caller.msg(full_speech, from_obj=self.caller)
|
||||||
|
|
||||||
# English is weird...
|
# English is weird...
|
||||||
|
|
@ -160,7 +189,7 @@ class CmdSay(MuxCommand):
|
||||||
|
|
||||||
targets = [item for item in self.caller.location.contents if item != self.caller]
|
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 ''
|
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)
|
send_emote(self.caller, targets, full_speech, msg_type="say", anonymous_add=None, quiet=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
from re import match
|
from re import match
|
||||||
|
|
||||||
from evennia import CmdSet
|
from evennia import CmdSet, create_script
|
||||||
from evennia.utils import delay, logger
|
from evennia.utils import delay, logger
|
||||||
from evennia.commands.default.muxcommand import MuxCommand
|
from evennia.commands.default.muxcommand import MuxCommand
|
||||||
|
from evennia.contrib.rpg.rpsystem import send_emote
|
||||||
|
|
||||||
from .command import Command
|
from .command import Command
|
||||||
|
from typeclasses.scripts import DonkeyHeadSpell
|
||||||
from utils.word_list import routput
|
from utils.word_list import routput
|
||||||
|
|
||||||
class CmdFly(Command):
|
class CmdFly(Command):
|
||||||
|
|
@ -65,8 +67,42 @@ class CmdGM(MuxCommand):
|
||||||
elif o.is_typeclass('typeclasses.characters.Character'):
|
elif o.is_typeclass('typeclasses.characters.Character'):
|
||||||
o.msg(self.args)
|
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):
|
class CmdGMTrigger(Command):
|
||||||
"""The trigger command kicks off a series of named events.
|
"""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.game_systems.gendersub import GenderCharacter
|
||||||
from evennia.contrib.rpg.rpsystem import ContribRPCharacter
|
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.prototypes.spawner import spawn
|
||||||
from evennia.utils import delay # , logger
|
from evennia.utils import delay # , logger
|
||||||
|
|
||||||
from utils.word_list import routput
|
from utils.word_list import routput, choices
|
||||||
from .objects import Object
|
from .objects import Object
|
||||||
from .tutorial import TutorBird, TutorialState
|
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.")
|
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):
|
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
|
||||||
|
|
|
||||||
|
|
@ -551,7 +551,7 @@ class BHB(Friendly):
|
||||||
self.adjust_character(feeder, 40)
|
self.adjust_character(feeder, 40)
|
||||||
feeder.has('berries').delete()
|
feeder.has('berries').delete()
|
||||||
else:
|
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)
|
feeder.msg(msg)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class Puppet(Character):
|
||||||
puppeting this Object.
|
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)
|
self.msg((self.at_look(self.location), {"type": "look"}), options=None)
|
||||||
|
|
||||||
def at_post_unpuppet(self, account=None, session=None, **kwargs):
|
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]
|
})[0]
|
||||||
stick.location = woods
|
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