Repository for mbEditorPro 2.0
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.

469 lines
21 KiB

# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
# Magicbane Emulator Project © 2013 - 2022
# www.magicbane.com
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(monster)
self.rune_helper_monster_types = []
for monster in data['rune_helper_monster_types']:
self.rune_helper_monster_types.append(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(monster)
data['rune_helper_monster_types'] = []
for monster in self.rune_helper_monster_types:
data['rune_helper_monster_types'].append(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