zoneNum and zoneEntId are the same thing now

This commit is contained in:
Darren Ranalli 2004-01-09 21:23:05 +00:00
parent cf8beef552
commit 7001df5c85
11 changed files with 119 additions and 171 deletions

View File

@ -195,11 +195,11 @@ class DistributedLevel(DistributedObject.DistributedObject,
# make sure the zoneNums from the model match the zoneNums from # make sure the zoneNums from the model match the zoneNums from
# the zone entities # the zone entities
modelZoneNums = self.zoneNums modelZoneNums = self.zoneNums
entityZoneNums = self.zoneNum2entId.keys() specZoneNums = self.zoneNum2zoneId.keys()
if not sameElements(modelZoneNums, entityZoneNums): if not sameElements(modelZoneNums, specZoneNums):
self.reportModelSpecSyncError( self.reportModelSpecSyncError(
'model zone nums (%s) do not match entity zone nums (%s)' % 'model zone nums (%s) do not match spec zone nums (%s)' %
(modelZoneNums, entityZoneNums)) (modelZoneNums, specZoneNums))
# load stuff # load stuff
self.initVisibility() self.initVisibility()
@ -236,7 +236,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
initialZoneEnt = self.getEntity(epEnt.getZoneEntId()) initialZoneEnt = self.getEntity(epEnt.getZoneEntId())
# kickstart the visibility # kickstart the visibility
self.enterZone(initialZoneEnt.getZoneNum()) self.enterZone(initialZoneEnt.entId)
def createEntityCreator(self): def createEntityCreator(self):
"""Create the object that will be used to create Entities. """Create the object that will be used to create Entities.
@ -263,13 +263,14 @@ class DistributedLevel(DistributedObject.DistributedObject,
self.zoneNums = self.zoneNum2node.keys() self.zoneNums = self.zoneNum2node.keys()
self.zoneNums.sort() self.zoneNums.sort()
DistributedLevel.notify.debug('zones: %s' % self.zoneNums) self.zoneNumDict = list2dict(self.zoneNums)
DistributedLevel.notify.debug('zones from model: %s' % self.zoneNums)
# fix up the floor collisions for walkable zones *before* # fix up the floor collisions for walkable zones *before*
# any entities get put under the model # any entities get put under the model
for zoneNum,zoneNode in self.zoneNum2node.items(): for zoneNum,zoneNode in self.zoneNum2node.items():
# don't do this to the uberzone # don't do this to the uberzone
if zoneNum == LevelConstants.UberZoneNum: if zoneNum == LevelConstants.UberZoneEntId:
continue continue
# if this is a walkable zone, fix up the model # if this is a walkable zone, fix up the model
allColls = zoneNode.findAllMatches('**/+CollisionNode').asList() allColls = zoneNode.findAllMatches('**/+CollisionNode').asList()
@ -347,9 +348,6 @@ class DistributedLevel(DistributedObject.DistributedObject,
# make sure the ouch task is stopped # make sure the ouch task is stopped
self.stopOuch() self.stopOuch()
def getZoneNode(self, zoneNum):
return self.zoneNum2node.get(zoneNum)
def requestReparent(self, entity, parentId): def requestReparent(self, entity, parentId):
if __debug__: if __debug__:
# some things (like cogs) are not actually entities yet; # some things (like cogs) are not actually entities yet;
@ -389,8 +387,11 @@ class DistributedLevel(DistributedObject.DistributedObject,
self.parent2pendingChildren[parentId].append(entity) self.parent2pendingChildren[parentId].append(entity)
def getZoneNode(self, zoneEntId):
return self.zoneNum2node.get(zoneEntId)
def showZone(self, zoneNum): def showZone(self, zoneNum):
zone = self.zoneNum2node[zoneNum] zone = self.getZoneNode(zoneNum)
zone.unstash() zone.unstash()
zone.clearColor() zone.clearColor()
@ -402,7 +403,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
return self.fColorZones return self.fColorZones
def hideZone(self, zoneNum): def hideZone(self, zoneNum):
zone = self.zoneNum2node[zoneNum] zone = self.getZoneNode(zoneNum)
if self.fColorZones: if self.fColorZones:
zone.unstash() zone.unstash()
zone.setColor(1,0,0) zone.setColor(1,0,0)
@ -414,7 +415,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
if zone is None: if zone is None:
node = self.geom node = self.geom
else: else:
node = self.zoneNum2node[zone] node = self.getZoneNode(zoneNum)
node.setAlphaScale(alpha) node.setAlphaScale(alpha)
def initVisibility(self): def initVisibility(self):
@ -423,7 +424,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
self.curVisibleZoneNums = list2dict(self.zoneNums) self.curVisibleZoneNums = list2dict(self.zoneNums)
# the UberZone is always visible, so it's not included in the # the UberZone is always visible, so it's not included in the
# zones' viz lists # zones' viz lists
del self.curVisibleZoneNums[0] del self.curVisibleZoneNums[LevelConstants.UberZoneEntId]
# we have not entered any zone yet # we have not entered any zone yet
self.curZoneNum = None self.curZoneNum = None
@ -452,7 +453,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
# if no viz, listen to all the zones # if no viz, listen to all the zones
if not DistributedLevel.WantVisibility: if not DistributedLevel.WantVisibility:
zoneNums = list(self.zoneNums) zoneNums = list(self.zoneNums)
zoneNums.remove(LevelConstants.UberZoneNum) zoneNums.remove(LevelConstants.UberZoneEntId)
self.setVisibility(zoneNums) self.setVisibility(zoneNums)
# send out any zone changes at the end of the frame, just before # send out any zone changes at the end of the frame, just before
@ -527,7 +528,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
def lockVisibility(self, zoneNum=None, zoneId=None): def lockVisibility(self, zoneNum=None, zoneId=None):
"""call this to lock the visibility to a particular zone """call this to lock the visibility to a particular zone
pass in either network zoneId or model zoneNum pass in either network zoneId or zoneNum
this was added for battles in the HQ factories; if you engage a suit this was added for battles in the HQ factories; if you engage a suit
in zone A with your camera in zone B, and you don't call this func, in zone A with your camera in zone B, and you don't call this func,
@ -563,7 +564,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
if zoneNum == self.curZoneNum: if zoneNum == self.curZoneNum:
return return
if zoneNum not in self.zoneNum2entId: if zoneNum not in self.zoneNumDict:
DistributedLevel.notify.error( DistributedLevel.notify.error(
'no ZoneEntity for this zone (%s)!!' % zoneNum) 'no ZoneEntity for this zone (%s)!!' % zoneNum)
@ -580,8 +581,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
if hasattr(self, 'lockVizZone'): if hasattr(self, 'lockVizZone'):
zoneNum = self.lockVizZone zoneNum = self.lockVizZone
zoneEntId = self.zoneNum2entId[zoneNum] zoneEnt = self.getEntity(zoneNum)
zoneEnt = self.getEntity(zoneEntId)
# use dicts to efficiently ensure that there are no duplicates # use dicts to efficiently ensure that there are no duplicates
visibleZoneNums = list2dict([zoneNum]) visibleZoneNums = list2dict([zoneNum])
visibleZoneNums.update(list2dict(zoneEnt.getVisibleZoneNums())) visibleZoneNums.update(list2dict(zoneEnt.getVisibleZoneNums()))
@ -600,7 +600,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
visibleZoneNums.update(list2dict([self.lastToonZone])) visibleZoneNums.update(list2dict([self.lastToonZone]))
# we should not have the uberZone in the list at this point # we should not have the uberZone in the list at this point
assert not 0 in visibleZoneNums assert not LevelConstants.UberZoneEntId in visibleZoneNums
if DistributedLevel.HideZones: if DistributedLevel.HideZones:
# figure out which zones are new and which are going invisible # figure out which zones are new and which are going invisible
@ -640,14 +640,14 @@ class DistributedLevel(DistributedObject.DistributedObject,
# if we're showing all zones, get all the DOs # if we're showing all zones, get all the DOs
if self.fColorZones and DistributedLevel.ColorZonesAllDOs: if self.fColorZones and DistributedLevel.ColorZonesAllDOs:
vizList = list(self.zoneNums) vizList = list(self.zoneNums)
vizList.remove(LevelConstants.UberZoneNum) vizList.remove(LevelConstants.UberZoneEntId)
# convert the zone numbers into their actual zoneIds # convert the zone numbers into their actual zoneIds
# always include Toontown and factory uberZones # always include Toontown and factory uberZones
uberZone = self.getZoneId(zoneNum=LevelConstants.UberZoneNum) uberZone = self.getZoneId(LevelConstants.UberZoneEntId)
# the level itself is in the 'level zone' # the level itself is in the 'level zone'
visibleZoneIds = [ToontownGlobals.UberZone, self.levelZone, uberZone] visibleZoneIds = [ToontownGlobals.UberZone, self.levelZone, uberZone]
for vz in vizList: for vz in vizList:
visibleZoneIds.append(self.getZoneId(zoneNum=vz)) visibleZoneIds.append(self.getZoneId(vz))
assert(uniqueElements(visibleZoneIds)) assert(uniqueElements(visibleZoneIds))
DistributedLevel.notify.info('new viz list: %s' % visibleZoneIds) DistributedLevel.notify.info('new viz list: %s' % visibleZoneIds)
@ -659,7 +659,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
self.curVisibleZoneNums = list2dict(self.zoneNums) self.curVisibleZoneNums = list2dict(self.zoneNums)
# the UberZone is always visible, so it's not included in the # the UberZone is always visible, so it's not included in the
# zones' viz lists # zones' viz lists
del self.curVisibleZoneNums[0] del self.curVisibleZoneNums[LevelConstants.UberZoneEntId]
# Make sure every zone is visible # Make sure every zone is visible
for vz,dummy in self.curVisibleZoneNums.items(): for vz,dummy in self.curVisibleZoneNums.items():
self.showZone(vz) self.showZone(vz)
@ -688,12 +688,10 @@ class DistributedLevel(DistributedObject.DistributedObject,
self.levelSpec.setAttribChange(entId, attribName, value, username) self.levelSpec.setAttribChange(entId, attribName, value, username)
def spawnTitleText(self): def spawnTitleText(self):
def getDescription(zoneId, self=self): def getDescription(zoneNum, self=self):
entId = self.zoneNum2entId.get(zoneId) ent = self.entities.get(zoneNum)
if entId: if ent and hasattr(ent, 'description'):
ent = self.entities.get(entId) return ent.description
if ent and hasattr(ent, 'description'):
return ent.description
return None return None
description = getDescription(self.lastCamZone) description = getDescription(self.lastCamZone)

View File

@ -63,7 +63,6 @@ class Zone(Nodepath):
) )
attribs = ( attribs = (
('parentEntId', 0, 'const'), ('parentEntId', 0, 'const'),
('modelZoneNum', -1, 'const'),
('description', '', 'string'), ('description', '', 'string'),
('visibility', [], 'visZoneList'), ('visibility', [], 'visZoneList'),
) )

View File

@ -22,9 +22,9 @@ you haven't created the zone's ZoneEntity, you're hurting.)
""" """
ZONE TERMINOLOGY ZONE TERMINOLOGY
zoneNum / modelZoneNum : the number that a modeler chooses for a zone zoneNum / zoneEntId: the number that a modeler chooses for a zone, and also
zoneEntId : the entity ID of the ZoneEntity that represents a zone the entity ID of the ZoneEntity that represents a zone
zoneId : the network ID of the zone zoneId : the network ID of a zone
""" """
class Level: class Level:
@ -221,10 +221,6 @@ class Level:
"""return entId of zone that contains the entity""" """return entId of zone that contains the entity"""
return self.levelSpec.getEntityZoneEntId(entId) return self.levelSpec.getEntityZoneEntId(entId)
def getEntityZoneNum(self, entId):
"""return the model zoneNum of zone that contains the entity"""
return self.levelSpec.getEntityZoneNum(entId)
def getEntityZoneId(self, entId): def getEntityZoneId(self, entId):
"""return network zoneId of zone that contains the entity""" """return network zoneId of zone that contains the entity"""
# this is called during entity creation on the AI; we have to # this is called during entity creation on the AI; we have to
@ -233,7 +229,7 @@ class Level:
# entities have been instantiated. # entities have been instantiated.
zoneEntId = self.getEntityZoneEntId(entId) zoneEntId = self.getEntityZoneEntId(entId)
# fundamental entities (levelMgr) are responsible for creating # fundamental entities (levelMgr) are responsible for creating
# tables like 'zoneEntId2zoneId'; if those tables haven't been # tables like 'zoneNum2zoneId'; if those tables haven't been
# created yet, just return None # created yet, just return None
if not hasattr(self, 'zoneNum2zoneId'): if not hasattr(self, 'zoneNum2zoneId'):
return None return None
@ -241,18 +237,12 @@ class Level:
# been created yet. this could be a problem if zone entities # been created yet. this could be a problem if zone entities
# are ever distributed. it also means that no distributed entities # are ever distributed. it also means that no distributed entities
# should be created before the zone entities. # should be created before the zone entities.
return self.zoneEntId2zoneId.get(zoneEntId) return self.zoneNum2zoneId.get(zoneEntId)
def getZoneId(self, dummy=None, zoneNum=None, entId=None): def getZoneId(self, zoneEntId):
"""look up network zoneId by zoneNum or entId""" """look up network zoneId by zone entId"""
assert (zoneNum is not None) or (entId is not None) assert zoneEntId in self.zoneNum2zoneId
assert not ((zoneNum is not None) and (entId is not None)) return self.zoneNum2zoneId[zoneEntId]
if zoneNum is not None:
assert zoneNum in self.zoneNum2zoneId
return self.zoneNum2zoneId[zoneNum]
else:
assert entId in self.zoneEntId2zoneId
return self.zoneEntId2zoneId[entId]
def getZoneNumFromId(self, zoneId): def getZoneNumFromId(self, zoneId):
"""returns the model zoneNum that corresponds to a network zoneId""" """returns the model zoneNum that corresponds to a network zoneId"""

View File

@ -1,10 +1,12 @@
"""LevelConstants module: contains Level-related constants""" """LevelConstants module: contains Level-related constants"""
# Zone Num from model is also the Zone Entity's entId
MinZoneNum = 0
MaxZoneNum = 999
# zoneNum 0 is reserved for UberZone
UberZoneEntId = 0 UberZoneEntId = 0
UberZoneNum = 0
LevelMgrEntId = 10 # system-allocated entities start at 1000
LevelMgrEntId = 1000
EditMgrEntId = 20 EditMgrEntId = 1001
ZoneEntIdStart = 100

View File

@ -12,14 +12,13 @@ class LevelMgr(LevelMgrBase.LevelMgrBase):
# load the model # load the model
self.geom = loader.loadModel(self.modelFilename) self.geom = loader.loadModel(self.modelFilename)
# modelZoneNum -> zone entId # this will hold the zoneNums/entIds for our own bookkeeping
self.level.zoneNum2entId = {} self.zoneNums = []
# modelZoneNum -> network zoneId
# zoneNum -> network zoneId
self.level.zoneNum2zoneId = {} self.level.zoneNum2zoneId = {}
# network zoneId -> modelZoneNum # network zoneId -> zoneNum
self.level.zoneId2zoneNum = {} self.level.zoneId2zoneNum = {}
# zone entId -> network zoneId
self.level.zoneEntId2zoneId = {}
# listen for every zone creation # listen for every zone creation
self.accept(self.level.getEntityOfTypeCreateEvent('zone'), self.accept(self.level.getEntityOfTypeCreateEvent('zone'),
@ -27,10 +26,8 @@ class LevelMgr(LevelMgrBase.LevelMgrBase):
def destroy(self): def destroy(self):
del self.level.zoneIds del self.level.zoneIds
del self.level.zoneEntId2zoneId
del self.level.zoneId2zoneNum del self.level.zoneId2zoneNum
del self.level.zoneNum2zoneId del self.level.zoneNum2zoneId
del self.level.zoneNum2entId
self.geom.removeNode() self.geom.removeNode()
del self.geom del self.geom
LevelMgrBase.LevelMgrBase.destroy(self) LevelMgrBase.LevelMgrBase.destroy(self)
@ -39,10 +36,11 @@ class LevelMgr(LevelMgrBase.LevelMgrBase):
zoneEnt = self.level.getEntity(entId) zoneEnt = self.level.getEntity(entId)
# register the zone's info in the tables # register the zone's info in the tables
# right off the bat, we have the zone's modelZoneNum and entId
self.level.zoneNum2entId[zoneEnt.modelZoneNum] = entId
# we can assume that we have a complete list of zoneIds in assert (zoneEnt.entId not in self.zoneNums)
self.zoneNums.append(zoneEnt.entId)
# we can assume that we have a complete list of network zoneIds in
# self.level.zoneIds. As each zone entity is created, set up # self.level.zoneIds. As each zone entity is created, set up
# as if we have all of the zone entities. This allows dynamic # as if we have all of the zone entities. This allows dynamic
# zone entity creation and deletion during editing. # zone entity creation and deletion during editing.
@ -57,33 +55,26 @@ class LevelMgr(LevelMgrBase.LevelMgrBase):
def handleZoneDestroy(self, entId): def handleZoneDestroy(self, entId):
zoneEnt = self.level.getEntity(entId) zoneEnt = self.level.getEntity(entId)
# unregister the zone from the maps # unregister the zone from the maps
del self.level.zoneNum2entId[zoneEnt.modelZoneNum]
del self.level.zoneId2zoneNum[ del self.level.zoneId2zoneNum[
self.level.zoneNum2zoneId[zoneEnt.modelZoneNum]] self.level.zoneNum2zoneId[zoneEnt.entId]]
del self.level.zoneNum2zoneId[zoneEnt.modelZoneNum] del self.level.zoneNum2zoneId[zoneEnt.entId]
del self.level.zoneEntId2zoneId[entId] self.zoneNums.remove(zoneEnt.entId)
# reassign the zoneIds (we may not need to do this, if all of the # reassign the zoneIds (we may not need to do this, if all of the
# other entities already have their correct zoneId...?) # other entities already have their correct zoneId...?)
self.privAssignZoneIds() self.privAssignZoneIds()
def privAssignZoneIds(self): def privAssignZoneIds(self):
"""assign zoneIds from self.level.zoneIds, according to the zones """assign network zoneIds from self.level.zoneIds, according to
that are registered so far in self.level.zoneNum2entId""" the zones that are registered so far"""
# sort the model zoneNums # sort the zoneNums
modelZoneNums = self.level.zoneNum2entId.keys() self.zoneNums.sort()
modelZoneNums.sort()
# dole out the zoneIds, in increasing order of zoneNum # dole out the zoneIds, in increasing order of zoneNum
for i in range(len(modelZoneNums)): for i in range(len(self.zoneNums)):
zoneNum = modelZoneNums[i] zoneNum = self.zoneNums[i]
entId = self.level.zoneNum2entId[zoneNum] zoneEnt = self.level.getEntity(zoneNum)
zoneEnt = self.level.getEntity(entId) zoneId = self.level.zoneIds[i]
zoneEnt.setZoneId(self.level.zoneIds[i]) zoneEnt.setZoneId(zoneId)
# the zoneIds have shifted. update the tables
# the zoneIds have shifted. update the tables self.level.zoneNum2zoneId[zoneNum] = zoneId
for entId in self.level.zoneNum2entId.values(): self.level.zoneId2zoneNum[zoneId] = zoneNum
zoneEnt = self.level.getEntity(entId)
zoneId = zoneEnt.getZoneId()
self.level.zoneNum2zoneId[zoneEnt.modelZoneNum] = zoneId
self.level.zoneId2zoneNum[zoneId] = zoneEnt.modelZoneNum
self.level.zoneEntId2zoneId[entId] = zoneId

View File

@ -8,13 +8,9 @@ class LevelMgrAI(LevelMgrBase.LevelMgrBase):
def __init__(self, level, entId): def __init__(self, level, entId):
LevelMgrBase.LevelMgrBase.__init__(self, level, entId) LevelMgrBase.LevelMgrBase.__init__(self, level, entId)
# modelZoneNum -> zone entId # zoneNum -> network zoneId
self.level.zoneNum2entId = {}
# modelZoneNum -> network zoneId
self.level.zoneNum2zoneId = {} self.level.zoneNum2zoneId = {}
# zone entId -> network zoneId # list of network zoneIDs, sorted by zoneNum
self.level.zoneEntId2zoneId = {}
# list of network zoneIDs, sorted by modelZoneNum
self.level.zoneIds = [] self.level.zoneIds = []
# listen for every zone creation # listen for every zone creation
@ -23,18 +19,14 @@ class LevelMgrAI(LevelMgrBase.LevelMgrBase):
def destroy(self): def destroy(self):
del self.level.zoneIds del self.level.zoneIds
del self.level.zoneEntId2zoneId
del self.level.zoneNum2zoneId del self.level.zoneNum2zoneId
del self.level.zoneNum2entId
LevelMgrBase.LevelMgrBase.destroy(self) LevelMgrBase.LevelMgrBase.destroy(self)
def handleZoneCreated(self, entId): def handleZoneCreated(self, entId):
zoneEnt = self.level.getEntity(entId) zoneEnt = self.level.getEntity(entId)
# register the zone's info in the tables # register the zone's info in the tables
self.level.zoneNum2entId[zoneEnt.modelZoneNum] = entId self.level.zoneNum2zoneId[zoneEnt.entId] = zoneEnt.getZoneId()
self.level.zoneNum2zoneId[zoneEnt.modelZoneNum] = zoneEnt.getZoneId()
self.level.zoneEntId2zoneId[entId] = zoneEnt.getZoneId()
# TODO: we should delay this until all zone entities have been # TODO: we should delay this until all zone entities have been
# created on level init # created on level init
@ -46,23 +38,22 @@ class LevelMgrAI(LevelMgrBase.LevelMgrBase):
def handleZoneDestroy(self, entId): def handleZoneDestroy(self, entId):
zoneEnt = self.level.getEntity(entId) zoneEnt = self.level.getEntity(entId)
# unregister the zone from the maps # unregister the zone from the tables
del self.level.zoneNum2entId[zoneEnt.modelZoneNum] del self.level.zoneNum2zoneId[zoneEnt.entId]
del self.level.zoneNum2zoneId[zoneEnt.modelZoneNum]
del self.level.zoneEntId2zoneId[entId]
# recreate the sorted network zoneId list # recreate the sorted network zoneId list
self.privCreateSortedZoneIdList() self.privCreateSortedZoneIdList()
def privCreateSortedZoneIdList(self): def privCreateSortedZoneIdList(self):
# sort the model zoneNums # sort the zoneNums
modelZoneNums = self.level.zoneNum2entId.keys() zoneNums = self.level.zoneNum2zoneId.keys()
modelZoneNums.sort() zoneNums.sort()
# create a list of network zoneIds, ordered by their corresponding # create a list of network zoneIds, ordered by their corresponding
# sorted model zoneNum values # sorted model zoneNum values
self.level.zoneIds = [] self.level.zoneIds = []
for zoneNum in modelZoneNums: for zoneNum in zoneNums:
self.level.zoneIds.append(self.level.zoneNum2zoneId[zoneNum]) self.level.zoneIds.append(self.level.zoneNum2zoneId[zoneNum])
# TODO: if we just added or removed a zone entity AFTER the level # TODO: if we ever allow dynamic insertion and removal of zone
# was initialized, we need to re-send the zoneId list # entities, and we just added or removed a zone entity AFTER the level
# was initialized, we would need to re-send the zoneId list

View File

@ -63,8 +63,6 @@ class LevelSpec:
# UberZone # UberZone
entId = LevelConstants.UberZoneEntId entId = LevelConstants.UberZoneEntId
self.insertEntity(entId, 'zone') self.insertEntity(entId, 'zone')
self.doSetAttrib(entId, 'modelZoneNum',
LevelConstants.UberZoneNum)
self.doSetAttrib(entId, 'name', 'UberZone') self.doSetAttrib(entId, 'name', 'UberZone')
# LevelMgr # LevelMgr
entId = LevelConstants.LevelMgrEntId entId = LevelConstants.LevelMgrEntId
@ -121,12 +119,6 @@ class LevelSpec:
# keep looking up the heirarchy for a zone entity # keep looking up the heirarchy for a zone entity
return self.getEntityZoneEntId(spec['parentEntId']) return self.getEntityZoneEntId(spec['parentEntId'])
def getEntityZoneNum(self, entId):
""" return the model zoneNum of zone that contains the entity """
zoneEntId = self.getEntityZoneEntId(entId)
spec = self.getEntitySpec(zoneEntId)
return spec['modelZoneNum']
def getEntType2ids(self, entIds): def getEntType2ids(self, entIds):
"""given list of entIds, return dict of entType 2 entIds""" """given list of entIds, return dict of entType 2 entIds"""
entType2ids = {} entType2ids = {}
@ -144,7 +136,7 @@ class LevelSpec:
return self.specDict['scenarios'][scenario][0] return self.specDict['scenarios'][scenario][0]
def printZones(self): def printZones(self):
"""currently prints list of modelZoneNum->zone name""" """currently prints list of zoneNum->zone name"""
# this could be more efficient # this could be more efficient
allIds = self.getAllEntIds() allIds = self.getAllEntIds()
type2id = self.getEntType2ids(allIds) type2id = self.getEntType2ids(allIds)
@ -152,17 +144,10 @@ class LevelSpec:
# omit the UberZone # omit the UberZone
if 0 in zoneIds: if 0 in zoneIds:
zoneIds.remove(0) zoneIds.remove(0)
# need to sort the zones by modelZoneNum zoneIds.sort()
zoneNum2zoneId = {} for zoneNum in zoneIds:
for id in zoneIds: spec = self.getEntitySpec(zoneNum)
spec = self.getEntitySpec(id) print 'zone %s : %s' % (zoneNum, spec['name'])
zoneNum2zoneId[spec['modelZoneNum']] = id
modelZoneNums = zoneNum2zoneId.keys()
modelZoneNums.sort()
for zoneNum in modelZoneNums:
id = zoneNum2zoneId[zoneNum]
spec = self.getEntitySpec(id)
print 'zone %s : %s' % (spec['modelZoneNum'], spec['name'])
if __dev__: if __dev__:
def setLevel(self, level): def setLevel(self, level):

View File

@ -1,6 +1,7 @@
"""LevelUtil module: contains Level utility funcs""" """LevelUtil module: contains Level utility funcs"""
import string import string
import LevelConstants
def getZoneNum2Node(levelModel): def getZoneNum2Node(levelModel):
""" given model, returns dict of ZoneNumber -> ZoneNode """ """ given model, returns dict of ZoneNumber -> ZoneNode """
@ -24,15 +25,27 @@ def getZoneNum2Node(levelModel):
if numDigits == 0: if numDigits == 0:
continue continue
num = int(name[:numDigits]) num = int(name[:numDigits])
# is this a valid zoneNum?
if num == LevelConstants.UberZoneEntId:
print ('warning: cannot use UberZone zoneNum (%s). '
'ignoring %s' % (LevelConstants.UberZoneEntId,
potentialNode))
continue
if (num < LevelConstants.MinZoneNum) or (
num > LevelConstants.MaxZoneNum):
print 'warning: zone %s is out of range. ignoring %s' % (
num, potentialNode)
continue
# do we already have a ZoneNode for this zone num? # do we already have a ZoneNode for this zone num?
if num in num2node: if num in num2node:
print 'warning: zone %s already assigned to %s. ignoring %s' % ( print 'warning: zone %s already assigned to %s. ignoring %s' % (
num, num2node[num], potentialNode) num, num2node[num], potentialNode)
continue
num2node[num] = potentialNode num2node[num] = potentialNode
return num2node return num2node
zoneNum2node = findNumberedNodes('zone', levelModel) zoneNum2node = findNumberedNodes('zone', levelModel)
# add the UberZone to the table # add the UberZone to the table
zoneNum2node[0] = levelModel zoneNum2node[LevelConstants.UberZoneEntId] = levelModel
return zoneNum2node return zoneNum2node

View File

@ -74,8 +74,8 @@ def privUpdateSpec(spec, modelPath, entTypeModule, newZonesGloballyVisible=0):
assert model is not None assert model is not None
TexturePool.clearFakeTextureImage() TexturePool.clearFakeTextureImage()
# get the model's zone info # get the model's zone info
modelZoneNum2node = LevelUtil.getZoneNum2Node(model) zoneNum2node = LevelUtil.getZoneNum2Node(model)
modelZoneNums = modelZoneNum2node.keys() zoneNums = zoneNum2node.keys()
# what zone entities do we have specs for? # what zone entities do we have specs for?
type2ids = spec.getEntType2ids(spec.getAllEntIds()) type2ids = spec.getEntType2ids(spec.getAllEntIds())
@ -86,50 +86,29 @@ def privUpdateSpec(spec, modelPath, entTypeModule, newZonesGloballyVisible=0):
spec.removeEntity(entId) spec.removeEntity(entId)
zoneEntIds.remove(entId) zoneEntIds.remove(entId)
def insertZoneEntity(entId, modelZoneNum, spec=spec, zoneEntIds=zoneEntIds): def insertZoneEntity(zoneNum, spec=spec, zoneEntIds=zoneEntIds):
spec.insertEntity(entId, 'zone', LevelConstants.UberZoneEntId) spec.insertEntity(zoneNum, 'zone', LevelConstants.UberZoneEntId)
spec.doSetAttrib(entId, 'name', 'zone%s' % modelZoneNum) spec.doSetAttrib(zoneNum, 'name', 'zone%s' % zoneNum)
spec.doSetAttrib(entId, 'modelZoneNum', modelZoneNum) zoneEntIds.append(zoneNum)
zoneEntIds.append(entId)
# create dict of zoneNum -> entId
zoneNum2entId = {}
for entId in list(zoneEntIds):
zoneNum = spec.getEntitySpec(entId)['modelZoneNum']
if zoneNum in zoneNum2entId:
print ('multiple zone entities reference zoneNum %s; removing '
'entity %s' % (zoneNum, entId))
removeZoneEntity(entId)
continue
zoneNum2entId[zoneNum] = entId
# prune zone entities that reference zones that no longer exist # prune zone entities that reference zones that no longer exist
removedZoneNums = [] removedZoneNums = []
for entId in list(zoneEntIds): for entId in list(zoneEntIds):
zoneNum = spec.getEntitySpec(entId)['modelZoneNum'] if entId not in zoneNums:
if zoneNum not in modelZoneNums: print 'zone %s no longer exists; removing' % entId
print 'zone %s no longer exists; removing entity %s' % (
zoneNum, entId)
removeZoneEntity(entId) removeZoneEntity(entId)
del zoneNum2entId[zoneNum] removedZoneNums.append(entId)
removedZoneNums.append(zoneNum)
# add new zone entities for new zones # add new zone entities for new zones
newZoneNums = [] newZoneNums = []
for zoneNum in modelZoneNums: for zoneNum in zoneNums:
if zoneNum not in zoneNum2entId: if zoneNum not in zoneEntIds:
newZoneNums.append(zoneNum) newZoneNums.append(zoneNum)
entIdDict = list2dict(spec.getAllEntIds()) print 'adding new zone entity %s' % zoneNum
entId = LevelConstants.ZoneEntIdStart insertZoneEntity(zoneNum)
# we could do better than linear
while entId in entIdDict:
entId += 1
print 'adding entity %s for new zone %s' % (entId, zoneNum)
insertZoneEntity(entId, zoneNum)
# by default, new zone can't see any other zones # by default, new zone can't see any other zones
spec.doSetAttrib(entId, 'visibility', []) spec.doSetAttrib(zoneNum, 'visibility', [])
if newZonesGloballyVisible: if newZonesGloballyVisible:
for entId in zoneEntIds: for entId in zoneEntIds:

View File

@ -7,12 +7,12 @@ class ZoneEntity(ZoneEntityBase.ZoneEntityBase, BasicEntities.NodePathAttribs):
def __init__(self, level, entId): def __init__(self, level, entId):
ZoneEntityBase.ZoneEntityBase.__init__(self, level, entId) ZoneEntityBase.ZoneEntityBase.__init__(self, level, entId)
self.nodePath = self.level.getZoneNode(self.modelZoneNum) self.nodePath = self.level.getZoneNode(self.entId)
if __dev__: if __dev__:
if self.nodePath is None: if self.nodePath is None:
self.level.reportModelSpecSyncError( self.level.reportModelSpecSyncError(
'unknown modelZoneNum %s; zone was removed from model?' % 'unknown zoneNum %s; zone was removed from model?' %
self.modelZoneNum) self.entId)
BasicEntities.NodePathAttribs.initNodePathAttribs(self, doReparent=0) BasicEntities.NodePathAttribs.initNodePathAttribs(self, doReparent=0)
# dict of zoneNum to 'visible' reference count # dict of zoneNum to 'visible' reference count

View File

@ -24,5 +24,5 @@ class ZoneEntityBase(Entity.Entity):
return self.zoneId return self.zoneId
def getZoneNum(self): def getZoneNum(self):
"""zoneNum from model""" """zoneNum from model / entityId"""
return self.modelZoneNum return self.entId