1 #include <cstring>
2 #include "xr_math.h"
3 #include "xr_entity.h"
4 #include "xr_packet.h"
5 
6 using namespace xray_re;
7 
8 const uint8_t UNDEF8 = UINT8_MAX;
9 const uint16_t UNDEF16 = UINT16_MAX;
10 const uint32_t UNDEF32 = UINT32_MAX;
11 
12 ////////////////////////////////////////////////////////////////////////////////
13 
cse_motion()14 cse_motion::cse_motion() {}
15 
~cse_motion()16 cse_motion::~cse_motion() {}
17 
motion_read(xr_packet & packet)18 void cse_motion::motion_read(xr_packet& packet)
19 {
20 	packet.r_sz(m_motion_name);
21 }
22 
motion_write(xr_packet & packet)23 void cse_motion::motion_write(xr_packet& packet)
24 {
25 	packet.w_sz(m_motion_name);
26 }
27 
28 ////////////////////////////////////////////////////////////////////////////////
29 
cse_visual()30 cse_visual::cse_visual(): m_flags(0) {}
31 
~cse_visual()32 cse_visual::~cse_visual() {}
33 
visual_read(xr_packet & packet,uint16_t version)34 void cse_visual::visual_read(xr_packet& packet, uint16_t version)
35 {
36 	packet.r_sz(m_visual_name);
37 	if (version > CSE_VERSION_0x67)
38 		packet.r_u8(m_flags);
39 }
40 
visual_write(xr_packet & packet,uint16_t version)41 void cse_visual::visual_write(xr_packet& packet, uint16_t version)
42 {
43 	packet.w_sz(m_visual_name);
44 	if (version > CSE_VERSION_0x67)
45 		packet.w_u8(m_flags);
46 }
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 
cse_shape()50 cse_shape::cse_shape() {}
51 
~cse_shape()52 cse_shape::~cse_shape() {}
53 
shapes()54 shape_def_vec& cse_shape::shapes() { return m_shapes; }
55 
cform_merge(xr_packet & packet)56 void cse_shape::cform_merge(xr_packet& packet)
57 {
58 	for (uint_fast32_t n = packet.r_u8(); n; --n) {
59 		uint8_t def_type = packet.r_u8();
60 		if (def_type == SHAPE_SPHERE) {
61 			packet.r_advance(sizeof(fvector3));
62 			packet.r_float();
63 		} else if (def_type == SHAPE_BOX) {
64 			packet.r_advance(4*sizeof(fvector3));
65 		} else {
66 			xr_not_expected();
67 		}
68 	}
69 }
70 
cform_read(xr_packet & packet)71 void cse_shape::cform_read(xr_packet& packet)
72 {
73 	m_shapes.clear();
74 	for (uint_fast32_t n = packet.r_u8(); n; --n) {
75 		m_shapes.push_back(shape_def());
76 		shape_def& def = m_shapes.back();
77 		packet.r_u8(def.type);
78 		if (def.type == SHAPE_SPHERE) {
79 			packet.r_vec3(def.sphere.p);
80 			packet.r_float(def.sphere.r);
81 		} else if (def.type == SHAPE_BOX) {
82 			packet.r_matrix(def.box);
83 		} else {
84 			xr_not_expected();
85 		}
86 	}
87 }
88 
cform_write(xr_packet & packet)89 void cse_shape::cform_write(xr_packet& packet)
90 {
91 	packet.w_size_u8(m_shapes.size());
92 	for (shape_def_vec_it it = m_shapes.begin(), end = m_shapes.end(); it != end; ++it) {
93 		packet.w_u8(it->type);
94 		if (it->type == SHAPE_SPHERE) {
95 			packet.w_vec3(it->sphere.p);
96 			packet.w_float(it->sphere.r);
97 		} else if (it->type == SHAPE_BOX) {
98 			packet.w_matrix(it->box);
99 		} else {
100 			xr_not_expected();
101 		}
102 	}
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 
cse_ph_skeleton()107 cse_ph_skeleton::cse_ph_skeleton(): m_flags(0), m_source_id(UNDEF16) {}
108 
~cse_ph_skeleton()109 cse_ph_skeleton::~cse_ph_skeleton() {}
110 
state_read(xr_packet & packet,uint16_t size)111 void cse_ph_skeleton::state_read(xr_packet& packet, uint16_t size)
112 {
113 	packet.r_sz(m_root_bone);
114 	packet.r_u8(m_flags);
115 	packet.r_u16(m_source_id);
116 }
117 
state_write(xr_packet & packet)118 void cse_ph_skeleton::state_write(xr_packet& packet)
119 {
120 	packet.w_sz(m_root_bone);
121 	packet.w_u8(m_flags);
122 	packet.w_u16(m_source_id);
123 }
124 
update_read(xr_packet & packet)125 void cse_ph_skeleton::update_read(xr_packet& packet) {}
update_write(xr_packet & packet)126 void cse_ph_skeleton::update_write(xr_packet& packet) {}
127 
data_load(xr_packet & packet)128 void cse_ph_skeleton::data_load(xr_packet& packet) {}
data_save(xr_packet & packet)129 void cse_ph_skeleton::data_save(xr_packet& packet) {}
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 
cse_abstract()133 cse_abstract::cse_abstract():
134 	m_version(0), m_script_version(0), m_respawn_time(0),
135 	m_id(UNDEF16), m_id_parent(UNDEF16), m_id_phantom(UNDEF16),
136 	m_s_game_id(GAME_ANY), m_s_rp(0xfe), m_s_flags(0),
137 	m_cs_unk1_u16(UNDEF16),
138 	m_spawn_id(UNDEF16)
139 {
140 	m_o_position.set();
141 	m_o_angle.set();
142 }
143 
~cse_abstract()144 cse_abstract::~cse_abstract() {}
shape()145 cse_shape* cse_abstract::shape() { return 0; }
visual()146 cse_visual* cse_abstract::visual() { return 0; }
motion()147 cse_motion* cse_abstract::motion() { return 0; }
base()148 cse_abstract* cse_abstract::base() { return this; }
149 
spawn_merge(xr_packet & packet)150 void cse_abstract::spawn_merge(xr_packet& packet)
151 {
152 	uint16_t dummy16 = 0;
153 	packet.r_begin(dummy16);
154 	xr_assert(dummy16 == M_SPAWN);
155 
156 	packet.skip_sz();
157 	const char* s_name_replace = packet.skip_sz();
158 	xr_assert(m_s_name_replace == s_name_replace);
159 	packet.r_u8();
160 	packet.r_u8();
161 	packet.r_advance(2*sizeof(fvector3));
162 	packet.r_u16();
163 	packet.r_u16();
164 	packet.r_u16();
165 	packet.r_u16();
166 	uint16_t s_flags;
167 	packet.r_u16(s_flags);
168 	uint16_t version = 0;
169 	if (s_flags & FL_SPAWN_DESTROY_ON_SPAWN)
170 		packet.r_u16(version);
171 	if (version > CSE_VERSION_0x78)
172 		packet.r_u16();
173 	uint16_t script_version = 0;
174 	if (version > CSE_VERSION_0x45)
175 		packet.r_u16(script_version);
176 	if (version > CSE_VERSION_0x46) {
177 		size_t n = (version > CSE_VERSION_0x5d) ? packet.r_u16() : packet.r_u8();
178 		xr_assert(n == 0);
179 	}
180 	if (version > CSE_VERSION_0x4f)
181 		packet.r_u16(m_spawn_id);
182 	if (version < CSE_VERSION_0x70) {
183 		if (version > CSE_VERSION_0x52)
184 			packet.r_float();
185 		if (version > CSE_VERSION_0x53) {
186 			packet.r_u32();
187 			packet.skip_sz();
188 			packet.r_u32();
189 			packet.r_u32();
190 			packet.r_u64();
191 		}
192 		if (version > CSE_VERSION_0x54) {
193 			packet.r_u64();
194 			packet.r_u64();
195 		}
196 	}
197 
198 	uint16_t size = packet.r_u16();
199 	xr_assert(size > 2);
200 	state_merge(packet, version);
201 }
202 
spawn_read(xr_packet & packet)203 void cse_abstract::spawn_read(xr_packet& packet)
204 {
205 	uint16_t dummy16 = 0;
206 	packet.r_begin(dummy16);
207 	xr_assert(dummy16 == M_SPAWN);
208 
209 	packet.r_sz(m_s_name);
210 	packet.r_sz(m_s_name_replace);
211 	packet.r_u8(m_s_game_id);
212 	packet.r_u8(m_s_rp);
213 	packet.r_vec3(m_o_position);
214 	packet.r_vec3(m_o_angle);
215 	packet.r_u16(m_respawn_time);
216 	packet.r_u16(m_id);
217 	packet.r_u16(m_id_parent);
218 	packet.r_u16(m_id_phantom);
219 	packet.r_u16(m_s_flags);
220 	if (m_s_flags & FL_SPAWN_DESTROY_ON_SPAWN)
221 		packet.r_u16(m_version);
222 	if (m_version > CSE_VERSION_0x78)
223 		packet.r_u16(m_cs_unk1_u16);
224 	else
225 		m_cs_unk1_u16 = UNDEF16;
226 	if (m_version > CSE_VERSION_0x45)
227 		packet.r_u16(m_script_version);
228 	if (m_version > CSE_VERSION_0x46) {
229 		size_t n = (m_version > CSE_VERSION_0x5d) ? packet.r_u16() : packet.r_u8();
230 		xr_assert(n == 0);
231 	}
232 	if (m_version > CSE_VERSION_0x4f)
233 		packet.r_u16(m_spawn_id);
234 	if (m_version < CSE_VERSION_0x70) {
235 		if (m_version > CSE_VERSION_0x52)
236 			packet.r_float();
237 		if (m_version > CSE_VERSION_0x53) {
238 			packet.r_u32();
239 			packet.skip_sz();
240 			packet.r_u32();
241 			packet.r_u32();
242 			packet.r_u64();
243 		}
244 		if (m_version > CSE_VERSION_0x54) {
245 			packet.r_u64();
246 			packet.r_u64();
247 		}
248 	}
249 	uint16_t size = packet.r_u16();
250 	xr_assert(size > 2);
251 	state_read(packet, size);
252 }
253 
spawn_write(xr_packet & packet,bool local)254 void cse_abstract::spawn_write(xr_packet& packet, bool local)
255 {
256 	packet.w_begin(M_SPAWN);
257 	packet.w_sz(m_s_name);
258 	packet.w_sz(m_s_name_replace);
259 	packet.w_u8(m_s_game_id);
260 	packet.w_u8(m_s_rp);
261 	packet.w_vec3(m_o_position);
262 	packet.w_vec3(m_o_angle);
263 	packet.w_u16(m_respawn_time);
264 	packet.w_u16(m_id);
265 	packet.w_u16(m_id_parent);
266 	packet.w_u16(m_id_phantom);
267 	m_s_flags |= FL_SPAWN_DESTROY_ON_SPAWN;
268 	if (local)
269 		m_s_flags |= FL_SPAWN_ENABLED;
270 	else
271 		m_s_flags &= ~(FL_SPAWN_ENABLED|FL_SPAWN_IF_DESTROYED_ONLY);
272 	packet.w_u16(m_s_flags);
273 	packet.w_u16(m_version);
274 	if (m_version > CSE_VERSION_0x78)
275 		packet.w_u16(m_cs_unk1_u16);
276 	packet.w_u16(m_script_version);
277 	packet.w_u16(0);
278 	packet.w_u16(m_spawn_id);
279 	if (m_version < CSE_VERSION_0x70) {
280 		packet.w_float(1.f);		// m_spawn_probability
281 		packet.w_u32(0x1f);		// m_spawn_flags
282 		packet.w_sz("");		// m_spawn_control
283 		packet.w_u32(1);		// m_max_spawn_count
284 		packet.w_u32(0);		// m_spawn_count
285 		packet.w_u64(0);		// m_last_spawn_time
286 		packet.w_u64(0);		// m_min_spawn_interval
287 		packet.w_u64(0);		// m_max_spawn_interval
288 	}
289 	size_t pos = packet.w_tell();
290 	packet.w_u16(0);
291 	state_write(packet);
292 	size_t size = packet.w_tell() - pos;
293 	xr_assert(size > 2);
294 	packet.w_seek(pos);
295 	packet.w_size_u16(size);
296 	packet.w_seek(pos + size);
297 }
298 
sm_record(const char * _name,size_t _offset)299 inline cse_abstract::sm_record::sm_record(const char* _name, size_t _offset):
300 	name(_name), offset(_offset) {}
301 
set_save_marker(xr_packet & packet,esm_mode mode,bool check,const char * name)302 void cse_abstract::set_save_marker(xr_packet& packet, esm_mode mode, bool check, const char* name)
303 {
304 	if (m_version < CSE_VERSION_0x7c_HACK)
305 		return;
306 
307 	if (check) {
308 		const sm_record& sm = m_markers.top();
309 		if (std::strcmp(name, sm.name))
310 			xr_not_expected();
311 		if (mode == SM_SAVE) {
312 			size_t diff = packet.w_tell() - sm.offset;
313 			packet.w_u16(uint16_t(diff & UINT16_MAX));
314 		} else {
315 			size_t diff = packet.r_tell() - sm.offset;
316 			if (diff != packet.r_u16())
317 				xr_not_expected();
318 		}
319 		m_markers.pop();
320 	} else {
321 		m_markers.push(sm_record(name,
322 				mode == SM_SAVE ? packet.w_tell() : packet.r_tell()));
323 	}
324 }
325 
326 ////////////////////////////////////////////////////////////////////////////////
327 
cse_alife_graph_point()328 cse_alife_graph_point::cse_alife_graph_point()
329 {
330 	std::memset(m_locations, 0, sizeof(m_locations));
331 }
332 
state_merge(xr_packet & packet,uint16_t version)333 void cse_alife_graph_point::state_merge(xr_packet& packet, uint16_t version) {}
334 
state_read(xr_packet & packet,uint16_t size)335 void cse_alife_graph_point::state_read(xr_packet& packet, uint16_t size)
336 {
337 	packet.r_sz(m_connection_point_name);
338 	if (m_version >= CSE_VERSION_0x21)
339 		packet.r_sz(m_connection_level_name);
340 	else
341 		packet.r_s32();
342 	packet.r_cseq(4, m_locations);
343 }
344 
state_write(xr_packet & packet)345 void cse_alife_graph_point::state_write(xr_packet& packet)
346 {
347 	packet.w_sz(m_connection_point_name);
348 	packet.w_sz(m_connection_level_name);
349 	packet.w_cseq(4, m_locations);
350 }
351 
update_read(xr_packet & packet)352 void cse_alife_graph_point::update_read(xr_packet& packet) {}
353 
update_write(xr_packet & packet)354 void cse_alife_graph_point::update_write(xr_packet& packet) {}
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 
cse_alife_object()358 cse_alife_object::cse_alife_object():
359 	m_graph_id(UNDEF16), m_distance(0), m_direct_control(false),
360 	m_node_id(UNDEF32), m_flags(UNDEF32),
361 	m_story_id(UNDEF32), m_spawn_story_id(UNDEF32) {}
362 
state_merge(xr_packet & packet,uint16_t version)363 void cse_alife_object::state_merge(xr_packet& packet, uint16_t version)
364 {
365 	if (version >= CSE_VERSION_0x01) {
366 		if (version <= CSE_VERSION_0x18)
367 			packet.r_s8();
368 		else if (version < CSE_VERSION_0x53)
369 			packet.r_float();
370 		if (version < CSE_VERSION_0x53)
371 			packet.r_s32();
372 		if (version < CSE_VERSION_0x04)
373 			packet.r_u16();
374 		packet.r_u16(m_graph_id);
375 		packet.r_float(m_distance);
376 	}
377 	if (version >= CSE_VERSION_0x04)
378 		packet.r_u32();
379 	if (version >= CSE_VERSION_0x08)
380 		packet.r_u32(m_node_id);
381 	if (version > CSE_VERSION_0x16 && version <= CSE_VERSION_0x4f)
382 		packet.r_u16();
383 	if (version > CSE_VERSION_0x17 && version < CSE_VERSION_0x54)
384 		packet.skip_sz();
385 	if (version > CSE_VERSION_0x31)
386 		packet.r_u32();
387 	if (version > CSE_VERSION_0x39)
388 		packet.skip_sz();
389 	if (version > CSE_VERSION_0x3d)
390 		packet.r_u32();
391 	if (version > CSE_VERSION_0x6f)
392 		packet.r_u32();
393 }
394 
state_read(xr_packet & packet,uint16_t size)395 void cse_alife_object::state_read(xr_packet& packet, uint16_t size)
396 {
397 	if (m_version >= CSE_VERSION_0x01) {
398 		if (m_version <= CSE_VERSION_0x18)
399 			packet.r_s8();
400 		else if (m_version < CSE_VERSION_0x53)
401 			packet.r_float();
402 		if (m_version < CSE_VERSION_0x53)
403 			packet.r_s32();
404 		if (m_version < CSE_VERSION_0x04)
405 			packet.r_u16();
406 		packet.r_u16(m_graph_id);
407 		packet.r_float(m_distance);
408 	}
409 	if (m_version >= CSE_VERSION_0x04)
410 		m_direct_control = (packet.r_u32() & 1) != 0;
411 	if (m_version >= CSE_VERSION_0x08)
412 		packet.r_u32(m_node_id);
413 	if (m_version > CSE_VERSION_0x16 && m_version <= CSE_VERSION_0x4f)
414 		packet.r_u16(m_spawn_id);
415 	if (m_version > CSE_VERSION_0x17 && m_version < CSE_VERSION_0x54)
416 		packet.skip_sz();
417 	if (m_version > CSE_VERSION_0x31)
418 		packet.r_u32(m_flags);
419 	if (m_version > CSE_VERSION_0x39)
420 		packet.r_sz(m_ini_string);
421 	if (m_version > CSE_VERSION_0x3d)
422 		packet.r_u32(m_story_id);
423 	if (m_version > CSE_VERSION_0x6f)
424 		packet.r_u32(m_spawn_story_id);
425 }
426 
state_write(xr_packet & packet)427 void cse_alife_object::state_write(xr_packet& packet)
428 {
429 	packet.w_u16(m_graph_id);
430 	packet.w_float(m_distance);
431 	packet.w_u32(m_direct_control ? 1 : 0);
432 	packet.w_u32(m_node_id);
433 	packet.w_u32(m_flags);
434 	packet.w_sz(m_ini_string);
435 	packet.w_u32(m_story_id);
436 	if (m_version > CSE_VERSION_0x6f)
437 		packet.w_u32(m_spawn_story_id);
438 }
439 
update_read(xr_packet & packet)440 void cse_alife_object::update_read(xr_packet& packet) {}
441 
update_write(xr_packet & packet)442 void cse_alife_object::update_write(xr_packet& packet) {}
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 
state_merge(xr_packet & packet,uint16_t version)446 void cse_alife_dynamic_object::state_merge(xr_packet& packet, uint16_t version)
447 {
448 	cse_alife_object::state_merge(packet, version);
449 }
450 
state_read(xr_packet & packet,uint16_t size)451 void cse_alife_dynamic_object::state_read(xr_packet& packet, uint16_t size)
452 {
453 	cse_alife_object::state_read(packet, size);
454 }
455 
state_write(xr_packet & packet)456 void cse_alife_dynamic_object::state_write(xr_packet& packet)
457 {
458 	cse_alife_object::state_write(packet);
459 }
460 
update_read(xr_packet & packet)461 void cse_alife_dynamic_object::update_read(xr_packet& packet) {}
462 
update_write(xr_packet & packet)463 void cse_alife_dynamic_object::update_write(xr_packet& packet) {}
464 
465 ////////////////////////////////////////////////////////////////////////////////
466 
state_read(xr_packet & packet,uint16_t size)467 void cse_alife_dynamic_object_visual::state_read(xr_packet& packet, uint16_t size)
468 {
469 	cse_alife_dynamic_object::state_read(packet, size);
470 	if (m_version > CSE_VERSION_0x1f)
471 		cse_visual::visual_read(packet, m_version);
472 }
473 
state_write(xr_packet & packet)474 void cse_alife_dynamic_object_visual::state_write(xr_packet& packet)
475 {
476 	cse_alife_dynamic_object::state_write(packet);
477 	cse_visual::visual_write(packet, m_version);
478 }
479 
update_read(xr_packet & packet)480 void cse_alife_dynamic_object_visual::update_read(xr_packet& packet) {}
481 
update_write(xr_packet & packet)482 void cse_alife_dynamic_object_visual::update_write(xr_packet& packet) {}
483 
visual()484 cse_visual* cse_alife_dynamic_object_visual::visual()
485 {
486 	return static_cast<cse_visual*>(this);
487 }
488 
489 ////////////////////////////////////////////////////////////////////////////////
490 
cse_alife_object_climable()491 cse_alife_object_climable::cse_alife_object_climable(): m_flags(0), m_game_material("materials\\fake_ladders") {}
492 
state_read(xr_packet & packet,uint16_t size)493 void cse_alife_object_climable::state_read(xr_packet& packet, uint16_t size)
494 {
495 	if (m_version > CSE_VERSION_0x63)
496 		cse_alife_dynamic_object::state_read(packet, size);
497 	cse_shape::cform_read(packet);
498 
499 	if (m_version >= CSE_VERSION_0x80)
500 		packet.r_sz(m_game_material);
501 }
502 
state_write(xr_packet & packet)503 void cse_alife_object_climable::state_write(xr_packet& packet)
504 {
505 	cse_alife_dynamic_object::state_write(packet);
506 	cse_shape::cform_write(packet);
507 
508 	if (m_version >= CSE_VERSION_0x80)
509 		packet.w_sz(m_game_material);
510 }
511 
update_read(xr_packet & packet)512 void cse_alife_object_climable::update_read(xr_packet& packet) {}
513 
update_write(xr_packet & packet)514 void cse_alife_object_climable::update_write(xr_packet& packet) {}
515 
shape()516 cse_shape* cse_alife_object_climable::shape()
517 {
518 	return static_cast<cse_shape*>(this);
519 }
520 
521 ////////////////////////////////////////////////////////////////////////////////
522 
cse_smart_cover()523 cse_smart_cover::cse_smart_cover():
524 	m_cs_unk1_sz(""), m_cs_unk2_float(0.f),
525 	m_enter_min_enemy_distance(15.f), m_exit_min_enemy_distance(10.f),
526 	m_is_combat_cover(true), m_cs_unk3_u8(0) {}
527 
state_read(xr_packet & packet,uint16_t size)528 void cse_smart_cover::state_read(xr_packet& packet, uint16_t size)
529 {
530 	cse_alife_dynamic_object::state_read(packet, size);
531 	cse_shape::cform_read(packet);
532 	packet.r_sz(m_cs_unk1_sz);
533 	packet.r_float(m_cs_unk2_float);
534 	if (m_version >= CSE_VERSION_0x78) {
535 		packet.r_float(m_enter_min_enemy_distance);
536 		packet.r_float(m_exit_min_enemy_distance);
537 	}
538 	if (m_version >= CSE_VERSION_0x7a)
539 		packet.r_bool(m_is_combat_cover);
540 	if (m_version >= CSE_VERSION_0x80)
541 		packet.r_u8(m_cs_unk3_u8);
542 }
543 
state_write(xr_packet & packet)544 void cse_smart_cover::state_write(xr_packet& packet)
545 {
546 	cse_alife_dynamic_object::state_write(packet);
547 	cse_shape::cform_write(packet);
548 	packet.w_sz(m_cs_unk1_sz);
549 	packet.w_float(m_cs_unk2_float);
550 	if (m_version >= CSE_VERSION_0x78) {
551 		packet.w_float(m_enter_min_enemy_distance);
552 		packet.w_float(m_exit_min_enemy_distance);
553 	}
554 	if (m_version >= CSE_VERSION_0x7a)
555 		packet.w_bool(m_is_combat_cover);
556 	if (m_version >= CSE_VERSION_0x80)
557 		packet.w_u8(m_cs_unk3_u8);
558 }
559 
update_read(xr_packet & packet)560 void cse_smart_cover::update_read(xr_packet& packet) {}
561 
update_write(xr_packet & packet)562 void cse_smart_cover::update_write(xr_packet& packet) {}
563 
shape()564 cse_shape* cse_smart_cover::shape() { return static_cast<cse_shape*>(this); }
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 
cse_alife_object_physic()568 cse_alife_object_physic::cse_alife_object_physic(): m_type(0), m_mass(10.f),
569 	m_num_items(0) {}
570 
state_read(xr_packet & packet,uint16_t size)571 void cse_alife_object_physic::state_read(xr_packet& packet, uint16_t size)
572 {
573 	if (m_version >= CSE_VERSION_0x0e) {
574 		if (m_version < CSE_VERSION_0x10)
575 			cse_alife_dynamic_object::state_read(packet, size);
576 		else
577 			cse_alife_dynamic_object_visual::state_read(packet, size);
578 		if (m_version < CSE_VERSION_0x20)
579 			cse_visual::visual_read(packet, m_version);
580 	}
581 	if (m_version >= CSE_VERSION_0x40)
582 		cse_ph_skeleton::state_read(packet, size);
583 	packet.r_u32(m_type);
584 	packet.r_float(m_mass);
585 	if (m_version > CSE_VERSION_0x09)
586 		packet.r_sz(m_fixed_bones);
587 	if (m_version > CSE_VERSION_0x1c && m_version < CSE_VERSION_0x41)
588 		packet.r_sz(cse_visual::m_startup_animation);
589 	if (m_version < CSE_VERSION_0x40) {
590 		if (m_version > CSE_VERSION_0x27)
591 			packet.r_u8(cse_ph_skeleton::m_flags);
592 		if (m_version > CSE_VERSION_0x38)
593 			packet.r_u16(cse_ph_skeleton::m_source_id);
594 		if ((m_version > CSE_VERSION_0x3c) && (cse_ph_skeleton::m_flags & FL_SAVED_DATA) != 0)
595 			data_load(packet);
596 	}
597 }
598 
state_write(xr_packet & packet)599 void cse_alife_object_physic::state_write(xr_packet& packet)
600 {
601 	cse_alife_dynamic_object_visual::state_write(packet);
602 	cse_ph_skeleton::state_write(packet);
603 	packet.w_u32(m_type);
604 	packet.w_float(m_mass);
605 	packet.w_sz(m_fixed_bones);
606 }
607 
update_read(xr_packet & packet)608 void cse_alife_object_physic::update_read(xr_packet& packet)
609 {
610 	cse_ph_skeleton::update_read(packet);
611 	if (!packet.r_eof()) {
612 		xr_assert(m_version >= CSE_VERSION_0x7a && m_version <= CSE_VERSION_COP);
613 		packet.r_u8(m_num_items);
614 		if (m_num_items) {
615 			packet.r_vec3(m_state.force);
616 			packet.r_vec3(m_state.torque);
617 			packet.r_vec3(m_state.position);
618 			packet.r_float(m_state.quaternion.x);
619 			packet.r_float(m_state.quaternion.y);
620 			packet.r_float(m_state.quaternion.z);
621 			packet.r_float(m_state.quaternion.w);
622 			uint_fast16_t flags = m_num_items >> 5;
623 			m_state.enabled = (flags & 1) != 0;
624 			if (flags & 0x2)
625 				m_state.angular_vel.set(0, 0, 0);
626 			else
627 				packet.r_vec3(m_state.angular_vel);
628 			if (flags & 0x4)
629 				m_state.linear_vel.set(0, 0, 0);
630 			else
631 				packet.r_vec3(m_state.linear_vel);
632 			if (!packet.r_eof())
633 				packet.r_bool();
634 		}
635 	}
636 }
637 
update_write(xr_packet & packet)638 void cse_alife_object_physic::update_write(xr_packet& packet)
639 {
640 	cse_ph_skeleton::update_write(packet);
641 	if (m_version >= CSE_VERSION_0x7a) {
642 		xr_assert(m_version <= CSE_VERSION_COP);
643 		if (m_num_items) {
644 			uint8_t num_items = uint8_t(m_num_items & 0x1f);
645 			if (m_state.enabled)
646 				num_items |= 0x20;
647 			if (m_state.angular_vel.square_magnitude() < 1e-7f)
648 				num_items |= 0x40;
649 			if (m_state.linear_vel.square_magnitude() < 1e-7f)
650 				num_items |= 0x80;
651 			packet.w_u8(num_items);
652 			packet.w_vec3(m_state.force);
653 			packet.w_vec3(m_state.torque);
654 			packet.w_vec3(m_state.position);
655 			packet.w_float(m_state.quaternion.x);
656 			packet.w_float(m_state.quaternion.y);
657 			packet.w_float(m_state.quaternion.z);
658 			packet.w_float(m_state.quaternion.w);
659 			if ((num_items & 0x40) == 0)
660 				packet.w_vec3(m_state.angular_vel);
661 			if ((num_items & 0x80) == 0)
662 				packet.w_vec3(m_state.linear_vel);
663 			packet.w_bool(true);
664 		} else {
665 			packet.w_u8(0);
666 		}
667 	}
668 }
669 
670 ////////////////////////////////////////////////////////////////////////////////
671 
cse_alife_object_hanging_lamp()672 cse_alife_object_hanging_lamp::cse_alife_object_hanging_lamp(): m_flags(0),
673 	m_cs_unk1_float(1.f), m_cs_unk2_float(1.f), m_cs_unk3_float(1.f) {}
674 
state_read(xr_packet & packet,uint16_t size)675 void cse_alife_object_hanging_lamp::state_read(xr_packet& packet, uint16_t size)
676 {
677 	if (m_version > CSE_VERSION_0x14)
678 		cse_alife_dynamic_object_visual::state_read(packet, size);
679 	if (m_version >= CSE_VERSION_0x45)
680 		cse_ph_skeleton::state_read(packet, size);
681 	if (m_version < CSE_VERSION_0x20)
682 		cse_visual::visual_read(packet, m_version);
683 	if (m_version < CSE_VERSION_0x31) {
684 		packet.r_u32(m_color);
685 		packet.r_sz(m_color_animator);
686 		packet.skip_sz();
687 		packet.skip_sz();
688 		packet.r_float(m_range);
689 		packet.r_angle8();			// FIXME mb
690 		if (m_version > CSE_VERSION_0x0a)
691 			packet.r_float(m_brightness);
692 		if (m_version > CSE_VERSION_0x0b)
693 			packet.r_u16(m_flags);
694 		if (m_version > CSE_VERSION_0x0c)
695 			packet.r_u32();
696 		if (m_version > CSE_VERSION_0x11)
697 			packet.r_sz(cse_visual::m_startup_animation);
698 		if (m_version > CSE_VERSION_0x2a) {
699 			packet.skip_sz();
700 			packet.r_u32();
701 		}
702 		if (m_version > CSE_VERSION_0x2b)
703 			packet.r_sz(m_fixed_bones);
704 		if (m_version > CSE_VERSION_0x2c)
705 			packet.r_float(m_health);
706 	} else {
707 		packet.r_u32(m_color);
708 		packet.r_float(m_brightness);
709 		packet.r_sz(m_color_animator);
710 		packet.r_float(m_range);
711 		packet.r_u16(m_flags);
712 		packet.r_sz(cse_visual::m_startup_animation);
713 		packet.r_sz(m_fixed_bones);
714 		packet.r_float(m_health);
715 	}
716 	if (m_version > CSE_VERSION_0x37) {
717 		packet.r_float(m_virtual_size);
718 		packet.r_float(m_ambient_radius);
719 		packet.r_float(m_ambient_power);
720 		packet.r_sz(m_ambient_texture);
721 		packet.r_sz(m_light_texture);
722 		packet.r_sz(m_light_main_bone);
723 		packet.r_float(m_spot_cone_angle);
724 		packet.r_sz(m_glow_texture);
725 		packet.r_float(m_glow_radius);
726 	}
727 	if (m_version > CSE_VERSION_0x60)
728 		packet.r_sz(m_light_ambient_bone);
729 	if (m_version > CSE_VERSION_0x76) {
730 		packet.r_float(m_cs_unk1_float);
731 		packet.r_float(m_cs_unk2_float);
732 		packet.r_float(m_cs_unk3_float);
733 	}
734 }
735 
state_write(xr_packet & packet)736 void cse_alife_object_hanging_lamp::state_write(xr_packet& packet)
737 {
738 	cse_alife_dynamic_object_visual::state_write(packet);
739 	cse_ph_skeleton::state_write(packet);
740 	packet.w_u32(m_color);
741 	packet.w_float(m_brightness);
742 	packet.w_sz(m_color_animator);
743 	packet.w_float(m_range);
744 	packet.w_u16(m_flags);
745 	packet.w_sz(cse_visual::m_startup_animation);
746 	packet.w_sz(m_fixed_bones);
747 	packet.w_float(m_health);
748 	packet.w_float(m_virtual_size);
749 	packet.w_float(m_ambient_radius);
750 	packet.w_float(m_ambient_power);
751 	packet.w_sz(m_ambient_texture);
752 	packet.w_sz(m_light_texture);
753 	packet.w_sz(m_light_main_bone);
754 	packet.w_float(m_spot_cone_angle);
755 	packet.w_sz(m_glow_texture);
756 	packet.w_float(m_glow_radius);
757 	packet.w_sz(m_light_ambient_bone);
758 	if (m_version > CSE_VERSION_0x76) {
759 		packet.w_float(m_cs_unk1_float);
760 		packet.w_float(m_cs_unk2_float);
761 		packet.w_float(m_cs_unk3_float);
762 	}
763 }
764 
update_read(xr_packet & packet)765 void cse_alife_object_hanging_lamp::update_read(xr_packet& packet)
766 {
767 	cse_ph_skeleton::update_read(packet);
768 }
769 
update_write(xr_packet & packet)770 void cse_alife_object_hanging_lamp::update_write(xr_packet& packet)
771 {
772 	cse_ph_skeleton::update_write(packet);
773 }
774 
775 ////////////////////////////////////////////////////////////////////////////////
776 
state_read(xr_packet & packet,uint16_t size)777 void cse_alife_object_projector::state_read(xr_packet& packet, uint16_t size)
778 {
779 	cse_alife_dynamic_object_visual::state_read(packet, size);
780 }
781 
state_write(xr_packet & packet)782 void cse_alife_object_projector::state_write(xr_packet& packet)
783 {
784 	cse_alife_dynamic_object_visual::state_write(packet);
785 }
786 
update_read(xr_packet & packet)787 void cse_alife_object_projector::update_read(xr_packet& packet) {}
788 
update_write(xr_packet & packet)789 void cse_alife_object_projector::update_write(xr_packet& packet) {}
790 
791 ////////////////////////////////////////////////////////////////////////////////
792 
cse_inventory_box()793 cse_inventory_box::cse_inventory_box():cse_alive_inventory_box__unk1_u8(1), cse_alive_inventory_box__unk2_u8(0), tip(""){};
794 
state_read(xr_packet & packet,uint16_t size)795 void cse_inventory_box::state_read(xr_packet& packet, uint16_t size)
796 {
797 	cse_alife_dynamic_object_visual::state_read(packet, size);
798 }
799 
state_write(xr_packet & packet)800 void cse_inventory_box::state_write(xr_packet& packet)
801 {
802 	cse_alife_dynamic_object_visual::state_write(packet);
803 }
804 
update_read(xr_packet & packet)805 void cse_inventory_box::update_read(xr_packet& packet)
806 {
807 	cse_alife_dynamic_object_visual::update_read(packet);
808 }
809 
update_write(xr_packet & packet)810 void cse_inventory_box::update_write(xr_packet& packet)
811 {
812 	cse_alife_dynamic_object_visual::update_write(packet);
813 }
814 
815 ////////////////////////////////////////////////////////////////////////////////
816 
cse_alife_object_breakable()817 cse_alife_object_breakable::cse_alife_object_breakable(): m_health(1.f) {}
818 
state_read(xr_packet & packet,uint16_t size)819 void cse_alife_object_breakable::state_read(xr_packet& packet, uint16_t size)
820 {
821 	cse_alife_dynamic_object_visual::state_read(packet, size);
822 	packet.r_float(m_health);
823 }
824 
state_write(xr_packet & packet)825 void cse_alife_object_breakable::state_write(xr_packet& packet)
826 {
827 	cse_alife_dynamic_object_visual::state_write(packet);
828 	packet.w_float(m_health);
829 }
830 
update_read(xr_packet & packet)831 void cse_alife_object_breakable::update_read(xr_packet& packet) {}
832 
update_write(xr_packet & packet)833 void cse_alife_object_breakable::update_write(xr_packet& packet) {}
834 
835 ////////////////////////////////////////////////////////////////////////////////
836 
state_read(xr_packet & packet,uint16_t size)837 void cse_alife_mounted_weapon::state_read(xr_packet& packet, uint16_t size)
838 {
839 	cse_alife_dynamic_object_visual::state_read(packet, size);
840 }
841 
state_write(xr_packet & packet)842 void cse_alife_mounted_weapon::state_write(xr_packet& packet)
843 {
844 	cse_alife_dynamic_object_visual::state_write(packet);
845 }
846 
update_read(xr_packet & packet)847 void cse_alife_mounted_weapon::update_read(xr_packet& packet) {}
848 
update_write(xr_packet & packet)849 void cse_alife_mounted_weapon::update_write(xr_packet& packet) {}
850 
851 ////////////////////////////////////////////////////////////////////////////////
852 
cse_alife_stationary_mgun()853 cse_alife_stationary_mgun::cse_alife_stationary_mgun(): m_working(false)
854 {
855 	m_dest_enemy_dir.set();
856 }
857 
state_read(xr_packet & packet,uint16_t size)858 void cse_alife_stationary_mgun::state_read(xr_packet& packet, uint16_t size)
859 {
860 	cse_alife_dynamic_object_visual::state_read(packet, size);
861 }
862 
state_write(xr_packet & packet)863 void cse_alife_stationary_mgun::state_write(xr_packet& packet)
864 {
865 	cse_alife_dynamic_object_visual::state_write(packet);
866 }
867 
update_read(xr_packet & packet)868 void cse_alife_stationary_mgun::update_read(xr_packet& packet)
869 {
870 	packet.r_bool(m_working);
871 	packet.r_vec3(m_dest_enemy_dir);
872 }
873 
update_write(xr_packet & packet)874 void cse_alife_stationary_mgun::update_write(xr_packet& packet)
875 {
876 	packet.w_bool(m_working);
877 	packet.w_vec3(m_dest_enemy_dir);
878 }
879 
880 ////////////////////////////////////////////////////////////////////////////////
881 
state_read(xr_packet & packet,uint16_t size)882 void cse_alife_ph_skeleton_object::state_read(xr_packet& packet, uint16_t size)
883 {
884 	cse_alife_dynamic_object_visual::state_read(packet, size);
885 	if (m_version >= CSE_VERSION_0x40)
886 		cse_ph_skeleton::state_read(packet, size);
887 }
888 
state_write(xr_packet & packet)889 void cse_alife_ph_skeleton_object::state_write(xr_packet& packet)
890 {
891 	cse_alife_dynamic_object_visual::state_write(packet);
892 	cse_ph_skeleton::state_write(packet);
893 }
894 
update_read(xr_packet & packet)895 void cse_alife_ph_skeleton_object::update_read(xr_packet& packet)
896 {
897 	cse_ph_skeleton::update_read(packet);
898 }
899 
update_write(xr_packet & packet)900 void cse_alife_ph_skeleton_object::update_write(xr_packet& packet)
901 {
902 	cse_ph_skeleton::update_write(packet);
903 }
904 
905 ////////////////////////////////////////////////////////////////////////////////
906 
cse_alife_car()907 cse_alife_car::cse_alife_car(): m_health(1.f) {}
908 
state_read(xr_packet & packet,uint16_t size)909 void cse_alife_car::state_read(xr_packet& packet, uint16_t size)
910 {
911 	cse_alife_dynamic_object_visual::state_read(packet, size);
912 	if (m_version > CSE_VERSION_0x41)
913 		cse_ph_skeleton::state_read(packet, size);
914 	if (m_version > CSE_VERSION_0x34 && m_version < CSE_VERSION_0x37)
915 		packet.r_float();
916 	if (m_version > CSE_VERSION_0x5c)
917 		packet.r_float(m_health);
918 	if (m_health > 1.f)
919 		m_health *= 0.01f;
920 }
921 
state_write(xr_packet & packet)922 void cse_alife_car::state_write(xr_packet& packet)
923 {
924 	cse_alife_dynamic_object_visual::state_write(packet);
925 	cse_ph_skeleton::state_write(packet);
926 	packet.w_float(m_health);
927 }
928 
update_read(xr_packet & packet)929 void cse_alife_car::update_read(xr_packet& packet)
930 {
931 	cse_ph_skeleton::update_read(packet);
932 }
933 
update_write(xr_packet & packet)934 void cse_alife_car::update_write(xr_packet& packet)
935 {
936 	cse_ph_skeleton::update_write(packet);
937 }
938 
939 ////////////////////////////////////////////////////////////////////////////////
940 
state_read(xr_packet & packet,uint16_t size)941 void cse_alife_helicopter::state_read(xr_packet& packet, uint16_t size)
942 {
943 	cse_alife_dynamic_object_visual::state_read(packet, size);
944 	cse_motion::motion_read(packet);
945 	if (m_version >= CSE_VERSION_0x45)
946 		cse_ph_skeleton::state_read(packet, size);
947 	packet.r_sz(cse_visual::m_startup_animation);
948 	packet.r_sz(m_engine_sound);
949 }
950 
state_write(xr_packet & packet)951 void cse_alife_helicopter::state_write(xr_packet& packet)
952 {
953 	cse_alife_dynamic_object_visual::state_write(packet);
954 	cse_motion::motion_write(packet);
955 	cse_ph_skeleton::state_write(packet);
956 	packet.w_sz(cse_visual::m_startup_animation);
957 	packet.w_sz(m_engine_sound);
958 }
959 
update_read(xr_packet & packet)960 void cse_alife_helicopter::update_read(xr_packet& packet)
961 {
962 	cse_ph_skeleton::update_read(packet);
963 }
964 
update_write(xr_packet & packet)965 void cse_alife_helicopter::update_write(xr_packet& packet)
966 {
967 	cse_ph_skeleton::update_write(packet);
968 }
969 
motion()970 cse_motion* cse_alife_helicopter::motion()
971 {
972 	return static_cast<cse_motion*>(this);
973 }
974 
975 ////////////////////////////////////////////////////////////////////////////////
976 
cse_alife_creature_abstract()977 cse_alife_creature_abstract::cse_alife_creature_abstract():
978 	m_s_team(0), m_s_squad(0), m_s_group(0),
979 	m_health(1.f), m_timestamp(0),
980 	m_flags(0), m_o_model(0), m_killer_id(UNDEF16)
981 {
982 	m_o_torso.yaw = 0;
983 	m_o_torso.pitch = 0;
984 	m_o_torso.roll = 0;
985 }
986 
state_read(xr_packet & packet,uint16_t size)987 void cse_alife_creature_abstract::state_read(xr_packet& packet, uint16_t size)
988 {
989 	cse_alife_dynamic_object_visual::state_read(packet, size);
990 	packet.r_u8(m_s_team);
991 	packet.r_u8(m_s_squad);
992 	packet.r_u8(m_s_group);
993 	if (m_version > CSE_VERSION_0x12)
994 		packet.r_float(m_health);
995 	if (m_version < CSE_VERSION_0x73)
996 		m_health *= 0.01f;
997 	if (m_version < CSE_VERSION_0x20)
998 		cse_visual::visual_read(packet, m_version);
999 	if (m_version > CSE_VERSION_0x57) {
1000 		packet.r_seq(packet.r_u32(), m_dynamic_out_restrictions);
1001 		packet.r_seq(packet.r_u32(), m_dynamic_in_restrictions);
1002 	}
1003 	if (m_version > CSE_VERSION_0x5e)
1004 		packet.r_u16(m_killer_id);
1005 	m_o_torso.yaw = m_o_angle.y;
1006 	m_o_torso.pitch = m_o_angle.x;
1007 	if (m_version > CSE_VERSION_0x73)
1008 		packet.r_u64(m_game_death_time);
1009 }
1010 
state_write(xr_packet & packet)1011 void cse_alife_creature_abstract::state_write(xr_packet& packet)
1012 {
1013 	cse_alife_dynamic_object_visual::state_write(packet);
1014 	packet.w_u8(m_s_team);
1015 	packet.w_u8(m_s_squad);
1016 	packet.w_u8(m_s_group);
1017 	if (m_version < CSE_VERSION_0x73)
1018 		packet.w_float(m_health*100.f);
1019 	else
1020 		packet.w_float(m_health);
1021 	packet.w_size_u32(m_dynamic_out_restrictions.size());
1022 	packet.w_seq(m_dynamic_out_restrictions);
1023 	packet.w_size_u32(m_dynamic_in_restrictions.size());
1024 	packet.w_seq(m_dynamic_in_restrictions);
1025 	packet.w_u16(m_killer_id);
1026 	if (m_version > CSE_VERSION_0x73)
1027 		packet.w_u64(m_game_death_time);
1028 }
1029 
update_read(xr_packet & packet)1030 void cse_alife_creature_abstract::update_read(xr_packet& packet)
1031 {
1032 	cse_alife_dynamic_object_visual::update_read(packet);
1033 	packet.r_float(m_health);
1034 	if (m_version < CSE_VERSION_0x73)
1035 		m_health *= 0.01f;
1036 	packet.r_u32(m_timestamp);
1037 	packet.r_u8(m_flags);
1038 	packet.r_vec3(m_o_position);
1039 	packet.r_float(m_o_model);
1040 	packet.r_float(m_o_torso.yaw);
1041 	packet.r_float(m_o_torso.pitch);
1042 	packet.r_float(m_o_torso.roll);
1043 	packet.r_u8(m_s_team);
1044 	packet.r_u8(m_s_squad);
1045 	packet.r_u8(m_s_group);
1046 }
1047 
update_write(xr_packet & packet)1048 void cse_alife_creature_abstract::update_write(xr_packet& packet)
1049 {
1050 	cse_alife_dynamic_object_visual::update_write(packet);
1051 	if (m_version < CSE_VERSION_0x73)
1052 		packet.w_float(m_health*100.f);
1053 	else
1054 		packet.w_float(m_health);
1055 	packet.w_u32(m_timestamp);
1056 	packet.w_u8(m_flags);
1057 	packet.w_vec3(m_o_position);
1058 	packet.w_float(m_o_model);
1059 	packet.w_float(m_o_torso.yaw);
1060 	packet.w_float(m_o_torso.pitch);
1061 	packet.w_float(m_o_torso.roll);
1062 	packet.w_u8(m_s_team);
1063 	packet.w_u8(m_s_squad);
1064 	packet.w_u8(m_s_group);
1065 }
1066 
1067 ////////////////////////////////////////////////////////////////////////////////
1068 
state_read(xr_packet & packet,uint16_t size)1069 void cse_alife_creature_crow::state_read(xr_packet& packet, uint16_t size)
1070 {
1071 	if (m_version > CSE_VERSION_0x14) {
1072 		cse_alife_creature_abstract::state_read(packet, size);
1073 		if (m_version < CSE_VERSION_0x20)
1074 			cse_visual::visual_read(packet, m_version);
1075 	}
1076 }
1077 
state_write(xr_packet & packet)1078 void cse_alife_creature_crow::state_write(xr_packet& packet)
1079 {
1080 	cse_alife_creature_abstract::state_write(packet);
1081 }
1082 
update_read(xr_packet & packet)1083 void cse_alife_creature_crow::update_read(xr_packet& packet)
1084 {
1085 	cse_alife_creature_abstract::update_read(packet);
1086 }
1087 
update_write(xr_packet & packet)1088 void cse_alife_creature_crow::update_write(xr_packet& packet)
1089 {
1090 	cse_alife_creature_abstract::update_write(packet);
1091 }
1092 
1093 ////////////////////////////////////////////////////////////////////////////////
1094 
state_read(xr_packet & packet,uint16_t size)1095 void cse_alife_creature_phantom::state_read(xr_packet& packet, uint16_t size)
1096 {
1097 	cse_alife_creature_abstract::state_read(packet, size);
1098 }
1099 
state_write(xr_packet & packet)1100 void cse_alife_creature_phantom::state_write(xr_packet& packet)
1101 {
1102 	cse_alife_creature_abstract::state_write(packet);
1103 }
1104 
update_read(xr_packet & packet)1105 void cse_alife_creature_phantom::update_read(xr_packet& packet)
1106 {
1107 	cse_alife_creature_abstract::update_read(packet);
1108 }
1109 
update_write(xr_packet & packet)1110 void cse_alife_creature_phantom::update_write(xr_packet& packet)
1111 {
1112 	cse_alife_creature_abstract::update_write(packet);
1113 }
1114 
1115 ////////////////////////////////////////////////////////////////////////////////
1116 
cse_alife_monster_abstract()1117 cse_alife_monster_abstract::cse_alife_monster_abstract():
1118 	m_next_graph_id(UNDEF16), m_prev_graph_id(UNDEF16),
1119 	m_distance_from_point(0), m_distance_to_point(0),
1120 	m_smart_terrain_id(UNDEF16), m_task_reached(false) {}
1121 
state_read(xr_packet & packet,uint16_t size)1122 void cse_alife_monster_abstract::state_read(xr_packet& packet, uint16_t size)
1123 {
1124 	cse_alife_creature_abstract::state_read(packet, size);
1125 	if (m_version > CSE_VERSION_0x48) {
1126 		packet.r_sz(m_out_space_restrictors);
1127 		if (m_version > CSE_VERSION_0x49)
1128 			packet.r_sz(m_in_space_restrictors);
1129 	}
1130 	if (m_version > CSE_VERSION_0x6f)
1131 		packet.r_u16(m_smart_terrain_id);
1132 	if (m_version > CSE_VERSION_0x71)
1133 		packet.r_bool(m_task_reached);
1134 }
1135 
state_write(xr_packet & packet)1136 void cse_alife_monster_abstract::state_write(xr_packet& packet)
1137 {
1138 	cse_alife_creature_abstract::state_write(packet);
1139 	packet.w_sz(m_out_space_restrictors);
1140 	packet.w_sz(m_in_space_restrictors);
1141 	if (m_version > CSE_VERSION_0x6f)
1142 		packet.w_u16(m_smart_terrain_id);
1143 	if (m_version > CSE_VERSION_0x71)
1144 		packet.w_bool(m_task_reached);
1145 }
1146 
update_read(xr_packet & packet)1147 void cse_alife_monster_abstract::update_read(xr_packet& packet)
1148 {
1149 	cse_alife_creature_abstract::update_read(packet);
1150 	packet.r_u16(m_next_graph_id);
1151 	packet.r_u16(m_prev_graph_id);
1152 	packet.r_float(m_distance_from_point);
1153 	packet.r_float(m_distance_to_point);
1154 }
1155 
update_write(xr_packet & packet)1156 void cse_alife_monster_abstract::update_write(xr_packet& packet)
1157 {
1158 	cse_alife_creature_abstract::update_write(packet);
1159 	packet.w_u16(m_next_graph_id);
1160 	packet.w_u16(m_prev_graph_id);
1161 	packet.w_float(m_distance_from_point);
1162 	packet.w_float(m_distance_to_point);
1163 }
1164 
1165 ////////////////////////////////////////////////////////////////////////////////
1166 
cse_alife_monster_zombie()1167 cse_alife_monster_zombie::cse_alife_monster_zombie() {}
1168 
state_read(xr_packet & packet,uint16_t size)1169 void cse_alife_monster_zombie::state_read(xr_packet& packet, uint16_t size)
1170 {
1171 	cse_alife_monster_abstract::state_read(packet, size);
1172 	packet.r_float(m_eye_fov);
1173 	packet.r_float(m_eye_range);
1174 	if (m_version <= CSE_VERSION_0x05)
1175 		packet.r_float(m_health);
1176 	packet.r_float(m_min_range);
1177 	packet.r_float(m_max_range);
1178 	packet.r_float(m_attack_speed);
1179 	packet.r_float(m_max_pursuit_radius);
1180 	packet.r_float(m_max_home_radius);
1181 	packet.r_float(m_hit_power);
1182 	packet.r_u16(m_hit_interval);
1183 	packet.r_float(m_attack_distance);
1184 	packet.r_float(m_attack_angle);
1185 }
1186 
state_write(xr_packet & packet)1187 void cse_alife_monster_zombie::state_write(xr_packet& packet)
1188 {
1189 	cse_alife_monster_abstract::state_write(packet);
1190 	packet.w_float(m_eye_fov);
1191 	packet.w_float(m_eye_range);
1192 	packet.w_float(m_min_range);
1193 	packet.w_float(m_max_range);
1194 	packet.w_float(m_attack_speed);
1195 	packet.w_float(m_max_pursuit_radius);
1196 	packet.w_float(m_max_home_radius);
1197 	packet.w_float(m_hit_power);
1198 	packet.w_u16(m_hit_interval);
1199 	packet.w_float(m_attack_distance);
1200 	packet.w_float(m_attack_angle);
1201 }
1202 
update_read(xr_packet & packet)1203 void cse_alife_monster_zombie::update_read(xr_packet& packet)
1204 {
1205 	cse_alife_monster_abstract::update_read(packet);
1206 }
1207 
update_write(xr_packet & packet)1208 void cse_alife_monster_zombie::update_write(xr_packet& packet)
1209 {
1210 	cse_alife_monster_abstract::update_write(packet);
1211 }
1212 
1213 ////////////////////////////////////////////////////////////////////////////////
1214 
cse_alife_monster_base()1215 cse_alife_monster_base::cse_alife_monster_base(): m_spec_object_id(UNDEF16) {}
1216 
state_read(xr_packet & packet,uint16_t size)1217 void cse_alife_monster_base::state_read(xr_packet& packet, uint16_t size)
1218 {
1219 	cse_alife_monster_abstract::state_read(packet, size);
1220 	if (m_version >= CSE_VERSION_0x44)
1221 		cse_ph_skeleton::state_read(packet, size);
1222 	if (m_version >= CSE_VERSION_0x6d)
1223 		packet.r_u16(m_spec_object_id);
1224 }
1225 
state_write(xr_packet & packet)1226 void cse_alife_monster_base::state_write(xr_packet& packet)
1227 {
1228 	cse_alife_monster_abstract::state_write(packet);
1229 	cse_ph_skeleton::state_write(packet);
1230 	if (m_version >= CSE_VERSION_0x6d)
1231 		packet.w_u16(m_spec_object_id);
1232 }
1233 
update_read(xr_packet & packet)1234 void cse_alife_monster_base::update_read(xr_packet& packet)
1235 {
1236 	cse_alife_monster_abstract::update_read(packet);
1237 	cse_ph_skeleton::update_read(packet);
1238 }
1239 
update_write(xr_packet & packet)1240 void cse_alife_monster_base::update_write(xr_packet& packet)
1241 {
1242 	cse_alife_monster_abstract::update_write(packet);
1243 	cse_ph_skeleton::update_write(packet);
1244 }
1245 
1246 ////////////////////////////////////////////////////////////////////////////////
1247 
state_read(xr_packet & packet,uint16_t size)1248 void cse_alife_psy_dog_phantom::state_read(xr_packet& packet, uint16_t size)
1249 {
1250 	cse_alife_monster_base::state_read(packet, size);
1251 }
1252 
state_write(xr_packet & packet)1253 void cse_alife_psy_dog_phantom::state_write(xr_packet& packet)
1254 {
1255 	cse_alife_monster_base::state_write(packet);
1256 }
1257 
update_read(xr_packet & packet)1258 void cse_alife_psy_dog_phantom::update_read(xr_packet& packet)
1259 {
1260 	cse_alife_monster_base::update_read(packet);
1261 }
1262 
update_write(xr_packet & packet)1263 void cse_alife_psy_dog_phantom::update_write(xr_packet& packet)
1264 {
1265 	cse_alife_monster_base::update_write(packet);
1266 }
1267 
1268 ////////////////////////////////////////////////////////////////////////////////
1269 
cse_alife_trader_abstract()1270 cse_alife_trader_abstract::cse_alife_trader_abstract():
1271 	m_money(0), m_trader_flags(FLAG_INFINITE_AMMO),
1272 	m_community_index(-1), m_reputation(0), m_rank(0),
1273 	m_unk1_u8(1), m_unk2_u8(0) {}
1274 
state_merge(xr_packet & packet,uint16_t version)1275 void cse_alife_trader_abstract::state_merge(xr_packet& packet, uint16_t version)
1276 {
1277 	if (version > CSE_VERSION_0x13) {
1278 		if (version < CSE_VERSION_0x6c) {
1279 			size_t n = packet.r_u32();
1280 			xr_assert(n == 0);
1281 		}
1282 		if (version < CSE_VERSION_0x24)
1283 			xr_not_implemented();
1284 		if (version > CSE_VERSION_0x3e)
1285 			packet.r_u32();
1286 		if (version > CSE_VERSION_0x4b && version < CSE_VERSION_0x62)
1287 			xr_not_implemented();
1288 		packet.skip_sz();
1289 		if (version > CSE_VERSION_0x4d)
1290 			packet.r_u32();
1291 		if (version > CSE_VERSION_0x51 && version < CSE_VERSION_0x60)
1292 			xr_not_implemented();
1293 		if (version > CSE_VERSION_0x5f)
1294 			packet.skip_sz();
1295 		if (version > CSE_VERSION_0x55)
1296 			packet.r_s32();
1297 		if (version > CSE_VERSION_0x56) {
1298 			packet.r_s32();
1299 			packet.r_s32();
1300 		}
1301 		if (version > CSE_VERSION_0x68)
1302 			packet.skip_sz();
1303 
1304 		if (version >= CSE_VERSION_0x80)
1305 		{
1306 			packet.r_u8();
1307 			packet.r_u8();
1308 		}
1309 	}
1310 }
1311 
state_read(xr_packet & packet,uint16_t size)1312 void cse_alife_trader_abstract::state_read(xr_packet& packet, uint16_t size)
1313 {
1314 	uint16_t version = base()->version();
1315 	if (version > CSE_VERSION_0x13) {
1316 		if (version < CSE_VERSION_0x6c) {
1317 			size_t n = packet.r_u32();
1318 			xr_assert(n == 0);
1319 		}
1320 		if (version < CSE_VERSION_0x24)
1321 			xr_not_implemented();
1322 		if (version > CSE_VERSION_0x3e)
1323 			packet.r_u32(m_money);
1324 		if (version > CSE_VERSION_0x4b && version < CSE_VERSION_0x62)
1325 			xr_not_implemented();
1326 		if (version > CSE_VERSION_0x2e)
1327 			packet.r_sz(m_specific_character);
1328 		if (version > CSE_VERSION_0x4d)
1329 			packet.r_u32(m_trader_flags);
1330 		if (version > CSE_VERSION_0x51 && version < CSE_VERSION_0x60)
1331 			xr_not_implemented();
1332 		if (version > CSE_VERSION_0x5f)
1333 			packet.r_sz(m_character_profile);
1334 		if (version > CSE_VERSION_0x55)
1335 			packet.r_s32(m_community_index);
1336 		if (version > CSE_VERSION_0x56) {
1337 			packet.r_s32(m_rank);
1338 			packet.r_s32(m_reputation);
1339 		}
1340 		if (version > CSE_VERSION_0x68)
1341 			packet.r_sz(m_character_name);
1342 
1343 		if (version >= CSE_VERSION_0x80)
1344 		{
1345 			m_unk1_u8 = packet.r_u8();
1346 			m_unk2_u8 = packet.r_u8();
1347 		}
1348 	}
1349 }
1350 
state_write(xr_packet & packet)1351 void cse_alife_trader_abstract::state_write(xr_packet& packet)
1352 {
1353 	uint16_t version = base()->version();
1354 	if (version < CSE_VERSION_0x6c)
1355 		packet.w_u32(0);
1356 	packet.w_u32(m_money);
1357 	packet.w_sz(m_specific_character);
1358 	packet.w_u32(m_trader_flags);
1359 	packet.w_sz(m_character_profile);
1360 	packet.w_s32(m_community_index);
1361 	packet.w_s32(m_rank);
1362 	packet.w_s32(m_reputation);
1363 	if (version > CSE_VERSION_0x68)
1364 		packet.w_sz(m_character_name);
1365 
1366 	if (version >= CSE_VERSION_0x80)
1367 	{
1368 		packet.w_u8(m_unk1_u8);
1369 		packet.w_u8(m_unk2_u8);
1370 	}
1371 }
1372 
update_read(xr_packet & packet)1373 void cse_alife_trader_abstract::update_read(xr_packet& packet) {}
1374 
update_write(xr_packet & packet)1375 void cse_alife_trader_abstract::update_write(xr_packet& packet) {}
1376 
1377 ////////////////////////////////////////////////////////////////////////////////
1378 
base()1379 cse_abstract* cse_alife_trader::base() { return cse_abstract::base(); }
1380 
state_read(xr_packet & packet,uint16_t size)1381 void cse_alife_trader::state_read(xr_packet& packet, uint16_t size)
1382 {
1383 	cse_alife_dynamic_object_visual::state_read(packet, size);
1384 	cse_alife_trader_abstract::state_read(packet, size);
1385 	if (m_version > CSE_VERSION_0x23 && m_version < CSE_VERSION_0x76)	// m_tOrdID
1386 		packet.r_u32();
1387 	if (m_version > CSE_VERSION_0x1d && m_version < CSE_VERSION_0x76) {	// m_tpOrderedArtefacts
1388 		for (uint_fast32_t n = packet.r_u32(); n; --n) {
1389 			packet.skip_sz();
1390 			packet.r_u32();
1391 			for (size_t k = packet.r_u32(); k; --k) {
1392 				packet.skip_sz();
1393 				packet.r_u32();
1394 				packet.r_u32();
1395 			}
1396 		}
1397 	}
1398 	if (m_version > CSE_VERSION_0x1e && m_version < CSE_VERSION_0x76) {	// m_tSupplies
1399 		for (uint_fast32_t n = packet.r_u32(); n; --n) {
1400 			packet.skip_sz();
1401 			packet.r_u32();
1402 			packet.r_float();
1403 			packet.r_float();
1404 		}
1405 	}
1406 }
1407 
state_write(xr_packet & packet)1408 void cse_alife_trader::state_write(xr_packet& packet)
1409 {
1410 	cse_alife_dynamic_object_visual::state_write(packet);
1411 	cse_alife_trader_abstract::state_write(packet);
1412 	if (m_version < CSE_VERSION_0x76) {
1413 		packet.w_u32(UNDEF32);	// m_tOrdID
1414 		packet.w_u32(0);	// m_tpOrderedArtefacts
1415 		packet.w_u32(0);	// m_tSupplies
1416 	}
1417 }
1418 
update_read(xr_packet & packet)1419 void cse_alife_trader::update_read(xr_packet& packet)
1420 {
1421 	cse_alife_dynamic_object_visual::update_read(packet);
1422 }
1423 
update_write(xr_packet & packet)1424 void cse_alife_trader::update_write(xr_packet& packet)
1425 {
1426 	cse_alife_dynamic_object_visual::update_write(packet);
1427 }
1428 
1429 ////////////////////////////////////////////////////////////////////////////////
1430 
base()1431 cse_abstract* cse_alife_human_abstract::base() { return cse_abstract::base(); }
1432 
state_merge(xr_packet & packet,uint16_t version)1433 void cse_alife_human_abstract::state_merge(xr_packet& packet, uint16_t version)
1434 {
1435 	cse_alife_trader_abstract::state_merge(packet, version);
1436 	cse_alife_monster_abstract::state_merge(packet, version);
1437 }
1438 
state_read(xr_packet & packet,uint16_t size)1439 void cse_alife_human_abstract::state_read(xr_packet& packet, uint16_t size)
1440 {
1441 	cse_alife_trader_abstract::state_read(packet, size);
1442 	cse_alife_monster_abstract::state_read(packet, size);
1443 	if (m_version > CSE_VERSION_0x13) {
1444 		if (m_version < CSE_VERSION_0x6e) {
1445 			for (uint_fast32_t n = packet.r_u32(); n; --n)	// m_tpPath
1446 				packet.r_u32();
1447 			packet.r_u32();				// m_baVisitedVertices
1448 		}
1449 		if (m_version > CSE_VERSION_0x23) {
1450 			if (m_version < CSE_VERSION_0x6e)
1451 				packet.skip_sz();		// m_caKnownCustomers
1452 			if (m_version < CSE_VERSION_0x76) {
1453 				for (uint_fast32_t n = packet.r_u32(); n; --n)	// m_tpKnownCustomers
1454 					packet.r_u32();
1455 			}
1456 		}
1457 		if (!packet.is_ini()) {
1458 			packet.r_seq(packet.r_u32(), m_equipment_preferences);
1459 			if (m_equipment_preferences.size() != 5)
1460 				msg("wrong size equipment_preferences %" PRIuSIZET ", expected %d %s (%s)", m_equipment_preferences.size(), 5, name_replace().c_str(),
1461 					name().c_str());
1462 			packet.r_seq(packet.r_u32(), m_main_weapon_preferences);
1463 			if (m_main_weapon_preferences.size() != 4)
1464 				msg("wrong size main_weapon_preferences %" PRIuSIZET ", expected %d %s (%s)", m_main_weapon_preferences.size(), 4, name_replace().c_str(),
1465 					name().c_str());
1466 		}
1467 	}
1468 	if (m_version >= CSE_VERSION_0x6e && m_version < 0x70)
1469 		packet.r_u16(m_smart_terrain_id);
1470 }
1471 
state_write(xr_packet & packet)1472 void cse_alife_human_abstract::state_write(xr_packet& packet)
1473 {
1474 	cse_alife_trader_abstract::state_write(packet);
1475 	cse_alife_monster_abstract::state_write(packet);
1476 	if (m_version < CSE_VERSION_0x6e) {
1477 		packet.w_u32(0);	// m_tpPath
1478 		packet.w_u32(0);	// m_baVisitedVertices
1479 		packet.w_sz("");	// m_caKnownCustomers
1480 	}
1481 	if (m_version < CSE_VERSION_0x76)
1482 		packet.w_u32(0);	// m_tpKnownCustomers
1483 	if (!packet.is_ini()) {
1484 		packet.w_size_u32(m_equipment_preferences.size());
1485 		packet.w_seq(m_equipment_preferences);
1486 		packet.w_size_u32(m_main_weapon_preferences.size());
1487 		packet.w_seq(m_main_weapon_preferences);
1488 	}
1489 	if (m_version >= CSE_VERSION_0x6e && m_version < 0x70)
1490 		packet.w_u16(m_smart_terrain_id);
1491 }
1492 
update_read(xr_packet & packet)1493 void cse_alife_human_abstract::update_read(xr_packet& packet)
1494 {
1495 	cse_alife_monster_abstract::update_read(packet);
1496 }
1497 
update_write(xr_packet & packet)1498 void cse_alife_human_abstract::update_write(xr_packet& packet)
1499 {
1500 	cse_alife_monster_abstract::update_write(packet);
1501 }
1502 
1503 ////////////////////////////////////////////////////////////////////////////////
1504 
state_read(xr_packet & packet,uint16_t size)1505 void cse_alife_human_stalker::state_read(xr_packet& packet, uint16_t size)
1506 {
1507 	cse_alife_human_abstract::state_read(packet, size);
1508 	if (m_version > CSE_VERSION_0x43)
1509 		cse_ph_skeleton::state_read(packet, size);
1510 	if (m_version > CSE_VERSION_0x5a && m_version < CSE_VERSION_0x6f)
1511 		packet.r_bool();
1512 }
1513 
state_write(xr_packet & packet)1514 void cse_alife_human_stalker::state_write(xr_packet& packet)
1515 {
1516 	cse_alife_human_abstract::state_write(packet);
1517 	cse_ph_skeleton::state_write(packet);
1518 	if (m_version < CSE_VERSION_0x6f)
1519 		packet.w_bool(false);		// m_demo_mode?
1520 }
1521 
update_read(xr_packet & packet)1522 void cse_alife_human_stalker::update_read(xr_packet& packet)
1523 {
1524 	cse_alife_human_abstract::update_read(packet);
1525 	cse_ph_skeleton::update_read(packet);
1526 	packet.r_sz(m_start_dialog);
1527 }
1528 
update_write(xr_packet & packet)1529 void cse_alife_human_stalker::update_write(xr_packet& packet)
1530 {
1531 	cse_alife_human_abstract::update_write(packet);
1532 	cse_ph_skeleton::update_write(packet);
1533 	packet.w_sz(m_start_dialog);
1534 }
1535 
1536 ////////////////////////////////////////////////////////////////////////////////
1537 
cse_alife_creature_actor()1538 cse_alife_creature_actor::cse_alife_creature_actor():
1539 	m_state(0xd20), m_radiation(0), m_weapon(0x6e), m_holder_id(UNDEF16), m_num_items(0)
1540 {
1541 	m_accel.set();
1542 	m_velocity.set();
1543 }
1544 
base()1545 cse_abstract* cse_alife_creature_actor::base() { return cse_abstract::base(); }
1546 
state_read(xr_packet & packet,uint16_t size)1547 void cse_alife_creature_actor::state_read(xr_packet& packet, uint16_t size)
1548 {
1549 	if (m_version < CSE_VERSION_0x15) {
1550 		packet.r_u8(m_s_team);
1551 		packet.r_u8(m_s_squad);
1552 		packet.r_u8(m_s_group);
1553 		if (m_version > CSE_VERSION_0x12)
1554 			packet.r_float(m_health);
1555 		if (m_version >= CSE_VERSION_0x03)
1556 			cse_visual::visual_read(packet, m_version);
1557 	} else {
1558 		cse_alife_creature_abstract::state_read(packet, size);
1559 		cse_alife_trader_abstract::state_read(packet, size);
1560 		if (m_version < CSE_VERSION_0x20)
1561 			cse_visual::visual_read(packet, m_version);
1562 	}
1563 	if (m_version > CSE_VERSION_0x5b)
1564 		cse_ph_skeleton::state_read(packet, size);
1565 	if (m_version > CSE_VERSION_0x58)
1566 		packet.r_u16(m_holder_id);
1567 }
1568 
state_write(xr_packet & packet)1569 void cse_alife_creature_actor::state_write(xr_packet& packet)
1570 {
1571 	cse_alife_creature_abstract::state_write(packet);
1572 	cse_alife_trader_abstract::state_write(packet);
1573 	cse_ph_skeleton::state_write(packet);
1574 	packet.w_u16(m_holder_id);
1575 }
1576 
update_read(xr_packet & packet)1577 void cse_alife_creature_actor::update_read(xr_packet& packet)
1578 {
1579 	cse_alife_creature_abstract::update_read(packet);
1580 	packet.r_u16(m_state);
1581 	packet.r_sdir(m_accel);
1582 	packet.r_sdir(m_velocity);
1583 	packet.r_float(m_radiation);
1584 	packet.r_u8(m_weapon);
1585 	packet.r_u16(m_num_items);
1586 	xr_assert(m_num_items == 0);
1587 }
1588 
update_write(xr_packet & packet)1589 void cse_alife_creature_actor::update_write(xr_packet& packet)
1590 {
1591 	cse_alife_creature_abstract::update_write(packet);
1592 	packet.w_u16(m_state);
1593 	packet.w_sdir(m_accel);
1594 	packet.w_sdir(m_velocity);
1595 	packet.w_float(m_radiation);
1596 	packet.w_u8(m_weapon);
1597 	packet.w_u16(m_num_items);
1598 	xr_assert(m_num_items == 0);
1599 }
1600 
1601 ////////////////////////////////////////////////////////////////////////////////
1602 
cse_alife_space_restrictor()1603 cse_alife_space_restrictor::cse_alife_space_restrictor():
1604 	m_space_restrictor_type(DEFAULT_RESTRICTOR_TYPE_NONE) {}
1605 
state_merge(xr_packet & packet,uint16_t version)1606 void cse_alife_space_restrictor::state_merge(xr_packet& packet, uint16_t version)
1607 {
1608 	cse_alife_dynamic_object::state_merge(packet, version);
1609 	cse_shape::cform_merge(packet);
1610 	if (version > CSE_VERSION_0x4a)
1611 		packet.r_u8();
1612 }
1613 
state_read(xr_packet & packet,uint16_t size)1614 void cse_alife_space_restrictor::state_read(xr_packet& packet, uint16_t size)
1615 {
1616 	cse_alife_dynamic_object::state_read(packet, size);
1617 	cse_shape::cform_read(packet);
1618 	if (m_version > CSE_VERSION_0x4a)
1619 		packet.r_u8(m_space_restrictor_type);
1620 }
1621 
state_write(xr_packet & packet)1622 void cse_alife_space_restrictor::state_write(xr_packet& packet)
1623 {
1624 	cse_alife_dynamic_object::state_write(packet);
1625 	cse_shape::cform_write(packet);
1626 	packet.w_s8(m_space_restrictor_type);
1627 }
1628 
update_read(xr_packet & packet)1629 void cse_alife_space_restrictor::update_read(xr_packet& packet) {}
1630 
update_write(xr_packet & packet)1631 void cse_alife_space_restrictor::update_write(xr_packet& packet) {}
1632 
shape()1633 cse_shape* cse_alife_space_restrictor::shape()
1634 {
1635 	return static_cast<cse_shape*>(this);
1636 }
1637 
1638 ////////////////////////////////////////////////////////////////////////////////
1639 
state_read(xr_packet & packet,uint16_t size)1640 void cse_alife_smart_zone::state_read(xr_packet& packet, uint16_t size)
1641 {
1642 	cse_alife_space_restrictor::state_read(packet, size);
1643 }
1644 
state_write(xr_packet & packet)1645 void cse_alife_smart_zone::state_write(xr_packet& packet)
1646 {
1647 	cse_alife_space_restrictor::state_write(packet);
1648 }
1649 
update_read(xr_packet & packet)1650 void cse_alife_smart_zone::update_read(xr_packet& packet) {}
1651 
update_write(xr_packet & packet)1652 void cse_alife_smart_zone::update_write(xr_packet& packet) {}
1653 
1654 ////////////////////////////////////////////////////////////////////////////////
1655 
cse_alife_team_base_zone()1656 cse_alife_team_base_zone::cse_alife_team_base_zone(): m_team(0) {}
1657 
state_read(xr_packet & packet,uint16_t size)1658 void cse_alife_team_base_zone::state_read(xr_packet& packet, uint16_t size)
1659 {
1660 	cse_alife_space_restrictor::state_read(packet, size);
1661 	packet.r_u8(m_team);
1662 }
1663 
state_write(xr_packet & packet)1664 void cse_alife_team_base_zone::state_write(xr_packet& packet)
1665 {
1666 	cse_alife_space_restrictor::state_write(packet);
1667 	packet.w_u8(m_team);
1668 }
1669 
update_read(xr_packet & packet)1670 void cse_alife_team_base_zone::update_read(xr_packet& packet) {}
1671 
update_write(xr_packet & packet)1672 void cse_alife_team_base_zone::update_write(xr_packet& packet) {}
1673 
1674 ////////////////////////////////////////////////////////////////////////////////
1675 
cse_alife_level_changer()1676 cse_alife_level_changer::cse_alife_level_changer():
1677 	m_next_graph_id(UNDEF16), m_next_node_id(UNDEF32),
1678 	m_silent_mode(false)
1679 {
1680 	m_next_position.set();
1681 	m_angles.set();
1682 }
1683 
state_read(xr_packet & packet,uint16_t size)1684 void cse_alife_level_changer::state_read(xr_packet& packet, uint16_t size)
1685 {
1686 	cse_alife_space_restrictor::state_read(packet, size);
1687 	if (m_version < CSE_VERSION_0x22) {
1688 		packet.r_s32();
1689 		packet.r_s32();
1690 	} else {
1691 		packet.r_u16(m_next_graph_id);
1692 		packet.r_u32(m_next_node_id);
1693 		packet.r_float(m_next_position.x);
1694 		packet.r_float(m_next_position.y);
1695 		packet.r_float(m_next_position.z);
1696 		if (m_version > CSE_VERSION_0x35) {
1697 			packet.r_vec3(m_angles);
1698 		} else {
1699 			m_angles.x = 0;
1700 			packet.r_float(m_angles.y);
1701 			m_angles.z = 0;
1702 		}
1703 	}
1704 	packet.r_sz(m_level_to_change);
1705 	packet.r_sz(m_level_point_to_change);
1706 	if (m_version > CSE_VERSION_0x74)
1707 		packet.r_bool(m_silent_mode);
1708 }
1709 
state_write(xr_packet & packet)1710 void cse_alife_level_changer::state_write(xr_packet& packet)
1711 {
1712 	cse_alife_space_restrictor::state_write(packet);
1713 	packet.w_u16(m_next_graph_id);
1714 	packet.w_u32(m_next_node_id);
1715 	packet.w_float(m_next_position.x);
1716 	packet.w_float(m_next_position.y);
1717 	packet.w_float(m_next_position.z);
1718 	packet.w_vec3(m_angles);
1719 	packet.w_sz(m_level_to_change);
1720 	packet.w_sz(m_level_point_to_change);
1721 	if (m_version > CSE_VERSION_0x74)
1722 		packet.w_bool(m_silent_mode);
1723 }
1724 
update_read(xr_packet & packet)1725 void cse_alife_level_changer::update_read(xr_packet& packet) {}
1726 
update_write(xr_packet & packet)1727 void cse_alife_level_changer::update_write(xr_packet& packet) {}
1728 
1729 ////////////////////////////////////////////////////////////////////////////////
1730 
cse_alife_custom_zone()1731 cse_alife_custom_zone::cse_alife_custom_zone():
1732 	m_max_power(0), m_owner_id(UNDEF32),
1733 	m_enabled_time(0), m_disabled_time(0), m_start_time_shift(0) {}
1734 
state_merge(xr_packet & packet,uint16_t version)1735 void cse_alife_custom_zone::state_merge(xr_packet& packet, uint16_t version)
1736 {
1737 	cse_alife_space_restrictor::state_merge(packet, version);
1738 	packet.r_float();
1739 	if (version < CSE_VERSION_0x71) {
1740 		packet.r_float();
1741 		packet.r_u32();
1742 	}
1743 	if (version > CSE_VERSION_0x42 && version < CSE_VERSION_0x76)
1744 		packet.r_u32();
1745 	if (version > CSE_VERSION_0x66)
1746 		packet.r_u32();
1747 	if (version > CSE_VERSION_0x69) {
1748 		packet.r_u32();
1749 		packet.r_u32();
1750 	}
1751 	if (version > CSE_VERSION_0x6a)
1752 		packet.r_u32();
1753 }
1754 
state_read(xr_packet & packet,uint16_t size)1755 void cse_alife_custom_zone::state_read(xr_packet& packet, uint16_t size)
1756 {
1757 	cse_alife_space_restrictor::state_read(packet, size);
1758 	packet.r_float(m_max_power);
1759 	if (m_version < CSE_VERSION_0x71) {
1760 		packet.r_float();
1761 		packet.r_u32();
1762 	}
1763 	if (m_version > CSE_VERSION_0x42 && m_version < CSE_VERSION_0x76)
1764 		packet.r_u32();
1765 	if (m_version > CSE_VERSION_0x66)
1766 		packet.r_u32(m_owner_id);
1767 	if (m_version > CSE_VERSION_0x69) {
1768 		packet.r_u32(m_enabled_time);
1769 		packet.r_u32(m_disabled_time);
1770 	}
1771 	if (m_version > CSE_VERSION_0x6a)
1772 		packet.r_u32(m_start_time_shift);
1773 }
1774 
state_write(xr_packet & packet)1775 void cse_alife_custom_zone::state_write(xr_packet& packet)
1776 {
1777 	cse_alife_space_restrictor::state_write(packet);
1778 	packet.w_float(m_max_power);
1779 	if (m_version < CSE_VERSION_0x71) {
1780 		packet.w_float(0);		// FIXME
1781 		packet.w_u32(1000);		// FIXME
1782 	}
1783 	if (m_version < CSE_VERSION_0x76)
1784 		packet.w_u32(0);		// FIXME
1785 	if (m_version > CSE_VERSION_0x66)
1786 		packet.w_u32(m_owner_id);
1787 	if (m_version > CSE_VERSION_0x69) {
1788 		packet.w_u32(m_enabled_time);
1789 		packet.w_u32(m_disabled_time);
1790 	}
1791 	if (m_version > CSE_VERSION_0x6a)
1792 		packet.w_u32(m_start_time_shift);
1793 }
1794 
update_read(xr_packet & packet)1795 void cse_alife_custom_zone::update_read(xr_packet& packet)
1796 {
1797 	cse_alife_space_restrictor::update_read(packet);
1798 	if (m_version > CSE_VERSION_0x66 && (m_version < CSE_VERSION_0x76 ||
1799 			(m_version == CSE_VERSION_0x76 && m_script_version < 6))) {
1800 		packet.r_u32(m_owner_id);
1801 	}
1802 }
1803 
update_write(xr_packet & packet)1804 void cse_alife_custom_zone::update_write(xr_packet& packet)
1805 {
1806 	cse_alife_space_restrictor::update_write(packet);
1807 	if (m_version > CSE_VERSION_0x66 && (m_version < CSE_VERSION_0x76 ||
1808 			(m_version == CSE_VERSION_0x76 && m_script_version < 6))) {
1809 		packet.w_u32(m_owner_id);
1810 	}
1811 }
1812 
1813 ////////////////////////////////////////////////////////////////////////////////
1814 
cse_alife_anomalous_zone()1815 cse_alife_anomalous_zone::cse_alife_anomalous_zone(): m_offline_interactive_radius(0),
1816 	m_artefact_position_offset(0), m_artefact_spawn_count(0) {}
1817 
state_merge(xr_packet & packet,uint16_t version)1818 void cse_alife_anomalous_zone::state_merge(xr_packet& packet, uint16_t version)
1819 {
1820 	cse_alife_custom_zone::state_merge(packet, version);
1821 	if (version > CSE_VERSION_0x15) {
1822 		packet.r_float(m_offline_interactive_radius);	// do we need to pick it?
1823 		if (version < CSE_VERSION_0x71) {
1824 			packet.r_float();
1825 			for (uint_fast32_t n = packet.r_u16(); n; --n) {
1826 				packet.skip_sz();
1827 				if (version > CSE_VERSION_0x1a)
1828 					packet.r_float();
1829 				else
1830 					packet.r_u32();
1831 			}
1832 		}
1833 	}
1834 	if (version > CSE_VERSION_0x19) {
1835 		packet.r_u16(m_artefact_spawn_count);
1836 		packet.r_u32(m_artefact_position_offset);
1837 	}
1838 }
1839 
state_read(xr_packet & packet,uint16_t size)1840 void cse_alife_anomalous_zone::state_read(xr_packet& packet, uint16_t size)
1841 {
1842 	cse_alife_custom_zone::state_read(packet, size);
1843 	if (m_version > CSE_VERSION_0x15) {
1844 		packet.r_float(m_offline_interactive_radius);
1845 		if (m_version < CSE_VERSION_0x71) {
1846 			packet.r_float();
1847 			for (uint_fast32_t n = packet.r_u16(); n; --n) {
1848 				packet.skip_sz();
1849 				if (m_version > CSE_VERSION_0x1a)
1850 					packet.r_float();
1851 				else
1852 					packet.r_u32();
1853 			}
1854 		}
1855 	}
1856 	if (m_version > CSE_VERSION_0x19) {
1857 		packet.r_u16(m_artefact_spawn_count);
1858 		packet.r_u32(m_artefact_position_offset);
1859 	}
1860 	if (m_version > CSE_VERSION_0x1b && m_version < CSE_VERSION_0x43)
1861 		packet.r_u32();
1862 	if (m_version > CSE_VERSION_0x26 && m_version < CSE_VERSION_0x71)
1863 		packet.r_float();
1864 	if (m_version > CSE_VERSION_0x4e && m_version < CSE_VERSION_0x71) {
1865 		packet.r_float();
1866 		packet.r_float();
1867 		packet.r_float();
1868 	}
1869 	if (m_version == CSE_VERSION_0x66)
1870 		packet.r_u32();
1871 }
1872 
state_write(xr_packet & packet)1873 void cse_alife_anomalous_zone::state_write(xr_packet& packet)
1874 {
1875 	cse_alife_custom_zone::state_write(packet);
1876 	packet.w_float(m_offline_interactive_radius);
1877 	if (m_version < CSE_VERSION_0x71) {
1878 		// FIXME
1879 		packet.w_float(0);
1880 		size_t n = 0;
1881 		packet.w_size_u16(n);
1882 		for (; n; --n) {
1883 			packet.w_sz("");
1884 			packet.w_float(0);	// FIXME
1885 		}
1886 	}
1887 	packet.w_u16(m_artefact_spawn_count);
1888 	packet.w_u32(m_artefact_position_offset);
1889 	if (m_version < CSE_VERSION_0x71) {
1890 		packet.w_float(0);
1891 
1892 		packet.w_float(0);
1893 		packet.w_float(0);
1894 		packet.w_float(0);
1895 	}
1896 	if (m_version == CSE_VERSION_0x66)
1897 		packet.w_u32(0);		// FIXME
1898 }
1899 
update_read(xr_packet & packet)1900 void cse_alife_anomalous_zone::update_read(xr_packet& packet)
1901 {
1902 	cse_alife_custom_zone::update_read(packet);
1903 }
1904 
update_write(xr_packet & packet)1905 void cse_alife_anomalous_zone::update_write(xr_packet& packet)
1906 {
1907 	cse_alife_custom_zone::update_write(packet);
1908 }
1909 
1910 ////////////////////////////////////////////////////////////////////////////////
1911 
state_read(xr_packet & packet,uint16_t size)1912 void cse_alife_zone_visual::state_read(xr_packet& packet, uint16_t size)
1913 {
1914 	cse_alife_anomalous_zone::state_read(packet, size);
1915 	cse_visual::visual_read(packet, m_version);
1916 	packet.r_sz(cse_visual::m_startup_animation);
1917 	packet.r_sz(m_attack_animation);
1918 }
1919 
state_write(xr_packet & packet)1920 void cse_alife_zone_visual::state_write(xr_packet& packet)
1921 {
1922 	cse_alife_anomalous_zone::state_write(packet);
1923 	cse_visual::visual_write(packet, m_version);
1924 	packet.w_sz(cse_visual::m_startup_animation);
1925 	packet.w_sz(m_attack_animation);
1926 }
1927 
update_read(xr_packet & packet)1928 void cse_alife_zone_visual::update_read(xr_packet& packet)
1929 {
1930 	cse_alife_anomalous_zone::update_read(packet);
1931 }
1932 
update_write(xr_packet & packet)1933 void cse_alife_zone_visual::update_write(xr_packet& packet)
1934 {
1935 	cse_alife_anomalous_zone::update_write(packet);
1936 }
1937 
visual()1938 cse_visual* cse_alife_zone_visual::visual()
1939 {
1940 	return static_cast<cse_visual*>(this);
1941 }
1942 
1943 ////////////////////////////////////////////////////////////////////////////////
1944 
state_read(xr_packet & packet,uint16_t size)1945 void cse_alife_torrid_zone::state_read(xr_packet& packet, uint16_t size)
1946 {
1947 	cse_alife_custom_zone::state_read(packet, size);
1948 	cse_motion::motion_read(packet);
1949 }
1950 
state_write(xr_packet & packet)1951 void cse_alife_torrid_zone::state_write(xr_packet& packet)
1952 {
1953 	cse_alife_custom_zone::state_write(packet);
1954 	cse_motion::motion_write(packet);
1955 }
1956 
update_read(xr_packet & packet)1957 void cse_alife_torrid_zone::update_read(xr_packet& packet)
1958 {
1959 	cse_alife_custom_zone::update_read(packet);
1960 }
1961 
update_write(xr_packet & packet)1962 void cse_alife_torrid_zone::update_write(xr_packet& packet)
1963 {
1964 	cse_alife_custom_zone::update_write(packet);
1965 }
1966 
motion()1967 cse_motion* cse_alife_torrid_zone::motion()
1968 {
1969 	return static_cast<cse_motion*>(this);
1970 }
1971 
1972 ////////////////////////////////////////////////////////////////////////////////
1973 
state_read(xr_packet & packet,uint16_t size)1974 void cse_alife_online_offline_group::state_read(xr_packet& packet, uint16_t size)
1975 {
1976 	cse_alife_dynamic_object::state_read(packet, size);
1977 	packet.r_seq(packet.r_u32(), m_members);
1978 }
1979 
state_write(xr_packet & packet)1980 void cse_alife_online_offline_group::state_write(xr_packet& packet)
1981 {
1982 	cse_alife_dynamic_object::state_write(packet);
1983 	packet.w_size_u32(m_members.size());
1984 	packet.w_seq(m_members);
1985 }
1986 
update_read(xr_packet & packet)1987 void cse_alife_online_offline_group::update_read(xr_packet& packet)
1988 {
1989 	cse_alife_dynamic_object::update_read(packet);
1990 }
1991 
update_write(xr_packet & packet)1992 void cse_alife_online_offline_group::update_write(xr_packet& packet)
1993 {
1994 	cse_alife_dynamic_object::update_write(packet);
1995 }
1996 
1997 ////////////////////////////////////////////////////////////////////////////////
1998 
cse_alife_inventory_item()1999 cse_alife_inventory_item::cse_alife_inventory_item():
2000 	m_condition(1.f), m_timestamp(0), m_num_items(FLAG_NO_POSITION)
2001 {
2002 	std::memset(&m_state, 0, sizeof(m_state));
2003 }
2004 
~cse_alife_inventory_item()2005 cse_alife_inventory_item::~cse_alife_inventory_item() {}
2006 
state_read(xr_packet & packet,uint16_t size)2007 void cse_alife_inventory_item::state_read(xr_packet& packet, uint16_t size)
2008 {
2009 	uint32_t version = base()->version();
2010 	if (version > CSE_VERSION_0x34)
2011 		packet.r_float(m_condition);
2012 	if (version > CSE_VERSION_0x7b) {
2013 		if (size_t n = packet.r_u32()) {
2014 			m_upgrades.reserve(n);
2015 			for (; n > 0; --n)
2016 				m_upgrades.push_back(packet.skip_sz());
2017 		}
2018 	}
2019 	m_state.position = base()->position();
2020 }
2021 
state_write(xr_packet & packet)2022 void cse_alife_inventory_item::state_write(xr_packet& packet)
2023 {
2024 	packet.w_float(m_condition);
2025 	if (base()->version() > CSE_VERSION_0x7b) {
2026 		packet.w_size_u32(m_upgrades.size());
2027 		for (std::vector<std::string>::const_iterator it = m_upgrades.begin(),
2028 				end = m_upgrades.end(); it != end; ++it) {
2029 			packet.w_sz(*it);
2030 		}
2031 	}
2032 	m_state.position = base()->position();
2033 }
2034 
update_read(xr_packet & packet)2035 void cse_alife_inventory_item::update_read(xr_packet& packet)
2036 {
2037 	if (base()->version() >= CSE_VERSION_0x7a) {
2038 		xr_assert(base()->version() <= CSE_VERSION_COP);
2039 		m_num_items = packet.r_u8();
2040 		if (m_num_items) {
2041 			packet.r_vec3(m_state.force);
2042 			packet.r_vec3(m_state.torque);
2043 			packet.r_vec3(m_state.position);
2044 			base()->position() = m_state.position;
2045 			packet.r_quat(m_state.quaternion);
2046 			uint_fast16_t flags = m_num_items >> 5;
2047 			m_state.enabled = (flags & 1) != 0;
2048 			if (flags & 0x2)
2049 				m_state.angular_vel.set(0, 0, 0);
2050 			else
2051 				packet.r_vec3(m_state.angular_vel);
2052 			if (flags & 0x4)
2053 				m_state.linear_vel.set(0, 0, 0);
2054 			else
2055 				packet.r_vec3(m_state.linear_vel);
2056 			if (!packet.r_eof())
2057 				packet.r_bool();
2058 		}
2059 	} else if (base()->script_version() > 5) {
2060 		xr_assert(base()->version() == CSE_VERSION_SOC);
2061 		m_num_items = packet.r_u8();
2062 		if (m_num_items) {
2063 			packet.r_vec3(m_state.position);
2064 			base()->position() = m_state.position;
2065 			packet.r_float_q8(m_state.quaternion.x);
2066 			packet.r_float_q8(m_state.quaternion.y);
2067 			packet.r_float_q8(m_state.quaternion.z);
2068 			packet.r_float_q8(m_state.quaternion.w);
2069 			uint_fast16_t flags = m_num_items >> 5;
2070 			m_state.enabled = (flags & 1) != 0;
2071 			if (flags & 0x2) {
2072 				m_state.angular_vel.set(0, 0, 0);
2073 			} else {
2074 				packet.r_float_q8(m_state.angular_vel.x, 0, float(2*M_PI));
2075 				packet.r_float_q8(m_state.angular_vel.y, 0, float(2*M_PI));
2076 				packet.r_float_q8(m_state.angular_vel.z, 0, float(2*M_PI));
2077 			}
2078 			if (flags & 0x4) {
2079 				m_state.linear_vel.set(0, 0, 0);
2080 			} else {
2081 				packet.r_float_q8(m_state.linear_vel.x, -32.f, +32.f);
2082 				packet.r_float_q8(m_state.linear_vel.y, -32.f, +32.f);
2083 				packet.r_float_q8(m_state.linear_vel.z, -32.f, +32.f);
2084 			}
2085 		}
2086 	} else {
2087 		packet.r_float(m_condition);
2088 		packet.r_u32(m_timestamp);
2089 		packet.r_u16(m_num_items);
2090 		if ((m_num_items & FLAG_NO_POSITION) == 0) {
2091 			packet.r_vec3(m_state.position);
2092 			base()->position() = m_state.position;
2093 		}
2094 		if (m_num_items & ~FLAG_NO_POSITION) {
2095 			packet.r_bool(m_state.enabled);
2096 			packet.r_vec3(m_state.angular_vel);
2097 			packet.r_vec3(m_state.linear_vel);
2098 			packet.r_vec3(m_state.force);
2099 			packet.r_vec3(m_state.torque);
2100 			packet.r_quat(m_state.quaternion);
2101 		}
2102 	}
2103 }
2104 
update_write(xr_packet & packet)2105 void cse_alife_inventory_item::update_write(xr_packet& packet)
2106 {
2107 	if (base()->version() >= CSE_VERSION_0x7a) {
2108 		xr_assert(base()->version() <= CSE_VERSION_COP);
2109 		if (m_num_items & ~FLAG_NO_POSITION) {
2110 			uint8_t num_items = uint8_t(m_num_items & 0x1f);
2111 			if (m_state.enabled)
2112 				num_items |= 0x20;
2113 			if (m_state.angular_vel.square_magnitude() < 1e-7f)
2114 				num_items |= 0x40;
2115 			if (m_state.linear_vel.square_magnitude() < 1e-7f)
2116 				num_items |= 0x80;
2117 			packet.w_u8(num_items);
2118 			packet.w_vec3(m_state.force);
2119 			packet.w_vec3(m_state.torque);
2120 			packet.w_vec3(m_state.position);
2121 			packet.w_quat(m_state.quaternion);
2122 			if ((num_items & 0x40) == 0)
2123 				packet.w_vec3(m_state.angular_vel);
2124 			if ((num_items & 0x80) == 0)
2125 				packet.w_vec3(m_state.linear_vel);
2126 			packet.w_bool(true);
2127 		} else {
2128 			packet.w_u8(0);
2129 		}
2130 	} else if (base()->script_version() > 5) {
2131 		xr_assert(base()->version() == CSE_VERSION_SOC);
2132 		if (m_num_items & ~FLAG_NO_POSITION) {
2133 			uint8_t num_items = uint8_t(m_num_items & 0x1f);
2134 			if (m_state.enabled)
2135 				num_items |= 0x20;
2136 			if (m_state.angular_vel.square_magnitude() < 1e-7f)
2137 				num_items |= 0x40;
2138 			if (m_state.linear_vel.square_magnitude() < 1e-7f)
2139 				num_items |= 0x80;
2140 			packet.w_u8(num_items);
2141 			packet.w_vec3(m_state.position);
2142 			// FIXME: check if it really exist in xrGame.dll
2143 			base()->position() = m_state.position;
2144 			packet.w_float_q8(m_state.quaternion.x);
2145 			packet.w_float_q8(m_state.quaternion.y);
2146 			packet.w_float_q8(m_state.quaternion.z);
2147 			packet.w_float_q8(m_state.quaternion.w);
2148 			if ((num_items & 0x40) == 0) {
2149 				packet.w_float_q8(m_state.angular_vel.x, 0, float(2*M_PI));
2150 				packet.w_float_q8(m_state.angular_vel.y, 0, float(2*M_PI));
2151 				packet.w_float_q8(m_state.angular_vel.z, 0, float(2*M_PI));
2152 			}
2153 			if ((num_items & 0x80) == 0) {
2154 				packet.w_float_q8(m_state.linear_vel.x, -32.f, +32.f);
2155 				packet.w_float_q8(m_state.linear_vel.y, -32.f, +32.f);
2156 				packet.w_float_q8(m_state.linear_vel.z, -32.f, +32.f);
2157 			}
2158 		} else {
2159 			packet.w_u8(0);
2160 		}
2161 	} else {
2162 		packet.w_float(m_condition);
2163 		packet.w_u32(m_timestamp);
2164 		packet.w_u16(m_num_items);
2165 		if ((m_num_items & FLAG_NO_POSITION) == 0) {
2166 			packet.w_vec3(m_state.position);
2167 			base()->position() = m_state.position;
2168 		}
2169 		if (m_num_items & ~FLAG_NO_POSITION) {
2170 			packet.w_bool(m_state.enabled);
2171 			packet.w_vec3(m_state.angular_vel);
2172 			packet.w_vec3(m_state.linear_vel);
2173 			packet.w_vec3(m_state.force);
2174 			packet.w_vec3(m_state.torque);
2175 			packet.w_quat(m_state.quaternion);
2176 		}
2177 	}
2178 }
2179 
2180 ////////////////////////////////////////////////////////////////////////////////
2181 
base()2182 cse_abstract* cse_alife_item::base() { return cse_abstract::base(); }
2183 
state_read(xr_packet & packet,uint16_t size)2184 void cse_alife_item::state_read(xr_packet& packet, uint16_t size)
2185 {
2186 	cse_alife_dynamic_object_visual::state_read(packet, size);
2187 	if (m_clsid == "W_BINOC" && m_version < CSE_VERSION_0x25) {
2188 		packet.r_s16();
2189 		packet.r_s16();
2190 		packet.r_s8();
2191 	}
2192 	cse_alife_inventory_item::state_read(packet, size);
2193 }
2194 
state_write(xr_packet & packet)2195 void cse_alife_item::state_write(xr_packet& packet)
2196 {
2197 	cse_alife_dynamic_object_visual::state_write(packet);
2198 	cse_alife_inventory_item::state_write(packet);
2199 }
2200 
update_read(xr_packet & packet)2201 void cse_alife_item::update_read(xr_packet& packet)
2202 {
2203 	cse_alife_dynamic_object_visual::update_read(packet);
2204 	cse_alife_inventory_item::update_read(packet);
2205 }
2206 
update_write(xr_packet & packet)2207 void cse_alife_item::update_write(xr_packet& packet)
2208 {
2209 	cse_alife_dynamic_object_visual::update_write(packet);
2210 	cse_alife_inventory_item::update_write(packet);
2211 }
2212 
2213 ////////////////////////////////////////////////////////////////////////////////
2214 
cse_alife_item_torch()2215 cse_alife_item_torch::cse_alife_item_torch():
2216 	m_active(false), m_nightvision_active(false), m_unknown(false) {}
2217 
state_read(xr_packet & packet,uint16_t size)2218 void cse_alife_item_torch::state_read(xr_packet& packet, uint16_t size)
2219 {
2220 	if (m_version > CSE_VERSION_0x14)
2221 		cse_alife_item::state_read(packet, size);
2222 
2223 	if (m_version >= CSE_VERSION_0x28 && m_version <= CSE_VERSION_0x2e) {
2224 		packet.r_u32();
2225 		packet.skip_sz();
2226 		packet.skip_sz();
2227 		packet.r_float();
2228 		packet.r_angle8();
2229 		packet.r_float();
2230 
2231 		if (m_version > 0x28u ) {
2232 			packet.skip_sz();
2233 			packet.r_float();
2234 		}
2235 		if (m_version > 0x29u )
2236 			packet.r_u16();
2237 	}
2238 }
2239 
state_write(xr_packet & packet)2240 void cse_alife_item_torch::state_write(xr_packet& packet)
2241 {
2242 	cse_alife_item::state_write(packet);
2243 }
2244 
update_read(xr_packet & packet)2245 void cse_alife_item_torch::update_read(xr_packet& packet)
2246 {
2247 	cse_alife_item::update_read(packet);
2248 	uint8_t flags = packet.r_u8();
2249 	m_active = (flags & FL_TORCH_ACTIVE) != 0;
2250 	m_nightvision_active = (flags & FL_NIGHT_VISION_ACTIVE) != 0;
2251 	m_unknown = (flags & FL_UNKNOWN) != 0;
2252 }
2253 
update_write(xr_packet & packet)2254 void cse_alife_item_torch::update_write(xr_packet& packet)
2255 {
2256 	cse_alife_item::update_write(packet);
2257 	uint8_t flags = 0;
2258 	if (m_active)
2259 		flags |= FL_TORCH_ACTIVE;
2260 	if (m_nightvision_active)
2261 		flags |= FL_NIGHT_VISION_ACTIVE;
2262 	if (m_unknown)
2263 		flags |= FL_UNKNOWN;
2264 	packet.w_u8(flags);
2265 }
2266 
2267 ////////////////////////////////////////////////////////////////////////////////
2268 
state_read(xr_packet & packet,uint16_t size)2269 void cse_alife_item_detector::state_read(xr_packet& packet, uint16_t size)
2270 {
2271 	if (m_version > CSE_VERSION_0x14)
2272 		cse_alife_item::state_read(packet, size);
2273 }
2274 
state_write(xr_packet & packet)2275 void cse_alife_item_detector::state_write(xr_packet& packet)
2276 {
2277 	cse_alife_item::state_write(packet);
2278 }
2279 
update_read(xr_packet & packet)2280 void cse_alife_item_detector::update_read(xr_packet& packet)
2281 {
2282 	cse_alife_item::update_read(packet);
2283 }
2284 
update_write(xr_packet & packet)2285 void cse_alife_item_detector::update_write(xr_packet& packet)
2286 {
2287 	cse_alife_item::update_write(packet);
2288 }
2289 
2290 ////////////////////////////////////////////////////////////////////////////////
2291 
state_read(xr_packet & packet,uint16_t size)2292 void cse_alife_item_artefact::state_read(xr_packet& packet, uint16_t size)
2293 {
2294 	cse_alife_item::state_read(packet, size);
2295 }
2296 
state_write(xr_packet & packet)2297 void cse_alife_item_artefact::state_write(xr_packet& packet)
2298 {
2299 	cse_alife_item::state_write(packet);
2300 }
2301 
update_read(xr_packet & packet)2302 void cse_alife_item_artefact::update_read(xr_packet& packet)
2303 {
2304 	cse_alife_item::update_read(packet);
2305 }
2306 
update_write(xr_packet & packet)2307 void cse_alife_item_artefact::update_write(xr_packet& packet)
2308 {
2309 	cse_alife_item::update_write(packet);
2310 }
2311 
2312 ////////////////////////////////////////////////////////////////////////////////
2313 
state_read(xr_packet & packet,uint16_t size)2314 void cse_alife_item_grenade::state_read(xr_packet& packet, uint16_t size)
2315 {
2316 	cse_alife_item::state_read(packet, size);
2317 }
2318 
state_write(xr_packet & packet)2319 void cse_alife_item_grenade::state_write(xr_packet& packet)
2320 {
2321 	cse_alife_item::state_write(packet);
2322 }
2323 
update_read(xr_packet & packet)2324 void cse_alife_item_grenade::update_read(xr_packet& packet)
2325 {
2326 	cse_alife_item::update_read(packet);
2327 }
2328 
update_write(xr_packet & packet)2329 void cse_alife_item_grenade::update_write(xr_packet& packet)
2330 {
2331 	cse_alife_item::update_write(packet);
2332 }
2333 
2334 ////////////////////////////////////////////////////////////////////////////////
2335 
state_read(xr_packet & packet,uint16_t size)2336 void cse_alife_item_explosive::state_read(xr_packet& packet, uint16_t size)
2337 {
2338 	cse_alife_item::state_read(packet, size);
2339 }
2340 
state_write(xr_packet & packet)2341 void cse_alife_item_explosive::state_write(xr_packet& packet)
2342 {
2343 	cse_alife_item::state_write(packet);
2344 }
2345 
update_read(xr_packet & packet)2346 void cse_alife_item_explosive::update_read(xr_packet& packet)
2347 {
2348 	cse_alife_item::update_read(packet);
2349 }
2350 
update_write(xr_packet & packet)2351 void cse_alife_item_explosive::update_write(xr_packet& packet)
2352 {
2353 	cse_alife_item::update_write(packet);
2354 }
2355 
2356 ////////////////////////////////////////////////////////////////////////////////
2357 
state_read(xr_packet & packet,uint16_t size)2358 void cse_alife_item_bolt::state_read(xr_packet& packet, uint16_t size)
2359 {
2360 	cse_alife_item::state_read(packet, size);
2361 }
2362 
state_write(xr_packet & packet)2363 void cse_alife_item_bolt::state_write(xr_packet& packet)
2364 {
2365 	cse_alife_item::state_write(packet);
2366 }
2367 
update_read(xr_packet & packet)2368 void cse_alife_item_bolt::update_read(xr_packet& packet)
2369 {
2370 	cse_alife_item::update_read(packet);
2371 }
2372 
update_write(xr_packet & packet)2373 void cse_alife_item_bolt::update_write(xr_packet& packet)
2374 {
2375 	cse_alife_item::update_write(packet);
2376 }
2377 
2378 ////////////////////////////////////////////////////////////////////////////////
2379 
state_read(xr_packet & packet,uint16_t size)2380 void cse_alife_item_custom_outfit::state_read(xr_packet& packet, uint16_t size)
2381 {
2382 	cse_alife_item::state_read(packet, size);
2383 }
2384 
state_write(xr_packet & packet)2385 void cse_alife_item_custom_outfit::state_write(xr_packet& packet)
2386 {
2387 	cse_alife_item::state_write(packet);
2388 }
2389 
update_read(xr_packet & packet)2390 void cse_alife_item_custom_outfit::update_read(xr_packet& packet)
2391 {
2392 	cse_alife_item::update_read(packet);
2393 	if (m_version >= CSE_VERSION_0x76 && m_script_version > 5)
2394 		packet.r_float_q8(m_condition);
2395 }
2396 
update_write(xr_packet & packet)2397 void cse_alife_item_custom_outfit::update_write(xr_packet& packet)
2398 {
2399 	cse_alife_item::update_write(packet);
2400 	if (m_version >= CSE_VERSION_0x76 && m_script_version > 5)
2401 		packet.w_float_q8(m_condition);
2402 }
2403 
2404 
2405 ////////////////////////////////////////////////////////////////////////////////
2406 
state_read(xr_packet & packet,uint16_t size)2407 void cse_alife_item_helmet::state_read(xr_packet& packet, uint16_t size)
2408 {
2409 	cse_alife_item::state_read(packet, size);
2410 }
2411 
state_write(xr_packet & packet)2412 void cse_alife_item_helmet::state_write(xr_packet& packet)
2413 {
2414 	cse_alife_item::state_write(packet);
2415 }
2416 
update_read(xr_packet & packet)2417 void cse_alife_item_helmet::update_read(xr_packet& packet)
2418 {
2419 	cse_alife_item::update_read(packet);
2420 	if (m_version >= CSE_VERSION_0x76 && m_script_version > 5)
2421 		packet.r_float_q8(m_condition);
2422 }
2423 
update_write(xr_packet & packet)2424 void cse_alife_item_helmet::update_write(xr_packet& packet)
2425 {
2426 	cse_alife_item::update_write(packet);
2427 	if (m_version >= CSE_VERSION_0x76 && m_script_version > 5)
2428 		packet.w_float_q8(m_condition);
2429 }
2430 
2431 ////////////////////////////////////////////////////////////////////////////////
2432 
cse_alife_item_pda()2433 cse_alife_item_pda::cse_alife_item_pda(): m_original_owner(UNDEF16) {}
2434 
state_read(xr_packet & packet,uint16_t size)2435 void cse_alife_item_pda::state_read(xr_packet& packet, uint16_t size)
2436 {
2437 	cse_alife_item::state_read(packet, size);
2438 	if (m_version > CSE_VERSION_0x3a)
2439 		packet.r_u16(m_original_owner);
2440 	if (m_version > CSE_VERSION_0x59) {
2441 		if (m_version < CSE_VERSION_0x62) {
2442 			packet.r_s32();
2443 			packet.r_s32();
2444 			m_specific_character.clear();
2445 			m_info_portion.clear();
2446 		} else {
2447 			packet.r_sz(m_specific_character);
2448 			packet.r_sz(m_info_portion);
2449 		}
2450 	}
2451 }
2452 
state_write(xr_packet & packet)2453 void cse_alife_item_pda::state_write(xr_packet& packet)
2454 {
2455 	cse_alife_item::state_write(packet);
2456 	packet.w_u16(m_original_owner);
2457 	packet.w_sz(m_specific_character);
2458 	packet.w_sz(m_info_portion);
2459 }
2460 
update_read(xr_packet & packet)2461 void cse_alife_item_pda::update_read(xr_packet& packet)
2462 {
2463 	cse_alife_item::update_read(packet);
2464 }
2465 
update_write(xr_packet & packet)2466 void cse_alife_item_pda::update_write(xr_packet& packet)
2467 {
2468 	cse_alife_item::update_write(packet);
2469 }
2470 
2471 ////////////////////////////////////////////////////////////////////////////////
2472 
state_read(xr_packet & packet,uint16_t size)2473 void cse_alife_item_document::state_read(xr_packet& packet, uint16_t size)
2474 {
2475 	cse_alife_item::state_read(packet, size);
2476 	if (m_version < CSE_VERSION_0x62)
2477 		packet.r_s16();
2478 	else
2479 		packet.r_sz(m_doc);
2480 }
2481 
state_write(xr_packet & packet)2482 void cse_alife_item_document::state_write(xr_packet& packet)
2483 {
2484 	cse_alife_item::state_write(packet);
2485 	packet.w_sz(m_doc);
2486 }
2487 
update_read(xr_packet & packet)2488 void cse_alife_item_document::update_read(xr_packet& packet)
2489 {
2490 	cse_alife_item::update_read(packet);
2491 }
2492 
update_write(xr_packet & packet)2493 void cse_alife_item_document::update_write(xr_packet& packet)
2494 {
2495 	cse_alife_item::update_write(packet);
2496 }
2497 
2498 ////////////////////////////////////////////////////////////////////////////////
2499 
cse_alife_item_ammo()2500 cse_alife_item_ammo::cse_alife_item_ammo(): m_elapsed(30) {}
2501 
state_read(xr_packet & packet,uint16_t size)2502 void cse_alife_item_ammo::state_read(xr_packet& packet, uint16_t size)
2503 {
2504 	cse_alife_item::state_read(packet, size);
2505 	packet.r_u16(m_elapsed);
2506 }
2507 
state_write(xr_packet & packet)2508 void cse_alife_item_ammo::state_write(xr_packet& packet)
2509 {
2510 	cse_alife_item::state_write(packet);
2511 	packet.w_u16(m_elapsed);
2512 }
2513 
update_read(xr_packet & packet)2514 void cse_alife_item_ammo::update_read(xr_packet& packet)
2515 {
2516 	cse_alife_item::update_read(packet);
2517 	packet.r_u16(m_elapsed);
2518 }
2519 
update_write(xr_packet & packet)2520 void cse_alife_item_ammo::update_write(xr_packet& packet)
2521 {
2522 	cse_alife_item::update_write(packet);
2523 	packet.w_u16(m_elapsed);
2524 }
2525 
2526 ////////////////////////////////////////////////////////////////////////////////
2527 
cse_alife_item_weapon()2528 cse_alife_item_weapon::cse_alife_item_weapon():
2529 	m_scope(ADDON_DISABLED), m_silencer(ADDON_DISABLED), m_grenade_launcher(ADDON_DISABLED),
2530 	m_flags(0), m_state(0), m_ammo_type(0), m_ammo_current(30), m_ammo_elapsed(30),
2531 	m_addon_flags(0), m_zoom(0), m_cs_unk1_u8(0) {}
2532 
state_read(xr_packet & packet,uint16_t size)2533 void cse_alife_item_weapon::state_read(xr_packet& packet, uint16_t size)
2534 {
2535 	cse_alife_item::state_read(packet, size);
2536 	packet.r_u16(m_ammo_current);
2537 	packet.r_u16(m_ammo_elapsed);
2538 	packet.r_u8(m_state);
2539 	if (m_version >= CSE_VERSION_0x28)
2540 		packet.r_u8(m_addon_flags);
2541 	if (m_version > CSE_VERSION_0x2e)
2542 		packet.r_u8(m_ammo_type);
2543 	if (m_version > CSE_VERSION_0x7a)
2544 		packet.r_u8(m_cs_unk1_u8);
2545 }
2546 
state_write(xr_packet & packet)2547 void cse_alife_item_weapon::state_write(xr_packet& packet)
2548 {
2549 	cse_alife_item::state_write(packet);
2550 	packet.w_u16(m_ammo_current);
2551 	packet.w_u16(m_ammo_elapsed);
2552 	packet.w_u8(m_state);
2553 	packet.w_u8(m_addon_flags);
2554 	packet.w_u8(m_ammo_type);
2555 	if (m_version > CSE_VERSION_0x7a)
2556 		packet.w_u8(m_cs_unk1_u8);
2557 }
2558 
update_read(xr_packet & packet)2559 void cse_alife_item_weapon::update_read(xr_packet& packet)
2560 {
2561 	cse_alife_item::update_read(packet);
2562 	if (m_version >= CSE_VERSION_SOC && m_script_version > 5)
2563 		packet.r_float_q8(m_condition);
2564 	packet.r_u8(m_flags);
2565 	packet.r_u16(m_ammo_elapsed);
2566 	packet.r_u8(m_addon_flags);
2567 	packet.r_u8(m_ammo_type);
2568 	packet.r_u8(m_state);
2569 // FIXME: mar_wpn_svd from 3120 has non-zero m_bZoom (or whatever it is?)
2570 //	packet.r_bool(m_zoom);
2571 	packet.r_u8(m_zoom);
2572 }
2573 
update_write(xr_packet & packet)2574 void cse_alife_item_weapon::update_write(xr_packet& packet)
2575 {
2576 	cse_alife_item::update_write(packet);
2577 	if (m_version >= CSE_VERSION_SOC && m_script_version > 5)
2578 		packet.w_float_q8(m_condition);
2579 	packet.w_u8(m_flags);
2580 	packet.w_u16(m_ammo_elapsed);
2581 	packet.w_u8(m_addon_flags);
2582 	packet.w_u8(m_ammo_type);
2583 	packet.w_u8(m_state);
2584 // see above
2585 //	packet.w_bool(m_zoom);
2586 	packet.w_u8(m_zoom);
2587 }
2588 
2589 ////////////////////////////////////////////////////////////////////////////////
2590 
cse_alife_item_weapon_magazined()2591 cse_alife_item_weapon_magazined::cse_alife_item_weapon_magazined(): m_cur_fire_mode(0) {}
2592 
state_read(xr_packet & packet,uint16_t size)2593 void cse_alife_item_weapon_magazined::state_read(xr_packet& packet, uint16_t size)
2594 {
2595 	cse_alife_item_weapon::state_read(packet, size);
2596 }
2597 
state_write(xr_packet & packet)2598 void cse_alife_item_weapon_magazined::state_write(xr_packet& packet)
2599 {
2600 	cse_alife_item_weapon::state_write(packet);
2601 }
2602 
update_read(xr_packet & packet)2603 void cse_alife_item_weapon_magazined::update_read(xr_packet& packet)
2604 {
2605 	cse_alife_item_weapon::update_read(packet);
2606 	packet.r_u8(m_cur_fire_mode);
2607 }
2608 
update_write(xr_packet & packet)2609 void cse_alife_item_weapon_magazined::update_write(xr_packet& packet)
2610 {
2611 	cse_alife_item_weapon::update_write(packet);
2612 	packet.w_u8(m_cur_fire_mode);
2613 }
2614 
2615 ////////////////////////////////////////////////////////////////////////////////
2616 
cse_alife_item_weapon_magazined_w_gl()2617 cse_alife_item_weapon_magazined_w_gl::cse_alife_item_weapon_magazined_w_gl(): m_grenade_mode(false) {}
2618 
state_read(xr_packet & packet,uint16_t size)2619 void cse_alife_item_weapon_magazined_w_gl::state_read(xr_packet& packet, uint16_t size)
2620 {
2621 	cse_alife_item_weapon_magazined::state_read(packet, size);
2622 }
2623 
state_write(xr_packet & packet)2624 void cse_alife_item_weapon_magazined_w_gl::state_write(xr_packet& packet)
2625 {
2626 	cse_alife_item_weapon_magazined::state_write(packet);
2627 }
2628 
update_read(xr_packet & packet)2629 void cse_alife_item_weapon_magazined_w_gl::update_read(xr_packet& packet)
2630 {
2631 	packet.r_bool(m_grenade_mode);
2632 	cse_alife_item_weapon_magazined::update_read(packet);
2633 }
2634 
update_write(xr_packet & packet)2635 void cse_alife_item_weapon_magazined_w_gl::update_write(xr_packet& packet)
2636 {
2637 	packet.w_bool(m_grenade_mode);
2638 	cse_alife_item_weapon_magazined::update_write(packet);
2639 }
2640 
2641 ////////////////////////////////////////////////////////////////////////////////
2642 
state_read(xr_packet & packet,uint16_t size)2643 void cse_alife_item_weapon_shotgun::state_read(xr_packet& packet, uint16_t size)
2644 {
2645 	cse_alife_item_weapon_magazined::state_read(packet, size);
2646 }
2647 
state_write(xr_packet & packet)2648 void cse_alife_item_weapon_shotgun::state_write(xr_packet& packet)
2649 {
2650 	cse_alife_item_weapon_magazined::state_write(packet);
2651 }
2652 
update_read(xr_packet & packet)2653 void cse_alife_item_weapon_shotgun::update_read(xr_packet& packet)
2654 {
2655 	cse_alife_item_weapon_magazined::update_read(packet);
2656 	packet.r_seq(packet.r_u8(), m_ammo_ids);
2657 }
2658 
update_write(xr_packet & packet)2659 void cse_alife_item_weapon_shotgun::update_write(xr_packet& packet)
2660 {
2661 	cse_alife_item_weapon_magazined::update_write(packet);
2662 	packet.w_size_u8(m_ammo_ids.size());
2663 	packet.w_seq(m_ammo_ids);
2664 }
2665