'''Noesis import plugin. Written by Tsukihime Note that this game is published under the names -Talisman Online -Weapons of War Online -TZ Online''' from inc_noesis import * import noesis import rapi def registerNoesisTypes(): '''Register the plugin. Just change the Game name and extension.''' handle = noesis.register("Tz Online", ".evs") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) return 1 def noepyCheckType(data): '''Verify that the format is supported by this plugin. Default yes''' if len(data) < 0: return 0 bs = NoeBitStream(data) return 1 def noepyLoadModel(data, mdlList): '''Build the model, set materials, bones, and animations. You do not need all of them as long as they are empty lists (they are by default)''' ctx = rapi.rpgCreateContext() parser = SanaeParser(data) parser.parse_file() mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(parser.texList, parser.matList)) mdl.setBones(parser.boneList) mdl.setAnims(parser.animList) mdlList.append(mdl) return 1 class Mesh(object): '''A generic mesh object, for convenience''' def __init__(self): self.positions = bytes() self.normals = bytes() self.uvs = bytes() self.numVerts = 0 self.numIdx = 0 self.idxBuff = bytes() self.matName = "" self.meshName = "" class SanaeParser(object): def __init__(self, data): '''Initialize some data. Refer to Sanae.py to see what is already initialized''' self.inFile = NoeBitStream(data) self.animList = [] self.texList = [] self.matList = [] self.boneList = [] self.meshList = [] self.filename = rapi.getLocalFileName(rapi.getInputName()) def build_mesh(self): for mesh in self.meshList: rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 28, 0) rapi.rpgCommitTriangles(None, noesis.RPGEODATA_UINT, mesh.numVerts, noesis.RPGEO_POINTS, 1) def read_name(self): string = self.inFile.readBytes(self.inFile.readUInt()) return noeStrFromBytes(string) def parse_material(self, matNum): idstring = self.inFile.readBytes(21) self.inFile.readByte() # 1 matName = self.read_name() print(matName) self.inFile.readByte() # 1 self.read_name() self.inFile.readUInt() lightmap = self.read_name() self.inFile.readBytes(3) # light properties self.inFile.read('48f') self.inFile.readByte() # 1 # unk self.inFile.readBytes(19) self.read_name() self.read_name() self.read_name() self.inFile.readByte() # 0 self.inFile.read('2L') self.read_name() self.inFile.readByte() # 0 self.inFile.read('3L') self.read_name() self.read_name() self.inFile.seek(18, 1) self.inFile.readByte() # 1 def parse_material_library(self): matIDstring = self.inFile.readBytes(21) self.inFile.readByte() numMat = self.inFile.readUInt() for i in range(numMat): self.parse_material(i) def parse_vertices(self, numVerts, mesh): vertBuff = bytes() totalVerts = 0 print("read %d verts" %numVerts) for i in range(numVerts): if totalVerts == numVerts - 100: break self.inFile.readBytes(12) count = self.inFile.readUInt() for j in range(count): self.inFile.readByte() verts = self.inFile.readBytes(28) self.inFile.readByte() # 1 totalVerts += 1 self.inFile.read('2f') self.inFile.readByte() # 1 vertBuff = b''.join([vertBuff, verts]) mesh.numVerts = totalVerts mesh.vertBuff = vertBuff def parse_faces(self, numIdx): return self.inFile.readBytes(numIdx*2) def parse_file(self): '''Main parser method''' idstring = self.inFile.readBytes(18) self.inFile.readByte() modelName = self.read_name() self.inFile.readByte() mesh = Mesh() faceGroups = self.inFile.readUInt() for i in range(faceGroups): groupName = self.read_name() matName = self.read_name() print(groupName, matName) numIdx = self.inFile.readUInt() self.parse_faces(numIdx) self.inFile.readByte() self.parse_material_library() self.inFile.read('2L') self.inFile.readByte() numVerts = self.inFile.readUInt() self.inFile.readUInt() #? self.parse_vertices(numVerts, mesh) self.inFile.readByte() self.meshList.append(mesh) self.build_mesh()