You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
644 lines
27 KiB
644 lines
27 KiB
# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄ |
|
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪ |
|
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄ |
|
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌ |
|
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪ |
|
# Magicbane Emulator Project © 2013 - 2022 |
|
# www.magicbane.com |
|
|
|
from collections import OrderedDict |
|
|
|
from arcane.util import ResStream |
|
|
|
TRACKER_TO_STRING = { |
|
0: 'NONE', |
|
1: 'XY', |
|
2: 'Y', |
|
} |
|
STRING_TO_TRACKER = {value: key for key, value in TRACKER_TO_STRING.items()} |
|
|
|
TRANSPARENT_TO_STRING = { |
|
0: 'NONE', |
|
1: 'PINK', |
|
2: 'BLACK', |
|
3: 'WHITE', |
|
4: 'SEMI', |
|
6: 'ALPHA', |
|
} |
|
STRING_TO_TRANSPARENT = {value: key for key, value in TRANSPARENT_TO_STRING.items()} |
|
|
|
TEXTURE_TO_STRING = { |
|
0: 'SINGLE_TEXTURE', |
|
1: 'COLOR_TEXTURE', |
|
3: 'ANIMATED_TEXTURE', |
|
} |
|
STRING_TO_TEXTURE = {value: key for key, value in TEXTURE_TO_STRING.items()} |
|
|
|
LIGHT_TYPE_TO_STRING = { |
|
0xb6787258: 'ArcLightPoint', |
|
0x54e8ff1d: 'ArcLightAffectorAttach', |
|
0xa73bd9d4: 'ArcLightAffectorFlicker', |
|
} |
|
STRING_TO_LIGHT_TYPE = {value: key for key, value in LIGHT_TYPE_TO_STRING.items()} |
|
|
|
|
|
class ArcSinglePolyMesh: |
|
def load_binary(self, stream: ResStream): |
|
self.polymesh_id = stream.read_qword() |
|
self.polymesh_decal = stream.read_bool() |
|
self.polymesh_double_sided = stream.read_bool() |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_qword(self.polymesh_id) |
|
stream.write_bool(self.polymesh_decal) |
|
stream.write_bool(self.polymesh_double_sided) |
|
|
|
def load_json(self, data): |
|
self.polymesh_id = data['polymesh_id'] |
|
self.polymesh_decal = data['polymesh_decal'] |
|
self.polymesh_double_sided = data['polymesh_double_sided'] |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['polymesh_id'] = self.polymesh_id |
|
data['polymesh_decal'] = self.polymesh_decal |
|
data['polymesh_double_sided'] = self.polymesh_double_sided |
|
return data |
|
|
|
|
|
class ArcMeshSet: |
|
def load_binary(self, stream: ResStream): |
|
num = stream.read_dword() |
|
self.mesh_set = [ArcSinglePolyMesh() for _ in range(num)] |
|
for mesh in self.mesh_set: |
|
mesh.load_binary(stream) |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_dword(len(self.mesh_set)) |
|
for mesh in self.mesh_set: |
|
mesh.save_binary(stream) |
|
|
|
def load_json(self, data): |
|
self.mesh_set = [] |
|
for mesh_data in data['mesh_set']: |
|
mesh = ArcSinglePolyMesh() |
|
mesh.load_json(mesh_data) |
|
self.mesh_set.append(mesh) |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['mesh_set'] = [] |
|
for mesh in self.mesh_set: |
|
data['mesh_set'].append(mesh.save_json()) |
|
return data |
|
|
|
|
|
class ArcRenderTemplate: |
|
def load_binary(self, stream: ResStream): |
|
self.template_object_can_fade = stream.read_bool() |
|
self.template_tracker = stream.read_dword() |
|
self.template_illuminated = stream.read_bool() |
|
self.template_bone_length = stream.read_float() |
|
self.template_clip_map = stream.read_dword() |
|
self.template_light_two_side = stream.read_dword() |
|
self.template_cull_face = stream.read_dword() |
|
self.template_specular_map = stream.read_qword() |
|
self.template_shininess = stream.read_float() |
|
self.template_has_mesh = stream.read_bool() |
|
if self.template_has_mesh: |
|
self.template_mesh = ArcMeshSet() |
|
self.template_mesh.load_binary(stream) |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_bool(self.template_object_can_fade) |
|
stream.write_dword(self.template_tracker) |
|
stream.write_bool(self.template_illuminated) |
|
stream.write_float(self.template_bone_length) |
|
stream.write_dword(self.template_clip_map) |
|
stream.write_dword(self.template_light_two_side) |
|
stream.write_dword(self.template_cull_face) |
|
stream.write_qword(self.template_specular_map) |
|
stream.write_float(self.template_shininess) |
|
stream.write_bool(self.template_has_mesh) |
|
if self.template_has_mesh: |
|
self.template_mesh.save_binary(stream) |
|
|
|
def load_json(self, data): |
|
self.template_object_can_fade = data['template_object_can_fade'] |
|
self.template_tracker = STRING_TO_TRACKER[data['template_tracker']] |
|
self.template_illuminated = data['template_illuminated'] |
|
self.template_bone_length = data['template_bone_length'] |
|
self.template_clip_map = data['template_clip_map'] |
|
self.template_light_two_side = data['template_light_two_side'] |
|
self.template_cull_face = data['template_cull_face'] |
|
self.template_specular_map = data['template_specular_map'] |
|
self.template_shininess = data['template_shininess'] |
|
self.template_has_mesh = data['template_has_mesh'] |
|
if self.template_has_mesh: |
|
self.template_mesh = ArcMeshSet() |
|
self.template_mesh.load_json(data['template_mesh']) |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['template_object_can_fade'] = self.template_object_can_fade |
|
data['template_tracker'] = TRACKER_TO_STRING[self.template_tracker] |
|
data['template_illuminated'] = self.template_illuminated |
|
data['template_bone_length'] = self.template_bone_length |
|
data['template_clip_map'] = self.template_clip_map |
|
data['template_light_two_side'] = self.template_light_two_side |
|
data['template_cull_face'] = self.template_cull_face |
|
data['template_specular_map'] = self.template_specular_map |
|
data['template_shininess'] = self.template_shininess |
|
data['template_has_mesh'] = self.template_has_mesh |
|
if self.template_has_mesh: |
|
data['template_mesh'] = self.template_mesh.save_json() |
|
return data |
|
|
|
|
|
class ArcSingleTexture: |
|
def load_binary(self, stream: ResStream): |
|
self.texture_id = stream.read_qword() |
|
self.texture_transparent = stream.read_dword() |
|
self.texture_compress = stream.read_bool() |
|
self.texture_normal_map = stream.read_bool() |
|
self.texture_detail_normal_map = stream.read_bool() |
|
self.texture_create_mip_maps = stream.read_bool() |
|
self.texture_x0 = stream.read_string() |
|
self.texture_x1 = stream.read_string() |
|
self.texture_x2 = stream.read_dword() |
|
self.texture_x3 = stream.read_dword() |
|
self.texture_x4 = stream.read_bool() |
|
self.texture_wrap = stream.read_bool() |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_qword(self.texture_id) |
|
stream.write_dword(self.texture_transparent) |
|
stream.write_bool(self.texture_compress) |
|
stream.write_bool(self.texture_normal_map) |
|
stream.write_bool(self.texture_detail_normal_map) |
|
stream.write_bool(self.texture_create_mip_maps) |
|
stream.write_string(self.texture_x0) |
|
stream.write_string(self.texture_x1) |
|
stream.write_dword(self.texture_x2) |
|
stream.write_dword(self.texture_x3) |
|
stream.write_bool(self.texture_x4) |
|
stream.write_bool(self.texture_wrap) |
|
|
|
def load_json(self, data): |
|
self.texture_id = data['texture_id'] |
|
self.texture_transparent = STRING_TO_TRANSPARENT[data['texture_transparent']] |
|
self.texture_compress = data['texture_compress'] |
|
self.texture_normal_map = data['texture_normal_map'] |
|
self.texture_detail_normal_map = data['texture_detail_normal_map'] |
|
self.texture_create_mip_maps = data['texture_create_mip_maps'] |
|
self.texture_x0 = '' |
|
self.texture_x1 = '' |
|
self.texture_x2 = 255 |
|
self.texture_x3 = 0 |
|
self.texture_x4 = False |
|
self.texture_wrap = data['texture_wrap'] |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['texture_id'] = self.texture_id |
|
data['texture_transparent'] = TRANSPARENT_TO_STRING[self.texture_transparent] |
|
data['texture_compress'] = self.texture_compress |
|
data['texture_normal_map'] = self.texture_normal_map |
|
data['texture_detail_normal_map'] = self.texture_detail_normal_map |
|
data['texture_create_mip_maps'] = self.texture_create_mip_maps |
|
data['texture_wrap'] = self.texture_wrap |
|
return data |
|
|
|
|
|
class ArcColorTexture(ArcSingleTexture): |
|
pass |
|
|
|
|
|
class ArcAnimatedTexture: |
|
def load_binary(self, stream: ResStream): |
|
self.animated_texture_id = stream.read_qword() |
|
self.animated_texture_transparent = stream.read_dword() |
|
self.animated_texture_compress = stream.read_bool() |
|
self.animated_texture_normal_map = stream.read_bool() |
|
self.animated_texture_detail_normal_map = stream.read_bool() |
|
self.animated_texture_create_mip_maps = stream.read_bool() |
|
self.animated_texture_frame_timer = stream.read_float() |
|
self.animated_texture_x0 = stream.read_float() |
|
self.animated_texture_frame_rand = stream.read_dword() |
|
|
|
num = stream.read_dword() |
|
self.animated_texture_sets = [ArcTextureSet() for _ in range(num)] |
|
for texture in self.animated_texture_sets: |
|
texture.load_binary(stream) |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_qword(self.animated_texture_id) |
|
stream.write_dword(self.animated_texture_transparent) |
|
stream.write_bool(self.animated_texture_compress) |
|
stream.write_bool(self.animated_texture_normal_map) |
|
stream.write_bool(self.animated_texture_detail_normal_map) |
|
stream.write_bool(self.animated_texture_create_mip_maps) |
|
stream.write_float(self.animated_texture_frame_timer) |
|
stream.write_float(self.animated_texture_x0) |
|
stream.write_dword(self.animated_texture_frame_rand) |
|
|
|
stream.write_dword(len(self.animated_texture_sets)) |
|
for texture in self.animated_texture_sets: |
|
texture.save_binary(stream) |
|
|
|
def load_json(self, data): |
|
self.animated_texture_id = data['animated_texture_id'] |
|
self.animated_texture_transparent = STRING_TO_TRANSPARENT[data['animated_texture_transparent']] |
|
self.animated_texture_compress = data['animated_texture_compress'] |
|
self.animated_texture_normal_map = data['animated_texture_normal_map'] |
|
self.animated_texture_detail_normal_map = data['animated_texture_detail_normal_map'] |
|
self.animated_texture_create_mip_maps = data['animated_texture_create_mip_maps'] |
|
self.animated_texture_frame_timer = data['animated_texture_frame_timer'] |
|
self.animated_texture_x0 = 0.0 |
|
self.animated_texture_frame_rand = data['animated_texture_frame_rand'] |
|
self.animated_texture_sets = [] |
|
for texture_data in data['animated_texture_sets']: |
|
texture = ArcTextureSet() |
|
texture.load_json(texture_data) |
|
self.animated_texture_sets.append(texture) |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['animated_texture_id'] = self.animated_texture_id |
|
data['animated_texture_transparent'] = TRANSPARENT_TO_STRING[self.animated_texture_transparent] |
|
data['animated_texture_compress'] = self.animated_texture_compress |
|
data['animated_texture_normal_map'] = self.animated_texture_normal_map |
|
data['animated_texture_detail_normal_map'] = self.animated_texture_detail_normal_map |
|
data['animated_texture_create_mip_maps'] = self.animated_texture_create_mip_maps |
|
data['animated_texture_frame_timer'] = self.animated_texture_frame_timer |
|
data['animated_texture_frame_rand'] = self.animated_texture_frame_rand |
|
data['animated_texture_sets'] = [] |
|
for texture in self.animated_texture_sets: |
|
data['animated_texture_sets'].append(texture.save_json()) |
|
return data |
|
|
|
|
|
class ArcTextureSet: |
|
def load_binary(self, stream: ResStream): |
|
self.texture_type = stream.read_dword() |
|
if self.texture_type == 0: |
|
self.texture_data = ArcSingleTexture() |
|
elif self.texture_type == 1: |
|
self.texture_data = ArcColorTexture() |
|
elif self.texture_type == 3: |
|
self.texture_data = ArcAnimatedTexture() |
|
self.texture_data.load_binary(stream) |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_dword(self.texture_type) |
|
self.texture_data.save_binary(stream) |
|
|
|
def load_json(self, data): |
|
self.texture_type = STRING_TO_TEXTURE[data['texture_type']] |
|
if self.texture_type == 0: |
|
self.texture_data = ArcSingleTexture() |
|
elif self.texture_type == 1: |
|
self.texture_data = ArcColorTexture() |
|
elif self.texture_type == 3: |
|
self.texture_data = ArcAnimatedTexture() |
|
self.texture_data.load_json(data['texture_data']) |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['texture_type'] = TEXTURE_TO_STRING[self.texture_type] |
|
data['texture_data'] = self.texture_data.save_json() |
|
return data |
|
|
|
|
|
class ArcLightPoint: |
|
def load_binary(self, stream: ResStream): |
|
self.lightpoint_x0 = stream.read_dword() |
|
self.lightpoint_x1 = stream.read_bool() |
|
self.lightpoint_shader = stream.read_bool() |
|
self.lightpoint_update_offscreen = stream.read_bool() |
|
self.lightpoint_radius = stream.read_float() |
|
self.lightpoint_position = stream.read_tuple() |
|
self.lightpoint_diffuse_color = [stream.read_float() for _ in range(4)] |
|
self.lightpoint_x2 = stream.read_dword() |
|
self.lightpoint_orientation = [stream.read_float() for _ in range(4)] |
|
self.lightpoint_cubemap = stream.read_dword() |
|
self.lightpoint_x3 = stream.read_bool() |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_dword(self.lightpoint_x0) |
|
stream.write_bool(self.lightpoint_x1) |
|
stream.write_bool(self.lightpoint_shader) |
|
stream.write_bool(self.lightpoint_update_offscreen) |
|
stream.write_float(self.lightpoint_radius) |
|
stream.write_tuple(self.lightpoint_position) |
|
for i in range(4): |
|
stream.write_float(self.lightpoint_diffuse_color[i]) |
|
stream.write_dword(self.lightpoint_x2) |
|
for i in range(4): |
|
stream.write_float(self.lightpoint_orientation[i]) |
|
stream.write_dword(self.lightpoint_cubemap) |
|
stream.write_bool(self.lightpoint_x3) |
|
|
|
def load_json(self, data): |
|
self.lightpoint_x0 = 1 |
|
self.lightpoint_x1 = True |
|
self.lightpoint_shader = data['lightpoint_shader'] |
|
self.lightpoint_update_offscreen = data['lightpoint_update_offscreen'] |
|
self.lightpoint_radius = data['lightpoint_radius'] |
|
self.lightpoint_position = data['lightpoint_position'] |
|
self.lightpoint_diffuse_color = data['lightpoint_diffuse_color'] |
|
self.lightpoint_x2 = 1 |
|
self.lightpoint_orientation = data['lightpoint_orientation'] |
|
self.lightpoint_cubemap = data['lightpoint_cubemap'] |
|
self.lightpoint_x3 = False |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['lightpoint_shader'] = self.lightpoint_shader |
|
data['lightpoint_update_offscreen'] = self.lightpoint_update_offscreen |
|
data['lightpoint_radius'] = self.lightpoint_radius |
|
data['lightpoint_position'] = self.lightpoint_position |
|
data['lightpoint_diffuse_color'] = self.lightpoint_diffuse_color |
|
data['lightpoint_orientation'] = self.lightpoint_orientation |
|
data['lightpoint_cubemap'] = self.lightpoint_cubemap |
|
return data |
|
|
|
|
|
class ArcLightAffectorAttach: |
|
def load_binary(self, stream: ResStream): |
|
self.attach_x0 = stream.read_dword() |
|
self.attach_offset = stream.read_tuple() |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_dword(self.attach_x0) |
|
stream.write_tuple(self.attach_offset) |
|
|
|
def load_json(self, data): |
|
self.attach_x0 = 1 |
|
self.attach_offset = data['attach_offset'] |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['attach_offset'] = self.attach_offset |
|
return data |
|
|
|
|
|
class ArcLightAffectorFlicker: |
|
def load_binary(self, stream: ResStream): |
|
self.flicker_x0 = stream.read_dword() |
|
self.flicker_avg_period = stream.read_float() |
|
self.flicker_std_dev_radius = stream.read_float() |
|
self.flicker_std_dev_period = stream.read_float() |
|
self.flicker_falloff = stream.read_float() |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_dword(self.flicker_x0) |
|
stream.write_float(self.flicker_avg_period) |
|
stream.write_float(self.flicker_std_dev_radius) |
|
stream.write_float(self.flicker_std_dev_period) |
|
stream.write_float(self.flicker_falloff) |
|
|
|
def load_json(self, data): |
|
self.flicker_x0 = 1 |
|
self.flicker_avg_period = data['flicker_avg_period'] |
|
self.flicker_std_dev_radius = data['flicker_std_dev_radius'] |
|
self.flicker_std_dev_period = data['flicker_std_dev_period'] |
|
self.flicker_falloff = data['flicker_falloff'] |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['flicker_avg_period'] = self.flicker_avg_period |
|
data['flicker_std_dev_radius'] = self.flicker_std_dev_radius |
|
data['flicker_std_dev_period'] = self.flicker_std_dev_period |
|
data['flicker_falloff'] = self.flicker_falloff |
|
return data |
|
|
|
|
|
class ArcLightAffectors: |
|
def load_binary(self, stream: ResStream): |
|
self.light_affector_type = stream.read_dword() |
|
|
|
if self.light_affector_type == 0x54e8ff1d: |
|
self.light_affector_data = ArcLightAffectorAttach() |
|
elif self.light_affector_type == 0xa73bd9d4: |
|
self.light_affector_data = ArcLightAffectorFlicker() |
|
self.light_affector_data.load_binary(stream) |
|
|
|
self.light_affector_0xdaed = stream.read_dword() |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_dword(self.light_affector_type) |
|
self.light_affector_data.save_binary(stream) |
|
stream.write_dword(self.light_affector_0xdaed) |
|
|
|
def load_json(self, data): |
|
self.light_affector_type = STRING_TO_LIGHT_TYPE[data['light_affector_type']] |
|
if self.light_affector_type == 0x54e8ff1d: |
|
self.light_affector_data = ArcLightAffectorAttach() |
|
elif self.light_affector_type == 0xa73bd9d4: |
|
self.light_affector_data = ArcLightAffectorFlicker() |
|
self.light_affector_data.load_json(data['light_affector_data']) |
|
self.light_affector_0xdaed = 0xddaaeedd |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['light_affector_type'] = LIGHT_TYPE_TO_STRING[self.light_affector_type] |
|
data['light_affector_data'] = self.light_affector_data.save_json() |
|
return data |
|
|
|
|
|
class ArcLight: |
|
def load_binary(self, stream: ResStream): |
|
self.light_x0 = stream.read_dword() |
|
self.light_x1 = stream.read_bool() |
|
self.light_type = stream.read_dword() |
|
|
|
if self.light_type == 0xb6787258: |
|
self.light_data = ArcLightPoint() |
|
self.light_data.load_binary(stream) |
|
|
|
self.light_0xdaed = stream.read_dword() |
|
|
|
num = stream.read_dword() |
|
self.light_affectors = [ArcLightAffectors() for _ in range(num)] |
|
for extra in self.light_affectors: |
|
extra.load_binary(stream) |
|
|
|
def save_binary(self, stream: ResStream): |
|
stream.write_dword(self.light_x0) |
|
stream.write_bool(self.light_x1) |
|
stream.write_dword(self.light_type) |
|
self.light_data.save_binary(stream) |
|
stream.write_dword(self.light_0xdaed) |
|
|
|
stream.write_dword(len(self.light_affectors)) |
|
for extra in self.light_affectors: |
|
extra.save_binary(stream) |
|
|
|
def load_json(self, data): |
|
self.light_x0 = 1 |
|
self.light_x1 = True |
|
self.light_type = STRING_TO_LIGHT_TYPE[data['light_type']] |
|
if self.light_type == 0xb6787258: |
|
self.light_data = ArcLightPoint() |
|
self.light_data.load_json(data['light_data']) |
|
self.light_0xdaed = 0xddaaeedd |
|
|
|
self.light_affectors = [] |
|
for extra_data in data['light_affectors']: |
|
extra = ArcLightAffectors() |
|
extra.load_json(extra_data) |
|
self.light_affectors.append(extra) |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['light_type'] = LIGHT_TYPE_TO_STRING[self.light_type] |
|
data['light_data'] = self.light_data.save_json() |
|
|
|
data['light_affectors'] = [] |
|
for extra in self.light_affectors: |
|
data['light_affectors'].append(extra.save_json()) |
|
return data |
|
|
|
|
|
class ArcRender: |
|
def load_binary(self, stream: ResStream): |
|
self.render_template = ArcRenderTemplate() |
|
self.render_template.load_binary(stream) |
|
self.render_target_bone = stream.read_string() |
|
self.render_scale = stream.read_tuple() |
|
self.render_has_loc = stream.read_dword() |
|
if self.render_has_loc: |
|
self.render_loc = stream.read_tuple() |
|
num_children = stream.read_dword() |
|
self.render_children = [stream.read_qword() for _ in range(num_children)] |
|
self.render_has_texture_set = stream.read_bool() |
|
if self.render_has_texture_set: |
|
num = stream.read_dword() |
|
self.render_texture_set = [ArcTextureSet() for _ in range(num)] |
|
for texture in self.render_texture_set: |
|
texture.load_binary(stream) |
|
self.render_collides = stream.read_bool() |
|
self.render_calculate_bounding_box = stream.read_bool() |
|
self.render_nation_crest = stream.read_bool() |
|
self.render_guild_crest = stream.read_bool() |
|
self.render_bumped = stream.read_bool() |
|
self.render_vp_active = stream.read_bool() |
|
if self.render_vp_active: |
|
self.render_vp_name = stream.read_string() |
|
num_params = stream.read_dword() |
|
self.render_vp_params = [ |
|
[ |
|
stream.read_dword(), |
|
stream.read_float(), |
|
stream.read_float(), |
|
stream.read_float(), |
|
stream.read_float(), |
|
] for _ in range(num_params) |
|
] |
|
self.render_has_light_effects = stream.read_bool() |
|
if self.render_has_light_effects: |
|
num_effects = stream.read_dword() |
|
self.render_light_effects = [ArcLight() for _ in range(num_effects)] |
|
for effect in self.render_light_effects: |
|
effect.load_binary(stream) |
|
|
|
def save_binary(self, stream: ResStream): |
|
self.render_template.save_binary(stream) |
|
stream.write_string(self.render_target_bone) |
|
stream.write_tuple(self.render_scale) |
|
stream.write_dword(self.render_has_loc) |
|
if self.render_has_loc: |
|
stream.write_tuple(self.render_loc) |
|
stream.write_dword(len(self.render_children)) |
|
for child in self.render_children: |
|
stream.write_qword(child) |
|
stream.write_bool(self.render_has_texture_set) |
|
if self.render_has_texture_set: |
|
stream.write_dword(len(self.render_texture_set)) |
|
for texture in self.render_texture_set: |
|
texture.save_binary(stream) |
|
stream.write_bool(self.render_collides) |
|
stream.write_bool(self.render_calculate_bounding_box) |
|
stream.write_bool(self.render_nation_crest) |
|
stream.write_bool(self.render_guild_crest) |
|
stream.write_bool(self.render_bumped) |
|
stream.write_bool(self.render_vp_active) |
|
if self.render_vp_active: |
|
stream.write_string(self.render_vp_name) |
|
|
|
stream.write_dword(len(self.render_vp_params)) |
|
for param in self.render_vp_params: |
|
stream.write_dword(param[0]) |
|
stream.write_float(param[1]) |
|
stream.write_float(param[2]) |
|
stream.write_float(param[3]) |
|
stream.write_float(param[4]) |
|
stream.write_bool(self.render_has_light_effects) |
|
if self.render_has_light_effects: |
|
stream.write_dword(len(self.render_light_effects)) |
|
for effect in self.render_light_effects: |
|
effect.save_binary(stream) |
|
|
|
def load_json(self, data): |
|
self.render_template = ArcRenderTemplate() |
|
self.render_template.load_json(data['render_template']) |
|
self.render_target_bone = data['render_target_bone'] |
|
self.render_scale = data['render_scale'] |
|
self.render_has_loc = data['render_has_loc'] |
|
if self.render_has_loc: |
|
self.render_loc = data['render_loc'] |
|
self.render_children = data['render_children'] |
|
self.render_has_texture_set = data['render_has_texture_set'] |
|
if self.render_has_texture_set: |
|
self.render_texture_set = [] |
|
for texture_data in data['render_texture_set']: |
|
texture = ArcTextureSet() |
|
texture.load_json(texture_data) |
|
self.render_texture_set.append(texture) |
|
self.render_collides = data['render_collides'] |
|
self.render_calculate_bounding_box = data['render_calculate_bounding_box'] |
|
self.render_nation_crest = data['render_nation_crest'] |
|
self.render_guild_crest = data['render_guild_crest'] |
|
self.render_bumped = data['render_bumped'] |
|
self.render_vp_active = data['render_vp_active'] |
|
if self.render_vp_active: |
|
self.render_vp_name = data['render_vp_name'] |
|
self.render_vp_params = data['render_vp_params'] |
|
self.render_has_light_effects = data['render_has_light_effects'] |
|
if self.render_has_light_effects: |
|
self.render_light_effects = [] |
|
for effect_data in data['render_light_effects']: |
|
effect = ArcLight() |
|
effect.load_json(effect_data) |
|
self.render_light_effects.append(effect) |
|
|
|
def save_json(self): |
|
data = OrderedDict() |
|
data['render_template'] = self.render_template.save_json() |
|
data['render_target_bone'] = self.render_target_bone |
|
data['render_scale'] = self.render_scale |
|
data['render_has_loc'] = self.render_has_loc |
|
if self.render_has_loc: |
|
data['render_loc'] = self.render_loc |
|
data['render_children'] = self.render_children |
|
data['render_has_texture_set'] = self.render_has_texture_set |
|
if self.render_has_texture_set: |
|
data['render_texture_set'] = [] |
|
for texture in self.render_texture_set: |
|
data['render_texture_set'].append(texture.save_json()) |
|
data['render_collides'] = self.render_collides |
|
data['render_calculate_bounding_box'] = self.render_calculate_bounding_box |
|
data['render_nation_crest'] = self.render_nation_crest |
|
data['render_guild_crest'] = self.render_guild_crest |
|
data['render_bumped'] = self.render_bumped |
|
data['render_vp_active'] = self.render_vp_active |
|
if self.render_vp_active: |
|
data['render_vp_name'] = self.render_vp_name |
|
data['render_vp_params'] = self.render_vp_params |
|
data['render_has_light_effects'] = self.render_has_light_effects |
|
if self.render_has_light_effects: |
|
data['render_light_effects'] = [] |
|
for effect in self.render_light_effects: |
|
data['render_light_effects'].append(effect.save_json()) |
|
return data
|
|
|