From 469b9b276e86300bd826345d7738fafac227b596 Mon Sep 17 00:00:00 2001 From: ccrs Date: Tue, 10 Feb 2026 18:05:16 +0100 Subject: [PATCH 1/5] if the creature vehicle stops evading, creature passengers who are evading stop evading too --- src/server/game/Entities/Vehicle/Vehicle.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index e746cc0f..7607db00 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -86,6 +86,22 @@ void Vehicle::InstallAllAccessories(bool evading) if (GetBase()->GetTypeId() == TYPEID_PLAYER || !evading) RemoveAllPassengers(); // We might have aura's saved in the DB with now invalid casters - remove + if (GetBase()->GetTypeId() == TYPEID_UNIT && evading) + for (auto const& [_, seat] : Seats) + { + if (!seat.Passenger.Guid.IsEmpty() && seat.Passenger.Guid.GetTypeId() == TYPEID_UNIT) + if (Creature* passenger = ObjectAccessor::GetCreature(*_me, seat.Passenger.Guid)) + if (passenger->IsInEvadeMode()) + { + passenger->ClearUnitState(UNIT_STATE_EVADE); + passenger->SetSpawnHealth(); + passenger->LoadCreaturesAddon(); + if (passenger->IsVehicle()) + passenger->GetVehicleKit()->Reset(true); + passenger->AI()->JustReachedHome(); + } + } + VehicleAccessoryList const* accessories = sObjectMgr->GetVehicleAccessoryList(this); if (!accessories) return; From 2e7551b4e7ddc23a4b1eb6ad348c7ab5a9a9d149 Mon Sep 17 00:00:00 2001 From: ccrs Date: Tue, 10 Feb 2026 18:21:38 +0100 Subject: [PATCH 2/5] here is that --- src/server/game/AI/CreatureAI.cpp | 9 +++++++++ src/server/game/AI/CreatureAI.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 8bd4a4e7..d44d7e40 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -283,6 +283,15 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/) me->GetSpellHistory()->ResetAllCooldowns(); EngagementOver(); + if (Vehicle* myVehicle = me->GetVehicleKit()) + for (auto const& [_, seat] : myVehicle->Seats) + { + if (!seat.Passenger.Guid.IsEmpty() && seat.Passenger.Guid.GetTypeId() == TYPEID_UNIT) + if (Creature* passenger = ObjectAccessor::GetCreature(*me, seat.Passenger.Guid)) + if (passenger->IsAIEnabled() && passenger->AI()) + passenger->AI()->EnterEvadeMode(EVADE_REASON_VEHICLE_EVADE); + } + return true; } diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 69bc6343..0184bcde 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -96,6 +96,7 @@ class TC_GAME_API CreatureAI : public UnitAI EVADE_REASON_NO_PATH, // the creature was unable to reach its target for over 5 seconds EVADE_REASON_SEQUENCE_BREAK, // this is a boss and the pre-requisite encounters for engaging it are not defeated yet EVADE_REASON_OTHER, // anything else + EVADE_REASON_VEHICLE_EVADE }; explicit CreatureAI(Creature* creature); From d3a0416e825898fb404ab18acd98e087a9d5e3c8 Mon Sep 17 00:00:00 2001 From: ccrs Date: Tue, 10 Feb 2026 18:41:03 +0100 Subject: [PATCH 3/5] this should be it --- src/server/game/AI/CoreAI/GuardAI.cpp | 5 +++-- src/server/game/AI/CreatureAI.cpp | 6 ++++++ src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp | 8 +++++++- src/server/game/AI/SmartScripts/SmartAI.cpp | 5 ++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp index 9235562f..a592870b 100644 --- a/src/server/game/AI/CoreAI/GuardAI.cpp +++ b/src/server/game/AI/CoreAI/GuardAI.cpp @@ -50,7 +50,7 @@ bool GuardAI::CanSeeAlways(WorldObject const* obj) return false; } -void GuardAI::EnterEvadeMode(EvadeReason /*why*/) +void GuardAI::EnterEvadeMode(EvadeReason why) { if (!me->IsAlive()) { @@ -66,7 +66,8 @@ void GuardAI::EnterEvadeMode(EvadeReason /*why*/) me->CombatStop(true); EngagementOver(); - me->GetMotionMaster()->MoveTargetedHome(); + if (why != EVADE_REASON_VEHICLE_EVADE) + me->GetMotionMaster()->MoveTargetedHome(); } void GuardAI::JustDied(Unit* killer) diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index d44d7e40..64e29c40 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -186,6 +186,12 @@ void CreatureAI::EnterEvadeMode(EvadeReason why) TC_LOG_DEBUG("scripts.ai", "CreatureAI::EnterEvadeMode: entering evade mode (why: {}) ({})", why, me->GetGUID().ToString()); + if (why == EVADE_REASON_VEHICLE_EVADE) + { + Reset(); + return; + } + if (!me->GetVehicle()) // otherwise me will be in evade mode forever { if (Unit* owner = me->GetCharmerOrOwner()) diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp index 57440748..0e919bfa 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp @@ -93,7 +93,7 @@ void EscortAI::ReturnToLastPoint() me->GetMotionMaster()->MovePoint(POINT_LAST_POINT, me->GetHomePosition()); } -void EscortAI::EnterEvadeMode(EvadeReason /*why*/) +void EscortAI::EnterEvadeMode(EvadeReason why) { me->RemoveAllAuras(); me->CombatStop(true); @@ -101,6 +101,12 @@ void EscortAI::EnterEvadeMode(EvadeReason /*why*/) EngagementOver(); + if (why == EVADE_REASON_VEHICLE_EVADE) + { + Reset(); + return; + } + if (HasEscortState(STATE_ESCORT_ESCORTING)) { AddEscortState(STATE_ESCORT_RETURNING); diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 7ea2a11b..e07a3ee2 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -394,7 +394,7 @@ void SmartAI::MovementInform(uint32 type, uint32 id) _OOCReached = true; } -void SmartAI::EnterEvadeMode(EvadeReason /*why*/) +void SmartAI::EnterEvadeMode(EvadeReason why) { if (_evadeDisabled) { @@ -417,6 +417,9 @@ void SmartAI::EnterEvadeMode(EvadeReason /*why*/) SetRun(_run); + if (why == EVADE_REASON_VEHICLE_EVADE) + return; + if (me->IsCharmed() && me->GetCharmerOrOwner()) { Unit* owner = me->GetCharmerOrOwner(); From aefcab453f8938ede6e6855145f76bb2d94952dd Mon Sep 17 00:00:00 2001 From: ccrs Date: Tue, 10 Feb 2026 19:11:12 +0100 Subject: [PATCH 4/5] weird case that the creature ejects the other creature while evading? --- src/server/game/Entities/Unit/Unit.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 5a7a2eba..83002004 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12788,6 +12788,16 @@ void Unit::_ExitVehicle(Position const* exitPosition) else ToTempSummon()->UnSummon(2000); // Approximation } + else if (HasUnitState(UNIT_STATE_EVADE) && GetTypeId() == TYPEID_UNIT) + { + Creature* toCreature = ToCreature(); + toCreature->ClearUnitState(UNIT_STATE_EVADE); + toCreature->SetSpawnHealth(); + toCreature->LoadCreaturesAddon(); + if (toCreature->IsVehicle()) + toCreature->GetVehicleKit()->Reset(true); + toCreature->AI()->JustReachedHome(); + } } void Unit::BuildMovementPacket(ByteBuffer *data) const From f8444d175dc6958a7190ba43c50b82aadae8c98d Mon Sep 17 00:00:00 2001 From: ccrs Date: Tue, 10 Feb 2026 19:16:38 +0100 Subject: [PATCH 5/5] saferish --- src/server/game/Entities/Unit/Unit.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 83002004..cf6d2089 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12725,6 +12725,9 @@ void Unit::_ExitVehicle(Position const* exitPosition) SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT AddUnitState(UNIT_STATE_MOVE); + bool wasEvading = HasUnitState(UNIT_STATE_EVADE); + if (wasEvading) + ClearUnitState(UNIT_STATE_EVADE); if (player) player->SetFallInformation(0, GetPositionZ()); @@ -12788,10 +12791,9 @@ void Unit::_ExitVehicle(Position const* exitPosition) else ToTempSummon()->UnSummon(2000); // Approximation } - else if (HasUnitState(UNIT_STATE_EVADE) && GetTypeId() == TYPEID_UNIT) + else if (wasEvading && GetTypeId() == TYPEID_UNIT) { Creature* toCreature = ToCreature(); - toCreature->ClearUnitState(UNIT_STATE_EVADE); toCreature->SetSpawnHealth(); toCreature->LoadCreaturesAddon(); if (toCreature->IsVehicle())