diff --git a/common/emu_oplist.h b/common/emu_oplist.h index aa8190720..83b7d2df0 100644 --- a/common/emu_oplist.h +++ b/common/emu_oplist.h @@ -374,6 +374,7 @@ N(OP_MultiLineMsg), N(OP_NewSpawn), N(OP_NewTitlesAvailable), N(OP_NewZone), +N(OP_NPCMoveUpdate), N(OP_OnLevelMessage), N(OP_OpenContainer), N(OP_OpenDiscordMerchant), diff --git a/common/patches/larion.cpp b/common/patches/larion.cpp index 269fe28ea..4ed644b4d 100644 --- a/common/patches/larion.cpp +++ b/common/patches/larion.cpp @@ -2349,6 +2349,64 @@ namespace Larion FINISH_ENCODE(); } + ENCODE(OP_RequestClientZoneChange) + { + ENCODE_LENGTH_EXACT(RequestClientZoneChange_Struct); + SETUP_DIRECT_ENCODE(RequestClientZoneChange_Struct, structs::RequestClientZoneChange_Struct); + + OUT(zone_id); + OUT(instance_id); + OUT(y); + OUT(x); + OUT(z); + OUT(heading); + eq->type = 0x0b; + eq->unknown004 = 0xffffffff; + eq->unknown172 = 0x0168b500; + + FINISH_ENCODE(); + } + + ENCODE(OP_ZoneChange) + { + ENCODE_LENGTH_EXACT(ZoneChange_Struct); + SETUP_DIRECT_ENCODE(ZoneChange_Struct, structs::ZoneChange_Struct); + + memcpy(eq->char_name, emu->char_name, sizeof(emu->char_name)); + OUT(zoneID); + OUT(instanceID); + OUT(y); + OUT(x); + OUT(z) + OUT(zone_reason); + OUT(success); + + if (eq->success < 0) + eq->success -= 1; + + FINISH_ENCODE(); + } + + ENCODE(OP_ClientUpdate) + { + ENCODE_LENGTH_EXACT(PlayerPositionUpdateServer_Struct); + SETUP_DIRECT_ENCODE(PlayerPositionUpdateServer_Struct, structs::PlayerPositionUpdateServer_Struct); + + OUT(spawn_id); + OUT(vehicle_id); + eq->position.x = emu->x_pos; + eq->position.y = emu->y_pos; + eq->position.z = emu->z_pos; + eq->position.heading = emu->heading; + eq->position.deltaX = emu->delta_x; + eq->position.deltaY = emu->delta_y; + eq->position.deltaZ = emu->delta_z; + eq->position.deltaHeading = emu->delta_heading; + eq->position.animation = emu->animation; + + FINISH_ENCODE(); + } + // DECODE methods DECODE(OP_EnterWorld) @@ -2372,5 +2430,44 @@ namespace Larion FINISH_DIRECT_DECODE(); } + + DECODE(OP_ZoneChange) + { + DECODE_LENGTH_EXACT(structs::ZoneChange_Struct); + SETUP_DIRECT_DECODE(ZoneChange_Struct, structs::ZoneChange_Struct); + + memcpy(emu->char_name, eq->char_name, sizeof(emu->char_name)); + IN(zoneID); + IN(instanceID); + IN(y); + IN(x); + IN(z) + IN(zone_reason); + IN(success); + + FINISH_DIRECT_DECODE(); + } + + DECODE(OP_ClientUpdate) + { + // for some odd reason, there is an extra byte on the end of this on occasion.. + DECODE_LENGTH_ATLEAST(structs::PlayerPositionUpdateClient_Struct); + SETUP_DIRECT_DECODE(PlayerPositionUpdateClient_Struct, structs::PlayerPositionUpdateClient_Struct); + + IN(spawn_id); + IN(vehicle_id); + IN(sequence); + emu->x_pos = eq->position.x; + emu->y_pos = eq->position.y; + emu->z_pos = eq->position.z; + emu->heading = eq->position.heading; + emu->delta_x = eq->position.delta_x; + emu->delta_y = eq->position.delta_y; + emu->delta_z = eq->position.delta_z; + emu->delta_heading = eq->position.delta_heading; + emu->animation = eq->position.animation; + + FINISH_DIRECT_DECODE(); + } } /*Larion*/ diff --git a/common/patches/larion_ops.h b/common/patches/larion_ops.h index 862fcae9e..7c801405e 100644 --- a/common/patches/larion_ops.h +++ b/common/patches/larion_ops.h @@ -16,10 +16,14 @@ E(OP_NewZone) E(OP_SpawnDoor) E(OP_GroundSpawn) E(OP_SendZonepoints) - +E(OP_RequestClientZoneChange) +E(OP_ZoneChange) +E(OP_ClientUpdate) //list of packets we need to decode on the way in: D(OP_EnterWorld) D(OP_ZoneEntry) +D(OP_ZoneChange) +D(OP_ClientUpdate) #undef E #undef D diff --git a/common/patches/larion_structs.h b/common/patches/larion_structs.h index 606f7bf06..8b238062f 100644 --- a/common/patches/larion_structs.h +++ b/common/patches/larion_structs.h @@ -257,6 +257,41 @@ namespace Larion { }; }; + struct Client_Position + { + /*00*/ float delta_x; + /*04*/ float x; + /*08*/ float z; + /*12*/ signed animation : 10; + signed padding1 : 22; + /*16*/ unsigned pitch : 12; + signed padding2 : 20; + /*20*/ float delta_y; + /*24*/ float y; + /*28*/ signed delta_heading : 10; + signed padding3 : 22; + /*32*/ signed heading : 12; + signed padding4 : 20; + /*36*/ float delta_z; + /*40*/ + }; + + struct PlayerPositionUpdateServer_Struct + { + /*00*/ uint16 spawn_id; + /*02*/ uint16 vehicle_id; + /*04*/ Spawn_Struct_Position position; + /*24*/ + }; + + struct PlayerPositionUpdateClient_Struct { + /*00*/ uint16 sequence; + /*02*/ uint16 spawn_id; + /*04*/ uint16 vehicle_id; + /*06*/ Client_Position position; + /*46*/ + }; + struct Door_Struct { /*000*/ char name[32]; @@ -321,6 +356,35 @@ namespace Larion { /*068*/ int32 unknown2; //larion handles these differently so for now im just going to ignore them till i figure it out }; + struct ZoneChange_Struct { + /*000*/ char char_name[64]; // Character Name + /*064*/ uint16 zoneID; + /*066*/ uint16 instanceID; + /*068*/ uint32 Unknown068; + /*072*/ uint32 Unknown072; + /*076*/ float y; + /*080*/ float x; + /*084*/ float z; + /*088*/ uint32 zone_reason; //0x0A == death, I think + /*092*/ int32 success; // =0 client->server, =1 server->client, -X=specific error + /*096*/ uint32 Unknown096; // Not sure the extra 4 bytes goes here or earlier in the struct. + /*100*/ + }; + + struct RequestClientZoneChange_Struct { + /*000*/ uint16 zone_id; + /*002*/ uint16 instance_id; + /*004*/ uint32 unknown004; + /*008*/ float y; + /*012*/ float x; + /*016*/ float z; + /*020*/ float heading; + /*024*/ uint32 type; //unknown... values + /*032*/ uint8 unknown032[144]; + /*172*/ uint32 unknown172; + /*176*/ + }; + #pragma pack() }; //end namespace structs diff --git a/utils/patches/patch_Larion.conf b/utils/patches/patch_Larion.conf index 43c036774..d88718599 100644 --- a/utils/patches/patch_Larion.conf +++ b/utils/patches/patch_Larion.conf @@ -68,8 +68,8 @@ OP_PlayerProfile=0x1c76 OP_TimeOfDay=0x3736 OP_LevelUpdate=0x0000 #0x0eb2 OP_Stamina=0x0000 #0x1563 -OP_RequestClientZoneChange=0x0000 #0x0191 -OP_ZoneChange=0x0000 #0x17a3 +OP_RequestClientZoneChange=0x0191 +OP_ZoneChange=0x17a3 OP_LockoutTimerInfo=0x0000 OP_ZoneServerReady=0x0000 OP_ZoneInUnknown=0x0000 @@ -110,7 +110,7 @@ OP_GuildMemberList=0x0000 OP_GuildMOTD=0x0000 OP_CharInventory=0x21d6 OP_WearChange=0x0000 #0x44c0 -OP_ClientUpdate=0x0000 #0x3a4b +OP_ClientUpdate=0x3a4b OP_ClientReady=0x0831 OP_SetServerFilter=0x0000 #0x6b7f