Last active
May 15, 2023 14:00
-
-
Save sevonj/250006853487afada89aff6b6ae574a3 to your computer and use it in GitHub Desktop.
Saints Row 2 .chunk_pc Kaitai Struct specification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
meta: | |
id: sr2_chunk_pc | |
file-extension: chunk_pc | |
license: MIT | |
encoding: utf-8 | |
endian: le | |
doc: | | |
MIT License | |
Copyright (c) 2022 Möyh Mäyhem | |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
The chunk parser is incomplete, but it gets pretty far. | |
seq: | |
- id: magic | |
contents: [0x12, 0xca, 0xca, 0xbb] | |
- id: version | |
contents: [0x79, 0x0, 0x0, 0x0] # Version 121. Same for every chunk in sr2. | |
- contents: [0x0e, 0x0, 0x0, 0x0] # Unknown. Same for every chunk in sr2. | |
- id: meshlibrary # 0 on every single chunkfile except for sr2_meshlibrary | |
size: 4 | |
- id: header_0x10 | |
type: u4 | |
- id: header_0x14 | |
size: 24 | |
- contents: [0, 0, 0, 0, 0, 0, 0, 0] | |
- id: header_xx | |
size: 40 | |
- contents: [0, 0, 0, 0] | |
- id: header_xxx | |
size: 20 | |
- contents: [0, 0, 0, 0] | |
- id: header_xxxx | |
size: 20 | |
- id: len_g_chunk_1 | |
type: u4 | |
- id: len_g_chunk_2 | |
type: u4 | |
- id: num_cityobjects | |
type: u4 | |
- id: num_unknown23 | |
type: u4 | |
- id: header_0x9c | |
type: u4 | |
- id: header_0xa0 | |
type: u4 | |
- contents: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 16B null | |
- id: num_mesh_movers | |
type: u4 | |
- id: num_unknown27 | |
type: u4 | |
- id: num_unknown28 | |
type: u4 | |
- id: num_unknown29 | |
type: u4 | |
- id: num_unknown30 | |
type: u4 | |
- id: num_unknown31 | |
type: u4 | |
- id: header_0xcc | |
type: u4 | |
- id: num_unknown26 # almost always 0, exceptions: sr2_skybox, sr2_intdkmissunkdk, sr2_intarcutlimo, sr2_intaicutjyucar | |
type: u4 | |
- id: world_min_x | |
type: f4 | |
- id: world_min_y | |
type: f4 | |
- id: world_min_z | |
type: f4 | |
- id: world_max_x | |
type: f4 | |
- id: world_max_y | |
type: f4 | |
- id: world_max_z | |
type: f4 | |
- id: header_0xec | |
type: f4 | |
- id: num_unknown32 | |
type: u4 | |
- contents: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 12B null | |
# Textures | |
- id: num_texture_names | |
type: u4 | |
- size: num_texture_names * 4 | |
- id: texture_names | |
type: strz | |
repeat: expr | |
repeat-expr: num_texture_names | |
- type: align(16) | |
# Model info | |
- id: num_rendermodels | |
type: u4 | |
- id: num_cityobject_parts | |
type: u4 | |
- id: model_count | |
type: u4 | |
- id: num_unknown3s | |
type: u4 | |
- id: num_unknown4s | |
type: u4 | |
- type: align(16) | |
- id: rendermodel_unk0s | |
type: rendermodel_unk0 | |
repeat: expr | |
repeat-expr: num_rendermodels | |
- type: align(16) | |
- id: cityobject_parts_offset | |
type: offset(_io.pos) | |
- id: cityobject_parts | |
type: cityobject_part | |
repeat: expr | |
repeat-expr: num_cityobject_parts | |
- type: align(16) | |
- id: unknown3s | |
type: unknown3 | |
repeat: expr | |
repeat-expr: num_unknown3s | |
- type: align(16) | |
- id: unknown4s | |
type: unknown4 | |
repeat: expr | |
repeat-expr: num_unknown4s | |
- type: align(16) | |
- id: num_unk_worldpositions | |
type: u4 | |
# Assumption: The data from here to mopp is some | |
# complicated Havok collision model. | |
- id: unk_worldpositions # is this vertices of a baked model? | |
type: vec3 | |
repeat: expr | |
repeat-expr: num_unk_worldpositions | |
- id: num_unknown6s # seems incomprehensible. | |
type: u4 | |
- id: unknown6s | |
size: 3 | |
repeat: expr | |
repeat-expr: num_unknown6s | |
- id: num_unknown7s | |
type: u4 | |
- id: unknown7s | |
type: u4 | |
repeat: expr | |
repeat-expr: num_unknown7s | |
- id: num_unknown8s | |
type: u4 | |
- id: unknown8s | |
size: 12 | |
repeat: expr | |
repeat-expr: num_unknown8s | |
- type: align(16) | |
# https://niftools.sourceforge.net/wiki/Nif_Format/Mopp | |
- id: len_havok_mopp | |
type: u4 | |
- type: align(16) | |
- id: havok_mopp | |
size: len_havok_mopp | |
- type: align(4) | |
# is this a bounding box? | |
- id: unknown10min | |
type: vec3 | |
- id: unknown10max | |
type: vec3 | |
- type: align(16) | |
# Model header | |
- id: model_headers | |
type: model_header(_index) | |
repeat: expr | |
repeat-expr: model_count | |
- id: vert_headers | |
type: vert_header_cont(model_headers[_index].vert_header_count) | |
repeat: expr | |
repeat-expr: model_count | |
- type: align(16) | |
- id: phys_models | |
type: phys_model_buffer( | |
model_headers[_index].type == 7, | |
model_headers[_index].num_indices, | |
vert_headers[_index].vert_header[0].num_vertices) | |
repeat: expr | |
repeat-expr: model_count | |
# Materials | |
- id: num_materials | |
type: u4 | |
- type: align(16) | |
- id: num_mat_shader_params | |
type: u4 | |
- id: pad_mat | |
size: 8 | |
- id: num_mat_unknown3s | |
type: u4 | |
- id: mat_unknown1 | |
type: u4 | |
- id: materials | |
type: material | |
repeat: expr | |
repeat-expr: num_materials | |
- id: mat_flags | |
type: mat_bitflag(materials[_index].bitflag_count) | |
repeat: expr | |
repeat-expr: num_materials | |
# Messing with these break shaders. | |
- id: mat_unknown2 | |
size: 16 | |
repeat: expr | |
repeat-expr: num_materials | |
- type: align(16) | |
# Mostly colors, sometimes affects scrolling textures. | |
- id: mat_shader_params | |
type: f4 | |
repeat: expr | |
repeat-expr: num_mat_shader_params | |
- id: mat_textures | |
type: mat_tex_cont | |
repeat: expr | |
repeat-expr: num_materials | |
- id: mat_unknown3s | |
type: mat_unknown3 | |
repeat: expr | |
repeat-expr: num_mat_unknown3s | |
# uints up to thousands? | |
- id: mat_unknown3_unk2 | |
size: mat_unknown3s[_index].unk2_count * 4 | |
repeat: expr | |
repeat-expr: num_mat_unknown3s | |
- id: rendermodels | |
type: rendermodel | |
repeat: expr | |
repeat-expr: num_rendermodels | |
- id: cityobjects | |
type: cityobject | |
repeat: expr | |
repeat-expr: num_cityobjects | |
- id: cityobject_names | |
type: strz | |
repeat: expr | |
repeat-expr: num_cityobjects | |
- type: align(16) | |
# are these names of destroyable objects? | |
- id: len_unknown_names | |
type: u4 | |
- id: unknown_names | |
size: len_unknown_names | |
- type: align(16) | |
- id: num_unknown13 | |
type: u4 | |
- id: unknown13 | |
type: u4 | |
repeat: expr | |
repeat-expr: num_unknown13 | |
- type: align(16) | |
- id: len_pad17 | |
type: u4 | |
- size: len_pad17 | |
- type: align(16) | |
# Only appears in crib chunks and chunk093, which is where Saints HQ is | |
- id: num_unknown18s | |
type: u4 | |
- id: unknown18s | |
type: unknown18 | |
repeat: expr | |
repeat-expr: num_unknown18s | |
- type: align(16) | |
- id: num_unknown19 | |
type: u4 | |
- size: num_unknown19 * 28 | |
- id: unknown19 | |
type: f4 | |
repeat: expr | |
repeat-expr: num_unknown19 * 7 | |
- id: num_unknown20 | |
type: u4 | |
- size: num_unknown20 * 12 | |
- id: unknown20 | |
size: 12 | |
repeat: expr | |
repeat-expr: num_unknown20 | |
- type: align(16) | |
# TODO: find a chunk that uses this one and get it's length right | |
- id: num_unknown21 | |
type: u4 | |
- id: unknown21_pad | |
size: num_unknown21 * 8 | |
- id: unknown21 | |
type: u4 | |
repeat: expr | |
repeat-expr: num_unknown21 * 2 | |
- type: align(16) | |
- id: num_unknown22 | |
type: u4 | |
- id: unknown22 | |
type: u4 | |
repeat: expr | |
repeat-expr: num_unknown22 | |
- type: align(16) | |
# floats, some world coord | |
- id: unknown23 | |
type: f4 | |
repeat: expr | |
repeat-expr: num_unknown23 * 12 | |
- id: num_unknown24s | |
type: u4 | |
- contents: [0, 0, 0, 0] | |
- id: num_unknown25 | |
type: u4 | |
- contents: [0, 0, 0, 0] | |
- id: unknown24s | |
type: unknown24 | |
repeat: expr | |
repeat-expr: num_unknown24s | |
- id: unknown25 | |
size: 2 | |
repeat: expr | |
repeat-expr: num_unknown25 | |
- type: align(16) | |
- id: unknown26 | |
size: 2 | |
repeat: expr | |
repeat-expr: num_unknown26 | |
- type: align(16) | |
- id: mesh_movers | |
type: mesh_mover | |
repeat: expr | |
repeat-expr: num_mesh_movers | |
- id: unknown27 | |
size: 24 | |
repeat: expr | |
repeat-expr: num_unknown27 | |
- id: unknown28 | |
size: 36 | |
repeat: expr | |
repeat-expr: num_unknown28 | |
- id: unknown29 | |
size: 4 | |
repeat: expr | |
repeat-expr: num_unknown29 | |
- id: unknown30 | |
size: 12 | |
repeat: expr | |
repeat-expr: num_unknown30 | |
- id: unknown31 | |
size: 8 | |
repeat: expr | |
repeat-expr: num_unknown31 | |
# Floats: 0's and 1's | |
- id: unknown32 | |
size: 8 | |
repeat: expr | |
repeat-expr: num_unknown32 | |
- id: mesh_mover_names | |
type: mesh_mover_name( | |
mesh_movers[_index].start_count | |
) | |
repeat: expr | |
repeat-expr: num_mesh_movers | |
- type: align(16) | |
# This is a duct tape solution to ignore lights | |
# when they don't exist. 1212891981 == "MCKH" | |
- id: num_lights | |
type: num_lights | |
- id: lights_offset | |
type: offset(_io.pos) | |
- id: light_unknown | |
type: u4 | |
if: num_lights.result != 0 | |
- id: light_data | |
type: light_data | |
repeat: expr | |
repeat-expr: num_lights.result | |
- id: light_names | |
type: strz | |
repeat: expr | |
repeat-expr: num_lights.result | |
- type: align(16) | |
- id: light_unkfloats | |
type: light_unkfloats(light_data[_index].num_light_unkfloats) | |
repeat: expr | |
repeat-expr: num_lights.result | |
- type: align(16) | |
#- id: num_unknown33s | |
# type: u4 | |
#- size: 4 #contents: [0,0,0,0] | |
#- id: num_unknown33b | |
# type: u4 | |
#- size: 4 #contents: [0,0,0,0] | |
#- id: unknown33s | |
# type: unknown33 | |
# repeat: expr | |
# repeat-expr: num_unknown33s | |
#- id: unknown33b | |
# type: u2 | |
# repeat: expr | |
# repeat-expr: num_unknown33b | |
#- type: align(16) | |
#- size: 96 | |
# if: num_lights != 1212891981 # MCHK | |
# | |
#- id: num_unknown33 | |
# type: u4 | |
# if: num_lights != 1212891981 # MCHK | |
# | |
#- contents: [0,0,0,0] | |
# if: num_lights != 1212891981 # MCHK | |
# | |
#- id: unknown33 | |
# size: 200 | |
# repeat: expr | |
# repeat-expr: num_unknown33 | |
# if: num_lights != 1212891981 # MCHK | |
#- size: 88 | |
#- contents: [77, 67, 75, 72] # MCHK | |
#- id: mckh_unk0 | |
# type: u4 | |
#- id: len_mckh | |
# type: u4 | |
#- id: mckh | |
# size: len_mckh | |
#- size: 68 | |
#- id: mckhs | |
# type: mckh | |
# repeat: expr | |
# repeat-expr: 132 | |
#- id: test | |
# size: 1000 | |
types: | |
align: | |
params: | |
- id: size | |
type: u4 | |
seq: | |
- size: (size - _io.pos) % size | |
vec3: | |
seq: | |
- id: x | |
type: f4 | |
- id: y | |
type: f4 | |
- id: z | |
type: f4 | |
offset: | |
params: | |
- id: off | |
type: s8 | |
rendermodel_unk0: | |
seq: | |
- id: unk0 | |
type: u4 | |
- id: unk1 | |
type: u4 | |
- id: unk2 | |
type: u4 | |
- id: unk3 | |
type: u4 | |
- id: unk4 | |
type: u4 | |
- id: unk5 | |
type: u4 | |
cityobject_part: | |
seq: | |
- id: pos | |
type: vec3 | |
- id: basis_x | |
type: vec3 | |
- id: basis_y | |
type: vec3 | |
- id: basis_z | |
type: vec3 | |
- id: rest_of_the_transform | |
size: 36 | |
- id: unk0 | |
type: u4 | |
- id: rendermodel_id | |
type: u4 | |
- id: unk1 | |
type: u4 | |
unknown3: | |
seq: | |
- id: float0 | |
type: f4 | |
- id: float1 | |
type: f4 | |
- id: float2 | |
type: f4 | |
- id: float3 | |
type: f4 | |
- id: float4 | |
type: f4 | |
- id: float5 | |
type: f4 | |
- id: float6 | |
type: f4 | |
- id: float7 | |
type: f4 | |
- id: float8 | |
type: f4 | |
- id: float9 | |
type: f4 | |
- id: floata | |
type: f4 | |
- id: floatb | |
type: f4 | |
- id: floatc | |
type: f4 | |
- id: floatd | |
type: f4 | |
- id: floate | |
type: f4 | |
- id: floatf | |
type: f4 | |
- id: float10 | |
type: f4 | |
- id: float11 | |
type: f4 | |
- id: float12 | |
type: f4 | |
- id: float13 | |
type: f4 | |
- id: float14 | |
type: f4 | |
- id: float15 | |
type: f4 | |
- id: float16 | |
type: f4 | |
- id: float17 | |
type: f4 | |
- id: float18 | |
type: f4 | |
unknown4: | |
seq: | |
- id: float0 | |
type: f4 | |
- id: float1 | |
type: f4 | |
- id: float2 | |
type: f4 | |
- id: float3 | |
type: f4 | |
- id: float4 | |
type: f4 | |
- id: float5 | |
type: f4 | |
- id: float6 | |
type: f4 | |
- id: float7 | |
type: f4 | |
- id: float8 | |
type: f4 | |
- id: float9 | |
type: f4 | |
- id: floata | |
type: f4 | |
- id: floatb | |
type: f4 | |
- id: floatc | |
type: f4 | |
model_header: | |
doc: | | |
A model header will talk about one of these two of things: | |
- A physmodel (type 7) | |
Each physmodel has a separate buffer and therefore each has its own | |
model_header. The buffers are stored in this file right after vert | |
headers. | |
- Rendermodels (type 0) | |
All buffers used for rendermodels are under this header. There is | |
exactly one rendermodel header per chunk (or none?). | |
Contains multiple vert_headers: one for each rendermodel vert buffer. | |
Buffers are stored in g_chunk file. | |
This does not tell how to get individual rendermodels. See rendermodel | |
type for that. | |
TODO: organize vert_headers in here somehow and get rid of vert_header_cont. | |
params: | |
- id: i | |
type: s4 | |
seq: # 20B | |
- id: type # Either 7 or 0? 7 is physmodel, 0 rendermodel. | |
type: u2 | |
- id: vert_header_count # here | |
type: u2 | |
- id: num_indices | |
type: u4 | |
- contents: [-1, -1, -1, -1] | |
- contents: [-1, -1, -1, -1] | |
- contents: [0, 0, 0, 0] | |
vert_header_cont: | |
doc: | | |
TODO: See todo in model_header. | |
params: | |
- id: num_vert_header | |
type: u2 | |
seq: | |
- id: vert_header | |
type: vert_header | |
repeat: expr | |
repeat-expr: num_vert_header | |
vert_header: | |
doc: | | |
Describes a vertex buffer. | |
unk2b_count: | |
Probs vertex normals or something | |
Each adds 2B to vert_size. | |
uv_count: | |
How many uv sets are used. | |
Each UV set adds 4B to vert_size | |
vert_size: | |
Size is 12B + above. | |
Physmodels don't use the above so size is always 12B. | |
unk: | |
There's probably some meaning to this but it's | |
_always_ the same. 0xffffffff00000000 | |
seq: # 16B | |
- id: unk2b_count | |
type: u1 | |
- id: uv_count | |
type: u1 | |
- id: vert_size | |
type: u2 | |
- id: num_vertices | |
type: u4 | |
- contents: [-1, -1, -1, -1] | |
- contents: [0, 0, 0, 0] | |
phys_model_buffer: | |
params: | |
- id: is_physmodel | |
type: bool | |
- id: num_indices | |
type: u4 | |
- id: num_vertices | |
type: u4 | |
seq: | |
- id: vertices | |
type: vec3 | |
repeat: expr | |
repeat-expr: num_vertices | |
if: is_physmodel | |
- type: align(16) | |
- id: indices | |
type: u2 | |
repeat: expr | |
repeat-expr: num_indices | |
if: is_physmodel | |
- type: align(16) | |
material: | |
doc: | | |
TODO: Move mat_textures, mat_bitflags, etc. inside material. | |
seq: | |
- id: unk | |
size: 12 | |
- id: bitflag_count | |
type: u2 | |
- id: tex_count | |
type: u2 | |
- contents: [0, 0] | |
- id: unk1 | |
type: u2 | |
- id: unk2 | |
type: s4 | |
mat_bitflag: | |
params: | |
- id: size | |
type: u2 | |
seq: | |
- id: data | |
size: size * 6 | |
- size: (4 - size * 6) % 4 | |
mat_tex_cont: | |
seq: | |
- id: tex_data | |
type: mat_tex | |
repeat: expr | |
repeat-expr: 16 | |
mat_tex: | |
seq: | |
- id: tex_id | |
type: u2 | |
- id: tex_flag | |
type: u2 | |
mat_unknown3: | |
seq: | |
- id: unk | |
size: 8 | |
- id: unk2_count | |
type: u2 | |
- id: unk3 | |
type: u2 | |
- contents: [-1, -1, -1, -1] | |
rendermodel: | |
doc: | | |
Describes vertex/index offsets and counts in buffers. | |
Rendermodels are divided to submeshes per material. | |
Some models use what I named submesh2. This format is unknown | |
and in such cases the normal submeshes are garbage too. | |
To be confirmed: bbox is a bounding box with min and max vert coords. | |
Bbox usage is unknown. | |
seq: | |
- id: bbox_min | |
type: vec3 | |
- id: bbox_max | |
type: vec3 | |
- id: unk0 | |
type: u4 | |
- id: unk1 | |
type: u4 | |
- id: check_submeshes | |
type: u4 | |
- id: check_submesh2 | |
type: u4 | |
- type: align(16) | |
- id: submesh_unk0 | |
type: u2 | |
if: check_submeshes != 0 | |
- id: num_submeshes | |
type: u2 | |
if: check_submeshes != 0 | |
- id: submesh_unk1 | |
size: 4 | |
if: check_submeshes != 0 | |
- id: submesh_unk2 | |
type: u4 | |
if: check_submeshes != 0 | |
- id: submesh_pad1 | |
contents: [0, 0, 0, 0] | |
if: check_submeshes != 0 | |
- id: submesh2_unk0 | |
type: u2 | |
if: check_submesh2 != 0 | |
- id: num_submesh2s | |
type: u2 | |
if: check_submesh2 != 0 | |
- id: submesh2_unk1 | |
size: 4 | |
if: check_submesh2 != 0 | |
- id: submesh2_unk2 | |
type: u4 | |
if: check_submesh2 != 0 | |
- id: submesh2_pad1 | |
contents: [0, 0, 0, 0] | |
if: check_submesh2 != 0 | |
- id: submeshes | |
type: submesh | |
repeat: expr | |
repeat-expr: num_submeshes | |
- id: submesh2s | |
type: submesh2 | |
if: check_submesh2 != 0 | |
repeat: expr | |
repeat-expr: num_submesh2s | |
types: | |
submesh: | |
seq: | |
- id: vert_buffer_id | |
type: u4 | |
- id: off_indices | |
type: u4 | |
- id: off_vertices | |
type: u4 | |
- id: num_indices | |
type: u2 | |
- id: material_id | |
type: u2 | |
submesh2: | |
seq: | |
- id: unused | |
contents: [0, 0, 0, 0] | |
- id: unknown | |
size: 4 | |
- id: unused2 | |
contents: [0, 0, 0, 0] | |
- id: num_indices # is it? | |
type: u2 | |
- id: material_id | |
type: u2 | |
cityobject: | |
doc: | | |
bbox is used for culling. | |
seq: | |
- id: bbox_min | |
type: vec3 | |
- contents: [0, 0, 0, 0] | |
- id: bbox_max | |
type: vec3 | |
- id: cull_distance | |
type: f4 | |
- contents: [0, 0, 0, 0] | |
- id: unk0 | |
size: 4 | |
- contents: [0, 0, 0, 0] | |
- id: unk1 | |
type: s2 | |
- contents: [0, 0] | |
- id: flags | |
size: 4 | |
- id: unk3 | |
size: 4 | |
- id: unk8 # Almost always 0. Exceptions: sr2_skybox, sr2_intdkmissunkdk, sr2_intarcutlimo, sr2_intaicutjyucar | |
size: 4 | |
- id: unk4 | |
type: s4 | |
- id: cityobject_part_id | |
type: u4 | |
- id: unk5 | |
type: u4 | |
- id: unk6 | |
type: s4 | |
- id: unk7 | |
type: s4 | |
unknown18: | |
seq: | |
- id: unk0 | |
type: u4 | |
- id: num_data0 | |
type: u4 | |
- size: num_data0 * 12 | |
- id: data0 | |
type: u4 | |
repeat: expr | |
repeat-expr: num_data0 | |
- id: num_data1 | |
type: u4 | |
- size: num_data1 * 12 | |
- id: data1 | |
type: u4 | |
repeat: expr | |
repeat-expr: num_data1 | |
- id: num_data2 | |
type: u4 | |
- size: num_data2 * 12 | |
- id: data2 | |
type: u4 | |
repeat: expr | |
repeat-expr: num_data2 | |
# World coord box | |
unknown24: | |
seq: | |
- id: box_min | |
type: vec3 | |
- id: unk0 | |
type: u4 | |
- id: box_max | |
type: vec3 | |
- id: unk1 | |
type: u4 | |
- id: unk2 | |
type: u4 | |
- contents: [0, 0, 0, 0] | |
- id: unk4 | |
type: u4 | |
- id: unk5 | |
type: u4 | |
mesh_mover: | |
seq: | |
- id: unk0 | |
size: 14 | |
- id: start_count | |
type: u2 | |
- id: unk1 | |
size: 12 | |
mesh_mover_name: | |
params: | |
- id: start_count | |
type: u2 | |
seq: | |
- id: name | |
type: strz | |
- id: start_names | |
type: strz | |
repeat: expr | |
repeat-expr: start_count | |
num_lights: | |
seq: | |
- id: input | |
type: u4 | |
instances: | |
result: | |
value: "input != 1212891981 ? input : 0" | |
light_data: | |
seq: | |
- id: bitmask | |
type: b1 | |
repeat: expr | |
repeat-expr: 32 | |
- contents: [0, 0, 0, 0] | |
- id: r | |
type: f4 | |
- id: g | |
type: f4 | |
- id: b | |
type: f4 | |
- id: unk5 | |
type: u4 | |
doc: bitmask? | |
- id: unk6 | |
type: u4 | |
doc: bitmask? | |
- id: unk7 | |
type: u4 | |
doc: bitmask? | |
- id: num_light_unkfloats | |
type: u4 | |
- contents: [-1, -1, -1, -1] | |
- id: unk10 | |
type: u4 | |
doc: bitmask? | |
- contents: [-1, -1, -1, -1] | |
- id: unk12 | |
type: u4 | |
doc: bitmask? | |
- id: unkf13 | |
type: f4 | |
- id: unkf14 | |
type: f4 | |
- id: position | |
type: vec3 | |
- id: unkf18 | |
type: f4 | |
- id: unkf19 | |
type: f4 | |
- id: unkf20 | |
type: f4 | |
- id: unkf21 | |
type: f4 | |
- id: unkf22 | |
type: f4 | |
- id: unkf23 | |
type: f4 | |
- id: unkf24 | |
type: f4 | |
- id: unkf25 | |
type: f4 | |
- id: unkf26 | |
type: f4 | |
- id: unkf27 | |
type: f4 | |
- id: unkf28 | |
type: f4 | |
- id: radius_inner | |
type: f4 | |
- id: radius_outer | |
type: f4 | |
- id: render_dist | |
type: f4 | |
- contents: [-1, -1, -1, -1] | |
- id: parent_cityobject | |
type: s4 | |
- id: unk34 | |
type: u4 | |
doc: bitmask? | |
- id: unk35 | |
type: u4 | |
doc: often 0, otherwise <250 | |
- id: type # 0 == omni, 2 == circular spotlight | |
type: u4 | |
instances: | |
bitflag0: | |
value: bitmask[0x00] | |
bitflag1: | |
value: bitmask[0x01] | |
bitflag2: | |
value: bitmask[0x02] | |
bitflag3: | |
value: bitmask[0x03] | |
bitflag4: | |
value: bitmask[0x04] | |
bitflag8: | |
value: bitmask[0x09] | |
bitflag10: | |
value: bitmask[0x0a] | |
shadow_character: | |
value: bitmask[0x0c] | |
shadow_level: | |
value: bitmask[0x0d] | |
light_character: | |
value: bitmask[0x0e] | |
light_level: | |
value: bitmask[0x0f] | |
bitflag22: | |
value: bitmask[0x16] | |
light_unkfloats: | |
params: | |
- id: num | |
type: u4 | |
seq: | |
- id: unk | |
type: f4 | |
repeat: expr | |
repeat-expr: num | |
unknown33: | |
seq: | |
- id: box_min | |
type: vec3 | |
- size: 4 | |
- id: box_max | |
type: vec3 | |
- size: 4 | |
- id: unk | |
size: 16 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment