#include "stdafx.h"
#include "DynamicObject.h"
#include "ResourceManager.h"
#include "UI/UChat.h"
#include "ItemManager.h"
#include "Map/Map.h"
CDynamicObj::CDynamicObj()
{
m_typeid = TYPE_DYNAMICOBJECT;
m_valuesCount = DYNAMICOBJECT_END;
m_MoveState = NORMALMove;
m_fFaceingAngle = 0.0f;
_InitValues();
}
CDynamicObj::~CDynamicObj()
{
NiAVObject* pkAVObject = m_spSceneNode->GetAt(0);
if(pkAVObject)
g_ResMgr->FreeNif(pkAVObject);
DetachFromScene(true);
}
void CDynamicObj::Update(float dt)
{
CAnimObject::Update(dt);
CGameObject::Update(dt);
UpdateMoveTransform(dt);
}
void CDynamicObj::OnCreate(class ByteBuffer* data, ui8 update_flags)
{
CAnimObject::OnCreate(data, update_flags);
ui32 displayid = GetUInt32Value(DYNAMICOBJECT_DISPLAYID);
ui32 spell = GetUInt32Value(DYNAMICOBJECT_SPELLID);
if (displayid)
{
std::string strFileName = "";
ItemMgr->GetDisplayInfo(displayid, strFileName, 0, 0, true);
if(!strFileName.size())
{
char szMsg[128];
NiSprintf(szMsg, 128, "Not found displayid[%d]
", displayid);
ChatSystem->AppendChatMsg(CHAT_MSG_SYSTEM,szMsg);
}
NiAVObject* pkAVObject = g_ResMgr->LoadNif(strFileName.c_str());
NIASSERT(GetSceneNode());
m_spSceneNode->SetAt(0, pkAVObject);
m_spSceneNode->UpdateNodeBound();
m_spSceneNode->UpdateProperties();
m_spSceneNode->UpdateEffects();
m_spSceneNode->Update(0.0f);
}
}
void CDynamicObj::OnValueChanged(class UpdateMask* mask)
{
CAnimObject::OnValueChanged(mask);
if(mask->GetBit(DYNAMICOBJECT_DISPLAYID))
{
NiAVObject* pkAVObject = m_spSceneNode->GetAt(0);
if(pkAVObject)
g_ResMgr->FreeNif(pkAVObject);
ui32 displayid = GetUInt32Value(DYNAMICOBJECT_DISPLAYID);
if (displayid)
{
std::string strFileName = "";
ItemMgr->GetDisplayInfo(displayid, strFileName, 0, 0, true);
if(!strFileName.size())
{
char szMsg[128];
NiSprintf(szMsg, 128, "Not found displayid[%d]
", displayid);
ChatSystem->AppendChatMsg(CHAT_MSG_SYSTEM,szMsg);
}
pkAVObject = g_ResMgr->LoadNif(strFileName.c_str());
NIASSERT(GetSceneNode());
m_spSceneNode->SetAt(0, pkAVObject);
m_spSceneNode->UpdateNodeBound();
m_spSceneNode->UpdateProperties();
m_spSceneNode->UpdateEffects();
m_spSceneNode->Update(0.0f);
}
}
}
bool CDynamicObj::Draw(CCullingProcess *pkCuller)
{
return CGameObject::Draw(pkCuller);
}
void CDynamicObj::MoveToPosition(const NiPoint3& kLocation, const NiPoint3& kTarget, const uint32& between)
{
m_kMoveTarget = kTarget;
NiPoint3 ptCur = GetPosition();
ptCur.z = kLocation.z;
if ( ( kLocation - ptCur ).Length() > 3.f )
{
SetPosition( kLocation );
}
NiPoint3 kDist = kTarget - kLocation;
kDist.z = 0;
float fNewSpeed = 0.0f;
if (between > 0)
fNewSpeed = kDist.Length()/((float)between*0.001f);
else
{
if (m_MoveState == WalkMove)
fNewSpeed = m_walkSpeed;
if (m_MoveState == RunMove)
fNewSpeed = m_runSpeed;
}
}
void CDynamicObj::UpdateMoveTransform(float fTimeDelta)
{
if (m_MoveState == NORMALMove)
return ;
float fNewSpeed = 0.0f;
if (m_MoveState == WalkMove)
fNewSpeed = m_walkSpeed;
if (m_MoveState == RunMove)
fNewSpeed = m_runSpeed;
NiPoint3 kStartPos, kDesiredPos;
kStartPos = GetPosition();
NiPoint3 vDir = m_kMoveTarget - kStartPos;
vDir.z = 0.0f;
vDir.Unitize();
NiPoint3 kDelta = fTimeDelta * vDir * fNewSpeed;
kDesiredPos = kStartPos + kDelta;
NiPoint3 vOldVec = vDir;
NiPoint3 vNewVec = m_kMoveTarget - kDesiredPos;
vOldVec.z = vNewVec.z = 0.0f;
vOldVec.Unitize();
vNewVec.Unitize();
CMap* pkmap = CMap::Get();
if (vOldVec.Dot(vNewVec) <= 0.001f)
{
kDesiredPos = m_kMoveTarget;
StopMove();
return ;
}
kDesiredPos.z = pkmap->GetHeight(kDesiredPos.x, kDesiredPos.y);
SetDirectionTo(kDesiredPos);
SetPosition(kDesiredPos);
}
void CDynamicObj::SetDesiredAngle(float fz)
{
m_fFaceingAngle = fz;
while( m_fFaceingAngle >= NI_TWO_PI )
{
m_fFaceingAngle -= NI_TWO_PI;
}
SetRotate(NiPoint3(0,0,m_fFaceingAngle));
}
void CDynamicObj::SetDirectionTo(NiPoint3 kpos)
{
NiPoint3 kDir( kpos );
kDir -= GetPosition();
kDir.Unitize();
float fZ = NiATan2(-kDir.y, kDir.x) - NI_PI/2;
if( fZ < 0.f )
fZ += NI_TWO_PI;
if( fZ > NI_TWO_PI )
fZ -= NI_TWO_PI;
if( abs(m_fFaceingAngle - fZ) > 0.01f )
SetDesiredAngle(fZ);
}
void CDynamicObj::StopMove()
{
m_kMoveTarget = GetPosition();
m_MoveState = NORMALMove;
}