mirror of
https://github.com/lcdr/utils.git
synced 2024-08-30 17:32:16 +00:00
Added parsing support for older lvl format.
This commit is contained in:
parent
b2946a5c28
commit
60dbb0178d
113
luzviewer.pyw
113
luzviewer.pyw
@ -80,13 +80,15 @@ class LUZViewer(viewer.Viewer):
|
|||||||
scene_name = stream.read(str, char_size=1, length_type=c_ubyte)
|
scene_name = stream.read(str, char_size=1, length_type=c_ubyte)
|
||||||
scene = self.tree.insert(scenes, END, text="Scene", values=(filename, scene_id, scene_name))
|
scene = self.tree.insert(scenes, END, text="Scene", values=(filename, scene_id, scene_name))
|
||||||
assert stream.read(bytes, length=3)
|
assert stream.read(bytes, length=3)
|
||||||
with open(os.path.join(os.path.dirname(luz_path), filename), "rb") as lvl:
|
lvl_path = os.path.join(os.path.dirname(luz_path), filename)
|
||||||
print("Loading lvl", filename)
|
if os.path.exists(lvl_path):
|
||||||
try:
|
with open(lvl_path, "rb") as lvl:
|
||||||
self.parse_lvl(BitStream(lvl.read()), scene)
|
print("Loading lvl", filename)
|
||||||
except Exception:
|
try:
|
||||||
import traceback
|
self.parse_lvl(BitStream(lvl.read()), scene)
|
||||||
traceback.print_exc()
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
assert stream.read(c_ubyte) == 0
|
assert stream.read(c_ubyte) == 0
|
||||||
|
|
||||||
### terrain
|
### terrain
|
||||||
@ -208,46 +210,63 @@ class LUZViewer(viewer.Viewer):
|
|||||||
self.tree.insert(waypoint, END, text="Config", values=(config_name, config_type_and_value))
|
self.tree.insert(waypoint, END, text="Config", values=(config_name, config_type_and_value))
|
||||||
|
|
||||||
def parse_lvl(self, stream, scene):
|
def parse_lvl(self, stream, scene):
|
||||||
while not stream.all_read():
|
if stream[0:4] == b"CHNK":
|
||||||
assert stream._read_offset//8 % 16 == 0 # seems everything is aligned like this?
|
# newer lvl file structure
|
||||||
start_pos = stream._read_offset//8
|
# chunk based
|
||||||
assert stream.read(bytes, length=4) == b"CHNK"
|
while not stream.all_read():
|
||||||
chunktype = stream.read(c_uint)
|
assert stream._read_offset//8 % 16 == 0 # seems everything is aligned like this?
|
||||||
assert stream.read(c_ushort) == 1
|
start_pos = stream._read_offset//8
|
||||||
assert stream.read(c_ushort) in (1, 2)
|
assert stream.read(bytes, length=4) == b"CHNK"
|
||||||
chunk_length = stream.read(c_uint)
|
chunk_type = stream.read(c_uint)
|
||||||
data_pos = stream.read(c_uint)
|
assert stream.read(c_ushort) == 1
|
||||||
stream._read_offset = data_pos * 8
|
assert stream.read(c_ushort) in (1, 2)
|
||||||
assert stream._read_offset//8 % 16 == 0
|
chunk_length = stream.read(c_uint)
|
||||||
if chunktype == 1000:
|
data_pos = stream.read(c_uint)
|
||||||
pass
|
stream._read_offset = data_pos * 8
|
||||||
elif chunktype == 2000:
|
assert stream._read_offset//8 % 16 == 0
|
||||||
pass
|
if chunk_type == 1000:
|
||||||
elif chunktype == 2001:
|
pass
|
||||||
for _ in range(stream.read(c_uint)):
|
elif chunk_type == 2000:
|
||||||
object_id = stream.read(c_int64) # seems like the object id, but without some bits
|
pass
|
||||||
lot = stream.read(c_uint)
|
elif chunk_type == 2001:
|
||||||
unknown1 = stream.read(c_uint)
|
self.lvl_parse_chunk_type_2001(stream, scene)
|
||||||
unknown2 = stream.read(c_uint)
|
elif chunk_type == 2002:
|
||||||
position = stream.read(c_float), stream.read(c_float), stream.read(c_float)
|
pass
|
||||||
rotation = stream.read(c_float), stream.read(c_float), stream.read(c_float), stream.read(c_float)
|
stream._read_offset = (start_pos + chunk_length) * 8 # go to the next CHNK
|
||||||
scale = stream.read(c_float)
|
else:
|
||||||
config_data = stream.read(str, length_type=c_uint)
|
# older lvl file structure
|
||||||
config_data = config_data.replace("{", "<crlbrktopen>").replace("}", "<crlbrktclose>").replace("\\", "<backslash>") # for some reason these characters aren't properly escaped when sent to Tk
|
stream.skip_read(265)
|
||||||
assert stream.read(c_uint) == 0
|
stream.read(str, char_size=1, length_type=c_uint)
|
||||||
lot_name = ""
|
for _ in range(5):
|
||||||
if lot == 176:
|
stream.read(str, char_size=1, length_type=c_uint)
|
||||||
lot_name = "Spawner - "
|
stream.skip_read(4)
|
||||||
lot = config_data[config_data.index("spawntemplate")+16:config_data.index("\n", config_data.index("spawntemplate")+16)]
|
for _ in range(stream.read(c_uint)):
|
||||||
try:
|
stream.read(c_float), stream.read(c_float), stream.read(c_float)
|
||||||
lot_name += self.db.execute("select name from Objects where id == "+str(lot)).fetchone()[0]
|
|
||||||
except TypeError:
|
self.lvl_parse_chunk_type_2001(stream, scene)
|
||||||
print("Name for lot", lot, "not found")
|
|
||||||
lot_name += " - "+str(lot)
|
def lvl_parse_chunk_type_2001(self, stream, scene):
|
||||||
self.tree.insert(scene, END, text="Object", values=(object_id, lot_name, unknown1, unknown2, position, rotation, scale, config_data))
|
for _ in range(stream.read(c_uint)):
|
||||||
elif chunktype == 2002:
|
object_id = stream.read(c_int64) # seems like the object id, but without some bits
|
||||||
pass
|
lot = stream.read(c_uint)
|
||||||
stream._read_offset = (start_pos + chunk_length) * 8 # go to the next CHNK
|
unknown1 = stream.read(c_uint)
|
||||||
|
unknown2 = stream.read(c_uint)
|
||||||
|
position = stream.read(c_float), stream.read(c_float), stream.read(c_float)
|
||||||
|
rotation = stream.read(c_float), stream.read(c_float), stream.read(c_float), stream.read(c_float)
|
||||||
|
scale = stream.read(c_float)
|
||||||
|
config_data = stream.read(str, length_type=c_uint)
|
||||||
|
config_data = config_data.replace("{", "<crlbrktopen>").replace("}", "<crlbrktclose>").replace("\\", "<backslash>") # for some reason these characters aren't properly escaped when sent to Tk
|
||||||
|
assert stream.read(c_uint) == 0
|
||||||
|
lot_name = ""
|
||||||
|
if lot == 176:
|
||||||
|
lot_name = "Spawner - "
|
||||||
|
lot = config_data[config_data.index("spawntemplate")+16:config_data.index("\n", config_data.index("spawntemplate")+16)]
|
||||||
|
try:
|
||||||
|
lot_name += self.db.execute("select name from Objects where id == "+str(lot)).fetchone()[0]
|
||||||
|
except TypeError:
|
||||||
|
print("Name for lot", lot, "not found")
|
||||||
|
lot_name += " - "+str(lot)
|
||||||
|
self.tree.insert(scene, END, text="Object", values=(object_id, lot_name, unknown1, unknown2, position, rotation, scale, config_data))
|
||||||
|
|
||||||
def on_item_select(self, _):
|
def on_item_select(self, _):
|
||||||
item = self.tree.selection()[0]
|
item = self.tree.selection()[0]
|
||||||
|
Loading…
Reference in New Issue
Block a user