Source code for evennia.scripts.scripthandler

"""
The script handler makes sure to check through all stored scripts to
make sure they are still relevant. A scripthandler is automatically
added to all game objects. You access it through the property
`scripts` on the game object.

"""

from django.utils.translation import gettext as _
from evennia.scripts.models import ScriptDB
from evennia.utils import create, logger


[docs]class ScriptHandler(object): """ Implements the handler. This sits on each game object. """
[docs] def __init__(self, obj): """ Set up internal state. Args: obj (Object): A reference to the object this handler is attached to. """ self.obj = obj
def __str__(self): """ List the scripts tied to this object. """ scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj) string = "" for script in scripts: interval = "inf" next_repeat = "inf" repeats = "inf" if script.interval > 0: interval = script.interval if script.repeats: repeats = script.repeats try: next_repeat = script.time_until_next_repeat() except Exception: next_repeat = "?" string += _("\n '{key}' ({next_repeat}/{interval}, {repeats} repeats): {desc}").format( key=script.key, next_repeat=next_repeat, interval=interval, repeats=repeats, desc=script.desc, ) return string.strip()
[docs] def add(self, scriptclass, key=None, autostart=True): """ Add a script to this object. Args: scriptclass (Scriptclass, Script or str): Either a class object inheriting from DefaultScript, an instantiated script object or a python path to such a class object. key (str, optional): Identifier for the script (often set in script definition and listings) autostart (bool, optional): Start the script upon adding it. Returns: Script: The newly created Script. """ if isinstance(scriptclass, str) or callable(scriptclass): # a str or class to use create before adding to an Object. We wait to autostart # so we can differentiate a failing creation from a script that immediately starts/stops. if self.obj.__dbclass__.__name__ == "AccountDB": # we add to an Account, not an Object script = create.create_script( scriptclass, key=key, account=self.obj, autostart=False ) else: script = create.create_script(scriptclass, key=key, obj=self.obj, autostart=False) else: # already an instantiated class script = scriptclass if script.db_obj and script.db_obj != self.obj: logger.log_err( f"Script instance {script} already belongs to " f"another object: {script.db_obj}." ) return None script.db_obj = self.obj script.save() if not script: logger.log_err(f"Script {scriptclass} failed to be created.") return None if autostart: script.start() if not script.id: # this can happen if the script has repeats=1 or calls stop() in at_repeat. logger.log_info( f"Script {scriptclass} started and then immediately stopped; " "it could probably be a normal function." ) return script
[docs] def start(self, key): """ Find scripts and force-start them Args: key (str): The script's key or dbref. Returns: nr_started (int): The number of started scripts found. """ scripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=key) num = 0 for script in scripts: script.start() num += 1 return num
[docs] def has(self, key): """ Determine if a given script exists on this object. Args: key (str): Search criterion, the script's key or dbref. Returns: bool: If the script exists or not. """ return ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=key).exists()
[docs] def get(self, key): """ Search scripts on this object. Args: key (str): Search criterion, the script's key or dbref. Returns: scripts (queryset): The found scripts matching `key`. """ return ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=key)
[docs] def remove(self, key=None): """ Forcibly delete a script from this object. Args: key (str, optional): A script key or the path to a script (in the latter case all scripts with this path will be deleted!) If no key is given, delete *all* scripts on the object! """ delscripts = ScriptDB.objects.get_all_scripts_on_obj(self.obj, key=key) if not delscripts: delscripts = [ script for script in ScriptDB.objects.get_all_scripts_on_obj(self.obj) if script.path == key ] num = 0 for script in delscripts: script.delete() num += 1 return num
# legacy aliases to remove delete = remove stop = delete
[docs] def all(self): """ Get all scripts stored in this handler. """ return ScriptDB.objects.get_all_scripts_on_obj(self.obj)