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.

340 lines
18 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.objects.ArcRune import Group
from arcane.objects.common.Inventory import Inventory
from arcane.util import ResStream
from .ArcBasicZoneObjectInfo import ArcBasicZoneObjectInfo
class Unknown:
def load_binary(self, stream: ResStream):
self.unknown_u = stream.read_dword()
self.unknown_u = stream.read_dword()
self.unknown_u = stream.read_dword()
self.unknown_check = stream.read_bool()
if self.unknown_check:
self.unknown_u = stream.read_qword()
else:
self.unknown_u = stream.read_dword()
self.unknown_u = stream.read_string()
self.unknown_u = stream.read_float()
class InventoryContents:
def load_binary(self, stream: ResStream):
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_tuple()
self.mobile_inventory_u = stream.read_tuple()
self.mobile_inventory_u = [stream.read_float() for _ in range(4)]
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_bool()
self.mobile_inventory_u = stream.read_string()
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
self.mobile_inventory_u = stream.read_float()
self.mobile_inventory_u = stream.read_float()
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_float()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_dword()
num = stream.read_dword()
self.mobile_inventory_u = [Unknown() for _ in range(num)]
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
self.mobile_inventory_u = stream.read_bool()
self.mobile_inventory_u = stream.read_float()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
self.mobile_inventory_u = [stream.read_dword() for _ in range(5)]
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
self.mobile_inventory_u = [stream.read_dword() for _ in range(5)]
self.mobile_inventory_u = stream.read_bool()
class MobileInfo:
def load_binary(self, stream: ResStream):
self.mobile_base_zone = ArcBasicZoneObjectInfo()
self.mobile_base_zone.load_binary(stream)
self.mobile_number_in_group = stream.read_dword()
self.mobile_change_to_find = stream.read_float()
self.mobile_level = stream.read_dword()
self.mobile_behavior_file = stream.read_string()
self.mobile_dialog_override = stream.read_dword()
self.mobile_base_exp_reward = stream.read_dword()
self.mobile_tenacity = stream.read_float()
self.mobile_courage = stream.read_float()
self.mobile_has_group_tactics = stream.read_bool()
if self.mobile_has_group_tactics:
self.mobile_group_tactics = stream.read_dword()
self.mobile_has_role_set = stream.read_bool()
if self.mobile_has_role_set:
self.mobile_role_set = stream.read_dword()
self.mobile_has_home_goal = stream.read_bool()
if self.mobile_has_home_goal:
self.mobile_home_goal = stream.read_dword()
self.mobile_spawn_home_goal = stream.read_bool()
self.mobile_has_target_goal = stream.read_bool()
if self.mobile_has_target_goal:
self.mobile_target_goal = stream.read_dword()
self.mobile_spawn_target_goal = stream.read_bool()
num_rune_stone_ids = stream.read_dword()
self.mobile_rune_stone_ids = [stream.read_qword() for _ in range(num_rune_stone_ids)]
self.mobile_has_content = stream.read_bool()
if self.mobile_has_content:
num_contents = stream.read_dword()
self.mobile_inventory_contents = [InventoryContents() for _ in range(num_contents)]
for content in self.mobile_inventory_contents:
content.load_binary(stream)
num_equipments = stream.read_dword()
self.mobile_equipment = [[
stream.read_qword(),
stream.read_float(),
] for _ in range(num_equipments)]
num_lores = stream.read_dword()
self.mobile_lores = [stream.read_dword() for _ in range(num_lores)]
self.mobile_use_prefered_hp = stream.read_bool()
num_spawn_hps = stream.read_dword()
self.mobile_spawn_hps = [stream.read_dword() for _ in range(num_spawn_hps)]
num = stream.read_dword()
self.mobile_booties = [Inventory() for _ in range(num)]
for booty in self.mobile_booties:
booty.load_binary(stream)
self.mobile_root_fs_mid = stream.read_string()
self.mobile_group = Group()
self.mobile_group.load_binary(stream)
num_enemy_monster_types = stream.read_dword()
self.mobile_enemy_monster_types = [stream.read_dword() for _ in range(num_enemy_monster_types)]
num_not_enemy_monster_types = stream.read_dword()
self.mobile_not_enemy_monster_types = [stream.read_dword() for _ in range(num_not_enemy_monster_types)]
num_groupee_monster_types = stream.read_dword()
self.mobile_groupee_monster_types = [stream.read_dword() for _ in range(num_groupee_monster_types)]
num_helper_monster_types = stream.read_dword()
self.mobile_helper_monster_types = [stream.read_dword() for _ in range(num_helper_monster_types)]
num_enemy_genders = stream.read_dword()
self.mobile_enemy_genders = [stream.read_dword() for _ in range(num_enemy_genders)]
num_friendly_charters = stream.read_dword()
self.mobile_friendly_charters = [stream.read_dword() for _ in range(num_friendly_charters)]
self.mobile_parley_name = stream.read_string()
def save_binary(self, stream: ResStream):
self.mobile_base_zone.save_binary(stream)
stream.write_dword(self.mobile_number_in_group)
stream.write_float(self.mobile_change_to_find)
stream.write_dword(self.mobile_level)
stream.write_string(self.mobile_behavior_file)
stream.write_dword(self.mobile_dialog_override)
stream.write_dword(self.mobile_base_exp_reward)
stream.write_float(self.mobile_tenacity)
stream.write_float(self.mobile_courage)
stream.write_bool(self.mobile_has_group_tactics)
if self.mobile_has_group_tactics:
stream.write_dword(self.mobile_group_tactics)
stream.write_bool(self.mobile_has_role_set)
if self.mobile_has_role_set:
stream.write_dword(self.mobile_role_set)
stream.write_bool(self.mobile_has_home_goal)
if self.mobile_has_home_goal:
stream.write_dword(self.mobile_home_goal)
stream.write_bool(self.mobile_spawn_home_goal)
stream.write_bool(self.mobile_has_target_goal)
if self.mobile_has_target_goal:
stream.write_dword(self.mobile_target_goal)
stream.write_bool(self.mobile_spawn_target_goal)
stream.write_dword(len(self.mobile_rune_stone_ids))
for rune_stone_id in self.mobile_rune_stone_ids:
stream.write_qword(rune_stone_id)
stream.write_bool(self.mobile_has_content)
if self.mobile_has_content:
stream.write_dword(len(self.mobile_inventory_contents))
for content in self.mobile_inventory_contents:
content.save_binary(stream)
stream.write_dword(len(self.mobile_equipment))
for equipment in self.mobile_equipment:
stream.write_qword(equipment[0])
stream.write_float(equipment[1])
stream.write_dword(len(self.mobile_lores))
for lore in self.mobile_lores:
stream.write_dword(lore)
stream.write_bool(self.mobile_use_prefered_hp)
stream.write_dword(len(self.mobile_spawn_hps))
for spawn_hp in self.mobile_spawn_hps:
stream.write_dword(spawn_hp)
stream.write_dword(len(self.mobile_booties))
for booty in self.mobile_booties:
booty.save_binary(stream)
stream.write_string(self.mobile_root_fs_mid)
self.mobile_group.save_binary(stream)
stream.write_dword(len(self.mobile_enemy_monster_types))
for enemy_monster_type in self.mobile_enemy_monster_types:
stream.write_dword(enemy_monster_type)
stream.write_dword(len(self.mobile_not_enemy_monster_types))
for not_enemy_monster_type in self.mobile_not_enemy_monster_types:
stream.write_dword(not_enemy_monster_type)
stream.write_dword(len(self.mobile_groupee_monster_types))
for groupee_monster_type in self.mobile_groupee_monster_types:
stream.write_dword(groupee_monster_type)
stream.write_dword(len(self.mobile_helper_monster_types))
for helper_monster_type in self.mobile_helper_monster_types:
stream.write_dword(helper_monster_type)
stream.write_dword(len(self.mobile_enemy_genders))
for enemy_gender in self.mobile_enemy_genders:
stream.write_dword(enemy_gender)
stream.write_dword(len(self.mobile_friendly_charters))
for friendly_charter in self.mobile_friendly_charters:
stream.write_dword(friendly_charter)
stream.write_string(self.mobile_parley_name)
def save_json(self):
data = OrderedDict()
data['mobile_base_zone'] = self.mobile_base_zone.save_json()
data['mobile_number_in_group'] = self.mobile_number_in_group
data['mobile_change_to_find'] = self.mobile_change_to_find
data['mobile_level'] = self.mobile_level
data['mobile_behavior_file'] = self.mobile_behavior_file
data['mobile_dialog_override'] = self.mobile_dialog_override
data['mobile_base_exp_reward'] = self.mobile_base_exp_reward
data['mobile_tenacity'] = self.mobile_tenacity
data['mobile_courage'] = self.mobile_courage
data['mobile_has_group_tactics'] = self.mobile_has_group_tactics
if self.mobile_has_group_tactics:
data['mobile_group_tactics'] = self.mobile_group_tactics
data['mobile_has_role_set'] = self.mobile_has_role_set
if self.mobile_has_role_set:
data['mobile_role_set'] = self.mobile_role_set
data['mobile_has_home_goal'] = self.mobile_has_home_goal
if self.mobile_has_home_goal:
data['mobile_home_goal'] = self.mobile_home_goal
data['mobile_spawn_home_goal'] = self.mobile_spawn_home_goal
data['mobile_has_target_goal'] = self.mobile_has_target_goal
if self.mobile_has_target_goal:
data['mobile_target_goal'] = self.mobile_target_goal
data['mobile_spawn_target_goal'] = self.mobile_spawn_target_goal
data['mobile_rune_stone_ids'] = self.mobile_rune_stone_ids
data['mobile_has_content'] = self.mobile_has_content
if self.mobile_has_content:
data['mobile_inventory_contents'] = []
for content in self.mobile_inventory_contents:
data['mobile_inventory_contents'].append(content.save_json())
data['mobile_equipment'] = self.mobile_equipment
data['mobile_lores'] = self.mobile_lores
data['mobile_use_prefered_hp'] = self.mobile_use_prefered_hp
data['mobile_spawn_hps'] = self.mobile_spawn_hps
data['mobile_booties'] = []
for booty in self.mobile_booties:
data['mobile_booties'].append(booty.save_json())
data['mobile_root_fs_mid'] = self.mobile_root_fs_mid
data['mobile_group'] = self.mobile_group.save_json()
data['mobile_enemy_monster_types'] = []
for enemy_monster_type in self.mobile_enemy_monster_types:
data['mobile_enemy_monster_types'].append(hash_to_string(enemy_monster_type))
data['mobile_not_enemy_monster_types'] = []
for not_enemy_monster_type in self.mobile_not_enemy_monster_types:
data['mobile_not_enemy_monster_types'].append(hash_to_string(not_enemy_monster_type))
data['mobile_groupee_monster_types'] = []
for groupee_monster_type in self.mobile_groupee_monster_types:
data['mobile_groupee_monster_types'].append(hash_to_string(groupee_monster_type))
data['mobile_helper_monster_types'] = []
for helper_monster_type in self.mobile_helper_monster_types:
data['mobile_helper_monster_types'].append(hash_to_string(helper_monster_type))
data['mobile_enemy_genders'] = []
for enemy_gender in self.mobile_enemy_genders:
data['mobile_enemy_genders'].append(RUNE_SEX_TO_STRING[enemy_gender])
data['mobile_friendly_charters'] = self.mobile_friendly_charters
data['mobile_parley_name'] = self.mobile_parley_name
return data
def load_json(self, data):
self.mobile_base_zone = ArcBasicZoneObjectInfo()
self.mobile_base_zone.load_json(data['mobile_base_zone'])
self.mobile_number_in_group = data['mobile_number_in_group']
self.mobile_change_to_find = data['mobile_change_to_find']
self.mobile_level = data['mobile_level']
self.mobile_behavior_file = data['mobile_behavior_file']
self.mobile_dialog_override = data['mobile_dialog_override']
self.mobile_base_exp_reward = data['mobile_base_exp_reward']
self.mobile_tenacity = data['mobile_tenacity']
self.mobile_courage = data['mobile_courage']
self.mobile_has_group_tactics = data['mobile_has_group_tactics']
if self.mobile_has_group_tactics:
self.mobile_group_tactics = data['mobile_group_tactics']
self.mobile_has_role_set = data['mobile_has_role_set']
if self.mobile_has_role_set:
self.mobile_role_set = data['mobile_role_set']
self.mobile_has_home_goal = data['mobile_has_home_goal']
if self.mobile_has_home_goal:
self.mobile_home_goal = data['mobile_home_goal']
self.mobile_spawn_home_goal = data['mobile_spawn_home_goal']
self.mobile_has_target_goal = data['mobile_has_target_goal']
if self.mobile_has_target_goal:
self.mobile_target_goal = data['mobile_target_goal']
self.mobile_spawn_target_goal = data['mobile_spawn_target_goal']
self.mobile_rune_stone_ids = data['mobile_rune_stone_ids']
self.mobile_has_content = data['mobile_has_content']
if self.mobile_has_content:
self.mobile_inventory_contents = []
for content_data in data['mobile_inventory_contents']:
content = InventoryContents()
content.load_json(content_data)
self.mobile_inventory_contents.append(content)
self.mobile_equipment = data['mobile_equipment']
self.mobile_lores = data['mobile_lores']
self.mobile_use_prefered_hp = data['mobile_use_prefered_hp']
self.mobile_spawn_hps = data['mobile_spawn_hps']
self.mobile_booties = []
for booty_data in data['mobile_booties']:
booty = Inventory()
booty.load_json(booty_data)
self.mobile_booties.append(booty)
self.mobile_root_fs_mid = data['mobile_root_fs_mid']
self.mobile_group = Group()
self.mobile_group.load_json(data['mobile_group'])
self.mobile_enemy_monster_types = []
for enemy_monster_type in data['mobile_enemy_monster_types']:
self.mobile_enemy_monster_types.append(string_to_hash(enemy_monster_type))
self.mobile_not_enemy_monster_types = []
for not_enemy_monster_type in data['mobile_not_enemy_monster_types']:
self.mobile_not_enemy_monster_types.append(string_to_hash(not_enemy_monster_type))
self.mobile_groupee_monster_types = []
for groupee_monster_type in data['mobile_groupee_monster_types']:
self.mobile_groupee_monster_types.append(string_to_hash(groupee_monster_type))
self.mobile_helper_monster_types = []
for helper_monster_type in data['mobile_helper_monster_types']:
self.mobile_helper_monster_types.append(string_to_hash(helper_monster_type))
self.mobile_enemy_genders = []
for enemy_gender in data['mobile_enemy_genders']:
self.mobile_enemy_genders.append(STRING_TO_RUNE_SEX[enemy_gender])
self.mobile_friendly_charters = data['mobile_friendly_charters']
self.mobile_parley_name = data['mobile_parley_name']