diff --git a/direct/src/level/DistributedLevel.py b/direct/src/level/DistributedLevel.py index b6729cdc2b..5524946a51 100755 --- a/direct/src/level/DistributedLevel.py +++ b/direct/src/level/DistributedLevel.py @@ -5,6 +5,7 @@ from PythonUtil import Functor, sameElements, list2dict, uniqueElements import ToontownGlobals import DistributedObject import Level +import LevelConstants import DirectNotifyGlobal import EntityCreator import OnscreenText @@ -363,7 +364,7 @@ class DistributedLevel(DistributedObject.DistributedObject, # if no viz, listen to all the zones if not DistributedLevel.WantVisibility: zoneNums = list(self.zoneNums) - zoneNums.remove(Level.Level.uberZoneNum) + zoneNums.remove(LevelConstants.UberZoneNum) self.setVisibility(zoneNums) def toonEnterZone(self, zoneNum): @@ -428,7 +429,7 @@ class DistributedLevel(DistributedObject.DistributedObject, # accepts list of visible zone numbers # convert the zone numbers into their actual zoneIds # always include Toontown and factory uberZones - uberZone = self.getZoneId(zoneNum=Level.Level.UberZoneNum) + uberZone = self.getZoneId(zoneNum=LevelConstants.UberZoneNum) # the level itself is in the 'level zone' visibleZoneIds = [ToontownGlobals.UberZone, self.levelZone, uberZone] for vz in vizList: diff --git a/direct/src/level/Level.py b/direct/src/level/Level.py index 297659c349..c6d521819f 100755 --- a/direct/src/level/Level.py +++ b/direct/src/level/Level.py @@ -2,6 +2,7 @@ import DirectNotifyGlobal import string +import LevelConstants from PythonUtil import lineInfo, uniqueElements """ @@ -30,9 +31,6 @@ class Level: entities and their interrelations, and creates and destroys entities""" notify = DirectNotifyGlobal.directNotify.newCategory('Level') - UberZoneNum = 0 - UberZoneEntId = 0 - def __init__(self): self.levelSpec = None self.initialized = 0 @@ -56,8 +54,18 @@ class Level: # there should be one and only one levelMgr assert len(self.entType2ids['levelMgr']) == 1 + self.levelMgrEntity = self.entType2ids['levelMgr'][0] + assert self.levelMgrEntity.entId == LevelConstants.LevelMgrEntId + + if __debug__: + # there should be one and only one editMgr + assert len(self.entType2ids['editMgr']) == 1 + self.editMgrEntity = self.entType2ids['editMgr'][0] + assert self.editMgrEntity.entId == LevelConstants.EditMgrEntId + # make sure the uberzone is there - assert Level.UberZoneEntId in self.entType2ids['zone'] + assert LevelConstants.UberZoneEntId in self.entType2ids['zone'] + self.UberZoneEntity = self.getEntity(LevelConstants.UberZoneEntId) # this list contains the entIds of entities that we have actually # created, in order of creation diff --git a/direct/src/level/LevelConstants.py b/direct/src/level/LevelConstants.py new file mode 100755 index 0000000000..304faa3d93 --- /dev/null +++ b/direct/src/level/LevelConstants.py @@ -0,0 +1,8 @@ +"""LevelConstants module: contains Level-related constants""" + +UberZoneEntId = 0 +UberZoneNum = 0 + +LevelMgrEntId = 10 + +EditMgrEntId = 20 diff --git a/direct/src/level/LevelSpec.py b/direct/src/level/LevelSpec.py index 5cdc3489a4..4bea391b15 100755 --- a/direct/src/level/LevelSpec.py +++ b/direct/src/level/LevelSpec.py @@ -3,18 +3,35 @@ import DirectNotifyGlobal from PythonUtil import list2dict, uniqueElements import string +import LevelConstants if __debug__: import os +if __debug__: + def makeNewSpec(filename, modelPath, ): + spec = LevelSpec() + spec.doSetAttrib(LevelConstants.LevelMgrEntId, + 'modelFilename', modelPath) + spec.saveToDisk(filename, makeBackup=0) + class LevelSpec: """contains spec data for a level, is responsible for handing the data out upon request, as well as recording changes made during editing, and saving out modified spec data""" notify = DirectNotifyGlobal.directNotify.newCategory("LevelSpec") - def __init__(self, specDict, scenario=0): + def __init__(self, specDict=None, scenario=0): self.specDict = specDict + if __debug__: + newSpec = 0 + if self.specDict == None: + newSpec = 1 + self.specDict = { + 'globalEntities': {}, + 'scenarios': [[{}, 1]], + } + # this maps an entId to the dict that holds its spec; # entities are either in the global dict or a scenario dict # update the map of entId to spec dict @@ -29,6 +46,33 @@ class LevelSpec: self.setScenario(scenario) + if __debug__: + if newSpec: + # add required entities + + # create an entityTypeReg before attempting entity + # insertions; basic EntityTypes reg is enough for our purposes + # here + import EntityTypes + import EntityTypeRegistry + etr = EntityTypeRegistry.EntityTypeRegistry(EntityTypes) + self.setEntityTypeReg(etr) + + # UberZone + entId = LevelConstants.UberZoneEntId + self.insertEntity(entId, 'zone', None) + self.doSetAttrib(entId, 'modelZoneNum', + LevelConstants.UberZoneNum) + self.doSetAttrib(entId, 'name', 'UberZone') + # LevelMgr + entId = LevelConstants.LevelMgrEntId + self.insertEntity(entId, 'levelMgr', None) + self.doSetAttrib(entId, 'name', 'LevelMgr') + # EditMgr + entId = LevelConstants.EditMgrEntId + self.insertEntity(entId, 'editMgr', None) + self.doSetAttrib(entId, 'name', 'EditMgr') + def getNumScenarios(self): return len(self.specDict['scenarios']) @@ -84,6 +128,9 @@ class LevelSpec: def setLevel(self, level): self.level = level + def hasLevel(self): + return hasattr(self, 'level') + def setEntityTypeReg(self, entTypeReg): self.entTypeReg = entTypeReg self.checkSpecIntegrity() @@ -94,20 +141,25 @@ class LevelSpec: def setFilename(self, filename): self.filename = filename - def setAttribChange(self, entId, attrib, value, username): - """ we're being asked to change an attribute """ - LevelSpec.notify.info("setAttribChange(%s): %s, %s = '%s'" % - (username, entId, attrib, repr(value))) + def doSetAttrib(self, entId, attrib, value): + """ do the dirty work of changing an attrib value """ assert entId in self.entId2specDict specDict = self.entId2specDict[entId] assert specDict[entId].has_key(attrib) specDict[entId][attrib] = value - # let the level know that this attribute value has - # officially changed - self.level.handleAttribChange(entId, attrib, value, username) + + def setAttribChange(self, entId, attrib, value, username): + """ we're being asked to change an attribute """ + LevelSpec.notify.info("setAttribChange(%s): %s, %s = '%s'" % + (username, entId, attrib, repr(value))) + self.doSetAttrib(entId, attrib, value) + if self.hasLevel(): + # let the level know that this attribute value has + # officially changed + self.level.handleAttribChange(entId, attrib, value, username) def insertEntity(self, entId, entType, parentEntId): - LevelSpec.notify.info('inserting entity %s' % entId) + LevelSpec.notify.info('inserting entity %s (%s)' % (entId, entType)) assert entId not in self.entId2specDict assert self.entTypeReg is not None globalEnts = self.privGetGlobalEntityDict() @@ -124,14 +176,18 @@ class LevelSpec: if 'parentEntId' in spec: spec['parentEntId'] = parentEntId - # notify the level - self.level.handleEntityInsert(entId) + if self.hasLevel(): + # notify the level + self.level.handleEntityInsert(entId) def removeEntity(self, entId): LevelSpec.notify.info('removing entity %s' % entId) assert entId in self.entId2specDict - # notify the level - self.level.handleEntityRemove(entId) + + if self.hasLevel(): + # notify the level + self.level.handleEntityRemove(entId) + # remove the entity's spec dict = self.entId2specDict[entId] del dict[entId] @@ -162,6 +218,7 @@ class LevelSpec: LevelSpec.notify.warning( 'error during backup: %s' % str(e)) + LevelSpec.notify.info("writing to '%s'" % filename) self.privRemoveFile(filename) self.privSaveToDisk(filename) diff --git a/direct/src/level/ZoneEntityBase.py b/direct/src/level/ZoneEntityBase.py index 6b5e783729..8f19ee706f 100755 --- a/direct/src/level/ZoneEntityBase.py +++ b/direct/src/level/ZoneEntityBase.py @@ -1,7 +1,7 @@ """ZoneEntityBase module: contains the ZoneEntityBase class""" import Entity -import Level +import LevelConstants class ZoneEntityBase(Entity.Entity): def __init__(self, level, entId): @@ -13,7 +13,7 @@ class ZoneEntityBase(Entity.Entity): Entity.Entity.destroy(self) def isUberZone(self): - return self.entId == Level.Level.UberZoneEntId + return self.entId == LevelConstants.UberZoneEntId def setZoneId(self, zoneId): """set the network zoneId that this zone entity corresponds to"""