From 03d415beb126900ae58492a8fa1e0067e13865a0 Mon Sep 17 00:00:00 2001 From: Griatch Date: Tue, 15 Dec 2015 19:26:11 +0100 Subject: [PATCH] Fixed errors due to the removal of execute_cmd("look") calls in the latest revisions - this turns out to bypass the normal use of cmdsets to control things like the dark room in the tutorial. Resolves the second mentioned error in #889. --- evennia/contrib/tutorial_world/rooms.py | 20 ++++++++++++++------ evennia/objects/models.py | 16 +++++++++++----- evennia/objects/objects.py | 3 ++- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/evennia/contrib/tutorial_world/rooms.py b/evennia/contrib/tutorial_world/rooms.py index d18fa4db4..6f24da666 100644 --- a/evennia/contrib/tutorial_world/rooms.py +++ b/evennia/contrib/tutorial_world/rooms.py @@ -15,7 +15,7 @@ from evennia import TICKER_HANDLER from evennia import CmdSet, Command, DefaultRoom from evennia import utils, create_object, search_object from evennia import syscmdkeys, default_cmds -from evennia.contrib.tutorial_world.objects import LightSource, TutorialObject +from evennia.contrib.tutorial_world.objects import LightSource # the system error-handling module is defined in the settings. We load the # given setting here using utils.object_from_module. This way we can use @@ -831,7 +831,7 @@ class DarkRoom(TutorialRoom): if there is a light-giving object in the room overall (like if a splinter was dropped in the room) """ - return obj.is_superuser or obj.db.is_giving_light or obj.is_superuser or any(o for o in obj.contents if o.db.is_giving_light) + return obj.is_superuser or obj.db.is_giving_light or any(o for o in obj.contents if o.db.is_giving_light) def _heal(self, character): """ @@ -840,14 +840,18 @@ class DarkRoom(TutorialRoom): health = character.db.health_max or 20 character.db.health = health - def check_light_state(self): + def check_light_state(self, exclude=None): """ This method checks if there are any light sources in the room. If there isn't it makes sure to add the dark cmdset to all characters in the room. It is called whenever characters enter the room and also by the Light sources when they turn on. + + Args: + exclude (Object): An object to not include in the light check. """ - if any(self._carries_light(obj) for obj in self.contents): + if any(self._carries_light(obj) for obj in self.contents if obj != exclude): + self.locks.add("view:all()") self.cmdset.remove(DarkCmdSet) self.db.is_lit = True for char in (obj for obj in self.contents if obj.has_player): @@ -856,6 +860,7 @@ class DarkRoom(TutorialRoom): else: # noone is carrying light - darken the room self.db.is_lit = False + self.locks.add("view:false()") self.cmdset.add(DarkCmdSet, permanent=True) for char in (obj for obj in self.contents if obj.has_player): if char.is_superuser: @@ -872,7 +877,7 @@ class DarkRoom(TutorialRoom): # a puppeted object, that is, a Character self._heal(obj) # in case the new guy carries light with them - self.check_light_state() + self.check_light_state() def at_object_leave(self, obj, target_location): """ @@ -880,7 +885,10 @@ class DarkRoom(TutorialRoom): DarkCmdSet if necessary. This also works if they are teleported away. """ - self.check_light_state() + # since this hook is called while the object is still in the room, + # we exclude it from the light check, to ignore any light sources + # it may be carrying. + self.check_light_state(exclude=obj) #------------------------------------------------------------ diff --git a/evennia/objects/models.py b/evennia/objects/models.py index aea943971..36aeda1e4 100644 --- a/evennia/objects/models.py +++ b/evennia/objects/models.py @@ -52,7 +52,7 @@ class ContentsHandler(object): """ self._pkcache.update(dict((obj.pk, None) for obj in - ObjectDB.objects.filter(db_location=self.obj))) + ObjectDB.objects.filter(db_location=self.obj) if obj.pk)) def get(self, exclude=None): """ @@ -65,16 +65,22 @@ class ContentsHandler(object): objects (list): the Objects inside this location """ - pks = list(self._pkcache) if exclude: - pks = [pk for pk in pks if pk not in [excl.pk for excl in make_iter(exclude)]] + pks = [pk for pk in self._pkcache if pk not in [excl.pk for excl in make_iter(exclude)]] + else: + pks = self._pkcache try: return [self._idcache[pk] for pk in pks] except KeyError: # this can happen if the idmapper cache was cleared for an object # in the contents cache. If so we need to re-initialize and try again. self.init() - return self.get(exclude=exclude) + try: + return [self._idcache[pk] for pk in pks] + except KeyError: + # this means an actual failure of caching. Return real database match. + logger.logerr("contents cache failed for %s." % (self.obj.key)) + return list(ObjectDB.objects.filter(db_location=self.obj)) def add(self, obj): """ @@ -102,7 +108,7 @@ class ContentsHandler(object): """ self._pkcache = {} - self._init() + self.init() #------------------------------------------------------------ # diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 712f20fc7..6e01556e1 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -1418,7 +1418,8 @@ class DefaultCharacter(DefaultObject): We make sure to look around after a move. """ - self.msg(self.at_look(self.location)) + if self.location.access(self, "view"): + self.msg(self.at_look(self.location)) def at_pre_puppet(self, player, session=None): """