*Fix a bug that player can change to an occupied seat on vehicle.
*Load full creature data for vehicles. --HG-- branch : trunk
This commit is contained in:
@@ -1434,7 +1434,10 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
|
||||
}
|
||||
m_originalEntry = Entry;
|
||||
|
||||
Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
|
||||
if(isVehicle())
|
||||
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
|
||||
else
|
||||
Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
|
||||
|
||||
if(!UpdateEntry(Entry, team, data))
|
||||
return false;
|
||||
|
||||
@@ -1719,6 +1719,8 @@ struct VehicleSeatEntry
|
||||
uint32 m_exitUISoundID; // 43
|
||||
int32 m_uiSkin; // 44
|
||||
uint32 m_flagsB; // 45
|
||||
|
||||
bool IsUsable() const { return m_flags & 0x2000000; }
|
||||
};
|
||||
|
||||
struct WorldMapAreaEntry
|
||||
|
||||
+8
-10
@@ -6812,27 +6812,25 @@ void AuraEffect::HandleAuraControlVehicle(bool apply, bool Real, bool /*changeAm
|
||||
return;
|
||||
|
||||
Unit *caster = GetCaster();
|
||||
if(!caster)
|
||||
if(!caster || caster == m_target)
|
||||
return;
|
||||
|
||||
/*Vehicle *vehicle = dynamic_cast<Vehicle*>(m_target);
|
||||
Vehicle *vehicle = dynamic_cast<Vehicle*>(m_target);
|
||||
|
||||
if (apply)
|
||||
{
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
if(Pet *pet = ((Player*)caster)->GetPet())
|
||||
pet->Remove(PET_SAVE_AS_CURRENT);
|
||||
caster->EnterVehicle(vehicle);
|
||||
//if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
// if(Pet *pet = ((Player*)caster)->GetPet())
|
||||
// pet->Remove(PET_SAVE_AS_CURRENT);
|
||||
caster->EnterVehicle(vehicle, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpellEntry const *spell = GetSpellProto();
|
||||
|
||||
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
|
||||
caster->RemoveAurasDueToSpell(spell->Id);
|
||||
caster->RemoveAurasDueToSpell(GetId());
|
||||
|
||||
caster->ExitVehicle();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraConvertRune(bool apply, bool Real, bool /*changeAmount*/)
|
||||
|
||||
+10
-5
@@ -10652,8 +10652,8 @@ bool Unit::CanHaveThreatList() const
|
||||
return false;
|
||||
|
||||
// vehicles can not have threat list
|
||||
if( ((Creature*)this)->isVehicle() )
|
||||
return false;
|
||||
//if( ((Creature*)this)->isVehicle() )
|
||||
// return false;
|
||||
|
||||
// pets can not have a threat list, unless they are controlled by a creature
|
||||
if( ((Creature*)this)->isPet() && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) )
|
||||
@@ -13929,6 +13929,9 @@ void Unit::JumpTo(WorldObject *obj, float speedZ)
|
||||
|
||||
void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId)
|
||||
{
|
||||
if(!isAlive() || this == vehicle)
|
||||
return;
|
||||
|
||||
if(m_Vehicle)
|
||||
{
|
||||
if(m_Vehicle == vehicle)
|
||||
@@ -14021,10 +14024,12 @@ void Unit::ExitVehicle()
|
||||
BuildHeartBeatMsg(&data);
|
||||
SendMessageToSet(&data, false);
|
||||
|
||||
if(m_Vehicle->GetOwnerGUID() == GetGUID())
|
||||
m_Vehicle->Dismiss();
|
||||
|
||||
// This should be done before dismiss, because there may be some aura removal
|
||||
Vehicle *vehicle = m_Vehicle;
|
||||
m_Vehicle = NULL;
|
||||
|
||||
if(vehicle->GetOwnerGUID() == GetGUID())
|
||||
vehicle->Dismiss();
|
||||
}
|
||||
|
||||
void Unit::BuildMovementPacket(ByteBuffer *data) const
|
||||
|
||||
+30
-31
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "Chat.h"
|
||||
|
||||
Vehicle::Vehicle() : Creature(), m_vehicleInfo(NULL)
|
||||
Vehicle::Vehicle() : Creature(), m_vehicleInfo(NULL), m_usableSeatNum(0)
|
||||
{
|
||||
m_summonMask |= SUMMON_MASK_VEHICLE;
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
|
||||
@@ -90,31 +90,12 @@ void Vehicle::Update(uint32 diff)
|
||||
// ModifyPower(POWER_ENERGY, 1);
|
||||
}
|
||||
|
||||
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team)
|
||||
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, const CreatureData * data)
|
||||
{
|
||||
//sLog.outError("create vehicle begin");
|
||||
SetMapId(map->GetId());
|
||||
SetInstanceId(map->GetInstanceId());
|
||||
|
||||
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
|
||||
|
||||
if(!InitEntry(Entry, team))
|
||||
if(!Creature::Create(guidlow, map, phaseMask, Entry, team, data))
|
||||
return false;
|
||||
|
||||
m_defaultMovementType = IDLE_MOTION_TYPE;
|
||||
|
||||
SetVehicleId(vehicleId);
|
||||
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
|
||||
|
||||
CreatureInfo const *ci = GetCreatureInfo();
|
||||
setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
|
||||
SetMaxHealth(ci->maxhealth);
|
||||
SelectLevel(ci);
|
||||
SetHealth(GetMaxHealth());
|
||||
|
||||
//sLog.outError("create vehicle end");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -143,16 +124,22 @@ void Vehicle::SetVehicleId(uint32 id)
|
||||
|
||||
RemoveAllPassengers();
|
||||
m_Seats.clear();
|
||||
m_usableSeatNum = 0;
|
||||
|
||||
for(uint32 i = 0; i < 8; ++i)
|
||||
{
|
||||
uint32 seatId = m_vehicleInfo->m_seatID[i];
|
||||
if(seatId)
|
||||
if(uint32 seatId = m_vehicleInfo->m_seatID[i])
|
||||
if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
|
||||
{
|
||||
m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
|
||||
if(veSeat->IsUsable())
|
||||
++m_usableSeatNum;
|
||||
}
|
||||
}
|
||||
|
||||
assert(!m_Seats.empty());
|
||||
if(m_usableSeatNum)
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
|
||||
bool Vehicle::HasEmptySeat(int8 seatId) const
|
||||
@@ -166,7 +153,7 @@ int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
|
||||
{
|
||||
SeatMap::const_iterator seat = m_Seats.find(seatId);
|
||||
if(seat == m_Seats.end()) return -1;
|
||||
while(seat->second.passenger)
|
||||
while(seat->second.passenger || !seat->second.seatInfo->IsUsable())
|
||||
{
|
||||
if(next)
|
||||
{
|
||||
@@ -181,7 +168,7 @@ int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
|
||||
--seat;
|
||||
}
|
||||
if(seat->first == seatId)
|
||||
return -1;
|
||||
return -1; // no available seat
|
||||
}
|
||||
return seat->first;
|
||||
}
|
||||
@@ -206,7 +193,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
|
||||
if(seatId < 0) // no specific seat requirement
|
||||
{
|
||||
for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
|
||||
if(!seat->second.passenger)
|
||||
if(!seat->second.passenger && seat->second.seatInfo->IsUsable())
|
||||
break;
|
||||
|
||||
if(seat == m_Seats.end()) // no available seat
|
||||
@@ -227,8 +214,14 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
|
||||
sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow());
|
||||
|
||||
seat->second.passenger = unit;
|
||||
if(seat->second.seatInfo->IsUsable())
|
||||
{
|
||||
assert(m_usableSeatNum);
|
||||
--m_usableSeatNum;
|
||||
if(!m_usableSeatNum)
|
||||
RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
}
|
||||
|
||||
//RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
//SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
|
||||
|
||||
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
@@ -250,7 +243,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
|
||||
{
|
||||
//ChatHandler(player).PSendSysMessage("Enter seat %u %u", veSeat->m_ID, seat->first);
|
||||
|
||||
if(seat->first == 0)
|
||||
if(seat->first == 0 && seat->second.seatInfo->IsUsable()) // not right
|
||||
{
|
||||
((Player*)unit)->SetCharm(this, true);
|
||||
((Player*)unit)->SetViewpoint(this, true);
|
||||
@@ -278,6 +271,12 @@ void Vehicle::RemovePassenger(Unit *unit)
|
||||
if(seat->second.passenger == unit)
|
||||
{
|
||||
seat->second.passenger = NULL;
|
||||
if(seat->second.seatInfo->IsUsable())
|
||||
{
|
||||
if(!m_usableSeatNum)
|
||||
SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
++m_usableSeatNum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -288,7 +287,7 @@ void Vehicle::RemovePassenger(Unit *unit)
|
||||
|
||||
//SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
|
||||
if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0)
|
||||
if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->IsUsable())
|
||||
{
|
||||
((Player*)unit)->SetCharm(this, false);
|
||||
((Player*)unit)->SetViewpoint(this, false);
|
||||
@@ -337,7 +336,7 @@ bool Vehicle::LoadFromDB(uint32 guid, Map *map)
|
||||
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_VEHICLE);
|
||||
|
||||
uint16 team = 0;
|
||||
if(!Create(guid,map,data->phaseMask,data->id,id,team))
|
||||
if(!Create(guid,map,data->phaseMask,data->id,id,team,data))
|
||||
return false;
|
||||
|
||||
Relocate(data->posX,data->posY,data->posZ,data->orientation);
|
||||
|
||||
+2
-1
@@ -44,7 +44,7 @@ class Vehicle : public Creature
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team);
|
||||
bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehicleId, uint32 team, const CreatureData * data = NULL);
|
||||
|
||||
void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState
|
||||
void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
|
||||
@@ -64,6 +64,7 @@ class Vehicle : public Creature
|
||||
SeatMap m_Seats;
|
||||
protected:
|
||||
VehicleEntry const *m_vehicleInfo;
|
||||
uint32 m_usableSeatNum;
|
||||
|
||||
void RemoveAllPassengers();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user