mirror of
https://github.com/araxiaonline/TrinityCore2.git
synced 2026-06-18 13:59:39 -04:00
Implement vehicles created by player mounts.
Original idea by Elmaster, packet research by Wrong, ty. --HG-- branch : trunk
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include "SocialMgr.h"
|
||||
#include "Util.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
class Aura;
|
||||
|
||||
@@ -775,6 +776,14 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
|
||||
*data << (uint16) 0;
|
||||
}
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
|
||||
{
|
||||
if(player->GetVehicle()){
|
||||
Vehicle* vv=player->GetVehicle();
|
||||
*data << (uint32) vv->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat];
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
|
||||
{
|
||||
if(pet)
|
||||
|
||||
@@ -358,6 +358,20 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||
plMover->UpdateFallInformationIfNeed(movementInfo, opcode);
|
||||
|
||||
// If on vehicle, update carried players
|
||||
if (Vehicle *vehicle=plMover->GetVehicleKit())
|
||||
{
|
||||
if (plMover->IsVehicle())
|
||||
{
|
||||
for (int i=0; i < 8; ++i)
|
||||
{
|
||||
if (Unit *passenger = vehicle->GetPassenger(i))
|
||||
if (passenger != NULL && passenger->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)passenger)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (movementInfo.z < -500.0f)
|
||||
{
|
||||
if (plMover->InBattleGround()
|
||||
|
||||
@@ -1219,9 +1219,9 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||
/*0x4A4*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4A5*/ { "UMSG_UNKNOWN_1189", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4A6*/ { "SMSG_UNKNOWN_1190", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4A7*/ { "SMSG_UNKNOWN_1191", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4A8*/ { "CMSG_UNKNOWN_1192", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4A9*/ { "CMSG_EJECT_PASSENGER", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER", STATUS_LOGGEDIN, &WorldSession::HandleEnterPlayerVehicle },
|
||||
/*0x4A9*/ { "CMSG_EJECT_PASSENGER", STATUS_LOGGEDIN, &WorldSession::HandleEjectPasenger },
|
||||
/*0x4AA*/ { "SMSG_PET_GUIDS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4AB*/ { "SMSG_CLIENTCACHE_VERSION", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4AC*/ { "UMSG_UNKNOWN_1196", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
|
||||
+2
-2
@@ -1227,8 +1227,8 @@ enum Opcodes
|
||||
CMSG_QUERY_VEHICLE_STATUS = 0x4A4, // not found
|
||||
UMSG_UNKNOWN_1189 = 0x4A5, // not found, old SMSG_PET_GUIDS
|
||||
SMSG_UNKNOWN_1190 = 0x4A6, // smsg unk, "You can't do that yet"
|
||||
SMSG_UNKNOWN_1191 = 0x4A7, // smsg guid+uint32 (vehicle)
|
||||
CMSG_UNKNOWN_1192 = 0x4A8, // cmsg uint64
|
||||
SMSG_PLAYER_VEHICLE_DATA = 0x4A7, // smsg guid+uint32 (vehicle)
|
||||
CMSG_PLAYER_VEHICLE_ENTER = 0x4A8, // cmsg uint64
|
||||
CMSG_EJECT_PASSENGER = 0x4A9, // cmsg uint64
|
||||
SMSG_PET_GUIDS = 0x4AA, // shifted+5
|
||||
SMSG_CLIENTCACHE_VERSION = 0x4AB, // shifted+5
|
||||
|
||||
@@ -3981,6 +3981,7 @@ void Player::InitVisibleBits()
|
||||
updateVisualBits.SetBit(PLAYER_BYTES_3);
|
||||
updateVisualBits.SetBit(PLAYER_DUEL_TEAM);
|
||||
updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);
|
||||
updateVisualBits.SetBit(UNIT_NPC_FLAGS);
|
||||
|
||||
// PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)...
|
||||
for (uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4)
|
||||
|
||||
@@ -3471,7 +3471,7 @@ void AuraEffect::HandleAuraMounted(AuraApplication const * aurApp, uint8 mode, b
|
||||
if(GetSpellProto()->Effect[i] == SPELL_EFFECT_SUMMON
|
||||
&& GetSpellProto()->EffectMiscValue[i] == GetMiscValue())
|
||||
display_id = 0;
|
||||
target->Mount(display_id);
|
||||
target->Mount(display_id,ci->VehicleId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+48
-1
@@ -11099,7 +11099,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellEntry * s
|
||||
return uint32((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
|
||||
}
|
||||
|
||||
void Unit::Mount(uint32 mount)
|
||||
void Unit::Mount(uint32 mount, uint32 VehicleId)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
|
||||
|
||||
@@ -11121,6 +11121,27 @@ void Unit::Mount(uint32 mount)
|
||||
else
|
||||
((Player*)this)->UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
|
||||
if(VehicleId !=0)
|
||||
{
|
||||
if(VehicleEntry const *ve = sVehicleStore.LookupEntry(VehicleId))
|
||||
{
|
||||
|
||||
if (CreateVehicleKit(VehicleId))
|
||||
{
|
||||
GetVehicleKit()->Reset();
|
||||
|
||||
// Send others that we now have a vehicle
|
||||
WorldPacket data( SMSG_PLAYER_VEHICLE_DATA, GetPackGUID().size()+4);
|
||||
data.appendPackGUID(GetGUID());
|
||||
data << uint32(VehicleId);
|
||||
SendMessageToSet( &data,true );
|
||||
|
||||
data.Initialize(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
|
||||
((Player*)this)->GetSession()->SendPacket( &data );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11148,6 +11169,16 @@ void Unit::Unmount()
|
||||
else
|
||||
((Player*)this)->ResummonPetTemporaryUnSummonedIfAny();
|
||||
}
|
||||
if(GetTypeId()==TYPEID_PLAYER && GetVehicleKit())
|
||||
{
|
||||
// Send other players that we are no longer a vehicle
|
||||
WorldPacket data( SMSG_PLAYER_VEHICLE_DATA, 8+4 );
|
||||
data.appendPackGUID(GetGUID());
|
||||
data << uint32(0);
|
||||
((Player*)this)->SendMessageToSet(&data, true);
|
||||
// Remove vehicle class from player
|
||||
RemoveVehicleKit();
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::SetInCombatWith(Unit* enemy)
|
||||
@@ -14956,6 +14987,22 @@ bool Unit::CreateVehicleKit(uint32 id)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::RemoveVehicleKit()
|
||||
{
|
||||
if (!m_vehicleKit)
|
||||
return;
|
||||
|
||||
m_vehicleKit->Uninstall();
|
||||
delete m_vehicleKit;
|
||||
|
||||
m_vehicleKit = NULL;
|
||||
|
||||
m_updateFlag &= ~UPDATEFLAG_VEHICLE;
|
||||
m_unitTypeMask &= ~UNIT_MASK_VEHICLE;
|
||||
RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
|
||||
}
|
||||
|
||||
Unit *Unit::GetVehicleBase() const
|
||||
{
|
||||
return m_vehicle ? m_vehicle->GetBase() : NULL;
|
||||
|
||||
+3
-1
@@ -631,6 +631,7 @@ enum NPCFlags
|
||||
UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100%
|
||||
UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode
|
||||
UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click), dynamic, set at loading and don't must be set in DB
|
||||
UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set
|
||||
UNIT_NPC_FLAG_GUARD = 0x10000000, // custom flag for guards
|
||||
UNIT_NPC_FLAG_OUTDOORPVP = 0x20000000, // custom flag for outdoor pvp creatures
|
||||
};
|
||||
@@ -1272,7 +1273,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
|
||||
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT ); }
|
||||
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
|
||||
void Mount(uint32 mount);
|
||||
void Mount(uint32 mount, uint32 vehicleId=0);
|
||||
void Unmount();
|
||||
|
||||
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
|
||||
@@ -1913,6 +1914,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
bool IsAIEnabled, NeedChangeAI;
|
||||
MovementInfo m_movementInfo;
|
||||
bool CreateVehicleKit(uint32 id);
|
||||
void RemoveVehicleKit();
|
||||
Vehicle *GetVehicleKit()const { return m_vehicleKit; }
|
||||
Vehicle *GetVehicle() const { return m_vehicle; }
|
||||
bool IsOnVehicle(const Unit *unit) const { return m_vehicle && m_vehicle == unit->GetVehicleKit(); }
|
||||
|
||||
+36
-12
@@ -151,9 +151,18 @@ void Vehicle::Die()
|
||||
void Vehicle::Reset()
|
||||
{
|
||||
sLog.outDebug("Vehicle::Reset");
|
||||
InstallAllAccessories();
|
||||
if(m_usableSeatNum)
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
{
|
||||
if (me->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
InstallAllAccessories();
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Vehicle::RemoveAllPassengers()
|
||||
@@ -275,7 +284,12 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
|
||||
assert(m_usableSeatNum);
|
||||
--m_usableSeatNum;
|
||||
if(!m_usableSeatNum)
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
{
|
||||
if (me->GetTypeId() == TYPEID_PLAYER)
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
|
||||
else
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
}
|
||||
|
||||
if(seat->second.seatInfo->m_flags && !(seat->second.seatInfo->m_flags & 0x400))
|
||||
@@ -292,21 +306,24 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
|
||||
unit->m_movementInfo.t_time = 0; // 1 for player
|
||||
unit->m_movementInfo.t_seat = seat->first;
|
||||
|
||||
if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) // not right
|
||||
if(me->GetTypeId() == TYPEID_UNIT
|
||||
&& unit->GetTypeId() == TYPEID_PLAYER
|
||||
&& seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) // not right
|
||||
if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE))
|
||||
assert(false);
|
||||
|
||||
if(me->GetTypeId() == TYPEID_UNIT)
|
||||
if(me->IsInWorld())
|
||||
{
|
||||
if(me->IsInWorld())
|
||||
unit->SendMonsterMoveTransport(me);
|
||||
|
||||
if(me->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
unit->SendMonsterMoveTransport(me);
|
||||
if(((Creature*)me)->IsAIEnabled)
|
||||
((Creature*)me)->AI()->PassengerBoarded(unit, seat->first, true);
|
||||
|
||||
// move self = move all passengers
|
||||
me->GetMap()->CreatureRelocation((Creature*)me, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
}
|
||||
|
||||
if(((Creature*)me)->IsAIEnabled)
|
||||
((Creature*)me)->AI()->PassengerBoarded(unit, seat->first, true);
|
||||
}
|
||||
|
||||
//if(unit->GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -334,7 +351,12 @@ void Vehicle::RemovePassenger(Unit *unit)
|
||||
if(seat->second.seatInfo->IsUsable())
|
||||
{
|
||||
if(!m_usableSeatNum)
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
{
|
||||
if (me->GetTypeId() == TYPEID_PLAYER)
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
|
||||
else
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
++m_usableSeatNum;
|
||||
}
|
||||
|
||||
@@ -342,7 +364,9 @@ void Vehicle::RemovePassenger(Unit *unit)
|
||||
|
||||
//SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
|
||||
if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800)
|
||||
if(me->GetTypeId() == TYPEID_UNIT
|
||||
&& unit->GetTypeId() == TYPEID_PLAYER
|
||||
&& seat->first == 0 && seat->second.seatInfo->m_flags & 0x800)
|
||||
me->RemoveCharmedBy(unit);
|
||||
|
||||
if(me->GetTypeId() == TYPEID_UNIT && ((Creature*)me)->IsAIEnabled)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Group.h"
|
||||
#include "Guild.h"
|
||||
@@ -937,6 +938,39 @@ void WorldSession::SendAddonsInfo()
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
|
||||
void WorldSession::HandleEnterPlayerVehicle(WorldPacket &data)
|
||||
{
|
||||
// Read guid
|
||||
uint64 guid;
|
||||
data >> guid;
|
||||
|
||||
if(Player* pl=ObjectAccessor::FindPlayer(guid))
|
||||
{
|
||||
if (!pl->GetVehicleKit())
|
||||
return;
|
||||
if (!pl->IsInRaidWith(_player))
|
||||
return;
|
||||
if(!pl->IsWithinDistInMap(_player,INTERACTION_DISTANCE))
|
||||
return;
|
||||
_player->EnterVehicle(pl);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleEjectPasenger(WorldPacket &data)
|
||||
{
|
||||
if(data.GetOpcode()==CMSG_EJECT_PASSENGER)
|
||||
{
|
||||
if(Vehicle* Vv= _player->GetVehicleKit())
|
||||
{
|
||||
uint64 guid;
|
||||
data >> guid;
|
||||
if(Player* Pl=ObjectAccessor::FindPlayer(guid))
|
||||
Pl->ExitVehicle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::SetPlayer( Player *plr )
|
||||
{
|
||||
_player = plr;
|
||||
|
||||
@@ -748,6 +748,8 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
bool HandleOnItemOpen(Item *pItem);
|
||||
bool HandleOnGoClick(GameObject *pGameObject);
|
||||
void HandleOnCreatureKill(Creature *pCreature);
|
||||
void HandleEjectPasenger(WorldPacket &data);
|
||||
void HandleEnterPlayerVehicle(WorldPacket &data);
|
||||
private:
|
||||
// private trade methods
|
||||
void moveItems(Item* myItems[], Item* hisItems[]);
|
||||
|
||||
Reference in New Issue
Block a user