SA2MTA/sa2mta.py

244 lines
6.9 KiB
Python

import sys
import os
import json
import shutil
p = os.path.join
def gtaStripLine(line):
line = line.replace("\n","")
line = line.replace("\r","")
while len(line) > 0 and line[0] in " ":
line = line[1:]
while len(line) > 0 and line[-1] in " ":
line = line[:-1]
return line
def gtaProcessConfigLine(line,commentChars="#\n",spaceChars=" "):
lineList = []
lineListLength = 0
currentValue = ""
def addValue():
nonlocal currentValue
nonlocal lineList
nonlocal lineListLength
if currentValue == "": return
lineList.append(currentValue)
currentValue = ""
lineListLength += 1
for char in line:
if char in commentChars: break
if char == "\r": continue
if char in spaceChars:
addValue()
continue
currentValue += char
addValue()
return lineList
def gtaReadIde(file):
elements = {}
with open(file) as fileh:
section = False
for line in fileh:
line = gtaStripLine(line)
line = line.split("#",1)[0]
args = line.split(",")
index = 0
length = len(args)
if length == 0: continue
while index < length:
args[index] = gtaStripLine(args[index])
index += 1
while length > 0 and args[-1] == "":
args = args[:-1]
length -= 1
if length == 0: continue
if length == 1:
section = args[0].lower()
if section == "end": section = False
continue
if section == False:
print("Malformed IDE - No section.")
continue
element = {}
if section == "objs":
element["id"] = args[0]
element["modelName"] = args[1]
element["textureName"] = args[2]
element["objectCount"] = 1
element["drawDistances"] = [args[3]]
element["flags"] = args[4]
if len(args) > 5:
element["objectCount"] = args[3]
element["drawDistances"] = args[4:4 + int(element["objectCount"])]
element["flags"] = args[4 + int(element["objectCount"])]
if not section in elements: elements[section] = []
if element != {}:
elements[section].append(element)
return elements
def gtaReadIpl(file):
elements = {}
with open(file) as fileh:
section = False
for line in fileh:
line = gtaStripLine(line)
line = line.split("#",1)[0]
args = line.split(",")
index = 0
length = len(args)
if length == 0: continue
while index < length:
args[index] = gtaStripLine(args[index])
index += 1
if length == 1:
section = args[0].lower()
if section == "end": section = False
continue
if section == False:
print("Malformed IPL - No section.")
continue
element = {}
if section == "inst":
element["id"] = args[0]
element["modelName"] = args[1]
element["interior"] = args[2]
element["position"] = [args[3],args[4],args[5]]
element["rotation"] = [args[6],args[7],args[8],args[9]]
if length < 11:
element["lod"] = "-1"
else:
element["lod"] = args[10]
if not section in elements: elements[section] = []
if element != {}:
elements[section].append(element)
return elements
def gtaReadDat(filePath,output={}):
global pathSA
with open(filePath,"r") as fileDat:
for line in fileDat:
line = gtaStripLine(line)
lineList = gtaProcessConfigLine(line)
if len(lineList) < 1: continue
if len(lineList) < 2:
print("Malformed line in gta.dat: " +line)
continue
dataType = lineList[0].lower()
dataPath = lineList[1].lower()
dataPathFull = p(pathSA,dataPath)
if dataType == "ide":
if not dataType in output: output[dataType] = {}
if not dataPath in output[dataType]:
output[dataType][dataPath] = gtaReadIde(dataPathFull)
if dataType == "ipl":
if not dataType in output: output[dataType] = {}
if not dataPath in output[dataType]:
output[dataType][dataPath] = gtaReadIpl(dataPathFull)
return output
def main():
global pathSA
pathSA = input("Path to San Andreas: ").replace("'","").replace('"',"")
pathGtaDat = p(pathSA,"data","gta.dat")
pathDefaultDat = p(pathSA,"data","default.dat")
pathOut = False
while pathOut == False or os.path.isdir(pathOut):
pathOut = input("Path to save resource in: ").replace("'","").replace('"',"")
shutil.copytree("baseResource",pathOut)
print("\n-- Interpreting files... --")
data = gtaReadDat(pathGtaDat)
data = gtaReadDat(pathDefaultDat,data)
print("Writing raw definitions...")
with open(p(pathOut,"raw.json"),"w") as logfile:
logfile.write(json.dumps(data, indent=2))
print("-- Re-interpreting and writing resource... --")
fileMeta = open(p(pathOut,"meta.xml"),"w")
fileMeta.write("<meta>\n")
fileMeta.write('<info author="unknown" version="1.0.0" name="' +pathOut.rsplit(os.path.sep,1)[-1]+ '"/>\n')
fileMeta.write('<download_priority_group>-1</download_priority_group>\n')
fileMeta.write('<script src="col.lua" type="client"/>\n')
fileMeta.write('<script src="quaternion.lua" type="client"/>\n')
fileMeta.write('<script src="client.lua" type="client"/>\n')
for ide in data["ide"]:
fileMeta.write('<script src="gta/' +ide.replace("\\","/")+ '.lua" type="client"/>\n')
for ipl in data["ipl"]:
fileMeta.write('<script src="gta/' +ipl.replace("\\","/")+ '.lua" type="client"/>\n')
objectIDs = []
iplIndex = 0
for ipl in data["ipl"]:
pathIpl = p(pathOut,"gta",ipl.replace("\\",os.path.sep) + ".lua")
try:
os.makedirs(os.path.dirname(pathIpl))
except:
pass
with open(pathIpl,"w") as fileIpl:
sectionIndex = 0
for section in data["ipl"][ipl]:
itemIndex = 0
if section == "inst":
for element in data["ipl"][ipl][section]:
if not element["id"] in objectIDs:
objectIDs.append(element["id"])
fileIpl.write('placeObject(' +str(iplIndex)+ ',' +str(sectionIndex)+ ',' +str(itemIndex)+ ',' +element["id"]+ ',' +element["interior"]+ ',' +element["position"][0]+ ',' +element["position"][1]+ ',' +element["position"][2]+ ',' +element["rotation"][0]+ ',' +element["rotation"][1]+ ',' +element["rotation"][2]+ ',' +element["rotation"][3]+ ',' +element["lod"]+ ')\n')
itemIndex += 1
sectionIndex += 1
iplIndex += 1
modelNames = []
textureNames = []
for ide in data["ide"]:
pathIde = p(pathOut,"gta",ide.replace("\\",os.path.sep) + ".lua")
try:
os.makedirs(os.path.dirname(pathIde))
except:
pass
with open(pathIde,"w") as fileIde:
for section in data["ide"][ide]:
if section == "objs":
for element in data["ide"][ide][section]:
if not element["id"] in objectIDs: continue
fileIde.write('registerObject(' +element["id"]+ ',"' +element["modelName"]+ '","' +element["textureName"]+ '",' +element["drawDistances"][0]+ ')\n')
if not element["modelName"] in modelNames:
fileMeta.write('<file src="img/' +element["modelName"]+ '.dff"/>\n')
modelNames.append(element["modelName"])
if not element["textureName"] in textureNames:
fileMeta.write('<file src="img/' +element["textureName"]+ '.txd"/>\n')
textureNames.append(element["textureName"])
fileMeta.write("</meta>\n")
fileMeta.close()
main()