Muttering and or, Singing NPCs
NPCs can, after a delay, state or do a few things from a file.
This commit is contained in:
parent
a5d88da4a8
commit
c7825731f2
1 changed files with 124 additions and 2 deletions
|
|
@ -12,12 +12,16 @@ just overloads its hooks to have it perform its function.
|
|||
|
||||
"""
|
||||
from enum import Enum
|
||||
from itertools import cycle
|
||||
from pathlib import Path
|
||||
from random import choice
|
||||
|
||||
from evennia.scripts.scripts import DefaultScript
|
||||
from evennia.prototypes.spawner import spawn
|
||||
from evennia.utils import logger
|
||||
from evennia.utils import logger, delay
|
||||
|
||||
from typeclasses.characters import Character
|
||||
|
||||
from .characters import Character
|
||||
|
||||
class Script(DefaultScript):
|
||||
"""
|
||||
|
|
@ -159,6 +163,7 @@ class Spell(Script):
|
|||
target.attributes.clear(category="effect")
|
||||
self.delete()
|
||||
|
||||
|
||||
class DonkeyHeadSpell(Spell):
|
||||
def at_start(self, **kwargs):
|
||||
target = self.attributes.get("target")
|
||||
|
|
@ -174,3 +179,120 @@ class DonkeyHeadSpell(Spell):
|
|||
|
||||
def at_repeat(self, **kwargs):
|
||||
self.stop()
|
||||
|
||||
|
||||
class Muttering(Script):
|
||||
"""
|
||||
Script to have an objects 'emote' phrases in sequence.
|
||||
|
||||
First add settings to the 'npc', for instance:
|
||||
|
||||
@set npc/muttering_interval = 120 # for 2 minutes
|
||||
@set npc/muttering_gap = 5 # for 5 seconds per sequence
|
||||
@set npc/muttering_formats = [
|
||||
"sings to |oself as if no one is listening, \"{0}\"",
|
||||
"continues to sing to |oself, \"{0}\"",
|
||||
"croons to |oself, \"{0}\"",
|
||||
"finishes |p verse, \"{0}\"|/",
|
||||
]
|
||||
@set npc/muttering_file = "song-lyrics.txt"
|
||||
|
||||
Then start the script by running the following:
|
||||
|
||||
@script npc = typeclasses.scripts.Muttering
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
self.key = "muttering"
|
||||
self.desc = "NPCs that Mutter"
|
||||
self.interval = self.obj.db.muttering_interval or 300 # seconds
|
||||
self.start_delay = False
|
||||
self.persistent = True
|
||||
self.reload()
|
||||
|
||||
def reload(self):
|
||||
self.db.mutter_delay_gap = self.obj.db.muttering_gap or 7
|
||||
self.db.mutter_sequence_index = 0
|
||||
mutter_file = self.obj.db.muttering_file
|
||||
if mutter_file:
|
||||
logger.info(f"Reading muttering file, {mutter_file}")
|
||||
self.db.mutters = self.load_mutter(mutter_file)
|
||||
|
||||
def at_repeat(self, **kwargs):
|
||||
"""
|
||||
If we have passengers, we need to sail...
|
||||
"""
|
||||
self.mutter_sequence()
|
||||
|
||||
def mutter_sequence(self):
|
||||
# if not hasattr(self, 'mutter_sequence_index'):
|
||||
# self.db.mutter_sequence_index = 0
|
||||
|
||||
if self.db.mutter_sequence_index < len(self.db.mutters):
|
||||
sequences = self.db.mutters[self.db.mutter_sequence_index]
|
||||
self.db.mutter_sequence_index += 1
|
||||
else:
|
||||
sequences = self.db.mutters[0]
|
||||
self.db.mutter_sequence_index = 1
|
||||
|
||||
formats = self.refresh_mutter_formats()
|
||||
zip_list = zip(sequences, cycle(formats)) \
|
||||
if len(sequences) > len(formats) \
|
||||
else zip(sequences, formats[:len(sequences)])
|
||||
|
||||
for idx, tup in enumerate(zip_list):
|
||||
logger.info(f"delay({idx} * {self.db.mutter_delay_gap}, self.mutter, {tup[0]}, {tup[1]})")
|
||||
delay(idx * self.db.mutter_delay_gap,
|
||||
self.mutter, tup[0], tup[1])
|
||||
|
||||
def mutter(self, phrase, msg_format):
|
||||
"""
|
||||
Mutter something aloud to the room the NPC resides.
|
||||
|
||||
Why wait for input from other characters when the NPC can
|
||||
pretend to be real.
|
||||
"""
|
||||
thing = self.obj
|
||||
room = thing.location
|
||||
name = choice([
|
||||
thing.key,
|
||||
thing.db._sdesc or thing.name,
|
||||
thing.key.split(" ")[-1]
|
||||
])
|
||||
|
||||
if thing.db.article:
|
||||
prefix = f"{thing.db.article} {name} {msg_format}"
|
||||
else:
|
||||
prefix = f"{name} {msg_format}"
|
||||
|
||||
if phrase:
|
||||
room.msg_contents(
|
||||
prefix.format(phrase),
|
||||
from_obj=self.obj)
|
||||
|
||||
def refresh_mutter_formats(self):
|
||||
return self.obj.db.muttering_formats or [
|
||||
"mutters as if no one is listening, \"{0}\"",
|
||||
"grumbles to |oself, \"{0}\"",
|
||||
"continues to mutter to |oself, \"{0}\"",
|
||||
"murmurs to |oself, \"{0}\"",
|
||||
"mutters to |oself, \"{0}\"|/",
|
||||
]
|
||||
|
||||
def load_mutter(self, data_file):
|
||||
"""
|
||||
Return 'data_file' and return a list of lists.
|
||||
|
||||
Where a blank line in the data file separates the list of
|
||||
lines from others.
|
||||
"""
|
||||
path = Path(__file__).with_name(data_file)
|
||||
mutters = []
|
||||
with open(path) as file:
|
||||
curr_mutter = []
|
||||
for line in file:
|
||||
if line.strip() == "":
|
||||
mutters = mutters + [curr_mutter]
|
||||
curr_mutter = []
|
||||
else:
|
||||
curr_mutter.append(line.strip())
|
||||
return mutters
|
||||
|
|
|
|||
Loading…
Reference in a new issue