Advertisement
RianeSN

quests.py

Mar 21st, 2025 (edited)
329
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.03 KB | None | 0 0
  1. from evennia.utils import logger
  2. from evennia.utils.dbserialize import deserialize
  3. from copy import copy
  4. from evennia.objects.objects import DefaultObject
  5. from evennia.utils import string_partial_matching, string_suggestions
  6.  
  7. class HandlerBase:
  8.     def __init__(self, obj, db_attr, db_cat='quests', default_data={}): # obj = original quest object, default_data is all the data filled in on that quest
  9.         self.obj = obj # QuestHandler doesn't have it's own db so data wouldn't be persistent, thus would need to be loaded on initialization.
  10.         self._db_attr = db_attr # the character's self.db.quest attribute, which is an array of dicts
  11.         self._db_cat = db_cat # might not be needed for children, but useful for a global handler
  12.         self._data = copy(default_data) # making a copy of the data as is currently - copy vs ref so changes on this copy won't impact the real world ref and vice versa
  13.         self._load()
  14.  
  15.     def _load(self):
  16.         if data := self.obj.attributes.get(self._db_attr, category=self._db_cat): # create local 'data' var, search character for specified attribute ('quests' in this case)
  17.             self._data = deserialize(data) # basically loading the data from the database into a live instance
  18.  
  19.     def _save(self):
  20.         try:
  21.             self.obj.attributes.add(self._db_attr, self._data, category=self._db_cat) #taking the updated quest data in the instance we have and storing it in the player's db
  22.         except Exception as e:
  23.             logger.log_err(f"Could not save handler data for {type(self)} on {self.obj} (#{self.obj.pk})! Cached data may be corrupt; reloading from database.")
  24.             logger.log_err(f"Cached data was: {self._data}")
  25.             self._load()
  26.  
  27.  
  28. class QuestHandler(HandlerBase):
  29.     def __init__(self, obj):
  30.         super().__init__(obj, "quests")
  31.    
  32.     def _load(self):
  33.         super()._load()
  34.         loaded_data = {}
  35.         for key, data in self._data.items():  #creating an array of quest data loaded in from character's db.quest attribute
  36.             loaded_data[key] = QuestMaster(handler=self, **data) #using a Key:Value pair system, aka dict. ie: 'QuestID':'QuestData'
  37.        
  38.         self.data = loaded_data  # quest data is now initialized on the QuestHandler
  39.  
  40.     def __getattr__(self, attr):
  41.         if quest := self.get(attr):   # temp variable basically just getting/seeing if a certain attribute on this handler exists,
  42.             return quest  # probably because you can't search it like object attributes can be searched?
  43.         raise AttributeError(f"'{self.__name__}' object has no attribute '{attr}'")
  44.    
  45.     def _save(self, key=None):
  46.         if key and key in self.data.keys():
  47.             data = { k:v for k, v in vars(self.data[key]).items() if k != 'handler' }
  48.             self._data[key] = data
  49.         else:
  50.             flattened = {}
  51.             for key, clsobj in self.data.items():
  52.                 data = vars(clsobj)
  53.                 del data['handler']
  54.                 flattened[key] = data
  55.             self._data = flattened
  56.         super()._save()
  57.  
  58.  
  59.  
  60. class QuestMaster:
  61.     parent = None # Unsure what this is for? Maybe attaching to an object?
  62.     child = None # Unsure what this is for?
  63.  
  64.     def __init__(self, handler, name, key, **kwargs):
  65.         # Handler ref here is used at line 36 in the handler when loading data from the quest to the handler.
  66.         # The data itself is being passed from the handler to create a populated instance of this quest.
  67.         self.handler = handler
  68.         self.name = name
  69.         self.key = key
  70.  
  71.         self.QuestID = 0
  72.         self.QuestName = ""  # Public facing name. If quest is TalkToTom3 it might be "Talk to Tom Again"
  73.         self.QuestDesc = "" # Shows up in the quest log when selecting this specific quest.
  74.         self.Requirements = []  # Other quests needed to be completed (by ID) to do this quest.
  75.  
  76.         #################################
  77.         #          Text Msgs
  78.         #################################
  79.         self.QuestOffer = ""
  80.         self.QuestRejected = ""
  81.         self.QuestAccepted = ""
  82.         self.QuestActive = ""
  83.         self.QuestTurnIn = ""
  84.         self.QuestCompleted = ""
  85.  
  86.         #################################
  87.         #          IDs
  88.         #################################
  89.         self.QuestTypeID =  0 #  0='collect', 1='kill', 2='interact' 3='location'
  90.         self.QuestGiverID = 0 # ID of the object or NPC giving this quest
  91.         self.QuestTurnInID = 0 # either the ID of the location on auto-turn in, or the ID of the NPC the quest is turned in with
  92.  
  93.         #################################
  94.         #          Text Msgs
  95.         #################################
  96.         self.Rewards = []
  97.  
  98.         for key, val in kwargs.items():   # loops through every attribute passed to this quest instance to populate it with the passed through data. Very versatile.
  99.             if callable(getattr(self, key, None)):
  100.                 continue
  101.             setattr(self, key, val)
  102.    
  103.     def __str__(self):
  104.         return self.name
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement