Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # created using python 3.6
- import math
- import os
- from struct import pack, unpack, calcsize
- import subprocess
- import sys
- import tempfile
- from zipfile import ZipFile
- ImageMagicConvert = '/usr/bin/convert'
- decalsArchivePath = '/home/b2ag/PlayOnLinux virtual drives/Supreme_Commander/drive_c/Program Files/THQ/Gas Powered Games/Supreme Commander - Forged Alliance/gamedata/env.scd'
- SCMAPMAGIC = b'\x4d\x61\x70\x1a'
- DDSMAGIC = b'DDS '
- debugEnabled = False
- class MapParsingException(Exception):
- def __init__( self, subject, fileObject ):
- self.offset = fileObject.tell()
- self.message = "Couldn't parse {} before offset {} ".format( subject, self.offset )
- super(Exception, self).__init__( self.message )
- def readcstr(f):
- buf = b''
- while True:
- b = f.read(1)
- if b is None or b == b'\0':
- return buf
- else:
- buf += b
- def getOffsetsFromMap( pathToScmap, offsets ):
- if type( offsets ) is not dict:
- raise Exception("Offsets parameter needs to have type of dict.")
- def debugPrint( label, text ):
- if debugEnabled:
- print("{}: {}".format(label,text))
- #mirrorMode = "Diagonal Top-Left to Bottom-Right"
- mirrorMode = "Left-Right"
- if mirrorMode == "Diagonal Top-Left to Bottom-Right":
- def mirrorPropPosition( position, mapSize ):
- return ( position[2], position[1], position[0] )
- def mirrorDecalPosition( position, mapSize ):
- return ( position[2], position[1], position[0] )
- def mirrorDecalRotation(rotation):
- return ( rotation[0], -rotation[1], rotation[2] )
- def mirrorDecalScale(scale):
- return ( scale[0], scale[1], scale[2] )
- def mirrorDecal( decalsArchive, decalToMirror ):
- if not decalToMirror:
- return b''
- newDecalPath = outDirectory + '/mdtlbr' + decalToMirror
- newDecalIngamePath = '/maps/{}/mdtlbr{}'.format( outMapNameWithVersion, decalToMirror )
- if os.path.exists( newDecalPath ):
- #print("{} already exists. Not going to overwrite.".format(newDecalPath))
- return newDecalIngamePath.encode()
- with decalsArchive.open(decalsArchive.decalsCaseInsensitiveLookup[decalToMirror[1:].lower()]) as decalTexture:
- with tempfile.NamedTemporaryFile() as originalDecalTempFile:
- originalDecalTempFile.write( decalTexture.read() )
- os.makedirs( os.path.dirname( newDecalPath ), exist_ok = True )
- subprocess.run([ImageMagicConvert, originalDecalTempFile.name, "-flop","-rotate","-90", newDecalPath])
- print(newDecalPath)
- return newDecalIngamePath.encode()
- # not really posible to mirror the mesh by rotation...
- def mirrorPropRotation( rotationX, rotationY, rotationZ ):
- newRotationX = ( -rotationX[0], rotationX[1], -rotationX[2] )
- newRotationY = ( rotationY[0], rotationY[1], rotationY[2] )
- newRotationZ = ( -rotationZ[0], rotationZ[1], -rotationZ[2] )
- return ( newRotationX, newRotationY, newRotationZ )
- elif mirrorMode == "Left-Right":
- def mirrorPropPosition( position, mapSize ):
- return ( ( mapSize[0] - position[0] ), position[1], position[2] )
- def mirrorDecalPosition( position, mapSize ):
- return ( ( mapSize[0] - position[0] ), position[1], position[2] )
- def mirrorDecalRotation(rotation):
- return ( -rotation[0], math.pi/2 - rotation[1], rotation[2] )
- def mirrorDecalScale(scale):
- return ( scale[0], scale[1], scale[2] )
- def mirrorDecal( decalsArchive, decalToMirror ):
- if not decalToMirror:
- return b''
- newDecalPath = outDirectory + '/mflop' + decalToMirror
- newDecalIngamePath = '/maps/{}/mflop{}'.format( outMapNameWithVersion, decalToMirror )
- if os.path.exists( newDecalPath ):
- #print("{} already exists. Not going to overwrite.".format(newDecalPath))
- return newDecalIngamePath.encode()
- print("Converting {}".format(newDecalPath))
- with decalsArchive.open(decalsArchive.decalsCaseInsensitiveLookup[decalToMirror[1:].lower()]) as decalTexture:
- with tempfile.NamedTemporaryFile() as originalDecalTempFile:
- originalDecalTempFile.write( decalTexture.read() )
- os.makedirs( os.path.dirname( newDecalPath ), exist_ok = True )
- cmd = [ImageMagicConvert,
- "-define","dds:compression=dxt5",
- "-define","dds:cluster-fit=true",
- "-define","dds:mipmaps=3",
- originalDecalTempFile.name,
- "-flop","-rotate","-90",
- newDecalPath]
- print("running {}".format(' '.join(cmd)))
- subprocess.run(cmd)
- return newDecalIngamePath.encode()
- # not really posible to mirror the mesh by rotation...
- def mirrorPropRotation( rotationX, rotationY, rotationZ ):
- newRotationX = ( math.pi/2 + rotationX[0], rotationX[1], math.pi/2 + rotationX[2] )
- newRotationY = ( rotationY[0], rotationY[1], rotationY[2] )
- newRotationZ = ( math.pi/2 + rotationZ[0], rotationZ[1], math.pi/2 + rotationZ[2] )
- return ( newRotationX, newRotationY, newRotationZ )
- def readMap( pathToScmap, decalsArchive ):
- infos = {}
- listOfDebugProps = []
- with open(pathToScmap,'rb') as scmap:
- scmapMagic = scmap.read(4)
- if scmapMagic != SCMAPMAGIC:
- raise MapParsingException( "file magic", scmap )
- fileVersionMajor = unpack('I', scmap.read(4) )[0]
- if not fileVersionMajor:
- raise MapParsingException( "file major version", scmap )
- debugPrint( "fileVersionMajor", fileVersionMajor )
- # always 0xbeeffeed and other always 2
- (unknown3,unknown4) = ( scmap.read(4), scmap.read(4) )
- debugPrint( "unknown3", unknown3 )
- debugPrint( "unknown4", unknown4 )
- (scaledMapWidth,scaledMapHeight) = unpack('ff', scmap.read(calcsize('ff')) )
- if not scaledMapWidth or not scaledMapHeight:
- raise MapParsingException( "scaled map size", scmap )
- debugPrint( "scaledMapWidth", scaledMapWidth )
- debugPrint( "scaledMapHeight", scaledMapHeight )
- # always 0
- (unknown5,unknown6) = ( scmap.read(4), scmap.read(2) )
- debugPrint( "unknown5", unknown5 )
- debugPrint( "unknown6", unknown6 )
- #######################################################################
- ### Preview Image
- #######################################################################
- previewImageDataLength = unpack('I', scmap.read(4) )[0]
- if not previewImageDataLength:
- raise MapParsingException( "preview image data length", scmap )
- previewImageData = scmap.read(previewImageDataLength)
- if len(previewImageData) != previewImageDataLength:
- raise MapParsingException( "preview image data ({} bytes)".format(previewImageDataLength), scmap )
- debugPrint( "previewImageDataLength", "{} bytes".format(previewImageDataLength) )
- debugPrint( "previewImageDataMagic", previewImageData[0:4].decode( ))
- #if previewImageData[0:4] == DDSMAGIC:
- #previewDataPath = "{}_preview.dds".format( scmap.name )
- #with open(previewDataPath,'wb') as previewDumpFile:
- #previewDumpFile.write( previewImageData )
- #print("preview image dumped to \"{}\"".format(previewDataPath))
- fileVersionMinor = unpack('I', scmap.read(4) )[0]
- if not fileVersionMinor:
- raise MapParsingException( "file minor version", scmap )
- debugPrint( "fileVersionMinor", fileVersionMinor )
- if fileVersionMinor not in [60, 59, 56, 53]:
- raise MapParsingException( "unsupported file minor version", scmap )
- #######################################################################
- mapSize = (mapWidth,mapHeight) = unpack('II', scmap.read(8) )
- if not mapWidth or not mapHeight:
- raise MapParsingException( "map size", scmap )
- debugPrint( "mapWidth", mapWidth )
- debugPrint( "mapHeight", mapHeight )
- #######################################################################
- ### Height Map
- #######################################################################
- # Height Scale, usually 1/128
- heightScale = unpack('f', scmap.read(4) )[0]
- debugPrint( "heightScale", heightScale )
- heightMapDataLength = ( mapHeight + 1 ) * ( mapWidth + 1 ) * calcsize('h')
- debugPrint( "heightMapDataLength", heightMapDataLength )
- heightMapData = scmap.read(heightMapDataLength)
- #######################################################################
- ### Some Shader
- #######################################################################
- if fileVersionMinor >= 56:
- unknown7 = readcstr(scmap)
- debugPrint( "unknown7", unknown7 )
- terrain = readcstr(scmap)
- debugPrint( "terrain", terrain )
- texPathBackground = readcstr(scmap)
- debugPrint( "texPathBackground", texPathBackground )
- texPathSkyCubemap = readcstr(scmap)
- debugPrint( "texPathSkyCubemap", texPathSkyCubemap )
- if fileVersionMinor < 56:
- texPathEnvCubemap = readcstr(scmap)
- debugPrint( "texPathEnvCubemap", texPathEnvCubemap )
- elif fileVersionMinor >= 56:
- environmentLookupTexturesCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "environmentLookupTexturesCount", environmentLookupTexturesCount )
- for i in range(environmentLookupTexturesCount):
- environmentLookupTexturesLabel = readcstr(scmap)
- debugPrint( "environmentLookupTexturesLabel", environmentLookupTexturesLabel )
- environmentLookupTexturesFile = readcstr(scmap)
- debugPrint( "environmentLookupTexturesFile", environmentLookupTexturesFile )
- #######################################################################
- ### Render Settings
- #######################################################################
- lightingMultiplier = unpack('f', scmap.read(4) )[0]
- debugPrint( "lightingMultiplier", lightingMultiplier )
- lightDirection = unpack('fff', scmap.read(12) )
- debugPrint( "lightDirection", lightDirection )
- ambienceLightColor = unpack('fff', scmap.read(12) )
- debugPrint( "ambienceLightColor", ambienceLightColor )
- lightColor = unpack('fff', scmap.read(12) )
- debugPrint( "lightColor", lightColor )
- shadowFillColor = unpack('fff', scmap.read(12) )
- debugPrint( "shadowFillColor", shadowFillColor )
- specularColor = unpack('ffff', scmap.read(16) )
- debugPrint( "specularColor", specularColor )
- bloom = unpack('f', scmap.read(4) )[0]
- debugPrint( "bloom", bloom )
- fogColor = unpack('fff', scmap.read(12) )
- debugPrint( "fogColor", fogColor )
- fogStart = unpack('f', scmap.read(4) )[0]
- debugPrint( "fogStart", fogStart )
- fogEnd = unpack('f', scmap.read(4) )[0]
- debugPrint( "fogEnd", fogEnd )
- hasWater = unpack('c', scmap.read(1) )[0]
- debugPrint( "hasWater", hasWater )
- waterElevation = unpack('f', scmap.read(4) )[0]
- debugPrint( "waterElevation", waterElevation )
- waterElevationDeep = unpack('f', scmap.read(4) )[0]
- debugPrint( "waterElevationDeep", waterElevationDeep )
- waterElevationAbyss = unpack('f', scmap.read(4) )[0]
- debugPrint( "waterElevationAbyss", waterElevationAbyss )
- surfaceColor = unpack('fff', scmap.read(12) )
- debugPrint( "surfaceColor", surfaceColor )
- colorLerpMin = unpack('f', scmap.read(4) )[0]
- debugPrint( "colorLerpMin", colorLerpMin )
- colorLerpMax = unpack('f', scmap.read(4) )[0]
- debugPrint( "colorLerpMax", colorLerpMax )
- refraction = unpack('f', scmap.read(4) )[0]
- debugPrint( "refraction", refraction )
- fresnelBias = unpack('f', scmap.read(4) )[0]
- debugPrint( "fresnelBias", fresnelBias )
- fresnelPower = unpack('f', scmap.read(4) )[0]
- debugPrint( "fresnelPower", fresnelPower )
- reflectionUnit = unpack('f', scmap.read(4) )[0]
- debugPrint( "reflectionUnit", reflectionUnit )
- reflectionSky = unpack('f', scmap.read(4) )[0]
- debugPrint( "reflectionSky", reflectionSky )
- sunShininess = unpack('f', scmap.read(4) )[0]
- debugPrint( "sunShininess", sunShininess )
- sunStrength = unpack('f', scmap.read(4) )[0]
- debugPrint( "sunStrength", sunStrength )
- sunGlow = unpack('f', scmap.read(4) )[0]
- debugPrint( "sunGlow", sunGlow )
- unknown8 = unpack('f', scmap.read(4) )[0]
- debugPrint( "unknown8", unknown8 )
- unknown9 = unpack('f', scmap.read(4) )[0]
- debugPrint( "unknown9", unknown9 )
- sunColor = unpack('fff', scmap.read(12) )
- debugPrint( "sunColor", sunColor )
- reflectionSun = unpack('f', scmap.read(4) )[0]
- debugPrint( "reflectionSun", reflectionSun )
- unknown10 = unpack('f', scmap.read(4) )[0]
- debugPrint( "unknown10", unknown10 )
- ### Texture Maps
- texPathWaterCubemap = readcstr(scmap)
- debugPrint( "texPathWaterCubemap", texPathWaterCubemap )
- texPathWaterRamp = readcstr(scmap)
- debugPrint( "texPathWaterRamp", texPathWaterRamp )
- for i in range(4):
- debugPrint( "waveTexture", i )
- normalsFrequency = unpack('f', scmap.read(4) )[0]
- debugPrint( "normalsFrequency", normalsFrequency )
- for i in range(4):
- debugPrint( "waveTexture", i )
- waveTextureScaleX = unpack('f', scmap.read(4) )[0]
- debugPrint( "waveTextureScaleX", waveTextureScaleX )
- waveTextureScaleY = unpack('f', scmap.read(4) )[0]
- debugPrint( "waveTextureScaleY", waveTextureScaleY )
- waveTexturePath = readcstr(scmap)
- debugPrint( "waveTexturePath", waveTexturePath )
- waveGeneratorCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "waveGeneratorCount", waveGeneratorCount )
- for i in range(waveGeneratorCount):
- debugPrint( "waveGenerator", i )
- textureName = readcstr(scmap)
- debugPrint( "textureName", textureName )
- rampName = readcstr(scmap)
- debugPrint( "rampName", rampName )
- position = unpack('fff', scmap.read(12) )
- debugPrint( "position", position )
- rotation = unpack('f', scmap.read(4) )[0]
- debugPrint( "rotation", rotation )
- velocity = unpack('fff', scmap.read(12) )
- debugPrint( "velocity", velocity )
- lifetimeFirst = unpack('f', scmap.read(4) )[0]
- debugPrint( "lifetimeFirst", lifetimeFirst )
- lifetimeSecond = unpack('f', scmap.read(4) )[0]
- debugPrint( "lifetimeSecond", lifetimeSecond )
- periodFirst = unpack('f', scmap.read(4) )[0]
- debugPrint( "periodFirst", periodFirst )
- periodSecond = unpack('f', scmap.read(4) )[0]
- debugPrint( "periodSecond", periodSecond )
- scaleFirst = unpack('f', scmap.read(4) )[0]
- debugPrint( "scaleFirst", scaleFirst )
- scaleSecond = unpack('f', scmap.read(4) )[0]
- debugPrint( "scaleSecond", scaleSecond )
- frameCount = unpack('f', scmap.read(4) )[0]
- debugPrint( "frameCount", frameCount )
- frameRateFirst = unpack('f', scmap.read(4) )[0]
- debugPrint( "frameRateFirst", frameRateFirst )
- frameRateSecond = unpack('f', scmap.read(4) )[0]
- debugPrint( "frameRateSecond", frameRateSecond )
- stripCount = unpack('f', scmap.read(4) )[0]
- debugPrint( "stripCount", stripCount )
- if fileVersionMinor >= 59:
- unkownData12 = scmap.read(28)
- debugPrint( "unkownData12", unkownData12.hex( ))
- elif fileVersionMinor > 53:
- unkownData12 = scmap.read(24)
- debugPrint( "unkownData12", unkownData12.hex( ))
- else:
- noTileset = readcstr(scmap)
- debugPrint( "noTileset", noTileset )
- if fileVersionMinor > 53:
- strata = ['LowerStratum','Stratum1','Stratum2','Stratum3','Stratum4','Stratum5','Stratum6','Stratum7','Stratum8','UpperStratum']
- debugPrint( "strata", strata )
- for stratum in strata:
- debugPrint( "stratum", stratum )
- albedoFile = readcstr(scmap)
- debugPrint( "albedoFile", albedoFile )
- albedoScale = unpack('f', scmap.read(4) )[0]
- debugPrint( "albedoScale", albedoScale )
- for stratum in strata:
- # fucking special cases
- if stratum == 'UpperStratum':
- # no Normal for UpperStratum
- continue
- debugPrint( "stratum", stratum )
- normalFile = readcstr(scmap)
- debugPrint( "normalFile", normalFile )
- normalScale = unpack('f', scmap.read(4) )[0]
- debugPrint( "normalScale", normalScale )
- else:
- strataCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "strataCount", strataCount )
- for stratum in range(strataCount):
- debugPrint( "stratum", stratum )
- albedoFile = readcstr(scmap)
- debugPrint( "albedoFile", albedoFile )
- normalFile = readcstr(scmap)
- debugPrint( "normalFile", normalFile )
- albedoScale = unpack('f', scmap.read(4) )[0]
- debugPrint( "albedoScale", albedoScale )
- normalScale = unpack('f', scmap.read(4) )[0]
- debugPrint( "normalScale", normalScale )
- unknown13 = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown13", unknown13 )
- unknown14 = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown14", unknown14 )
- #######################################################################
- ### Decals
- #######################################################################
- decalsBlockStartOffset = scmap.tell()
- infos["decalsBlockStartOffset"] = decalsBlockStartOffset
- decalsCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalsCount", decalsCount )
- decalsList = []
- for decalIndex in range(decalsCount):
- decalId = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalId", decalId )
- unknown15 = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown15", unknown15 )
- decalType = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalType", decalType )
- decalsTexture1PathLength = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalsTexture1PathLength", decalsTexture1PathLength )
- if decalsTexture1PathLength > 1024:
- raise MapParsingException( "decalsTexture1PathLength", scmap )
- decalsTexture1Path = scmap.read(decalsTexture1PathLength)
- debugPrint( "decalsTexture1Path", decalsTexture1Path )
- decalsTexture2PathLength = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalsTexture2PathLength", decalsTexture2PathLength )
- if decalsTexture2PathLength > 1024:
- raise MapParsingException( "decalsTexture2PathLength", scmap )
- if decalsTexture2PathLength > 0:
- decalsTexture2Path = scmap.read(decalsTexture2PathLength)
- debugPrint( "decalsTexture2Path", decalsTexture2Path )
- else:
- decalsTexture2Path = b''
- scale = unpack('fff', scmap.read(12) )
- debugPrint( "scale", scale )
- position = unpack('fff', scmap.read(12) )
- debugPrint( "position", position )
- rotation = unpack('fff', scmap.read(12) )
- debugPrint( "rotation", rotation )
- cutOffLOD = unpack('f', scmap.read(4) )[0]
- debugPrint( "cutOffLOD", cutOffLOD )
- nearCutOffLOD = unpack('f', scmap.read(4) )[0]
- debugPrint( "nearCutOffLOD", nearCutOffLOD )
- removeTick = unpack('I', scmap.read(4) )[0]
- debugPrint( "removeTick", removeTick )
- decalDebug = False
- if decalDebug:
- unknown15 = 1
- decal = pack('IIII',decalId,unknown15,decalType,len(decalsTexture1Path))
- decal += decalsTexture1Path
- decal += pack('I',len(decalsTexture2Path))
- if decalsTexture2Path:
- decal += decalsTexture2Path
- decal += pack('fffffffff',*scale,*position,*rotation)
- decal += pack('ffI',cutOffLOD,nearCutOffLOD,removeTick)
- newPosition = mirrorDecalPosition( position, mapSize )
- newRotation = mirrorDecalRotation( rotation )
- newScale = mirrorDecalScale( scale )
- if decalDebug:
- listOfDebugProps += [(
- b'/env/redrocks/props/thetabridge01_prop.bp',
- *position,
- *(-math.cos(rotation[1]),0,-math.sin(rotation[1])),
- *(0,1,0),
- *(math.sin(rotation[1]),0,-math.cos(rotation[1])),
- *(1,1,1))]
- listOfDebugProps += [(
- b'/env/redrocks/props/thetabridge01_prop.bp',
- *newPosition,
- *(-math.cos(newRotation[1]),0,-math.sin(newRotation[1])),
- *(0,1,0),
- *(math.sin(newRotation[1]),0,-math.cos(newRotation[1])),
- *(1,1,1))]
- newDecalsTexture1Path = mirrorDecal( decalsArchive, decalToMirror=decalsTexture1Path.decode() )
- newDecalsTexture2Path = mirrorDecal( decalsArchive, decalToMirror=decalsTexture2Path.decode() )
- newdecal = pack('IIII',decalsCount+decalId,unknown15,decalType,len(newDecalsTexture1Path))
- newdecal += newDecalsTexture1Path
- newdecal += pack('I',len(newDecalsTexture2Path))
- if newDecalsTexture2Path:
- newdecal += newDecalsTexture2Path
- newdecal += pack('fffffffff',*newScale,*newPosition,*newRotation)
- newdecal += pack('ffI',cutOffLOD,nearCutOffLOD,removeTick)
- decalsList += [decal,newdecal]
- #infos["decalsBlockFormat"] = 'IIII{}sI{}sfffffffffffI'.format(decalsTexture1PathLength,decalsTexture2PathLength)
- infos["decalsList"] = decalsList
- decalsBlockEndOffset = scmap.tell()
- infos["decalsBlockEndOffset"] = decalsBlockEndOffset
- decalGroupsCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalGroupsCount", decalGroupsCount )
- for decalGroupIndex in range(decalGroupsCount):
- decalGroupId = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalGroupId", decalGroupId )
- decalGroupName = readcstr(scmap)
- debugPrint( "decalGroupName", decalGroupName )
- decalGroupEntriesCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalGroupEntriesCount", decalGroupEntriesCount )
- for i in range(decalGroupEntriesCount):
- decalGroupEntry = unpack('I', scmap.read(4) )[0]
- debugPrint( "decalGroupEntry", decalGroupEntry )
- (unknown19Width,unknown19Height) = unpack('II', scmap.read(8) )
- debugPrint( "unknown19Width", unknown19Width )
- debugPrint( "unknown19Height", unknown19Height )
- # most often 1, sometimes 4
- normalMapsCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "normalMapsCount", normalMapsCount )
- for normalMapIndex in range(normalMapsCount):
- normalMapDataLength = unpack('I', scmap.read(4) )[0]
- debugPrint( "normalMapDataLength", normalMapDataLength )
- normalMapData = scmap.read(normalMapDataLength)
- debugPrint( "normalMapData", "{}...".format(normalMapData[:4]) )
- #if normalMapData[0:4] == DDSMAGIC:
- #pnormalMapDataPath = "{}_normalMap{}.dds".format( scmap.name, normalMapIndex )
- #with open(pnormalMapDataPath,'wb') as dumpFile:
- #dumpFile.write( normalMapData )
- #print("normalMapData dumped to \"{}\"".format(pnormalMapDataPath))
- if fileVersionMinor < 56:
- unknown20 = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown20", unknown20 )
- textureMapDataLength = unpack('I', scmap.read(4) )[0]
- debugPrint( "textureMapDataLength", textureMapDataLength )
- textureMapData = scmap.read(textureMapDataLength)
- debugPrint( "textureMapData", "{}...".format(textureMapData[:4]) )
- if fileVersionMinor < 56:
- unknown21 = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown21", unknown21 )
- waterMapDataLength = unpack('I', scmap.read(4) )[0]
- debugPrint( "waterMapDataLength", waterMapDataLength )
- waterMapData = scmap.read(waterMapDataLength)
- debugPrint( "waterMapData", "{}...".format(waterMapData[:4]) )
- if fileVersionMinor > 53:
- unknown22 = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown22", unknown22 )
- unknown23MapDataLength = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown23MapDataLength", unknown23MapDataLength )
- unknown23MapData = scmap.read(unknown23MapDataLength)
- debugPrint( "unknown23MapData", "{}...".format(unknown23MapData[:4]) )
- someWaterMapLength = int( (mapWidth / 2) * (mapHeight / 2) )
- waterFoamMapData = scmap.read(someWaterMapLength)
- debugPrint( "waterFoamMapData", "{}...".format(waterFoamMapData[:4]) )
- waterFlatnessMapData = scmap.read(someWaterMapLength)
- debugPrint( "waterFlatnessMapData", "{}...".format(waterFlatnessMapData[:4]) )
- waterDepthBiasMapData = scmap.read(someWaterMapLength)
- debugPrint( "waterDepthBiasMapData", "{}...".format(waterDepthBiasMapData[:4]) )
- terrainTypeDataLength = mapWidth * mapHeight
- debugPrint( "terrainTypeDataLength", "{}...".format(terrainTypeDataLength) )
- terrainTypeData = scmap.read(terrainTypeDataLength)
- debugPrint( "terrainTypeData", "{}...".format(terrainTypeData[:4]) )
- if fileVersionMinor < 53:
- unknown24 = unpack('h', scmap.read(2) )[0]
- debugPrint( "unknown24", unknown24 )
- if fileVersionMinor >= 59:
- unknown25 = scmap.read(64)
- debugPrint( "unknown25", unknown25[:4] )
- unknown26String = readcstr(scmap)
- debugPrint( "unknown26String", unknown26String )
- unknown27String = readcstr(scmap)
- debugPrint( "unknown27String", unknown27String )
- unknown28 = unpack('I', scmap.read(4) )[0]
- debugPrint( "unknown28", unknown28 )
- unknown28MagicFactor = 40
- if unknown28 > 0:
- unknown29 = scmap.read( unknown28 * unknown28MagicFactor )
- debugPrint( "unknown29", unknown29[:4] )
- unknown30 = scmap.read(19)
- debugPrint( "unknown30", unknown30 )
- unknown31String = readcstr(scmap)
- debugPrint( "unknown31String", unknown31String )
- unknown31 = scmap.read(88)
- debugPrint( "unknown31", unknown31[:4] )
- propsBlockStartOffset = scmap.tell()
- infos["propsBlockStartOffset"] = propsBlockStartOffset
- propsCount = unpack('I', scmap.read(4) )[0]
- debugPrint( "propsCount", propsCount )
- propsList = []
- for propIndex in range( 0, propsCount ):
- blueprintPath = readcstr(scmap)
- debugPrint( "blueprintPath", blueprintPath )
- position = unpack('fff', scmap.read(12) )
- debugPrint( "position", position )
- rotationX = unpack('fff', scmap.read(12) )
- debugPrint( "rotationX", rotationX )
- rotationY = unpack('fff', scmap.read(12) )
- debugPrint( "rotationY", rotationY )
- rotationZ = unpack('fff', scmap.read(12) )
- debugPrint( "rotationZ", rotationZ )
- scale = unpack('fff', scmap.read(12) )
- debugPrint( "scale", scale )
- # add this prop to prop to props list
- propsList += [(blueprintPath,*position,*rotationX,*rotationY,*rotationZ,*scale)]
- # create mirrored parameters
- newPosition = mirrorPropPosition( position, mapSize )
- #(newRotationX,newRotationY,newRotationZ) = (rotationX,rotationY,rotationZ)
- (newRotationX,newRotationY,newRotationZ) = mirrorPropRotation(rotationX,rotationY,rotationZ)
- # add version with mirrored parameters to props list
- propsList += [(blueprintPath,*newPosition,*newRotationX,*newRotationY,*newRotationZ,*scale)]
- infos["propsList"] = propsList + listOfDebugProps
- return infos
- def writeMirroredMap( pathToScmap, pathToNewScmap, infos ):
- with open(pathToScmap,'rb') as scmap:
- with open(pathToNewScmap,'wb') as newscmap:
- newscmap.write(scmap.read(infos["decalsBlockStartOffset"]))
- writeDecals( newscmap, infos["decalsList"] )
- scmap.seek(infos["decalsBlockEndOffset"])
- newscmap.write(scmap.read( infos["propsBlockStartOffset"] -infos["decalsBlockEndOffset"] ))
- writeProps( newscmap, infos["propsList"] )
- def writeDecals( newscmap, decalsList ):
- newscmap.write(pack('I',len(decalsList)))
- for decal in decalsList:
- newscmap.write(decal)
- def writeProps( newscmap, propsList ):
- newscmap.write(pack('I',len(propsList)))
- for prop in propsList:
- newscmap.write(prop[0])
- newscmap.write(b'\0')
- newscmap.write(pack('fffffffffffffff',*prop[1:]))
- if __name__ == '__main__':
- if len(sys.argv) < 3:
- print("Usage: {} <infile> <outfile>".format(sys.argv[0]))
- sys.exit(1)
- with ZipFile( decalsArchivePath, 'r' ) as decalsArchive:
- decalsArchive.decalsCaseInsensitiveLookup = { s.lower():s for s in decalsArchive.namelist() }
- pathToNewScmap = sys.argv[2]
- outDirectory = os.path.dirname( pathToNewScmap )
- outMapNameWithVersion = os.path.basename( outDirectory )
- infos = readMap( pathToScmap = sys.argv[1], decalsArchive = decalsArchive )
- writeMirroredMap( pathToScmap = sys.argv[1], pathToNewScmap = pathToNewScmap, infos = infos )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement