*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:
megamage
2009-05-23 20:40:14 -05:00
parent 7ef7f7fa82
commit 2780893030
6 changed files with 56 additions and 48 deletions
+4 -1
View File
@@ -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;
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();