From 7e724568a6844251f88ff1dd60b50db54178e2a2 Mon Sep 17 00:00:00 2001 From: Uleat Date: Thu, 5 Dec 2019 18:24:29 -0500 Subject: [PATCH] Update to boat-related opcode handlers --- zone/client_packet.cpp | 36 ++++++++++++++++++++++++------------ zone/mob.cpp | 19 ++++++++++++++++++- zone/mob.h | 1 + 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index c99ffe3b8..8b21c2f70 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -3838,8 +3838,9 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app) boatname[63] = '\0'; Mob* boat = entity_list.GetMob(boatname); - if (!boat || (boat->GetRace() != CONTROLLED_BOAT && boat->GetRace() != 502)) + if (!boat || !boat->IsControllableBoat()) { return; + } controlling_boat_id = boat->GetID(); // set the client's BoatID to show that it's on this boat Message(0, "Board boat: %s", boatname); @@ -4941,12 +4942,16 @@ void Client::Handle_OP_ControlBoat(const EQApplicationPacket *app) LogError("Wrong size: OP_ControlBoat, size=[{}], expected [{}]", app->size, sizeof(ControlBoat_Struct)); return; } + ControlBoat_Struct* cbs = (ControlBoat_Struct*)app->pBuffer; Mob* boat = entity_list.GetMob(cbs->boatId); - if (boat == 0) - return; // do nothing if the boat isn't valid + if (!boat) { - if (!boat->IsNPC() || (boat->GetRace() != CONTROLLED_BOAT && boat->GetRace() != 502)) + LogError("Player tried to take control of non-existent boat (char_id: %u, boat_eid: %u)", CharacterID(), cbs->boatId); + return; // do nothing if the boat isn't valid + } + + if (!boat->IsNPC() || !boat->IsControllableBoat()) { char *hacked_string = nullptr; MakeAnyLenString(&hacked_string, "OP_Control Boat was sent against %s which is of race %u", boat->GetName(), boat->GetRace()); @@ -4957,20 +4962,24 @@ void Client::Handle_OP_ControlBoat(const EQApplicationPacket *app) if (cbs->TakeControl) { // this uses the boat's target to indicate who has control of it. It has to check hate to make sure the boat isn't actually attacking anyone. - if ((boat->GetTarget() == 0) || (boat->GetTarget() == this && boat->GetHateAmount(this) == 0)) { + if (!boat->GetTarget() || (boat->GetTarget() == this && boat->GetHateAmount(this) == 0)) { boat->SetTarget(this); } else { + this->MessageString(Chat::Red, IN_USE); return; } } - else - boat->SetTarget(0); + else { + if (boat->GetTarget() == this) { + boat->SetTarget(nullptr); + } + } + + // client responds better to a packet echo than an empty op + QueuePacket(app); - auto outapp = new EQApplicationPacket(OP_ControlBoat, 0); - FastQueuePacket(&outapp); - safe_delete(outapp); // have the boat signal itself, so quests can be triggered by boat use boat->CastToNPC()->SignalNPC(0); } @@ -8940,10 +8949,13 @@ void Client::Handle_OP_LeaveBoat(const EQApplicationPacket *app) { Mob* boat = entity_list.GetMob(this->controlling_boat_id); // find the mob corresponding to the boat id if (boat) { - if ((boat->GetTarget() == this) && boat->GetHateAmount(this) == 0) // if the client somehow left while still controlling the boat (and the boat isn't attacking them) - boat->SetTarget(0); // fix it to stop later problems + if ((boat->GetTarget() == this) && boat->GetHateAmount(this) == 0) { // if the client somehow left while still controlling the boat (and the boat isn't attacking them) + boat->SetTarget(nullptr); // fix it to stop later problems + } } + this->controlling_boat_id = 0; + return; } diff --git a/zone/mob.cpp b/zone/mob.cpp index 37d59c78c..5cbd4d70f 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -4829,7 +4829,24 @@ void Mob::RemoveNimbusEffect(int effectid) } bool Mob::IsBoat() const { - return (race == 72 || race == 73 || race == 114 || race == 404 || race == 550 || race == 551 || race == 552); + + return ( + race == RACE_SHIP_72 || + race == RACE_LAUNCH_73 || + race == RACE_GHOST_SHIP_114 || + race == RACE_SHIP_404 || + race == RACE_MERCHANT_SHIP_550 || + race == RACE_PIRATE_SHIP_551 || + race == RACE_GHOST_SHIP_552 + ); +} + +bool Mob::IsControllableBoat() const { + + return ( + race == RACE_BOAT_141 || + race == RACE_ROWBOAT_502 + ); } void Mob::SetBodyType(bodyType new_body, bool overwrite_orig) { diff --git a/zone/mob.h b/zone/mob.h index bcf3adcca..25e62f29e 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -566,6 +566,7 @@ public: inline const float GetBaseSize() const { return base_size; } inline const GravityBehavior GetFlyMode() const { return flymode; } bool IsBoat() const; + bool IsControllableBoat() const; //Group virtual bool HasRaid() = 0;