소스 검색

spec update fixes -- use correct entTypeReg, put new zones in all viz lists

Darren Ranalli 22 년 전
부모
커밋
0b1cd49273
2개의 변경된 파일43개의 추가작업 그리고 24개의 파일을 삭제
  1. 0 8
      direct/src/level/LevelSpec.py
  2. 43 16
      direct/src/level/SpecUtil.py

+ 0 - 8
direct/src/level/LevelSpec.py

@@ -52,14 +52,6 @@ class LevelSpec:
             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)

+ 43 - 16
direct/src/level/SpecUtil.py

@@ -4,24 +4,31 @@ import LevelSpec
 import LevelConstants
 import LevelUtil
 from PythonUtil import list2dict
+import EntityTypes
+import types
 
-def makeNewSpec(filename, modelPath):
+def makeNewSpec(filename, modelPath, entTypeModule=EntityTypes):
     """call this to create a new level spec for the level model at 'modelPath'.
     Spec will be saved as 'filename'"""
     spec = LevelSpec.LevelSpec()
-    privUpdateSpec(spec, modelPath)
+    privUpdateSpec(spec, modelPath, entTypeModule)
     spec.saveToDisk(filename, makeBackup=0)
 
-def updateSpec(specModule, modelPath=None):
+def updateSpec(specModule, entTypeModule=EntityTypes, modelPath=None):
     """Call this to update an existing levelSpec to work with a new level
     model. If the level model has a new path, pass it in as 'modelPath'.
     specModule must be a Python module"""
     spec = LevelSpec.LevelSpec(specModule)
-    privUpdateSpec(spec, modelPath)
+    privUpdateSpec(spec, modelPath, entTypeModule)
     spec.saveToDisk()
 
-def privUpdateSpec(spec, modelPath=None):
+def privUpdateSpec(spec, modelPath, entTypeModule):
     """internal: take a spec and update it to match its level model"""
+    assert type(entTypeModule) is types.ModuleType
+    import EntityTypeRegistry
+    etr = EntityTypeRegistry.EntityTypeRegistry(entTypeModule)
+    spec.setEntityTypeReg(etr)
+
     if modelPath is None:
         modelPath = spec.getEntitySpec(
             LevelConstants.LevelMgrEntId)['modelFilename']
@@ -39,20 +46,21 @@ def privUpdateSpec(spec, modelPath=None):
     type2ids = spec.getEntType2ids(spec.getAllEntIds())
     type2ids.setdefault('zone', [])
     zoneEntIds = type2ids['zone']
-    zoneEntId2spec = list2dict(zoneEntIds)
-    for entId in zoneEntIds:
-        zoneEntId2spec[entId] = spec.getEntitySpec(entId)
 
-    def removeZoneEntity(entId, spec=spec, zoneEntIds=zoneEntIds,
-                         zoneEntId2spec=zoneEntId2spec):
+    def removeZoneEntity(entId, spec=spec, zoneEntIds=zoneEntIds):
         spec.removeEntity(entId)
         zoneEntIds.remove(entId)
-        del zoneEntId2spec[entId]
+
+    def insertZoneEntity(entId, modelZoneNum, spec=spec, zoneEntIds=zoneEntIds):
+        spec.insertEntity(entId, 'zone', LevelConstants.UberZoneEntId)
+        spec.doSetAttrib(entId, 'name', 'zone%s' % modelZoneNum)
+        spec.doSetAttrib(entId, 'modelZoneNum', modelZoneNum)
+        zoneEntIds.append(entId)
 
     # create dict of zoneNum -> entId
     zoneNum2entId = {}
     for entId in list(zoneEntIds):
-        zoneNum = zoneEntId2spec[entId]['modelZoneNum']
+        zoneNum = spec.getEntitySpec(entId)['modelZoneNum']
         if zoneNum in zoneNum2entId:
             print ('multiple zone entities reference zoneNum %s; removing '
                    'entity %s' % (zoneNum, entId))
@@ -61,17 +69,22 @@ def privUpdateSpec(spec, modelPath=None):
         zoneNum2entId[zoneNum] = entId
 
     # prune zone entities that reference zones that no longer exist
+    removedZoneNums = []
     for entId in list(zoneEntIds):
-        zoneNum = zoneEntId2spec[entId]['modelZoneNum']
+        zoneNum = spec.getEntitySpec(entId)['modelZoneNum']
         if zoneNum not in modelZoneNums:
             print 'zone %s no longer exists; removing entity %s' % (
                 zoneNum, entId)
             removeZoneEntity(entId)
             del zoneNum2entId[zoneNum]
+            removedZoneNums.append(zoneNum)
             
     # add new zone entities for new zones
+    newZoneNums = []
     for zoneNum in modelZoneNums:
         if zoneNum not in zoneNum2entId:
+            newZoneNums.append(zoneNum)
+
             entIdDict = list2dict(spec.getAllEntIds())
             entId = LevelConstants.ZoneEntIdStart
             # we could do better than linear
@@ -79,12 +92,26 @@ def privUpdateSpec(spec, modelPath=None):
                 entId += 1
 
             print 'adding entity %s for new zone %s' % (entId, zoneNum)
-            spec.insertEntity(entId, 'zone', LevelConstants.UberZoneEntId)
-            spec.doSetAttrib(entId, 'name', 'zone%s' % zoneNum)
-            spec.doSetAttrib(entId, 'modelZoneNum', zoneNum)
+            insertZoneEntity(entId, zoneNum)
             # by default, new zone can see every other zone
             visList = list(modelZoneNums)
             # cur zone and uberzone are implicit
             visList.remove(zoneNum)
             visList.remove(0)
+            visList.sort()
             spec.doSetAttrib(entId, 'visibility', visList)
+
+    # make sure none of the zones reference removed zones, and add
+    # the new zones to each zone's visibility list
+    for entId in zoneEntIds:
+        visList = spec.getEntitySpec(entId)['visibility']
+        visDict = list2dict(visList)
+        for zoneNum in removedZoneNums:
+            if zoneNum in visDict:
+                del visDict[zoneNum]
+        for zoneNum in newZoneNums:
+            if zoneNum not in visDict:
+                visDict[zoneNum]=None
+        visList = visDict.keys()
+        visList.sort()
+        spec.doSetAttrib(entId, 'visibility', visList)