diff --git a/direct/src/level/DistributedLevel.py b/direct/src/level/DistributedLevel.py index bbc7053899..18d8510542 100755 --- a/direct/src/level/DistributedLevel.py +++ b/direct/src/level/DistributedLevel.py @@ -265,7 +265,6 @@ class DistributedLevel(DistributedObject.DistributedObject, # if no viz, listen to all the zones if not DistributedLevel.WantVisibility: zones = list(self.zoneNums) - #zones.remove(0) self.sendSetZone(0, zones) def toonEnterZone(self, zoneNum): diff --git a/direct/src/level/DistributedLevelAI.py b/direct/src/level/DistributedLevelAI.py index 34b78da883..8cac14cdcf 100755 --- a/direct/src/level/DistributedLevelAI.py +++ b/direct/src/level/DistributedLevelAI.py @@ -107,3 +107,14 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI, self.destroyLevel() DistributedObjectAI.DistributedObjectAI.delete(self) + + if __debug__: + # level editors should call this func to tweak attributes of level + # entities + def setAttribChange(self, entId, attribName, value): + # send a copy to the client-side level obj + self.sendUpdate('setAttribChange', + [entId, attribName, repr(value)]) + + entity = self.getEntity(entId) + entity.handleAttribChange(attribName, value) diff --git a/direct/src/level/Entity.py b/direct/src/level/Entity.py index 529b048888..b6154e699e 100755 --- a/direct/src/level/Entity.py +++ b/direct/src/level/Entity.py @@ -1,10 +1,13 @@ """Entity.py: contains the Entity class""" import string +import DirectNotifyGlobal +from PythonUtil import lineInfo class Entity: """Entity is the base class for all objects that exist in a Level and can be edited with the LevelEditor.""" + notify = DirectNotifyGlobal.directNotify.newCategory('Entity') # these are values that can be changed in the level editor Attribs = ( @@ -22,6 +25,9 @@ class Entity: if attribs is not None: self.attribs.update(attribs) + def __str__(self): + return 'ent%s(%s)' % (self.entId, self.level.getEntityType(self.entId)) + def initializeEntity(self): """Call this once on initialization to set this entity's spec data""" @@ -36,33 +42,62 @@ class Entity: return getattr(self, setFuncName) return None - def callSetters(self, *attribs): - """call this with a list of attribs, and any that exist on the - entity and have setters will be passed to their setter""" + def privCallSetters(self, doDelete, *attribs): + """common implementation of callSetters and callSettersAndDelete""" for attrib in attribs: if hasattr(self, attrib): setter = self.privGetSetter(attrib) if setter is not None: - setter(getattr(self, attrib)) + value = getattr(self, attrib) + if doDelete: + delattr(self, attrib) + setter(value) - def attribChanged(self): - """This is called when a parameter is tweaked and no setter - is called; i.e. the value is set directly on the object. - Some Entities might want to completely reset every time anything - is tweaked; this is the place to do it; override this func in your - derived class - """ - pass + def callSetters(self, *attribs): + """call this with a list of attribs, and any that exist on the + entity and have setters will be passed to their setter""" + self.privCallSetters(0, *attribs) - def getAttribInfo(self): - return self.attribs + def callSettersAndDelete(self, *attribs): + """same as callSetters, but also removes attribs from entity""" + self.privCallSetters(1, *attribs) - def privTweak(self, name, value): - self.__dict__[name] = value + # this will be called with each item of our spec data on initialization + def setAttribInit(self, attrib, value): + if hasattr(self, attrib): + Entity.notify.warning('%s already has member %s in %s' % + (self, attrib, lineInfo()[2])) + # TODO: we should probably put this crep in a dictionary + # rather than dump it into the entity's namespace + self.__dict__[attrib] = value + + if __debug__: + # support for level editing + def handleAttribChange(self, attrib, value): + # call callback function if it exists + # otherwise set attrib directly and call notify func + setter = self.privGetSetter(attrib) + if setter is not None: + # call the setter + setter(value) + else: + # set the attrib directly + self.__dict__[attrib] = value + # and call the notify func + self.attribChanged(attrib) + + def attribChanged(self, attrib): + """This is called when a parameter is tweaked and no setter + is called; i.e. the value is set directly on the object. + Some Entities might want to completely reset every time anything + is tweaked; this is the place to do it, just override this func + in your derived class + """ + pass + + def getAttribInfo(self): + return self.attribs - def __str__(self): - return 'ent%s(%s)' % (self.entId, self.level.getEntityType(self.entId)) - if __debug__: def debugPrint(self, message): """for debugging""" diff --git a/direct/src/level/EntityCreator.py b/direct/src/level/EntityCreator.py index d7872305ed..fe4b39e192 100755 --- a/direct/src/level/EntityCreator.py +++ b/direct/src/level/EntityCreator.py @@ -37,6 +37,6 @@ class EntityCreator: def createEntity(self, entType, level, entId): if not self.entType2Ctor.has_key(entType): EntityCreator.notify.warning( - 'createEntity(entType=%s) not found' % entType) + 'createEntity(entType=%s): entType not found' % entType) return None return self.entType2Ctor[entType](level, entId) diff --git a/direct/src/level/EntityCreatorAI.py b/direct/src/level/EntityCreatorAI.py index 304e4955fc..62a9078954 100755 --- a/direct/src/level/EntityCreatorAI.py +++ b/direct/src/level/EntityCreatorAI.py @@ -48,7 +48,7 @@ class EntityCreatorAI: if not self.entType2Ctor.has_key(entType): EntityCreatorAI.notify.warning( 'createEntity(entType=%s, levelDoId=%s, ' - 'entId=%s, zoneId=%s) not found' % + 'entId=%s, zoneId=%s): entType not found' % (entType, levelDoId, entId, zoneId)) return None diff --git a/direct/src/level/LevelBase.py b/direct/src/level/LevelBase.py index 64ed4ab1ff..0492b8360c 100755 --- a/direct/src/level/LevelBase.py +++ b/direct/src/level/LevelBase.py @@ -69,34 +69,13 @@ class LevelBase: for key,value in spec.items(): if key in ('type', 'name', 'comment',): continue - if hasattr(entity, key): - self.notify.warning('entity %s (%s) already has member %s' % - (entId, spec['type'], key)) - entity.__dict__[key] = value + entity.setAttribInit(key, value) # entity is initialized, add it to the list of entities self.entities[entity.entId] = entity # send the create event messenger.send(self.getEntityCreateEvent(entity.entId)) - """ - # set items directly on entity, or call callback functions... - for key,value in spec.items(): - # filter out some entries; we might want to restructure the - # spec data into different categories of properties instead - # of filtering them here - if key in ('type', 'name', 'comment', 'zone',): - continue - setFuncName = 'set%s%s' % (string.upper(key[0]), key[1:]) - if hasattr(entity, setFuncName): - # call the setter - func = getattr(entity, setFuncName) - func(value) - else: - # set the param directly on the object - entity.__dict__[key] = value - """ - def getEntityCreateEvent(self, entId): """This is the event that is thrown immediately after an entity is initialized"""