#include "StdAfx.h"
#include "Utils/LockDB.h"
#include "SceneGameObj.h"
#include "SceneManager.h"
#include "Utils/ClientUtils.h"
#include "Effect/EffectManager.h"
#include "ItemManager.h"
#include "UI/UISystem.h"
#include "UI/UIGamePlay.h"
#include "UI/UChat.h"
#include "ResourceManager.h"
#include "Skill/SkillManager.h"
#include "SpellEffect.h"
#include "LocalPlayer.h"
#include "ObjectManager.h"
#include "../../../../SDBase/Public/CreatureDef.h"
#include "../../../../SDBase/Public/DBCStores.h"
CSceneGameObj::CSceneGameObj()
:m_bFlag(false)
,m_fColor(0.0f)
{
m_typeid = TYPEID_GAMEOBJECT;
m_GameObjInfo = NULL;
m_pkAmbentLight = NULL;
m_valuesCount = GAMEOBJECT_END;
m_bDrawName = TRUE;
_InitValues();
m_pkScenceOBJEffect = NULL ;
m_bVisiblePickUpEffect = FALSE ;
m_bInBurn = false;
m_FlagType = 0;
m_bInappear = false;
m_pkFlagEffect[0] = NULL;
m_pkFlagEffect[1] = NULL;
m_pkFlagEffect[2] = NULL;
m_pkFlagEffect[3] = NULL;
m_pkFlagEffect[4] = NULL;
m_pkFlagEffect[5] = NULL;
m_pkFlagEffect[6] = NULL;
m_pkFlagEffectBurn = NULL;
m_pkFlagEffectAppear = NULL;
m_fShowTime = 0;
}
CSceneGameObj::~CSceneGameObj()
{
NiAVObject* pkAVObject = m_spSceneNode->GetAt(0);
if(pkAVObject)
g_ResMgr->FreeNif(pkAVObject);
for ( int i = 0; i < 7; i++ )
{
if ( m_pkFlagEffect[i] )
{
if ( EffectMgr )
{
EffectMgr->ReleaseEffect( m_pkFlagEffect[i] );
}
}
}
if (m_pkAmbentLight)
{
NiDelete m_pkAmbentLight;
}
if (m_pkScenceOBJEffect)
{
if(EffectMgr)
EffectMgr->ReleaseEffect(m_pkScenceOBJEffect);
m_pkScenceOBJEffect = NULL ;
}
DetachFromScene(true);
}
void CSceneGameObj::OnValueChanged(class UpdateMask* mask)
{
CCharacter::OnValueChanged( mask );
if(mask->GetBit(OBJECT_FIELD_SCALE_X))
{
float scale = GetFloatValue(OBJECT_FIELD_SCALE_X);
GetSceneNode()->SetScale(scale);
GetSceneNode()->Update(0);
GetSceneNode()->UpdateProperties();
}
if ( GetUInt32Value( GAMEOBJECT_TYPE_ID ) != GAMEOBJECT_TYPE_FLAGSTAND )
{
return;
}
if ( m_justCreate )
{
int flagCreate = GetInt32Value( GAMEOBJECT_FLAGS );
if ( flagCreate < 0 )
{
return;
}
if ( flagCreate > 10 )
{
flagCreate = 3 + flagCreate%10;
}
m_FlagType = flagCreate;
m_pkFlagEffect[flagCreate]->SetVisible( true );
return;
}
if( mask->GetBit( GAMEOBJECT_FLAGS ))
{
int flag = GetInt32Value( GAMEOBJECT_FLAGS );
if ( flag < 0 )
{
return;
}
if ( flag > 10 )
{
flag = 3 + flag%10;
}
std::string strFileName;
if ( m_FlagType == flag && !m_bInappear && !m_bInBurn )
{
if ( m_FlagType < 7 && m_FlagType >= 0 )
{
if ( m_pkFlagEffect[flag] )
{
m_pkFlagEffect[flag]->SetVisible( true );
}
//SetCurAnimation( strFileName.c_str(), 1.f, 1, TRUE );
return;
}
}
switch(m_FlagType)
{
case 0:
{
strFileName = "flags/flag_war_fire.nif";
}
break;
case 1:
{
strFileName = "flags/flag_y_fire.nif";
}
break;
case 2:
{
strFileName = "flags/flag_r_fire.nif";
}
break;
case 3:
{
strFileName = "flags/flag_w_fire.nif";
}
break;
case 4:
{
strFileName = "flags/flag_y_dark_disppear.nif";
}
break;
case 5:
{
strFileName = "flags/flag_r_dark_disppear.nif";
}
break;
case 6:
{
strFileName = "flags/flag_w_dark_disppear.nif";
}
break;
}
if ( strFileName.length() > 0 )
{
m_pkFlagEffectBurn = (CSceneEffect*)EffectMgr->CreateSceneEffect( strFileName.c_str(), true, true, false, 1 );
if ( m_pkFlagEffectBurn )
{
m_pkFlagEffectBurn->AttachToSceneObject( GetGUID() );
NiTimeController* MaxTimeCtrl = NULL;
CGameObject::GetMaxAnimTime(m_pkFlagEffectBurn->GetAVObject(), m_fShowTime, &MaxTimeCtrl);
m_pkFlagEffectBurn->SetVisible( true );
m_bInBurn = true;
}
}
if ( m_FlagType != flag )
{
if ( m_FlagType < 7 && m_FlagType >= 0 )
{
if( m_pkFlagEffect[m_FlagType] )
m_pkFlagEffect[m_FlagType]->SetVisible( false );
}
}
m_FlagType = flag;
}
}
void CSceneGameObj::OnCreate(class ByteBuffer* data, ui8 update_flags)
{
CCharacter::OnCreate(data, update_flags);
if ( GetUInt32Value( GAMEOBJECT_TYPE_ID ) == GAMEOBJECT_TYPE_FLAGSTAND )
{
m_pkFlagEffect[0] = (CSceneEffect*)EffectMgr->CreateSceneEffect( "flags/flag_war_wait.nif" );
m_pkFlagEffect[0]->AttachToSceneObject( GetGUID() );
m_pkFlagEffect[1] = (CSceneEffect*)EffectMgr->CreateSceneEffect( "flags/flag_y_wait.nif" );
m_pkFlagEffect[1]->AttachToSceneObject( GetGUID() );
m_pkFlagEffect[2] = (CSceneEffect*)EffectMgr->CreateSceneEffect( "flags/flag_r_wait.nif");
m_pkFlagEffect[2]->AttachToSceneObject( GetGUID() );
m_pkFlagEffect[3] = (CSceneEffect*)EffectMgr->CreateSceneEffect( "flags/flag_w_wait.nif");
m_pkFlagEffect[3]->AttachToSceneObject( GetGUID() );
m_pkFlagEffect[4] = (CSceneEffect*)EffectMgr->CreateSceneEffect( "flags/flag_y_dark_wait.nif");
m_pkFlagEffect[4]->AttachToSceneObject( GetGUID() );
m_pkFlagEffect[5] = (CSceneEffect*)EffectMgr->CreateSceneEffect( "flags/flag_r_dark_wait.nif");
m_pkFlagEffect[5]->AttachToSceneObject( GetGUID() );
m_pkFlagEffect[6] = (CSceneEffect*)EffectMgr->CreateSceneEffect( "flags/flag_w_dark_wait.nif");
m_pkFlagEffect[6]->AttachToSceneObject( GetGUID() );
}
CreateSceneGameObj(GetUInt32Value(OBJECT_FIELD_ENTRY));
NiAVObject* pkNameOffset = GetSceneNode()->GetObjectByName("Dummy02");
if(pkNameOffset)
m_kNamePosOffset = pkNameOffset->GetTranslate().z * 1.f;
else
m_kNamePosOffset += 1.0f;
m_spNameRef = new sNameRecode;
}
BOOL CSceneGameObj::IsGatherObj()
{
if (m_GameObjInfo && m_GameObjInfo->Type == GAMEOBJECT_TYPE_PICK)
{
return TRUE ;
}
return FALSE ;
}
uint32 CSceneGameObj::GetReqSpell()
{
return m_GameObjInfo->ReqSpell;
}
BOOL CSceneGameObj::CanSeeCollection()
{
CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer();
BOOL hasQuest = true ;
BOOL hasLearnSpell = true ;
if (pkLocal && m_GameObjInfo)
{
if (m_GameObjInfo->QuestID)
{
hasQuest = pkLocal->IsNeedAddScenOBJ(GetUInt32Value(OBJECT_FIELD_ENTRY), m_GameObjInfo->QuestID, m_GameObjInfo->QuestItemID);
}
if (m_GameObjInfo->ReqSpell && m_GameObjInfo->ReqSpell != 4)
{
hasLearnSpell = pkLocal->HasLearnSkill(m_GameObjInfo->ReqSpell);
}
return (hasLearnSpell && hasQuest);
}
return FALSE ;
}
BOOL CSceneGameObj::HasRegItem()
{
CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer();
BOOL hasItem = true ;
if (m_GameObjInfo->ReqItem)
{
hasItem = pkLocal->HasItem(m_GameObjInfo->ReqItem);
}
return hasItem;
}
bool CSceneGameObj::GetPickBound(NiBound& kBound)
{
if (!GetSceneNode())
return false;
return CAnimObject::GetPickBound(kBound);
}
bool CSceneGameObj::IsPick(NiPick& kPicker,const NiPoint3& kOrig,const NiPoint3& kDir)
{
if (!GetSceneNode())
return false;
return CAnimObject::IsPick(kPicker, kOrig, kDir);
}
void CSceneGameObj::AddEffect()
{
if (m_pkScenceOBJEffect == NULL)
{
m_pkScenceOBJEffect = (CSceneEffect*)EffectMgr->CreateSceneEffect("Effect_pickup01.nif", true, true);
if (m_pkScenceOBJEffect)
{
m_pkScenceOBJEffect->AttachToSceneObject(GetGUID());
m_pkScenceOBJEffect->SetVisible(false);
}
}
if (m_pkScenceOBJEffect && !m_bVisiblePickUpEffect)
{
m_bVisiblePickUpEffect = TRUE;
m_pkScenceOBJEffect->SetVisible(m_bVisiblePickUpEffect);
}
}
void CSceneGameObj::DelEffect()
{
if (m_bVisiblePickUpEffect && m_pkScenceOBJEffect)
{
m_bVisiblePickUpEffect = FALSE ;
m_pkScenceOBJEffect->SetVisible(m_bVisiblePickUpEffect);
}
}
bool CSceneGameObj::CreateSceneGameObj(ui32 entry)
{
// ×°ÔØNif
//m_pkItemProperty = ItemMgr->GetItemPropertyFromDataBase(itemid);
//if(m_pkItemProperty)
{
ui32 displayid = GetUInt32Value(GAMEOBJECT_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);
CGameObjectDB::stGameObject* pGameObject = g_pkGameObjectDB->GetGameObject(entry);
m_GameObjInfo = pGameObject;
CaculateBoundBox();
if (IsGatherObj())
{
SetName(pGameObject ? pGameObject->Name.c_str() : _TRAN("δ֪"));
CPlayerLocal* pkLocal = ObjectMgr->GetLocalPlayer();
if (CanSeeCollection())
{
AddEffect();
}
}
m_spSceneNode->UpdateNodeBound();
m_spSceneNode->UpdateProperties();
m_spSceneNode->UpdateEffects();
m_spSceneNode->Update(0.0f);
}
return true;
}
void CSceneGameObj::SpellGo(SpellID spellID, const vector& vTargetHit, const SpellCastTargets& sepllCastTarget)
{
// SpellTemplate* pkSpellTemplate = SYState()->SkillMgr->GetSpellTemplate(spellID);
// if (!pkSpellTemplate)
// return;
// const SpellVisualDesc* pkVisualKit = pkSpellTemplate->GetVisulalKit();
// if (!pkVisualKit) return;
// const std::vector& effects = pkVisualKit->m_kEffects.vEffects;
// Target target;
SpellEffectEmit::EmitParam ep;
ep.m_iSpellid = spellID;
ep.m_OwnerID = this->GetGUID();
unsigned int ui = 0;
for ( ui = 0; ui < vTargetHit.size(); ui++)
ep.m_kTargets.AddEntry(vTargetHit[ui]);
// std::vector result;
std::vector results;
SpellEffectEmit::Get()->Emit(ep, results);
// for ( ui = 0; ui < effects.size(); ui++ )
// {
// SpellEffectEmit::Get()->EmitEffect(this, &target, effects[ui], pkSpellTemplate, true);
// }
}
void CSceneGameObj::Update(float dt)
{
CGameObject::Update(dt);
m_fShowTime -= dt;
if ( m_fShowTime < 0.f )
{
m_fShowTime = 0.f;
}
// ??
UpdateEffect(dt);
if ( m_bInBurn )
{
if ( m_fShowTime < 0.0001f )
{
std::string strFileName;
switch(m_FlagType)
{
case 0:
{
strFileName = "flags/flag_war_appear.nif";
}
break;
case 1:
{
strFileName = "flags/flag_y_appear.nif";
}
break;
case 2:
{
strFileName = "flags/flag_r_appear.nif";
}
break;
case 3:
{
strFileName = "flags/flag_w_appear.nif";
}
break;
case 4:
{
strFileName = "flags/flag_y_dark_appear.nif";
}
break;
case 5:
{
strFileName = "flags/flag_r_dark_appear.nif";
}
break;
case 6:
{
strFileName = "flags/flag_w_dark_appear.nif";
}
break;
}
if ( strFileName.length() > 0 )
{
m_pkFlagEffectAppear = (CSceneEffect*)EffectMgr->CreateSceneEffect( strFileName.c_str(), true, true, false, 1 );
if ( m_pkFlagEffectAppear )
{
m_pkFlagEffectAppear->AttachToSceneObject( GetGUID() );
NiTimeController* MaxTimeCtrl = NULL;
CGameObject::GetMaxAnimTime(m_pkFlagEffectAppear->GetAVObject(), m_fShowTime, &MaxTimeCtrl);
m_pkFlagEffectAppear->SetVisible( true );
m_bInBurn = false;
}
}
m_bInappear = true;
return;
}
}
if ( m_bInappear )
{
if ( m_fShowTime < 0.0001f )
{
if ( m_FlagType < 7 && m_FlagType >= 0 )
{
if( m_pkFlagEffect[m_FlagType] )
m_pkFlagEffect[m_FlagType]->SetVisible( true );
}
m_bInappear = false;
}
}
}
void CSceneGameObj::UpdateEffect(float dt)
{
if(m_bFlag)
{
m_fColor -= dt;
if(m_fColor < 0.0f)
{
m_fColor = 0.0f;
m_bFlag = false;
}
}
else
{
m_fColor += dt;
if(m_fColor > 1.0f)
{
m_fColor = 1.0f;
m_bFlag = true;
}
}
const NiDynamicEffectList& kEffectList = m_spSceneNode->GetEffectList();
NiTListIterator kIter = kEffectList.GetHeadPos();
while(kIter != NULL)
{
NiDynamicEffect* pkEffect = kEffectList.GetNext(kIter);
if(NiIsKindOf(NiAmbientLight, pkEffect))
{
NiAmbientLight* pkAmbLight = NiDynamicCast(NiAmbientLight, pkEffect);
if (pkAmbLight)
{
pkAmbLight->SetDiffuseColor(NiColor(m_fColor, m_fColor, m_fColor));
pkAmbLight->SetAmbientColor(NiColor(m_fColor, m_fColor, m_fColor));
pkAmbLight->SetSpecularColor(NiColor(m_fColor, m_fColor, m_fColor));
}
break;
}
}
m_spSceneNode->UpdateEffects();
}
void CSceneGameObj::DrawName(const NiCamera* Camera)
{
CPlayerLocal* pkLocalPlayer = ObjectMgr->GetLocalPlayer();
NiPoint3 Point( GetPosition() );
Point -= pkLocalPlayer->GetCamera().GetTranslate();
float dist = Point.Length();
NiPoint3 kPos( GetSceneNode()->GetTranslate() );
kPos.z += m_kNamePosOffset * GetSceneNode()->GetScale();
WorldPtToUIPt(kPos, Camera);
CharName* NewName = &m_spNameRef->stName;
NewName->bAFK = false;
NewName->bDND = false;
NewName->bShowMask = false;
NewName->bShowName = true;
NewName->Class = 0;
NewName->ffa = 0;
NewName->zodiac = 0;
NewName->bGM = false;
m_spNameRef->type = GOT_SCENEOBJECT;
EffectMgr->AddCharName(m_spNameRef, kPos, GetName(), NULL, NULL, NULL, 0xfff4d31d, dist, false, true);
}
bool CSceneGameObj::Draw(CCullingProcess* pkCuller)
{
NiCamera* pkCamera = pkCuller->GetCamera();
//ÏÔʾÐÕÃû
if (m_bDrawName)
{
DrawName(pkCamera);
}
return CGameObject::Draw(pkCuller);
}
int CSceneGameObj::CanbeCollected()
{
if ( !m_GameObjInfo )
{
return FALSE;
}
Lock* plock = g_LockObjects->GetObjectLock( m_GameObjInfo->SpellFocus );
if ( plock )
{
for (int i = 0; i < 8; i ++)
{
switch (plock->locktype[i])
{
case 2:
{
if( plock->lockmisc[i] == LOCKTYPE_HERBALISM)
{
CPlayerLocal* plLocal = ObjectMgr->GetLocalPlayer();
if ( plLocal->GetProfessionState( 182 ) && ( plLocal->GetProfessionState( 182 )->current < plock->minlockskill[i] ) )
{
return 1;
}
}
if( plock->lockmisc[i] == LOCKTYPE_MINING)
{
CPlayerLocal* plLocal = ObjectMgr->GetLocalPlayer();
uint32 reqitem = m_GameObjInfo->ReqItem;
if ( reqitem && !plLocal->HasItem( reqitem))
{
return 2;
}
uint32 skilllock = plock->minlockskill[i];
if ( ( plLocal->GetProfessionState( 186 ) && ( plLocal->GetProfessionState( 186 )->current < skilllock )) )
{
return 3;
}
}
}
break;
}
}
}
return 0;
}