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.
470 lines
21 KiB
470 lines
21 KiB
2 years ago
|
# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
|
||
|
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
|
||
|
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
|
||
|
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
|
||
|
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
|
||
|
# Magicbane Emulator Project © 2013 - 2022
|
||
|
# www.magicbane.com
|
||
2 years ago
|
|
||
|
from collections import OrderedDict
|
||
|
|
||
|
from arcane.enums.arc_rune import *
|
||
|
from arcane.enums.hashes import hash_to_string, string_to_hash
|
||
|
from arcane.util import ResStream
|
||
|
from .ArcItem import ArcItem
|
||
|
from .common.Arcane import AttributeValue, SkillGrant
|
||
|
from .common.Inventory import Inventory
|
||
|
from .common.SparseData import SparseData
|
||
|
|
||
|
|
||
|
class Group:
|
||
|
def load_binary(self, stream: ResStream):
|
||
|
self.group_type = stream.read_dword()
|
||
|
self.group_is_faction = stream.read_bool()
|
||
|
self.group_is_guild = stream.read_bool()
|
||
|
|
||
|
def save_binary(self, stream: ResStream):
|
||
|
stream.write_dword(self.group_type)
|
||
|
stream.write_bool(self.group_is_faction)
|
||
|
stream.write_bool(self.group_is_guild)
|
||
|
|
||
|
def load_json(self, data):
|
||
|
self.group_type = data['group_type']
|
||
|
self.group_is_faction = data['group_is_faction']
|
||
|
self.group_is_guild = data['group_is_guild']
|
||
|
|
||
|
def save_json(self):
|
||
|
data = OrderedDict()
|
||
|
data['group_type'] = self.group_type
|
||
|
data['group_is_faction'] = self.group_is_faction
|
||
|
data['group_is_guild'] = self.group_is_guild
|
||
|
return data
|
||
|
|
||
|
|
||
|
class SkillAdjust:
|
||
|
def load_binary(self, stream: ResStream):
|
||
|
self.skill_type = stream.read_dword()
|
||
|
|
||
|
num_adjusts = stream.read_dword()
|
||
|
self.skill_adjusts = [
|
||
|
[
|
||
|
stream.read_dword(),
|
||
|
stream.read_dword(),
|
||
|
] for _ in range(num_adjusts)
|
||
|
]
|
||
|
|
||
|
def save_binary(self, stream: ResStream):
|
||
|
stream.write_dword(self.skill_type)
|
||
|
stream.write_dword(len(self.skill_adjusts))
|
||
|
for skill in self.skill_adjusts:
|
||
|
stream.write_dword(skill[0])
|
||
|
stream.write_dword(skill[1])
|
||
|
|
||
|
def load_json(self, data):
|
||
|
self.skill_type = string_to_hash(data['skill_type'])
|
||
|
self.skill_adjusts = []
|
||
|
for skill in data['skill_adjusts']:
|
||
|
self.skill_adjusts.append(skill)
|
||
|
|
||
|
def save_json(self):
|
||
|
data = OrderedDict()
|
||
|
data['skill_type'] = hash_to_string(self.skill_type)
|
||
|
data['skill_adjusts'] = []
|
||
|
for skill in self.skill_adjusts:
|
||
|
data['skill_adjusts'].append(skill)
|
||
|
return data
|
||
|
|
||
|
|
||
|
class BodyPart:
|
||
|
def load_binary(self, stream: ResStream):
|
||
|
self.body_part_render = stream.read_qword()
|
||
|
self.body_part_position = stream.read_tuple()
|
||
|
|
||
|
def save_binary(self, stream: ResStream):
|
||
|
stream.write_qword(self.body_part_render)
|
||
|
stream.write_tuple(self.body_part_position)
|
||
|
|
||
|
def load_json(self, data):
|
||
|
self.body_part_render = data['body_part_render']
|
||
|
self.body_part_position = data['body_part_position']
|
||
|
|
||
|
def save_json(self):
|
||
|
data = OrderedDict()
|
||
|
data['body_part_render'] = self.body_part_render
|
||
|
data['body_part_position'] = self.body_part_position
|
||
|
return data
|
||
|
|
||
|
|
||
|
class ArcRune(ArcItem):
|
||
|
def load_binary(self, stream: ResStream):
|
||
|
super().load_binary(stream)
|
||
|
self.rune_type = stream.read_dword()
|
||
|
self.rune_sub_type = stream.read_dword()
|
||
|
self.rune_is_standard_character_creation = stream.read_bool()
|
||
|
self.rune_creation_cost = stream.read_dword()
|
||
|
self.rune_rank = stream.read_dword()
|
||
|
self.rune_pracs_per_level = stream.read_dword()
|
||
|
self.rune_exp_req_to_level = stream.read_float()
|
||
|
self.rune_sex = stream.read_dword()
|
||
|
self.rune_class_icon = stream.read_qword()
|
||
|
self.rune_health = stream.read_dword()
|
||
|
self.rune_mana = stream.read_dword()
|
||
|
self.rune_stamina = stream.read_dword()
|
||
|
self.rune_min_damage = stream.read_float()
|
||
|
self.rune_max_damage = stream.read_float()
|
||
|
self.rune_attack = stream.read_dword()
|
||
|
self.rune_defense = stream.read_dword()
|
||
|
self.rune_level = stream.read_dword()
|
||
|
self.rune_speed = [
|
||
|
stream.read_float() for _ in range(7)
|
||
|
]
|
||
|
self.rune_group = Group()
|
||
|
self.rune_group.load_binary(stream)
|
||
|
self.rune_dsc = stream.read_string()
|
||
|
self.rune_fx_txt = stream.read_string()
|
||
|
self.rune_group_tactics = stream.read_dword()
|
||
|
self.rune_group_role_set = stream.read_dword()
|
||
|
num_enemies = stream.read_dword()
|
||
|
self.rune_enemy_monster_types = [
|
||
|
stream.read_dword() for _ in range(num_enemies)
|
||
|
]
|
||
|
num_groupees = stream.read_dword()
|
||
|
self.rune_groupee_monster_types = [
|
||
|
stream.read_dword() for _ in range(num_groupees)
|
||
|
]
|
||
|
num_helpers = stream.read_dword()
|
||
|
self.rune_helper_monster_types = [
|
||
|
stream.read_dword() for _ in range(num_helpers)
|
||
|
]
|
||
|
num_not_enemies = stream.read_dword()
|
||
|
self.rune_not_enemy_monster_types = [
|
||
|
stream.read_dword() for _ in range(num_not_enemies)
|
||
|
]
|
||
|
num_genders = stream.read_dword()
|
||
|
self.rune_enemy_gender = [
|
||
|
stream.read_dword() for _ in range(num_genders)
|
||
|
]
|
||
|
num_skill_grants = stream.read_dword()
|
||
|
self.rune_skill_grant = [SkillGrant() for _ in range(num_skill_grants)]
|
||
|
for grant in self.rune_skill_grant:
|
||
|
grant.load_binary(stream)
|
||
|
num_skill_adjusts = stream.read_dword()
|
||
|
self.rune_skill_adj = [SkillAdjust() for _ in range(num_skill_adjusts)]
|
||
|
for adjust in self.rune_skill_adj:
|
||
|
adjust.load_binary(stream)
|
||
|
num_attr_adjusts = stream.read_dword()
|
||
|
self.rune_attr_adj = [AttributeValue() for _ in range(num_attr_adjusts)]
|
||
|
for attr in self.rune_attr_adj:
|
||
|
attr.load_binary(stream)
|
||
|
num_max_attr_adjusts = stream.read_dword()
|
||
|
self.rune_max_attr_adj = [AttributeValue() for _ in range(num_max_attr_adjusts)]
|
||
|
for attr in self.rune_max_attr_adj:
|
||
|
attr.load_binary(stream)
|
||
|
num_natural_attacks = stream.read_dword()
|
||
|
self.rune_naturalattacks = [
|
||
|
[
|
||
|
stream.read_float(),
|
||
|
stream.read_float(),
|
||
|
stream.read_dword(),
|
||
|
stream.read_dword(),
|
||
|
stream.read_qword(),
|
||
|
stream.read_float(),
|
||
|
stream.read_dword(),
|
||
|
stream.read_dword(),
|
||
|
stream.read_dword(),
|
||
|
stream.read_dword(),
|
||
|
] for _ in range(num_natural_attacks)
|
||
|
]
|
||
|
num_enchants = stream.read_dword()
|
||
|
self.rune_enchantment_type = [
|
||
|
stream.read_dword() for _ in range(num_enchants)
|
||
|
]
|
||
|
num_contents = stream.read_dword()
|
||
|
self.rune_inventory_contents = [Inventory() for _ in range(num_contents)]
|
||
|
for content in self.rune_inventory_contents:
|
||
|
content.load_binary(stream)
|
||
|
|
||
|
self.rune_renderable = stream.read_bool()
|
||
|
if self.rune_renderable:
|
||
|
self.rune_scale_factor = stream.read_tuple()
|
||
|
self.rune_skeleton = stream.read_qword()
|
||
|
self.rune_slope_hugger = stream.read_bool()
|
||
|
self.rune_can_fly = stream.read_bool()
|
||
|
self.rune_death_effect = stream.read_qword()
|
||
|
self.rune_tombstone_id = stream.read_qword()
|
||
|
num_body_parts = stream.read_dword()
|
||
|
self.rune_body_parts = [BodyPart() for _ in range(num_body_parts)]
|
||
|
for part in self.rune_body_parts:
|
||
|
part.load_binary(stream)
|
||
|
num_hair = stream.read_dword()
|
||
|
self.rune_hair = [
|
||
|
stream.read_qword() for _ in range(num_hair)
|
||
|
]
|
||
|
num_beard = stream.read_dword()
|
||
|
self.rune_beard = [
|
||
|
stream.read_qword() for _ in range(num_beard)
|
||
|
]
|
||
|
self.rune_natural_power_attack = stream.read_dword()
|
||
|
self.rune_sparse_data = SparseData()
|
||
|
self.rune_sparse_data.load_binary(stream)
|
||
|
|
||
|
def save_binary(self, stream: ResStream):
|
||
|
super().save_binary(stream)
|
||
|
stream.write_dword(self.rune_type)
|
||
|
stream.write_dword(self.rune_sub_type)
|
||
|
stream.write_bool(self.rune_is_standard_character_creation)
|
||
|
stream.write_dword(self.rune_creation_cost)
|
||
|
stream.write_dword(self.rune_rank)
|
||
|
stream.write_dword(self.rune_pracs_per_level)
|
||
|
stream.write_float(self.rune_exp_req_to_level)
|
||
|
stream.write_dword(self.rune_sex)
|
||
|
stream.write_qword(self.rune_class_icon)
|
||
|
stream.write_dword(self.rune_health)
|
||
|
stream.write_dword(self.rune_mana)
|
||
|
stream.write_dword(self.rune_stamina)
|
||
|
stream.write_float(self.rune_min_damage)
|
||
|
stream.write_float(self.rune_max_damage)
|
||
|
stream.write_dword(self.rune_attack)
|
||
|
stream.write_dword(self.rune_defense)
|
||
|
stream.write_dword(self.rune_level)
|
||
|
for i in range(7):
|
||
|
stream.write_float(self.rune_speed[i])
|
||
|
self.rune_group.save_binary(stream)
|
||
|
stream.write_string(self.rune_dsc)
|
||
|
stream.write_string(self.rune_fx_txt)
|
||
|
stream.write_dword(self.rune_group_tactics)
|
||
|
stream.write_dword(self.rune_group_role_set)
|
||
|
stream.write_dword(len(self.rune_enemy_monster_types))
|
||
|
for monster in self.rune_enemy_monster_types:
|
||
|
stream.write_dword(monster)
|
||
|
stream.write_dword(len(self.rune_groupee_monster_types))
|
||
|
for monster in self.rune_groupee_monster_types:
|
||
|
stream.write_dword(monster)
|
||
|
stream.write_dword(len(self.rune_helper_monster_types))
|
||
|
for monster in self.rune_helper_monster_types:
|
||
|
stream.write_dword(monster)
|
||
|
stream.write_dword(len(self.rune_not_enemy_monster_types))
|
||
|
for monster in self.rune_not_enemy_monster_types:
|
||
|
stream.write_dword(monster)
|
||
|
stream.write_dword(len(self.rune_enemy_gender))
|
||
|
for gender in self.rune_enemy_gender:
|
||
|
stream.write_dword(gender)
|
||
|
stream.write_dword(len(self.rune_skill_grant))
|
||
|
for grant in self.rune_skill_grant:
|
||
|
grant.save_binary(stream)
|
||
|
stream.write_dword(len(self.rune_skill_adj))
|
||
|
for adjust in self.rune_skill_adj:
|
||
|
adjust.save_binary(stream)
|
||
|
stream.write_dword(len(self.rune_attr_adj))
|
||
|
for attr in self.rune_attr_adj:
|
||
|
attr.save_binary(stream)
|
||
|
stream.write_dword(len(self.rune_max_attr_adj))
|
||
|
for attr in self.rune_max_attr_adj:
|
||
|
attr.save_binary(stream)
|
||
|
stream.write_dword(len(self.rune_naturalattacks))
|
||
|
for attack in self.rune_naturalattacks:
|
||
|
stream.write_float(attack[0])
|
||
|
stream.write_float(attack[1])
|
||
|
stream.write_dword(attack[2])
|
||
|
stream.write_dword(attack[3])
|
||
|
stream.write_qword(attack[4])
|
||
|
stream.write_float(attack[5])
|
||
|
stream.write_dword(attack[6])
|
||
|
stream.write_dword(attack[7])
|
||
|
stream.write_dword(attack[8])
|
||
|
stream.write_dword(attack[9])
|
||
|
stream.write_dword(len(self.rune_enchantment_type))
|
||
|
for enchantment in self.rune_enchantment_type:
|
||
|
stream.write_dword(enchantment)
|
||
|
stream.write_dword(len(self.rune_inventory_contents))
|
||
|
for content in self.rune_inventory_contents:
|
||
|
content.save_binary(stream)
|
||
|
stream.write_bool(self.rune_renderable)
|
||
|
if self.rune_renderable:
|
||
|
stream.write_tuple(self.rune_scale_factor)
|
||
|
stream.write_qword(self.rune_skeleton)
|
||
|
stream.write_bool(self.rune_slope_hugger)
|
||
|
stream.write_bool(self.rune_can_fly)
|
||
|
stream.write_qword(self.rune_death_effect)
|
||
|
stream.write_qword(self.rune_tombstone_id)
|
||
|
stream.write_dword(len(self.rune_body_parts))
|
||
|
for part in self.rune_body_parts:
|
||
|
part.save_binary(stream)
|
||
|
stream.write_dword(len(self.rune_hair))
|
||
|
for hair in self.rune_hair:
|
||
|
stream.write_qword(hair)
|
||
|
stream.write_dword(len(self.rune_beard))
|
||
|
for beard in self.rune_beard:
|
||
|
stream.write_qword(beard)
|
||
|
stream.write_dword(self.rune_natural_power_attack)
|
||
|
self.rune_sparse_data.save_binary(stream)
|
||
|
|
||
|
def load_json(self, data):
|
||
|
super().load_json(data)
|
||
|
self.rune_type = STRING_TO_RUNE_TYPE[data['rune_type']]
|
||
|
self.rune_sub_type = string_to_hash(data['rune_sub_type'])
|
||
|
self.rune_is_standard_character_creation = data['rune_is_standard_character_creation']
|
||
|
self.rune_creation_cost = data['rune_creation_cost']
|
||
|
self.rune_rank = data['rune_rank']
|
||
|
self.rune_pracs_per_level = data['rune_pracs_per_level']
|
||
|
self.rune_exp_req_to_level = data['rune_exp_req_to_level']
|
||
|
self.rune_sex = STRING_TO_RUNE_SEX[data['rune_sex']]
|
||
|
self.rune_class_icon = data['rune_class_icon']
|
||
|
self.rune_health = data['rune_health']
|
||
|
self.rune_mana = data['rune_mana']
|
||
|
self.rune_stamina = data['rune_stamina']
|
||
|
self.rune_min_damage = data['rune_min_damage']
|
||
|
self.rune_max_damage = data['rune_max_damage']
|
||
|
self.rune_attack = data['rune_attack']
|
||
|
self.rune_defense = data['rune_defense']
|
||
|
self.rune_level = data['rune_level']
|
||
|
self.rune_speed = []
|
||
|
for i in range(7):
|
||
|
self.rune_speed.append(data['rune_speed'][SPEED_TYPE_TO_STRING[i]])
|
||
|
self.rune_group = Group()
|
||
|
self.rune_group.load_json(data['rune_group'])
|
||
|
self.rune_dsc = data['rune_dsc']
|
||
|
self.rune_fx_txt = data['rune_fx_txt']
|
||
|
self.rune_group_tactics = data['rune_group_tactics']
|
||
|
self.rune_group_role_set = data['rune_group_role_set']
|
||
|
self.rune_enemy_monster_types = []
|
||
|
for monster in data['rune_enemy_monster_types']:
|
||
|
self.rune_enemy_monster_types.append(string_to_hash(monster))
|
||
|
self.rune_groupee_monster_types = []
|
||
|
for monster in data['rune_groupee_monster_types']:
|
||
|
self.rune_groupee_monster_types.append(string_to_hash(monster))
|
||
|
self.rune_helper_monster_types = []
|
||
|
for monster in data['rune_helper_monster_types']:
|
||
|
self.rune_helper_monster_types.append(string_to_hash(monster))
|
||
|
self.rune_not_enemy_monster_types = []
|
||
|
for monster in data['rune_not_enemy_monster_types']:
|
||
|
self.rune_not_enemy_monster_types.append(string_to_hash(monster))
|
||
|
self.rune_enemy_gender = []
|
||
|
for gender in data['rune_enemy_gender']:
|
||
|
self.rune_enemy_gender.append(gender)
|
||
|
self.rune_skill_grant = []
|
||
|
for grant_data in data['rune_skill_grant']:
|
||
|
grant = SkillGrant()
|
||
|
grant.load_json(grant_data)
|
||
|
self.rune_skill_grant.append(grant)
|
||
|
self.rune_skill_adj = []
|
||
|
for adjust_data in data['rune_skill_adj']:
|
||
|
adjust = SkillAdjust()
|
||
|
adjust.load_json(adjust_data)
|
||
|
self.rune_skill_adj.append(adjust)
|
||
|
self.rune_attr_adj = []
|
||
|
for attr_data in data['rune_attr_adj']:
|
||
|
attr = AttributeValue()
|
||
|
attr.load_json(attr_data)
|
||
|
self.rune_attr_adj.append(attr)
|
||
|
self.rune_max_attr_adj = []
|
||
|
for attr_data in data['rune_max_attr_adj']:
|
||
|
attr = AttributeValue()
|
||
|
attr.load_json(attr_data)
|
||
|
self.rune_max_attr_adj.append(attr)
|
||
|
self.rune_naturalattacks = data['rune_naturalattacks']
|
||
|
self.rune_enchantment_type = []
|
||
|
for enchantment in data['rune_enchantment_type']:
|
||
|
self.rune_enchantment_type.append(enchantment)
|
||
|
self.rune_inventory_contents = []
|
||
|
for content_data in data['rune_inventory_contents']:
|
||
|
content = Inventory()
|
||
|
content.load_json(content_data)
|
||
|
self.rune_inventory_contents.append(content)
|
||
|
self.rune_renderable = data['rune_renderable']
|
||
|
if self.rune_renderable:
|
||
|
self.rune_scale_factor = data['rune_scale_factor']
|
||
|
self.rune_skeleton = data['rune_skeleton']
|
||
|
self.rune_slope_hugger = data['rune_slope_hugger']
|
||
|
self.rune_can_fly = data['rune_can_fly']
|
||
|
self.rune_death_effect = data['rune_death_effect']
|
||
|
self.rune_tombstone_id = data['rune_tombstone_id']
|
||
|
self.rune_body_parts = []
|
||
|
for part_data in data['rune_body_parts']:
|
||
|
part = BodyPart()
|
||
|
part.load_json(part_data)
|
||
|
self.rune_body_parts.append(part)
|
||
|
self.rune_hair = data['rune_hair']
|
||
|
self.rune_beard = data['rune_beard']
|
||
|
self.rune_natural_power_attack = data['rune_natural_power_attack']
|
||
|
self.rune_sparse_data = SparseData()
|
||
|
self.rune_sparse_data.load_json(data['rune_sparse_data'])
|
||
|
|
||
|
def save_json(self):
|
||
|
data = super().save_json()
|
||
|
data['rune_type'] = RUNE_TYPE_TO_STRING[self.rune_type]
|
||
|
data['rune_sub_type'] = hash_to_string(self.rune_sub_type)
|
||
|
data['rune_is_standard_character_creation'] = self.rune_is_standard_character_creation
|
||
|
data['rune_creation_cost'] = self.rune_creation_cost
|
||
|
data['rune_rank'] = self.rune_rank
|
||
|
data['rune_pracs_per_level'] = self.rune_pracs_per_level
|
||
|
data['rune_exp_req_to_level'] = self.rune_exp_req_to_level
|
||
|
data['rune_sex'] = RUNE_SEX_TO_STRING[self.rune_sex]
|
||
|
data['rune_class_icon'] = self.rune_class_icon
|
||
|
data['rune_health'] = self.rune_health
|
||
|
data['rune_mana'] = self.rune_mana
|
||
|
data['rune_stamina'] = self.rune_stamina
|
||
|
data['rune_min_damage'] = self.rune_min_damage
|
||
|
data['rune_max_damage'] = self.rune_max_damage
|
||
|
data['rune_attack'] = self.rune_attack
|
||
|
data['rune_defense'] = self.rune_defense
|
||
|
data['rune_level'] = self.rune_level
|
||
|
data['rune_speed'] = OrderedDict()
|
||
|
for i in range(7):
|
||
|
data['rune_speed'][SPEED_TYPE_TO_STRING[i]] = self.rune_speed[i]
|
||
|
data['rune_group'] = self.rune_group.save_json()
|
||
|
data['rune_dsc'] = self.rune_dsc
|
||
|
data['rune_fx_txt'] = self.rune_fx_txt
|
||
|
data['rune_group_tactics'] = self.rune_group_tactics
|
||
|
data['rune_group_role_set'] = self.rune_group_role_set
|
||
|
data['rune_enemy_monster_types'] = []
|
||
|
for monster in self.rune_enemy_monster_types:
|
||
|
data['rune_enemy_monster_types'].append(hash_to_string(monster))
|
||
|
data['rune_groupee_monster_types'] = []
|
||
|
for monster in self.rune_groupee_monster_types:
|
||
|
data['rune_groupee_monster_types'].append(hash_to_string(monster))
|
||
|
data['rune_helper_monster_types'] = []
|
||
|
for monster in self.rune_helper_monster_types:
|
||
|
data['rune_helper_monster_types'].append(hash_to_string(monster))
|
||
|
data['rune_not_enemy_monster_types'] = []
|
||
|
for monster in self.rune_not_enemy_monster_types:
|
||
|
data['rune_not_enemy_monster_types'].append(hash_to_string(monster))
|
||
|
data['rune_enemy_gender'] = []
|
||
|
for gender in self.rune_enemy_gender:
|
||
|
data['rune_enemy_gender'].append(gender)
|
||
|
data['rune_skill_grant'] = []
|
||
|
for grant in self.rune_skill_grant:
|
||
|
data['rune_skill_grant'].append(grant.save_json())
|
||
|
data['rune_skill_adj'] = []
|
||
|
for adjust in self.rune_skill_adj:
|
||
|
data['rune_skill_adj'].append(adjust.save_json())
|
||
|
data['rune_attr_adj'] = []
|
||
|
for attr in self.rune_attr_adj:
|
||
|
data['rune_attr_adj'].append(attr.save_json())
|
||
|
data['rune_max_attr_adj'] = []
|
||
|
for attr in self.rune_max_attr_adj:
|
||
|
data['rune_max_attr_adj'].append(attr.save_json())
|
||
|
data['rune_naturalattacks'] = self.rune_naturalattacks
|
||
|
data['rune_enchantment_type'] = []
|
||
|
for enchantment in self.rune_enchantment_type:
|
||
|
data['rune_enchantment_type'].append(enchantment)
|
||
|
data['rune_inventory_contents'] = []
|
||
|
for content in self.rune_inventory_contents:
|
||
|
data['rune_inventory_contents'].append(content.save_json())
|
||
|
data['rune_renderable'] = self.rune_renderable
|
||
|
if self.rune_renderable:
|
||
|
data['rune_scale_factor'] = self.rune_scale_factor
|
||
|
data['rune_skeleton'] = self.rune_skeleton
|
||
|
data['rune_slope_hugger'] = self.rune_slope_hugger
|
||
|
data['rune_can_fly'] = self.rune_can_fly
|
||
|
data['rune_death_effect'] = self.rune_death_effect
|
||
|
data['rune_tombstone_id'] = self.rune_tombstone_id
|
||
|
data['rune_body_parts'] = []
|
||
|
for part in self.rune_body_parts:
|
||
|
data['rune_body_parts'].append(part.save_json())
|
||
|
data['rune_hair'] = self.rune_hair
|
||
|
data['rune_beard'] = self.rune_beard
|
||
|
data['rune_natural_power_attack'] = self.rune_natural_power_attack
|
||
|
data['rune_sparse_data'] = self.rune_sparse_data.save_json()
|
||
|
return data
|