Small progress with vehicles

This commit is contained in:
tomrus88 2008-11-12 00:49:19 +03:00
parent 204b61c220
commit 871d5f8c99
18 changed files with 175 additions and 21 deletions

View file

@ -157,6 +157,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "sellerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSellErrorCommand, "", NULL },
{ "buyerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBuyErrorCommand, "", NULL },
{ "sendopcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendOpcodeCommand, "", NULL },
{ "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSpawnVehicle, "", NULL },
{ "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL },
{ "ps", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlaySound2Command, "", NULL },
{ "scn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL },

View file

@ -427,6 +427,7 @@ class ChatHandler
bool HandleSaveAllCommand(const char* args);
bool HandleGetItemState(const char * args);
bool HandleGetLootRecipient(const char * args);
bool HandleSpawnVehicle(const char * args);
Player* getSelectedPlayer();
Creature* getSelectedCreature();

View file

@ -1696,7 +1696,7 @@ void Creature::CallAssistence()
void Creature::SaveRespawnTime()
{
if(isPet() || !m_DBTableGuid)
if(isPet() || isVehicle() || !m_DBTableGuid)
return;
if(m_respawnTime > time(NULL)) // dead (no corpse)

View file

@ -410,6 +410,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
uint32 GetEquipmentId() const { return m_equipmentId; }
bool isPet() const { return m_isPet; }
bool isVehicle() const { return m_isVehicle; }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
bool isTotem() const { return m_isTotem; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
@ -618,6 +619,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
uint8 m_emoteState;
bool m_isPet; // set only in Pet::Pet
bool m_isVehicle; // set only in Vehicle::Vehicle
bool m_isTotem; // set only in Totem::Totem
void RegenerateMana();
void RegenerateHealth();

View file

@ -949,7 +949,7 @@ bool ChatHandler::HandleNpcDeleteCommand(const char* args)
else
unit = getSelectedCreature();
if(!unit || unit->isPet() || unit->isTotem())
if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())
{
SendSysMessage(LANG_SELECT_CREATURE);
SetSentErrorMessage(true);

View file

@ -253,7 +253,7 @@ template<>
void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// add to world object registry in grid
if(obj->isPet())
if(obj->isPet() || obj->isVehicle())
{
(*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID());
obj->SetCurrentCell(cell);
@ -297,7 +297,7 @@ template<>
void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// remove from world object registry in grid
if(obj->isPet())
if(obj->isPet() || obj->isVehicle())
{
(*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID());
}

View file

@ -1661,15 +1661,16 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data )
uint64 guid;
recv_data >> guid;
Unit *vehicle = ObjectAccessor::GetUnit(*_player, guid);
Vehicle *vehicle = ObjectAccessor::GetVehicle(guid);
if(!vehicle)
return;
_player->SetClientControl(vehicle, 1);
_player->CastSpell(_player, 43768, true);
_player->SetUInt64Value(UNIT_FIELD_CHARM, guid);
_player->SetUInt64Value(PLAYER_FARSIGHT, guid);
//_player->SetClientControl(vehicle, 1);
//_player->CastSpell(_player, 43768, true);
//_player->SetUInt64Value(UNIT_FIELD_CHARM, guid);
//_player->SetUInt64Value(PLAYER_FARSIGHT, guid);
_player->EnterVehicle(vehicle);
}
void WorldSession::HandleInspectAchievements( WorldPacket & recv_data )

View file

@ -201,7 +201,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
recv_data >> movementInfo.t_z;
recv_data >> movementInfo.t_o;
recv_data >> movementInfo.t_time;
recv_data >> movementInfo.t_unk;
recv_data >> movementInfo.t_seat;
}
if((MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (movementInfo.unk1 & 0x20))

View file

@ -258,6 +258,10 @@ void Object::DestroyForPlayer(Player *target) const
void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const
{
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
if(GetTypeId() == TYPEID_UNIT)
if(((Creature*)this)->isVehicle())
unk_flags |= 0x20; // always allow pitch
*data << (uint8)flags; // update flags
@ -331,7 +335,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2)
*data << (float)((Player*)this)->GetTransOffsetZ();
*data << (float)((Player*)this)->GetTransOffsetO();
*data << (uint32)((Player*)this)->GetTransTime();
*data << (uint8)((Player*)this)->GetTransUnk();
*data << (int8)((Player*)this)->GetTransSeat();
}
//MaNGOS currently not have support for other than player on transport
}
@ -544,7 +548,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2)
// 0x80
if(flags & UPDATEFLAG_VEHICLE) // unused for now
{
*data << uint32(0); // vehicle id
*data << uint32(((Vehicle*)this)->GetVehicleId()); // vehicle id
*data << float(0); // facing adjustment
}
}

View file

@ -132,6 +132,9 @@ ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid)
if(Creature *unit = GetPet(guid))
return unit;
if(Creature *unit = GetVehicle(guid))
return unit;
return GetCreature(u, guid);
}
@ -367,6 +370,12 @@ ObjectAccessor::GetPet(uint64 guid)
return GetObjectInWorld(guid, (Pet*)NULL);
}
Vehicle*
ObjectAccessor::GetVehicle(uint64 guid)
{
return GetObjectInWorld(guid, (Vehicle*)NULL);
}
Corpse*
ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
{

View file

@ -149,6 +149,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
static DynamicObject* GetDynamicObject(Unit const &, uint64);
static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
static Pet* GetPet(uint64 guid);
static Vehicle* GetVehicle(uint64 guid);
static Player* FindPlayer(uint64);
Player* FindPlayerByName(const char *name) ;

View file

@ -50,14 +50,14 @@ ObjectGridRespawnMover::Visit(CreatureMapType &m)
{
// creature in unloading grid can have respawn point in another grid
// if it will be unloaded then it will not respawn in original grid until unload/load original grid
// move to respwn point to prevent this case. For player view in respawn grid this wll be normal respawn.
// move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
for(CreatureMapType::iterator iter=m.begin(), next; iter != m.end(); iter = next)
{
next = iter; ++next;
Creature * c = iter->getSource();
assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets");
assert((!c->isPet() || !c->isVehicle()) && "ObjectGridRespawnMover don't must be called for pets");
Cell const& cur_cell = c->GetCurrentCell();

View file

@ -18596,3 +18596,72 @@ void Player::InitGlyphsForLevel()
SetUInt32Value(PLAYER_GLYPHS_ENABLED, value);
}
void Player::EnterVehicle(Vehicle *vehicle)
{
vehicle->SetCharmerGUID(GetGUID());
vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
vehicle->setFaction(getFaction());
SetCharm(vehicle);
SetUInt64Value(PLAYER_FARSIGHT, vehicle->GetGUID());
SetClientControl(vehicle, 1);
WorldPacket data(SMSG_UNKNOWN_1181, 0);
GetSession()->SendPacket(&data);
data.Initialize(MSG_MOVE_TELEPORT_ACK, 30);
data.append(GetPackGUID());
data << uint32(0); // counter?
data << uint32(MOVEMENTFLAG_ONTRANSPORT); // transport
data << uint16(0); // special flags
data << uint32(getMSTime()); // time
data << vehicle->GetPositionX(); // x
data << vehicle->GetPositionY(); // y
data << vehicle->GetPositionZ(); // z
data << vehicle->GetOrientation(); // o
// transport part
data << vehicle->GetGUID(); // transport guid
data << float(0); // transport offsetX
data << float(0); // transport offsetY
data << float(1); // transport offsetZ
data << float(0); // transport orientation
data << uint32(getMSTime()); // transport time
data << uint8(0); // seat
// end of transport part
data << uint32(0); // fall time
GetSession()->SendPacket(&data);
}
void Player::ExitVehicle(Vehicle *vehicle)
{
vehicle->SetCharmerGUID(0);
vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
SetCharm(NULL);
SetUInt64Value(PLAYER_FARSIGHT, 0);
SetClientControl(vehicle, 0);
WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30);
data.append(GetPackGUID());
data << uint32(0); // counter?
data << uint32(MOVEMENTFLAG_FLY_UNK1); // fly unk
data << uint16(0x40); // special flags
data << uint32(getMSTime()); // time
data << vehicle->GetPositionX(); // x
data << vehicle->GetPositionY(); // y
data << vehicle->GetPositionZ(); // z
data << vehicle->GetOrientation(); // o
data << uint32(0); // fall time
GetSession()->SendPacket(&data);
// only for flyable vehicles?
CastSpell(this, 45472, true); // Parachute
}

View file

@ -47,6 +47,7 @@ class Transport;
class UpdateMask;
class PlayerSocial;
class AchievementMgr;
class Vehicle;
typedef std::deque<Mail*> PlayerMails;
@ -736,7 +737,7 @@ struct MovementInfo
uint64 t_guid;
float t_x, t_y, t_z, t_o;
uint32 t_time;
uint8 t_unk;
int8 t_seat;
// swimming and unknown
float s_pitch;
// last fall time
@ -1950,6 +1951,9 @@ class MANGOS_DLL_SPEC Player : public Unit
void SetClientControl(Unit* target, uint8 allowMove);
void EnterVehicle(Vehicle *vehicle);
void ExitVehicle(Vehicle *vehicle);
// Transports
Transport * GetTransport() const { return m_transport; }
void SetTransport(Transport * t) { m_transport = t; }
@ -1959,7 +1963,7 @@ class MANGOS_DLL_SPEC Player : public Unit
float GetTransOffsetZ() const { return m_movementInfo.t_z; }
float GetTransOffsetO() const { return m_movementInfo.t_o; }
uint32 GetTransTime() const { return m_movementInfo.t_time; }
uint8 GetTransUnk() const { return m_movementInfo.t_unk; }
int8 GetTransSeat() const { return m_movementInfo.t_seat; }
uint32 GetSaveTimer() const { return m_nextSave; }
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }

View file

@ -9061,7 +9061,7 @@ bool Unit::CanHaveThreatList() const
return false;
// pets and totems can not have threat list
if( ((Creature*)this)->isPet() || ((Creature*)this)->isTotem() )
if( ((Creature*)this)->isPet() || ((Creature*)this)->isTotem() || ((Creature*)this)->isVehicle() )
return false;
return true;

View file

@ -28,8 +28,9 @@
#include "Unit.h"
#include "Util.h"
Vehicle::Vehicle() : Creature()
Vehicle::Vehicle() : Creature(), m_vehicleId(0)
{
m_isVehicle = true;
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
}
@ -64,15 +65,29 @@ void Vehicle::Update(uint32 diff)
Creature::Update(diff);
}
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry)
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
if(!InitEntry(Entry))
if(!InitEntry(Entry, team))
return false;
m_defaultMovementType = IDLE_MOTION_TYPE;
AIM_Initialize();
SetVehicleId(vehicleId);
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
CreatureInfo const *ci = GetCreatureInfo();
setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
SetMaxHealth(ci->maxhealth);
SelectLevel(ci);
SetHealth(GetMaxHealth());
return true;
}

View file

@ -32,12 +32,16 @@ class Vehicle : public Creature
void AddToWorld();
void RemoveFromWorld();
bool Create (uint32 guidlow, Map *map, uint32 Entry);
bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team);
void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState
void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
uint32 GetVehicleId() { return m_vehicleId; }
void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; }
protected:
uint32 m_vehicleId;
private:
void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called

View file

@ -31,6 +31,7 @@
#include "Language.h"
#include "MapManager.h"
#include <fstream>
#include "ObjectMgr.h"
bool ChatHandler::HandleDebugInArcCommand(const char* /*args*/)
{
@ -518,3 +519,45 @@ bool ChatHandler::HandleGetItemState(const char* args)
return true;
}
bool ChatHandler::HandleSpawnVehicle(const char* args)
{
if(!args)
return false;
char* e = strtok((char*)args, " ");
char* i = strtok(NULL, " ");
if (!e || !i)
return false;
uint32 entry = (uint32)atoi(e);
uint32 id = (uint32)atoi(i);
// TODO: check entry, id...
Vehicle *v = new Vehicle;
Map *map = m_session->GetPlayer()->GetMap();
if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam()))
{
delete v;
return false;
}
float px, py, pz;
m_session->GetPlayer()->GetClosePoint(px, py, pz, m_session->GetPlayer()->GetObjectSize());
v->Relocate(px, py, pz, m_session->GetPlayer()->GetOrientation());
if(!v->IsPositionValid())
{
sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
delete v;
return false;
}
map->Add((Creature*)v);
return true;
}