Poodletooth-iLand/toontown/dna/DNALoader.py
2015-03-03 17:10:12 -05:00

220 lines
7.1 KiB
Python

from pandac.PandaModules import *
from direct.distributed.PyDatagramIterator import PyDatagramIterator
from direct.distributed.PyDatagram import PyDatagram
from direct.stdpy.file import *
import DNAUtil
import DNAError
import DNAAnimBuilding
import DNAAnimProp
import DNACornice
import DNADoor
import DNAFlatBuilding
import DNAFlatDoor
import DNAGroup
import DNAInteractiveProp
import DNALandmarkBuilding
import DNANode
import DNAProp
import DNASign
import DNASignBaseline
import DNASignGraphic
import DNASignText
import DNAStreet
import DNAVisGroup
import DNAWall
import DNAWindows
import DNABattleCell
import DNASuitPoint
import zlib
import sys
sys.setrecursionlimit(10000)
compClassTable = {
1: DNAGroup.DNAGroup,
2: DNAVisGroup.DNAVisGroup,
3: DNANode.DNANode,
4: DNAProp.DNAProp,
5: DNASign.DNASign,
6: DNASignBaseline.DNASignBaseline,
7: DNASignText.DNASignText,
8: DNASignGraphic.DNASignGraphic,
9: DNAFlatBuilding.DNAFlatBuilding,
10: DNAWall.DNAWall,
11: DNAWindows.DNAWindows,
12: DNACornice.DNACornice,
13: DNALandmarkBuilding.DNALandmarkBuilding,
14: DNAAnimProp.DNAAnimProp,
15: DNAInteractiveProp.DNAInteractiveProp,
16: DNAAnimBuilding.DNAAnimBuilding,
17: DNADoor.DNADoor,
18: DNAFlatDoor.DNAFlatDoor,
19: DNAStreet.DNAStreet
}
childlessComps = (
7, # DNASignText
11, # DNAWindows
12, # DNACornice
17, # DNADoor
18, # DNAFlatDoor
19 # DNAStreet
)
class DNALoader:
def __init__(self):
self.dnaStorage = None
self.prop = None
def destroy(self):
del self.dnaStorage
del self.prop
def handleStorageData(self, dgi):
# Catalog Codes
numRoots = dgi.getUint16()
for _ in xrange(numRoots):
root = DNAUtil.dgiExtractString8(dgi)
numCodes = dgi.getUint8()
for i in xrange(numCodes):
code = DNAUtil.dgiExtractString8(dgi)
self.dnaStorage.storeCatalogCode(root, code)
# Textures
numTextures = dgi.getUint16()
for _ in xrange(numTextures):
code = DNAUtil.dgiExtractString8(dgi)
filename = DNAUtil.dgiExtractString8(dgi)
self.dnaStorage.storeTexture(code, loader.pdnaTexture(filename, okMissing=True))
# Fonts
numFonts = dgi.getUint16()
for _ in xrange(numFonts):
code = DNAUtil.dgiExtractString8(dgi)
filename = DNAUtil.dgiExtractString8(dgi)
self.dnaStorage.storeFont(code, loader.pdnaFont(filename))
# Nodes
self.handleNode(dgi, target = self.dnaStorage.storeNode)
self.handleNode(dgi, target = self.dnaStorage.storeHoodNode)
self.handleNode(dgi, target = self.dnaStorage.storePlaceNode)
# Blocks
numBlocks = dgi.getUint16()
for _ in xrange(numBlocks):
number = dgi.getUint8()
zone = dgi.getUint16()
title = DNAUtil.dgiExtractString8(dgi)
article = DNAUtil.dgiExtractString8(dgi)
bldgType = DNAUtil.dgiExtractString8(dgi)
self.dnaStorage.storeBlock(number, title, article, bldgType, zone)
# Suit Points
numPoints = dgi.getUint16()
for _ in xrange(numPoints):
index = dgi.getUint16()
pointType = dgi.getUint8()
x, y, z = (dgi.getInt32() / 100.0 for i in xrange(3))
graph = dgi.getUint8()
landmarkBuildingIndex = dgi.getInt8()
self.dnaStorage.storeSuitPoint(DNASuitPoint.DNASuitPoint(index, pointType, LVector3f(x, y, z), landmarkBuildingIndex))
# Suit Edges
numEdges = dgi.getUint16()
for _ in xrange(numEdges):
index = dgi.getUint16()
numPoints = dgi.getUint16()
for i in xrange(numPoints):
endPoint = dgi.getUint16()
zoneId = dgi.getUint16()
self.dnaStorage.storeSuitEdge(index, endPoint, zoneId)
# Battle Cells
numCells = dgi.getUint16()
for _ in xrange(numCells):
w = dgi.getUint8()
h = dgi.getUint8()
x, y, z = (dgi.getInt32() / 100.0 for i in xrange(3))
self.dnaStorage.storeBattleCell(DNABattleCell.DNABattleCell(w, h, LVector3f(x, y, z)))
def handleCompData(self, dgi):
while True:
propCode = dgi.getUint8()
if propCode == 255:
if self.prop == None:
raise DNAError.DNAError('Unexpected 255 found.')
prop = self.prop.getParent()
if prop is not None:
self.prop = prop
else:
assert self.prop.getName() == 'root'
elif propCode in compClassTable:
propClass = compClassTable[propCode]
if propClass.__init__.func_code.co_argcount > 1:
newComp = propClass('unnamed_comp')
else:
newComp = propClass()
if propCode == 2:
newComp.makeFromDGI(dgi, self.dnaStorage)
self.dnaStorage.storeDNAVisGroup(newComp)
else:
newComp.makeFromDGI(dgi)
else:
raise DNAError.DNAError('Invalid prop code: %d' % propCode)
if dgi.getRemainingSize():
if propCode != 255:
if self.prop is not None:
newComp.setParent(self.prop)
self.prop.add(newComp)
if propCode not in childlessComps:
self.prop = newComp
continue
break
def handleNode(self, dgi, target = None):
if target is None:
return
numNodes = dgi.getUint16()
for _ in xrange(numNodes):
code = DNAUtil.dgiExtractString8(dgi)
file = DNAUtil.dgiExtractString8(dgi)
node = DNAUtil.dgiExtractString8(dgi)
np = NodePath(loader.pdnaModel(file))
if node:
newNode = np.find('**/' + node).copyTo(NodePath())
np.removeNode()
np = newNode
np.setTag('DNACode', code)
np.setTag('DNARoot', node)
target(np, code)
def loadDNAFileBase(self, dnaStorage, file):
self.dnaStorage = dnaStorage
dnaFile = open(file, 'rb')
dnaData = dnaFile.read()
dg = PyDatagram(dnaData)
dgi = PyDatagramIterator(dg)
dnaFile.close()
header = dgi.extractBytes(5)
if header != 'PDNA\n':
raise DNAError.DNAError('Invalid header: %s' % (header))
compressed = dgi.getBool()
dgi.skipBytes(1)
if compressed:
data = dgi.getRemainingBytes()
data = zlib.decompress(data)
dg = PyDatagram(data)
dgi = PyDatagramIterator(dg)
self.handleStorageData(dgi)
self.handleCompData(dgi)
def loadDNAFile(self, dnaStorage, file):
self.loadDNAFileBase(dnaStorage, file)
nodePath = NodePath(PandaNode('dna'))
self.prop.traverse(nodePath, self.dnaStorage)
return nodePath
def loadDNAFileAI(self, dnaStorage, file):
self.loadDNAFileBase(dnaStorage, file)
return self.prop