|
|
@@ -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)
|