pso2packetlib/protocol/
objects.rs

1//! Object related packets. \[0x04\]
2use super::{
3    models::{
4        character::{Class, ClassInfo},
5        Position,
6    },
7    Flags, ObjectHeader, PacketError, PacketHeader, PacketReadWrite, PacketType,
8};
9use crate::{fixed_types::FixedBytes, AsciiString};
10use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
11use half::f16;
12use std::{
13    io::{Read, Seek, Write},
14    time::Duration,
15};
16
17// ----------------------------------------------------------------
18// Object related packets
19// ----------------------------------------------------------------
20
21/// (0x04, 0x02) Object Teleport Location
22///
23/// (S -> C) Sent when the client is teleported.
24///
25/// Response to: [`crate::protocol::Packet::Interact`]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27#[cfg_attr(feature = "serde", serde(default))]
28#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
29#[Id(0x04, 0x02)]
30#[Flags(Flags::OBJECT_RELATED)]
31pub struct TeleportTransferPacket {
32    pub unk1: [u8; 0xC],
33    /// Object that started the teleportation.
34    pub source_tele: ObjectHeader,
35    /// New location.
36    pub location: Position,
37    pub unk2: u16,
38}
39
40/// (0x04, 0x06) Despawn Object.
41///
42/// (S -> C) Sent when an object is despawning (i.e. picking up an item or a concert is starting).
43///
44/// Response to: [`crate::protocol::Packet::ItemPickupRequest`] and ???
45#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
46#[cfg_attr(feature = "serde", serde(default))]
47#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
48#[Id(0x04, 0x06)]
49#[Flags(Flags::OBJECT_RELATED)]
50pub struct DespawnObjectPacket {
51    /// Player that received this packet.
52    pub player: ObjectHeader,
53    /// Object that was despawned.
54    pub item: ObjectHeader,
55}
56
57/// (0x04, 0x07) Object Movement. (broadcast)
58///
59/// (Bidirectional) Sent when players (or objects?) move.
60///
61/// Response to: [`crate::protocol::Packet::Movement`] (C->S)
62/// Respond with: [`crate::protocol::Packet::Movement`] (S->C)
63#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64#[cfg_attr(feature = "serde", serde(default))]
65#[derive(Debug, Clone, Default, PartialEq)]
66pub struct MovementPacket {
67    pub unk: [u8; 0x6],
68    pub ent1_id: Option<u64>,
69    pub ent1_type: Option<u16>,
70    pub ent1_unk: Option<u16>,
71    pub ent2_id: Option<u64>,
72    pub ent2_type: Option<u16>,
73    pub ent2_unk: Option<u16>,
74    /// Timestamp of action.
75    pub timestamp: Option<Duration>,
76    /// X quaternion rotation.
77    pub rot_x: Option<f16>,
78    /// Y quaternion rotation.
79    pub rot_y: Option<f16>,
80    /// Z quaternion rotation.
81    pub rot_z: Option<f16>,
82    /// W quaternion rotation.
83    pub rot_w: Option<f16>,
84    /// Current x position (i.e. new position).
85    pub cur_x: Option<f16>,
86    /// Current y position (i.e. new position).
87    pub cur_y: Option<f16>,
88    /// Current z position (i.e. new position).
89    pub cur_z: Option<f16>,
90    pub unk1: Option<f16>,
91    pub unk_x: Option<f16>,
92    pub unk_y: Option<f16>,
93    pub unk_z: Option<f16>,
94    pub unk2: Option<f16>,
95    pub unk3: Option<u32>,
96    pub unk4: Option<u8>,
97}
98
99/// (0x04, 0x08) Client Movement Action.
100///
101/// (C -> S) Sent when players does some action (e.g. jumping or attacking).
102///
103/// Respond with: [`crate::protocol::Packet::MovementActionServer`]
104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
105#[cfg_attr(feature = "serde", serde(default))]
106#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
107#[Id(0x04, 0x08)]
108#[Flags(Flags::PACKED | Flags::OBJECT_RELATED)]
109#[Magic(0x922D, 0x45)]
110pub struct MovementActionPacket {
111    pub unk1: ObjectHeader,
112    /// Object that performed an action.
113    pub performer: ObjectHeader,
114    pub unk3: u32,
115    pub unk4: [u8; 0x10],
116    pub unk5: [u8; 0x8],
117    pub unk6: [u8; 0xC],
118    /// Name of performed action.
119    pub action: AsciiString,
120    pub unk7: u32,
121    pub unk8: u32,
122    pub unk9: Vec<u32>,
123    pub unk10: u32,
124}
125
126/// (0x04, 0x0F) Enemy Killed (map broadcast).
127///
128/// (S -> C) Send when an enemy is killed.
129///
130/// Followed by: [`crate::protocol::Packet::GainedEXP`]
131// literally the same as DamageReceive
132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
133#[cfg_attr(feature = "serde", serde(default))]
134#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
135#[Id(0x04, 0x0F)]
136#[Flags(Flags::OBJECT_RELATED)]
137pub struct EnemyKilledPacket {
138    /// Player that receives this packet.
139    pub receiver: ObjectHeader,
140    /// Object that receives this damage.
141    pub dmg_target: ObjectHeader,
142    /// Object that deals this damage.
143    pub dmg_inflicter: ObjectHeader,
144    /// Inflicted damage ID.
145    pub damage_id: u32,
146    /// How much damage was inflicted.
147    pub dmg_amount: i32,
148    /// New HP.
149    pub new_hp: u32,
150    /// Hitbox ID (?).
151    pub hitbox_id: u32,
152    /// Hit x position.
153    pub x_pos: f16,
154    /// Hit y position.
155    pub y_pos: f16,
156    /// Hit z position.
157    pub z_pos: f16,
158    pub unk1: u16,
159    pub unk2: u16,
160    pub unk3: u16,
161    pub unk4: u16,
162    pub unk5: u16,
163    pub unk6: u32,
164    pub unk7: u32,
165}
166
167/// (0x04, 0x13) Unknown.
168///
169/// (C -> S)
170#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
171#[cfg_attr(feature = "serde", serde(default))]
172#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
173#[Id(0x04, 0x13)]
174#[Flags(Flags::OBJECT_RELATED)]
175pub struct Unk0413Packet {
176    pub unk1: [u8; 0xC],
177    pub unk2: ObjectHeader,
178    pub unk3: ObjectHeader,
179    pub unk4: u32,
180}
181
182/// (0x04, 0x14) Client Interaction.
183///
184/// (C -> S) Sent when players interacts with some object.
185///
186/// Respond with: [`crate::protocol::Packet::SetTag`] (optional)
187#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
188#[cfg_attr(feature = "serde", serde(default))]
189#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
190#[Id(0x04, 0x14)]
191#[Flags(Flags::PACKED | Flags::OBJECT_RELATED)]
192#[Magic(0xD711, 0xCA)]
193pub struct InteractPacket {
194    pub unk1: [u8; 0xC],
195    /// Target. (?)
196    pub object1: ObjectHeader,
197    pub unk2: [u8; 0x4],
198    pub object3: ObjectHeader,
199    pub object4: [u8; 0x10],
200    /// Name of the action.
201    pub action: AsciiString,
202}
203
204/// (0x04, 0x15) Object Action or Set Object Tag. (unicast or broadcast)
205///
206/// (S -> C) Sent when object performs some action or it has new tag (usually after interaction).
207///
208/// Response to: [`crate::protocol::Packet::Interact`] (optional)
209#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
210#[cfg_attr(feature = "serde", serde(default))]
211#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
212#[Id(0x04, 0x15)]
213#[Flags(Flags::PACKED | Flags::OBJECT_RELATED)]
214#[Magic(0x5CCF, 0x15)]
215pub struct SetTagPacket {
216    /// Player that receives this packet.
217    pub receiver: ObjectHeader,
218    /// Target object.
219    pub target: ObjectHeader,
220    pub unk1: u32,
221    pub object3: ObjectHeader,
222    pub object4: ObjectHeader,
223    pub unk2: u8,
224    pub unk3: u8,
225    pub unk4: u8,
226    pub unk5: u8,
227    /// Name of the action or tag.
228    pub attribute: AsciiString,
229}
230
231/// (0x04, 0x20) Change Class Request.
232///
233/// (C -> S) Sent when the client wants to change the active class.
234///
235/// Respond with: [`crate::protocol::Packet::ChangeClass`], [`crate::protocol::Packet::Unk042C`].
236#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
237#[cfg_attr(feature = "serde", serde(default))]
238#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
239#[Id(0x04, 0x20)]
240#[Flags(Flags::OBJECT_RELATED)]
241pub struct ChangeClassRequestPacket {
242    /// Unused object header.
243    pub unused: ObjectHeader,
244    /// Player object that changed the class.
245    pub player: ObjectHeader,
246    /// New main class.
247    pub main_class: Class,
248    /// New sub class.
249    pub sub_class: Class,
250    pub unk: u16,
251}
252
253/// (0x04, 0x21) Change Class Response.
254///
255/// (S -> C) Sent in response to the request.
256///
257/// Response to: [`crate::protocol::Packet::ChangeClassRequest`].
258///
259/// Follow with: [`crate::protocol::Packet::Unk0E21`].
260#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
261#[cfg_attr(feature = "serde", serde(default))]
262#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
263#[Id(0x04, 0x21)]
264#[Flags(Flags::OBJECT_RELATED)]
265pub struct ChangeClassPacket {
266    /// Receiving player object header.
267    pub receiver: ObjectHeader,
268    /// Player object that changed the class.
269    pub player: ObjectHeader,
270    /// New class info.
271    pub new_info: ClassInfo,
272    pub unk3: [u16; 11],
273}
274
275/// (0x04, 0x22) Enemy Action. (map broadcast)
276///
277/// (S -> C) Sent when an enemy performs an action (i.e. spawns or dies).
278#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
279#[cfg_attr(feature = "serde", serde(default))]
280#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
281#[Id(0x04, 0x22)]
282#[Flags(Flags::OBJECT_RELATED)]
283pub struct EnemyActionPacket {
284    pub receiver: ObjectHeader,
285    pub actor: ObjectHeader,
286    pub action_id: u32,
287    pub action_starter: ObjectHeader,
288    pub unk5: [u8; 0x18],
289}
290
291/// (0x04, 0x23) Unknown.
292///
293/// (C -> S)
294#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
295#[cfg_attr(feature = "serde", serde(default))]
296#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
297#[Id(0x04, 0x23)]
298#[Flags(Flags::OBJECT_RELATED)]
299pub struct Unk0423Packet {
300    pub unk1: [u8; 0xC],
301    pub unk2: ObjectHeader,
302    pub unk3: ObjectHeader,
303    pub unk4: u32,
304}
305
306/// (0x04, 0x24) Unknown.
307///
308/// (S -> C)
309#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
310#[cfg_attr(feature = "serde", serde(default))]
311#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
312#[Id(0x04, 0x24)]
313#[Flags(Flags::OBJECT_RELATED)]
314pub struct Unk0424Packet {
315    pub unk1: ObjectHeader,
316    pub unk2: ObjectHeader,
317    pub unk3: ObjectHeader,
318    pub unk4: u32,
319    pub unk5: u32,
320    pub unk6: [u8; 0xC],
321    pub unk7: [u8; 0xC],
322}
323
324/// (0x04, 0x25) Unknown.
325///
326/// (S -> C)
327#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
328#[cfg_attr(feature = "serde", serde(default))]
329#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
330#[Id(0x04, 0x25)]
331#[Flags(Flags::OBJECT_RELATED)]
332pub struct Unk0425Packet {
333    pub unk1: ObjectHeader,
334    pub unk2: ObjectHeader,
335    pub unk3: u32,
336    pub unk4: u32,
337    pub unk5: u32,
338}
339
340/// (0x04, 0x2B) Unknown.
341///
342/// (C -> S)
343#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
344#[cfg_attr(feature = "serde", serde(default))]
345#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
346#[Id(0x04, 0x2B)]
347#[Flags(Flags::OBJECT_RELATED)]
348pub struct Unk042BPacket {
349    pub unk1: [u8; 0xC],
350    pub unk2: ObjectHeader,
351}
352
353/// (0x04, 0x2C) Unknown.
354///
355/// (S -> C)
356///
357/// Response to: [`crate::protocol::Packet::ChangeClassRequest`].
358#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
359#[cfg_attr(feature = "serde", serde(default))]
360#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
361#[Id(0x04, 0x2C)]
362#[Flags(Flags::OBJECT_RELATED)]
363pub struct Unk042CPacket {
364    pub unk1: ObjectHeader,
365    pub unk2: ObjectHeader,
366    pub unk3: u8,
367    pub unk4: u8,
368    pub unk5: u16,
369    pub unk6: [u8; 0x10],
370}
371
372/// (0x04, 0x2E) Load Learned Photon Arts. (broadcast)
373///
374/// (S -> C) Sent on any character spawning to list learned photon arts.
375#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
376#[cfg_attr(feature = "serde", serde(default))]
377#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
378#[Id(0x04, 0x2E)]
379#[Flags(Flags::OBJECT_RELATED)]
380pub struct LoadPAsPacket {
381    /// Player that receives this packet.
382    pub receiver: ObjectHeader,
383    /// Player that has this data.
384    pub target: ObjectHeader,
385    /// Levels for PAs.
386    pub levels: FixedBytes<0xEE>,
387    pub unk: FixedBytes<0x40>,
388}
389
390/// (0x04, 0x3B) Despawn Player. (broadcast)
391///
392/// (S -> C) Sent when a player leaves a map (e.g player disconnects).
393#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
394#[cfg_attr(feature = "serde", serde(default))]
395#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
396#[Id(0x04, 0x3B)]
397#[Flags(Flags::OBJECT_RELATED)]
398pub struct DespawnPlayerPacket {
399    /// Player that receives this packet.
400    pub receiver: ObjectHeader,
401    /// Player that got removed.
402    pub removed_player: ObjectHeader,
403}
404
405/// (0x04, 0x3C) Client Action Update.
406///
407/// (C -> S) Sent when player wants to update action data.
408///
409/// Respond with: [`crate::protocol::Packet::ActionUpdateServer`]
410#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
411#[cfg_attr(feature = "serde", serde(default))]
412#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
413#[Id(0x04, 0x3C)]
414#[Flags(Flags::OBJECT_RELATED)]
415pub struct ActionUpdatePacket {
416    pub unk1: ObjectHeader,
417    /// Object that performed this action.
418    pub performer: ObjectHeader,
419    pub unk2: [u8; 0x20],
420}
421
422/// (0x04, 0x52) Damage Received.
423///
424/// (S -> C) Sent when object receives damage (including healing and selfdamage).
425///
426/// Response to: [`crate::protocol::Packet::DealDamage`]
427#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
428#[cfg_attr(feature = "serde", serde(default))]
429#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
430#[Id(0x04, 0x52)]
431#[Flags(Flags::OBJECT_RELATED)]
432pub struct DamageReceivePacket {
433    /// Player that receives this packet.
434    pub receiver: ObjectHeader,
435    /// Object that receives this damage.
436    pub dmg_target: ObjectHeader,
437    /// Object that deals this damage.
438    pub dmg_inflicter: ObjectHeader,
439    /// Inflicted damage ID.
440    pub damage_id: u32,
441    /// How much damage was inflicted.
442    pub dmg_amount: i32,
443    /// New HP.
444    pub new_hp: u32,
445    /// Hitbox ID (?).
446    pub hitbox_id: u32,
447    /// Hit x position.
448    pub x_pos: f16,
449    /// Hit y position.
450    pub y_pos: f16,
451    /// Hit z position.
452    pub z_pos: f16,
453    pub unk1: u16,
454    pub unk2: u16,
455    pub unk3: u16,
456    pub unk4: u16,
457    pub unk5: u16,
458    pub unk6: u32,
459    pub unk7: u32,
460}
461
462/// (0x04, 0x5F) Set Title Request.
463///
464/// (C -> S) Sent when a client sets an active title.
465///
466/// Respond with: [`crate::protocol::Packet::SetTitle`].
467#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
468#[cfg_attr(feature = "serde", serde(default))]
469#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
470#[Id(0x04, 0x5F)]
471#[Flags(Flags::OBJECT_RELATED)]
472pub struct SetTitleRequestPacket {
473    pub unused: ObjectHeader,
474    /// Object of the player that has set the title.
475    pub target: ObjectHeader,
476    pub unk: u32,
477    /// Active title ID.
478    pub title_id: u32,
479}
480
481/// (0x04, 0x71) Object Movement End. (broadcast)
482///
483/// (Bidirectional) Sent when players (or objects?) stop moving.
484///
485/// Response to: [`crate::protocol::Packet::MovementEnd`] (C->S)
486/// Respond with: [`crate::protocol::Packet::MovementEnd`] (S->C)
487#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
488#[cfg_attr(feature = "serde", serde(default))]
489#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
490#[Id(0x04, 0x71)]
491#[Flags(Flags::OBJECT_RELATED)]
492pub struct MovementEndPacket {
493    pub unk1: ObjectHeader,
494    pub unk2: ObjectHeader,
495    pub unk3: u32,
496    /// Current position of the object.
497    pub cur_pos: Position,
498    pub unk5: u16,
499    pub unk_x: f16,
500    pub unk_y: f16,
501    pub unk_z: f16,
502    pub unk7: u16,
503    pub unk8: u32,
504}
505
506/// (0x04, 0x72) Set Title. (broadcast)
507///
508/// (S -> C) Sent in response to the request.
509///
510/// Response to: [`crate::protocol::Packet::SetTitleRequest`].
511#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
512#[cfg_attr(feature = "serde", serde(default))]
513#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
514#[Id(0x04, 0x72)]
515#[Flags(Flags::OBJECT_RELATED | Flags::PACKED)]
516#[Magic(0xF2B6, 0x5F)]
517pub struct SetTitlePacket {
518    /// Object of the player that receives this packet.
519    pub receiver: ObjectHeader,
520    /// Object of the player that has set the title.
521    pub target: ObjectHeader,
522    /// JP version of the title.
523    pub jp_title: String,
524    /// NA version of the title.
525    pub en_title: String,
526}
527
528/// (0x04, 0x75) Action End. (broadcast)
529///
530/// (Bidirectional) Sent when objects stop an action.
531///
532/// Response to: [`crate::protocol::Packet::ActionEnd`] (C->S)
533/// Respond with: [`crate::protocol::Packet::ActionEnd`] (S->C)
534#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
535#[cfg_attr(feature = "serde", serde(default))]
536#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
537#[Id(0x04, 0x75)]
538#[Flags(Flags::PACKED | Flags::OBJECT_RELATED)]
539#[Magic(0x83EF, 0x40)]
540pub struct ActionEndPacket {
541    pub unk1: ObjectHeader,
542    /// Object that was performing an action.
543    pub performer: ObjectHeader,
544    pub unk2: u32,
545    pub unk3: ObjectHeader,
546    pub unk4: ObjectHeader,
547    pub unk5: [u8; 4],
548    /// Name of an action.
549    pub action: AsciiString,
550}
551
552/// (0x04, 0x79) Unknown.
553///
554/// (S -> C)
555#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
556#[cfg_attr(feature = "serde", serde(default))]
557#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
558#[Id(0x04, 0x79)]
559#[Flags(Flags::OBJECT_RELATED)]
560pub struct Unk0479Packet {
561    pub unk1: ObjectHeader,
562    pub unk2: ObjectHeader,
563    pub unk3: u32,
564}
565
566/// (0x04, 0x80) Movement Action Response. (broadcast)
567///
568/// (S -> C) Sent when players does some action (e.g. jumping or attacking).
569///
570/// Response to: [`crate::protocol::Packet::MovementAction`]
571#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
572#[cfg_attr(feature = "serde", serde(default))]
573#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
574#[Id(0x04, 0x80)]
575#[Flags(Flags::PACKED | Flags::OBJECT_RELATED)]
576#[Magic(0x4315, 0x7A)]
577pub struct MovementActionServerPacket {
578    /// Player that receives this packet.
579    pub receiver: ObjectHeader,
580    /// Object that performed this action.
581    pub performer: ObjectHeader,
582    pub unk3: u32,
583    pub unk4: [u8; 0x10],
584    pub unk5: [u8; 0x8],
585    pub unk6: [u8; 0xC],
586    /// Name of an action.
587    pub action: AsciiString,
588    pub unk7: u32,
589    pub unk8: u32,
590    pub unk9: Vec<u32>,
591    pub unk10: u32,
592}
593
594/// (0x04, 0x81) Action Update Response. (broadcast)
595///
596/// (S -> C) Sent when player wants to update action data.
597///
598/// Response to: [`crate::protocol::Packet::ActionUpdate`]
599#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
600#[cfg_attr(feature = "serde", serde(default))]
601#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
602#[Id(0x04, 0x81)]
603#[Flags(Flags::OBJECT_RELATED)]
604pub struct ActionUpdateServerPacket {
605    /// Player that receives this packet.
606    pub receiver: ObjectHeader,
607    /// Object that performed this action.
608    pub performer: ObjectHeader,
609    pub unk2: [u8; 0x20],
610}
611
612/// (0x04, 0x86) Unknown.
613///
614/// (S -> C)
615#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
616#[cfg_attr(feature = "serde", serde(default))]
617#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
618#[Id(0x04, 0x86)]
619#[Flags(Flags::OBJECT_RELATED)]
620pub struct Unk0486Packet {
621    pub unk1: ObjectHeader,
622    pub unk2: ObjectHeader,
623}
624
625/// (0x04, 0xB0) Unknown.
626///
627/// (S -> C)
628#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
629#[cfg_attr(feature = "serde", serde(default))]
630#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
631#[Id(0x04, 0xB0)]
632#[Flags(Flags::OBJECT_RELATED)]
633pub struct Unk04B0Packet {
634    pub unk1: ObjectHeader,
635    pub unk2: ObjectHeader,
636    pub unk3: [u8; 0xC],
637    pub unk4: u32,
638}
639
640/// (0x04, 0xBA) Unknown.
641///
642/// (S -> C)
643#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
644#[cfg_attr(feature = "serde", serde(default))]
645#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
646#[Id(0x04, 0xBA)]
647#[Flags(Flags::OBJECT_RELATED)]
648pub struct Unk04BAPacket {
649    pub unk1: ObjectHeader,
650    pub unk2: ObjectHeader,
651    pub unk3: u32,
652    pub unk4: u8,
653    pub unk5: u8,
654    pub unk6: u8,
655    pub unk7: u8,
656}
657
658/// (0x04, 0xEA) Unknown.
659///
660/// (S -> C)
661#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
662#[cfg_attr(feature = "serde", serde(default))]
663#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
664#[Id(0x04, 0xEA)]
665#[Flags(Flags::OBJECT_RELATED)]
666pub struct Unk04EAPacket {
667    pub unk1: ObjectHeader,
668    pub unk2: ObjectHeader,
669    pub unk3: u32,
670    pub unk4: u32,
671    pub unk5: u32,
672    pub unk6: [u8; 0xC],
673    pub unk7: u32,
674    pub unk8: [u8; 0x14],
675    pub unk9: u16,
676    pub unk10: u16,
677    pub unk11: u32,
678}
679
680// ----------------------------------------------------------------
681// Read/Write implementations
682// ----------------------------------------------------------------
683
684//yikes
685impl PacketReadWrite for MovementPacket {
686    fn read(
687        reader: &mut (impl Read + Seek),
688        flags: &Flags,
689        _: PacketType,
690    ) -> Result<Self, PacketError> {
691        let mut packet = Self::default();
692        reader
693            .read_exact(&mut packet.unk)
694            .map_err(|e| PacketError::FieldError {
695                packet_name: "MovementPacket",
696                field_name: "unk",
697                error: e,
698            })?;
699        if flags.contains(Flags::FULL_MOVEMENT) {
700            packet.ent1_id =
701                Some(
702                    reader
703                        .read_u64::<LittleEndian>()
704                        .map_err(|e| PacketError::FieldError {
705                            packet_name: "MovementPacket",
706                            field_name: "ent1_id",
707                            error: e,
708                        })?,
709                );
710            packet.ent1_type =
711                Some(
712                    reader
713                        .read_u16::<LittleEndian>()
714                        .map_err(|e| PacketError::FieldError {
715                            packet_name: "MovementPacket",
716                            field_name: "ent1_type",
717                            error: e,
718                        })?,
719                );
720            packet.ent1_unk =
721                Some(
722                    reader
723                        .read_u16::<LittleEndian>()
724                        .map_err(|e| PacketError::FieldError {
725                            packet_name: "MovementPacket",
726                            field_name: "ent1_unk",
727                            error: e,
728                        })?,
729                );
730            packet.ent2_id =
731                Some(
732                    reader
733                        .read_u64::<LittleEndian>()
734                        .map_err(|e| PacketError::FieldError {
735                            packet_name: "MovementPacket",
736                            field_name: "ent2_id",
737                            error: e,
738                        })?,
739                );
740            packet.ent2_type =
741                Some(
742                    reader
743                        .read_u16::<LittleEndian>()
744                        .map_err(|e| PacketError::FieldError {
745                            packet_name: "MovementPacket",
746                            field_name: "ent2_type",
747                            error: e,
748                        })?,
749                );
750            packet.ent2_unk =
751                Some(
752                    reader
753                        .read_u16::<LittleEndian>()
754                        .map_err(|e| PacketError::FieldError {
755                            packet_name: "MovementPacket",
756                            field_name: "ent2_unk",
757                            error: e,
758                        })?,
759                );
760            packet.timestamp = Some(Duration::from_secs(
761                reader
762                    .read_u32::<LittleEndian>()
763                    .map_err(|e| PacketError::FieldError {
764                        packet_name: "MovementPacket",
765                        field_name: "timestamp",
766                        error: e,
767                    })? as u64,
768            ));
769            packet.rot_x = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
770                |e| PacketError::FieldError {
771                    packet_name: "MovementPacket",
772                    field_name: "rot_x",
773                    error: e,
774                },
775            )?));
776            packet.rot_y = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
777                |e| PacketError::FieldError {
778                    packet_name: "MovementPacket",
779                    field_name: "rot_y",
780                    error: e,
781                },
782            )?));
783            packet.rot_z = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
784                |e| PacketError::FieldError {
785                    packet_name: "MovementPacket",
786                    field_name: "rot_z",
787                    error: e,
788                },
789            )?));
790            packet.rot_w = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
791                |e| PacketError::FieldError {
792                    packet_name: "MovementPacket",
793                    field_name: "rot_w",
794                    error: e,
795                },
796            )?));
797            packet.cur_x = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
798                |e| PacketError::FieldError {
799                    packet_name: "MovementPacket",
800                    field_name: "cur_x",
801                    error: e,
802                },
803            )?));
804            packet.cur_y = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
805                |e| PacketError::FieldError {
806                    packet_name: "MovementPacket",
807                    field_name: "cur_y",
808                    error: e,
809                },
810            )?));
811            packet.cur_z = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
812                |e| PacketError::FieldError {
813                    packet_name: "MovementPacket",
814                    field_name: "cur_z",
815                    error: e,
816                },
817            )?));
818            packet.unk1 = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
819                |e| PacketError::FieldError {
820                    packet_name: "MovementPacket",
821                    field_name: "unk1",
822                    error: e,
823                },
824            )?));
825            packet.unk_x = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
826                |e| PacketError::FieldError {
827                    packet_name: "MovementPacket",
828                    field_name: "unk_x",
829                    error: e,
830                },
831            )?));
832            packet.unk_y = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
833                |e| PacketError::FieldError {
834                    packet_name: "MovementPacket",
835                    field_name: "unk_y",
836                    error: e,
837                },
838            )?));
839            packet.unk_z = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
840                |e| PacketError::FieldError {
841                    packet_name: "MovementPacket",
842                    field_name: "unk_z",
843                    error: e,
844                },
845            )?));
846            packet.unk2 = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
847                |e| PacketError::FieldError {
848                    packet_name: "MovementPacket",
849                    field_name: "unk2",
850                    error: e,
851                },
852            )?));
853            packet.unk3 =
854                Some(
855                    reader
856                        .read_u32::<LittleEndian>()
857                        .map_err(|e| PacketError::FieldError {
858                            packet_name: "MovementPacket",
859                            field_name: "unk3",
860                            error: e,
861                        })?,
862                );
863            return Ok(packet);
864        }
865        let flags = reader
866            .read_u24::<LittleEndian>()
867            .map_err(|e| PacketError::FieldError {
868                packet_name: "MovementPacket",
869                field_name: "flags",
870                error: e,
871            })?;
872        if flags & 0x1 != 0 {
873            packet.ent1_id =
874                Some(
875                    reader
876                        .read_u64::<LittleEndian>()
877                        .map_err(|e| PacketError::FieldError {
878                            packet_name: "MovementPacket",
879                            field_name: "ent1_id",
880                            error: e,
881                        })?,
882                );
883        }
884        if flags & 0x2 != 0 {
885            packet.ent1_type =
886                Some(
887                    reader
888                        .read_u16::<LittleEndian>()
889                        .map_err(|e| PacketError::FieldError {
890                            packet_name: "MovementPacket",
891                            field_name: "ent1_type",
892                            error: e,
893                        })?,
894                );
895        }
896        if flags & 0x4 != 0 {
897            packet.ent1_unk =
898                Some(
899                    reader
900                        .read_u16::<LittleEndian>()
901                        .map_err(|e| PacketError::FieldError {
902                            packet_name: "MovementPacket",
903                            field_name: "ent1_unk",
904                            error: e,
905                        })?,
906                );
907        }
908        if flags & 0x8 != 0 {
909            packet.ent2_id =
910                Some(
911                    reader
912                        .read_u64::<LittleEndian>()
913                        .map_err(|e| PacketError::FieldError {
914                            packet_name: "MovementPacket",
915                            field_name: "ent2_id",
916                            error: e,
917                        })?,
918                );
919        }
920        if flags & 0x10 != 0 {
921            packet.ent2_type =
922                Some(
923                    reader
924                        .read_u16::<LittleEndian>()
925                        .map_err(|e| PacketError::FieldError {
926                            packet_name: "MovementPacket",
927                            field_name: "ent2_type",
928                            error: e,
929                        })?,
930                );
931        }
932        if flags & 0x20 != 0 {
933            packet.ent2_unk =
934                Some(
935                    reader
936                        .read_u16::<LittleEndian>()
937                        .map_err(|e| PacketError::FieldError {
938                            packet_name: "MovementPacket",
939                            field_name: "ent2_unk",
940                            error: e,
941                        })?,
942                );
943        }
944        if flags & 0x40 != 0 {
945            packet.timestamp = Some(Duration::from_secs(
946                reader
947                    .read_u32::<LittleEndian>()
948                    .map_err(|e| PacketError::FieldError {
949                        packet_name: "MovementPacket",
950                        field_name: "timestamp",
951                        error: e,
952                    })? as u64,
953            ));
954        }
955        if flags & 0x80 != 0 {
956            packet.rot_x = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
957                |e| PacketError::FieldError {
958                    packet_name: "MovementPacket",
959                    field_name: "rot_x",
960                    error: e,
961                },
962            )?));
963        }
964        if flags & 0x100 != 0 {
965            packet.rot_y = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
966                |e| PacketError::FieldError {
967                    packet_name: "MovementPacket",
968                    field_name: "rot_y",
969                    error: e,
970                },
971            )?));
972        }
973        if flags & 0x200 != 0 {
974            packet.rot_z = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
975                |e| PacketError::FieldError {
976                    packet_name: "MovementPacket",
977                    field_name: "rot_z",
978                    error: e,
979                },
980            )?));
981        }
982        if flags & 0x400 != 0 {
983            packet.rot_w = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
984                |e| PacketError::FieldError {
985                    packet_name: "MovementPacket",
986                    field_name: "rot_w",
987                    error: e,
988                },
989            )?));
990        }
991        if flags & 0x800 != 0 {
992            packet.cur_x = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
993                |e| PacketError::FieldError {
994                    packet_name: "MovementPacket",
995                    field_name: "cur_x",
996                    error: e,
997                },
998            )?));
999        }
1000        if flags & 0x1000 != 0 {
1001            packet.cur_y = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
1002                |e| PacketError::FieldError {
1003                    packet_name: "MovementPacket",
1004                    field_name: "cur_y",
1005                    error: e,
1006                },
1007            )?));
1008        }
1009        if flags & 0x2000 != 0 {
1010            packet.cur_z = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
1011                |e| PacketError::FieldError {
1012                    packet_name: "MovementPacket",
1013                    field_name: "cur_z",
1014                    error: e,
1015                },
1016            )?));
1017        }
1018        if flags & 0x4000 != 0 {
1019            packet.unk1 = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
1020                |e| PacketError::FieldError {
1021                    packet_name: "MovementPacket",
1022                    field_name: "unk1",
1023                    error: e,
1024                },
1025            )?));
1026        }
1027        if flags & 0x8000 != 0 {
1028            packet.unk_x = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
1029                |e| PacketError::FieldError {
1030                    packet_name: "MovementPacket",
1031                    field_name: "unk_x",
1032                    error: e,
1033                },
1034            )?));
1035        }
1036        if flags & 0x10000 != 0 {
1037            packet.unk_y = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
1038                |e| PacketError::FieldError {
1039                    packet_name: "MovementPacket",
1040                    field_name: "unk_y",
1041                    error: e,
1042                },
1043            )?));
1044        }
1045        if flags & 0x20000 != 0 {
1046            packet.unk_z = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
1047                |e| PacketError::FieldError {
1048                    packet_name: "MovementPacket",
1049                    field_name: "unk_z",
1050                    error: e,
1051                },
1052            )?));
1053        }
1054        if flags & 0x40000 != 0 {
1055            packet.unk2 = Some(f16::from_bits(reader.read_u16::<LittleEndian>().map_err(
1056                |e| PacketError::FieldError {
1057                    packet_name: "MovementPacket",
1058                    field_name: "unk2",
1059                    error: e,
1060                },
1061            )?));
1062        }
1063        if flags & 0x80000 != 0 {
1064            if flags & 0x100000 != 0 {
1065                packet.unk4 = Some(reader.read_u8().map_err(|e| PacketError::FieldError {
1066                    packet_name: "MovementPacket",
1067                    field_name: "unk4",
1068                    error: e,
1069                })?);
1070            } else {
1071                packet.unk3 = Some(reader.read_u32::<LittleEndian>().map_err(|e| {
1072                    PacketError::FieldError {
1073                        packet_name: "MovementPacket",
1074                        field_name: "unk3",
1075                        error: e,
1076                    }
1077                })?);
1078            }
1079        }
1080        Ok(packet)
1081    }
1082    fn write(&self, packet_type: PacketType) -> Result<Vec<u8>, PacketError> {
1083        let mut tmp_buf = vec![];
1084        let mut flags = 0u32;
1085        if let Some(n) = self.ent1_id {
1086            tmp_buf
1087                .write_u64::<LittleEndian>(n)
1088                .map_err(|e| PacketError::FieldError {
1089                    packet_name: "MovementPacket",
1090                    field_name: "ent1_id",
1091                    error: e,
1092                })?;
1093            flags += 0x1;
1094        }
1095        if let Some(n) = self.ent1_type {
1096            tmp_buf
1097                .write_u16::<LittleEndian>(n)
1098                .map_err(|e| PacketError::FieldError {
1099                    packet_name: "MovementPacket",
1100                    field_name: "ent1_type",
1101                    error: e,
1102                })?;
1103            flags += 0x2;
1104        }
1105        if let Some(n) = self.ent1_unk {
1106            tmp_buf
1107                .write_u16::<LittleEndian>(n)
1108                .map_err(|e| PacketError::FieldError {
1109                    packet_name: "MovementPacket",
1110                    field_name: "ent1_unk",
1111                    error: e,
1112                })?;
1113            flags += 0x4;
1114        }
1115        if let Some(n) = self.ent2_id {
1116            tmp_buf
1117                .write_u64::<LittleEndian>(n)
1118                .map_err(|e| PacketError::FieldError {
1119                    packet_name: "MovementPacket",
1120                    field_name: "ent2_id",
1121                    error: e,
1122                })?;
1123            flags += 0x8;
1124        }
1125        if let Some(n) = self.ent2_type {
1126            tmp_buf
1127                .write_u16::<LittleEndian>(n)
1128                .map_err(|e| PacketError::FieldError {
1129                    packet_name: "MovementPacket",
1130                    field_name: "ent2_type",
1131                    error: e,
1132                })?;
1133            flags += 0x10;
1134        }
1135        if let Some(n) = self.ent2_unk {
1136            tmp_buf
1137                .write_u16::<LittleEndian>(n)
1138                .map_err(|e| PacketError::FieldError {
1139                    packet_name: "MovementPacket",
1140                    field_name: "ent2_unk",
1141                    error: e,
1142                })?;
1143            flags += 0x20;
1144        }
1145        if let Some(x) = self.timestamp {
1146            tmp_buf
1147                .write_u32::<LittleEndian>(x.as_secs() as u32)
1148                .map_err(|e| PacketError::FieldError {
1149                    packet_name: "MovementPacket",
1150                    field_name: "timestamp",
1151                    error: e,
1152                })?;
1153            flags += 0x40;
1154        }
1155        if let Some(n) = self.rot_x {
1156            tmp_buf
1157                .write_u16::<LittleEndian>(n.to_bits())
1158                .map_err(|e| PacketError::FieldError {
1159                    packet_name: "MovementPacket",
1160                    field_name: "rot_x",
1161                    error: e,
1162                })?;
1163            flags += 0x80;
1164        }
1165        if let Some(n) = self.rot_y {
1166            tmp_buf
1167                .write_u16::<LittleEndian>(n.to_bits())
1168                .map_err(|e| PacketError::FieldError {
1169                    packet_name: "MovementPacket",
1170                    field_name: "rot_y",
1171                    error: e,
1172                })?;
1173            flags += 0x100;
1174        }
1175        if let Some(n) = self.rot_z {
1176            tmp_buf
1177                .write_u16::<LittleEndian>(n.to_bits())
1178                .map_err(|e| PacketError::FieldError {
1179                    packet_name: "MovementPacket",
1180                    field_name: "rot_z",
1181                    error: e,
1182                })?;
1183            flags += 0x200;
1184        }
1185        if let Some(n) = self.rot_w {
1186            tmp_buf
1187                .write_u16::<LittleEndian>(n.to_bits())
1188                .map_err(|e| PacketError::FieldError {
1189                    packet_name: "MovementPacket",
1190                    field_name: "rot_w",
1191                    error: e,
1192                })?;
1193            flags += 0x400;
1194        }
1195        if let Some(n) = self.cur_x {
1196            tmp_buf
1197                .write_u16::<LittleEndian>(n.to_bits())
1198                .map_err(|e| PacketError::FieldError {
1199                    packet_name: "MovementPacket",
1200                    field_name: "cur_x",
1201                    error: e,
1202                })?;
1203            flags += 0x800;
1204        }
1205        if let Some(n) = self.cur_y {
1206            tmp_buf
1207                .write_u16::<LittleEndian>(n.to_bits())
1208                .map_err(|e| PacketError::FieldError {
1209                    packet_name: "MovementPacket",
1210                    field_name: "cur_y",
1211                    error: e,
1212                })?;
1213            flags += 0x1000;
1214        }
1215        if let Some(n) = self.cur_z {
1216            tmp_buf
1217                .write_u16::<LittleEndian>(n.to_bits())
1218                .map_err(|e| PacketError::FieldError {
1219                    packet_name: "MovementPacket",
1220                    field_name: "cur_z",
1221                    error: e,
1222                })?;
1223            flags += 0x2000;
1224        }
1225        if let Some(n) = self.unk1 {
1226            tmp_buf
1227                .write_u16::<LittleEndian>(n.to_bits())
1228                .map_err(|e| PacketError::FieldError {
1229                    packet_name: "MovementPacket",
1230                    field_name: "unk1",
1231                    error: e,
1232                })?;
1233            flags += 0x4000;
1234        }
1235        if let Some(n) = self.unk_x {
1236            tmp_buf
1237                .write_u16::<LittleEndian>(n.to_bits())
1238                .map_err(|e| PacketError::FieldError {
1239                    packet_name: "MovementPacket",
1240                    field_name: "unk_x",
1241                    error: e,
1242                })?;
1243            flags += 0x8000;
1244        }
1245        if let Some(n) = self.unk_y {
1246            tmp_buf
1247                .write_u16::<LittleEndian>(n.to_bits())
1248                .map_err(|e| PacketError::FieldError {
1249                    packet_name: "MovementPacket",
1250                    field_name: "unk_y",
1251                    error: e,
1252                })?;
1253            flags += 0x10000;
1254        }
1255        if let Some(n) = self.unk_z {
1256            tmp_buf
1257                .write_u16::<LittleEndian>(n.to_bits())
1258                .map_err(|e| PacketError::FieldError {
1259                    packet_name: "MovementPacket",
1260                    field_name: "unk_z",
1261                    error: e,
1262                })?;
1263            flags += 0x20000;
1264        }
1265        if let Some(n) = self.unk2 {
1266            tmp_buf
1267                .write_u16::<LittleEndian>(n.to_bits())
1268                .map_err(|e| PacketError::FieldError {
1269                    packet_name: "MovementPacket",
1270                    field_name: "unk2",
1271                    error: e,
1272                })?;
1273            flags += 0x40000;
1274        }
1275        if let Some(n) = self.unk4 {
1276            tmp_buf.write_u8(n).map_err(|e| PacketError::FieldError {
1277                packet_name: "MovementPacket",
1278                field_name: "unk4",
1279                error: e,
1280            })?;
1281            flags += 0x180000;
1282        } else if let Some(n) = self.unk3 {
1283            tmp_buf
1284                .write_u32::<LittleEndian>(n)
1285                .map_err(|e| PacketError::FieldError {
1286                    packet_name: "MovementPacket",
1287                    field_name: "unk3",
1288                    error: e,
1289                })?;
1290            flags += 0x80000;
1291        }
1292        let mut buf = if flags == 0xFFFFF {
1293            PacketHeader::new(
1294                0x04,
1295                0x07,
1296                Flags::OBJECT_RELATED | Flags::FLAG_10 | Flags::FULL_MOVEMENT,
1297            )
1298            .write(packet_type)
1299        } else {
1300            PacketHeader::new(0x04, 0x07, Flags::OBJECT_RELATED | Flags::FLAG_10).write(packet_type)
1301        };
1302        buf.write_all(&self.unk)
1303            .map_err(|e| PacketError::FieldError {
1304                packet_name: "MovementPacket",
1305                field_name: "unk",
1306                error: e,
1307            })?;
1308        if flags != 0xFFFFF {
1309            buf.write_u24::<LittleEndian>(flags)
1310                .map_err(|e| PacketError::FieldError {
1311                    packet_name: "MovementPacket",
1312                    field_name: "flags",
1313                    error: e,
1314                })?;
1315        }
1316        buf.append(&mut tmp_buf);
1317        Ok(buf)
1318    }
1319}