fix(Core/Vehicles): feat vehicle seat addon, vehicle enter/exit positions (#20082)

* implement initial vehicle_seat_addon

Co-authored-by: Ovah <dreadkiller@gmx.de>

* add more vehicle_seat_addon data

* make exiting passenger visible

fixes "immediate despawn" of travelers mammoth

* style, update comments

* remove hacked pos relocate

* remove sending MSG_MOVE_ROOT/UNROOT on Ack

* set and unset UNIT_NPC_FLAG_PLAYER_VEHICLE on init/entry

* ulduar demolisher: remove flag correction and no longer needed usableseat

* fixup! implement initial vehicle_seat_addon

* fixup! fixup! implement initial vehicle_seat_addon

* re-add AddPassenger Flame Leviathan hack

was commented by mistake

* Update rev_1725993194571320983.sql

add missing ticks

---------

Co-authored-by: Ovah <dreadkiller@gmx.de>
This commit is contained in:
Jelle Meeus
2024-10-11 07:08:14 +02:00
committed by GitHub
parent e43b760c08
commit 859a42a41e
10 changed files with 192 additions and 54 deletions

View File

@@ -19756,6 +19756,8 @@ void Unit::_ExitVehicle(Position const* exitPosition)
if (!m_vehicle)
return;
// This should be done before dismiss, because there may be some aura removal
VehicleSeatAddon const* seatAddon = m_vehicle->GetSeatAddonForSeatOfPassenger(this);
m_vehicle->RemovePassenger(this);
Player* player = ToPlayer();
@@ -19764,7 +19766,6 @@ void Unit::_ExitVehicle(Position const* exitPosition)
if (player && player->duel && player->duel->IsMounted)
player->DuelComplete(DUEL_FLED);
// This should be done before dismiss, because there may be some aura removal
Vehicle* vehicle = m_vehicle;
Unit* vehicleBase = m_vehicle->GetBase();
m_vehicle = nullptr;
@@ -19775,33 +19776,22 @@ void Unit::_ExitVehicle(Position const* exitPosition)
SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
Position pos;
if (!exitPosition) // Exit position not specified
pos = vehicleBase->GetPosition(); // This should use passenger's current position, leaving it as it is now
// because we calculate positions incorrect (sometimes under map)
else
// If we ask for a specific exit position, use that one. Otherwise allow scripts to modify it
if (exitPosition)
pos = *exitPosition;
// HACK
VehicleEntry const* vehicleInfo = vehicle->GetVehicleInfo();
if (vehicleInfo)
else
{
if (vehicleInfo->m_ID == 380) // Kologarn right arm
// Set exit position to vehicle position and use the current orientation
pos = vehicleBase->GetPosition(); // This should use passenger's current position, leaving it as it is now
pos.SetOrientation(vehicleBase->GetOrientation());
// Change exit position based on seat entry addon data
if (seatAddon)
{
pos.Relocate(1776.0f, -24.0f, 448.75f, 0.0f);
}
else if (vehicleInfo->m_ID == 91) // Helsman's Ship
{
pos.Relocate(2802.18f, 7054.91f, -0.6f, 4.67f);
}
else if (vehicleInfo->m_ID == 349) // AT Mounts, dismount to the right
{
float x = pos.GetPositionX() + 2.0f * cos(pos.GetOrientation() - M_PI / 2.0f);
float y = pos.GetPositionY() + 2.0f * std::sin(pos.GetOrientation() - M_PI / 2.0f);
float z = GetMapHeight(x, y, pos.GetPositionZ());
if (z > INVALID_HEIGHT)
{
pos.Relocate(x, y, z);
}
if (seatAddon->ExitParameter == VehicleExitParameters::VehicleExitParamOffset)
pos.RelocateOffset({ seatAddon->ExitParameterX, seatAddon->ExitParameterY, seatAddon->ExitParameterZ, seatAddon->ExitParameterO });
else if (seatAddon->ExitParameter == VehicleExitParameters::VehicleExitParamDest)
pos.Relocate({ seatAddon->ExitParameterX, seatAddon->ExitParameterY, seatAddon->ExitParameterZ, seatAddon->ExitParameterO });
}
}
@@ -19821,11 +19811,12 @@ void Unit::_ExitVehicle(Position const* exitPosition)
}
// xinef: hack for flameleviathan seat vehicle
VehicleEntry const* vehicleInfo = vehicle->GetVehicleInfo();
if (!vehicleInfo || vehicleInfo->m_ID != 341)
{
Movement::MoveSplineInit init(this);
init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
init.SetFacing(GetOrientation());
init.SetFacing(vehicleBase->GetOrientation());
init.SetTransportExit();
init.Launch();
}
@@ -19878,10 +19869,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
setDeathState(DeathState::JustDied);
// If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
else
{
SetVisible(false);
ToTempSummon()->UnSummon(2000); // Approximation
}
}
if (player)

View File

@@ -34,15 +34,18 @@ Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry)
if (uint32 seatId = _vehicleInfo->m_seatID[i])
if (VehicleSeatEntry const* veSeat = sVehicleSeatStore.LookupEntry(seatId))
{
Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
VehicleSeatAddon const* addon = sObjectMgr->GetVehicleSeatAddon(seatId);
Seats.insert(std::make_pair(i, VehicleSeat(veSeat, addon)));
if (veSeat->CanEnterOrExit())
++_usableSeatNum;
}
}
// Ulduar demolisher
if (vehInfo->m_ID == 338)
++_usableSeatNum;
// Set or remove correct flags based on available seats. Will overwrite db data (if wrong).
if (_usableSeatNum)
_me->SetNpcFlag((_me->IsPlayer() ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK));
else
_me->RemoveNpcFlag((_me->IsPlayer() ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK));
InitMovementInfoForBase();
}
@@ -230,6 +233,15 @@ Unit* Vehicle::GetPassenger(int8 seatId) const
return ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger.Guid);
}
VehicleSeatAddon const* Vehicle::GetSeatAddonForSeatOfPassenger(Unit const* passenger) const
{
for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); itr++)
if (!itr->second.IsEmpty() && itr->second.Passenger.Guid == passenger->GetGUID())
return itr->second.SeatAddon;
return nullptr;
}
int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
{
SeatMap::const_iterator seat = Seats.find(seatId);
@@ -356,12 +368,9 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
ASSERT(_usableSeatNum);
--_usableSeatNum;
if (!_usableSeatNum)
{
if (_me->IsPlayer())
_me->RemoveNpcFlag(UNIT_NPC_FLAG_PLAYER_VEHICLE);
else
_me->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
}
_me->RemoveNpcFlag(_me->IsPlayer() ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK);
else
_me->SetNpcFlag(_me->IsPlayer() ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK);
}
if (!_me || !_me->IsInWorld() || _me->IsDuringRemoveFromWorld())
@@ -376,7 +385,14 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
VehicleSeatEntry const* veSeat = seat->second.SeatInfo;
unit->m_movementInfo.transport.pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
VehicleSeatAddon const* veSeatAddon = seat->second.SeatAddon;
float o = veSeatAddon ? veSeatAddon->SeatOrientationOffset : 0.f;
float x = veSeat->m_attachmentOffsetX;
float y = veSeat->m_attachmentOffsetY;
float z = veSeat->m_attachmentOffsetZ;
unit->m_movementInfo.transport.pos.Relocate(x, y, z, o);
unit->m_movementInfo.transport.time = 0;
unit->m_movementInfo.transport.seat = seat->first;
unit->m_movementInfo.transport.guid = _me->GetGUID();
@@ -410,16 +426,17 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
// also adds MOVEMENTFLAG_ROOT
Movement::MoveSplineInit init(unit);
init.DisableTransportPathTransformations();
init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
init.MoveTo(x, y, z, false, true);
// Xinef: did not found anything unique in dbc, maybe missed something
if (veSeat->m_ID == 3566 || veSeat->m_ID == 3567 || veSeat->m_ID == 3568 || veSeat->m_ID == 3570)
{
float x = veSeat->m_attachmentOffsetX, y = veSeat->m_attachmentOffsetY, z = veSeat->m_attachmentOffsetZ, o;
CalculatePassengerPosition(x, y, z, &o);
init.SetFacing(_me->GetAngle(x, y));
}
else
init.SetFacing(0.0f);
{
init.SetFacing(o);
}
init.SetTransportEnter();
init.Launch();

View File

@@ -41,6 +41,7 @@ public:
bool HasEmptySeat(int8 seatId) const;
Unit* GetPassenger(int8 seatId) const;
int8 GetNextEmptySeat(int8 seatId, bool next) const;
VehicleSeatAddon const* GetSeatAddonForSeatOfPassenger(Unit const* passenger) const;
uint8 GetAvailableSeatCount() const;
bool AddPassenger(Unit* passenger, int8 seatId = -1);

View File

@@ -56,6 +56,14 @@ enum VehicleSpells
VEHICLE_SPELL_SHADE_CONTROL_END = 58664
};
enum class VehicleExitParameters
{
VehicleExitParamNone = 0, // provided parameters will be ignored
VehicleExitParamOffset = 1, // provided parameters will be used as offset values
VehicleExitParamDest = 2, // provided parameters will be used as absolute destination
VehicleExitParamMax
};
enum VehicleNPCs
{
NPC_EIDOLON_WATCHER = 31110,
@@ -74,9 +82,24 @@ struct PassengerInfo
}
};
struct VehicleSeatAddon
{
VehicleSeatAddon() { }
VehicleSeatAddon(float orientatonOffset, float exitX, float exitY, float exitZ, float exitO, uint8 param) :
SeatOrientationOffset(orientatonOffset), ExitParameterX(exitX), ExitParameterY(exitY), ExitParameterZ(exitZ),
ExitParameterO(exitO), ExitParameter(VehicleExitParameters(param)) { }
float SeatOrientationOffset = 0.f;
float ExitParameterX = 0.f;
float ExitParameterY = 0.f;
float ExitParameterZ = 0.f;
float ExitParameterO = 0.f;
VehicleExitParameters ExitParameter = VehicleExitParameters::VehicleExitParamNone;
};
struct VehicleSeat
{
explicit VehicleSeat(VehicleSeatEntry const* seatInfo) : SeatInfo(seatInfo)
explicit VehicleSeat(VehicleSeatEntry const* seatInfo, VehicleSeatAddon const* seatAddon) : SeatInfo(seatInfo), SeatAddon(seatAddon)
{
Passenger.Reset();
}
@@ -84,6 +107,7 @@ struct VehicleSeat
[[nodiscard]] bool IsEmpty() const { return !Passenger.Guid; }
VehicleSeatEntry const* SeatInfo;
VehicleSeatAddon const* SeatAddon;
PassengerInfo Passenger;
};