Code:
import sys
import struct
class WRPError:
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class WRPObject:
def __init__(self, rotation, position, index, path):
if self.rotation:
self.rotation = rotation
else:
self.rotation = (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)
self.position = position
self.index = index
self.path = path
def pack(self):
tmp = ("9f3fi76s", ) + self.rotation + self.position + (self.index,self.path)
return struct.pack( *tmp )
def __str__(self):
return "WRPObject(%s, %s, %s, %s)" % (self.rotation, self.position, self.index, self.path)
def __repr__(self):
return "WRPObject(%r, %r, %r, %r)" % (self.rotation, self.position, self.index, self.path)
def shortToFloat(packed): return float(packed) / 22.222;
def floatToShort(number): return int( max( -1800.0, min(1800.0, number) ) * 22.222 )
class WRPFile:
def __init__(self):
self.width = 1
self.height = 1
self.textures = []
self.elevations = []
self.textureIndices = []
self.objects = []
def readFromPath(self, path):
file = open(path, "rb")
self.readFromFile(file)
file.close()
def readFromFile(self, file, close=False):
magic = struct.unpack("4s", file.read(4))[0]
if magic == "4WVR":
self.read4WVR(file, close)
elif magic == "8WVR":
raise WRPError, "8WVR is not supported yet!"
else:
raise WRPError, "Only 4WVR WRP files are supported, not '%s'!" % magic
def read4WVR(self, file, close):
self.width, self.height = struct.unpack("2i", file.read(8))
if self.width != self.height:
raise WRPError, "Width and height are supposed to be the same, not %d x %d!" % (self.width, self.height)
cellcount = self.width * self.height
elevReader = ( struct.unpack("h", file.read(2))[0] for x in xrange(cellcount) )
self.elevations = [ float(x)/22.222 for x in elevReader ]
# now the same number of texture indices!
self.textureIndices = [ struct.unpack("H", file.read(2))[0] for x in xrange(cellcount) ]
# now the texture paths!
# Every path is 32 byte 0-terminated/padded string; there are always 512!
self.textures = [ struct.unpack("32s", file.read(32))[0] for x in xrange(512) ]
# now comes the tricky part! The objects have the following layout
# float[9] rotation; /// rotation matrix
# float x, z, y; /// the position of the object
# uint index; /// the index on the map
# char[76] path; /// the path to the object
#
# those are 13*4 + 76 bytes = 128
# now we read 128 bytes as long as
buf = file.read(128)
while len(buf) == 128:
obj = struct.unpack("9f3fi76s", buf)
self.objects.append( WRPObject( obj[0:9], obj[9:12], obj[12], obj[13] ) )
buf = file.read(128)
if close:
file.close()
def writeToPath(self, path):
file = open(path, "wb")
self.writeToFile(file)
file.close()
def writeToFile(self, file, close=False):
file.write("4WVR")
file.write( struct.pack("ii", self.width, self.height) )
for elev in self.elevations:
file.write( struct.pack("h", floatToShort(elev) ) )
for index in self.textureIndices:
file.write( struct.pack("H", index) )
# first texture should be '\data\more_anim.01.pac'
for texture in self.textures:
file.write( struct.pack("32s", texture) )
# if there were not enough textures, fill them up!
for i in xrange( 512 - len(self.textures) ):
file.write( struct.pack("32s", "") )
# now the objects...
for obj in self.objects:
file.write( obj.pack() )
if close:
file.close()
def generate(self, size, defaultHeight):
self.width = size
self.height = size
self.textures = ['\\data\\more_anim.01.pac']
self.elevations = [ defaultHeight for x in xrange(size*size) ]
self.textureIndices = [ 1 for x in xrange(size*size) ]
def printInfo(self):
print "Size: %d x %d" % (self.width, self.height)
print "Number of elevations: %d" % len(self.elevations)
print "Number of texture indices: %d" % len(self.textureIndices)
print "Number of (non-empty) textures: %d" % len(self.textures)
print "Number of objects: %d" % len(self.objects)
The objects you add, need to be realigned to ground in WrpTool manually, since there is some extra data from the models (the offset value) required to place the models correctly.