mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-18 22:19:54 -04:00
Core/Transports
* Rewritten path generation, now uses splines - timers are a lot more accurate now * Implemented stopping transports * Implemented spawning transports in instances * Implemented spawning gameobjects as transport passengers * Transport passengers are now stored in creature/gameobject table using gameobject_template.data6 from transport's template as map id
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <G3D/Quat.h>
|
||||
#include "GameObjectAI.h"
|
||||
#include "Battleground.h"
|
||||
#include "CellImpl.h"
|
||||
@@ -32,8 +33,10 @@
|
||||
#include "SpellMgr.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
#include "World.h"
|
||||
#include "Transport.h"
|
||||
|
||||
GameObject::GameObject(): WorldObject(false), m_model(NULL), m_goValue(), m_AI(NULL)
|
||||
GameObject::GameObject() : WorldObject(false), MapObject(),
|
||||
m_model(NULL), m_goValue(), m_AI(NULL)
|
||||
{
|
||||
m_objectType |= TYPEMASK_GAMEOBJECT;
|
||||
m_objectTypeId = TYPEID_GAMEOBJECT;
|
||||
@@ -100,6 +103,9 @@ void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
|
||||
|
||||
if (m_uint32Values) // field array can be not exist if GameOBject not loaded
|
||||
RemoveFromOwner();
|
||||
|
||||
if (GetTransport() && !ToTransport())
|
||||
GetTransport()->RemovePassenger(this);
|
||||
}
|
||||
|
||||
void GameObject::RemoveFromOwner()
|
||||
@@ -169,6 +175,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
SetMap(map);
|
||||
|
||||
Relocate(x, y, z, ang);
|
||||
m_stationaryPosition.Relocate(x, y, z, ang);
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_GENERAL, "Gameobject (GUID: %u Entry: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, name_id, x, y);
|
||||
@@ -192,6 +199,9 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
return false;
|
||||
}
|
||||
|
||||
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
|
||||
m_updateFlag = (m_updateFlag | UPDATEFLAG_TRANSPORT) & ~UPDATEFLAG_POSITION;
|
||||
|
||||
Object::_Create(guidlow, goinfo->entry, HIGHGUID_GAMEOBJECT);
|
||||
|
||||
m_goInfo = goinfo;
|
||||
@@ -238,9 +248,11 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_TRANSPORT:
|
||||
SetUInt32Value(GAMEOBJECT_LEVEL, goinfo->transport.pause);
|
||||
if (goinfo->transport.startOpen)
|
||||
SetGoState(GO_STATE_ACTIVE);
|
||||
SetGoState(goinfo->transport.startOpen ? GO_STATE_ACTIVE : GO_STATE_READY);
|
||||
SetGoAnimProgress(animprogress);
|
||||
m_goValue.Transport.PathProgress = 0;
|
||||
m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(goinfo->entry);
|
||||
m_goValue.Transport.CurrentSeg = 0;
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_FISHINGNODE:
|
||||
SetGoAnimProgress(0);
|
||||
@@ -274,18 +286,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
|
||||
void GameObject::Update(uint32 diff)
|
||||
{
|
||||
if (!AI())
|
||||
{
|
||||
if (!AIM_Initialize())
|
||||
TC_LOG_ERROR(LOG_FILTER_GENERAL, "Could not initialize GameObjectAI");
|
||||
} else
|
||||
if (AI())
|
||||
AI()->UpdateAI(diff);
|
||||
|
||||
if (IS_MO_TRANSPORT_GUID(GetGUID()))
|
||||
{
|
||||
//((Transport*)this)->Update(p_time);
|
||||
return;
|
||||
}
|
||||
else if (!AIM_Initialize())
|
||||
TC_LOG_ERROR(LOG_FILTER_GENERAL, "Could not initialize GameObjectAI");
|
||||
|
||||
switch (m_lootState)
|
||||
{
|
||||
@@ -308,6 +312,38 @@ void GameObject::Update(uint32 diff)
|
||||
m_lootState = GO_READY;
|
||||
break;
|
||||
}
|
||||
/* TODO: Fix movement in unloaded grid - currently GO will just disappear
|
||||
case GAMEOBJECT_TYPE_TRANSPORT:
|
||||
{
|
||||
if (!m_goValue.Transport.AnimationInfo)
|
||||
break;
|
||||
|
||||
if (GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
m_goValue.Transport.PathProgress += diff;
|
||||
uint32 timer = m_goValue.Transport.PathProgress % m_goValue.Transport.AnimationInfo->TotalTime;
|
||||
TransportAnimationEntry const* node = m_goValue.Transport.AnimationInfo->GetAnimNode(timer);
|
||||
if (node && m_goValue.Transport.CurrentSeg != node->TimeSeg)
|
||||
{
|
||||
m_goValue.Transport.CurrentSeg = node->TimeSeg;
|
||||
|
||||
G3D::Quat rotation = m_goValue.Transport.AnimationInfo->GetAnimRotation(timer);
|
||||
G3D::Vector3 pos = rotation.toRotationMatrix()
|
||||
* G3D::Matrix3::fromEulerAnglesZYX(GetOrientation(), 0.0f, 0.0f)
|
||||
* G3D::Vector3(node->X, node->Y, node->Z);
|
||||
|
||||
pos += G3D::Vector3(GetStationaryX(), GetStationaryY(), GetStationaryZ());
|
||||
|
||||
G3D::Vector3 src(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
|
||||
sLog->outInfo(LOG_FILTER_GENERAL, "Src: %s Dest: %s", src.toString().c_str(), pos.toString().c_str());
|
||||
|
||||
GetMap()->GameObjectRelocation(this, pos.x, pos.y, pos.z, GetOrientation());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
case GAMEOBJECT_TYPE_FISHINGNODE:
|
||||
{
|
||||
// fishing code (bobber ready)
|
||||
@@ -1182,10 +1218,12 @@ void GameObject::Use(Unit* user)
|
||||
if (itr->second)
|
||||
{
|
||||
if (Player* ChairUser = ObjectAccessor::FindPlayer(itr->second))
|
||||
{
|
||||
if (ChairUser->IsSitState() && ChairUser->getStandState() != UNIT_STAND_STATE_SIT && ChairUser->GetExactDist2d(x_i, y_i) < 0.1f)
|
||||
continue; // This seat is already occupied by ChairUser. NOTE: Not sure if the ChairUser->getStandState() != UNIT_STAND_STATE_SIT check is required.
|
||||
else
|
||||
itr->second = 0; // This seat is unoccupied.
|
||||
}
|
||||
else
|
||||
itr->second = 0; // The seat may of had an occupant, but they're offline.
|
||||
}
|
||||
@@ -2102,6 +2140,7 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
if (index == GAMEOBJECT_DYNAMIC)
|
||||
{
|
||||
uint16 dynFlags = 0;
|
||||
int16 pathProgress = -1;
|
||||
switch (GetGoType())
|
||||
{
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
@@ -2115,12 +2154,13 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
if (ActivateToQuest(target))
|
||||
dynFlags |= GO_DYNFLAG_LO_SPARKLE;
|
||||
break;
|
||||
default:
|
||||
case GAMEOBJECT_TYPE_MO_TRANSPORT:
|
||||
pathProgress = int16(float(m_goValue.Transport.PathProgress) / float(GetUInt32Value(GAMEOBJECT_LEVEL)) * 65535.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
fieldBuffer << uint16(dynFlags);
|
||||
fieldBuffer << uint16(-1);
|
||||
fieldBuffer << int16(pathProgress);
|
||||
}
|
||||
else if (index == GAMEOBJECT_FLAGS)
|
||||
{
|
||||
@@ -2140,3 +2180,25 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
updateMask.AppendToPacket(data);
|
||||
data->append(fieldBuffer);
|
||||
}
|
||||
|
||||
void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /* = NULL*/) const
|
||||
{
|
||||
if (m_DBTableGuid)
|
||||
{
|
||||
if (GameObjectData const* data = sObjectMgr->GetGOData(GetDBTableGUIDLow()))
|
||||
{
|
||||
x = data->posX;
|
||||
y = data->posY;
|
||||
z = data->posZ;
|
||||
if (ori)
|
||||
*ori = data->orientation;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
x = GetPositionX();
|
||||
y = GetPositionY();
|
||||
z = GetPositionZ();
|
||||
if (ori)
|
||||
*ori = GetOrientation();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user