# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄ # ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪ # ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄ # ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌ # ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪ # Magicbane Emulator Project © 2013 - 2022 # www.magicbane.com from collections import OrderedDict from arcane.enums.hashes import hash_to_string, string_to_hash from arcane.enums.zone.arc_prop import * from arcane.objects.common.Inventory import Inventory from arcane.util import ResStream from .ArcMobile import ArcMobile from .mobile.ArcBasicZoneObjectInfo import ArcBasicZoneObjectInfo class ArcPropInfo: def load_binary(self, stream: ResStream): self.prop_basic_zone = ArcBasicZoneObjectInfo() self.prop_basic_zone.load_binary(stream) self.prop_has_platform = stream.read_bool() self.prop_platform_height = stream.read_float() self.prop_is_light_data = stream.read_bool() if self.prop_is_light_data: self.prop_light_color = [stream.read_dword() for _ in range(4)] self.prop_light_radius = stream.read_float() self.prop_light_flicker = stream.read_dword() self.prop_light_cube_map = stream.read_dword() num_content_props = stream.read_dword() self.prop_content_props = [ArcProp() for _ in range(num_content_props)] for prop in self.prop_content_props: prop.load_binary(stream) num_content_mobiles = stream.read_dword() self.prop_content_mobiles = [ArcMobile() for _ in range(num_content_mobiles)] for mobile in self.prop_content_mobiles: mobile.load_binary(stream) num_descriptors = stream.read_dword() self.prop_descriptors = [stream.read_string() for _ in range(num_descriptors)] self.prop_registry = stream.read_dword() if self.prop_registry: self.prop_registry_name = stream.read_string() self.prop_has_zone_event = stream.read_bool() self.prop_has_teleporter = stream.read_bool() if self.prop_has_zone_event: self.prop_zone_event = stream.read_dword() if self.prop_has_teleporter: self.prop_teleporter = stream.read_dword() def save_binary(self, stream: ResStream): self.prop_basic_zone.save_binary(stream) stream.write_bool(self.prop_has_platform) stream.write_float(self.prop_platform_height) stream.write_bool(self.prop_is_light_data) if self.prop_is_light_data: for i in range(4): stream.write_dword(self.prop_light_color[i]) stream.write_float(self.prop_light_radius) stream.write_dword(self.prop_light_flicker) stream.write_dword(self.prop_light_cube_map) stream.write_dword(len(self.prop_content_props)) for prop in self.prop_content_props: prop.save_binary(stream) stream.write_dword(len(self.prop_content_mobiles)) for mobile in self.prop_content_mobiles: mobile.save_binary(stream) stream.write_dword(len(self.prop_descriptors)) for descriptor in self.prop_descriptors: stream.write_string(descriptor) stream.write_dword(self.prop_registry) if self.prop_registry: stream.write_string(self.prop_registry_name) stream.write_bool(self.prop_has_zone_event) stream.write_bool(self.prop_has_teleporter) if self.prop_has_zone_event: stream.write_dword(self.prop_zone_event) if self.prop_has_teleporter: stream.write_dword(self.prop_teleporter) def save_json(self): data = OrderedDict() data['prop_basic_zone'] = self.prop_basic_zone.save_json() data['prop_has_platform'] = self.prop_has_platform data['prop_platform_height'] = self.prop_platform_height data['prop_is_light_data'] = self.prop_is_light_data if self.prop_is_light_data: data['prop_light_color'] = self.prop_light_color data['prop_light_radius'] = self.prop_light_radius data['prop_light_flicker'] = self.prop_light_flicker data['prop_light_cube_map'] = self.prop_light_cube_map data['prop_content_props'] = [] for prop in self.prop_content_props: data['prop_content_props'].append(prop.save_json()) data['prop_content_mobiles'] = [] for mobile in self.prop_content_mobiles: data['prop_content_mobiles'].append(mobile.save_json()) data['prop_descriptors'] = self.prop_descriptors data['prop_registry'] = self.prop_registry if self.prop_registry: data['prop_registry_name'] = self.prop_registry_name data['prop_has_zone_event'] = self.prop_has_zone_event data['prop_has_teleporter'] = self.prop_has_teleporter if self.prop_has_zone_event: data['prop_zone_event'] = hash_to_string(self.prop_zone_event) if self.prop_has_teleporter: data['prop_teleporter'] = hash_to_string(self.prop_teleporter) return data def load_json(self, data): self.prop_basic_zone = ArcBasicZoneObjectInfo() self.prop_basic_zone.load_json(data['prop_basic_zone']) self.prop_has_platform = data['prop_has_platform'] self.prop_platform_height = data['prop_platform_height'] self.prop_is_light_data = data['prop_is_light_data'] if self.prop_is_light_data: self.prop_light_color = data['prop_light_color'] self.prop_light_radius = data['prop_light_radius'] self.prop_light_flicker = data['prop_light_flicker'] self.prop_light_cube_map = data['prop_light_cube_map'] self.prop_content_props = [] for prop_data in data['prop_content_props']: prop = ArcProp() prop.load_json(prop_data) self.prop_content_props.append(prop) self.prop_content_mobiles = [] for mobile_data in data['prop_content_mobiles']: mobile = ArcMobile() mobile.load_json(mobile_data) self.prop_content_mobiles.append(mobile) self.prop_descriptors = data['prop_descriptors'] self.prop_registry = data['prop_registry'] if self.prop_registry: self.prop_registry_name = data['prop_registry_name'] self.prop_has_zone_event = data['prop_has_zone_event'] self.prop_has_teleporter = data['prop_has_teleporter'] if self.prop_has_zone_event: self.prop_zone_event = string_to_hash(data['prop_zone_event']) if self.prop_has_teleporter: self.prop_teleporter = string_to_hash(data['prop_teleporter']) class ArcCityPropInfo(ArcPropInfo): def load_binary(self, stream: ResStream): super().load_binary(stream) self.city_prop_gm_guild = stream.read_dword() self.city_prop_gm_nation = stream.read_dword() self.city_prop_asset_rank = stream.read_dword() self.city_prop_asset_funds = stream.read_dword() def save_binary(self, stream: ResStream): super().save_binary(stream) stream.write_dword(self.city_prop_gm_guild) stream.write_dword(self.city_prop_gm_nation) stream.write_dword(self.city_prop_asset_rank) stream.write_dword(self.city_prop_asset_funds) def save_json(self): data = super().save_json() data['city_prop_gm_guild'] = self.city_prop_gm_guild data['city_prop_gm_nation'] = self.city_prop_gm_nation data['city_prop_asset_rank'] = self.city_prop_asset_rank data['city_prop_asset_funds'] = self.city_prop_asset_funds return data def load_json(self, data): super().load_json(data) self.city_prop_gm_guild = data['city_prop_gm_guild'] self.city_prop_gm_nation = data['city_prop_gm_nation'] self.city_prop_asset_rank = data['city_prop_asset_rank'] self.city_prop_asset_funds = data['city_prop_asset_funds'] class ArcContainerInfo(ArcPropInfo): def load_binary(self, stream: ResStream): super().load_binary(stream) self.container_locked = stream.read_dword() self.container_locked_rank = stream.read_dword() self.container_barred = stream.read_dword() self.container_barred_rank = stream.read_dword() self.container_trapped = stream.read_dword() self.container_trapped_rank = stream.read_dword() num_booties = stream.read_dword() self.container_booties = [Inventory() for _ in range(num_booties)] for inventory in self.container_booties: inventory.load_binary(stream) def save_binary(self, stream: ResStream): super().save_binary(stream) stream.write_dword(self.container_locked) stream.write_dword(self.container_locked_rank) stream.write_dword(self.container_barred) stream.write_dword(self.container_barred_rank) stream.write_dword(self.container_trapped) stream.write_dword(self.container_trapped_rank) stream.write_dword(len(self.container_booties)) for inventory in self.container_booties: inventory.save_binary(stream) def save_json(self): data = super().save_json() data['container_locked'] = self.container_locked data['container_locked_rank'] = self.container_locked_rank data['container_barred'] = self.container_barred data['container_barred_rank'] = self.container_barred_rank data['container_trapped'] = self.container_trapped data['container_trapped_rank'] = self.container_trapped_rank data['container_booties'] = [] for inventory in self.container_booties: data['container_booties'].append(inventory.save_json()) return data def load_json(self, data): super().load_json(data) self.container_locked = data['container_locked'] self.container_locked_rank = data['container_locked_rank'] self.container_barred = data['container_barred'] self.container_barred_rank = data['container_barred_rank'] self.container_trapped = data['container_trapped'] self.container_trapped_rank = data['container_trapped_rank'] self.container_booties = [] for inventory_data in data['container_booties']: inventory = Inventory() inventory.load_json(inventory_data) self.container_booties.append(inventory) class ArcProp: def load_binary(self, stream: ResStream): self.prop_type = stream.read_dword() if self.prop_type == 5: self.prop_data = ArcPropInfo() self.prop_data.load_binary(stream) elif self.prop_type == 6: self.prop_data = ArcCityPropInfo() self.prop_data.load_binary(stream) elif self.prop_type == 7: self.prop_data = ArcContainerInfo() self.prop_data.load_binary(stream) def save_binary(self, stream: ResStream): stream.write_dword(self.prop_type) self.prop_data.save_binary(stream) def save_json(self): data = OrderedDict() data['prop_type'] = PROP_TO_STRING[self.prop_type] data['prop_data'] = self.prop_data.save_json() return data def load_json(self, data): self.prop_type = STRING_TO_PROP[data['prop_type']] if self.prop_type == 5: self.prop_data = ArcPropInfo() elif self.prop_type == 6: self.prop_data = ArcCityPropInfo() elif self.prop_type == 7: self.prop_data = ArcContainerInfo() self.prop_data.load_json(data['prop_data'])