Read client signed int32 zone fields as signed
Use read_long/write_long for every CZone value the client loads with ResStream_ReadInt32: basic zone level/room/dungeon indexes (default -1), zone width/material thresholds and indexes, sea level index, pattern and texture ints, terrain octaves and seeds, terrain object ints, goal delay and points, mobile group size/level/exp, shopkeeper gold, buy and sell list values, prop light ints, city prop rank/funds and container lock/bar/trap values. Hash, enum, flag and count fields stay unsigned. The binary is unchanged; on the sample cache JSON only changes from 4294967295 to -1 in the five basic zone index fields. Older dumps still pack because write_long accepts the unsigned form. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2e1cef3da8
commit
876484947c
9 files changed
+80
-80
No files matched your search
@@ -27,8 +27,8 @@ class ArcPropInfo:
|
||||
if self.prop_is_light_data:
|
||||
self.prop_light_color = [stream.read_float() 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()
|
||||
self.prop_light_flicker = stream.read_long()
|
||||
self.prop_light_cube_map = stream.read_long()
|
||||
num_content_props = stream.read_dword()
|
||||
self.prop_content_props = [ArcProp() for _ in range(num_content_props)]
|
||||
for prop in self.prop_content_props:
|
||||
@@ -60,8 +60,8 @@ class ArcPropInfo:
|
||||
for i in range(4):
|
||||
stream.write_float(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_long(self.prop_light_flicker)
|
||||
stream.write_long(self.prop_light_cube_map)
|
||||
|
||||
stream.write_dword(len(self.prop_content_props))
|
||||
for prop in self.prop_content_props:
|
||||
@@ -154,15 +154,15 @@ class ArcCityPropInfo(ArcPropInfo):
|
||||
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()
|
||||
self.city_prop_asset_rank = stream.read_long()
|
||||
self.city_prop_asset_funds = stream.read_long()
|
||||
|
||||
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)
|
||||
stream.write_long(self.city_prop_asset_rank)
|
||||
stream.write_long(self.city_prop_asset_funds)
|
||||
|
||||
def save_json(self):
|
||||
data = super().save_json()
|
||||
@@ -183,12 +183,12 @@ class ArcCityPropInfo(ArcPropInfo):
|
||||
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()
|
||||
self.container_locked = stream.read_long()
|
||||
self.container_locked_rank = stream.read_long()
|
||||
self.container_barred = stream.read_long()
|
||||
self.container_barred_rank = stream.read_long()
|
||||
self.container_trapped = stream.read_long()
|
||||
self.container_trapped_rank = stream.read_long()
|
||||
num_booties = stream.read_dword()
|
||||
self.container_booties = [Inventory() for _ in range(num_booties)]
|
||||
for inventory in self.container_booties:
|
||||
@@ -196,12 +196,12 @@ class ArcContainerInfo(ArcPropInfo):
|
||||
|
||||
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_long(self.container_locked)
|
||||
stream.write_long(self.container_locked_rank)
|
||||
stream.write_long(self.container_barred)
|
||||
stream.write_long(self.container_barred_rank)
|
||||
stream.write_long(self.container_trapped)
|
||||
stream.write_long(self.container_trapped_rank)
|
||||
stream.write_dword(len(self.container_booties))
|
||||
for inventory in self.container_booties:
|
||||
inventory.save_binary(stream)
|
||||
|
||||
@@ -21,12 +21,12 @@ class ArcTerrainGen:
|
||||
self.terrain_max_z = stream.read_float()
|
||||
self.terrain_h = stream.read_float()
|
||||
self.terrain_lacunarity = stream.read_float()
|
||||
self.terrain_octaves = stream.read_dword()
|
||||
self.terrain_octaves = stream.read_long()
|
||||
self.terrain_offset = stream.read_float()
|
||||
self.terrain_gain = stream.read_float()
|
||||
self.terrain_seeds = [
|
||||
stream.read_dword(),
|
||||
stream.read_dword(),
|
||||
stream.read_long(),
|
||||
stream.read_long(),
|
||||
]
|
||||
if self.terrain_type == 4:
|
||||
self.terrain_max_x = stream.read_float()
|
||||
@@ -54,11 +54,11 @@ class ArcTerrainGen:
|
||||
stream.write_float(self.terrain_max_z)
|
||||
stream.write_float(self.terrain_h)
|
||||
stream.write_float(self.terrain_lacunarity)
|
||||
stream.write_dword(self.terrain_octaves)
|
||||
stream.write_long(self.terrain_octaves)
|
||||
stream.write_float(self.terrain_offset)
|
||||
stream.write_float(self.terrain_gain)
|
||||
stream.write_dword(self.terrain_seeds[0])
|
||||
stream.write_dword(self.terrain_seeds[1])
|
||||
stream.write_long(self.terrain_seeds[0])
|
||||
stream.write_long(self.terrain_seeds[1])
|
||||
if self.terrain_type == 4:
|
||||
stream.write_float(self.terrain_max_x)
|
||||
stream.write_float(self.terrain_max_z)
|
||||
|
||||
@@ -29,10 +29,10 @@ class ArcZone:
|
||||
self.zone_type = stream.read_dword()
|
||||
self.zone_name = stream.read_string()
|
||||
self.zone_custom_texture = stream.read_qword()
|
||||
self.zone_width_threshold = stream.read_dword()
|
||||
self.zone_material_threshold = stream.read_dword()
|
||||
self.zone_max_width_index = stream.read_dword()
|
||||
self.zone_max_material_index = stream.read_dword()
|
||||
self.zone_width_threshold = stream.read_long()
|
||||
self.zone_material_threshold = stream.read_long()
|
||||
self.zone_max_width_index = stream.read_long()
|
||||
self.zone_max_material_index = stream.read_long()
|
||||
self.zone_custom_texture_wrap = stream.read_bool()
|
||||
self.zone_peace_zone = stream.read_bool()
|
||||
self.zone_guild_zone = stream.read_bool()
|
||||
@@ -49,7 +49,7 @@ class ArcZone:
|
||||
self.zone_tile_cord_type = stream.read_dword()
|
||||
self.zone_tile_pattern_prob = stream.read_float()
|
||||
self.zone_pattern_type = stream.read_dword()
|
||||
self.zone_sea_level_index = stream.read_dword()
|
||||
self.zone_sea_level_index = stream.read_long()
|
||||
self.zone_sea_level = stream.read_float()
|
||||
self.zone_sea_level_type = stream.read_dword()
|
||||
self.zone_grad = stream.read_float()
|
||||
@@ -74,7 +74,7 @@ class ArcZone:
|
||||
num_patterns = stream.read_dword()
|
||||
self.zone_patterns = [
|
||||
[
|
||||
stream.read_dword(),
|
||||
stream.read_long(),
|
||||
stream.read_float(),
|
||||
] for _ in range(num_patterns)
|
||||
]
|
||||
@@ -132,9 +132,9 @@ class ArcZone:
|
||||
stream.read_float(),
|
||||
stream.read_float(),
|
||||
stream.read_float(),
|
||||
stream.read_dword(),
|
||||
stream.read_dword(),
|
||||
stream.read_dword(),
|
||||
stream.read_long(),
|
||||
stream.read_long(),
|
||||
stream.read_long(),
|
||||
] for _ in range(num_textures)
|
||||
]
|
||||
|
||||
@@ -142,10 +142,10 @@ class ArcZone:
|
||||
stream.write_dword(self.zone_type)
|
||||
stream.write_string(self.zone_name)
|
||||
stream.write_qword(self.zone_custom_texture)
|
||||
stream.write_dword(self.zone_width_threshold)
|
||||
stream.write_dword(self.zone_material_threshold)
|
||||
stream.write_dword(self.zone_max_width_index)
|
||||
stream.write_dword(self.zone_max_material_index)
|
||||
stream.write_long(self.zone_width_threshold)
|
||||
stream.write_long(self.zone_material_threshold)
|
||||
stream.write_long(self.zone_max_width_index)
|
||||
stream.write_long(self.zone_max_material_index)
|
||||
stream.write_bool(self.zone_custom_texture_wrap)
|
||||
stream.write_bool(self.zone_peace_zone)
|
||||
stream.write_bool(self.zone_guild_zone)
|
||||
@@ -162,7 +162,7 @@ class ArcZone:
|
||||
stream.write_dword(self.zone_tile_cord_type)
|
||||
stream.write_float(self.zone_tile_pattern_prob)
|
||||
stream.write_dword(self.zone_pattern_type)
|
||||
stream.write_dword(self.zone_sea_level_index)
|
||||
stream.write_long(self.zone_sea_level_index)
|
||||
stream.write_float(self.zone_sea_level)
|
||||
stream.write_dword(self.zone_sea_level_type)
|
||||
stream.write_float(self.zone_grad)
|
||||
@@ -182,7 +182,7 @@ class ArcZone:
|
||||
self.zone_terrain_gen.save_binary(stream)
|
||||
stream.write_dword(len(self.zone_patterns))
|
||||
for pattern in self.zone_patterns:
|
||||
stream.write_dword(pattern[0])
|
||||
stream.write_long(pattern[0])
|
||||
stream.write_float(pattern[1])
|
||||
stream.write_dword(len(self.zone_alts))
|
||||
for alt in self.zone_alts:
|
||||
@@ -234,9 +234,9 @@ class ArcZone:
|
||||
stream.write_float(texture[3])
|
||||
stream.write_float(texture[4])
|
||||
stream.write_float(texture[5])
|
||||
stream.write_dword(texture[6])
|
||||
stream.write_dword(texture[7])
|
||||
stream.write_dword(texture[8])
|
||||
stream.write_long(texture[6])
|
||||
stream.write_long(texture[7])
|
||||
stream.write_long(texture[8])
|
||||
|
||||
def save_json(self):
|
||||
data = OrderedDict()
|
||||
|
||||
@@ -15,12 +15,12 @@ from arcane.util import ResStream
|
||||
|
||||
class ArcZoneGoalPoint:
|
||||
def load_binary(self, stream: ResStream):
|
||||
self.zone_goal_point_vectors = [stream.read_dword() for _ in range(6)]
|
||||
self.zone_goal_point_vectors = [stream.read_long() for _ in range(6)]
|
||||
self.zone_goal_point_location = stream.read_tuple()
|
||||
|
||||
def save_binary(self, stream: ResStream):
|
||||
for i in range(6):
|
||||
stream.write_dword(self.zone_goal_point_vectors[i])
|
||||
stream.write_long(self.zone_goal_point_vectors[i])
|
||||
stream.write_tuple(self.zone_goal_point_location)
|
||||
|
||||
def save_json(self):
|
||||
@@ -39,7 +39,7 @@ class ArcZoneGoal:
|
||||
self.zone_goal_type = stream.read_dword()
|
||||
self.zone_goal_value = stream.read_dword()
|
||||
self.zone_goal_name = stream.read_string()
|
||||
self.zone_goal_delay = stream.read_dword()
|
||||
self.zone_goal_delay = stream.read_long()
|
||||
self.zone_goal_has_teleport_registry = stream.read_bool()
|
||||
if self.zone_goal_has_teleport_registry:
|
||||
self.zone_goal_teleport_registry = stream.read_dword()
|
||||
@@ -53,7 +53,7 @@ class ArcZoneGoal:
|
||||
stream.write_dword(self.zone_goal_type)
|
||||
stream.write_dword(self.zone_goal_value)
|
||||
stream.write_string(self.zone_goal_name)
|
||||
stream.write_dword(self.zone_goal_delay)
|
||||
stream.write_long(self.zone_goal_delay)
|
||||
stream.write_bool(self.zone_goal_has_teleport_registry)
|
||||
if self.zone_goal_has_teleport_registry:
|
||||
stream.write_dword(self.zone_goal_teleport_registry)
|
||||
|
||||
@@ -17,16 +17,16 @@ class TerrainObjectInfo:
|
||||
self.terrain_object_id = stream.read_qword()
|
||||
self.terrain_object_h = stream.read_float()
|
||||
self.terrain_object_lacunarity = stream.read_float()
|
||||
self.terrain_object_octaves = stream.read_dword()
|
||||
self.terrain_object_octaves = stream.read_long()
|
||||
self.terrain_object_offset = stream.read_float()
|
||||
self.terrain_object_gain = stream.read_float()
|
||||
self.terrain_object_min_alt = stream.read_float()
|
||||
self.terrain_object_max_alt = stream.read_float()
|
||||
self.terrain_object_min_slope = stream.read_float()
|
||||
self.terrain_object_max_slope = stream.read_float()
|
||||
self.terrain_object_max_pop = stream.read_dword()
|
||||
self.terrain_object_max_pop = stream.read_long()
|
||||
self.terrain_object_is_fractal_pop = stream.read_bool()
|
||||
self.terrain_object_unknown1 = stream.read_dword()
|
||||
self.terrain_object_unknown1 = stream.read_long()
|
||||
self.terrain_object_y_offset = stream.read_float()
|
||||
self.terrain_object_pop_image_id = stream.read_qword()
|
||||
self.terrain_object_image_min_y = stream.read_float()
|
||||
@@ -36,16 +36,16 @@ class TerrainObjectInfo:
|
||||
stream.write_qword(self.terrain_object_id)
|
||||
stream.write_float(self.terrain_object_h)
|
||||
stream.write_float(self.terrain_object_lacunarity)
|
||||
stream.write_dword(self.terrain_object_octaves)
|
||||
stream.write_long(self.terrain_object_octaves)
|
||||
stream.write_float(self.terrain_object_offset)
|
||||
stream.write_float(self.terrain_object_gain)
|
||||
stream.write_float(self.terrain_object_min_alt)
|
||||
stream.write_float(self.terrain_object_max_alt)
|
||||
stream.write_float(self.terrain_object_min_slope)
|
||||
stream.write_float(self.terrain_object_max_slope)
|
||||
stream.write_dword(self.terrain_object_max_pop)
|
||||
stream.write_long(self.terrain_object_max_pop)
|
||||
stream.write_bool(self.terrain_object_is_fractal_pop)
|
||||
stream.write_dword(self.terrain_object_unknown1)
|
||||
stream.write_long(self.terrain_object_unknown1)
|
||||
stream.write_float(self.terrain_object_y_offset)
|
||||
stream.write_qword(self.terrain_object_pop_image_id)
|
||||
stream.write_float(self.terrain_object_image_min_y)
|
||||
|
||||
@@ -22,12 +22,12 @@ class ArcBasicZoneObjectInfo:
|
||||
self.basic_zone_y_rot = stream.read_float()
|
||||
self.basic_zone_template_id = stream.read_qword()
|
||||
self.basic_zone_unknown1 = stream.read_qword()
|
||||
self.basic_zone_level_number = stream.read_dword()
|
||||
self.basic_zone_room_number = stream.read_dword()
|
||||
self.basic_zone_level_number = stream.read_long()
|
||||
self.basic_zone_room_number = stream.read_long()
|
||||
self.basic_zone_unknown2 = stream.read_qword()
|
||||
self.basic_zone_dungeon_level = stream.read_dword()
|
||||
self.basic_zone_dungeon_row = stream.read_dword()
|
||||
self.basic_zone_dungeon_column = stream.read_dword()
|
||||
self.basic_zone_dungeon_level = stream.read_long()
|
||||
self.basic_zone_dungeon_row = stream.read_long()
|
||||
self.basic_zone_dungeon_column = stream.read_long()
|
||||
self.basic_zone_sparse_data = SparseData()
|
||||
self.basic_zone_sparse_data.load_binary(stream)
|
||||
|
||||
@@ -39,12 +39,12 @@ class ArcBasicZoneObjectInfo:
|
||||
stream.write_float(self.basic_zone_y_rot)
|
||||
stream.write_qword(self.basic_zone_template_id)
|
||||
stream.write_qword(self.basic_zone_unknown1)
|
||||
stream.write_dword(self.basic_zone_level_number)
|
||||
stream.write_dword(self.basic_zone_room_number)
|
||||
stream.write_long(self.basic_zone_level_number)
|
||||
stream.write_long(self.basic_zone_room_number)
|
||||
stream.write_qword(self.basic_zone_unknown2)
|
||||
stream.write_dword(self.basic_zone_dungeon_level)
|
||||
stream.write_dword(self.basic_zone_dungeon_row)
|
||||
stream.write_dword(self.basic_zone_dungeon_column)
|
||||
stream.write_long(self.basic_zone_dungeon_level)
|
||||
stream.write_long(self.basic_zone_dungeon_row)
|
||||
stream.write_long(self.basic_zone_dungeon_column)
|
||||
self.basic_zone_sparse_data.save_binary(stream)
|
||||
|
||||
def save_json(self):
|
||||
|
||||
@@ -23,12 +23,12 @@ class MerchantInfo(MobileInfo):
|
||||
num_buy_list = stream.read_dword()
|
||||
self.merchant_buy_list = [[
|
||||
stream.read_qword(),
|
||||
stream.read_dword(),
|
||||
stream.read_long(),
|
||||
] for _ in range(num_buy_list)]
|
||||
num_sell_list = stream.read_dword()
|
||||
self.merchant_sell_list = [[
|
||||
stream.read_qword(),
|
||||
stream.read_dword(),
|
||||
stream.read_long(),
|
||||
] for _ in range(num_sell_list)]
|
||||
|
||||
def save_binary(self, stream: ResStream):
|
||||
@@ -43,11 +43,11 @@ class MerchantInfo(MobileInfo):
|
||||
stream.write_dword(len(self.merchant_buy_list))
|
||||
for l in self.merchant_buy_list:
|
||||
stream.write_qword(l[0])
|
||||
stream.write_dword(l[1])
|
||||
stream.write_long(l[1])
|
||||
stream.write_dword(len(self.merchant_sell_list))
|
||||
for l in self.merchant_sell_list:
|
||||
stream.write_qword(l[0])
|
||||
stream.write_dword(l[1])
|
||||
stream.write_long(l[1])
|
||||
|
||||
def save_json(self):
|
||||
data = super().save_json()
|
||||
|
||||
@@ -22,12 +22,12 @@ 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_number_in_group = stream.read_long()
|
||||
self.mobile_change_to_find = stream.read_float()
|
||||
self.mobile_level = stream.read_dword()
|
||||
self.mobile_level = stream.read_long()
|
||||
self.mobile_behavior_file = stream.read_string()
|
||||
self.mobile_dialog_override = stream.read_dword()
|
||||
self.mobile_base_exp_reward = stream.read_dword()
|
||||
self.mobile_base_exp_reward = stream.read_long()
|
||||
self.mobile_tenacity = stream.read_float()
|
||||
self.mobile_courage = stream.read_float()
|
||||
self.mobile_has_group_tactics = stream.read_bool()
|
||||
@@ -85,12 +85,12 @@ class MobileInfo:
|
||||
|
||||
def save_binary(self, stream: ResStream):
|
||||
self.mobile_base_zone.save_binary(stream)
|
||||
stream.write_dword(self.mobile_number_in_group)
|
||||
stream.write_long(self.mobile_number_in_group)
|
||||
stream.write_float(self.mobile_change_to_find)
|
||||
stream.write_dword(self.mobile_level)
|
||||
stream.write_long(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_long(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)
|
||||
|
||||
@@ -14,7 +14,7 @@ class ShopKeeperInfo(MobileInfo):
|
||||
def load_binary(self, stream: ResStream):
|
||||
super().load_binary(stream)
|
||||
self.shopkeeper_shop_type = stream.read_dword()
|
||||
self.shopkeeper_start_gold = stream.read_dword()
|
||||
self.shopkeeper_start_gold = stream.read_long()
|
||||
self.shopkeeper_std_buy_percent = stream.read_float()
|
||||
self.shopkeeper_std_sell_percent = stream.read_float()
|
||||
self.shopkeeper_nation_buy_percent = stream.read_float()
|
||||
@@ -22,18 +22,18 @@ class ShopKeeperInfo(MobileInfo):
|
||||
num_buy_list = stream.read_dword()
|
||||
self.shopkeeper_buy_list = [[
|
||||
stream.read_qword(),
|
||||
stream.read_dword(),
|
||||
stream.read_long(),
|
||||
] for _ in range(num_buy_list)]
|
||||
num_sell_list = stream.read_dword()
|
||||
self.shopkeeper_sell_list = [[
|
||||
stream.read_qword(),
|
||||
stream.read_dword(),
|
||||
stream.read_long(),
|
||||
] for _ in range(num_sell_list)]
|
||||
|
||||
def save_binary(self, stream: ResStream):
|
||||
super().save_binary(stream)
|
||||
stream.write_dword(self.shopkeeper_shop_type)
|
||||
stream.write_dword(self.shopkeeper_start_gold)
|
||||
stream.write_long(self.shopkeeper_start_gold)
|
||||
stream.write_float(self.shopkeeper_std_buy_percent)
|
||||
stream.write_float(self.shopkeeper_std_sell_percent)
|
||||
stream.write_float(self.shopkeeper_nation_buy_percent)
|
||||
@@ -41,11 +41,11 @@ class ShopKeeperInfo(MobileInfo):
|
||||
stream.write_dword(len(self.shopkeeper_buy_list))
|
||||
for l in self.shopkeeper_buy_list:
|
||||
stream.write_qword(l[0])
|
||||
stream.write_dword(l[1])
|
||||
stream.write_long(l[1])
|
||||
stream.write_dword(len(self.shopkeeper_sell_list))
|
||||
for l in self.shopkeeper_sell_list:
|
||||
stream.write_qword(l[0])
|
||||
stream.write_dword(l[1])
|
||||
stream.write_long(l[1])
|
||||
|
||||
def save_json(self):
|
||||
data = super().save_json()
|
||||
|
||||
Reference in new issue
Block a user