*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; 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)) if(!UpdateEntry(Entry, team, data))
return false; return false;
+2
View File
@@ -1719,6 +1719,8 @@ struct VehicleSeatEntry
uint32 m_exitUISoundID; // 43 uint32 m_exitUISoundID; // 43
int32 m_uiSkin; // 44 int32 m_uiSkin; // 44
uint32 m_flagsB; // 45 uint32 m_flagsB; // 45
bool IsUsable() const { return m_flags & 0x2000000; }
}; };
struct WorldMapAreaEntry struct WorldMapAreaEntry
+8 -10
View File
@@ -6812,27 +6812,25 @@ void AuraEffect::HandleAuraControlVehicle(bool apply, bool Real, bool /*changeAm
return; return;
Unit *caster = GetCaster(); Unit *caster = GetCaster();
if(!caster) if(!caster || caster == m_target)
return; return;
/*Vehicle *vehicle = dynamic_cast<Vehicle*>(m_target); Vehicle *vehicle = dynamic_cast<Vehicle*>(m_target);
if (apply) if (apply)
{ {
if(caster->GetTypeId() == TYPEID_PLAYER) //if(caster->GetTypeId() == TYPEID_PLAYER)
if(Pet *pet = ((Player*)caster)->GetPet()) // if(Pet *pet = ((Player*)caster)->GetPet())
pet->Remove(PET_SAVE_AS_CURRENT); // pet->Remove(PET_SAVE_AS_CURRENT);
caster->EnterVehicle(vehicle); caster->EnterVehicle(vehicle, 0);
} }
else else
{ {
SpellEntry const *spell = GetSpellProto();
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
caster->RemoveAurasDueToSpell(spell->Id); caster->RemoveAurasDueToSpell(GetId());
caster->ExitVehicle(); caster->ExitVehicle();
}*/ }
} }
void AuraEffect::HandleAuraConvertRune(bool apply, bool Real, bool /*changeAmount*/) void AuraEffect::HandleAuraConvertRune(bool apply, bool Real, bool /*changeAmount*/)
+10 -5
View File
@@ -10652,8 +10652,8 @@ bool Unit::CanHaveThreatList() const
return false; return false;
// vehicles can not have threat list // vehicles can not have threat list
if( ((Creature*)this)->isVehicle() ) //if( ((Creature*)this)->isVehicle() )
return false; // return false;
// pets can not have a threat list, unless they are controlled by a creature // pets can not have a threat list, unless they are controlled by a creature
if( ((Creature*)this)->isPet() && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) ) 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) void Unit::EnterVehicle(Vehicle *vehicle, int8 seatId)
{ {
if(!isAlive() || this == vehicle)
return;
if(m_Vehicle) if(m_Vehicle)
{ {
if(m_Vehicle == vehicle) if(m_Vehicle == vehicle)
@@ -14021,10 +14024,12 @@ void Unit::ExitVehicle()
BuildHeartBeatMsg(&data); BuildHeartBeatMsg(&data);
SendMessageToSet(&data, false); SendMessageToSet(&data, false);
if(m_Vehicle->GetOwnerGUID() == GetGUID()) // This should be done before dismiss, because there may be some aura removal
m_Vehicle->Dismiss(); Vehicle *vehicle = m_Vehicle;
m_Vehicle = NULL; m_Vehicle = NULL;
if(vehicle->GetOwnerGUID() == GetGUID())
vehicle->Dismiss();
} }
void Unit::BuildMovementPacket(ByteBuffer *data) const void Unit::BuildMovementPacket(ByteBuffer *data) const
+30 -31
View File
@@ -26,7 +26,7 @@
#include "Chat.h" #include "Chat.h"
Vehicle::Vehicle() : Creature(), m_vehicleInfo(NULL) Vehicle::Vehicle() : Creature(), m_vehicleInfo(NULL), m_usableSeatNum(0)
{ {
m_summonMask |= SUMMON_MASK_VEHICLE; m_summonMask |= SUMMON_MASK_VEHICLE;
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_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); // 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"); if(!Creature::Create(guidlow, map, phaseMask, Entry, team, data))
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
if(!InitEntry(Entry, team))
return false; return false;
m_defaultMovementType = IDLE_MOTION_TYPE;
SetVehicleId(vehicleId); 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; return true;
} }
@@ -143,16 +124,22 @@ void Vehicle::SetVehicleId(uint32 id)
RemoveAllPassengers(); RemoveAllPassengers();
m_Seats.clear(); m_Seats.clear();
m_usableSeatNum = 0;
for(uint32 i = 0; i < 8; ++i) for(uint32 i = 0; i < 8; ++i)
{ {
uint32 seatId = m_vehicleInfo->m_seatID[i]; if(uint32 seatId = m_vehicleInfo->m_seatID[i])
if(seatId)
if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId)) if(VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(seatId))
{
m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat))); m_Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
if(veSeat->IsUsable())
++m_usableSeatNum;
}
} }
assert(!m_Seats.empty()); assert(!m_Seats.empty());
if(m_usableSeatNum)
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
} }
bool Vehicle::HasEmptySeat(int8 seatId) const 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); SeatMap::const_iterator seat = m_Seats.find(seatId);
if(seat == m_Seats.end()) return -1; if(seat == m_Seats.end()) return -1;
while(seat->second.passenger) while(seat->second.passenger || !seat->second.seatInfo->IsUsable())
{ {
if(next) if(next)
{ {
@@ -181,7 +168,7 @@ int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
--seat; --seat;
} }
if(seat->first == seatId) if(seat->first == seatId)
return -1; return -1; // no available seat
} }
return seat->first; return seat->first;
} }
@@ -206,7 +193,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
if(seatId < 0) // no specific seat requirement if(seatId < 0) // no specific seat requirement
{ {
for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat) for(seat = m_Seats.begin(); seat != m_Seats.end(); ++seat)
if(!seat->second.passenger) if(!seat->second.passenger && seat->second.seatInfo->IsUsable())
break; break;
if(seat == m_Seats.end()) // no available seat 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()); sLog.outDebug("Unit %s enter vehicle entry %u id %u dbguid %u", unit->GetName(), GetEntry(), m_vehicleInfo->m_ID, GetDBTableGUIDLow());
seat->second.passenger = unit; 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); //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 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); //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)->SetCharm(this, true);
((Player*)unit)->SetViewpoint(this, true); ((Player*)unit)->SetViewpoint(this, true);
@@ -278,6 +271,12 @@ void Vehicle::RemovePassenger(Unit *unit)
if(seat->second.passenger == unit) if(seat->second.passenger == unit)
{ {
seat->second.passenger = NULL; seat->second.passenger = NULL;
if(seat->second.seatInfo->IsUsable())
{
if(!m_usableSeatNum)
SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
++m_usableSeatNum;
}
break; break;
} }
} }
@@ -288,7 +287,7 @@ void Vehicle::RemovePassenger(Unit *unit)
//SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); //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)->SetCharm(this, false);
((Player*)unit)->SetViewpoint(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); if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_VEHICLE);
uint16 team = 0; 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; return false;
Relocate(data->posX,data->posY,data->posZ,data->orientation); Relocate(data->posX,data->posY,data->posZ,data->orientation);
+2 -1
View File
@@ -44,7 +44,7 @@ class Vehicle : public Creature
void AddToWorld(); void AddToWorld();
void RemoveFromWorld(); 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 setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState
void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
@@ -64,6 +64,7 @@ class Vehicle : public Creature
SeatMap m_Seats; SeatMap m_Seats;
protected: protected:
VehicleEntry const *m_vehicleInfo; VehicleEntry const *m_vehicleInfo;
uint32 m_usableSeatNum;
void RemoveAllPassengers(); void RemoveAllPassengers();