diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 2ba4b7027..1f0dbe54e 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -4400,11 +4400,6 @@ struct FindPerson_Point { float z; }; -struct FindPersonRequest_Struct { - uint32 npc_id; - FindPerson_Point client_pos; -}; - //variable length packet of points struct FindPersonResult_Struct { FindPerson_Point dest; @@ -6461,6 +6456,13 @@ struct FindableLocation_Struct { /*32*/ }; +struct FindPersonRequest_Struct { + FindLocationType type; + int32 id; + FindPerson_Point client_pos; + FindPerson_Point target_pos; +}; + // Restore structure packing to default #pragma pack() diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 7d16d95e4..f43c3cfdb 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -4538,10 +4538,14 @@ namespace RoF DECODE_LENGTH_EXACT(structs::FindPersonRequest_Struct); SETUP_DIRECT_DECODE(FindPersonRequest_Struct, structs::FindPersonRequest_Struct); - IN(npc_id); + IN(type) + IN(id); IN(client_pos.x); IN(client_pos.y); IN(client_pos.z); + IN(target_pos.x); + IN(target_pos.y); + IN(target_pos.z); FINISH_DIRECT_DECODE(); } diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 9024f93b9..db1df1cde 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -5517,10 +5517,14 @@ namespace RoF2 DECODE_LENGTH_EXACT(structs::FindPersonRequest_Struct); SETUP_DIRECT_DECODE(FindPersonRequest_Struct, structs::FindPersonRequest_Struct); - IN(npc_id); + IN(type) + IN(id); IN(client_pos.x); IN(client_pos.y); IN(client_pos.z); + IN(target_pos.x); + IN(target_pos.y); + IN(target_pos.z); FINISH_DIRECT_DECODE(); } diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index fa43b65b3..b16708f76 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -4016,14 +4016,13 @@ struct FindPerson_Point { }; struct FindPersonRequest_Struct { -/*00*/ uint32 unknown00; -/*04*/ uint32 npc_id; -/*08*/ uint32 unknown08; -/*12*/ uint32 unknown12; +/*00*/ FindLocationType type; +/*04*/ int32 id; +/*08*/ int32 unknown08; +/*12*/ int32 unknown12; /*16*/ FindPerson_Point client_pos; -/*28*/ uint32 unknown28; -/*32*/ uint32 unknown32; -/*36*/ uint32 unknown36; +/*28*/ FindPerson_Point target_pos; +/*40*/ }; //variable length packet of points diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index d502eddd6..d5f53f8e3 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -3779,14 +3779,13 @@ struct FindPerson_Point { }; struct FindPersonRequest_Struct { -/*00*/ uint32 unknown00; -/*04*/ uint32 npc_id; -/*08*/ uint32 unknown08; -/*12*/ uint32 unknown12; -/*16*/ FindPerson_Point client_pos; -/*28*/ uint32 unknown28; -/*32*/ uint32 unknown32; -/*36*/ uint32 unknown36; + /*00*/ FindLocationType type; + /*04*/ int32 id; + /*08*/ int32 unknown08; + /*12*/ int32 unknown12; + /*16*/ FindPerson_Point client_pos; + /*28*/ FindPerson_Point target_pos; + /*40*/ }; //variable length packet of points diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index d8f174196..29fe13040 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -3150,7 +3150,8 @@ namespace SoD DECODE_LENGTH_EXACT(structs::FindPersonRequest_Struct); SETUP_DIRECT_DECODE(FindPersonRequest_Struct, structs::FindPersonRequest_Struct); - IN(npc_id); + emu->type = FindLocationType::LocationPlayer; + emu->id = eq->npc_id; IN(client_pos.x); IN(client_pos.y); IN(client_pos.z); diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index be18a78c7..79b4c8963 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -2605,7 +2605,8 @@ namespace SoF DECODE_LENGTH_EXACT(structs::FindPersonRequest_Struct); SETUP_DIRECT_DECODE(FindPersonRequest_Struct, structs::FindPersonRequest_Struct); - IN(npc_id); + emu->type = FindLocationType::LocationPlayer; + emu->id = eq->npc_id; IN(client_pos.x); IN(client_pos.y); IN(client_pos.z); diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index e9cec60a6..22c34d45b 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -3327,6 +3327,20 @@ namespace Titanium FINISH_DIRECT_DECODE(); } + DECODE(OP_FindPersonRequest) + { + DECODE_LENGTH_EXACT(structs::FindPersonRequest_Struct); + SETUP_DIRECT_DECODE(FindPersonRequest_Struct, structs::FindPersonRequest_Struct); + + emu->type = FindLocationType::LocationPlayer; + emu->id = eq->npc_id; + IN(client_pos.x); + IN(client_pos.y); + IN(client_pos.z); + + FINISH_DIRECT_DECODE(); + } + // file scope helper methods void SerializeItem(EQ::OutBuffer& ob, const EQ::ItemInstance *inst, int16 slot_id_in, uint8 depth) { const char *protection = "\\\\\\\\\\"; diff --git a/common/patches/titanium_ops.h b/common/patches/titanium_ops.h index a891b8102..8d9285fe9 100644 --- a/common/patches/titanium_ops.h +++ b/common/patches/titanium_ops.h @@ -132,6 +132,7 @@ D(OP_TradeSkillCombine) D(OP_TributeItem) D(OP_WearChange) D(OP_WhoAllRequest) +D(OP_FindPersonRequest) #undef E #undef D diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index da07f068e..98f587918 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -3982,7 +3982,8 @@ namespace UF DECODE_LENGTH_EXACT(structs::FindPersonRequest_Struct); SETUP_DIRECT_DECODE(FindPersonRequest_Struct, structs::FindPersonRequest_Struct); - IN(npc_id); + emu->type = FindLocationType::LocationPlayer; + emu->id = eq->npc_id; IN(client_pos.x); IN(client_pos.y); IN(client_pos.z); diff --git a/zone/client.cpp b/zone/client.cpp index d0a8d97b0..a27941b24 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -11995,15 +11995,13 @@ void Client::MaxSkills() } } -void Client::SendPath(Mob* target) -{ +void Client::SendPath(Mob* target) { if (!target) { EQApplicationPacket outapp(OP_FindPersonReply, 0); QueuePacket(&outapp); return; } - if ( !RuleB(Pathing, Find) && RuleB(Bazaar, EnableWarpToTrader) && @@ -12011,7 +12009,7 @@ void Client::SendPath(Mob* target) ( target->CastToClient()->IsTrader() || target->CastToClient()->IsBuyer() - ) + ) ) { Message( Chat::Yellow, @@ -12031,6 +12029,17 @@ void Client::SendPath(Mob* target) return; } + glm::vec3 target_loc( + target->GetX(), + target->GetY(), + target->GetZ() + (target->GetSize() < 6.0 ? 6 : target->GetSize()) * HEAD_POSITION + ); + + SendPath(target_loc); +} + +void Client::SendPath(const glm::vec3& loc) +{ std::vector points; if (!RuleB(Pathing, Find) || !zone->pathing) { @@ -12041,9 +12050,9 @@ void Client::SendPath(Mob* target) a.x = GetX(); a.y = GetY(); a.z = GetZ(); - b.x = target->GetX(); - b.y = target->GetY(); - b.z = target->GetZ(); + b.x = loc.x; + b.y = loc.y; + b.z = loc.z; points.push_back(a); points.push_back(b); @@ -12056,9 +12065,9 @@ void Client::SendPath(Mob* target) ); glm::vec3 path_end( - target->GetX(), - target->GetY(), - target->GetZ() + (target->GetSize() < 6.0 ? 6 : target->GetSize()) * HEAD_POSITION + loc.x, + loc.y, + loc.z ); bool partial = false; @@ -12081,18 +12090,6 @@ void Client::SendPath(Mob* target) bool leads_to_teleporter = false; - auto v = path_list.back(); - - p.x = v.pos.x; - p.y = v.pos.y; - p.z = v.pos.z; - points.push_back(p); - - p.x = GetX(); - p.y = GetY(); - p.z = GetZ(); - points.push_back(p); - for (const auto &n: path_list) { if (n.teleport) { leads_to_teleporter = true; @@ -12108,14 +12105,6 @@ void Client::SendPath(Mob* target) ++point_number; } - - if (!leads_to_teleporter) { - p.x = target->GetX(); - p.y = target->GetY(); - p.z = target->GetZ(); - - points.push_back(p); - } } SendPathPacket(points); diff --git a/zone/client.h b/zone/client.h index 5acc388b3..7c8924300 100644 --- a/zone/client.h +++ b/zone/client.h @@ -869,6 +869,7 @@ public: int GetAccountAge(); void SendPath(Mob* target); + void SendPath(const glm::vec3 &loc); bool IsDiscovered(uint32 itemid); void DiscoverItem(uint32 itemid); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 95689c39a..4664546f4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -6477,9 +6477,40 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app) else { auto* t = (FindPersonRequest_Struct*)app->pBuffer; - auto* m = entity_list.GetMob(t->npc_id); + switch (t->type) { + case FindLocationType::LocationPlayer: { + auto* m = entity_list.GetMob(t->id); + SendPath(m); + break; + } + case FindLocationType::LocationSwitch: + { + auto *d = entity_list.GetDoorsByDoorID(t->id); + if (d == nullptr) { + Message(Chat::Red, "Switch for find not found."); + return; + } - SendPath(m); + glm::vec3 door_loc; + door_loc.x = d->GetX(); + door_loc.y = d->GetY(); + door_loc.z = d->GetZ(); + SendPath(door_loc); + break; + } + case FindLocationType::LocationLocation: + { + glm::vec3 target_pos; + target_pos.x = t->target_pos.x; + target_pos.y = t->target_pos.y; + target_pos.z = t->target_pos.z; + + SendPath(target_pos); + break; + } + default: + break; + } } } diff --git a/zone/pathing.cpp b/zone/pathing.cpp index 5a44b2832..3548fe7a1 100644 --- a/zone/pathing.cpp +++ b/zone/pathing.cpp @@ -72,22 +72,19 @@ void Client::SendPathPacket(const std::vector &points) { Message(Chat::System, "Total points %u", points.size()); } - int len = sizeof(FindPersonResult_Struct) + (points.size() + 1) * sizeof(FindPerson_Point); + int len = (points.size() + 1) * sizeof(FindPerson_Point); auto outapp = new EQApplicationPacket(OP_FindPersonReply, len); - FindPersonResult_Struct* fpr = (FindPersonResult_Struct*)outapp->pBuffer; - - std::vector::iterator cur, end; - cur = points.begin(); - end = points.end(); - unsigned int r; - for (r = 0; cur != end; ++cur, r++) { - fpr->path[r] = *cur; + auto& last = points.back(); + outapp->WriteFloat(last.y); + outapp->WriteFloat(last.x); + outapp->WriteFloat(last.z); + + for (auto& p : points) { + outapp->WriteFloat(p.y); + outapp->WriteFloat(p.x); + outapp->WriteFloat(p.z); } - //put the last element into the destination field - --cur; - fpr->path[r] = *cur; - fpr->dest = *cur; FastQueuePacket(&outapp); })