Initial commit: client source
This commit is contained in:
@@ -0,0 +1,979 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
#include "AreaTerrain.h"
|
||||
#include "RaceData.h"
|
||||
#include "../SpeedTreeLib/SpeedTreeForestDirectX8.h"
|
||||
#include "../SpeedTreeLib/SpeedTreeWrapper.h"
|
||||
|
||||
enum
|
||||
{
|
||||
MAIN_RACE_MAX_NUM = 8,
|
||||
};
|
||||
|
||||
void CActorInstance::INSTANCEBASE_Deform()
|
||||
{
|
||||
Deform();
|
||||
TraceProcess();
|
||||
}
|
||||
|
||||
void CActorInstance::INSTANCEBASE_Transform()
|
||||
{
|
||||
if (m_pkHorse)
|
||||
{
|
||||
m_pkHorse->INSTANCEBASE_Transform();
|
||||
|
||||
m_x = m_pkHorse->NEW_GetCurPixelPositionRef().x;
|
||||
m_y = -m_pkHorse->NEW_GetCurPixelPositionRef().y;
|
||||
m_z = m_pkHorse->NEW_GetCurPixelPositionRef().z;
|
||||
m_bNeedUpdateCollision = TRUE;
|
||||
}
|
||||
|
||||
//DWORD t2=ELTimer_GetMSec();
|
||||
Update();
|
||||
//DWORD t3=ELTimer_GetMSec();
|
||||
TransformProcess();
|
||||
//DWORD t4=ELTimer_GetMSec();
|
||||
Transform();
|
||||
//DWORD t5=ELTimer_GetMSec();
|
||||
UpdatePointInstance();
|
||||
//DWORD t6=ELTimer_GetMSec();
|
||||
ShakeProcess();
|
||||
//DWORD t7=ELTimer_GetMSec();
|
||||
UpdateBoundingSphere();
|
||||
//DWORD t8=ELTimer_GetMSec();
|
||||
UpdateAttribute();
|
||||
}
|
||||
|
||||
/*
|
||||
void CActorInstance::TEMP_Update()
|
||||
{
|
||||
//DWORD t1=ELTimer_GetMSec();
|
||||
OnUpdate();
|
||||
//DWORD t2=ELTimer_GetMSec();
|
||||
UpdateBoundingSphere();
|
||||
//DWORD t3=ELTimer_GetMSec();
|
||||
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
{
|
||||
static FILE* fp=fopen("perf_actor_update.txt", "w");
|
||||
|
||||
if (t3-t1>3)
|
||||
{
|
||||
fprintf(fp, "AIU.Total %d (Time %f)\n",
|
||||
t3-t1, ELTimer_GetMSec()/1000.0f);
|
||||
fprintf(fp, "AIU.UP %d\n", t2-t1);
|
||||
fprintf(fp, "AIU.UBS %d\n", t3-t2);
|
||||
fprintf(fp, "-------------------------------- \n");
|
||||
fflush(fp);
|
||||
}
|
||||
fflush(fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
void CActorInstance::OnUpdate()
|
||||
{
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t1=ELTimer_GetMSec();
|
||||
#endif
|
||||
if (!IsParalysis())
|
||||
CGraphicThingInstance::OnUpdate();
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t2=ELTimer_GetMSec();
|
||||
#endif
|
||||
|
||||
UpdateAttachingInstances();
|
||||
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t3=ELTimer_GetMSec();
|
||||
#endif
|
||||
|
||||
__BlendAlpha_Update();
|
||||
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t4=ELTimer_GetMSec();
|
||||
{
|
||||
static FILE* fp=fopen("perf_actor_update2.txt", "w");
|
||||
|
||||
if (t4-t1>3)
|
||||
{
|
||||
fprintf(fp, "AIU2.Total %d (Time %f)\n",
|
||||
t4-t1, ELTimer_GetMSec()/1000.0f);
|
||||
fprintf(fp, "AIU2.GU %d\n", t2-t1);
|
||||
fprintf(fp, "AIU2.UAI %d\n", t3-t2);
|
||||
fprintf(fp, "AIU2.BAU %d\n", t4-t3);
|
||||
fprintf(fp, "-------------------------------- \n");
|
||||
fflush(fp);
|
||||
}
|
||||
fflush(fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// 2004.07.05.myevan. 궁신탄영 맵에 끼이는 문제해결
|
||||
IBackground& CActorInstance::GetBackground()
|
||||
{
|
||||
return IBackground::Instance();
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::SetMainInstance()
|
||||
{
|
||||
m_isMain=true;
|
||||
}
|
||||
|
||||
void CActorInstance::SetParalysis(bool isParalysis)
|
||||
{
|
||||
m_isParalysis=isParalysis;
|
||||
}
|
||||
|
||||
void CActorInstance::SetFaint(bool isFaint)
|
||||
{
|
||||
m_isFaint=isFaint;
|
||||
}
|
||||
|
||||
void CActorInstance::SetSleep(bool isSleep)
|
||||
{
|
||||
m_isSleep=isSleep;
|
||||
|
||||
Stop();
|
||||
}
|
||||
|
||||
void CActorInstance::SetResistFallen(bool isResistFallen)
|
||||
{
|
||||
m_isResistFallen=isResistFallen;
|
||||
}
|
||||
|
||||
void CActorInstance::SetReachScale(float fScale)
|
||||
{
|
||||
m_fReachScale=fScale;
|
||||
}
|
||||
|
||||
float CActorInstance::__GetReachScale()
|
||||
{
|
||||
return m_fReachScale;
|
||||
}
|
||||
|
||||
float CActorInstance::__GetAttackSpeed()
|
||||
{
|
||||
return m_fAtkSpd;
|
||||
}
|
||||
|
||||
WORD CActorInstance::__GetCurrentComboType()
|
||||
{
|
||||
if (IsBowMode())
|
||||
return 0;
|
||||
if (IsHandMode())
|
||||
return 0;
|
||||
if (__IsMountingHorse())
|
||||
return 0;
|
||||
|
||||
return m_wcurComboType;
|
||||
}
|
||||
|
||||
void CActorInstance::SetComboType(WORD wComboType)
|
||||
{
|
||||
m_wcurComboType = wComboType;
|
||||
}
|
||||
|
||||
void CActorInstance::SetAttackSpeed(float fAtkSpd)
|
||||
{
|
||||
m_fAtkSpd=fAtkSpd;
|
||||
}
|
||||
|
||||
void CActorInstance::SetMoveSpeed(float fMovSpd)
|
||||
{
|
||||
if (m_fMovSpd==fMovSpd)
|
||||
return;
|
||||
|
||||
m_fMovSpd=fMovSpd;
|
||||
|
||||
if (__IsMoveMotion())
|
||||
{
|
||||
Stop();
|
||||
Move();
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::SetFishingPosition(D3DXVECTOR3 & rv3Position)
|
||||
{
|
||||
m_v3FishingPosition = rv3Position;
|
||||
}
|
||||
|
||||
// ActorInstanceMotion.cpp 에 넣도록 하자
|
||||
void CActorInstance::Move()
|
||||
{
|
||||
if (m_isWalking)
|
||||
{
|
||||
SetLoopMotion(CRaceMotionData::NAME_WALK, 0.15f, m_fMovSpd);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLoopMotion(CRaceMotionData::NAME_RUN, 0.15f, m_fMovSpd);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::Stop(float fBlendingTime)
|
||||
{
|
||||
__ClearMotion();
|
||||
SetLoopMotion(CRaceMotionData::NAME_WAIT, fBlendingTime);
|
||||
}
|
||||
|
||||
void CActorInstance::SetOwner(DWORD dwOwnerVID)
|
||||
{
|
||||
m_fOwnerBaseTime=GetLocalTime();
|
||||
m_dwOwnerVID=dwOwnerVID;
|
||||
}
|
||||
|
||||
void CActorInstance::SetActorType(UINT eType)
|
||||
{
|
||||
m_eActorType=eType;
|
||||
}
|
||||
|
||||
UINT CActorInstance::GetActorType() const
|
||||
{
|
||||
return m_eActorType;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsHandMode()
|
||||
{
|
||||
if (CRaceMotionData::MODE_GENERAL==GetMotionMode())
|
||||
return true;
|
||||
|
||||
if (CRaceMotionData::MODE_HORSE==GetMotionMode())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsTwoHandMode()
|
||||
{
|
||||
if (CRaceMotionData::MODE_TWOHAND_SWORD==GetMotionMode())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsBowMode()
|
||||
{
|
||||
if (CRaceMotionData::MODE_BOW==GetMotionMode())
|
||||
return true;
|
||||
|
||||
if (CRaceMotionData::MODE_HORSE_BOW==GetMotionMode())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsPoly()
|
||||
{
|
||||
if (TYPE_POLY==m_eActorType)
|
||||
return true;
|
||||
|
||||
if (TYPE_PC==m_eActorType)
|
||||
if (m_eRace >= MAIN_RACE_MAX_NUM)
|
||||
return TRUE;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsPC()
|
||||
{
|
||||
if (TYPE_PC==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsNPC()
|
||||
{
|
||||
if (TYPE_NPC==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsEnemy()
|
||||
{
|
||||
if (TYPE_ENEMY==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsStone()
|
||||
{
|
||||
if (TYPE_STONE==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsWarp()
|
||||
{
|
||||
if (TYPE_WARP==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsGoto()
|
||||
{
|
||||
if (TYPE_GOTO==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsBuilding()
|
||||
{
|
||||
if (TYPE_BUILDING==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsDoor()
|
||||
{
|
||||
if (TYPE_DOOR==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsObject()
|
||||
{
|
||||
if (TYPE_OBJECT==m_eActorType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CActorInstance::DestroySystem()
|
||||
{
|
||||
}
|
||||
|
||||
void CActorInstance::DieEnd()
|
||||
{
|
||||
Die();
|
||||
|
||||
CGraphicThingInstance::SetMotionAtEnd();
|
||||
}
|
||||
|
||||
void CActorInstance::Die()
|
||||
{
|
||||
if (m_isRealDead)
|
||||
return;
|
||||
|
||||
if (__IsMoveMotion())
|
||||
Stop();
|
||||
|
||||
SetAdvancingRotation(GetRotation());
|
||||
|
||||
if (IsStone())
|
||||
{
|
||||
InterceptOnceMotion(CRaceMotionData::NAME_DEAD);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!__IsDieMotion())
|
||||
{
|
||||
InterceptOnceMotion(CRaceMotionData::NAME_DEAD);
|
||||
}
|
||||
}
|
||||
|
||||
m_isRealDead = TRUE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsSleep()
|
||||
{
|
||||
return m_isSleep;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsParalysis()
|
||||
{
|
||||
return m_isParalysis;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsFaint()
|
||||
{
|
||||
return m_isFaint;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsResistFallen()
|
||||
{
|
||||
return m_isResistFallen;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsMoving()
|
||||
{
|
||||
return __IsMoveMotion();
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsWaiting()
|
||||
{
|
||||
return __IsWaitMotion();
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsDead()
|
||||
{
|
||||
return m_isRealDead;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsKnockDown()
|
||||
{
|
||||
return __IsKnockDownMotion();
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsDamage()
|
||||
{
|
||||
return __IsDamageMotion();
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsAttacked()
|
||||
{
|
||||
if (IsPushing())
|
||||
return TRUE;
|
||||
|
||||
if (__IsDamageMotion())
|
||||
return TRUE;
|
||||
|
||||
if (__IsKnockDownMotion())
|
||||
return TRUE;
|
||||
|
||||
if (__IsDieMotion())
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Process
|
||||
void CActorInstance::PhysicsProcess()
|
||||
{
|
||||
m_PhysicsObject.Update(m_fSecondElapsed);
|
||||
AddMovement(m_PhysicsObject.GetXMovement(), m_PhysicsObject.GetYMovement(), 0.0f);
|
||||
}
|
||||
|
||||
void CActorInstance::__AccumulationMovement(float fRot)
|
||||
{
|
||||
// NOTE - 일단은 WAIT로 미끄러짐 방지
|
||||
// 추후에는 RaceMotionData가 이동되는 모션인지에 대한 Flag를 갖고 있게끔 한다. - [levites]
|
||||
if (CRaceMotionData::NAME_WAIT == __GetCurrentMotionIndex())
|
||||
return;
|
||||
|
||||
D3DXMATRIX s_matRotationZ;
|
||||
D3DXMatrixRotationZ(&s_matRotationZ, D3DXToRadian(fRot));
|
||||
UpdateTransform(&s_matRotationZ, GetAverageSecondElapsed());
|
||||
|
||||
AddMovement(s_matRotationZ._41, s_matRotationZ._42, s_matRotationZ._43);
|
||||
}
|
||||
|
||||
void CActorInstance::AccumulationMovement()
|
||||
{
|
||||
if (m_pkTree)
|
||||
return;
|
||||
|
||||
if (m_pkHorse)
|
||||
{
|
||||
m_pkHorse->__AccumulationMovement(m_fcurRotation);
|
||||
return;
|
||||
}
|
||||
|
||||
__AccumulationMovement(m_fAdvancingRotation);
|
||||
}
|
||||
|
||||
void CActorInstance::TransformProcess()
|
||||
{
|
||||
if (!IsParalysis())
|
||||
{
|
||||
m_x += m_v3Movement.x;
|
||||
m_y += m_v3Movement.y;
|
||||
m_z += m_v3Movement.z;
|
||||
}
|
||||
|
||||
__InitializeMovement();
|
||||
|
||||
SetPosition(m_x, m_y, m_z);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Process
|
||||
|
||||
void CActorInstance::OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector)
|
||||
{
|
||||
assert(pscdVector);
|
||||
CStaticCollisionDataVector::const_iterator it;
|
||||
for(it = pscdVector->begin();it!=pscdVector->end();++it)
|
||||
{
|
||||
const CStaticCollisionData & c_rColliData = *it;
|
||||
const D3DXMATRIX & c_rMatrix = GetTransform();
|
||||
AddCollision(&c_rColliData, &c_rMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance)
|
||||
{
|
||||
assert(pAttributeInstance);
|
||||
SetHeightInstance(pAttributeInstance);
|
||||
}
|
||||
|
||||
bool CActorInstance::OnGetObjectHeight(float fX, float fY, float * pfHeight)
|
||||
{
|
||||
if (!m_pHeightAttributeInstance)
|
||||
return false;
|
||||
|
||||
if (TYPE_BUILDING != GetType())
|
||||
return false;
|
||||
|
||||
return m_pHeightAttributeInstance->GetHeight(fX, fY, pfHeight) == 1 ? true : false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Battle
|
||||
void CActorInstance::Revive()
|
||||
{
|
||||
m_isSleep = FALSE;
|
||||
m_isParalysis = FALSE;
|
||||
m_isFaint = FALSE;
|
||||
m_isRealDead = FALSE;
|
||||
m_isStun = FALSE;
|
||||
m_isWalking = FALSE;
|
||||
m_isMain = FALSE;
|
||||
m_isResistFallen = FALSE;
|
||||
|
||||
__InitializeCollisionData();
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsStun()
|
||||
{
|
||||
return m_isStun;
|
||||
}
|
||||
|
||||
void CActorInstance::Stun()
|
||||
{
|
||||
m_isStun = TRUE;
|
||||
}
|
||||
|
||||
void CActorInstance::SetWalkMode()
|
||||
{
|
||||
m_isWalking = TRUE;
|
||||
if (CRaceMotionData::NAME_RUN == GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey))
|
||||
SetLoopMotion(CRaceMotionData::NAME_WALK, 0.15f, m_fMovSpd);
|
||||
}
|
||||
|
||||
void CActorInstance::SetRunMode()
|
||||
{
|
||||
m_isWalking = FALSE;
|
||||
if (CRaceMotionData::NAME_WALK == GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey))
|
||||
SetLoopMotion(CRaceMotionData::NAME_RUN, 0.15f, m_fMovSpd);
|
||||
}
|
||||
|
||||
MOTION_KEY CActorInstance::GetNormalAttackIndex()
|
||||
{
|
||||
WORD wMotionIndex;
|
||||
m_pkCurRaceData->GetNormalAttackIndex(GetMotionMode(), &wMotionIndex);
|
||||
|
||||
return MAKE_MOTION_KEY(GetMotionMode(), wMotionIndex);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Movement
|
||||
void CActorInstance::__InitializeMovement()
|
||||
{
|
||||
m_v3Movement.x = 0.0f;
|
||||
m_v3Movement.y = 0.0f;
|
||||
m_v3Movement.z = 0.0f;
|
||||
}
|
||||
|
||||
void CActorInstance::AddMovement(float fx, float fy, float fz)
|
||||
{
|
||||
m_v3Movement.x += fx;
|
||||
m_v3Movement.y += fy;
|
||||
m_v3Movement.z += fz;
|
||||
}
|
||||
|
||||
const float gc_fActorSlideMoveSpeed = 5.0f;
|
||||
|
||||
void CActorInstance::AdjustDynamicCollisionMovement(const CActorInstance * c_pActorInstance)
|
||||
{
|
||||
if (m_pkHorse)
|
||||
{
|
||||
m_pkHorse->AdjustDynamicCollisionMovement(c_pActorInstance);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE : 기존의 Sphere Overlap됬을경우 처리가 비비기를 하면은 Penetration될 위험이 많아서 ( 실제로도 나왔고 --)
|
||||
// Sphere간 Collision이 생겼을 경우 이전위치로 RollBack하는 방식으로 바꿨다.
|
||||
// 단 BGObject에 대해서만.
|
||||
|
||||
if (isAttacking() )
|
||||
return;
|
||||
|
||||
UINT uActorType = c_pActorInstance->GetActorType();
|
||||
if( (uActorType == TYPE_BUILDING) || (uActorType == TYPE_OBJECT) || (uActorType == TYPE_DOOR) || (uActorType == TYPE_STONE))
|
||||
{
|
||||
BlockMovement();
|
||||
|
||||
//Movement초기화
|
||||
/* m_v3Movement = D3DXVECTOR3(0.f,0.f,0.f);
|
||||
|
||||
TCollisionPointInstanceListIterator itMain = m_BodyPointInstanceList.begin();
|
||||
for (; itMain != m_BodyPointInstanceList.end(); ++itMain)
|
||||
{
|
||||
CDynamicSphereInstanceVector & c_rMainSphereVector = (*itMain).SphereInstanceVector;
|
||||
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
|
||||
{
|
||||
CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
|
||||
c_rMainSphere.v3Position =c_rMainSphere.v3LastPosition;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
float move_length = D3DXVec3Length(&m_v3Movement);
|
||||
if (move_length>gc_fActorSlideMoveSpeed)
|
||||
m_v3Movement*=gc_fActorSlideMoveSpeed/move_length;
|
||||
|
||||
TCollisionPointInstanceListIterator itMain = m_BodyPointInstanceList.begin();
|
||||
for (; itMain != m_BodyPointInstanceList.end(); ++itMain)
|
||||
{
|
||||
CDynamicSphereInstanceVector & c_rMainSphereVector = (*itMain).SphereInstanceVector;
|
||||
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
|
||||
{
|
||||
CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
|
||||
|
||||
TCollisionPointInstanceList::const_iterator itOpp = c_pActorInstance->m_BodyPointInstanceList.begin();
|
||||
for(;itOpp != c_pActorInstance->m_BodyPointInstanceList.end();++itOpp)
|
||||
{
|
||||
CSphereCollisionInstance s;
|
||||
s.GetAttribute().fRadius=itOpp->SphereInstanceVector[0].fRadius;
|
||||
s.GetAttribute().v3Position=itOpp->SphereInstanceVector[0].v3Position;
|
||||
D3DXVECTOR3 v3Delta = s.GetCollisionMovementAdjust(c_rMainSphere);
|
||||
m_v3Movement+=v3Delta;
|
||||
c_rMainSphere.v3Position+=v3Delta;
|
||||
|
||||
if (v3Delta.x !=0.0f || v3Delta.y !=0.0f || v3Delta.z !=0.0f )
|
||||
{
|
||||
move_length = D3DXVec3Length(&m_v3Movement);
|
||||
if (move_length>gc_fActorSlideMoveSpeed)
|
||||
{
|
||||
m_v3Movement*=gc_fActorSlideMoveSpeed/move_length;
|
||||
c_rMainSphere.v3Position = c_rMainSphere.v3LastPosition;
|
||||
c_rMainSphere.v3Position+=m_v3Movement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::__AdjustCollisionMovement(const CGraphicObjectInstance * c_pGraphicObjectInstance)
|
||||
{
|
||||
if (m_pkHorse)
|
||||
{
|
||||
m_pkHorse->__AdjustCollisionMovement(c_pGraphicObjectInstance);
|
||||
return;
|
||||
}
|
||||
|
||||
// Body는 하나임을 가정합니다.
|
||||
|
||||
if (m_v3Movement.x == 0.0f && m_v3Movement.y == 0.0f && m_v3Movement.z == 0.0f)
|
||||
return;
|
||||
|
||||
float move_length = D3DXVec3Length(&m_v3Movement);
|
||||
if (move_length>gc_fActorSlideMoveSpeed)
|
||||
m_v3Movement*=gc_fActorSlideMoveSpeed/move_length;
|
||||
|
||||
TCollisionPointInstanceListIterator itMain = m_BodyPointInstanceList.begin();
|
||||
for (; itMain != m_BodyPointInstanceList.end(); ++itMain)
|
||||
{
|
||||
CDynamicSphereInstanceVector & c_rMainSphereVector = (*itMain).SphereInstanceVector;
|
||||
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
|
||||
{
|
||||
CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
|
||||
|
||||
D3DXVECTOR3 v3Delta = c_pGraphicObjectInstance->GetCollisionMovementAdjust(c_rMainSphere);
|
||||
m_v3Movement+=v3Delta;
|
||||
c_rMainSphere.v3Position+=v3Delta;
|
||||
|
||||
if (v3Delta.x !=0.0f || v3Delta.y !=0.0f || v3Delta.z !=0.0f )
|
||||
{
|
||||
move_length = D3DXVec3Length(&m_v3Movement);
|
||||
if (move_length>gc_fActorSlideMoveSpeed)
|
||||
{
|
||||
m_v3Movement*=gc_fActorSlideMoveSpeed/move_length;
|
||||
c_rMainSphere.v3Position = c_rMainSphere.v3LastPosition;
|
||||
c_rMainSphere.v3Position+=m_v3Movement;
|
||||
}
|
||||
}
|
||||
|
||||
/*if (c_pObjectInstance->CollisionDynamicSphere(c_rMainSphere))
|
||||
{
|
||||
const D3DXVECTOR3 & c_rv3Position = c_pObjectInstance->GetPosition();
|
||||
//if (GetVector3Distance(c_rMainSphere.v3Position, c_rv3Position) <
|
||||
// GetVector3Distance(c_rMainSphere.v3LastPosition, c_rv3Position))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsMovement()
|
||||
{
|
||||
if (m_pkHorse)
|
||||
if (m_pkHorse->IsMovement())
|
||||
return TRUE;
|
||||
|
||||
if (0.0f != m_v3Movement.x)
|
||||
return TRUE;
|
||||
if (0.0f != m_v3Movement.y)
|
||||
return TRUE;
|
||||
if (0.0f != m_v3Movement.z)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
float CActorInstance::GetHeight()
|
||||
{
|
||||
return CGraphicThingInstance::GetHeight();
|
||||
}
|
||||
|
||||
bool CActorInstance::IntersectDefendingSphere()
|
||||
{
|
||||
for (TCollisionPointInstanceList::iterator it = m_DefendingPointInstanceList.begin(); it != m_DefendingPointInstanceList.end(); ++it)
|
||||
{
|
||||
CDynamicSphereInstanceVector & rSphereInstanceVector = (*it).SphereInstanceVector;
|
||||
|
||||
CDynamicSphereInstanceVector::iterator it2 = rSphereInstanceVector.begin();
|
||||
for (; it2 != rSphereInstanceVector.end(); ++it2)
|
||||
{
|
||||
CDynamicSphereInstance & rInstance = *it2;
|
||||
D3DXVECTOR3 v3SpherePosition = rInstance.v3Position;
|
||||
float fRadius = rInstance.fRadius;
|
||||
|
||||
D3DXVECTOR3 v3Orig;
|
||||
D3DXVECTOR3 v3Dir;
|
||||
float fRange;
|
||||
ms_Ray.GetStartPoint(&v3Orig);
|
||||
ms_Ray.GetDirection(&v3Dir, &fRange);
|
||||
|
||||
D3DXVECTOR3 v3Distance = v3Orig - v3SpherePosition;
|
||||
float b = D3DXVec3Dot(&v3Dir, &v3Distance);
|
||||
float c = D3DXVec3Dot(&v3Distance, &v3Distance) - fRadius*fRadius;
|
||||
|
||||
if (b*b - c >= 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsMountingHorse()
|
||||
{
|
||||
return NULL != m_pkHorse;
|
||||
}
|
||||
|
||||
void CActorInstance::MountHorse(CActorInstance * pkHorse)
|
||||
{
|
||||
m_pkHorse = pkHorse;
|
||||
|
||||
if (m_pkHorse)
|
||||
{
|
||||
m_pkHorse->SetCurPixelPosition(NEW_GetCurPixelPositionRef());
|
||||
m_pkHorse->SetRotation(GetRotation());
|
||||
m_pkHorse->SetAdvancingRotation(GetRotation());
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__CreateTree(const char * c_szFileName)
|
||||
{
|
||||
__DestroyTree();
|
||||
|
||||
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
|
||||
m_pkTree=rkForest.CreateInstance(m_x, m_y, m_z, GetCaseCRC32(c_szFileName, strlen(c_szFileName)), c_szFileName);
|
||||
m_pkTree->SetPosition(m_x, m_y, m_z);
|
||||
m_pkTree->UpdateBoundingSphere();
|
||||
m_pkTree->UpdateCollisionData();
|
||||
}
|
||||
|
||||
void CActorInstance::__DestroyTree()
|
||||
{
|
||||
if (!m_pkTree)
|
||||
return;
|
||||
|
||||
CSpeedTreeForestDirectX8::Instance().DeleteInstance(m_pkTree);
|
||||
}
|
||||
|
||||
void CActorInstance::__SetTreePosition(float fx, float fy, float fz)
|
||||
{
|
||||
if (!m_pkTree)
|
||||
return;
|
||||
if (m_x == fx && m_y == fy && m_z == fz)
|
||||
return;
|
||||
|
||||
m_pkTree->SetPosition(fx, fy, fz);
|
||||
m_pkTree->UpdateBoundingSphere();
|
||||
m_pkTree->UpdateCollisionData();
|
||||
}
|
||||
|
||||
void CActorInstance::ClearAttachingEffect()
|
||||
{
|
||||
__ClearAttachingEffect();
|
||||
}
|
||||
|
||||
void CActorInstance::Destroy()
|
||||
{
|
||||
ClearFlyTargeter();
|
||||
|
||||
m_HitDataMap.clear();
|
||||
m_MotionDeque.clear();
|
||||
|
||||
if (m_pAttributeInstance)
|
||||
{
|
||||
m_pAttributeInstance->Clear();
|
||||
CAttributeInstance::Delete(m_pAttributeInstance);
|
||||
m_pAttributeInstance = NULL;
|
||||
}
|
||||
|
||||
__ClearAttachingEffect();
|
||||
|
||||
CGraphicThingInstance::Clear();
|
||||
|
||||
__DestroyWeaponTrace();
|
||||
__DestroyTree();
|
||||
//m_PhysicsObject.SetActorInstance(NULL);
|
||||
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CActorInstance::__InitializeRotationData()
|
||||
{
|
||||
m_fAtkDirRot = 0.0f;
|
||||
m_fcurRotation = 0.0f;
|
||||
m_rotBegin = 0.0f;
|
||||
m_rotEnd = 0.0f;
|
||||
m_rotEndTime = 0.0f;
|
||||
m_rotBeginTime = 0.0f;
|
||||
m_rotBlendTime = 0.0f;
|
||||
m_fAdvancingRotation = 0.0f;
|
||||
m_rotX = 0.0f;
|
||||
m_rotY = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::__InitializeStateData()
|
||||
{
|
||||
m_bEffectInitialized = false;
|
||||
|
||||
m_isPreInput = FALSE;
|
||||
m_isNextPreInput = FALSE;
|
||||
|
||||
m_isSleep = FALSE;
|
||||
m_isParalysis = FALSE;
|
||||
m_isFaint = FALSE;
|
||||
m_isRealDead = FALSE;
|
||||
m_isWalking = FALSE;
|
||||
m_isMain = FALSE;
|
||||
m_isStun = FALSE;
|
||||
m_isHiding = FALSE;
|
||||
m_isResistFallen = FALSE;
|
||||
|
||||
m_iRenderMode = RENDER_MODE_NORMAL;
|
||||
m_fAlphaValue = 0.0f;
|
||||
m_AddColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
m_dwMtrlColor=0xffffffff;
|
||||
m_dwMtrlAlpha=0xff000000;
|
||||
|
||||
m_dwBattleHitEffectID = 0;
|
||||
m_dwBattleAttachEffectID = 0;
|
||||
}
|
||||
|
||||
void CActorInstance::__InitializeMotionData()
|
||||
{
|
||||
m_wcurMotionMode = CRaceMotionData::MODE_GENERAL;
|
||||
m_wcurComboType = 0;
|
||||
|
||||
m_fReachScale=1.0f;
|
||||
m_fMovSpd=1.0f;
|
||||
m_fAtkSpd=1.0f;
|
||||
|
||||
m_fInvisibleTime = 0.0f;
|
||||
|
||||
m_kSplashArea.isEnableHitProcess=TRUE;
|
||||
m_kSplashArea.uSkill=0;
|
||||
m_kSplashArea.MotionKey=0;
|
||||
m_kSplashArea.fDisappearingTime = 0.0f;
|
||||
m_kSplashArea.SphereInstanceVector.clear();
|
||||
m_kSplashArea.HittedInstanceMap.clear();
|
||||
|
||||
memset(&m_kCurMotNode, 0, sizeof(m_kCurMotNode));
|
||||
|
||||
__ClearCombo();
|
||||
}
|
||||
|
||||
void CActorInstance::__Initialize()
|
||||
{
|
||||
m_pkCurRaceMotionData=NULL;
|
||||
m_pkCurRaceData=NULL;
|
||||
m_pkHorse=NULL;
|
||||
m_pkTree=NULL;
|
||||
|
||||
m_fOwnerBaseTime=0.0f;
|
||||
|
||||
m_eActorType = TYPE_PC;
|
||||
m_eRace = 0;
|
||||
|
||||
m_eShape = 0;
|
||||
m_eHair = 0;
|
||||
|
||||
m_dwSelfVID = 0;
|
||||
m_dwOwnerVID = 0;
|
||||
|
||||
m_pkEventHandler = NULL;
|
||||
|
||||
m_PhysicsObject.Initialize();
|
||||
|
||||
m_pAttributeInstance = NULL;
|
||||
|
||||
m_pFlyEventHandler = 0;
|
||||
|
||||
m_v3FishingPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_iFishingEffectID = -1;
|
||||
|
||||
m_pkHorse = NULL;
|
||||
|
||||
__InitializePositionData();
|
||||
__InitializeRotationData();
|
||||
__InitializeMotionData();
|
||||
__InitializeStateData();
|
||||
__InitializeCollisionData();
|
||||
|
||||
__BlendAlpha_Initialize();
|
||||
|
||||
ClearFlyTargeter();
|
||||
}
|
||||
|
||||
CActorInstance::CActorInstance()
|
||||
{
|
||||
__Initialize();
|
||||
m_PhysicsObject.SetActorInstance(this);
|
||||
}
|
||||
|
||||
CActorInstance::~CActorInstance()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,889 @@
|
||||
#pragma once
|
||||
|
||||
// class CActorInstance
|
||||
|
||||
// Note : 캐릭터의 Lighting, Local Point Light, Weapon Trace 등의 효과와 콤보 데이타, 사운드 데이타,
|
||||
// 모션 데이타 들을 추상적, 총체적으로 관리하는 개별 매니저가 될 것이다.
|
||||
|
||||
#include "FlyTarget.h"
|
||||
#include "RaceData.h"
|
||||
#include "RaceMotionData.h"
|
||||
#include "PhysicsObject.h"
|
||||
#include "ActorInstanceInterface.h"
|
||||
#include "Interface.h"
|
||||
//#include "../eterGrnLib/ThingInstance.h"
|
||||
|
||||
class CItemData;
|
||||
class CWeaponTrace;
|
||||
class IFlyEventHandler;
|
||||
class CSpeedTreeWrapper;
|
||||
|
||||
class IMobProto : public CSingleton<IMobProto>
|
||||
{
|
||||
public:
|
||||
IMobProto() {}
|
||||
virtual ~IMobProto() {}
|
||||
|
||||
virtual bool FindRaceType(UINT eRace, UINT* puType);
|
||||
};
|
||||
|
||||
class CActorInstance : public IActorInstance, public IFlyTargetableObject
|
||||
{
|
||||
public:
|
||||
class IEventHandler
|
||||
{
|
||||
public:
|
||||
static IEventHandler* GetEmptyPtr();
|
||||
|
||||
public:
|
||||
struct SState
|
||||
{
|
||||
TPixelPosition kPPosSelf;
|
||||
FLOAT fAdvRotSelf;
|
||||
};
|
||||
|
||||
public:
|
||||
IEventHandler() {}
|
||||
virtual ~IEventHandler() {}
|
||||
|
||||
virtual void OnSyncing(const SState& c_rkState) = 0;
|
||||
virtual void OnWaiting(const SState& c_rkState) = 0;
|
||||
virtual void OnMoving(const SState& c_rkState) = 0;
|
||||
virtual void OnMove(const SState& c_rkState) = 0;
|
||||
virtual void OnStop(const SState& c_rkState) = 0;
|
||||
virtual void OnWarp(const SState& c_rkState) = 0;
|
||||
virtual void OnSetAffect(UINT uAffect) = 0;
|
||||
virtual void OnResetAffect(UINT uAffect) = 0;
|
||||
virtual void OnClearAffects() = 0;
|
||||
|
||||
virtual void OnAttack(const SState& c_rkState, WORD wMotionIndex) = 0;
|
||||
virtual void OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uMotLoopCount) = 0;
|
||||
|
||||
virtual void OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket) = 0;
|
||||
|
||||
virtual void OnChangeShape() = 0;
|
||||
};
|
||||
|
||||
// 2004.07.05.myevan.궁신탄영 맵에 끼이는 문제해결
|
||||
private:
|
||||
static IBackground& GetBackground();
|
||||
|
||||
public:
|
||||
static bool IsDirLine();
|
||||
|
||||
public:
|
||||
|
||||
enum EType
|
||||
{
|
||||
TYPE_ENEMY,
|
||||
TYPE_NPC,
|
||||
TYPE_STONE,
|
||||
TYPE_WARP,
|
||||
TYPE_DOOR,
|
||||
TYPE_BUILDING,
|
||||
TYPE_PC,
|
||||
TYPE_POLY,
|
||||
TYPE_HORSE,
|
||||
TYPE_GOTO,
|
||||
|
||||
TYPE_OBJECT, // Only For Client
|
||||
};
|
||||
|
||||
enum ERenderMode
|
||||
{
|
||||
RENDER_MODE_NORMAL,
|
||||
RENDER_MODE_BLEND,
|
||||
RENDER_MODE_ADD,
|
||||
RENDER_MODE_MODULATE,
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Motion Queueing System
|
||||
enum EMotionPushType
|
||||
{
|
||||
MOTION_TYPE_NONE,
|
||||
MOTION_TYPE_ONCE,
|
||||
MOTION_TYPE_LOOP,
|
||||
};
|
||||
|
||||
typedef struct SReservingMotionNode
|
||||
{
|
||||
EMotionPushType iMotionType;
|
||||
|
||||
float fStartTime;
|
||||
float fBlendTime;
|
||||
float fDuration;
|
||||
float fSpeedRatio;
|
||||
|
||||
DWORD dwMotionKey;
|
||||
} TReservingMotionNode;
|
||||
|
||||
struct SCurrentMotionNode
|
||||
{
|
||||
EMotionPushType iMotionType;
|
||||
DWORD dwMotionKey;
|
||||
|
||||
DWORD dwcurFrame;
|
||||
DWORD dwFrameCount;
|
||||
|
||||
float fStartTime;
|
||||
float fEndTime;
|
||||
float fSpeedRatio;
|
||||
|
||||
int iLoopCount;
|
||||
UINT uSkill;
|
||||
};
|
||||
|
||||
typedef std::deque<TReservingMotionNode> TMotionDeque;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Motion Event
|
||||
typedef struct SMotionEventInstance
|
||||
{
|
||||
int iType;
|
||||
int iMotionEventIndex;
|
||||
float fStartingTime;
|
||||
|
||||
const CRaceMotionData::TMotionEventData * c_pMotionData;
|
||||
} TMotionEventInstance;
|
||||
|
||||
typedef std::list<TMotionEventInstance> TMotionEventInstanceList;
|
||||
typedef TMotionEventInstanceList::iterator TMotionEventInstanceListIterator;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Collision Detection
|
||||
typedef struct SCollisionPointInstance
|
||||
{
|
||||
const NRaceData::TCollisionData * c_pCollisionData;
|
||||
BOOL isAttached;
|
||||
DWORD dwModelIndex;
|
||||
DWORD dwBoneIndex;
|
||||
CDynamicSphereInstanceVector SphereInstanceVector;
|
||||
} TCollisionPointInstance;
|
||||
typedef std::list<TCollisionPointInstance> TCollisionPointInstanceList;
|
||||
typedef TCollisionPointInstanceList::iterator TCollisionPointInstanceListIterator;
|
||||
|
||||
typedef std::map<CActorInstance*, float> THittedInstanceMap;
|
||||
typedef std::map<const NRaceData::THitData *, THittedInstanceMap> THitDataMap;
|
||||
struct SSplashArea
|
||||
{
|
||||
BOOL isEnableHitProcess;
|
||||
UINT uSkill;
|
||||
MOTION_KEY MotionKey;
|
||||
float fDisappearingTime;
|
||||
const CRaceMotionData::TMotionAttackingEventData * c_pAttackingEvent;
|
||||
CDynamicSphereInstanceVector SphereInstanceVector;
|
||||
|
||||
THittedInstanceMap HittedInstanceMap;
|
||||
};
|
||||
|
||||
typedef struct SHittingData
|
||||
{
|
||||
BYTE byAttackingType;
|
||||
DWORD dwMotionKey;
|
||||
BYTE byEventIndex;
|
||||
} THittingData;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Attaching
|
||||
enum EAttachEffect
|
||||
{
|
||||
EFFECT_LIFE_NORMAL,
|
||||
EFFECT_LIFE_INFINITE,
|
||||
EFFECT_LIFE_WITH_MOTION,
|
||||
};
|
||||
|
||||
struct TAttachingEffect
|
||||
{
|
||||
DWORD dwEffectIndex;
|
||||
int iBoneIndex;
|
||||
DWORD dwModelIndex;
|
||||
D3DXMATRIX matTranslation;
|
||||
BOOL isAttaching;
|
||||
|
||||
int iLifeType;
|
||||
DWORD dwEndTime;
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public:
|
||||
static void ShowDirectionLine(bool isVisible);
|
||||
static void DestroySystem();
|
||||
|
||||
public:
|
||||
CActorInstance();
|
||||
virtual ~CActorInstance();
|
||||
|
||||
// 20041201.myevan.인스턴스베이스용 함수
|
||||
void INSTANCEBASE_Transform();
|
||||
void INSTANCEBASE_Deform();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void Move();
|
||||
void Stop(float fBlendingTime=0.15f);
|
||||
|
||||
void SetMainInstance();
|
||||
|
||||
void SetParalysis(bool isParalysis);
|
||||
void SetFaint(bool isFaint);
|
||||
void SetSleep(bool isSleep);
|
||||
void SetResistFallen(bool isResistFallen);
|
||||
|
||||
void SetAttackSpeed(float fAtkSpd);
|
||||
void SetMoveSpeed(float fMovSpd);
|
||||
|
||||
void SetMaterialAlpha(DWORD dwAlpha);
|
||||
void SetMaterialColor(DWORD dwColor);
|
||||
|
||||
void SetEventHandler(IEventHandler* pkEventHandler);
|
||||
|
||||
bool SetRace(DWORD eRace);
|
||||
void SetHair(DWORD eHair);
|
||||
void SetVirtualID(DWORD dwVID);
|
||||
|
||||
void SetShape(DWORD eShape, float fSpecular=0.0f);
|
||||
void ChangeMaterial(const char * c_szFileName);
|
||||
|
||||
public:
|
||||
void SetComboType(WORD wComboType);
|
||||
|
||||
DWORD GetRace();
|
||||
DWORD GetVirtualID();
|
||||
|
||||
UINT GetActorType() const;
|
||||
void SetActorType(UINT eType);
|
||||
|
||||
bool CanAct();
|
||||
bool CanMove();
|
||||
bool CanAttack();
|
||||
bool CanUseSkill();
|
||||
|
||||
bool IsPC();
|
||||
bool IsNPC();
|
||||
bool IsEnemy();
|
||||
bool IsStone();
|
||||
bool IsWarp();
|
||||
bool IsGoto();
|
||||
bool IsObject();
|
||||
bool IsDoor();
|
||||
bool IsPoly();
|
||||
|
||||
bool IsBuilding();
|
||||
|
||||
bool IsHandMode();
|
||||
bool IsBowMode();
|
||||
bool IsTwoHandMode();
|
||||
|
||||
void AttachWeapon(DWORD dwItemIndex,DWORD dwParentPartIndex = CRaceData::PART_MAIN, DWORD dwPartIndex = CRaceData::PART_WEAPON);
|
||||
void AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData);
|
||||
|
||||
void RefreshActorInstance();
|
||||
DWORD GetPartItemID(DWORD dwPartIndex);
|
||||
|
||||
// Attach Effect
|
||||
BOOL GetAttachingBoneName(DWORD dwPartIndex, const char ** c_szBoneName);
|
||||
void UpdateAttachingInstances();
|
||||
void DettachEffect(DWORD dwEID);
|
||||
DWORD AttachEffectByName(DWORD dwParentPartIndex, const char * c_pszBoneName, const char * c_pszEffectFileName);
|
||||
DWORD AttachEffectByID(DWORD dwParentPartIndex, const char * c_pszBoneName, DWORD dwEffectID, const D3DXVECTOR3 * c_pv3Position = NULL);
|
||||
DWORD AttachSmokeEffect(DWORD eSmoke);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Motion Queueing System
|
||||
void SetMotionMode(int iMotionMode); // FIXME : 모드의 시간차 적용이 가능하게끔 한다.
|
||||
int GetMotionMode();
|
||||
void SetLoopMotion(DWORD dwMotion, float fBlendTime = 0.1f, float fSpeedRatio=1.0f);
|
||||
bool InterceptOnceMotion(DWORD dwMotion, float fBlendTime = 0.1f, UINT uSkill=0, float fSpeedRatio=1.0f);
|
||||
bool InterceptLoopMotion(DWORD dwMotion, float fBlendTime = 0.1f);
|
||||
bool PushOnceMotion(DWORD dwMotion, float fBlendTime = 0.1f, float fSpeedRatio=1.0f); // FIXME : 모드의 시간차 적용이 가능하게끔 한다.
|
||||
bool PushLoopMotion(DWORD dwMotion, float fBlendTime = 0.1f, float fSpeedRatio=1.0f); // FIXME : 모드의 시간차 적용이 가능하게끔 한다.
|
||||
void SetMotionLoopCount(int iCount);
|
||||
|
||||
bool IsPushing();
|
||||
|
||||
BOOL isLock();
|
||||
BOOL IsUsingSkill();
|
||||
BOOL CanCheckAttacking();
|
||||
BOOL CanCancelSkill();
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Collison Detection
|
||||
bool CreateCollisionInstancePiece(DWORD dwAttachingModelIndex, const NRaceData::TAttachingData * c_pAttachingData, TCollisionPointInstance * pPointInstance);
|
||||
|
||||
void UpdatePointInstance();
|
||||
void UpdatePointInstance(TCollisionPointInstance * pPointInstance);
|
||||
bool CheckCollisionDetection(const CDynamicSphereInstanceVector * c_pAttackingSphereVector, D3DXVECTOR3 * pv3Position);
|
||||
|
||||
// Collision Detection Checking
|
||||
virtual bool TestCollisionWithDynamicSphere(const CDynamicSphereInstance & dsi);
|
||||
|
||||
void UpdateAdvancingPointInstance();
|
||||
|
||||
BOOL IsClickableDistanceDestInstance(CActorInstance & rkInstDst, float fDistance);
|
||||
|
||||
bool AvoidObject(const CGraphicObjectInstance& c_rkBGObj);
|
||||
bool IsBlockObject(const CGraphicObjectInstance& c_rkBGObj);
|
||||
void BlockMovement();
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
BOOL __TestObjectCollision(const CGraphicObjectInstance * c_pObjectInstance);
|
||||
|
||||
public:
|
||||
BOOL TestActorCollision(CActorInstance & rVictim );
|
||||
BOOL TestPhysicsBlendingCollision(CActorInstance & rVictim);
|
||||
|
||||
BOOL AttackingProcess(CActorInstance & rVictim);
|
||||
|
||||
void PreAttack();
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Battle
|
||||
// Input
|
||||
// 하위로 옮길 가능성이 있는 코드들
|
||||
// 네트웍 연동시 전투 관련은 플레이어를 제외하곤 단순히 Showing Type이기 때문에
|
||||
// 조건 검사가 필요 없다.
|
||||
void InputNormalAttackCommand(float fDirRot); // Process input - Only used by player's character
|
||||
bool InputComboAttackCommand(float fDirRot); // Process input - Only used by player's character
|
||||
|
||||
// Command
|
||||
BOOL isAttacking();
|
||||
BOOL isNormalAttacking();
|
||||
BOOL isComboAttacking();
|
||||
BOOL IsSplashAttacking();
|
||||
BOOL IsUsingMovingSkill();
|
||||
BOOL IsActEmotion();
|
||||
DWORD GetComboIndex();
|
||||
float GetAttackingElapsedTime();
|
||||
void SetBlendingPosition(const TPixelPosition & c_rPosition, float fBlendingTime = 1.0f);
|
||||
void ResetBlendingPosition();
|
||||
void GetBlendingPosition(TPixelPosition * pPosition);
|
||||
|
||||
BOOL NormalAttack(float fDirRot, float fBlendTime = 0.1f);
|
||||
BOOL ComboAttack(DWORD wMotionIndex, float fDirRot, float fBlendTime = 0.1f);
|
||||
|
||||
void Revive();
|
||||
|
||||
BOOL IsSleep();
|
||||
BOOL IsParalysis();
|
||||
BOOL IsFaint();
|
||||
BOOL IsResistFallen();
|
||||
BOOL IsWaiting();
|
||||
BOOL IsMoving();
|
||||
BOOL IsDead();
|
||||
BOOL IsStun();
|
||||
BOOL IsAttacked();
|
||||
BOOL IsDamage();
|
||||
BOOL IsKnockDown();
|
||||
void SetWalkMode();
|
||||
void SetRunMode();
|
||||
void Stun();
|
||||
void Die();
|
||||
void DieEnd();
|
||||
|
||||
void SetBattleHitEffect(DWORD dwID);
|
||||
void SetBattleAttachEffect(DWORD dwID);
|
||||
|
||||
MOTION_KEY GetNormalAttackIndex();
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Position
|
||||
const D3DXVECTOR3& GetMovementVectorRef();
|
||||
const D3DXVECTOR3& GetPositionVectorRef();
|
||||
|
||||
void SetCurPixelPosition(const TPixelPosition& c_rkPPosCur);
|
||||
void NEW_SetAtkPixelPosition(const TPixelPosition& c_rkPPosAtk);
|
||||
void NEW_SetSrcPixelPosition(const TPixelPosition& c_rkPPosSrc);
|
||||
void NEW_SetDstPixelPosition(const TPixelPosition& c_rkPPosDst);
|
||||
void NEW_SetDstPixelPositionZ(float z);
|
||||
|
||||
const TPixelPosition& NEW_GetAtkPixelPositionRef();
|
||||
const TPixelPosition& NEW_GetCurPixelPositionRef();
|
||||
const TPixelPosition& NEW_GetSrcPixelPositionRef();
|
||||
const TPixelPosition& NEW_GetDstPixelPositionRef();
|
||||
|
||||
const TPixelPosition& NEW_GetLastPixelPositionRef();
|
||||
|
||||
void GetPixelPosition(TPixelPosition * pPixelPosition);
|
||||
void SetPixelPosition(const TPixelPosition& c_rPixelPos);
|
||||
|
||||
// Rotation Command
|
||||
void LookAt(float fDirRot);
|
||||
void LookAt(float fx, float fy);
|
||||
void LookAt(CActorInstance * pInstance);
|
||||
void LookWith(CActorInstance * pInstance);
|
||||
void LookAtFromXY(float x, float y, CActorInstance * pDestInstance);
|
||||
|
||||
|
||||
void SetReachScale(float fScale);
|
||||
void SetOwner(DWORD dwOwnerVID);
|
||||
|
||||
float GetRotation();
|
||||
float GetTargetRotation();
|
||||
|
||||
float GetAdvancingRotation();
|
||||
|
||||
float GetRotatingTime();
|
||||
void SetRotation(float fRot);
|
||||
void SetXYRotation(float fRotX, float fRotY);
|
||||
void BlendRotation(float fRot, float fBlendTime);
|
||||
void SetAdvancingRotation(float fRot);
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void MotionEventProcess();
|
||||
void MotionEventProcess(DWORD dwcurTime, int iIndex, const CRaceMotionData::TMotionEventData * c_pData);
|
||||
void SoundEventProcess(BOOL bCheckFrequency);
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////
|
||||
// Rendering Functions - Temporary Place
|
||||
BOOL IsMovement();
|
||||
|
||||
void RestoreRenderMode();
|
||||
|
||||
void BeginDiffuseRender();
|
||||
void EndDiffuseRender();
|
||||
void BeginOpacityRender();
|
||||
void EndOpacityRender();
|
||||
|
||||
void BeginBlendRender();
|
||||
void EndBlendRender();
|
||||
void SetBlendRenderMode();
|
||||
void SetAlphaValue(float fAlpha);
|
||||
float GetAlphaValue();
|
||||
void BlendAlphaValue(float fDstAlpha, float fDuration);
|
||||
void SetSpecularInfo(BOOL bEnable, int iPart, float fAlpha);
|
||||
void SetSpecularInfoForce(BOOL bEnable, int iPart, float fAlpha);
|
||||
|
||||
void BeginAddRender();
|
||||
void EndAddRender();
|
||||
void SetAddRenderMode();
|
||||
void SetAddColor(const D3DXCOLOR & c_rColor);
|
||||
|
||||
void BeginModulateRender();
|
||||
void EndModulateRender();
|
||||
void SetModulateRenderMode();
|
||||
|
||||
void SetRenderMode(int iRenderMode);
|
||||
|
||||
void RenderTrace();
|
||||
void RenderCollisionData();
|
||||
void RenderToShadowMap();
|
||||
|
||||
|
||||
protected:
|
||||
void __AdjustCollisionMovement(const CGraphicObjectInstance * c_pGraphicObjectInstance);
|
||||
|
||||
public:
|
||||
void AdjustDynamicCollisionMovement(const CActorInstance * c_pActorInstance);
|
||||
|
||||
// Weapon Trace
|
||||
void SetWeaponTraceTexture(const char * szTextureName);
|
||||
void UseTextureWeaponTrace();
|
||||
void UseAlphaWeaponTrace();
|
||||
|
||||
// ETC
|
||||
void UpdateAttribute();
|
||||
bool IntersectDefendingSphere();
|
||||
float GetHeight();
|
||||
void ShowAllAttachingEffect();
|
||||
void HideAllAttachingEffect();
|
||||
void ClearAttachingEffect();
|
||||
|
||||
// Fishing
|
||||
bool CanFishing();
|
||||
BOOL IsFishing();
|
||||
void SetFishingPosition(D3DXVECTOR3 & rv3Position);
|
||||
|
||||
// Flying Methods
|
||||
// As a Flying Target
|
||||
public:
|
||||
virtual D3DXVECTOR3 OnGetFlyTargetPosition();
|
||||
|
||||
void OnShootDamage();
|
||||
|
||||
// As a Shooter
|
||||
// NOTE : target and target position are exclusive
|
||||
public:
|
||||
void ClearFlyTarget();
|
||||
bool IsFlyTargetObject();
|
||||
void AddFlyTarget(const CFlyTarget & cr_FlyTarget);
|
||||
void SetFlyTarget(const CFlyTarget & cr_FlyTarget);
|
||||
void LookAtFlyTarget();
|
||||
|
||||
float GetFlyTargetDistance();
|
||||
|
||||
void ClearFlyEventHandler();
|
||||
void SetFlyEventHandler(IFlyEventHandler * pHandler);
|
||||
|
||||
// 2004. 07. 07. [levites] - 스킬 사용중 타겟이 바뀌는 문제 해결을 위한 코드
|
||||
bool CanChangeTarget();
|
||||
|
||||
protected:
|
||||
IFlyEventHandler * m_pFlyEventHandler;
|
||||
|
||||
public:
|
||||
void MountHorse(CActorInstance * pkHorse);
|
||||
void HORSE_MotionProcess(BOOL isPC);
|
||||
void MotionProcess(BOOL isPC);
|
||||
void RotationProcess();
|
||||
void PhysicsProcess();
|
||||
void ComboProcess();
|
||||
void TransformProcess();
|
||||
void AccumulationMovement();
|
||||
void ShakeProcess();
|
||||
void TraceProcess();
|
||||
void __MotionEventProcess(BOOL isPC);
|
||||
void __AccumulationMovement(float fRot);
|
||||
BOOL __SplashAttackProcess(CActorInstance & rVictim);
|
||||
BOOL __NormalAttackProcess(CActorInstance & rVictim);
|
||||
bool __CanInputNormalAttackCommand();
|
||||
|
||||
private:
|
||||
void __Shake(DWORD dwDuration);
|
||||
|
||||
protected:
|
||||
CFlyTarget m_kFlyTarget;
|
||||
CFlyTarget m_kBackupFlyTarget;
|
||||
std::deque<CFlyTarget> m_kQue_kFlyTarget;
|
||||
|
||||
protected:
|
||||
bool __IsInSplashTime();
|
||||
|
||||
void OnUpdate();
|
||||
void OnRender();
|
||||
|
||||
BOOL isValidAttacking();
|
||||
|
||||
void ReservingMotionProcess();
|
||||
void CurrentMotionProcess();
|
||||
MOTION_KEY GetRandomMotionKey(MOTION_KEY dwMotionKey);
|
||||
|
||||
float GetLastMotionTime(float fBlendTime); // NOTE : 자동으로 BlendTime만큼을 앞당긴 시간을 리턴
|
||||
float GetMotionDuration(DWORD dwMotionKey);
|
||||
|
||||
bool InterceptMotion(EMotionPushType iMotionType, WORD wMotion, float fBlendTime = 0.1f, UINT uSkill=0, float fSpeedRatio=1.0f);
|
||||
void PushMotion(EMotionPushType iMotionType, DWORD dwMotionKey, float fBlendTime, float fSpeedRatio=1.0f);
|
||||
void ProcessMotionEventEffectEvent(const CRaceMotionData::TMotionEventData * c_pData);
|
||||
void ProcessMotionEventEffectToTargetEvent(const CRaceMotionData::TMotionEventData * c_pData);
|
||||
void ProcessMotionEventSpecialAttacking(int iMotionEventIndex, const CRaceMotionData::TMotionEventData * c_pData);
|
||||
void ProcessMotionEventSound(const CRaceMotionData::TMotionEventData * c_pData);
|
||||
void ProcessMotionEventFly(const CRaceMotionData::TMotionEventData * c_pData);
|
||||
void ProcessMotionEventWarp(const CRaceMotionData::TMotionEventData * c_pData);
|
||||
|
||||
void AddMovement(float fx, float fy, float fz);
|
||||
|
||||
bool __IsLeftHandWeapon(DWORD type);
|
||||
bool __IsRightHandWeapon(DWORD type);
|
||||
bool __IsWeaponTrace(DWORD weaponType);
|
||||
|
||||
protected:
|
||||
void __InitializeMovement();
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
|
||||
void __ClearAttachingEffect();
|
||||
|
||||
float __GetOwnerTime();
|
||||
DWORD __GetOwnerVID();
|
||||
bool __CanPushDestActor(CActorInstance& rkActorDst);
|
||||
|
||||
protected:
|
||||
void __RunNextCombo();
|
||||
void __ClearCombo();
|
||||
void __OnEndCombo();
|
||||
|
||||
void __ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill = 0, BOOL isSendPacket = TRUE);
|
||||
void __ProcessMotionEventAttackSuccess(DWORD dwMotionKey, BYTE byEventIndex, CActorInstance & rVictim);
|
||||
void __ProcessMotionAttackSuccess(DWORD dwMotionKey, CActorInstance & rVictim);
|
||||
|
||||
|
||||
void __HitStone(CActorInstance& rVictim);
|
||||
void __HitGood(CActorInstance& rVictim);
|
||||
void __HitGreate(CActorInstance& rVictim);
|
||||
|
||||
void __PushDirect(CActorInstance & rVictim);
|
||||
void __PushCircle(CActorInstance & rVictim);
|
||||
bool __isInvisible();
|
||||
void __SetFallingDirection(float fx, float fy);
|
||||
|
||||
protected:
|
||||
struct SSetMotionData
|
||||
{
|
||||
MOTION_KEY dwMotKey;
|
||||
float fSpeedRatio;
|
||||
float fBlendTime;
|
||||
int iLoopCount;
|
||||
UINT uSkill;
|
||||
|
||||
SSetMotionData()
|
||||
{
|
||||
iLoopCount=0;
|
||||
dwMotKey=0;
|
||||
fSpeedRatio=1.0f;
|
||||
fBlendTime=0.0f;
|
||||
uSkill=0;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
float __GetAttackSpeed();
|
||||
DWORD __SetMotion(const SSetMotionData& c_rkSetMotData, DWORD dwRandMotKey=0); // 모션 데이터 설정
|
||||
void __ClearMotion();
|
||||
|
||||
bool __BindMotionData(DWORD dwMotionKey); // 모션 데이터를 바인딩
|
||||
void __ClearHittedActorInstanceMap(); // 때려진 액터 인스턴스 맵을 지운다
|
||||
|
||||
UINT __GetMotionType(); // 모션 타입 얻기
|
||||
|
||||
bool __IsNeedFlyTargetMotion(); // FlyTarget 이 필요한 모션인가?
|
||||
bool __HasMotionFlyEvent(); // 무언가를 쏘는가?
|
||||
bool __IsWaitMotion(); // 대기 모션 인가?
|
||||
bool __IsMoveMotion(); // 이동 모션 인가?
|
||||
bool __IsAttackMotion(); // 공격 모션 인가?
|
||||
bool __IsComboAttackMotion(); // 콤보 공격 모션 인가?
|
||||
bool __IsDamageMotion(); // 데미지 모션인가?
|
||||
bool __IsKnockDownMotion(); // 넉다운 모션인가?
|
||||
bool __IsDieMotion(); // 사망 모션 인가?
|
||||
bool __IsStandUpMotion(); // 일어서기 모션인가?
|
||||
bool __IsMountingHorse();
|
||||
|
||||
bool __CanAttack(); // 공격 할수 있는가?
|
||||
bool __CanNextComboAttack(); // 다음 콤보 어택이 가능한가?
|
||||
|
||||
bool __IsComboAttacking(); // 콤보 공격중인가?
|
||||
void __CancelComboAttack(); // 콤보 공격 취소
|
||||
|
||||
WORD __GetCurrentMotionIndex();
|
||||
DWORD __GetCurrentMotionKey();
|
||||
|
||||
int __GetLoopCount();
|
||||
WORD __GetCurrentComboType();
|
||||
|
||||
void __ShowEvent();
|
||||
void __HideEvent();
|
||||
BOOL __IsHiding();
|
||||
BOOL __IsMovingSkill(WORD wSkillNumber);
|
||||
|
||||
float __GetReachScale();
|
||||
|
||||
void __CreateAttributeInstance(CAttributeData * pData);
|
||||
|
||||
bool __IsFlyTargetPC();
|
||||
bool __IsSameFlyTarget(CActorInstance * pInstance);
|
||||
D3DXVECTOR3 __GetFlyTargetPosition();
|
||||
|
||||
protected:
|
||||
void __DestroyWeaponTrace(); // 무기 잔상을 제거한다
|
||||
void __ShowWeaponTrace(); // 무기 잔상을 보인다
|
||||
void __HideWeaponTrace(); // 무기 잔상을 감춘다
|
||||
|
||||
protected:
|
||||
// collision data
|
||||
void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector);
|
||||
void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance);
|
||||
bool OnGetObjectHeight(float fX, float fY, float * pfHeight);
|
||||
|
||||
protected:
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Motion Queueing System
|
||||
TMotionDeque m_MotionDeque;
|
||||
SCurrentMotionNode m_kCurMotNode;
|
||||
WORD m_wcurMotionMode;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Collision Detection
|
||||
TCollisionPointInstanceList m_BodyPointInstanceList;
|
||||
TCollisionPointInstanceList m_DefendingPointInstanceList;
|
||||
SSplashArea m_kSplashArea; // TODO : 복수에 대한 고려를 해야한다 - [levites]
|
||||
CAttributeInstance * m_pAttributeInstance;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Battle System
|
||||
std::vector<CWeaponTrace*> m_WeaponTraceVector;
|
||||
CPhysicsObject m_PhysicsObject;
|
||||
|
||||
DWORD m_dwcurComboIndex;
|
||||
|
||||
DWORD m_eActorType;
|
||||
|
||||
DWORD m_eRace;
|
||||
DWORD m_eShape;
|
||||
DWORD m_eHair;
|
||||
BOOL m_isPreInput;
|
||||
BOOL m_isNextPreInput;
|
||||
DWORD m_dwcurComboBackMotionIndex;
|
||||
|
||||
WORD m_wcurComboType;
|
||||
|
||||
float m_fAtkDirRot;
|
||||
|
||||
CRaceData* m_pkCurRaceData;
|
||||
CRaceMotionData* m_pkCurRaceMotionData;
|
||||
|
||||
// Defender
|
||||
float m_fInvisibleTime;
|
||||
BOOL m_isHiding;
|
||||
|
||||
// TODO : State로 통합 시킬 수 있는지 고려해 볼것
|
||||
BOOL m_isResistFallen;
|
||||
BOOL m_isSleep;
|
||||
BOOL m_isFaint;
|
||||
BOOL m_isParalysis;
|
||||
BOOL m_isStun;
|
||||
BOOL m_isRealDead;
|
||||
BOOL m_isWalking;
|
||||
BOOL m_isMain;
|
||||
|
||||
// Effect
|
||||
DWORD m_dwBattleHitEffectID;
|
||||
DWORD m_dwBattleAttachEffectID;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Fishing
|
||||
D3DXVECTOR3 m_v3FishingPosition;
|
||||
int m_iFishingEffectID;
|
||||
|
||||
// Position
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
D3DXVECTOR3 m_v3Pos;
|
||||
D3DXVECTOR3 m_v3Movement;
|
||||
BOOL m_bNeedUpdateCollision;
|
||||
|
||||
DWORD m_dwShakeTime;
|
||||
|
||||
float m_fReachScale;
|
||||
float m_fMovSpd;
|
||||
float m_fAtkSpd;
|
||||
|
||||
// Rotation
|
||||
float m_fcurRotation;
|
||||
float m_rotBegin;
|
||||
float m_rotEnd;
|
||||
float m_rotEndTime;
|
||||
float m_rotBeginTime;
|
||||
float m_rotBlendTime;
|
||||
float m_fAdvancingRotation;
|
||||
float m_rotX;
|
||||
float m_rotY;
|
||||
|
||||
float m_fOwnerBaseTime;
|
||||
|
||||
// Rendering
|
||||
int m_iRenderMode;
|
||||
D3DXCOLOR m_AddColor;
|
||||
float m_fAlphaValue;
|
||||
|
||||
// Part
|
||||
DWORD m_adwPartItemID[CRaceData::PART_MAX_NUM];
|
||||
|
||||
// Attached Effect
|
||||
std::list<TAttachingEffect> m_AttachingEffectList;
|
||||
bool m_bEffectInitialized;
|
||||
|
||||
// material color
|
||||
DWORD m_dwMtrlColor;
|
||||
DWORD m_dwMtrlAlpha;
|
||||
|
||||
TPixelPosition m_kPPosCur;
|
||||
TPixelPosition m_kPPosSrc;
|
||||
TPixelPosition m_kPPosDst;
|
||||
TPixelPosition m_kPPosAtk;
|
||||
|
||||
TPixelPosition m_kPPosLast;
|
||||
|
||||
THitDataMap m_HitDataMap;
|
||||
|
||||
CActorInstance * m_pkHorse;
|
||||
CSpeedTreeWrapper * m_pkTree;
|
||||
|
||||
|
||||
protected:
|
||||
DWORD m_dwSelfVID;
|
||||
DWORD m_dwOwnerVID;
|
||||
|
||||
|
||||
protected:
|
||||
void __InitializeStateData();
|
||||
void __InitializeMotionData();
|
||||
void __InitializeRotationData();
|
||||
void __InitializePositionData();
|
||||
|
||||
public: // InstanceBase 통합전 임시로 public
|
||||
IEventHandler* __GetEventHandlerPtr();
|
||||
IEventHandler& __GetEventHandlerRef();
|
||||
|
||||
void __OnSyncing();
|
||||
void __OnWaiting();
|
||||
void __OnMoving();
|
||||
void __OnMove();
|
||||
void __OnStop();
|
||||
void __OnWarp();
|
||||
void __OnClearAffects();
|
||||
void __OnSetAffect(UINT uAffect);
|
||||
void __OnResetAffect(UINT uAffect);
|
||||
void __OnAttack(WORD wMotionIndex);
|
||||
void __OnUseSkill(UINT uMotSkill, UINT uLoopCount, bool isMoving);
|
||||
|
||||
protected:
|
||||
void __OnHit(UINT uSkill, CActorInstance& rkInstVictm, BOOL isSendPacket);
|
||||
|
||||
public:
|
||||
void EnableSkipCollision();
|
||||
void DisableSkipCollision();
|
||||
bool CanSkipCollision();
|
||||
|
||||
protected:
|
||||
void __InitializeCollisionData();
|
||||
|
||||
bool m_canSkipCollision;
|
||||
|
||||
protected:
|
||||
struct SBlendAlpha
|
||||
{
|
||||
float m_fBaseTime;
|
||||
float m_fBaseAlpha;
|
||||
float m_fDuration;
|
||||
float m_fDstAlpha;
|
||||
|
||||
DWORD m_iOldRenderMode;
|
||||
bool m_isBlending;
|
||||
} m_kBlendAlpha;
|
||||
|
||||
void __BlendAlpha_Initialize();
|
||||
void __BlendAlpha_Apply(float fDstAlpha, float fDuration);
|
||||
void __BlendAlpha_Update();
|
||||
void __BlendAlpha_UpdateFadeIn();
|
||||
void __BlendAlpha_UpdateFadeOut();
|
||||
void __BlendAlpha_UpdateComplete();
|
||||
float __BlendAlpha_GetElapsedTime();
|
||||
|
||||
void __Push(int x, int y);
|
||||
|
||||
public:
|
||||
void TEMP_Push(int x, int y);
|
||||
bool __IsSyncing();
|
||||
|
||||
void __CreateTree(const char * c_szFileName);
|
||||
void __DestroyTree();
|
||||
void __SetTreePosition(float fx, float fy, float fz);
|
||||
|
||||
protected:
|
||||
IEventHandler* m_pkEventHandler;
|
||||
|
||||
protected:
|
||||
static bool ms_isDirLine;
|
||||
};
|
||||
@@ -0,0 +1,606 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EffectLib/EffectManager.h"
|
||||
|
||||
#include "ActorInstance.h"
|
||||
#include "ItemData.h"
|
||||
#include "ItemManager.h"
|
||||
#include "RaceData.h"
|
||||
#include "WeaponTrace.h"
|
||||
|
||||
BOOL USE_WEAPON_SPECULAR = TRUE;
|
||||
|
||||
BOOL USE_VIETNAM_CONVERT_WEAPON_VNUM = FALSE;
|
||||
|
||||
DWORD Vietnam_ConvertWeaponVnum(DWORD vnum)
|
||||
{
|
||||
DWORD base = vnum / 10 * 10;
|
||||
DWORD rest = vnum % 10;
|
||||
switch (base)
|
||||
{
|
||||
case 10:base = 5000;break;
|
||||
case 20:base = 5010;break;
|
||||
case 30:base = 5020;break;
|
||||
case 40:base = 5030;break;
|
||||
case 50:base = 5030;break;
|
||||
case 60:base = 5040;break;
|
||||
case 70:base = 5040;break;
|
||||
case 80:base = 5050;break;
|
||||
case 90:base = 5050;break;
|
||||
case 100:base = 5060;break;
|
||||
case 110:base = 5060;break;
|
||||
case 120:base = 5070;break;
|
||||
case 130:base = 5070;break;
|
||||
case 140:base = 5080;break;
|
||||
case 150:base = 5080;break;
|
||||
case 160:base = 5090;break;
|
||||
case 170:base = 5090;break;
|
||||
case 180:base = 5100;break;
|
||||
case 190:base = 5100;break;
|
||||
case 200:base = 5110;break;
|
||||
case 210:base = 5110;break;
|
||||
case 220:base = 5120;break;
|
||||
case 230:base = 5120;break;
|
||||
case 240:base = 5130;break;
|
||||
case 250:base = 5130;break;
|
||||
case 260:base = 5140;break;
|
||||
case 270:base = 5140;break;
|
||||
case 280:base = 5150;break;
|
||||
case 290:base = 5150;break;
|
||||
case 1000:base = 5000;break;
|
||||
case 1010:base = 5010;break;
|
||||
case 1020:base = 5020;break;
|
||||
case 1030:base = 5030;break;
|
||||
case 1040:base = 5040;break;
|
||||
case 1050:base = 5050;break;
|
||||
case 1060:base = 5060;break;
|
||||
case 1070:base = 5070;break;
|
||||
case 1080:base = 5080;break;
|
||||
case 1090:base = 5090;break;
|
||||
case 1100:base = 5100;break;
|
||||
case 1110:base = 5110;break;
|
||||
case 1120:base = 5120;break;
|
||||
case 1130:base = 5130;break;
|
||||
case 1140:base = 5140;break;
|
||||
case 1150:base = 5150;break;
|
||||
case 1160:base = 5150;break;
|
||||
case 1170:base = 5150;break;
|
||||
case 3000:base = 5000;break;
|
||||
case 3010:base = 5010;break;
|
||||
case 3020:base = 5020;break;
|
||||
case 3030:base = 5030;break;
|
||||
case 3040:base = 5040;break;
|
||||
case 3050:base = 5050;break;
|
||||
case 3060:base = 5060;break;
|
||||
case 3070:base = 5070;break;
|
||||
case 3080:base = 5080;break;
|
||||
case 3090:base = 5090;break;
|
||||
case 3100:base = 5100;break;
|
||||
case 3110:base = 5100;break;
|
||||
case 3120:base = 5110;break;
|
||||
case 3130:base = 5110;break;
|
||||
case 3140:base = 5120;break;
|
||||
case 3150:base = 5120;break;
|
||||
case 3160:base = 5130;break;
|
||||
case 3170:base = 5130;break;
|
||||
case 3180:base = 5140;break;
|
||||
case 3190:base = 5140;break;
|
||||
case 3200:base = 5150;break;
|
||||
case 3210:base = 5150;break;
|
||||
}
|
||||
return base + rest;
|
||||
}
|
||||
|
||||
|
||||
DWORD CActorInstance::AttachSmokeEffect(DWORD eSmoke)
|
||||
{
|
||||
if (!m_pkCurRaceData)
|
||||
return 0;
|
||||
|
||||
DWORD dwSmokeEffectID=m_pkCurRaceData->GetSmokeEffectID(eSmoke);
|
||||
|
||||
return AttachEffectByID(0, m_pkCurRaceData->GetSmokeBone().c_str(), dwSmokeEffectID);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsLeftHandWeapon(DWORD type)
|
||||
{
|
||||
if (CItemData::WEAPON_DAGGER == type || (CItemData::WEAPON_FAN == type && __IsMountingHorse()))
|
||||
return true;
|
||||
else if (CItemData::WEAPON_BOW == type)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsRightHandWeapon(DWORD type)
|
||||
{
|
||||
if (CItemData::WEAPON_DAGGER == type || (CItemData::WEAPON_FAN == type && __IsMountingHorse()))
|
||||
return true;
|
||||
else if (CItemData::WEAPON_BOW == type)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsWeaponTrace(DWORD weaponType)
|
||||
{
|
||||
switch(weaponType)
|
||||
{
|
||||
case CItemData::WEAPON_BELL:
|
||||
case CItemData::WEAPON_FAN:
|
||||
case CItemData::WEAPON_BOW:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::AttachWeapon(DWORD dwItemIndex,DWORD dwParentPartIndex, DWORD dwPartIndex)
|
||||
{
|
||||
if (dwPartIndex>=CRaceData::PART_MAX_NUM)
|
||||
return;
|
||||
|
||||
m_adwPartItemID[dwPartIndex]=dwItemIndex;
|
||||
|
||||
if (USE_VIETNAM_CONVERT_WEAPON_VNUM)
|
||||
dwItemIndex = Vietnam_ConvertWeaponVnum(dwItemIndex);
|
||||
|
||||
CItemData * pItemData;
|
||||
if (!CItemManager::Instance().GetItemDataPointer(dwItemIndex, &pItemData))
|
||||
{
|
||||
RegisterModelThing(dwPartIndex, NULL);
|
||||
SetModelInstance(dwPartIndex, dwPartIndex, 0);
|
||||
|
||||
RegisterModelThing(CRaceData::PART_WEAPON_LEFT, NULL);
|
||||
SetModelInstance(CRaceData::PART_WEAPON_LEFT, CRaceData::PART_WEAPON_LEFT, 0);
|
||||
|
||||
RefreshActorInstance();
|
||||
return;
|
||||
}
|
||||
|
||||
__DestroyWeaponTrace();
|
||||
//양손무기(자객 이도류) 왼손,오른손 모두에 장착.
|
||||
if (__IsRightHandWeapon(pItemData->GetWeaponType()))
|
||||
AttachWeapon(dwParentPartIndex, CRaceData::PART_WEAPON, pItemData);
|
||||
if (__IsLeftHandWeapon(pItemData->GetWeaponType()))
|
||||
AttachWeapon(dwParentPartIndex, CRaceData::PART_WEAPON_LEFT, pItemData);
|
||||
}
|
||||
|
||||
BOOL CActorInstance::GetAttachingBoneName(DWORD dwPartIndex, const char ** c_pszBoneName)
|
||||
{
|
||||
return m_pkCurRaceData->GetAttachingBoneName(dwPartIndex, c_pszBoneName);
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData)
|
||||
{
|
||||
// assert(m_pkCurRaceData);
|
||||
if (!pItemData)
|
||||
return;
|
||||
|
||||
const char * szBoneName;
|
||||
if (!GetAttachingBoneName(dwPartIndex, &szBoneName))
|
||||
return;
|
||||
|
||||
// NOTE : (이도류처리)단도일 경우 형태가 다른 것으로 얻는다. 없을 경우 디폴트를 리턴
|
||||
if (CRaceData::PART_WEAPON_LEFT == dwPartIndex)
|
||||
{
|
||||
RegisterModelThing(dwPartIndex, pItemData->GetSubModelThing());
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisterModelThing(dwPartIndex, pItemData->GetModelThing());
|
||||
}
|
||||
|
||||
for (DWORD i = 0; i < pItemData->GetLODModelThingCount(); ++i)
|
||||
{
|
||||
CGraphicThing * pThing;
|
||||
|
||||
if (!pItemData->GetLODModelThingPointer(i, &pThing))
|
||||
continue;
|
||||
|
||||
RegisterLODThing(dwPartIndex, pThing);
|
||||
}
|
||||
|
||||
SetModelInstance(dwPartIndex, dwPartIndex, 0);
|
||||
AttachModelInstance(dwParentPartIndex, szBoneName, dwPartIndex);
|
||||
|
||||
// 20041208.myevan.무기스펙큘러(값옷은 SetShape에서 직접 해준다.)
|
||||
if (USE_WEAPON_SPECULAR)
|
||||
{
|
||||
SMaterialData kMaterialData;
|
||||
kMaterialData.pImage = NULL;
|
||||
kMaterialData.isSpecularEnable = TRUE;
|
||||
kMaterialData.fSpecularPower = pItemData->GetSpecularPowerf();
|
||||
kMaterialData.bSphereMapIndex = 1;
|
||||
SetMaterialData(dwPartIndex, NULL, kMaterialData);
|
||||
}
|
||||
|
||||
// Weapon Trace
|
||||
if (__IsWeaponTrace(pItemData->GetWeaponType()))
|
||||
{
|
||||
CWeaponTrace * pWeaponTrace = CWeaponTrace::New();
|
||||
pWeaponTrace->SetWeaponInstance(this, dwPartIndex, szBoneName);
|
||||
m_WeaponTraceVector.push_back(pWeaponTrace);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::DettachEffect(DWORD dwEID)
|
||||
{
|
||||
std::list<TAttachingEffect>::iterator i = m_AttachingEffectList.begin();
|
||||
|
||||
while (i != m_AttachingEffectList.end())
|
||||
{
|
||||
TAttachingEffect & rkAttEft = (*i);
|
||||
|
||||
if (rkAttEft.dwEffectIndex == dwEID)
|
||||
{
|
||||
i = m_AttachingEffectList.erase(i);
|
||||
CEffectManager::Instance().DestroyEffectInstance(dwEID);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CActorInstance::AttachEffectByName(DWORD dwParentPartIndex, const char * c_pszBoneName, const char * c_pszEffectName)
|
||||
{
|
||||
std::string str;
|
||||
DWORD dwCRC;
|
||||
StringPath(c_pszEffectName, str);
|
||||
dwCRC = GetCaseCRC32(str.c_str(), str.length());
|
||||
|
||||
return AttachEffectByID(dwParentPartIndex, c_pszBoneName, dwCRC);
|
||||
}
|
||||
|
||||
DWORD CActorInstance::AttachEffectByID(DWORD dwParentPartIndex, const char * c_pszBoneName, DWORD dwEffectID, const D3DXVECTOR3 * c_pv3Position)
|
||||
{
|
||||
TAttachingEffect ae;
|
||||
ae.iLifeType = EFFECT_LIFE_INFINITE;
|
||||
ae.dwEndTime = 0;
|
||||
ae.dwModelIndex = dwParentPartIndex;
|
||||
ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex();
|
||||
ae.isAttaching = TRUE;
|
||||
if (c_pv3Position)
|
||||
{
|
||||
D3DXMatrixTranslation(&ae.matTranslation, c_pv3Position->x, c_pv3Position->y, c_pv3Position->z);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DXMatrixIdentity(&ae.matTranslation);
|
||||
}
|
||||
CEffectManager& rkEftMgr=CEffectManager::Instance();
|
||||
rkEftMgr.CreateEffectInstance(ae.dwEffectIndex, dwEffectID);
|
||||
|
||||
if (c_pszBoneName)
|
||||
{
|
||||
int iBoneIndex;
|
||||
|
||||
if (!FindBoneIndex(dwParentPartIndex,c_pszBoneName, &iBoneIndex))
|
||||
{
|
||||
ae.iBoneIndex = -1;
|
||||
//Tracef("Cannot get Bone Index\n");
|
||||
//assert(false && "Cannot get Bone Index");
|
||||
}
|
||||
else
|
||||
{
|
||||
ae.iBoneIndex = iBoneIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ae.iBoneIndex = -1;
|
||||
}
|
||||
|
||||
m_AttachingEffectList.push_back(ae);
|
||||
|
||||
return ae.dwEffectIndex;
|
||||
}
|
||||
|
||||
void CActorInstance::RefreshActorInstance()
|
||||
{
|
||||
if (!m_pkCurRaceData)
|
||||
{
|
||||
TraceError("void CActorInstance::RefreshActorInstance() - m_pkCurRaceData=NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
// This is Temporary place before making the weapon detection system
|
||||
// Setup Collison Detection Data
|
||||
m_BodyPointInstanceList.clear();
|
||||
//m_AttackingPointInstanceList.clear();
|
||||
m_DefendingPointInstanceList.clear();
|
||||
|
||||
// Base
|
||||
for (DWORD i = 0; i < m_pkCurRaceData->GetAttachingDataCount(); ++i)
|
||||
{
|
||||
const NRaceData::TAttachingData * c_pAttachingData;
|
||||
|
||||
if (!m_pkCurRaceData->GetAttachingDataPointer(i, &c_pAttachingData))
|
||||
continue;
|
||||
|
||||
switch (c_pAttachingData->dwType)
|
||||
{
|
||||
case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA:
|
||||
{
|
||||
const NRaceData::TCollisionData * c_pCollisionData = c_pAttachingData->pCollisionData;
|
||||
|
||||
TCollisionPointInstance PointInstance;
|
||||
if (NRaceData::COLLISION_TYPE_ATTACKING == c_pCollisionData->iCollisionType)
|
||||
continue;
|
||||
|
||||
if (!CreateCollisionInstancePiece(CRaceData::PART_MAIN, c_pAttachingData, &PointInstance))
|
||||
continue;
|
||||
|
||||
switch (c_pCollisionData->iCollisionType)
|
||||
{
|
||||
case NRaceData::COLLISION_TYPE_ATTACKING:
|
||||
//m_AttackingPointInstanceList.push_back(PointInstance);
|
||||
break;
|
||||
case NRaceData::COLLISION_TYPE_DEFENDING:
|
||||
m_DefendingPointInstanceList.push_back(PointInstance);
|
||||
break;
|
||||
case NRaceData::COLLISION_TYPE_BODY:
|
||||
m_BodyPointInstanceList.push_back(PointInstance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NRaceData::ATTACHING_DATA_TYPE_EFFECT:
|
||||
// if (!m_bEffectInitialized)
|
||||
// {
|
||||
// DWORD dwCRC;
|
||||
// StringPath(c_pAttachingData->pEffectData->strFileName);
|
||||
// dwCRC = GetCaseCRC32(c_pAttachingData->pEffectData->strFileName.c_str(),c_pAttachingData->pEffectData->strFileName.length());
|
||||
//
|
||||
// TAttachingEffect ae;
|
||||
// ae.iLifeType = EFFECT_LIFE_INFINITE;
|
||||
// ae.dwEndTime = 0;
|
||||
// ae.dwModelIndex = 0;
|
||||
// ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex();
|
||||
// ae.isAttaching = TRUE;
|
||||
// CEffectManager::Instance().CreateEffectInstance(ae.dwEffectIndex, dwCRC);
|
||||
//
|
||||
// if (c_pAttachingData->isAttaching)
|
||||
// {
|
||||
// int iBoneIndex;
|
||||
// if (!FindBoneIndex(0,c_pAttachingData->strAttachingBoneName.c_str(), &iBoneIndex))
|
||||
// {
|
||||
// Tracef("Cannot get Bone Index\n");
|
||||
// assert(false/*Cannot get Bone Index*/);
|
||||
// }
|
||||
//
|
||||
// ae.iBoneIndex = iBoneIndex;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ae.iBoneIndex = -1;
|
||||
// }
|
||||
//
|
||||
// m_AttachingEffectList.push_back(ae);
|
||||
// }
|
||||
|
||||
if (c_pAttachingData->isAttaching)
|
||||
{
|
||||
AttachEffectByName(0, c_pAttachingData->strAttachingBoneName.c_str(), c_pAttachingData->pEffectData->strFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachEffectByName(0, 0, c_pAttachingData->pEffectData->strFileName.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case NRaceData::ATTACHING_DATA_TYPE_OBJECT:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false/*NOT_IMPLEMENTED*/);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (DWORD j = 0; j < CRaceData::PART_MAX_NUM; ++j)
|
||||
{
|
||||
if (0 == m_adwPartItemID[j])
|
||||
continue;
|
||||
|
||||
CItemData * pItemData;
|
||||
if (!CItemManager::Instance().GetItemDataPointer(m_adwPartItemID[j], &pItemData))
|
||||
return;
|
||||
|
||||
for (DWORD k = 0; k < pItemData->GetAttachingDataCount(); ++k)
|
||||
{
|
||||
const NRaceData::TAttachingData * c_pAttachingData;
|
||||
|
||||
if (!pItemData->GetAttachingDataPointer(k, &c_pAttachingData))
|
||||
continue;
|
||||
|
||||
switch(c_pAttachingData->dwType)
|
||||
{
|
||||
case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA:
|
||||
{
|
||||
const NRaceData::TCollisionData * c_pCollisionData = c_pAttachingData->pCollisionData;
|
||||
|
||||
// FIXME : 첫번째 인자는 Part의 번호다.
|
||||
// Base는 무조건 0인가? - [levites]
|
||||
TCollisionPointInstance PointInstance;
|
||||
if (NRaceData::COLLISION_TYPE_ATTACKING == c_pCollisionData->iCollisionType)
|
||||
continue;
|
||||
if (!CreateCollisionInstancePiece(j, c_pAttachingData, &PointInstance))
|
||||
continue;
|
||||
|
||||
switch (c_pCollisionData->iCollisionType)
|
||||
{
|
||||
case NRaceData::COLLISION_TYPE_ATTACKING:
|
||||
//m_AttackingPointInstanceList.push_back(PointInstance);
|
||||
break;
|
||||
case NRaceData::COLLISION_TYPE_DEFENDING:
|
||||
m_DefendingPointInstanceList.push_back(PointInstance);
|
||||
break;
|
||||
case NRaceData::COLLISION_TYPE_BODY:
|
||||
m_BodyPointInstanceList.push_back(PointInstance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NRaceData::ATTACHING_DATA_TYPE_EFFECT:
|
||||
if (!m_bEffectInitialized)
|
||||
{
|
||||
DWORD dwCRC;
|
||||
StringPath(c_pAttachingData->pEffectData->strFileName);
|
||||
dwCRC = GetCaseCRC32(c_pAttachingData->pEffectData->strFileName.c_str(),c_pAttachingData->pEffectData->strFileName.length());
|
||||
|
||||
TAttachingEffect ae;
|
||||
ae.iLifeType = EFFECT_LIFE_INFINITE;
|
||||
ae.dwEndTime = 0;
|
||||
ae.dwModelIndex = j;
|
||||
ae.dwEffectIndex = CEffectManager::Instance().GetEmptyIndex();
|
||||
ae.isAttaching = TRUE;
|
||||
CEffectManager::Instance().CreateEffectInstance(ae.dwEffectIndex, dwCRC);
|
||||
|
||||
int iBoneIndex;
|
||||
if (!FindBoneIndex(j,c_pAttachingData->strAttachingBoneName.c_str(), &iBoneIndex))
|
||||
{
|
||||
Tracef("Cannot get Bone Index\n");
|
||||
assert(false/*Cannot get Bone Index*/);
|
||||
}
|
||||
Tracef("Creating %p %d %d\n", this, j,k);
|
||||
|
||||
ae.iBoneIndex = iBoneIndex;
|
||||
|
||||
m_AttachingEffectList.push_back(ae);
|
||||
}
|
||||
break;
|
||||
|
||||
case NRaceData::ATTACHING_DATA_TYPE_OBJECT:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false/*NOT_IMPLEMENTED*/);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_bEffectInitialized = true;
|
||||
}
|
||||
|
||||
void CActorInstance::SetWeaponTraceTexture(const char * szTextureName)
|
||||
{
|
||||
std::vector<CWeaponTrace*>::iterator it;
|
||||
for (it = m_WeaponTraceVector.begin(); it != m_WeaponTraceVector.end(); ++it)
|
||||
{
|
||||
(*it)->SetTexture(szTextureName);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::UseTextureWeaponTrace()
|
||||
{
|
||||
for_each(
|
||||
m_WeaponTraceVector.begin(),
|
||||
m_WeaponTraceVector.end(),
|
||||
std::mem_fn(&CWeaponTrace::UseTexture)
|
||||
);
|
||||
}
|
||||
|
||||
void CActorInstance::UseAlphaWeaponTrace()
|
||||
{
|
||||
for_each(
|
||||
m_WeaponTraceVector.begin(),
|
||||
m_WeaponTraceVector.end(),
|
||||
std::mem_fn(&CWeaponTrace::UseAlpha)
|
||||
);
|
||||
}
|
||||
|
||||
void CActorInstance::UpdateAttachingInstances()
|
||||
{
|
||||
CEffectManager& rkEftMgr=CEffectManager::Instance();
|
||||
|
||||
std::list<TAttachingEffect>::iterator it;
|
||||
DWORD dwCurrentTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
for (it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();)
|
||||
{
|
||||
if (EFFECT_LIFE_WITH_MOTION == it->iLifeType)
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((EFFECT_LIFE_NORMAL == it->iLifeType && it->dwEndTime < dwCurrentTime) ||
|
||||
!rkEftMgr.IsAliveEffect(it->dwEffectIndex))
|
||||
{
|
||||
rkEftMgr.DestroyEffectInstance(it->dwEffectIndex);
|
||||
it = m_AttachingEffectList.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (it->isAttaching)
|
||||
{
|
||||
rkEftMgr.SelectEffectInstance(it->dwEffectIndex);
|
||||
|
||||
if (it->iBoneIndex == -1)
|
||||
{
|
||||
D3DXMATRIX matTransform;
|
||||
matTransform = it->matTranslation;
|
||||
matTransform *= m_worldMatrix;
|
||||
rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DXMATRIX * pBoneMat;
|
||||
if (GetBoneMatrix(it->dwModelIndex, it->iBoneIndex, &pBoneMat))
|
||||
{
|
||||
D3DXMATRIX matTransform;
|
||||
matTransform = *pBoneMat;
|
||||
matTransform *= it->matTranslation;
|
||||
matTransform *= m_worldMatrix;
|
||||
rkEftMgr.SetEffectInstanceGlobalMatrix(matTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
//TraceError("GetBoneMatrix(modelIndex(%d), boneIndex(%d)).NOT_FOUND_BONE",
|
||||
// it->dwModelIndex, it->iBoneIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::ShowAllAttachingEffect()
|
||||
{
|
||||
std::list<TAttachingEffect>::iterator it;
|
||||
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
|
||||
{
|
||||
CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex);
|
||||
CEffectManager::Instance().ShowEffect();
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::HideAllAttachingEffect()
|
||||
{
|
||||
std::list<TAttachingEffect>::iterator it;
|
||||
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
|
||||
{
|
||||
CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex);
|
||||
CEffectManager::Instance().HideEffect();
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__ClearAttachingEffect()
|
||||
{
|
||||
m_bEffectInitialized = false;
|
||||
|
||||
std::list<TAttachingEffect>::iterator it;
|
||||
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
|
||||
{
|
||||
CEffectManager::Instance().DestroyEffectInstance(it->dwEffectIndex);
|
||||
}
|
||||
m_AttachingEffectList.clear();
|
||||
}
|
||||
@@ -0,0 +1,967 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../effectLib/EffectManager.h"
|
||||
#include "../milesLib/SoundManager.h"
|
||||
|
||||
#include "ActorInstance.h"
|
||||
#include "RaceData.h"
|
||||
|
||||
void CActorInstance::SetBattleHitEffect(DWORD dwID)
|
||||
{
|
||||
m_dwBattleHitEffectID = dwID;
|
||||
}
|
||||
|
||||
void CActorInstance::SetBattleAttachEffect(DWORD dwID)
|
||||
{
|
||||
m_dwBattleAttachEffectID = dwID;
|
||||
}
|
||||
|
||||
bool CActorInstance::CanAct()
|
||||
{
|
||||
if (IsDead())
|
||||
return false;
|
||||
|
||||
if (IsStun())
|
||||
return false;
|
||||
|
||||
if (IsParalysis())
|
||||
return false;
|
||||
|
||||
if (IsFaint())
|
||||
return false;
|
||||
|
||||
if (IsSleep())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::CanUseSkill()
|
||||
{
|
||||
if (!CanAct())
|
||||
return false;
|
||||
|
||||
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
|
||||
|
||||
// Locked during attack
|
||||
switch (dwCurMotionIndex)
|
||||
{
|
||||
case CRaceMotionData::NAME_FISHING_THROW:
|
||||
case CRaceMotionData::NAME_FISHING_WAIT:
|
||||
case CRaceMotionData::NAME_FISHING_STOP:
|
||||
case CRaceMotionData::NAME_FISHING_REACT:
|
||||
case CRaceMotionData::NAME_FISHING_CATCH:
|
||||
case CRaceMotionData::NAME_FISHING_FAIL:
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Locked during using skill
|
||||
if (IsUsingSkill())
|
||||
{
|
||||
if (m_pkCurRaceMotionData->IsCancelEnableSkill())
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::CanMove()
|
||||
{
|
||||
if (!CanAct())
|
||||
return false;
|
||||
|
||||
if (isLock())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::CanAttack()
|
||||
{
|
||||
if (!CanAct())
|
||||
return false;
|
||||
|
||||
if (IsUsingSkill())
|
||||
{
|
||||
if (!CanCancelSkill())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::CanFishing()
|
||||
{
|
||||
if (!CanAct())
|
||||
return false;
|
||||
|
||||
if (IsUsingSkill())
|
||||
return false;
|
||||
|
||||
switch (__GetCurrentMotionIndex())
|
||||
{
|
||||
case CRaceMotionData::NAME_WAIT:
|
||||
case CRaceMotionData::NAME_WALK:
|
||||
case CRaceMotionData::NAME_RUN:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsClickableDistanceDestInstance(CActorInstance & rkInstDst, float fDistance)
|
||||
{
|
||||
TPixelPosition kPPosSrc;
|
||||
GetPixelPosition(&kPPosSrc);
|
||||
|
||||
D3DXVECTOR3 kD3DVct3Src(kPPosSrc);
|
||||
|
||||
TCollisionPointInstanceList& rkLstkDefPtInst=rkInstDst.m_DefendingPointInstanceList;
|
||||
TCollisionPointInstanceList::iterator i;
|
||||
|
||||
for (i=rkLstkDefPtInst.begin(); i!=rkLstkDefPtInst.end(); ++i)
|
||||
{
|
||||
CDynamicSphereInstanceVector& rkVctkDefSphere = (*i).SphereInstanceVector;
|
||||
|
||||
CDynamicSphereInstanceVector::iterator j;
|
||||
for (j=rkVctkDefSphere.begin(); j!=rkVctkDefSphere.end(); ++j)
|
||||
{
|
||||
CDynamicSphereInstance& rkSphere=(*j);
|
||||
|
||||
const auto vv = D3DXVECTOR3(rkSphere.v3Position - kD3DVct3Src);
|
||||
float fMovDistance=D3DXVec3Length(&vv);
|
||||
float fAtkDistance=rkSphere.fRadius+fDistance;
|
||||
|
||||
if (fAtkDistance>fMovDistance)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CActorInstance::InputNormalAttackCommand(float fDirRot)
|
||||
{
|
||||
if (!__CanInputNormalAttackCommand())
|
||||
return;
|
||||
|
||||
m_fAtkDirRot=fDirRot;
|
||||
NormalAttack(m_fAtkDirRot);
|
||||
}
|
||||
|
||||
bool CActorInstance::InputComboAttackCommand(float fDirRot)
|
||||
{
|
||||
m_fAtkDirRot=fDirRot;
|
||||
|
||||
if (m_isPreInput)
|
||||
return false;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Process Input
|
||||
if (0 == m_dwcurComboIndex)
|
||||
{
|
||||
__RunNextCombo();
|
||||
return true;
|
||||
}
|
||||
else if (m_pkCurRaceMotionData->IsComboInputTimeData())
|
||||
{
|
||||
// 동작 경과 시간
|
||||
float fElapsedTime = GetAttackingElapsedTime();
|
||||
|
||||
// 이미 입력 한계 시간이 지났다면..
|
||||
if (fElapsedTime > m_pkCurRaceMotionData->GetComboInputEndTime())
|
||||
{
|
||||
//Tracen("입력 한계 시간 지남");
|
||||
if (IsBowMode())
|
||||
m_isNextPreInput = TRUE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fElapsedTime > m_pkCurRaceMotionData->GetNextComboTime()) // 콤보 발동 시간 이 후라면
|
||||
{
|
||||
//Tracen("다음 콤보 동작");
|
||||
// args : BlendingTime
|
||||
__RunNextCombo();
|
||||
return true;
|
||||
}
|
||||
else if (fElapsedTime > m_pkCurRaceMotionData->GetComboInputStartTime()) // 선 입력 시간 범위 라면..
|
||||
{
|
||||
//Tracen("선 입력 설정");
|
||||
m_isPreInput = TRUE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float fElapsedTime = GetAttackingElapsedTime();
|
||||
if (fElapsedTime > m_pkCurRaceMotionData->GetMotionDuration()*0.9f) // 콤보 발동 시간 이 후라면
|
||||
{
|
||||
//Tracen("다음 콤보 동작");
|
||||
// args : BlendingTime
|
||||
__RunNextCombo();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Process Input
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CActorInstance::ComboProcess()
|
||||
{
|
||||
// If combo is on action
|
||||
if (0 != m_dwcurComboIndex)
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
{
|
||||
Tracef("Attacking motion data is NULL! : %d\n", m_dwcurComboIndex);
|
||||
__ClearCombo();
|
||||
return;
|
||||
}
|
||||
|
||||
float fElapsedTime = GetAttackingElapsedTime();
|
||||
|
||||
// Process PreInput
|
||||
if (m_isPreInput)
|
||||
{
|
||||
//Tracenf("선입력 %f 다음콤보시간 %f", fElapsedTime, m_pkCurRaceMotionData->GetNextComboTime());
|
||||
if (fElapsedTime > m_pkCurRaceMotionData->GetNextComboTime())
|
||||
{
|
||||
__RunNextCombo();
|
||||
m_isPreInput = FALSE;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isPreInput = FALSE;
|
||||
|
||||
if (!IsUsingSkill()) // m_isNextPreInput는 활모드 일때만 사용하는 변수
|
||||
if (m_isNextPreInput) // 활일때만 스킬이 캔슬 되는건 이곳 때문임
|
||||
{
|
||||
__RunNextCombo();
|
||||
m_isNextPreInput = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__RunNextCombo()
|
||||
{
|
||||
++m_dwcurComboIndex;
|
||||
///////////////////////////
|
||||
|
||||
WORD wComboIndex = m_dwcurComboIndex;
|
||||
WORD wComboType = __GetCurrentComboType();
|
||||
|
||||
if (wComboIndex==0)
|
||||
{
|
||||
TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d)", wComboType, wComboIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD dwComboArrayIndex = wComboIndex - 1;
|
||||
|
||||
CRaceData::TComboData * pComboData;
|
||||
|
||||
if (!m_pkCurRaceData->GetComboDataPointer(m_wcurMotionMode, wComboType, &pComboData))
|
||||
{
|
||||
TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d) - m_pkCurRaceData->GetComboDataPointer(m_wcurMotionMode=%d, &pComboData) == NULL",
|
||||
wComboType, wComboIndex, m_wcurMotionMode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dwComboArrayIndex >= pComboData->ComboIndexVector.size())
|
||||
{
|
||||
TraceError("CActorInstance::__RunNextCombo(wComboType=%d, wComboIndex=%d) - (dwComboArrayIndex=%d) >= (pComboData->ComboIndexVector.size()=%d)",
|
||||
wComboType, wComboIndex, dwComboArrayIndex, pComboData->ComboIndexVector.size());
|
||||
return;
|
||||
}
|
||||
|
||||
WORD wcurComboMotionIndex = pComboData->ComboIndexVector[dwComboArrayIndex];
|
||||
ComboAttack(wcurComboMotionIndex, m_fAtkDirRot, 0.1f);
|
||||
|
||||
////////////////////////////////
|
||||
// 콤보가 끝났다면
|
||||
if (m_dwcurComboIndex == pComboData->ComboIndexVector.size())
|
||||
{
|
||||
__OnEndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__OnEndCombo()
|
||||
{
|
||||
if (__IsMountingHorse())
|
||||
{
|
||||
m_dwcurComboIndex = 1;
|
||||
}
|
||||
|
||||
// 여기서 콤보를 초기화 해선 안된다.
|
||||
// 콤보가 초기화 되는 곳은 마지막 콤보가 끝나고 Motion 이 자동으로 Wait 으로 돌아가는 시점이다.
|
||||
}
|
||||
|
||||
void CActorInstance::__ClearCombo()
|
||||
{
|
||||
m_dwcurComboIndex = 0;
|
||||
m_isPreInput = FALSE;
|
||||
m_pkCurRaceMotionData = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL CActorInstance::isAttacking()
|
||||
{
|
||||
if (isNormalAttacking())
|
||||
return TRUE;
|
||||
|
||||
if (isComboAttacking())
|
||||
return TRUE;
|
||||
|
||||
if (IsSplashAttacking())
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::isValidAttacking()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return FALSE;
|
||||
|
||||
if (!m_pkCurRaceMotionData->isAttackingMotion())
|
||||
return FALSE;
|
||||
|
||||
const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
|
||||
float fElapsedTime = GetAttackingElapsedTime();
|
||||
NRaceData::THitDataContainer::const_iterator itor = c_pData->HitDataContainer.begin();
|
||||
for (; itor != c_pData->HitDataContainer.end(); ++itor)
|
||||
{
|
||||
const NRaceData::THitData & c_rHitData = *itor;
|
||||
if (fElapsedTime > c_rHitData.fAttackStartTime &&
|
||||
fElapsedTime < c_rHitData.fAttackEndTime)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::CanCheckAttacking()
|
||||
{
|
||||
if (isAttacking())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsInSplashTime()
|
||||
{
|
||||
if (m_kSplashArea.fDisappearingTime>GetLocalTime())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::isNormalAttacking()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return FALSE;
|
||||
|
||||
if (!m_pkCurRaceMotionData->isAttackingMotion())
|
||||
return FALSE;
|
||||
|
||||
const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
|
||||
if (NRaceData::MOTION_TYPE_NORMAL != c_pData->iMotionType)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::isComboAttacking()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return FALSE;
|
||||
|
||||
if (!m_pkCurRaceMotionData->isAttackingMotion())
|
||||
return FALSE;
|
||||
|
||||
const NRaceData::TMotionAttackData * c_pData = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
|
||||
if (NRaceData::MOTION_TYPE_COMBO != c_pData->iMotionType)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsSplashAttacking()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return FALSE;
|
||||
|
||||
if (m_pkCurRaceMotionData->HasSplashMotionEvent())
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::__IsMovingSkill(WORD wSkillNumber)
|
||||
{
|
||||
enum
|
||||
{
|
||||
HORSE_DASH_SKILL_NUMBER = 137,
|
||||
};
|
||||
|
||||
return HORSE_DASH_SKILL_NUMBER == wSkillNumber;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsActEmotion()
|
||||
{
|
||||
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
|
||||
switch (dwCurMotionIndex)
|
||||
{
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_START+0:
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_START+1:
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_START+2:
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_START+3:
|
||||
case CRaceMotionData::NAME_KISS_START+0:
|
||||
case CRaceMotionData::NAME_KISS_START+1:
|
||||
case CRaceMotionData::NAME_KISS_START+2:
|
||||
case CRaceMotionData::NAME_KISS_START+3:
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsUsingMovingSkill()
|
||||
{
|
||||
return __IsMovingSkill(m_kCurMotNode.uSkill);
|
||||
}
|
||||
|
||||
DWORD CActorInstance::GetComboIndex()
|
||||
{
|
||||
return m_dwcurComboIndex;
|
||||
}
|
||||
|
||||
float CActorInstance::GetAttackingElapsedTime()
|
||||
{
|
||||
return (GetLocalTime() - m_kCurMotNode.fStartTime) * m_kCurMotNode.fSpeedRatio;
|
||||
// return (GetLocalTime() - m_kCurMotNode.fStartTime) * __GetAttackSpeed();
|
||||
}
|
||||
|
||||
bool CActorInstance::__CanInputNormalAttackCommand()
|
||||
{
|
||||
if (IsWaiting())
|
||||
return true;
|
||||
|
||||
if (isNormalAttacking())
|
||||
{
|
||||
float fElapsedTime = GetAttackingElapsedTime();
|
||||
|
||||
if (fElapsedTime > m_pkCurRaceMotionData->GetMotionDuration()*0.9f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::NormalAttack(float fDirRot, float fBlendTime)
|
||||
{
|
||||
WORD wMotionIndex;
|
||||
if (!m_pkCurRaceData->GetNormalAttackIndex(m_wcurMotionMode, &wMotionIndex))
|
||||
return FALSE;
|
||||
|
||||
BlendRotation(fDirRot, fBlendTime);
|
||||
SetAdvancingRotation(fDirRot);
|
||||
InterceptOnceMotion(wMotionIndex, 0.1f, 0, __GetAttackSpeed());
|
||||
|
||||
__OnAttack(wMotionIndex);
|
||||
|
||||
NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::ComboAttack(DWORD dwMotionIndex, float fDirRot, float fBlendTime)
|
||||
{
|
||||
BlendRotation(fDirRot, fBlendTime);
|
||||
SetAdvancingRotation(fDirRot);
|
||||
|
||||
InterceptOnceMotion(dwMotionIndex, fBlendTime, 0, __GetAttackSpeed());
|
||||
|
||||
__OnAttack(dwMotionIndex);
|
||||
|
||||
NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CActorInstance::__ProcessMotionEventAttackSuccess(DWORD dwMotionKey, BYTE byEventIndex, CActorInstance & rVictim)
|
||||
{
|
||||
CRaceMotionData * pMotionData;
|
||||
|
||||
if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &pMotionData))
|
||||
return;
|
||||
|
||||
if (byEventIndex >= pMotionData->GetMotionEventDataCount())
|
||||
return;
|
||||
|
||||
const CRaceMotionData::TMotionAttackingEventData * pMotionEventData;
|
||||
if (!pMotionData->GetMotionAttackingEventDataPointer(byEventIndex, &pMotionEventData))
|
||||
return;
|
||||
|
||||
const D3DXVECTOR3& c_rv3VictimPos=rVictim.GetPositionVectorRef();
|
||||
__ProcessDataAttackSuccess(pMotionEventData->AttackData, rVictim, c_rv3VictimPos);
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::__ProcessMotionAttackSuccess(DWORD dwMotionKey, CActorInstance & rVictim)
|
||||
{
|
||||
CRaceMotionData * c_pMotionData;
|
||||
|
||||
if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &c_pMotionData))
|
||||
return;
|
||||
|
||||
const D3DXVECTOR3& c_rv3VictimPos=rVictim.GetPositionVectorRef();
|
||||
__ProcessDataAttackSuccess(c_pMotionData->GetMotionAttackDataReference(), rVictim, c_rv3VictimPos);
|
||||
}
|
||||
|
||||
|
||||
DWORD CActorInstance::__GetOwnerVID()
|
||||
{
|
||||
return m_dwOwnerVID;
|
||||
}
|
||||
|
||||
float CActorInstance::__GetOwnerTime()
|
||||
{
|
||||
return GetLocalTime()-m_fOwnerBaseTime;
|
||||
}
|
||||
|
||||
bool IS_HUGE_RACE(unsigned int vnum)
|
||||
{
|
||||
switch (vnum)
|
||||
{
|
||||
case 2493:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::__CanPushDestActor(CActorInstance& rkActorDst)
|
||||
{
|
||||
if (rkActorDst.IsBuilding())
|
||||
return false;
|
||||
|
||||
if (rkActorDst.IsDoor())
|
||||
return false;
|
||||
|
||||
if (rkActorDst.IsStone())
|
||||
return false;
|
||||
|
||||
if (rkActorDst.IsNPC())
|
||||
return false;
|
||||
|
||||
// 거대 몬스터 밀림 제외
|
||||
extern bool IS_HUGE_RACE(unsigned int vnum);
|
||||
if (IS_HUGE_RACE(rkActorDst.GetRace()))
|
||||
return false;
|
||||
|
||||
if (rkActorDst.IsStun())
|
||||
return true;
|
||||
|
||||
if (rkActorDst.__GetOwnerVID()!=GetVirtualID())
|
||||
return false;
|
||||
|
||||
if (rkActorDst.__GetOwnerTime()>3.0f)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IS_PARTY_HUNTING_RACE(unsigned int vnum)
|
||||
{
|
||||
return true;
|
||||
|
||||
// 모든 몬스터 파티 사냥 적용
|
||||
/*
|
||||
if (vnum < 8) // 플레이어
|
||||
return true;
|
||||
|
||||
if (vnum >= 8000 && vnum <= 8112) // 메틴석
|
||||
return true;
|
||||
|
||||
if (vnum >= 2400 && vnum < 5000) // 천의 동굴 이후 몬스터
|
||||
return true;
|
||||
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill, BOOL isSendPacket)
|
||||
{
|
||||
if (NRaceData::HIT_TYPE_NONE == c_rAttackData.iHittingType)
|
||||
return;
|
||||
|
||||
InsertDelay(c_rAttackData.fStiffenTime);
|
||||
|
||||
if (__CanPushDestActor(rVictim) && c_rAttackData.fExternalForce > 0.0f)
|
||||
{
|
||||
__PushCircle(rVictim);
|
||||
|
||||
// VICTIM_COLLISION_TEST
|
||||
const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
|
||||
rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);
|
||||
|
||||
// VICTIM_COLLISION_TEST_END
|
||||
}
|
||||
|
||||
// Invisible Time
|
||||
if (IS_PARTY_HUNTING_RACE(rVictim.GetRace()))
|
||||
{
|
||||
if (uiSkill) // 파티 사냥 몬스터라도 스킬이면 무적시간 적용
|
||||
rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
|
||||
|
||||
if (m_isMain) // #0000794: [M2KR] 폴리모프 - 밸런싱 문제 타인 공격에 의한 무적 타임은 고려하지 않고 자신 공격에 의한것만 체크한다
|
||||
rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
|
||||
}
|
||||
else // 파티 사냥 몬스터가 아닐 경우만 적용
|
||||
{
|
||||
rVictim.m_fInvisibleTime = CTimer::Instance().GetCurrentSecond() + c_rAttackData.fInvisibleTime;
|
||||
}
|
||||
|
||||
// Stiffen Time
|
||||
rVictim.InsertDelay(c_rAttackData.fStiffenTime);
|
||||
|
||||
// Hit Effect
|
||||
D3DXVECTOR3 vec3Effect(rVictim.m_x, rVictim.m_y, rVictim.m_z);
|
||||
|
||||
// #0000780: [M2KR] 수룡 타격구 문제
|
||||
extern bool IS_HUGE_RACE(unsigned int vnum);
|
||||
if (IS_HUGE_RACE(rVictim.GetRace()))
|
||||
{
|
||||
vec3Effect = c_rv3Position;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3 & v3Pos = GetPosition();
|
||||
|
||||
float fHeight = D3DXToDegree(atan2(-vec3Effect.x + v3Pos.x,+vec3Effect.y - v3Pos.y));
|
||||
|
||||
// 2004.08.03.myevan.빌딩이나 문의 경우 타격 효과가 보이지 않는다
|
||||
if (rVictim.IsBuilding()||rVictim.IsDoor())
|
||||
{
|
||||
D3DXVECTOR3 vec3Delta=vec3Effect-v3Pos;
|
||||
D3DXVec3Normalize(&vec3Delta, &vec3Delta);
|
||||
vec3Delta*=30.0f;
|
||||
|
||||
CEffectManager& rkEftMgr=CEffectManager::Instance();
|
||||
if (m_dwBattleHitEffectID)
|
||||
rkEftMgr.CreateEffect(m_dwBattleHitEffectID, v3Pos+vec3Delta, D3DXVECTOR3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
CEffectManager& rkEftMgr=CEffectManager::Instance();
|
||||
if (m_dwBattleHitEffectID)
|
||||
rkEftMgr.CreateEffect(m_dwBattleHitEffectID, vec3Effect, D3DXVECTOR3(0.0f, 0.0f, fHeight));
|
||||
if (m_dwBattleAttachEffectID)
|
||||
rVictim.AttachEffectByID(0, NULL, m_dwBattleAttachEffectID);
|
||||
}
|
||||
|
||||
if (rVictim.IsBuilding())
|
||||
{
|
||||
// 2004.08.03.빌딩의 경우 흔들리면 이상하다
|
||||
}
|
||||
else if (rVictim.IsStone() || rVictim.IsDoor())
|
||||
{
|
||||
__HitStone(rVictim);
|
||||
}
|
||||
else
|
||||
{
|
||||
///////////
|
||||
// Motion
|
||||
if (NRaceData::HIT_TYPE_GOOD == c_rAttackData.iHittingType || rVictim.IsResistFallen())
|
||||
{
|
||||
__HitGood(rVictim);
|
||||
}
|
||||
else if (NRaceData::HIT_TYPE_GREAT == c_rAttackData.iHittingType)
|
||||
{
|
||||
__HitGreate(rVictim);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceError("ProcessSucceedingAttacking: Unknown AttackingData.iHittingType %d", c_rAttackData.iHittingType);
|
||||
}
|
||||
}
|
||||
|
||||
__OnHit(uiSkill, rVictim, isSendPacket);
|
||||
}
|
||||
|
||||
void CActorInstance::OnShootDamage()
|
||||
{
|
||||
if (IsStun())
|
||||
{
|
||||
Die();
|
||||
}
|
||||
else
|
||||
{
|
||||
__Shake(100);
|
||||
|
||||
if (!isLock() && !__IsKnockDownMotion() && !__IsStandUpMotion())
|
||||
{
|
||||
if (InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE))
|
||||
PushLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__Shake(DWORD dwDuration)
|
||||
{
|
||||
DWORD dwCurTime=ELTimer_GetMSec();
|
||||
m_dwShakeTime=dwCurTime+dwDuration;
|
||||
}
|
||||
|
||||
void CActorInstance::ShakeProcess()
|
||||
{
|
||||
if (m_dwShakeTime)
|
||||
{
|
||||
D3DXVECTOR3 v3Pos(0.0f, 0.0f, 0.0f);
|
||||
|
||||
DWORD dwCurTime=ELTimer_GetMSec();
|
||||
|
||||
if (m_dwShakeTime<dwCurTime)
|
||||
{
|
||||
m_dwShakeTime=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int nShakeSize=10;
|
||||
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0:v3Pos.x+=rand()%nShakeSize;break;
|
||||
case 1:v3Pos.x-=rand()%nShakeSize;break;
|
||||
}
|
||||
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0:v3Pos.y+=rand()%nShakeSize;break;
|
||||
case 1:v3Pos.y-=rand()%nShakeSize;break;
|
||||
}
|
||||
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0:v3Pos.z+=rand()%nShakeSize;break;
|
||||
case 1:v3Pos.z-=rand()%nShakeSize;break;
|
||||
}
|
||||
}
|
||||
|
||||
m_worldMatrix._41 += v3Pos.x;
|
||||
m_worldMatrix._42 += v3Pos.y;
|
||||
m_worldMatrix._43 += v3Pos.z;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__HitStone(CActorInstance& rVictim)
|
||||
{
|
||||
if (rVictim.IsStun())
|
||||
{
|
||||
rVictim.Die();
|
||||
}
|
||||
else
|
||||
{
|
||||
rVictim.__Shake(100);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__HitGood(CActorInstance& rVictim)
|
||||
{
|
||||
if (rVictim.IsKnockDown())
|
||||
return;
|
||||
|
||||
if (rVictim.IsStun())
|
||||
{
|
||||
rVictim.Die();
|
||||
}
|
||||
else
|
||||
{
|
||||
rVictim.__Shake(100);
|
||||
|
||||
if (!rVictim.isLock())
|
||||
{
|
||||
float fRotRad = D3DXToRadian(GetRotation());
|
||||
float fVictimRotRad = D3DXToRadian(rVictim.GetRotation());
|
||||
|
||||
D3DXVECTOR2 v2Normal(sin(fRotRad), cos(fRotRad));
|
||||
D3DXVECTOR2 v2VictimNormal(sin(fVictimRotRad), cos(fVictimRotRad));
|
||||
|
||||
D3DXVec2Normalize(&v2Normal, &v2Normal);
|
||||
D3DXVec2Normalize(&v2VictimNormal, &v2VictimNormal);
|
||||
|
||||
float fScalar = D3DXVec2Dot(&v2Normal, &v2VictimNormal);
|
||||
|
||||
if (fScalar < 0.0f)
|
||||
{
|
||||
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE))
|
||||
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_BACK))
|
||||
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
else if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE))
|
||||
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__HitGreate(CActorInstance& rVictim)
|
||||
{
|
||||
// DISABLE_KNOCKDOWN_ATTACK
|
||||
if (rVictim.IsKnockDown())
|
||||
return;
|
||||
if (rVictim.__IsStandUpMotion())
|
||||
return;
|
||||
// END_OF_DISABLE_KNOCKDOWN_ATTACK
|
||||
|
||||
float fRotRad = D3DXToRadian(GetRotation());
|
||||
float fVictimRotRad = D3DXToRadian(rVictim.GetRotation());
|
||||
|
||||
D3DXVECTOR2 v2Normal(sin(fRotRad), cos(fRotRad));
|
||||
D3DXVECTOR2 v2VictimNormal(sin(fVictimRotRad), cos(fVictimRotRad));
|
||||
|
||||
D3DXVec2Normalize(&v2Normal, &v2Normal);
|
||||
D3DXVec2Normalize(&v2VictimNormal, &v2VictimNormal);
|
||||
|
||||
float fScalar = D3DXVec2Dot(&v2Normal, &v2VictimNormal);
|
||||
|
||||
rVictim.__Shake(100);
|
||||
|
||||
if (rVictim.IsUsingSkill())
|
||||
return;
|
||||
|
||||
if (rVictim.IsStun())
|
||||
{
|
||||
if (fScalar < 0.0f)
|
||||
rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
|
||||
else
|
||||
{
|
||||
if (!rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING_BACK))
|
||||
rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
|
||||
}
|
||||
|
||||
rVictim.m_isRealDead=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fScalar < 0.0f)
|
||||
{
|
||||
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING))
|
||||
{
|
||||
rVictim.PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
|
||||
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING_BACK))
|
||||
{
|
||||
if (rVictim.InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING))
|
||||
{
|
||||
rVictim.PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
|
||||
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rVictim.PushOnceMotion(CRaceMotionData::NAME_STAND_UP_BACK);
|
||||
rVictim.PushLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::SetBlendingPosition(const TPixelPosition & c_rPosition, float fBlendingTime)
|
||||
{
|
||||
//return;
|
||||
TPixelPosition Position;
|
||||
|
||||
Position.x = c_rPosition.x - m_x;
|
||||
Position.y = c_rPosition.y - m_y;
|
||||
Position.z = 0;
|
||||
|
||||
m_PhysicsObject.SetLastPosition(Position, fBlendingTime);
|
||||
}
|
||||
|
||||
void CActorInstance::ResetBlendingPosition()
|
||||
{
|
||||
m_PhysicsObject.Initialize();
|
||||
}
|
||||
|
||||
void CActorInstance::GetBlendingPosition(TPixelPosition * pPosition)
|
||||
{
|
||||
if (m_PhysicsObject.isBlending())
|
||||
{
|
||||
m_PhysicsObject.GetLastPosition(pPosition);
|
||||
pPosition->x += m_x;
|
||||
pPosition->y += m_y;
|
||||
pPosition->z += m_z;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPosition->x = m_x;
|
||||
pPosition->y = m_y;
|
||||
pPosition->z = m_z;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__PushCircle(CActorInstance & rVictim)
|
||||
{
|
||||
const TPixelPosition& c_rkPPosAtk=NEW_GetAtkPixelPositionRef();
|
||||
|
||||
D3DXVECTOR3 v3SrcPos(c_rkPPosAtk.x, -c_rkPPosAtk.y, c_rkPPosAtk.z);
|
||||
|
||||
const D3DXVECTOR3& c_rv3SrcPos = v3SrcPos;
|
||||
const D3DXVECTOR3& c_rv3DstPos = rVictim.GetPosition();
|
||||
|
||||
D3DXVECTOR3 v3Direction;
|
||||
v3Direction.x = c_rv3DstPos.x - c_rv3SrcPos.x;
|
||||
v3Direction.y = c_rv3DstPos.y - c_rv3SrcPos.y;
|
||||
v3Direction.z = 0.0f;
|
||||
D3DXVec3Normalize(&v3Direction, &v3Direction);
|
||||
|
||||
rVictim.__SetFallingDirection(v3Direction.x, v3Direction.y);
|
||||
}
|
||||
|
||||
void CActorInstance::__PushDirect(CActorInstance & rVictim)
|
||||
{
|
||||
D3DXVECTOR3 v3Direction;
|
||||
v3Direction.x = cosf(D3DXToRadian(m_fcurRotation + 270.0f));
|
||||
v3Direction.y = sinf(D3DXToRadian(m_fcurRotation + 270.0f));
|
||||
v3Direction.z = 0.0f;
|
||||
|
||||
rVictim.__SetFallingDirection(v3Direction.x, v3Direction.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool CActorInstance::__isInvisible()
|
||||
{
|
||||
if (IsDead())
|
||||
return true;
|
||||
|
||||
if (CTimer::Instance().GetCurrentSecond() >= m_fInvisibleTime)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CActorInstance::__SetFallingDirection(float fx, float fy)
|
||||
{
|
||||
m_PhysicsObject.SetDirection(D3DXVECTOR3(fx, fy, 0.0f));
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
|
||||
void CActorInstance::BlendAlphaValue(float fDstAlpha, float fDuration)
|
||||
{
|
||||
__BlendAlpha_Apply(fDstAlpha, fDuration);
|
||||
}
|
||||
|
||||
void CActorInstance::SetBlendRenderMode()
|
||||
{
|
||||
m_iRenderMode = RENDER_MODE_BLEND;
|
||||
}
|
||||
|
||||
void CActorInstance::SetAlphaValue(float fAlpha)
|
||||
{
|
||||
m_fAlphaValue = fAlpha;
|
||||
}
|
||||
|
||||
float CActorInstance::GetAlphaValue()
|
||||
{
|
||||
return m_fAlphaValue;
|
||||
}
|
||||
|
||||
void CActorInstance::__BlendAlpha_Initialize()
|
||||
{
|
||||
m_kBlendAlpha.m_isBlending=false;
|
||||
m_kBlendAlpha.m_fBaseTime=0.0f;
|
||||
m_kBlendAlpha.m_fDuration=0.0f;
|
||||
m_kBlendAlpha.m_fBaseAlpha=0.0f;
|
||||
m_kBlendAlpha.m_fDstAlpha=0.0f;
|
||||
m_kBlendAlpha.m_iOldRenderMode=RENDER_MODE_NORMAL;
|
||||
}
|
||||
|
||||
void CActorInstance::__BlendAlpha_Apply(float fDstAlpha, float fDuration)
|
||||
{
|
||||
m_kBlendAlpha.m_isBlending=true;
|
||||
m_kBlendAlpha.m_fBaseAlpha=GetAlphaValue();
|
||||
m_kBlendAlpha.m_fBaseTime=GetLocalTime();
|
||||
m_kBlendAlpha.m_fDuration=fDuration;
|
||||
m_kBlendAlpha.m_fDstAlpha=fDstAlpha;
|
||||
m_kBlendAlpha.m_iOldRenderMode=m_iRenderMode;
|
||||
}
|
||||
|
||||
void CActorInstance::__BlendAlpha_Update()
|
||||
{
|
||||
if (!m_kBlendAlpha.m_isBlending)
|
||||
return;
|
||||
|
||||
float fElapsedTime=__BlendAlpha_GetElapsedTime();
|
||||
|
||||
if (fElapsedTime<m_kBlendAlpha.m_fDuration)
|
||||
{
|
||||
float fCurAlpha=m_kBlendAlpha.m_fBaseAlpha+(m_kBlendAlpha.m_fDstAlpha-m_kBlendAlpha.m_fBaseAlpha)*fElapsedTime/m_kBlendAlpha.m_fDuration;
|
||||
SetBlendRenderMode();
|
||||
SetAlphaValue(fCurAlpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (1.0f>m_kBlendAlpha.m_fDstAlpha)
|
||||
{
|
||||
SetBlendRenderMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iRenderMode=m_kBlendAlpha.m_iOldRenderMode;
|
||||
}
|
||||
|
||||
SetAlphaValue(m_kBlendAlpha.m_fDstAlpha);
|
||||
|
||||
__BlendAlpha_UpdateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__BlendAlpha_UpdateComplete()
|
||||
{
|
||||
m_kBlendAlpha.m_isBlending=false;
|
||||
}
|
||||
|
||||
float CActorInstance::__BlendAlpha_GetElapsedTime()
|
||||
{
|
||||
float fCurTime=GetLocalTime();
|
||||
return fCurTime-m_kBlendAlpha.m_fBaseTime;
|
||||
}
|
||||
@@ -0,0 +1,744 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/GrpMath.h"
|
||||
|
||||
#include "ActorInstance.h"
|
||||
|
||||
void CActorInstance::__InitializeCollisionData()
|
||||
{
|
||||
m_canSkipCollision=false;
|
||||
}
|
||||
|
||||
void CActorInstance::EnableSkipCollision()
|
||||
{
|
||||
m_canSkipCollision=true;
|
||||
}
|
||||
|
||||
void CActorInstance::DisableSkipCollision()
|
||||
{
|
||||
m_canSkipCollision=false;
|
||||
}
|
||||
|
||||
bool CActorInstance::CanSkipCollision()
|
||||
{
|
||||
return m_canSkipCollision;
|
||||
}
|
||||
|
||||
void CActorInstance::UpdatePointInstance()
|
||||
{
|
||||
TCollisionPointInstanceListIterator itor;
|
||||
for (itor = m_DefendingPointInstanceList.begin(); itor != m_DefendingPointInstanceList.end(); ++itor)
|
||||
UpdatePointInstance(&(*itor));
|
||||
}
|
||||
|
||||
void CActorInstance::UpdatePointInstance(TCollisionPointInstance * pPointInstance)
|
||||
{
|
||||
if (!pPointInstance)
|
||||
{
|
||||
assert(!"CActorInstance::UpdatePointInstance - pPointInstance is NULL"); // 레퍼런스로 교체하시오
|
||||
return;
|
||||
}
|
||||
|
||||
D3DXMATRIX matBone;
|
||||
|
||||
if (pPointInstance->isAttached)
|
||||
{
|
||||
if (pPointInstance->dwModelIndex>=m_LODControllerVector.size())
|
||||
{
|
||||
//Tracenf("CActorInstance::UpdatePointInstance - rInstance.dwModelIndex=%d >= m_LODControllerVector.size()=%d",
|
||||
// pPointInstance->dwModelIndex>m_LODControllerVector.size());
|
||||
return;
|
||||
}
|
||||
|
||||
CGrannyLODController* pGrnLODController=m_LODControllerVector[pPointInstance->dwModelIndex];
|
||||
if (!pGrnLODController)
|
||||
{
|
||||
//Tracenf("CActorInstance::UpdatePointInstance - m_LODControllerVector[pPointInstance->dwModelIndex=%d] is NULL", pPointInstance->dwModelIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
CGrannyModelInstance * pModelInstance = pGrnLODController->GetModelInstance();
|
||||
if (!pModelInstance)
|
||||
{
|
||||
//Tracenf("CActorInstance::UpdatePointInstance - pGrnLODController->GetModelInstance() is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
D3DXMATRIX * pmatBone = (D3DXMATRIX *)pModelInstance->GetBoneMatrixPointer(pPointInstance->dwBoneIndex);
|
||||
matBone = *(D3DXMATRIX *)pModelInstance->GetCompositeBoneMatrixPointer(pPointInstance->dwBoneIndex);
|
||||
matBone._41 = pmatBone->_41;
|
||||
matBone._42 = pmatBone->_42;
|
||||
matBone._43 = pmatBone->_43;
|
||||
matBone *= m_worldMatrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
matBone = m_worldMatrix;
|
||||
}
|
||||
|
||||
// Update Collsion Sphere
|
||||
CSphereCollisionInstanceVector::const_iterator sit = pPointInstance->c_pCollisionData->SphereDataVector.begin();
|
||||
CDynamicSphereInstanceVector::iterator dit=pPointInstance->SphereInstanceVector.begin();
|
||||
for (;sit!=pPointInstance->c_pCollisionData->SphereDataVector.end();++sit,++dit)
|
||||
{
|
||||
const TSphereData & c = sit->GetAttribute();//c_pCollisionData->SphereDataVector[j].GetAttribute();
|
||||
|
||||
D3DXMATRIX matPoint;
|
||||
D3DXMatrixTranslation(&matPoint, c.v3Position.x, c.v3Position.y, c.v3Position.z);
|
||||
matPoint = matPoint * matBone;
|
||||
|
||||
dit->v3LastPosition = dit->v3Position;
|
||||
dit->v3Position.x = matPoint._41;
|
||||
dit->v3Position.y = matPoint._42;
|
||||
dit->v3Position.z = matPoint._43;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::UpdateAdvancingPointInstance()
|
||||
{
|
||||
// 말을 탔을 경우 사람은 이동값을 가지고 있지 않기 때문에 말로 부터 얻어와야 한다 - [levites]
|
||||
D3DXVECTOR3 v3Movement = m_v3Movement;
|
||||
if (m_pkHorse)
|
||||
v3Movement = m_pkHorse->m_v3Movement;
|
||||
|
||||
// 말은 업데이트 하지 않아도 된다 - [levites]
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->UpdateAdvancingPointInstance();
|
||||
|
||||
D3DXMATRIX matPoint;
|
||||
D3DXMATRIX matCenter;
|
||||
|
||||
TCollisionPointInstanceListIterator itor = m_BodyPointInstanceList.begin();
|
||||
for (; itor != m_BodyPointInstanceList.end(); ++itor)
|
||||
{
|
||||
TCollisionPointInstance & rInstance = *itor;
|
||||
|
||||
if (rInstance.isAttached)
|
||||
{
|
||||
if (rInstance.dwModelIndex>=m_LODControllerVector.size())
|
||||
{
|
||||
Tracenf("CActorInstance::UpdateAdvancingPointInstance - rInstance.dwModelIndex=%d >= m_LODControllerVector.size()=%d",
|
||||
rInstance.dwModelIndex, m_LODControllerVector.size());
|
||||
continue;
|
||||
}
|
||||
|
||||
CGrannyLODController* pGrnLODController=m_LODControllerVector[rInstance.dwModelIndex];
|
||||
if (!pGrnLODController)
|
||||
{
|
||||
Tracenf("CActorInstance::UpdateAdvancingPointInstance - m_LODControllerVector[rInstance.dwModelIndex=%d] is NULL", rInstance.dwModelIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
CGrannyModelInstance * pModelInstance = pGrnLODController->GetModelInstance();
|
||||
if (!pModelInstance)
|
||||
{
|
||||
//Tracenf("CActorInstance::UpdateAdvancingPointInstance - pGrnLODController->GetModelInstance() is NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
matCenter = *(D3DXMATRIX *)pModelInstance->GetBoneMatrixPointer(rInstance.dwBoneIndex);
|
||||
matCenter *= m_worldMatrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
matCenter = m_worldMatrix;
|
||||
}
|
||||
|
||||
// Update Collision Sphere
|
||||
const NRaceData::TCollisionData * c_pCollisionData = rInstance.c_pCollisionData;
|
||||
if (c_pCollisionData)
|
||||
{
|
||||
for (DWORD j = 0; j < c_pCollisionData->SphereDataVector.size(); ++j)
|
||||
{
|
||||
const TSphereData & c = c_pCollisionData->SphereDataVector[j].GetAttribute();
|
||||
CDynamicSphereInstance & rSphereInstance = rInstance.SphereInstanceVector[j];
|
||||
|
||||
D3DXMatrixTranslation(&matPoint, c.v3Position.x, c.v3Position.y, c.v3Position.z);
|
||||
matPoint = matPoint * matCenter;
|
||||
|
||||
rSphereInstance.v3LastPosition.x = matPoint._41;
|
||||
rSphereInstance.v3LastPosition.y = matPoint._42;
|
||||
rSphereInstance.v3LastPosition.z = matPoint._43;
|
||||
rSphereInstance.v3Position = rSphereInstance.v3LastPosition;
|
||||
rSphereInstance.v3Position += v3Movement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CActorInstance::CheckCollisionDetection(const CDynamicSphereInstanceVector * c_pAttackingSphereVector, D3DXVECTOR3 * pv3Position)
|
||||
{
|
||||
if (!c_pAttackingSphereVector)
|
||||
{
|
||||
assert(!"CActorInstance::CheckCollisionDetection - c_pAttackingSphereVector is NULL"); // 레퍼런스로 교체하시오
|
||||
return false;
|
||||
}
|
||||
|
||||
TCollisionPointInstanceListIterator itor;
|
||||
for (itor = m_DefendingPointInstanceList.begin(); itor != m_DefendingPointInstanceList.end(); ++itor)
|
||||
{
|
||||
const CDynamicSphereInstanceVector * c_pDefendingSphereVector = &(*itor).SphereInstanceVector;
|
||||
|
||||
for (DWORD i = 0; i < c_pAttackingSphereVector->size(); ++i)
|
||||
for (DWORD j = 0; j < c_pDefendingSphereVector->size(); ++j)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rAttackingSphere = c_pAttackingSphereVector->at(i);
|
||||
const CDynamicSphereInstance & c_rDefendingSphere = c_pDefendingSphereVector->at(j);
|
||||
|
||||
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rAttackingSphere, c_rDefendingSphere))
|
||||
{
|
||||
// FIXME : 두 원의 교점을 찾아내는 식으로 바꿔야 한다.
|
||||
*pv3Position = (c_rAttackingSphere.v3Position + c_rDefendingSphere.v3Position) / 2.0f;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::CreateCollisionInstancePiece(DWORD dwAttachingModelIndex, const NRaceData::TAttachingData * c_pAttachingData, TCollisionPointInstance * pPointInstance)
|
||||
{
|
||||
if (!c_pAttachingData)
|
||||
{
|
||||
assert(!"CActorInstance::CreateCollisionInstancePiece - c_pAttachingData is NULL"); // 레퍼런스로 교체하시오
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!c_pAttachingData->pCollisionData)
|
||||
{
|
||||
assert(!"CActorInstance::CreateCollisionInstancePiece - c_pAttachingData->pCollisionData is NULL"); // 레퍼런스로 교체하시오
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pPointInstance)
|
||||
{
|
||||
assert(!"CActorInstance::CreateCollisionInstancePiece - pPointInstance is NULL"); // 레퍼런스로 교체하시오
|
||||
return false;
|
||||
}
|
||||
|
||||
pPointInstance->dwModelIndex = dwAttachingModelIndex;
|
||||
pPointInstance->isAttached = FALSE;
|
||||
pPointInstance->dwBoneIndex = 0;
|
||||
pPointInstance->c_pCollisionData = c_pAttachingData->pCollisionData;
|
||||
|
||||
if (c_pAttachingData->isAttaching)
|
||||
{
|
||||
int iAttachingBoneIndex;
|
||||
|
||||
CGrannyModelInstance * pModelInstance = m_LODControllerVector[dwAttachingModelIndex]->GetModelInstance();
|
||||
|
||||
if (pModelInstance && pModelInstance->GetBoneIndexByName(c_pAttachingData->strAttachingBoneName.c_str(),
|
||||
&iAttachingBoneIndex))
|
||||
{
|
||||
pPointInstance->isAttached = TRUE;
|
||||
pPointInstance->dwBoneIndex = iAttachingBoneIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
//TraceError("CActorInstance::CreateCollisionInstancePiece: Cannot get matrix of bone %s ModelInstance 0x%p", c_pAttachingData->strAttachingBoneName.c_str(), pModelInstance);
|
||||
pPointInstance->isAttached = TRUE;
|
||||
pPointInstance->dwBoneIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const CSphereCollisionInstanceVector & c_rSphereDataVector = c_pAttachingData->pCollisionData->SphereDataVector;
|
||||
|
||||
pPointInstance->SphereInstanceVector.clear();
|
||||
pPointInstance->SphereInstanceVector.reserve(c_rSphereDataVector.size());
|
||||
|
||||
CSphereCollisionInstanceVector::const_iterator it;
|
||||
CDynamicSphereInstance dsi;
|
||||
|
||||
dsi.v3LastPosition = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
dsi.v3Position = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
for (it = c_rSphereDataVector.begin(); it!=c_rSphereDataVector.end(); ++it)
|
||||
{
|
||||
const TSphereData & c_rSphereData = it->GetAttribute();
|
||||
dsi.fRadius = c_rSphereData.fRadius;
|
||||
pPointInstance->SphereInstanceVector.push_back(dsi);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL CActorInstance::__SplashAttackProcess(CActorInstance & rVictim)
|
||||
{
|
||||
D3DXVECTOR3 v3Distance(rVictim.m_x - m_x, rVictim.m_z - m_z, rVictim.m_z - m_z);
|
||||
float fDistance = D3DXVec3LengthSq(&v3Distance);
|
||||
if (fDistance >= 1000.0f*1000.0f)
|
||||
return FALSE;
|
||||
|
||||
// Check Distance
|
||||
if (!__IsInSplashTime())
|
||||
return FALSE;
|
||||
|
||||
const CRaceMotionData::TMotionAttackingEventData * c_pAttackingEvent = m_kSplashArea.c_pAttackingEvent;
|
||||
const NRaceData::TAttackData & c_rAttackData = c_pAttackingEvent->AttackData;
|
||||
THittedInstanceMap & rHittedInstanceMap = m_kSplashArea.HittedInstanceMap;
|
||||
|
||||
// NOTE : 이미 때렸다면 때릴 수 없음
|
||||
if (rHittedInstanceMap.end() != rHittedInstanceMap.find(&rVictim))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// NOTE : Snipe 모드이고..
|
||||
if (NRaceData::ATTACK_TYPE_SNIPE == c_rAttackData.iAttackType)
|
||||
{
|
||||
// Target 이 PC 라면..
|
||||
if (__IsFlyTargetPC())
|
||||
// 다른 객체는 때릴 수 없다
|
||||
if (!__IsSameFlyTarget(&rVictim))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
if (IsFlyTargetObject())
|
||||
{
|
||||
CActorInstance * pActorInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
|
||||
|
||||
// NOTE : Target 이 PC 일때는 한명만 때릴 수 있다.
|
||||
if (pActorInstance->IsPC())
|
||||
if (&rVictim != pActorInstance)
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
D3DXVECTOR3 v3HitPosition;
|
||||
if (rVictim.CheckCollisionDetection(&m_kSplashArea.SphereInstanceVector, &v3HitPosition))
|
||||
{
|
||||
rHittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+c_rAttackData.fInvisibleTime));
|
||||
|
||||
int iCurrentHitCount = rHittedInstanceMap.size();
|
||||
int iMaxHitCount = (0 == c_rAttackData.iHitLimitCount ? 16 : c_rAttackData.iHitLimitCount);
|
||||
//Tracef(" ------------------- Splash Hit : %d\n", iCurrentHitCount);
|
||||
|
||||
if (iCurrentHitCount > iMaxHitCount)
|
||||
{
|
||||
//Tracef(" ------------------- OVER FLOW :: Splash Hit Count : %d\n", iCurrentHitCount);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NEW_SetAtkPixelPosition(NEW_GetCurPixelPositionRef());
|
||||
__ProcessDataAttackSuccess(c_rAttackData, rVictim, v3HitPosition, m_kSplashArea.uSkill, m_kSplashArea.isEnableHitProcess);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::__NormalAttackProcess(CActorInstance & rVictim)
|
||||
{
|
||||
// Check Distance
|
||||
// NOTE - 일단 근접 체크만 하고 있음
|
||||
D3DXVECTOR3 v3Distance(rVictim.m_x - m_x, rVictim.m_z - m_z, rVictim.m_z - m_z);
|
||||
float fDistance = D3DXVec3LengthSq(&v3Distance);
|
||||
|
||||
extern bool IS_HUGE_RACE(unsigned int vnum);
|
||||
if (IS_HUGE_RACE(rVictim.GetRace()))
|
||||
{
|
||||
if (fDistance >= 500.0f*500.0f)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fDistance >= 300.0f*300.0f)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!isValidAttacking())
|
||||
return FALSE;
|
||||
|
||||
const float c_fAttackRadius = 20.0f;
|
||||
const NRaceData::TMotionAttackData * pad = m_pkCurRaceMotionData->GetMotionAttackDataPointer();
|
||||
|
||||
const float motiontime = GetAttackingElapsedTime();
|
||||
|
||||
NRaceData::THitDataContainer::const_iterator itorHitData = pad->HitDataContainer.begin();
|
||||
for (; itorHitData != pad->HitDataContainer.end(); ++itorHitData)
|
||||
{
|
||||
const NRaceData::THitData & c_rHitData = *itorHitData;
|
||||
|
||||
// NOTE : 이미 맞았는지 체크
|
||||
THitDataMap::iterator itHitData = m_HitDataMap.find(&c_rHitData);
|
||||
if (itHitData != m_HitDataMap.end())
|
||||
{
|
||||
THittedInstanceMap & rHittedInstanceMap = itHitData->second;
|
||||
|
||||
THittedInstanceMap::iterator itInstance;
|
||||
if ((itInstance=rHittedInstanceMap.find(&rVictim)) != rHittedInstanceMap.end())
|
||||
{
|
||||
if (pad->iMotionType==NRaceData::MOTION_TYPE_COMBO || itInstance->second > GetLocalTime())
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
NRaceData::THitTimePositionMap::const_iterator range_start, range_end;
|
||||
range_start = c_rHitData.mapHitPosition.lower_bound(motiontime-CTimer::Instance().GetElapsedSecond());
|
||||
range_end = c_rHitData.mapHitPosition.upper_bound(motiontime);
|
||||
float c = cosf(D3DXToRadian(GetRotation()));
|
||||
float s = sinf(D3DXToRadian(GetRotation()));
|
||||
|
||||
for(;range_start!=range_end;++range_start)
|
||||
{
|
||||
const CDynamicSphereInstance& dsiSrc=range_start->second;
|
||||
|
||||
CDynamicSphereInstance dsi;
|
||||
dsi = dsiSrc;
|
||||
dsi.fRadius = c_fAttackRadius;
|
||||
{
|
||||
D3DXVECTOR3 v3SrcDir=dsiSrc.v3Position-dsiSrc.v3LastPosition;
|
||||
v3SrcDir*=__GetReachScale();
|
||||
|
||||
const D3DXVECTOR3& v3Src = dsiSrc.v3LastPosition+v3SrcDir;
|
||||
D3DXVECTOR3& v3Dst = dsi.v3Position;
|
||||
v3Dst.x = v3Src.x * c - v3Src.y * s;
|
||||
v3Dst.y = v3Src.x * s + v3Src.y * c;
|
||||
v3Dst += GetPosition();
|
||||
}
|
||||
{
|
||||
const D3DXVECTOR3& v3Src = dsiSrc.v3LastPosition;
|
||||
D3DXVECTOR3& v3Dst = dsi.v3LastPosition;
|
||||
v3Dst.x = v3Src.x * c - v3Src.y * s;
|
||||
v3Dst.y = v3Src.x * s + v3Src.y * c;
|
||||
v3Dst += GetPosition();
|
||||
}
|
||||
|
||||
|
||||
TCollisionPointInstanceList::iterator cpit;
|
||||
for(cpit = rVictim.m_DefendingPointInstanceList.begin(); cpit!=rVictim.m_DefendingPointInstanceList.end();++cpit)
|
||||
{
|
||||
int index = 0;
|
||||
const CDynamicSphereInstanceVector & c_DefendingSphereVector = cpit->SphereInstanceVector;
|
||||
CDynamicSphereInstanceVector::const_iterator dsit;
|
||||
for(dsit = c_DefendingSphereVector.begin(); dsit!= c_DefendingSphereVector.end();++dsit, ++index)
|
||||
{
|
||||
const CDynamicSphereInstance& sub = *dsit;
|
||||
if (DetectCollisionDynamicZCylinderVSDynamicZCylinder(dsi, sub))
|
||||
{
|
||||
THitDataMap::iterator itHitData = m_HitDataMap.find(&c_rHitData);
|
||||
if (itHitData == m_HitDataMap.end())
|
||||
{
|
||||
THittedInstanceMap HittedInstanceMap;
|
||||
HittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+pad->fInvisibleTime));
|
||||
//HittedInstanceMap.insert(std::make_pair(&rVictim, GetLocalTime()+HIT_COOL_TIME));
|
||||
m_HitDataMap.insert(std::make_pair(&c_rHitData, HittedInstanceMap));
|
||||
|
||||
//Tracef(" ----------- First Hit\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
itHitData->second.insert(std::make_pair(&rVictim, GetLocalTime()+pad->fInvisibleTime));
|
||||
//itHitData->second.insert(std::make_pair(&rVictim, GetLocalTime()+HIT_COOL_TIME));
|
||||
|
||||
//Tracef(" ----------- Next Hit : %d\n", itHitData->second.size());
|
||||
|
||||
int iCurrentHitCount = itHitData->second.size();
|
||||
// NOTE : 보통 공격은 16명이 한계
|
||||
if (NRaceData::MOTION_TYPE_COMBO == pad->iMotionType || NRaceData::MOTION_TYPE_NORMAL == pad->iMotionType)
|
||||
{
|
||||
if (iCurrentHitCount > 16)
|
||||
{
|
||||
//Tracef(" Type NORMAL :: Overflow - Can't process, skip\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iCurrentHitCount > pad->iHitLimitCount)
|
||||
{
|
||||
//Tracef(" Type SKILL :: Overflow - Can't process, skip\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D3DXVECTOR3 v3HitPosition = (GetPosition() + rVictim.GetPosition()) *0.5f;
|
||||
|
||||
// #0000780: [M2KR] 수룡 타격구 문제
|
||||
extern bool IS_HUGE_RACE(unsigned int vnum);
|
||||
if (IS_HUGE_RACE(rVictim.GetRace()))
|
||||
{
|
||||
v3HitPosition = (GetPosition() + sub.v3Position) * 0.5f;
|
||||
}
|
||||
|
||||
__ProcessDataAttackSuccess(*pad, rVictim, v3HitPosition, m_kCurMotNode.uSkill);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::AttackingProcess(CActorInstance & rVictim)
|
||||
{
|
||||
if (rVictim.__isInvisible())
|
||||
return FALSE;
|
||||
|
||||
if (__SplashAttackProcess(rVictim))
|
||||
return TRUE;
|
||||
|
||||
if (__NormalAttackProcess(rVictim))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::TestPhysicsBlendingCollision(CActorInstance & rVictim)
|
||||
{
|
||||
if (rVictim.IsDead())
|
||||
return FALSE;
|
||||
|
||||
TPixelPosition kPPosLast;
|
||||
GetBlendingPosition( &kPPosLast );
|
||||
|
||||
D3DXVECTOR3 v3Distance = D3DXVECTOR3(rVictim.m_x - kPPosLast.x, rVictim.m_y - kPPosLast.y, rVictim.m_z - kPPosLast.z);
|
||||
float fDistance = D3DXVec3LengthSq(&v3Distance);
|
||||
if (fDistance > 800.0f*800.0f)
|
||||
return FALSE;
|
||||
|
||||
// NOTE : 공격 중일때는 Defending Sphere로 Collision Check를 합니다.
|
||||
// NOTE : Wait로 블렌딩 되는 도중에 뚫고 들어가는 문제가 있어서.. - [levites]
|
||||
TCollisionPointInstanceList * pMainList;
|
||||
TCollisionPointInstanceList * pVictimList;
|
||||
if (isAttacking() || IsWaiting())
|
||||
{
|
||||
pMainList = &m_DefendingPointInstanceList;
|
||||
pVictimList = &rVictim.m_DefendingPointInstanceList;
|
||||
}
|
||||
else
|
||||
{
|
||||
pMainList = &m_BodyPointInstanceList;
|
||||
pVictimList = &rVictim.m_BodyPointInstanceList;
|
||||
}
|
||||
|
||||
TPixelPosition kPDelta;
|
||||
m_PhysicsObject.GetLastPosition(&kPDelta);
|
||||
|
||||
D3DXVECTOR3 prevLastPosition, prevPosition;
|
||||
const int nSubCheckCount = 50;
|
||||
|
||||
TCollisionPointInstanceListIterator itorMain = pMainList->begin();
|
||||
TCollisionPointInstanceListIterator itorVictim = pVictimList->begin();
|
||||
for (; itorMain != pMainList->end(); ++itorMain)
|
||||
{
|
||||
for (; itorVictim != pVictimList->end(); ++itorVictim)
|
||||
{
|
||||
CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
|
||||
CDynamicSphereInstanceVector & c_rVictimSphereVector = (*itorVictim).SphereInstanceVector;
|
||||
|
||||
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
|
||||
{
|
||||
CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
|
||||
//adjust main sphere center
|
||||
prevLastPosition = c_rMainSphere.v3LastPosition;
|
||||
prevPosition = c_rMainSphere.v3Position;
|
||||
|
||||
c_rMainSphere.v3LastPosition = prevPosition;
|
||||
|
||||
for( int i = 1; i <= nSubCheckCount; ++ i )
|
||||
{
|
||||
c_rMainSphere.v3Position = prevPosition + (float)(i/(float)nSubCheckCount) * kPDelta;
|
||||
|
||||
for (DWORD j = 0; j < c_rVictimSphereVector.size(); ++j)
|
||||
{
|
||||
CDynamicSphereInstance & c_rVictimSphere = c_rVictimSphereVector[j];
|
||||
|
||||
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, c_rVictimSphere))
|
||||
{
|
||||
BOOL bResult = GetVector3Distance(c_rMainSphere.v3Position, c_rVictimSphere.v3Position) <= GetVector3Distance(c_rMainSphere.v3LastPosition, c_rVictimSphere.v3Position);
|
||||
|
||||
c_rMainSphere.v3LastPosition = prevLastPosition;
|
||||
c_rMainSphere.v3Position = prevPosition;
|
||||
|
||||
return bResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//restore
|
||||
c_rMainSphere.v3LastPosition = prevLastPosition;
|
||||
c_rMainSphere.v3Position = prevPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CActorInstance::TestActorCollision(CActorInstance & rVictim)
|
||||
{
|
||||
/*
|
||||
if (m_pkHorse)
|
||||
{
|
||||
if (m_pkHorse->TestActorCollision(rVictim))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
if (rVictim.IsDead())
|
||||
return FALSE;
|
||||
|
||||
// Check Distance
|
||||
// NOTE : 적당히 멀면 체크 안함
|
||||
// 프레임 스킵시나 대상 오브젝트의 크기가 클경우 문제가 생길 여지가 있음
|
||||
// 캐릭터가 자신의 Body Sphere Radius 보다 더 크게 이동했는지를 체크하고,
|
||||
// 만약 그렇지 않다면 거리로 체크해서 걸러준다.
|
||||
D3DXVECTOR3 v3Distance = D3DXVECTOR3(rVictim.m_x - m_x, rVictim.m_y - m_y, rVictim.m_z - m_z);
|
||||
float fDistance = D3DXVec3LengthSq(&v3Distance);
|
||||
if (fDistance > 800.0f*800.0f)
|
||||
return FALSE;
|
||||
|
||||
// NOTE : 공격 중일때는 Defending Sphere로 Collision Check를 합니다.
|
||||
// NOTE : Wait로 블렌딩 되는 도중에 뚫고 들어가는 문제가 있어서.. - [levites]
|
||||
TCollisionPointInstanceList * pMainList;
|
||||
TCollisionPointInstanceList * pVictimList;
|
||||
if (isAttacking() || IsWaiting())
|
||||
{
|
||||
pMainList = &m_DefendingPointInstanceList;
|
||||
pVictimList = &rVictim.m_DefendingPointInstanceList;
|
||||
}
|
||||
else
|
||||
{
|
||||
pMainList = &m_BodyPointInstanceList;
|
||||
pVictimList = &rVictim.m_BodyPointInstanceList;
|
||||
}
|
||||
|
||||
TCollisionPointInstanceListIterator itorMain = pMainList->begin();
|
||||
TCollisionPointInstanceListIterator itorVictim = pVictimList->begin();
|
||||
for (; itorMain != pMainList->end(); ++itorMain)
|
||||
for (; itorVictim != pVictimList->end(); ++itorVictim)
|
||||
{
|
||||
const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
|
||||
const CDynamicSphereInstanceVector & c_rVictimSphereVector = (*itorVictim).SphereInstanceVector;
|
||||
|
||||
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
|
||||
for (DWORD j = 0; j < c_rVictimSphereVector.size(); ++j)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
|
||||
const CDynamicSphereInstance & c_rVictimSphere = c_rVictimSphereVector[j];
|
||||
|
||||
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, c_rVictimSphere))
|
||||
{
|
||||
if (GetVector3Distance(c_rMainSphere.v3Position, c_rVictimSphere.v3Position) <=
|
||||
GetVector3Distance(c_rMainSphere.v3LastPosition, c_rVictimSphere.v3Position))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool CActorInstance::AvoidObject(const CGraphicObjectInstance& c_rkBGObj)
|
||||
{
|
||||
#ifdef __MOVIE_MODE__
|
||||
if (IsMovieMode())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (this==&c_rkBGObj)
|
||||
return false;
|
||||
|
||||
if (!__TestObjectCollision(&c_rkBGObj))
|
||||
return false;
|
||||
|
||||
__AdjustCollisionMovement(&c_rkBGObj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsBlockObject(const CGraphicObjectInstance& c_rkBGObj)
|
||||
{
|
||||
if (this==&c_rkBGObj)
|
||||
return false;
|
||||
|
||||
if (!__TestObjectCollision(&c_rkBGObj))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CActorInstance::BlockMovement()
|
||||
{
|
||||
if (m_pkHorse)
|
||||
{
|
||||
m_pkHorse->__InitializeMovement();
|
||||
return;
|
||||
}
|
||||
|
||||
__InitializeMovement();
|
||||
}
|
||||
|
||||
BOOL CActorInstance::__TestObjectCollision(const CGraphicObjectInstance * c_pObjectInstance)
|
||||
{
|
||||
if (m_pkHorse)
|
||||
{
|
||||
if (m_pkHorse->__TestObjectCollision(c_pObjectInstance))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (m_canSkipCollision)
|
||||
return FALSE;
|
||||
|
||||
if (m_v3Movement.x == 0.0f && m_v3Movement.y == 0.0f && m_v3Movement.z == 0.0f)
|
||||
return FALSE;
|
||||
|
||||
TCollisionPointInstanceListIterator itorMain = m_BodyPointInstanceList.begin();
|
||||
for (; itorMain != m_BodyPointInstanceList.end(); ++itorMain)
|
||||
{
|
||||
const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
|
||||
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
|
||||
|
||||
if (c_pObjectInstance->MovementCollisionDynamicSphere(c_rMainSphere))
|
||||
{
|
||||
//const D3DXVECTOR3 & c_rv3Position = c_pObjectInstance->GetPosition();
|
||||
//if (GetVector3Distance(c_rMainSphere.v3Position, c_rv3Position) <
|
||||
// GetVector3Distance(c_rMainSphere.v3LastPosition, c_rv3Position))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool CActorInstance::TestCollisionWithDynamicSphere(const CDynamicSphereInstance & dsi)
|
||||
{
|
||||
TCollisionPointInstanceListIterator itorMain = m_BodyPointInstanceList.begin();
|
||||
for (; itorMain != m_BodyPointInstanceList.end(); ++itorMain)
|
||||
{
|
||||
const CDynamicSphereInstanceVector & c_rMainSphereVector = (*itorMain).SphereInstanceVector;
|
||||
for (DWORD i = 0; i < c_rMainSphereVector.size(); ++i)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rMainSphere = c_rMainSphereVector[i];
|
||||
|
||||
if (DetectCollisionDynamicSphereVSDynamicSphere(c_rMainSphere, dsi))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
#include "RaceManager.h"
|
||||
#include "ItemManager.h"
|
||||
#include "RaceData.h"
|
||||
|
||||
#include "../eterlib/ResourceManager.h"
|
||||
#include "../etergrnlib/util.h"
|
||||
|
||||
DWORD CActorInstance::GetVirtualID()
|
||||
{
|
||||
return m_dwSelfVID;
|
||||
}
|
||||
|
||||
void CActorInstance::SetVirtualID(DWORD dwVID)
|
||||
{
|
||||
m_dwSelfVID=dwVID;
|
||||
}
|
||||
|
||||
void CActorInstance::UpdateAttribute()
|
||||
{
|
||||
if (!m_pAttributeInstance)
|
||||
return;
|
||||
|
||||
if (!m_bNeedUpdateCollision)
|
||||
return;
|
||||
|
||||
m_bNeedUpdateCollision = FALSE;
|
||||
|
||||
const CStaticCollisionDataVector & c_rkVec_ColliData = m_pAttributeInstance->GetObjectPointer()->GetCollisionDataVector();
|
||||
UpdateCollisionData(&c_rkVec_ColliData);
|
||||
|
||||
m_pAttributeInstance->RefreshObject(GetTransform());
|
||||
UpdateHeightInstance(m_pAttributeInstance);
|
||||
|
||||
//BOOL isHeightData = m_pAttributeInstance->IsEmpty();
|
||||
}
|
||||
|
||||
void CActorInstance::__CreateAttributeInstance(CAttributeData * pData)
|
||||
{
|
||||
m_pAttributeInstance = CAttributeInstance::New();
|
||||
m_pAttributeInstance->Clear();
|
||||
m_pAttributeInstance->SetObjectPointer(pData);
|
||||
if (pData->IsEmpty())
|
||||
{
|
||||
m_pAttributeInstance->Clear();
|
||||
CAttributeInstance::Delete(m_pAttributeInstance);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CActorInstance::GetRace()
|
||||
{
|
||||
return m_eRace;
|
||||
}
|
||||
|
||||
bool CActorInstance::SetRace(DWORD eRace)
|
||||
{
|
||||
CRaceData * pRaceData;
|
||||
if (!CRaceManager::Instance().GetRaceDataPointer(eRace, &pRaceData))
|
||||
{
|
||||
m_eRace=0;
|
||||
m_pkCurRaceData=NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_eRace=eRace;
|
||||
m_pkCurRaceData = pRaceData;
|
||||
|
||||
CAttributeData * pAttributeData = pRaceData->GetAttributeDataPtr();
|
||||
if (pAttributeData)
|
||||
{
|
||||
__CreateAttributeInstance(pAttributeData);
|
||||
}
|
||||
|
||||
memset(m_adwPartItemID, 0, sizeof(m_adwPartItemID));
|
||||
|
||||
// Setup Graphic ResourceData
|
||||
__ClearAttachingEffect();
|
||||
|
||||
CGraphicThingInstance::Clear();
|
||||
|
||||
//NOTE : PC만 Part별로 다 생성하게 해준다.
|
||||
if( IsPC())
|
||||
{
|
||||
CGraphicThingInstance::ReserveModelThing(CRaceData::PART_MAX_NUM);
|
||||
CGraphicThingInstance::ReserveModelInstance(CRaceData::PART_MAX_NUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGraphicThingInstance::ReserveModelThing(1);
|
||||
CGraphicThingInstance::ReserveModelInstance(1);
|
||||
}
|
||||
|
||||
|
||||
CRaceData::TMotionModeDataIterator itor;
|
||||
|
||||
if (pRaceData->CreateMotionModeIterator(itor))
|
||||
{
|
||||
do
|
||||
{
|
||||
WORD wMotionMode = itor->first;
|
||||
CRaceData::TMotionModeData * pMotionModeData = itor->second;
|
||||
|
||||
CRaceData::TMotionVectorMap::iterator itorMotion = pMotionModeData->MotionVectorMap.begin();
|
||||
for (; itorMotion != pMotionModeData->MotionVectorMap.end(); ++itorMotion)
|
||||
{
|
||||
WORD wMotionIndex = itorMotion->first;
|
||||
const CRaceData::TMotionVector & c_rMotionVector = itorMotion->second;
|
||||
CRaceData::TMotionVector::const_iterator it;
|
||||
DWORD i;
|
||||
for (i = 0, it = c_rMotionVector.begin(); it != c_rMotionVector.end(); ++i, ++it)
|
||||
{
|
||||
DWORD dwMotionKey = MAKE_RANDOM_MOTION_KEY(wMotionMode, wMotionIndex, i);
|
||||
CGraphicThingInstance::RegisterMotionThing(dwMotionKey, it->pMotion);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (pRaceData->NextMotionModeIterator(itor));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CActorInstance::SetHair(DWORD eHair)
|
||||
{
|
||||
m_eHair = eHair;
|
||||
|
||||
CRaceData * pRaceData;
|
||||
|
||||
if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pRaceData))
|
||||
return;
|
||||
|
||||
CRaceData::SHair* pkHair=pRaceData->FindHair(eHair);
|
||||
if (pkHair)
|
||||
{
|
||||
if (!pkHair->m_stModelFileName.empty())
|
||||
{
|
||||
CGraphicThing * pkHairThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(pkHair->m_stModelFileName.c_str());
|
||||
RegisterModelThing(CRaceData::PART_HAIR, pkHairThing);
|
||||
SetModelInstance(CRaceData::PART_HAIR, CRaceData::PART_HAIR, 0, CRaceData::PART_MAIN);
|
||||
}
|
||||
|
||||
const std::vector<CRaceData::SSkin>& c_rkVct_kSkin = pkHair->m_kVct_kSkin;
|
||||
std::vector<CRaceData::SSkin>::const_iterator i;
|
||||
for (i = c_rkVct_kSkin.begin(); i != c_rkVct_kSkin.end(); ++i)
|
||||
{
|
||||
const CRaceData::SSkin& c_rkSkinItem = *i;
|
||||
|
||||
CResource * pkRes = CResourceManager::Instance().GetResourcePointer(c_rkSkinItem.m_stDstFileName.c_str());
|
||||
|
||||
if (pkRes)
|
||||
SetMaterialImagePointer(CRaceData::PART_HAIR, c_rkSkinItem.m_stSrcFileName.c_str(), static_cast<CGraphicImage*>(pkRes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CActorInstance::SetShape(DWORD eShape, float fSpecular)
|
||||
{
|
||||
m_eShape = eShape;
|
||||
|
||||
CRaceData * pRaceData;
|
||||
if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pRaceData))
|
||||
return;
|
||||
|
||||
CRaceData::SShape* pkShape=pRaceData->FindShape(eShape);
|
||||
if (pkShape)
|
||||
{
|
||||
CResourceManager& rkResMgr=CResourceManager::Instance();
|
||||
|
||||
if (pkShape->m_stModelFileName.empty())
|
||||
{
|
||||
CGraphicThing* pModelThing = pRaceData->GetBaseModelThing();
|
||||
RegisterModelThing(0, pModelThing);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGraphicThing* pModelThing = (CGraphicThing *)rkResMgr.GetResourcePointer(pkShape->m_stModelFileName.c_str());
|
||||
RegisterModelThing(0, pModelThing);
|
||||
}
|
||||
|
||||
{
|
||||
std::string stLODModelFileName;
|
||||
|
||||
char szLODModelFileNameEnd[256];
|
||||
for (UINT uLODIndex=1; uLODIndex<=3; ++uLODIndex)
|
||||
{
|
||||
sprintf(szLODModelFileNameEnd, "_lod_%.2d.gr2", uLODIndex);
|
||||
stLODModelFileName = CFileNameHelper::NoExtension(pkShape->m_stModelFileName) + szLODModelFileNameEnd;
|
||||
if (!rkResMgr.IsFileExist(stLODModelFileName.c_str()))
|
||||
break;
|
||||
|
||||
CGraphicThing* pLODModelThing = (CGraphicThing *)rkResMgr.GetResourcePointer(stLODModelFileName.c_str());
|
||||
if (!pLODModelThing)
|
||||
break;
|
||||
|
||||
RegisterLODThing(0, pLODModelThing);
|
||||
}
|
||||
}
|
||||
|
||||
SetModelInstance(0, 0, 0);
|
||||
|
||||
const std::vector<CRaceData::SSkin>& c_rkVct_kSkin = pkShape->m_kVct_kSkin;
|
||||
std::vector<CRaceData::SSkin>::const_iterator i;
|
||||
for (i = c_rkVct_kSkin.begin(); i != c_rkVct_kSkin.end(); ++i)
|
||||
{
|
||||
const CRaceData::SSkin& c_rkSkinItem = *i;
|
||||
|
||||
CResource * pkRes = CResourceManager::Instance().GetResourcePointer(c_rkSkinItem.m_stDstFileName.c_str());
|
||||
|
||||
if (pkRes)
|
||||
{
|
||||
if (fSpecular > 0.0f)
|
||||
{
|
||||
SMaterialData kMaterialData;
|
||||
kMaterialData.pImage = static_cast<CGraphicImage*>(pkRes);
|
||||
kMaterialData.isSpecularEnable = TRUE;
|
||||
kMaterialData.fSpecularPower = fSpecular;
|
||||
kMaterialData.bSphereMapIndex = 0;
|
||||
SetMaterialData(c_rkSkinItem.m_ePart, c_rkSkinItem.m_stSrcFileName.c_str(), kMaterialData);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMaterialImagePointer(c_rkSkinItem.m_ePart, c_rkSkinItem.m_stSrcFileName.c_str(), static_cast<CGraphicImage*>(pkRes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pRaceData->IsTree())
|
||||
{
|
||||
__CreateTree(pRaceData->GetTreeFileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
CGraphicThing* pModelThing = pRaceData->GetBaseModelThing();
|
||||
RegisterModelThing(0, pModelThing);
|
||||
|
||||
CGraphicThing* pLODModelThing = pRaceData->GetLODModelThing();
|
||||
RegisterLODThing(0, pLODModelThing);
|
||||
|
||||
SetModelInstance(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Attaching Objects
|
||||
for (DWORD i = 0; i < pRaceData->GetAttachingDataCount(); ++i)
|
||||
{
|
||||
const NRaceData::TAttachingData * c_pAttachingData;
|
||||
if (!pRaceData->GetAttachingDataPointer(i, &c_pAttachingData))
|
||||
continue;
|
||||
|
||||
switch (c_pAttachingData->dwType)
|
||||
{
|
||||
case NRaceData::ATTACHING_DATA_TYPE_EFFECT:
|
||||
if (c_pAttachingData->isAttaching)
|
||||
{
|
||||
AttachEffectByName(0, c_pAttachingData->strAttachingBoneName.c_str(), c_pAttachingData->pEffectData->strFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachEffectByName(0, 0, c_pAttachingData->pEffectData->strFileName.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::ChangeMaterial(const char * c_szFileName)
|
||||
{
|
||||
CRaceData * pRaceData;
|
||||
if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pRaceData))
|
||||
return;
|
||||
|
||||
CRaceData::SShape* pkShape=pRaceData->FindShape(m_eShape);
|
||||
if (!pkShape)
|
||||
return;
|
||||
|
||||
const std::vector<CRaceData::SSkin>& c_rkVct_kSkin = pkShape->m_kVct_kSkin;
|
||||
if (c_rkVct_kSkin.empty())
|
||||
return;
|
||||
|
||||
std::vector<CRaceData::SSkin>::const_iterator i = c_rkVct_kSkin.begin();
|
||||
const CRaceData::SSkin& c_rkSkinItem = *i;
|
||||
|
||||
std::string dstFileName = "d:/ymir work/npc/guild_symbol/guild_symbol.dds";
|
||||
dstFileName = c_szFileName;
|
||||
|
||||
CResource * pkRes = CResourceManager::Instance().GetResourcePointer(dstFileName.c_str());
|
||||
if (!pkRes)
|
||||
return;
|
||||
|
||||
SetMaterialImagePointer(c_rkSkinItem.m_ePart, c_rkSkinItem.m_stSrcFileName.c_str(), static_cast<CGraphicImage*>(pkRes));
|
||||
}
|
||||
/*
|
||||
void CActorInstance::SetPart(DWORD dwPartIndex, DWORD dwItemID)
|
||||
{
|
||||
if (dwPartIndex>=CRaceData::PART_MAX_NUM)
|
||||
return;
|
||||
|
||||
if (!m_pkCurRaceData)
|
||||
{
|
||||
assert(m_pkCurRaceData);
|
||||
return;
|
||||
}
|
||||
|
||||
CItemData * pItemData;
|
||||
if (!CItemManager::Instance().GetItemDataPointer(dwItemID, &pItemData))
|
||||
return;
|
||||
|
||||
RegisterModelThing(dwPartIndex, pItemData->GetModelThing());
|
||||
for (DWORD i = 0; i < pItemData->GetLODModelThingCount(); ++i)
|
||||
{
|
||||
CGraphicThing * pThing;
|
||||
if (!pItemData->GetLODModelThingPointer(i, &pThing))
|
||||
continue;
|
||||
|
||||
RegisterLODThing(dwPartIndex, pThing);
|
||||
}
|
||||
SetModelInstance(dwPartIndex, dwPartIndex, 0);
|
||||
|
||||
m_adwPartItemID[dwPartIndex] = dwItemID;
|
||||
}
|
||||
*/
|
||||
|
||||
DWORD CActorInstance::GetPartItemID(DWORD dwPartIndex)
|
||||
{
|
||||
if (dwPartIndex>=CRaceData::PART_MAX_NUM)
|
||||
{
|
||||
TraceError("CActorInstance::GetPartIndex(dwPartIndex=%d/CRaceData::PART_MAX_NUM=%d)", dwPartIndex, CRaceData::PART_MAX_NUM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_adwPartItemID[dwPartIndex];
|
||||
}
|
||||
|
||||
void CActorInstance::SetSpecularInfo(BOOL bEnable, int iPart, float fAlpha)
|
||||
{
|
||||
CRaceData * pkRaceData;
|
||||
if (!CRaceManager::Instance().GetRaceDataPointer(m_eRace, &pkRaceData))
|
||||
return;
|
||||
|
||||
CRaceData::SShape * pkShape = pkRaceData->FindShape(m_eShape);
|
||||
if (pkShape->m_kVct_kSkin.empty())
|
||||
return;
|
||||
|
||||
std::string filename = pkShape->m_kVct_kSkin[0].m_stSrcFileName.c_str();
|
||||
CFileNameHelper::ChangeDosPath(filename);
|
||||
|
||||
CGraphicThingInstance::SetSpecularInfo(iPart, filename.c_str(), bEnable, fAlpha);
|
||||
}
|
||||
|
||||
void CActorInstance::SetSpecularInfoForce(BOOL bEnable, int iPart, float fAlpha)
|
||||
{
|
||||
CGraphicThingInstance::SetSpecularInfo(iPart, NULL, bEnable, fAlpha);
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
|
||||
void CActorInstance::__OnSyncing()
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
IEventHandler::SState kState;
|
||||
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
|
||||
kState.fAdvRotSelf=GetAdvancingRotation();
|
||||
rkEventHandler.OnSyncing(kState);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnWaiting()
|
||||
{
|
||||
assert(!IsPushing());
|
||||
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
IEventHandler::SState kState;
|
||||
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
|
||||
kState.fAdvRotSelf=GetAdvancingRotation();
|
||||
rkEventHandler.OnWaiting(kState);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnMoving()
|
||||
{
|
||||
assert(!IsPushing());
|
||||
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
const TPixelPosition& c_rkPPosCur=NEW_GetCurPixelPositionRef();
|
||||
const TPixelPosition& c_rkPPosDst=NEW_GetDstPixelPositionRef();
|
||||
|
||||
TPixelPosition kPPosDir=c_rkPPosDst-c_rkPPosCur;
|
||||
float distance=sqrt(kPPosDir.x*kPPosDir.x+kPPosDir.y*kPPosDir.y);
|
||||
|
||||
IEventHandler::SState kState;
|
||||
|
||||
if (distance>1000.0f)
|
||||
{
|
||||
D3DXVec3Normalize(&kPPosDir, &kPPosDir);
|
||||
D3DXVec3Scale(&kPPosDir, &kPPosDir, 1000.0f);
|
||||
D3DXVec3Add(&kState.kPPosSelf, &kPPosDir, &c_rkPPosCur);
|
||||
}
|
||||
else
|
||||
{
|
||||
kState.kPPosSelf=c_rkPPosDst;
|
||||
}
|
||||
kState.fAdvRotSelf=GetAdvancingRotation();
|
||||
rkEventHandler.OnMoving(kState);
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::__OnMove()
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
IEventHandler::SState kState;
|
||||
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
|
||||
kState.fAdvRotSelf=GetAdvancingRotation();
|
||||
rkEventHandler.OnMove(kState);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnStop()
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
IEventHandler::SState kState;
|
||||
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
|
||||
kState.fAdvRotSelf=GetAdvancingRotation();
|
||||
rkEventHandler.OnStop(kState);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnWarp()
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
IEventHandler::SState kState;
|
||||
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
|
||||
kState.fAdvRotSelf=GetAdvancingRotation();
|
||||
rkEventHandler.OnWarp(kState);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnAttack(WORD wMotionIndex)
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
IEventHandler::SState kState;
|
||||
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
|
||||
kState.fAdvRotSelf=GetTargetRotation();
|
||||
rkEventHandler.OnAttack(kState, wMotionIndex);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnUseSkill(UINT uMotSkill, UINT uLoopCount, bool isMovingSkill)
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
|
||||
IEventHandler::SState kState;
|
||||
kState.kPPosSelf=NEW_GetCurPixelPositionRef();
|
||||
kState.fAdvRotSelf=GetAdvancingRotation();
|
||||
|
||||
UINT uArg=uLoopCount;
|
||||
if (isMovingSkill)
|
||||
uArg|=1<<4;
|
||||
|
||||
rkEventHandler.OnUseSkill(kState, uMotSkill, uArg);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnHit(UINT uSkill, CActorInstance& rkActorVictm, BOOL isSendPacket)
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
rkEventHandler.OnHit(uSkill, rkActorVictm, isSendPacket);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnClearAffects()
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
rkEventHandler.OnClearAffects();
|
||||
}
|
||||
|
||||
void CActorInstance::__OnSetAffect(UINT uAffect)
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
rkEventHandler.OnSetAffect(uAffect);
|
||||
}
|
||||
|
||||
void CActorInstance::__OnResetAffect(UINT uAffect)
|
||||
{
|
||||
IEventHandler& rkEventHandler=__GetEventHandlerRef();
|
||||
rkEventHandler.OnResetAffect(uAffect);
|
||||
}
|
||||
|
||||
|
||||
CActorInstance::IEventHandler& CActorInstance::__GetEventHandlerRef()
|
||||
{
|
||||
assert(m_pkEventHandler!=NULL && "CActorInstance::GetEventHandlerRef");
|
||||
return *m_pkEventHandler;
|
||||
}
|
||||
|
||||
CActorInstance::IEventHandler* CActorInstance::__GetEventHandlerPtr()
|
||||
{
|
||||
return m_pkEventHandler;
|
||||
}
|
||||
|
||||
void CActorInstance::SetEventHandler(IEventHandler* pkEventHandler)
|
||||
{
|
||||
m_pkEventHandler=pkEventHandler;
|
||||
}
|
||||
|
||||
CActorInstance::IEventHandler* CActorInstance::IEventHandler::GetEmptyPtr()
|
||||
{
|
||||
static class CEmptyEventHandler : public IEventHandler
|
||||
{
|
||||
public:
|
||||
CEmptyEventHandler() {}
|
||||
virtual ~CEmptyEventHandler() {}
|
||||
|
||||
virtual void OnSyncing(const SState& c_rkState) {}
|
||||
virtual void OnWaiting(const SState& c_rkState) {}
|
||||
virtual void OnMoving(const SState& c_rkState) {}
|
||||
virtual void OnMove(const SState& c_rkState) {}
|
||||
virtual void OnStop(const SState& c_rkState) {}
|
||||
virtual void OnWarp(const SState& c_rkState) {}
|
||||
|
||||
virtual void OnClearAffects() {}
|
||||
virtual void OnSetAffect(UINT uAffect) {}
|
||||
virtual void OnResetAffect(UINT uAffect) {}
|
||||
|
||||
virtual void OnAttack(const SState& c_rkState, WORD wMotionIndex) {}
|
||||
virtual void OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uMotLoopCount) {}
|
||||
|
||||
virtual void OnHit(UINT uMotAttack, CActorInstance& rkActorVictim, BOOL isSendPacket) {}
|
||||
|
||||
virtual void OnChangeShape() {}
|
||||
|
||||
} s_kEmptyEventHandler;
|
||||
|
||||
return &s_kEmptyEventHandler;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
|
||||
D3DXVECTOR3 CActorInstance::OnGetFlyTargetPosition()
|
||||
{
|
||||
D3DXVECTOR3 v3Center;
|
||||
if (m_fRadius<=0)
|
||||
{
|
||||
BuildBoundingSphere();
|
||||
v3Center = m_v3Center;
|
||||
}
|
||||
else
|
||||
{
|
||||
v3Center = m_v3Center;
|
||||
}
|
||||
|
||||
D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform());
|
||||
return v3Center;
|
||||
}
|
||||
|
||||
void CActorInstance::ClearFlyTarget()
|
||||
{
|
||||
m_kFlyTarget.Clear();
|
||||
m_kBackupFlyTarget.Clear();
|
||||
m_kQue_kFlyTarget.clear();
|
||||
}
|
||||
|
||||
bool CActorInstance::IsFlyTargetObject()
|
||||
{
|
||||
return m_kFlyTarget.IsObject();
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsFlyTargetPC()
|
||||
{
|
||||
if (!IsFlyTargetObject())
|
||||
return false;
|
||||
|
||||
CActorInstance * pFlyInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
|
||||
if (pFlyInstance->IsPC())
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsSameFlyTarget(CActorInstance * pInstance)
|
||||
{
|
||||
if (!IsFlyTargetObject())
|
||||
return false;
|
||||
|
||||
CActorInstance * pFlyInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
|
||||
if (pInstance == pFlyInstance)
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 CActorInstance::__GetFlyTargetPosition()
|
||||
{
|
||||
if (!m_kFlyTarget.IsValidTarget())
|
||||
{
|
||||
return D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
return m_kFlyTarget.GetFlyTargetPosition();
|
||||
}
|
||||
|
||||
float CActorInstance::GetFlyTargetDistance()
|
||||
{
|
||||
const D3DXVECTOR3& c_rv3FlyTargetPos=m_kFlyTarget.GetFlyTargetPosition();
|
||||
const D3DXVECTOR3& c_rkPosSrc=GetPosition();
|
||||
|
||||
D3DXVECTOR3 kPPosDelta=c_rv3FlyTargetPos-c_rkPosSrc;
|
||||
kPPosDelta.z=0;
|
||||
|
||||
return D3DXVec3Length(&kPPosDelta);
|
||||
}
|
||||
|
||||
void CActorInstance::LookAtFlyTarget()
|
||||
{
|
||||
if (!IsFlyTargetObject())
|
||||
return;
|
||||
|
||||
const D3DXVECTOR3& c_rv3FlyTargetPos=m_kFlyTarget.GetFlyTargetPosition();
|
||||
LookAt(c_rv3FlyTargetPos.x, c_rv3FlyTargetPos.y);
|
||||
}
|
||||
|
||||
void CActorInstance::AddFlyTarget(const CFlyTarget & cr_FlyTarget)
|
||||
{
|
||||
if (m_kFlyTarget.IsValidTarget())
|
||||
m_kQue_kFlyTarget.push_back(cr_FlyTarget);
|
||||
else
|
||||
SetFlyTarget(cr_FlyTarget);
|
||||
}
|
||||
|
||||
void CActorInstance::SetFlyTarget(const CFlyTarget & cr_FlyTarget)
|
||||
{
|
||||
m_kFlyTarget = cr_FlyTarget;
|
||||
}
|
||||
|
||||
void CActorInstance::ClearFlyEventHandler()
|
||||
{
|
||||
m_pFlyEventHandler = 0;
|
||||
}
|
||||
|
||||
void CActorInstance::SetFlyEventHandler(IFlyEventHandler * pHandler)
|
||||
{
|
||||
m_pFlyEventHandler = pHandler;
|
||||
}
|
||||
|
||||
// 2004. 07. 07. [levites] - 스킬 사용중 타겟이 바뀌는 문제 해결을 위한 코드
|
||||
bool CActorInstance::CanChangeTarget()
|
||||
{
|
||||
if (__IsNeedFlyTargetMotion())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "../eterGrnLib/ThingInstance.h"
|
||||
|
||||
class IActorInstance : public CGraphicThingInstance
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ID = ACTOR_OBJECT
|
||||
};
|
||||
int GetType() const { return ID; }
|
||||
|
||||
IActorInstance() {}
|
||||
virtual ~IActorInstance() {}
|
||||
virtual bool TestCollisionWithDynamicSphere(const CDynamicSphereInstance & dsi) = 0;
|
||||
virtual DWORD GetVirtualID() = 0;
|
||||
};
|
||||
@@ -0,0 +1,911 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
#include "RaceData.h"
|
||||
#include "FlyHandler.h"
|
||||
|
||||
UINT CActorInstance::__GetMotionType()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return CRaceMotionData::TYPE_NONE;
|
||||
|
||||
return m_pkCurRaceMotionData->GetType();
|
||||
}
|
||||
|
||||
void CActorInstance::__MotionEventProcess(BOOL isPC)
|
||||
{
|
||||
if (isAttacking())
|
||||
{
|
||||
DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS);
|
||||
for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame)
|
||||
{
|
||||
MotionEventProcess();
|
||||
SoundEventProcess(!isPC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MotionEventProcess();
|
||||
SoundEventProcess(!isPC);
|
||||
|
||||
++m_kCurMotNode.dwcurFrame;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::MotionProcess(BOOL isPC)
|
||||
{
|
||||
__MotionEventProcess(isPC);
|
||||
CurrentMotionProcess();
|
||||
ReservingMotionProcess();
|
||||
}
|
||||
|
||||
void CActorInstance::HORSE_MotionProcess(BOOL isPC)
|
||||
{
|
||||
__MotionEventProcess(isPC);
|
||||
|
||||
if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType)
|
||||
if (m_kCurMotNode.dwcurFrame >= m_kCurMotNode.dwFrameCount)
|
||||
m_kCurMotNode.dwcurFrame = 0;
|
||||
}
|
||||
|
||||
void CActorInstance::ReservingMotionProcess()
|
||||
{
|
||||
if (m_MotionDeque.empty())
|
||||
return;
|
||||
|
||||
TReservingMotionNode & rReservingMotionNode = m_MotionDeque.front();
|
||||
|
||||
float fCurrentTime = GetLocalTime();
|
||||
if (rReservingMotionNode.fStartTime > fCurrentTime)
|
||||
return;
|
||||
|
||||
DWORD dwNextMotionIndex = GET_MOTION_INDEX(rReservingMotionNode.dwMotionKey);
|
||||
switch (dwNextMotionIndex)
|
||||
{
|
||||
case CRaceMotionData::NAME_STAND_UP:
|
||||
case CRaceMotionData::NAME_STAND_UP_BACK:
|
||||
if (IsFaint())
|
||||
{
|
||||
//Tracenf("일어서려고 했으나 기절중");
|
||||
|
||||
SetEndStopMotion();
|
||||
|
||||
// 이후의 모션 전부 1초씩 딜레이
|
||||
TMotionDeque::iterator itor = m_MotionDeque.begin();
|
||||
for (; itor != m_MotionDeque.end(); ++itor)
|
||||
{
|
||||
TReservingMotionNode & rNode = *itor;
|
||||
rNode.fStartTime += 1.0f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SCurrentMotionNode kPrevMotionNode=m_kCurMotNode;
|
||||
|
||||
EMotionPushType iMotionType=rReservingMotionNode.iMotionType;
|
||||
float fSpeedRatio=rReservingMotionNode.fSpeedRatio;
|
||||
float fBlendTime=rReservingMotionNode.fBlendTime;
|
||||
|
||||
DWORD dwMotionKey=rReservingMotionNode.dwMotionKey;
|
||||
|
||||
m_MotionDeque.pop_front();
|
||||
|
||||
DWORD dwCurrentMotionIndex=GET_MOTION_INDEX(dwMotionKey);
|
||||
switch (dwCurrentMotionIndex)
|
||||
{
|
||||
case CRaceMotionData::NAME_STAND_UP:
|
||||
case CRaceMotionData::NAME_STAND_UP_BACK:
|
||||
if (IsDead())
|
||||
{
|
||||
//Tracenf("일어서려고 했으나 사망");
|
||||
// 예전 데이터로 복구
|
||||
m_kCurMotNode=kPrevMotionNode;
|
||||
__ClearMotion();
|
||||
|
||||
// 이전 동작 마지막 상태 유지
|
||||
SetEndStopMotion();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//Tracenf("MOTION %d", GET_MOTION_INDEX(dwMotionKey));
|
||||
|
||||
int iLoopCount;
|
||||
if (MOTION_TYPE_ONCE == iMotionType)
|
||||
iLoopCount=1;
|
||||
else
|
||||
iLoopCount=0;
|
||||
|
||||
SSetMotionData kSetMotData;
|
||||
kSetMotData.dwMotKey=dwMotionKey;
|
||||
kSetMotData.fBlendTime=fBlendTime;
|
||||
kSetMotData.fSpeedRatio=fSpeedRatio;
|
||||
kSetMotData.iLoopCount=iLoopCount;
|
||||
|
||||
DWORD dwRealMotionKey = __SetMotion(kSetMotData);
|
||||
|
||||
if (0 == dwRealMotionKey)
|
||||
return;
|
||||
|
||||
// FIX: 위에서 호출한 __SetMotion 함수 안에서 랜덤으로 다른 모션을 재생할 가능성도 있으므로 duration은 '현재 재생중인' 모션의 duration값을 사용해야 함.
|
||||
//float fDurationTime=rReservingMotionNode.fDuration;
|
||||
float fDurationTime = GetMotionDuration(dwRealMotionKey) / fSpeedRatio;
|
||||
float fStartTime = rReservingMotionNode.fStartTime;
|
||||
float fEndTime = fStartTime + fDurationTime;
|
||||
|
||||
if (dwRealMotionKey == 16777473)
|
||||
{
|
||||
int bp = 0;
|
||||
bp++;
|
||||
}
|
||||
|
||||
m_kCurMotNode.uSkill = 0;
|
||||
m_kCurMotNode.iMotionType = iMotionType;
|
||||
m_kCurMotNode.fSpeedRatio = fSpeedRatio;
|
||||
m_kCurMotNode.fStartTime = fStartTime;
|
||||
m_kCurMotNode.fEndTime = fEndTime;
|
||||
m_kCurMotNode.dwMotionKey = dwRealMotionKey;
|
||||
m_kCurMotNode.dwcurFrame = 0;
|
||||
m_kCurMotNode.dwFrameCount = fDurationTime / (1.0f / g_fGameFPS);
|
||||
}
|
||||
|
||||
void CActorInstance::CurrentMotionProcess()
|
||||
{
|
||||
if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType) // 임시다. 최종적인 목표는 Once도 절대로 넘어가선 안된다. - [levites]
|
||||
if (m_kCurMotNode.dwcurFrame >= m_kCurMotNode.dwFrameCount)
|
||||
m_kCurMotNode.dwcurFrame = 0;
|
||||
|
||||
if (IsDead())
|
||||
return;
|
||||
|
||||
if (!m_MotionDeque.empty())
|
||||
return;
|
||||
|
||||
float fCurrentTime = GetLocalTime();
|
||||
|
||||
DWORD dwMotionIndex=GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey);
|
||||
|
||||
bool isLooping=false;
|
||||
|
||||
// 끝났다면 Playing Flag를 끈다
|
||||
if (m_pkCurRaceMotionData && m_pkCurRaceMotionData->IsLoopMotion())
|
||||
{
|
||||
if (m_kCurMotNode.iLoopCount > 1 || m_kCurMotNode.iLoopCount == -1)
|
||||
{
|
||||
if (fCurrentTime - m_kCurMotNode.fStartTime > m_pkCurRaceMotionData->GetLoopEndTime())
|
||||
{
|
||||
m_kCurMotNode.dwcurFrame = DWORD(m_pkCurRaceMotionData->GetLoopStartTime() * g_fGameFPS);
|
||||
__SetLocalTime(m_kCurMotNode.fStartTime + m_pkCurRaceMotionData->GetLoopStartTime());
|
||||
if (-1 != m_kCurMotNode.iLoopCount)
|
||||
--m_kCurMotNode.iLoopCount;
|
||||
|
||||
isLooping=true;
|
||||
}
|
||||
}
|
||||
else if (!m_kQue_kFlyTarget.empty())
|
||||
{
|
||||
if (!m_kBackupFlyTarget.IsObject())
|
||||
{
|
||||
m_kBackupFlyTarget = m_kFlyTarget;
|
||||
}
|
||||
|
||||
if (fCurrentTime - m_kCurMotNode.fStartTime > m_pkCurRaceMotionData->GetLoopEndTime())
|
||||
{
|
||||
m_kCurMotNode.dwcurFrame = DWORD(m_pkCurRaceMotionData->GetLoopStartTime() * g_fGameFPS);
|
||||
__SetLocalTime(m_kCurMotNode.fStartTime + m_pkCurRaceMotionData->GetLoopStartTime());
|
||||
|
||||
SetFlyTarget(m_kQue_kFlyTarget.front());
|
||||
m_kQue_kFlyTarget.pop_front();
|
||||
|
||||
isLooping=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLooping)
|
||||
{
|
||||
if (fCurrentTime > m_kCurMotNode.fEndTime)
|
||||
{
|
||||
if (m_kBackupFlyTarget.IsValidTarget())
|
||||
{
|
||||
m_kFlyTarget = m_kBackupFlyTarget;
|
||||
m_kBackupFlyTarget.Clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
if (MOTION_TYPE_ONCE == m_kCurMotNode.iMotionType)
|
||||
{
|
||||
switch (dwMotionIndex)
|
||||
{
|
||||
case CRaceMotionData::NAME_DAMAGE_FLYING:
|
||||
case CRaceMotionData::NAME_DAMAGE_FLYING_BACK:
|
||||
case CRaceMotionData::NAME_DEAD:
|
||||
case CRaceMotionData::NAME_INTRO_SELECTED:
|
||||
case CRaceMotionData::NAME_INTRO_NOT_SELECTED:
|
||||
m_kCurMotNode.fEndTime+=3.0f;
|
||||
SetEndStopMotion();
|
||||
break;
|
||||
default:
|
||||
InterceptLoopMotion(CRaceMotionData::NAME_WAIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (MOTION_TYPE_LOOP == m_kCurMotNode.iMotionType)
|
||||
{
|
||||
if (CRaceMotionData::NAME_WAIT == dwMotionIndex)
|
||||
{
|
||||
PushLoopMotion(CRaceMotionData::NAME_WAIT, 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::SetMotionMode(int iMotionMode)
|
||||
{
|
||||
if (IsPoly())
|
||||
iMotionMode=CRaceMotionData::MODE_GENERAL;
|
||||
|
||||
m_wcurMotionMode = iMotionMode;
|
||||
}
|
||||
|
||||
int CActorInstance::GetMotionMode()
|
||||
{
|
||||
return m_wcurMotionMode;
|
||||
}
|
||||
|
||||
void CActorInstance::SetMotionLoopCount(int iCount)
|
||||
{
|
||||
assert(iCount >= -1 && iCount < 100);
|
||||
m_kCurMotNode.iLoopCount = iCount;
|
||||
}
|
||||
|
||||
void CActorInstance::PushMotion(EMotionPushType iMotionType, DWORD dwMotionKey, float fBlendTime, float fSpeedRatio)
|
||||
{
|
||||
if (!CheckMotionThingIndex(dwMotionKey))
|
||||
{
|
||||
Tracef(" Error - Not found want to using motion : %d\n", GET_MOTION_INDEX(dwMotionKey));
|
||||
return;
|
||||
}
|
||||
|
||||
TReservingMotionNode MotionNode;
|
||||
|
||||
MotionNode.iMotionType = iMotionType;
|
||||
MotionNode.dwMotionKey = dwMotionKey;
|
||||
MotionNode.fStartTime = GetLastMotionTime(fBlendTime);
|
||||
MotionNode.fBlendTime = fBlendTime;
|
||||
MotionNode.fSpeedRatio = fSpeedRatio;
|
||||
MotionNode.fDuration = GetMotionDuration(dwMotionKey);
|
||||
|
||||
m_MotionDeque.push_back(MotionNode);
|
||||
}
|
||||
|
||||
bool CActorInstance::InterceptOnceMotion(DWORD dwMotion, float fBlendTime, UINT uSkill, float fSpeedRatio)
|
||||
{
|
||||
return InterceptMotion(MOTION_TYPE_ONCE, dwMotion, fBlendTime, uSkill, fSpeedRatio);
|
||||
}
|
||||
|
||||
bool CActorInstance::InterceptLoopMotion(DWORD dwMotion, float fBlendTime)
|
||||
{
|
||||
return InterceptMotion(MOTION_TYPE_LOOP, dwMotion, fBlendTime);
|
||||
}
|
||||
|
||||
void CActorInstance::SetLoopMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio)
|
||||
{
|
||||
if (!m_pkCurRaceData)
|
||||
{
|
||||
Tracenf("CActorInstance::SetLoopMotion(dwMotion=%d, fBlendTime=%f, fSpeedRatio=%f)",
|
||||
dwMotion, fBlendTime, fSpeedRatio);
|
||||
return;
|
||||
}
|
||||
|
||||
MOTION_KEY dwMotionKey;
|
||||
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &dwMotionKey))
|
||||
{
|
||||
Tracenf("CActorInstance::SetLoopMotion(dwMotion=%d, fBlendTime=%f, fSpeedRatio=%f) - GetMotionKey(m_wcurMotionMode=%d, dwMotion=%d, &MotionKey) ERROR",
|
||||
dwMotion, fBlendTime, fSpeedRatio, m_wcurMotionMode, dwMotion);
|
||||
return;
|
||||
}
|
||||
|
||||
__ClearMotion();
|
||||
|
||||
SSetMotionData kSetMotData;
|
||||
kSetMotData.dwMotKey=dwMotionKey;
|
||||
kSetMotData.fBlendTime=fBlendTime;
|
||||
kSetMotData.fSpeedRatio=fSpeedRatio;
|
||||
|
||||
DWORD dwRealMotionKey = __SetMotion(kSetMotData);
|
||||
|
||||
if (0 == dwRealMotionKey)
|
||||
return;
|
||||
|
||||
m_kCurMotNode.iMotionType = MOTION_TYPE_LOOP;
|
||||
m_kCurMotNode.fStartTime = GetLocalTime();
|
||||
m_kCurMotNode.dwMotionKey = dwRealMotionKey;
|
||||
m_kCurMotNode.fEndTime = 0.0f;
|
||||
m_kCurMotNode.fSpeedRatio = fSpeedRatio;
|
||||
m_kCurMotNode.dwcurFrame = 0;
|
||||
m_kCurMotNode.dwFrameCount = GetMotionDuration(dwRealMotionKey) / (1.0f / g_fGameFPS);
|
||||
m_kCurMotNode.uSkill = 0;
|
||||
}
|
||||
|
||||
// 리턴값 == SetMotion의 리턴값 == 실제로 애니메이션 데이터를 플레이 했느냐?
|
||||
bool CActorInstance::InterceptMotion(EMotionPushType iMotionType, WORD wMotion, float fBlendTime, UINT uSkill, float fSpeedRatio)
|
||||
{
|
||||
if (!m_pkCurRaceData)
|
||||
{
|
||||
Tracef("CActorInstance::InterceptMotion(iMotionType=%d, wMotion=%d, fBlendTime=%f) - m_pkCurRaceData=NULL", iMotionType, wMotion, fBlendTime);
|
||||
return false;
|
||||
}
|
||||
|
||||
MOTION_KEY dwMotionKey;
|
||||
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, wMotion, &dwMotionKey))
|
||||
{
|
||||
Tracenf("CActorInstance::InterceptMotion(iLoopType=%d, wMotionMode=%d, wMotion=%d, fBlendTime=%f) - GetMotionKey(m_wcurMotionMode=%d, wMotion=%d, &MotionKey) ERROR",
|
||||
iMotionType, m_wcurMotionMode, wMotion, fBlendTime, m_wcurMotionMode, wMotion);
|
||||
return false;
|
||||
}
|
||||
|
||||
__ClearMotion();
|
||||
|
||||
int iLoopCount;
|
||||
if (MOTION_TYPE_ONCE == iMotionType)
|
||||
iLoopCount=1;
|
||||
else
|
||||
iLoopCount=0;
|
||||
|
||||
SSetMotionData kSetMotData;
|
||||
kSetMotData.dwMotKey=dwMotionKey;
|
||||
kSetMotData.fBlendTime=fBlendTime;
|
||||
kSetMotData.iLoopCount=iLoopCount;
|
||||
kSetMotData.fSpeedRatio=fSpeedRatio;
|
||||
kSetMotData.uSkill=uSkill;
|
||||
|
||||
DWORD dwRealMotionKey = __SetMotion(kSetMotData);
|
||||
|
||||
if (0 == dwRealMotionKey)
|
||||
return false;
|
||||
|
||||
if (m_pFlyEventHandler)
|
||||
{
|
||||
if (__IsNeedFlyTargetMotion())
|
||||
{
|
||||
m_pFlyEventHandler->OnSetFlyTarget();
|
||||
}
|
||||
}
|
||||
|
||||
assert(NULL != m_pkCurRaceMotionData);
|
||||
|
||||
// FIX : 위에서 호출한 __SetMotion 함수 내에서 랜덤으로 다른 모션을 선택할 수도 있기 때문에 dwMotionKey값은 유효하지 않고
|
||||
// 따라서 해당 키로 산출한 duration은 유효하지 않음. 당연히 현재 play중인 모션의 시간을 구해야 함.. -_-;;
|
||||
// float fDuration=GetMotionDuration(dwMotionKey)/fSpeedRatio;
|
||||
float fDuration = GetMotionDuration(dwRealMotionKey) / fSpeedRatio;
|
||||
|
||||
m_kCurMotNode.iMotionType = iMotionType;
|
||||
m_kCurMotNode.fStartTime = GetLocalTime();
|
||||
m_kCurMotNode.fEndTime = m_kCurMotNode.fStartTime + fDuration;
|
||||
m_kCurMotNode.dwMotionKey = dwRealMotionKey;
|
||||
m_kCurMotNode.dwcurFrame = 0;
|
||||
m_kCurMotNode.dwFrameCount = fDuration / (1.0f / g_fGameFPS);
|
||||
m_kCurMotNode.uSkill = uSkill;
|
||||
m_kCurMotNode.fSpeedRatio = fSpeedRatio;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::PushOnceMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio)
|
||||
{
|
||||
assert(m_pkCurRaceData);
|
||||
|
||||
MOTION_KEY MotionKey;
|
||||
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &MotionKey))
|
||||
return false;
|
||||
|
||||
PushMotion(MOTION_TYPE_ONCE, MotionKey, fBlendTime, fSpeedRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::PushLoopMotion(DWORD dwMotion, float fBlendTime, float fSpeedRatio)
|
||||
{
|
||||
assert(m_pkCurRaceData);
|
||||
|
||||
MOTION_KEY MotionKey;
|
||||
if (!m_pkCurRaceData->GetMotionKey(m_wcurMotionMode, dwMotion, &MotionKey))
|
||||
return false;
|
||||
|
||||
PushMotion(MOTION_TYPE_LOOP, MotionKey, fBlendTime, fSpeedRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
WORD CActorInstance::__GetCurrentMotionIndex()
|
||||
{
|
||||
return GET_MOTION_INDEX(m_kCurMotNode.dwMotionKey);
|
||||
}
|
||||
|
||||
DWORD CActorInstance::__GetCurrentMotionKey()
|
||||
{
|
||||
return m_kCurMotNode.dwMotionKey;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsUsingSkill()
|
||||
{
|
||||
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
|
||||
|
||||
if (dwCurMotionIndex>=CRaceMotionData::NAME_SKILL && dwCurMotionIndex<CRaceMotionData::NAME_SKILL_END)
|
||||
return TRUE;
|
||||
|
||||
switch (dwCurMotionIndex)
|
||||
{
|
||||
case CRaceMotionData::NAME_SPECIAL_1:
|
||||
case CRaceMotionData::NAME_SPECIAL_2:
|
||||
case CRaceMotionData::NAME_SPECIAL_3:
|
||||
case CRaceMotionData::NAME_SPECIAL_4:
|
||||
case CRaceMotionData::NAME_SPECIAL_5:
|
||||
case CRaceMotionData::NAME_SPECIAL_6:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::IsFishing()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return FALSE;
|
||||
|
||||
if (__GetCurrentMotionIndex() == CRaceMotionData::NAME_FISHING_WAIT ||
|
||||
__GetCurrentMotionIndex() == CRaceMotionData::NAME_FISHING_REACT)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CActorInstance::CanCancelSkill()
|
||||
{
|
||||
assert(IsUsingSkill());
|
||||
return m_pkCurRaceMotionData->IsCancelEnableSkill();
|
||||
}
|
||||
|
||||
BOOL CActorInstance::isLock()
|
||||
{
|
||||
DWORD dwCurMotionIndex=__GetCurrentMotionIndex();
|
||||
|
||||
// Locked during attack
|
||||
switch (dwCurMotionIndex)
|
||||
{
|
||||
case CRaceMotionData::NAME_NORMAL_ATTACK:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_1:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_2:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_3:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_4:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_5:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_6:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_7:
|
||||
case CRaceMotionData::NAME_COMBO_ATTACK_8:
|
||||
case CRaceMotionData::NAME_SPECIAL_1:
|
||||
case CRaceMotionData::NAME_SPECIAL_2:
|
||||
case CRaceMotionData::NAME_SPECIAL_3:
|
||||
case CRaceMotionData::NAME_SPECIAL_4:
|
||||
case CRaceMotionData::NAME_SPECIAL_5:
|
||||
case CRaceMotionData::NAME_SPECIAL_6:
|
||||
case CRaceMotionData::NAME_FISHING_THROW:
|
||||
case CRaceMotionData::NAME_FISHING_WAIT:
|
||||
case CRaceMotionData::NAME_FISHING_STOP:
|
||||
case CRaceMotionData::NAME_FISHING_REACT:
|
||||
case CRaceMotionData::NAME_FISHING_CATCH:
|
||||
case CRaceMotionData::NAME_FISHING_FAIL:
|
||||
case CRaceMotionData::NAME_CLAP:
|
||||
case CRaceMotionData::NAME_DANCE_1:
|
||||
case CRaceMotionData::NAME_DANCE_2:
|
||||
case CRaceMotionData::NAME_DANCE_3:
|
||||
case CRaceMotionData::NAME_DANCE_4:
|
||||
case CRaceMotionData::NAME_DANCE_5:
|
||||
case CRaceMotionData::NAME_DANCE_6:
|
||||
case CRaceMotionData::NAME_CONGRATULATION:
|
||||
case CRaceMotionData::NAME_FORGIVE:
|
||||
case CRaceMotionData::NAME_ANGRY:
|
||||
case CRaceMotionData::NAME_ATTRACTIVE:
|
||||
case CRaceMotionData::NAME_SAD:
|
||||
case CRaceMotionData::NAME_SHY:
|
||||
case CRaceMotionData::NAME_CHEERUP:
|
||||
case CRaceMotionData::NAME_BANTER:
|
||||
case CRaceMotionData::NAME_JOY:
|
||||
case CRaceMotionData::NAME_CHEERS_1:
|
||||
case CRaceMotionData::NAME_CHEERS_2:
|
||||
case CRaceMotionData::NAME_KISS_WITH_WARRIOR:
|
||||
case CRaceMotionData::NAME_KISS_WITH_ASSASSIN:
|
||||
case CRaceMotionData::NAME_KISS_WITH_SURA:
|
||||
case CRaceMotionData::NAME_KISS_WITH_SHAMAN:
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_WITH_WARRIOR:
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_WITH_ASSASSIN:
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_WITH_SURA:
|
||||
case CRaceMotionData::NAME_FRENCH_KISS_WITH_SHAMAN:
|
||||
case CRaceMotionData::NAME_SLAP_HIT_WITH_WARRIOR:
|
||||
case CRaceMotionData::NAME_SLAP_HIT_WITH_ASSASSIN:
|
||||
case CRaceMotionData::NAME_SLAP_HIT_WITH_SURA:
|
||||
case CRaceMotionData::NAME_SLAP_HIT_WITH_SHAMAN:
|
||||
case CRaceMotionData::NAME_SLAP_HURT_WITH_WARRIOR:
|
||||
case CRaceMotionData::NAME_SLAP_HURT_WITH_ASSASSIN:
|
||||
case CRaceMotionData::NAME_SLAP_HURT_WITH_SURA:
|
||||
case CRaceMotionData::NAME_SLAP_HURT_WITH_SHAMAN:
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Locked during using skill
|
||||
if (IsUsingSkill())
|
||||
{
|
||||
if (m_pkCurRaceMotionData->IsCancelEnableSkill())
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
float CActorInstance::GetLastMotionTime(float fBlendTime)
|
||||
{
|
||||
if (m_MotionDeque.empty())
|
||||
{
|
||||
if (MOTION_TYPE_ONCE == m_kCurMotNode.iMotionType)
|
||||
return (m_kCurMotNode.fEndTime - fBlendTime);
|
||||
|
||||
return GetLocalTime();
|
||||
}
|
||||
|
||||
TReservingMotionNode & rMotionNode = m_MotionDeque[m_MotionDeque.size()-1];
|
||||
|
||||
return rMotionNode.fStartTime + rMotionNode.fDuration - fBlendTime;
|
||||
}
|
||||
|
||||
float CActorInstance::GetMotionDuration(DWORD dwMotionKey)
|
||||
{
|
||||
CGraphicThing * pMotion;
|
||||
|
||||
if (!GetMotionThingPointer(dwMotionKey, &pMotion))
|
||||
{
|
||||
Tracenf("CActorInstance::GetMotionDuration - Cannot get motion: %d / %d",
|
||||
GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey));
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (0 == pMotion->GetMotionCount())
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Tracenf("CActorInstance::GetMotionDuration - Invalid Motion Key : %d, %d, %d",
|
||||
GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey), GET_MOTION_SUB_INDEX(dwMotionKey));
|
||||
#endif
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
CGrannyMotion * pGrannyMotion = pMotion->GetMotionPointer(0);
|
||||
return pGrannyMotion->GetDuration();
|
||||
}
|
||||
|
||||
MOTION_KEY CActorInstance::GetRandomMotionKey(MOTION_KEY dwMotionKey)
|
||||
{
|
||||
// NOTE : 자주 호출 되는 부분은 아니지만 어느 정도의 최적화 여지가 있음 - [levites]
|
||||
// FIXME : 처음에 선택된 모션이 없는 것에 대한 처리가 되어 있지 않다.
|
||||
WORD wMode = GET_MOTION_MODE(dwMotionKey);
|
||||
WORD wIndex = GET_MOTION_INDEX(dwMotionKey);
|
||||
|
||||
const CRaceData::TMotionVector * c_pMotionVector;
|
||||
if (m_pkCurRaceData->GetMotionVectorPointer(wMode, wIndex, &c_pMotionVector))
|
||||
if (c_pMotionVector->size() > 1)
|
||||
{
|
||||
int iPercentage = random() % 100;
|
||||
for (DWORD i = 0; i < c_pMotionVector->size(); ++i)
|
||||
{
|
||||
const CRaceData::TMotion & c_rMotion = c_pMotionVector->at(i);
|
||||
iPercentage -= c_rMotion.byPercentage;
|
||||
|
||||
if (iPercentage < 0)
|
||||
{
|
||||
dwMotionKey = MAKE_RANDOM_MOTION_KEY(wMode, wIndex, i);
|
||||
|
||||
// Temporary
|
||||
// NOTE: 현재로선 여기서 해봤자 의미없다. 전체적으로 확인결과 아래는 씹히는 코드고 다른곳에서 해결해야 하므로 일단 주석처리함. 나중에 통채로 지우자..
|
||||
// m_kCurMotNode.fEndTime = m_kCurMotNode.fStartTime + GetMotionDuration(dwMotionKey);
|
||||
// Temporary
|
||||
|
||||
return dwMotionKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dwMotionKey;
|
||||
}
|
||||
|
||||
void CActorInstance::PreAttack()
|
||||
{
|
||||
}
|
||||
|
||||
void CActorInstance::__ClearMotion()
|
||||
{
|
||||
__HideWeaponTrace();
|
||||
|
||||
m_MotionDeque.clear();
|
||||
m_kCurMotNode.dwcurFrame=0;
|
||||
m_kCurMotNode.dwFrameCount=0;
|
||||
m_kCurMotNode.uSkill=0;
|
||||
m_kCurMotNode.iLoopCount=0;
|
||||
m_kCurMotNode.iMotionType=MOTION_TYPE_NONE;
|
||||
}
|
||||
|
||||
|
||||
DWORD CActorInstance::__SetMotion(const SSetMotionData& c_rkSetMotData, DWORD dwRandMotKey)
|
||||
{
|
||||
DWORD dwMotKey = dwRandMotKey;
|
||||
|
||||
if (dwMotKey == 0)
|
||||
dwMotKey = GetRandomMotionKey(c_rkSetMotData.dwMotKey);
|
||||
|
||||
UINT uNextMot = GET_MOTION_INDEX(c_rkSetMotData.dwMotKey);
|
||||
|
||||
if (IsDead())
|
||||
{
|
||||
if (uNextMot!=CRaceMotionData::NAME_DAMAGE_FLYING && uNextMot!=CRaceMotionData::NAME_DAMAGE_FLYING_BACK && uNextMot!=CRaceMotionData::NAME_DEAD && uNextMot!=CRaceMotionData::NAME_DEAD_BACK)
|
||||
return 0;
|
||||
}
|
||||
if (IsUsingSkill())
|
||||
{
|
||||
__OnStop();
|
||||
}
|
||||
|
||||
if (__IsStandUpMotion())
|
||||
{
|
||||
__OnStop();
|
||||
}
|
||||
|
||||
|
||||
if (__IsMoveMotion())
|
||||
{
|
||||
if (uNextMot==CRaceMotionData::NAME_DAMAGE || uNextMot==CRaceMotionData::NAME_DAMAGE_BACK || uNextMot==CRaceMotionData::NAME_DAMAGE_FLYING || uNextMot==CRaceMotionData::NAME_DAMAGE_FLYING_BACK)
|
||||
{
|
||||
if (!m_isMain)
|
||||
{
|
||||
Logn(0, "주인공이 아니라면 이동중이라 데미지 동작을 취하지 않음");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (uNextMot!=CRaceMotionData::NAME_RUN &&
|
||||
uNextMot!=CRaceMotionData::NAME_WALK &&
|
||||
!__IsMovingSkill(c_rkSetMotData.uSkill))
|
||||
{
|
||||
__OnStop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (uNextMot==CRaceMotionData::NAME_RUN || __IsMovingSkill(c_rkSetMotData.uSkill))
|
||||
{
|
||||
__OnMove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE : 스킬 사용중 사라지는 문제를 위한 안전 장치 - [levites]
|
||||
if (__IsHiding())
|
||||
{
|
||||
__ShowEvent();
|
||||
}
|
||||
|
||||
|
||||
if (-1 != m_iFishingEffectID)
|
||||
{
|
||||
CEffectManager& rkEftMgr=CEffectManager::Instance();
|
||||
rkEftMgr.DeactiveEffectInstance(m_iFishingEffectID);
|
||||
|
||||
m_iFishingEffectID = -1;
|
||||
}
|
||||
|
||||
if (m_pkHorse)
|
||||
{
|
||||
WORD wMotionIndex = GET_MOTION_INDEX(dwMotKey);
|
||||
WORD wMotionSubIndex = GET_MOTION_SUB_INDEX(dwMotKey);
|
||||
DWORD dwChildMotKey = MAKE_RANDOM_MOTION_KEY(m_pkHorse->m_wcurMotionMode, wMotionIndex, wMotionSubIndex);
|
||||
|
||||
if (CRaceMotionData::NAME_DEAD == wMotionIndex)
|
||||
CGraphicThingInstance::ChangeMotion(dwMotKey, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
|
||||
else
|
||||
CGraphicThingInstance::SetMotion(dwMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
|
||||
|
||||
m_pkHorse->SetMotion(dwChildMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
|
||||
m_pkHorse->__BindMotionData(dwChildMotKey);
|
||||
|
||||
if (c_rkSetMotData.iLoopCount)
|
||||
m_pkHorse->m_kCurMotNode.iMotionType = MOTION_TYPE_ONCE; // 무조건 이전 모션 타입으로 설정되고 있었음
|
||||
else
|
||||
m_pkHorse->m_kCurMotNode.iMotionType = MOTION_TYPE_LOOP;
|
||||
|
||||
m_pkHorse->m_kCurMotNode.dwFrameCount = m_pkHorse->GetMotionDuration(dwChildMotKey) / (1.0f / g_fGameFPS);
|
||||
m_pkHorse->m_kCurMotNode.dwcurFrame = 0;
|
||||
m_pkHorse->m_kCurMotNode.dwMotionKey = dwChildMotKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
CGraphicThingInstance::SetMotion(dwMotKey, c_rkSetMotData.fBlendTime, c_rkSetMotData.iLoopCount, c_rkSetMotData.fSpeedRatio);
|
||||
}
|
||||
|
||||
__HideWeaponTrace();
|
||||
|
||||
if (__BindMotionData(dwMotKey))
|
||||
{
|
||||
int iLoopCount = __GetLoopCount();
|
||||
SetMotionLoopCount(iLoopCount);
|
||||
|
||||
if (__CanAttack())
|
||||
{
|
||||
// 여기서 공격 모션일 경우의 처리를 합니다 - [levites]
|
||||
__ShowWeaponTrace();
|
||||
|
||||
m_HitDataMap.clear();
|
||||
//PreAttack();
|
||||
}
|
||||
|
||||
if (__IsComboAttacking())
|
||||
{
|
||||
if (!__CanNextComboAttack())
|
||||
{
|
||||
// 2004.11.19.myevan.동물 변신시 이부분에서 바로 리셋되어 다음동작 안나온다
|
||||
m_dwcurComboIndex = 0; // 콤보 리셋 - [levites]
|
||||
|
||||
// NOTE : ClearCombo() 를 수행해서는 안된다.
|
||||
// 콤보 다음에 스킬을 이어서 사용할 경우 m_pkCurRaceMotionData까지 초기화 되어 버린다.
|
||||
//Tracef("MotionData에 콤보 데이타가 들어 있지 않습니다.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dwMotKey;
|
||||
}
|
||||
|
||||
bool CActorInstance::__BindMotionData(DWORD dwMotionKey)
|
||||
{
|
||||
if (!m_pkCurRaceData->GetMotionDataPointer(dwMotionKey, &m_pkCurRaceMotionData))
|
||||
{
|
||||
Tracen("Failed to bind motion.");
|
||||
m_pkCurRaceMotionData=NULL;
|
||||
m_dwcurComboIndex=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CActorInstance::__GetLoopCount()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
{
|
||||
TraceError("CActorInstance::__GetLoopCount() - m_pkCurRaceMotionData==NULL");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return m_pkCurRaceMotionData->GetLoopCount();
|
||||
}
|
||||
|
||||
bool CActorInstance::__CanAttack()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
{
|
||||
TraceError("CActorInstance::__CanAttack() - m_pkCurRaceMotionData==NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_pkCurRaceMotionData->isAttackingMotion())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::__CanNextComboAttack()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
{
|
||||
TraceError("CActorInstance::__CanNextComboAttack() - m_pkCurRaceMotionData==NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_pkCurRaceMotionData->IsComboInputTimeData())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsComboAttacking()
|
||||
{
|
||||
if (0 == m_dwcurComboIndex)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsNeedFlyTargetMotion()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return true;
|
||||
|
||||
for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i)
|
||||
{
|
||||
const CRaceMotionData::TMotionEventData * c_pData;
|
||||
if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData))
|
||||
continue;
|
||||
|
||||
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_WARP)
|
||||
return true;
|
||||
|
||||
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_FLY)
|
||||
return true;
|
||||
|
||||
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::__HasMotionFlyEvent()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return true;
|
||||
|
||||
for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i)
|
||||
{
|
||||
const CRaceMotionData::TMotionEventData * c_pData;
|
||||
if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData))
|
||||
continue;
|
||||
|
||||
if (c_pData->iType == CRaceMotionData::MOTION_EVENT_TYPE_FLY)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsWaitMotion()
|
||||
{
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_WAIT);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsMoveMotion()
|
||||
{
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_MOVE);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsAttackMotion()
|
||||
{
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_ATTACK);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsComboAttackMotion()
|
||||
{
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_COMBO);
|
||||
}
|
||||
|
||||
|
||||
bool CActorInstance::__IsDamageMotion()
|
||||
{
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_DAMAGE);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsKnockDownMotion()
|
||||
{
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_KNOCKDOWN);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsDieMotion()
|
||||
{
|
||||
if (__IsKnockDownMotion())
|
||||
return true;
|
||||
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_DIE);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsStandUpMotion()
|
||||
{
|
||||
return (__GetMotionType()==CRaceMotionData::TYPE_STANDUP);
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EffectLib/EffectManager.h"
|
||||
#include "../milesLib/SoundManager.h"
|
||||
|
||||
#include "ActorInstance.h"
|
||||
#include "FlyingObjectManager.h"
|
||||
#include "FlyingInstance.h"
|
||||
#include "GameEventManager.h"
|
||||
|
||||
#include "FlyHandler.h"
|
||||
|
||||
void CActorInstance::MotionEventProcess()
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return;
|
||||
|
||||
for (DWORD i = 0; i < m_pkCurRaceMotionData->GetMotionEventDataCount(); ++i)
|
||||
{
|
||||
const CRaceMotionData::TMotionEventData * c_pData;
|
||||
if (!m_pkCurRaceMotionData->GetMotionEventDataPointer(i, &c_pData))
|
||||
continue;
|
||||
|
||||
MotionEventProcess(m_kCurMotNode.dwcurFrame, i, c_pData);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::SoundEventProcess(BOOL bCheckFrequency)
|
||||
{
|
||||
if (!m_pkCurRaceMotionData)
|
||||
return;
|
||||
|
||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
||||
const NSound::TSoundInstanceVector* c_pkVct_kSndInst=m_pkCurRaceMotionData->GetSoundInstanceVectorPointer();
|
||||
rkSndMgr.UpdateSoundInstance(m_x, m_y, m_z, m_kCurMotNode.dwcurFrame, c_pkVct_kSndInst, bCheckFrequency);
|
||||
}
|
||||
|
||||
void CActorInstance::MotionEventProcess(DWORD dwcurFrame, int iIndex, const CRaceMotionData::TMotionEventData * c_pData)
|
||||
{
|
||||
if (c_pData->dwFrame != dwcurFrame)
|
||||
return;
|
||||
|
||||
switch (c_pData->iType)
|
||||
{
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_EFFECT:
|
||||
ProcessMotionEventEffectEvent(c_pData);
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET:
|
||||
ProcessMotionEventEffectToTargetEvent(c_pData);
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_SCREEN_WAVING:
|
||||
CGameEventManager::Instance().ProcessEventScreenWaving(this, (const CRaceMotionData::TScreenWavingEventData *)c_pData);
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_SPECIAL_ATTACKING:
|
||||
ProcessMotionEventSpecialAttacking(iIndex, c_pData);
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_SOUND:
|
||||
ProcessMotionEventSound(c_pData);
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_FLY:
|
||||
ProcessMotionEventFly(c_pData);
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_CHARACTER_SHOW:
|
||||
__ShowEvent();
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_CHARACTER_HIDE:
|
||||
__HideEvent();
|
||||
break;
|
||||
|
||||
case CRaceMotionData::MOTION_EVENT_TYPE_WARP:
|
||||
#ifndef WORLD_EDITOR
|
||||
ProcessMotionEventWarp(c_pData);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::__ShowEvent()
|
||||
{
|
||||
m_isHiding = FALSE;
|
||||
RestoreRenderMode();
|
||||
SetAlphaValue(1.0f);
|
||||
}
|
||||
|
||||
void CActorInstance::__HideEvent()
|
||||
{
|
||||
m_isHiding = TRUE;
|
||||
SetBlendRenderMode();
|
||||
SetAlphaValue(0.0f);
|
||||
}
|
||||
|
||||
BOOL CActorInstance::__IsHiding()
|
||||
{
|
||||
return m_isHiding;
|
||||
}
|
||||
|
||||
void CActorInstance::ProcessMotionEventEffectEvent(const CRaceMotionData::TMotionEventData * c_pData)
|
||||
{
|
||||
if (CRaceMotionData::MOTION_EVENT_TYPE_EFFECT != c_pData->iType)
|
||||
return;
|
||||
|
||||
const CRaceMotionData::TMotionEffectEventData * c_pEffectData = (const CRaceMotionData::TMotionEffectEventData *)c_pData;
|
||||
|
||||
if (c_pEffectData->isIndependent)
|
||||
{
|
||||
int iIndex = CEffectManager::Instance().CreateEffect(c_pEffectData->dwEffectIndex, D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
D3DXMATRIX matLocalPosition;
|
||||
D3DXMatrixTranslation(&matLocalPosition, c_pEffectData->v3EffectPosition.x, c_pEffectData->v3EffectPosition.y, c_pEffectData->v3EffectPosition.z);
|
||||
|
||||
D3DXMATRIX matWorld;
|
||||
matWorld = matLocalPosition;
|
||||
matWorld *= m_worldMatrix;
|
||||
|
||||
CEffectManager::Instance().SelectEffectInstance(iIndex);
|
||||
CEffectManager::Instance().SetEffectInstanceGlobalMatrix(matWorld);
|
||||
return;
|
||||
}
|
||||
|
||||
if (c_pEffectData->isAttaching)
|
||||
{
|
||||
if (c_pEffectData->isFollowing)
|
||||
{
|
||||
AttachEffectByID(0,
|
||||
c_pEffectData->strAttachingBoneName.c_str(),
|
||||
c_pEffectData->dwEffectIndex,
|
||||
&c_pEffectData->v3EffectPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
int iBoneIndex;
|
||||
DWORD dwPartIndex = 0;
|
||||
if (FindBoneIndex(dwPartIndex, c_pEffectData->strAttachingBoneName.c_str(), &iBoneIndex))
|
||||
{
|
||||
D3DXMATRIX * pBoneMat;
|
||||
GetBoneMatrix(dwPartIndex, iBoneIndex, &pBoneMat);
|
||||
|
||||
D3DXMATRIX matLocalPosition;
|
||||
D3DXMatrixTranslation(&matLocalPosition, c_pEffectData->v3EffectPosition.x, c_pEffectData->v3EffectPosition.y, c_pEffectData->v3EffectPosition.z);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
D3DXMATRIX matWorld;
|
||||
matWorld = *pBoneMat;
|
||||
matWorld *= matLocalPosition;
|
||||
matWorld *= m_worldMatrix;
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
int iIndex = CEffectManager::Instance().CreateEffect(c_pEffectData->dwEffectIndex,
|
||||
c_pEffectData->v3EffectPosition,
|
||||
D3DXVECTOR3(0.0f, 0.0f, 0.0f));
|
||||
CEffectManager::Instance().SelectEffectInstance(iIndex);
|
||||
CEffectManager::Instance().SetEffectInstanceGlobalMatrix(matWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachEffectByID(0, NULL, c_pEffectData->dwEffectIndex, &c_pEffectData->v3EffectPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::ProcessMotionEventEffectToTargetEvent(const CRaceMotionData::TMotionEventData * c_pData)
|
||||
{
|
||||
if (CRaceMotionData::MOTION_EVENT_TYPE_EFFECT_TO_TARGET != c_pData->iType)
|
||||
return;
|
||||
|
||||
const CRaceMotionData::TMotionEffectToTargetEventData * c_pEffectToTargetData = (const CRaceMotionData::TMotionEffectToTargetEventData *)c_pData;
|
||||
|
||||
if (c_pEffectToTargetData->isFishingEffect)
|
||||
{
|
||||
CEffectManager& rkEftMgr=CEffectManager::Instance();
|
||||
|
||||
if (-1 != m_iFishingEffectID)
|
||||
{
|
||||
rkEftMgr.DeactiveEffectInstance(m_iFishingEffectID);
|
||||
}
|
||||
|
||||
m_iFishingEffectID = rkEftMgr.CreateEffect(c_pEffectToTargetData->dwEffectIndex, m_v3FishingPosition, D3DXVECTOR3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_kFlyTarget.IsValidTarget())
|
||||
return;
|
||||
|
||||
if (c_pEffectToTargetData->isFollowing && IsFlyTargetObject())
|
||||
{
|
||||
CActorInstance * pTargetInstance = (CActorInstance *)m_kFlyTarget.GetFlyTarget();
|
||||
D3DXVECTOR3 v3Position( c_pEffectToTargetData->v3EffectPosition.x,
|
||||
c_pEffectToTargetData->v3EffectPosition.y,
|
||||
c_pEffectToTargetData->v3EffectPosition.z);
|
||||
pTargetInstance->AttachEffectByID(0, NULL, c_pEffectToTargetData->dwEffectIndex, &v3Position);
|
||||
}
|
||||
else
|
||||
{
|
||||
const D3DXVECTOR3 & c_rv3FlyTarget = m_kFlyTarget.GetFlyTargetPosition();
|
||||
D3DXVECTOR3 v3Position( c_rv3FlyTarget.x + c_pEffectToTargetData->v3EffectPosition.x,
|
||||
c_rv3FlyTarget.y + c_pEffectToTargetData->v3EffectPosition.y,
|
||||
c_rv3FlyTarget.z + c_pEffectToTargetData->v3EffectPosition.z);
|
||||
CEffectManager::Instance().CreateEffect(c_pEffectToTargetData->dwEffectIndex, v3Position, D3DXVECTOR3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::ProcessMotionEventSpecialAttacking(int iMotionEventIndex, const CRaceMotionData::TMotionEventData * c_pData)
|
||||
{
|
||||
if (CRaceMotionData::MOTION_EVENT_TYPE_SPECIAL_ATTACKING != c_pData->iType)
|
||||
return;
|
||||
|
||||
const CRaceMotionData::TMotionAttackingEventData * c_pAttackingData = (const CRaceMotionData::TMotionAttackingEventData *)c_pData;
|
||||
|
||||
float fRadian = D3DXToRadian(270.0f + 360.0f - GetRotation());
|
||||
m_kSplashArea.isEnableHitProcess=c_pAttackingData->isEnableHitProcess;
|
||||
m_kSplashArea.uSkill=m_kCurMotNode.uSkill;
|
||||
m_kSplashArea.MotionKey = m_kCurMotNode.dwMotionKey;
|
||||
m_kSplashArea.fDisappearingTime = GetLocalTime() + c_pAttackingData->fDurationTime;
|
||||
m_kSplashArea.c_pAttackingEvent = c_pAttackingData;
|
||||
m_kSplashArea.HittedInstanceMap.clear();
|
||||
|
||||
m_kSplashArea.SphereInstanceVector.clear();
|
||||
m_kSplashArea.SphereInstanceVector.resize(c_pAttackingData->CollisionData.SphereDataVector.size());
|
||||
for (DWORD i = 0; i < c_pAttackingData->CollisionData.SphereDataVector.size(); ++i)
|
||||
{
|
||||
const TSphereData & c_rSphereData = c_pAttackingData->CollisionData.SphereDataVector[i].GetAttribute();
|
||||
CDynamicSphereInstance & rSphereInstance = m_kSplashArea.SphereInstanceVector[i];
|
||||
|
||||
rSphereInstance.fRadius = c_rSphereData.fRadius;
|
||||
//rSphereInstance.v3Advance = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
rSphereInstance.v3Position.x = m_x + c_rSphereData.v3Position.x*sinf(fRadian) + c_rSphereData.v3Position.y*cosf(fRadian);
|
||||
rSphereInstance.v3Position.y = m_y + c_rSphereData.v3Position.x*cosf(fRadian) - c_rSphereData.v3Position.y*sinf(fRadian);
|
||||
rSphereInstance.v3Position.z = m_z + c_rSphereData.v3Position.z;
|
||||
rSphereInstance.v3LastPosition = rSphereInstance.v3Position;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::ProcessMotionEventSound(const CRaceMotionData::TMotionEventData * c_pData)
|
||||
{
|
||||
if (CRaceMotionData::MOTION_EVENT_TYPE_SOUND != c_pData->iType)
|
||||
return;
|
||||
|
||||
const CRaceMotionData::TMotionSoundEventData * c_pSoundData = (const CRaceMotionData::TMotionSoundEventData *)c_pData;
|
||||
|
||||
Tracenf("PLAY SOUND: %s", c_pSoundData->strSoundFileName.c_str());
|
||||
CSoundManager::Instance().PlaySound3D(m_x, m_y, m_z, c_pSoundData->strSoundFileName.c_str());
|
||||
}
|
||||
|
||||
void CActorInstance::ProcessMotionEventFly(const CRaceMotionData::TMotionEventData * c_pData)
|
||||
{
|
||||
if (CRaceMotionData::MOTION_EVENT_TYPE_FLY != c_pData->iType)
|
||||
return;
|
||||
|
||||
const CRaceMotionData::TMotionFlyEventData * c_pFlyData = (const CRaceMotionData::TMotionFlyEventData *)c_pData;
|
||||
|
||||
if (m_kFlyTarget.IsValidTarget())
|
||||
{
|
||||
CFlyingManager & rfm = CFlyingManager::Instance();
|
||||
|
||||
D3DXVECTOR3 v3Start(c_pFlyData->v3FlyPosition);
|
||||
v3Start += m_v3Position;
|
||||
|
||||
if (c_pFlyData->isAttaching)
|
||||
{
|
||||
D3DXMATRIX * pBoneMat;
|
||||
int iBoneIndex;
|
||||
DWORD dwPartIndex = 0;
|
||||
|
||||
if (FindBoneIndex(dwPartIndex, c_pFlyData->strAttachingBoneName.c_str(), &iBoneIndex))
|
||||
if (GetBoneMatrix(dwPartIndex,iBoneIndex,&pBoneMat))
|
||||
{
|
||||
v3Start.x += pBoneMat->_41;
|
||||
v3Start.y += pBoneMat->_42;
|
||||
v3Start.z += pBoneMat->_43;
|
||||
}
|
||||
}
|
||||
|
||||
CFlyingInstance * pInstance = rfm.CreateFlyingInstanceFlyTarget(c_pFlyData->dwFlyIndex,v3Start,m_kFlyTarget,true);
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetEventHandler(m_pFlyEventHandler);
|
||||
pInstance->SetOwner(this);
|
||||
pInstance->SetSkillIndex(m_kCurMotNode.uSkill);
|
||||
}
|
||||
|
||||
if (m_pFlyEventHandler)
|
||||
{
|
||||
m_pFlyEventHandler->OnShoot(m_kCurMotNode.uSkill);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TraceError("ActorInstance::ProcessMotionEventFly No Target");
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::ProcessMotionEventWarp(const CRaceMotionData::TMotionEventData * c_pData)
|
||||
{
|
||||
if (CRaceMotionData::MOTION_EVENT_TYPE_WARP != c_pData->iType)
|
||||
return;
|
||||
|
||||
// FIXME : TMotionWarpEventData로 뺄 변수 - [levites]
|
||||
static const float sc_fDistanceFromTarget = 270.0f;
|
||||
|
||||
if (m_kFlyTarget.IsValidTarget())
|
||||
{
|
||||
D3DXVECTOR3 v3MainPosition(m_x, m_y, m_z);
|
||||
const D3DXVECTOR3 & c_rv3TargetPosition = __GetFlyTargetPosition();
|
||||
|
||||
D3DXVECTOR3 v3Distance = c_rv3TargetPosition - v3MainPosition;
|
||||
D3DXVec3Normalize(&v3Distance, &v3Distance);
|
||||
TPixelPosition DestPixelPosition = c_rv3TargetPosition - (v3Distance * sc_fDistanceFromTarget);
|
||||
|
||||
// 2004.07.05.myevan.궁신탄영 맵에 끼이는 문제해결. 목표위치가 이동 못하는 곳일 경우 이동하지 않는다
|
||||
IBackground& rkBG=GetBackground();
|
||||
if (!rkBG.IsBlock(DestPixelPosition.x, -DestPixelPosition.y))
|
||||
SetPixelPosition(DestPixelPosition);
|
||||
|
||||
LookAt(c_rv3TargetPosition.x, c_rv3TargetPosition.y);
|
||||
|
||||
__OnWarp();
|
||||
}
|
||||
else
|
||||
{
|
||||
//TraceError("ActorInstance::ProcessMotionEventFly No Target");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
|
||||
const TPixelPosition& CActorInstance::NEW_GetLastPixelPositionRef()
|
||||
{
|
||||
GetBlendingPosition(&m_kPPosLast);
|
||||
m_kPPosLast.y=-m_kPPosLast.y;
|
||||
|
||||
return m_kPPosLast;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3& CActorInstance::GetPositionVectorRef()
|
||||
{
|
||||
m_v3Pos.x=m_x;
|
||||
m_v3Pos.y=m_y;
|
||||
m_v3Pos.z=m_z;
|
||||
return m_v3Pos;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3& CActorInstance::GetMovementVectorRef()
|
||||
{
|
||||
if (m_pkHorse)
|
||||
return m_pkHorse->GetMovementVectorRef();
|
||||
|
||||
return m_v3Movement;
|
||||
}
|
||||
|
||||
void CActorInstance::NEW_SetAtkPixelPosition(const TPixelPosition& c_rkPPosAtk)
|
||||
{
|
||||
m_kPPosAtk=c_rkPPosAtk;
|
||||
}
|
||||
|
||||
void CActorInstance::SetCurPixelPosition(const TPixelPosition& c_rkPPosCur)
|
||||
{
|
||||
D3DXVECTOR3 v3PosCur;
|
||||
v3PosCur.x=+c_rkPPosCur.x;
|
||||
v3PosCur.y=-c_rkPPosCur.y;
|
||||
v3PosCur.z=+c_rkPPosCur.z;
|
||||
|
||||
SetPixelPosition(v3PosCur);
|
||||
}
|
||||
|
||||
void CActorInstance::NEW_SetSrcPixelPosition(const TPixelPosition& c_rkPPosSrc)
|
||||
{
|
||||
m_kPPosSrc=c_rkPPosSrc;
|
||||
}
|
||||
|
||||
void CActorInstance::NEW_SetDstPixelPositionZ(float z)
|
||||
{
|
||||
m_kPPosDst.z=z;
|
||||
}
|
||||
|
||||
void CActorInstance::NEW_SetDstPixelPosition(const TPixelPosition& c_rkPPosDst)
|
||||
{
|
||||
m_kPPosDst=c_rkPPosDst;
|
||||
}
|
||||
|
||||
const TPixelPosition& CActorInstance::NEW_GetAtkPixelPositionRef()
|
||||
{
|
||||
return m_kPPosAtk;
|
||||
}
|
||||
|
||||
const TPixelPosition& CActorInstance::NEW_GetSrcPixelPositionRef()
|
||||
{
|
||||
return m_kPPosSrc;
|
||||
}
|
||||
|
||||
|
||||
const TPixelPosition& CActorInstance::NEW_GetDstPixelPositionRef()
|
||||
{
|
||||
return m_kPPosDst;
|
||||
}
|
||||
|
||||
const TPixelPosition& CActorInstance::NEW_GetCurPixelPositionRef()
|
||||
{
|
||||
m_kPPosCur.x=+m_x;
|
||||
m_kPPosCur.y=-m_y;
|
||||
m_kPPosCur.z=+m_z;
|
||||
|
||||
return m_kPPosCur;
|
||||
}
|
||||
|
||||
void CActorInstance::GetPixelPosition(TPixelPosition * pPixelPosition)
|
||||
{
|
||||
pPixelPosition->x = m_x;
|
||||
pPixelPosition->y = m_y;
|
||||
pPixelPosition->z = m_z;
|
||||
}
|
||||
|
||||
void CActorInstance::SetPixelPosition(const TPixelPosition& c_rPixelPos)
|
||||
{
|
||||
if (m_pkTree)
|
||||
{
|
||||
__SetTreePosition(c_rPixelPos.x, c_rPixelPos.y, c_rPixelPos.z);
|
||||
}
|
||||
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->SetPixelPosition(c_rPixelPos);
|
||||
|
||||
m_x = c_rPixelPos.x;
|
||||
m_y = c_rPixelPos.y;
|
||||
m_z = c_rPixelPos.z;
|
||||
m_bNeedUpdateCollision = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::__InitializePositionData()
|
||||
{
|
||||
m_dwShakeTime = 0;
|
||||
|
||||
m_x = 0.0f;
|
||||
m_y = 0.0f;
|
||||
m_z = 0.0f;
|
||||
m_bNeedUpdateCollision = FALSE;
|
||||
|
||||
m_kPPosAtk=m_kPPosLast=m_kPPosDst=m_kPPosCur=m_kPPosSrc=TPixelPosition(0.0f, 0.0f, 0.0f);
|
||||
|
||||
__InitializeMovement();
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/StateManager.h"
|
||||
|
||||
#include "ActorInstance.h"
|
||||
|
||||
bool CActorInstance::ms_isDirLine=false;
|
||||
|
||||
bool CActorInstance::IsDirLine()
|
||||
{
|
||||
return ms_isDirLine;
|
||||
}
|
||||
|
||||
void CActorInstance::ShowDirectionLine(bool isVisible)
|
||||
{
|
||||
ms_isDirLine=isVisible;
|
||||
}
|
||||
|
||||
void CActorInstance::SetMaterialColor(DWORD dwColor)
|
||||
{
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->SetMaterialColor(dwColor);
|
||||
|
||||
m_dwMtrlColor&=0xff000000;
|
||||
m_dwMtrlColor|=(dwColor&0x00ffffff);
|
||||
}
|
||||
|
||||
void CActorInstance::SetMaterialAlpha(DWORD dwAlpha)
|
||||
{
|
||||
m_dwMtrlAlpha=dwAlpha;
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::OnRender()
|
||||
{
|
||||
D3DMATERIAL8 kMtrl;
|
||||
STATEMANAGER.GetMaterial(&kMtrl);
|
||||
|
||||
kMtrl.Diffuse=D3DXCOLOR(m_dwMtrlColor);
|
||||
STATEMANAGER.SetMaterial(&kMtrl);
|
||||
|
||||
// 현재는 이렇게.. 최종적인 형태는 Diffuse와 Blend의 분리로..
|
||||
// 아니면 이런 형태로 가되 Texture & State Sorting 지원으로.. - [levites]
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
switch(m_iRenderMode)
|
||||
{
|
||||
case RENDER_MODE_NORMAL:
|
||||
BeginDiffuseRender();
|
||||
RenderWithOneTexture();
|
||||
EndDiffuseRender();
|
||||
BeginOpacityRender();
|
||||
BlendRenderWithOneTexture();
|
||||
EndOpacityRender();
|
||||
break;
|
||||
case RENDER_MODE_BLEND:
|
||||
if (m_fAlphaValue == 1.0f)
|
||||
{
|
||||
BeginDiffuseRender();
|
||||
RenderWithOneTexture();
|
||||
EndDiffuseRender();
|
||||
BeginOpacityRender();
|
||||
BlendRenderWithOneTexture();
|
||||
EndOpacityRender();
|
||||
}
|
||||
else if (m_fAlphaValue > 0.0f)
|
||||
{
|
||||
BeginBlendRender();
|
||||
RenderWithOneTexture();
|
||||
BlendRenderWithOneTexture();
|
||||
EndBlendRender();
|
||||
}
|
||||
break;
|
||||
case RENDER_MODE_ADD:
|
||||
BeginAddRender();
|
||||
RenderWithOneTexture();
|
||||
BlendRenderWithOneTexture();
|
||||
EndAddRender();
|
||||
break;
|
||||
case RENDER_MODE_MODULATE:
|
||||
BeginModulateRender();
|
||||
RenderWithOneTexture();
|
||||
BlendRenderWithOneTexture();
|
||||
EndModulateRender();
|
||||
break;
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
|
||||
kMtrl.Diffuse=D3DXCOLOR(0xffffffff);
|
||||
STATEMANAGER.SetMaterial(&kMtrl);
|
||||
|
||||
if (ms_isDirLine)
|
||||
{
|
||||
D3DXVECTOR3 kD3DVt3Cur(m_x, m_y, m_z);
|
||||
|
||||
D3DXVECTOR3 kD3DVt3LookDir(0.0f, -1.0f, 0.0f);
|
||||
D3DXMATRIX kD3DMatLook;
|
||||
D3DXMatrixRotationZ(&kD3DMatLook, D3DXToRadian(GetRotation()));
|
||||
D3DXVec3TransformCoord(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DMatLook);
|
||||
D3DXVec3Scale(&kD3DVt3LookDir, &kD3DVt3LookDir, 200.0f);
|
||||
D3DXVec3Add(&kD3DVt3LookDir, &kD3DVt3LookDir, &kD3DVt3Cur);
|
||||
|
||||
D3DXVECTOR3 kD3DVt3AdvDir(0.0f, -1.0f, 0.0f);
|
||||
D3DXMATRIX kD3DMatAdv;
|
||||
D3DXMatrixRotationZ(&kD3DMatAdv, D3DXToRadian(GetAdvancingRotation()));
|
||||
D3DXVec3TransformCoord(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DMatAdv);
|
||||
D3DXVec3Scale(&kD3DVt3AdvDir, &kD3DVt3AdvDir, 200.0f);
|
||||
D3DXVec3Add(&kD3DVt3AdvDir, &kD3DVt3AdvDir, &kD3DVt3Cur);
|
||||
|
||||
static CScreen s_kScreen;
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, FALSE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
|
||||
s_kScreen.SetDiffuseColor(1.0f, 1.0f, 0.0f);
|
||||
s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3AdvDir.x, kD3DVt3AdvDir.y, kD3DVt3AdvDir.z);
|
||||
|
||||
s_kScreen.SetDiffuseColor(0.0f, 1.0f, 1.0f);
|
||||
s_kScreen.RenderLine3d(kD3DVt3Cur.x, kD3DVt3Cur.y, kD3DVt3Cur.z, kD3DVt3LookDir.x, kD3DVt3LookDir.y, kD3DVt3LookDir.z);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
|
||||
STATEMANAGER.RestoreVertexShader();
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::BeginDiffuseRender()
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
|
||||
void CActorInstance::EndDiffuseRender()
|
||||
{
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
}
|
||||
|
||||
void CActorInstance::BeginOpacityRender()
|
||||
{
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
}
|
||||
|
||||
void CActorInstance::EndOpacityRender()
|
||||
{
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
|
||||
}
|
||||
|
||||
void CActorInstance::BeginBlendRender()
|
||||
{
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, m_fAlphaValue));
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
|
||||
}
|
||||
|
||||
void CActorInstance::EndBlendRender()
|
||||
{
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
}
|
||||
|
||||
void CActorInstance::BeginAddRender()
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_AddColor);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
|
||||
void CActorInstance::EndAddRender()
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
}
|
||||
|
||||
void CActorInstance::RestoreRenderMode()
|
||||
{
|
||||
// NOTE : This is temporary code. I wanna convert this code to that restore the mode to
|
||||
// model's default setting which had has as like specular or normal. - [levites]
|
||||
m_iRenderMode = RENDER_MODE_NORMAL;
|
||||
if (m_kBlendAlpha.m_isBlending)
|
||||
{
|
||||
m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::SetAddRenderMode()
|
||||
{
|
||||
m_iRenderMode = RENDER_MODE_ADD;
|
||||
if (m_kBlendAlpha.m_isBlending)
|
||||
{
|
||||
m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::SetRenderMode(int iRenderMode)
|
||||
{
|
||||
m_iRenderMode = iRenderMode;
|
||||
if (m_kBlendAlpha.m_isBlending)
|
||||
{
|
||||
m_kBlendAlpha.m_iOldRenderMode = iRenderMode;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::SetAddColor(const D3DXCOLOR & c_rColor)
|
||||
{
|
||||
m_AddColor = c_rColor;
|
||||
m_AddColor.a = 1.0f;
|
||||
}
|
||||
|
||||
void CActorInstance::BeginModulateRender()
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, m_AddColor);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
}
|
||||
|
||||
void CActorInstance::EndModulateRender()
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
}
|
||||
|
||||
void CActorInstance::SetModulateRenderMode()
|
||||
{
|
||||
m_iRenderMode = RENDER_MODE_MODULATE;
|
||||
if (m_kBlendAlpha.m_isBlending)
|
||||
{
|
||||
m_kBlendAlpha.m_iOldRenderMode = m_iRenderMode;
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::RenderCollisionData()
|
||||
{
|
||||
static CScreen s_Screen;
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
if (m_pAttributeInstance)
|
||||
{
|
||||
for (DWORD col=0; col < GetCollisionInstanceCount(); ++col)
|
||||
{
|
||||
CBaseCollisionInstance * pInstance = GetCollisionInstanceData(col);
|
||||
pInstance->Render();
|
||||
}
|
||||
}
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
s_Screen.SetColorOperation();
|
||||
s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f);
|
||||
TCollisionPointInstanceList::iterator itor;
|
||||
/*itor = m_AttackingPointInstanceList.begin();
|
||||
for (; itor != m_AttackingPointInstanceList.end(); ++itor)
|
||||
{
|
||||
const TCollisionPointInstance & c_rInstance = *itor;
|
||||
for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i];
|
||||
s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x,
|
||||
c_rSphereInstance.v3Position.y,
|
||||
c_rSphereInstance.v3Position.z,
|
||||
c_rSphereInstance.fRadius);
|
||||
}
|
||||
}*/
|
||||
s_Screen.SetDiffuseColor(1.0f, (isShow())?1.0f:0.0f, 0.0f);
|
||||
D3DXVECTOR3 center;
|
||||
float r;
|
||||
GetBoundingSphere(center,r);
|
||||
s_Screen.RenderCircle3d(center.x,center.y,center.z,r);
|
||||
|
||||
s_Screen.SetDiffuseColor(0.0f, 0.0f, 1.0f);
|
||||
itor = m_DefendingPointInstanceList.begin();
|
||||
for (; itor != m_DefendingPointInstanceList.end(); ++itor)
|
||||
{
|
||||
const TCollisionPointInstance & c_rInstance = *itor;
|
||||
for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i];
|
||||
s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x,
|
||||
c_rSphereInstance.v3Position.y,
|
||||
c_rSphereInstance.v3Position.z,
|
||||
c_rSphereInstance.fRadius);
|
||||
}
|
||||
}
|
||||
|
||||
s_Screen.SetDiffuseColor(0.0f, 1.0f, 0.0f);
|
||||
itor = m_BodyPointInstanceList.begin();
|
||||
for (; itor != m_BodyPointInstanceList.end(); ++itor)
|
||||
{
|
||||
const TCollisionPointInstance & c_rInstance = *itor;
|
||||
for (DWORD i = 0; i < c_rInstance.SphereInstanceVector.size(); ++i)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rSphereInstance = c_rInstance.SphereInstanceVector[i];
|
||||
s_Screen.RenderCircle3d(c_rSphereInstance.v3Position.x,
|
||||
c_rSphereInstance.v3Position.y,
|
||||
c_rSphereInstance.v3Position.z,
|
||||
c_rSphereInstance.fRadius);
|
||||
}
|
||||
}
|
||||
|
||||
s_Screen.SetDiffuseColor(1.0f, 0.0f, 0.0f);
|
||||
// if (m_SplashArea.fDisappearingTime > GetLocalTime())
|
||||
{
|
||||
CDynamicSphereInstanceVector::iterator itor = m_kSplashArea.SphereInstanceVector.begin();
|
||||
for (; itor != m_kSplashArea.SphereInstanceVector.end(); ++itor)
|
||||
{
|
||||
const CDynamicSphereInstance & c_rInstance = *itor;
|
||||
s_Screen.RenderCircle3d(c_rInstance.v3Position.x,
|
||||
c_rInstance.v3Position.y,
|
||||
c_rInstance.v3Position.z,
|
||||
c_rInstance.fRadius);
|
||||
}
|
||||
}
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_ZENABLE, TRUE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
||||
}
|
||||
|
||||
|
||||
void CActorInstance::RenderToShadowMap()
|
||||
{
|
||||
if (RENDER_MODE_BLEND == m_iRenderMode)
|
||||
if (GetAlphaValue() < 0.5f)
|
||||
return;
|
||||
|
||||
CGraphicThingInstance::RenderToShadowMap();
|
||||
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->RenderToShadowMap();
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
|
||||
void CActorInstance::SetXYRotation(float fRotX, float fRotY)
|
||||
{
|
||||
m_rotX = fRotX;
|
||||
m_rotY = fRotY;
|
||||
}
|
||||
|
||||
void CActorInstance::SetRotation(float fRot)
|
||||
{
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->SetRotation(fRot);
|
||||
|
||||
m_fcurRotation = fRot;
|
||||
m_rotBegin = m_fcurRotation;
|
||||
m_rotEnd = m_fcurRotation;
|
||||
|
||||
m_rotBlendTime = 0.0f;
|
||||
m_rotBeginTime = 0.0f;
|
||||
m_rotEndTime = 0.0f;
|
||||
|
||||
m_bNeedUpdateCollision = TRUE;
|
||||
}
|
||||
|
||||
void CActorInstance::BlendRotation(float fRot, float fBlendTime)
|
||||
{
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->BlendRotation(fRot, fBlendTime);
|
||||
|
||||
if (m_fcurRotation == fRot)
|
||||
return;
|
||||
|
||||
m_rotBegin = fmod(m_fcurRotation, 360.0f);
|
||||
m_rotEnd = fRot;
|
||||
|
||||
m_rotBlendTime = fBlendTime;
|
||||
m_rotBeginTime = GetLocalTime();
|
||||
m_rotEndTime = m_rotBeginTime + m_rotBlendTime;
|
||||
}
|
||||
|
||||
void CActorInstance::SetAdvancingRotation(float fRot)
|
||||
{
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->SetAdvancingRotation(fRot);
|
||||
|
||||
m_fAdvancingRotation = fRot;
|
||||
}
|
||||
|
||||
void CActorInstance::RotationProcess()
|
||||
{
|
||||
if (m_pkHorse)
|
||||
m_pkHorse->RotationProcess();
|
||||
|
||||
if (GetLocalTime() < m_rotEndTime)
|
||||
{
|
||||
m_fcurRotation = GetInterpolatedRotation(m_rotBegin, m_rotEnd, (GetLocalTime() - m_rotBeginTime) / m_rotBlendTime);
|
||||
SetAdvancingRotation(m_fcurRotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fcurRotation = m_rotEnd;
|
||||
}
|
||||
|
||||
// FIXME : "건물일때만 체크"로 바꾼다. - [levites]
|
||||
if (0.0f != m_rotX || 0.0f != m_rotY)
|
||||
{
|
||||
CGraphicObjectInstance::SetRotation(m_rotX, m_rotY, m_fcurRotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGraphicObjectInstance::SetRotation(m_fcurRotation);
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::LookAtFromXY(float x, float y, CActorInstance * pDestInstance)
|
||||
{
|
||||
float rot = GetDegreeFromPosition2(pDestInstance->m_x,
|
||||
pDestInstance->m_y,
|
||||
x,
|
||||
y);
|
||||
|
||||
LookAt(rot);
|
||||
}
|
||||
|
||||
void CActorInstance::LookAt(float fDirRot)
|
||||
{
|
||||
BlendRotation(fDirRot, 0.3f);
|
||||
}
|
||||
|
||||
void CActorInstance::LookAt(float fx, float fy)
|
||||
{
|
||||
float rot = GetDegreeFromPosition2(m_x, m_y, fx, fy);
|
||||
|
||||
LookAt(rot);
|
||||
}
|
||||
|
||||
void CActorInstance::LookAt(CActorInstance * pInstance)
|
||||
{
|
||||
TPixelPosition PixelPosition;
|
||||
pInstance->GetPixelPosition(&PixelPosition);
|
||||
LookAt(PixelPosition.x, PixelPosition.y);
|
||||
}
|
||||
|
||||
void CActorInstance::LookWith(CActorInstance * pInstance)
|
||||
{
|
||||
BlendRotation(pInstance->m_rotEnd, 0.3f);
|
||||
}
|
||||
|
||||
float CActorInstance::GetRotation()
|
||||
{
|
||||
return m_fcurRotation;
|
||||
}
|
||||
|
||||
float CActorInstance::GetTargetRotation()
|
||||
{
|
||||
return m_rotEnd;
|
||||
}
|
||||
|
||||
float CActorInstance::GetRotatingTime()
|
||||
{
|
||||
return m_rotEndTime;
|
||||
}
|
||||
|
||||
float CActorInstance::GetAdvancingRotation()
|
||||
{
|
||||
return m_fAdvancingRotation;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
#include "RaceData.h"
|
||||
|
||||
|
||||
|
||||
void CActorInstance::__Push(int x, int y)
|
||||
{
|
||||
if (IsResistFallen())
|
||||
return;
|
||||
|
||||
//DWORD dwVID=GetVirtualID();
|
||||
//Tracenf("VID %d SyncPixelPosition %d %d", dwVID, x, y);
|
||||
|
||||
const D3DXVECTOR3& c_rv3Src=GetPosition();
|
||||
const D3DXVECTOR3 c_v3Dst=D3DXVECTOR3(x, -y, c_rv3Src.z);
|
||||
const D3DXVECTOR3 c_v3Delta=c_v3Dst-c_rv3Src;
|
||||
|
||||
const int LoopValue = 100;
|
||||
const D3DXVECTOR3 inc=c_v3Delta / LoopValue;
|
||||
|
||||
D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f);
|
||||
|
||||
IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld();
|
||||
|
||||
if (!pWorld)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < LoopValue; ++i)
|
||||
{
|
||||
if (pWorld->isPhysicalCollision(c_rv3Src + v3Movement))
|
||||
{
|
||||
ResetBlendingPosition();
|
||||
return;
|
||||
}
|
||||
v3Movement += inc;
|
||||
}
|
||||
|
||||
SetBlendingPosition(c_v3Dst);
|
||||
|
||||
if (!IsUsingSkill())
|
||||
{
|
||||
int len=sqrt(c_v3Delta.x*c_v3Delta.x+c_v3Delta.y*c_v3Delta.y);
|
||||
if (len>150.0f)
|
||||
{
|
||||
InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
|
||||
PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::TEMP_Push(int x, int y)
|
||||
{
|
||||
__Push(x, y);
|
||||
}
|
||||
|
||||
bool CActorInstance::__IsSyncing()
|
||||
{
|
||||
if (IsDead())
|
||||
return TRUE;
|
||||
|
||||
if (IsStun())
|
||||
return TRUE;
|
||||
|
||||
if (IsPushing())
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool CActorInstance::IsPushing()
|
||||
{
|
||||
return m_PhysicsObject.isBlending();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "StdAfx.h"
|
||||
#include "ActorInstance.h"
|
||||
#include "WeaponTrace.h"
|
||||
|
||||
void CActorInstance::TraceProcess()
|
||||
{
|
||||
if (!m_WeaponTraceVector.empty())
|
||||
{
|
||||
std::vector<CWeaponTrace*>::iterator it;
|
||||
for(it = m_WeaponTraceVector.begin(); it != m_WeaponTraceVector.end(); ++it)
|
||||
{
|
||||
CWeaponTrace * pWeaponTrace = (*it);
|
||||
pWeaponTrace->SetPosition(m_x, m_y, m_z);
|
||||
pWeaponTrace->SetRotation(m_fcurRotation);
|
||||
pWeaponTrace->Update(__GetReachScale());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::RenderTrace()
|
||||
{
|
||||
for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::Render));
|
||||
}
|
||||
|
||||
void CActorInstance::__DestroyWeaponTrace()
|
||||
{
|
||||
std::for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), CWeaponTrace::Delete);
|
||||
m_WeaponTraceVector.clear();
|
||||
}
|
||||
|
||||
void CActorInstance::__ShowWeaponTrace()
|
||||
{
|
||||
for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::TurnOn));
|
||||
}
|
||||
|
||||
void CActorInstance::__HideWeaponTrace()
|
||||
{
|
||||
for_each(m_WeaponTraceVector.begin(), m_WeaponTraceVector.end(), std::mem_fn(&CWeaponTrace::TurnOff));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,310 @@
|
||||
#pragma once
|
||||
|
||||
#include "../SpeedTreeLib/SpeedTreeWrapper.h"
|
||||
#include "../eterGrnLib/ThingInstance.h"
|
||||
#include "MapType.h"
|
||||
#include "DungeonBlock.h"
|
||||
|
||||
class CMapOutdoor;
|
||||
class CEffectInstance;
|
||||
|
||||
class CArea
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ROTATION_STEP_COUNT = 24,
|
||||
ROTATION_STEP_AMOUNT = 360 / ROTATION_STEP_COUNT,
|
||||
YAW_STEP_COUNT = 24,
|
||||
YAW_STEP_AMOUNT = 360 / YAW_STEP_COUNT,
|
||||
PITCH_STEP_COUNT = YAW_STEP_COUNT,
|
||||
PITCH_STEP_AMOUNT = YAW_STEP_AMOUNT,
|
||||
};
|
||||
|
||||
typedef D3DXVECTOR3 TObjectPosition;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Object Static Data
|
||||
typedef struct SObjectData
|
||||
{
|
||||
TObjectPosition Position;
|
||||
DWORD dwCRC;
|
||||
BYTE abyPortalID[PORTAL_ID_MAX_NUM];
|
||||
|
||||
// For Tree
|
||||
// - Nothing
|
||||
|
||||
// For Granny Thing
|
||||
float m_fYaw;
|
||||
float m_fPitch;
|
||||
float m_fRoll;
|
||||
float m_fHeightBias;
|
||||
|
||||
// For Effect
|
||||
// - Nothing
|
||||
|
||||
// For Ambience
|
||||
DWORD dwRange;
|
||||
float fMaxVolumeAreaPercentage;
|
||||
|
||||
void InitializeRotation();
|
||||
} TObjectData;
|
||||
|
||||
struct ObjectDataComp
|
||||
{
|
||||
bool operator () (TObjectData & lhs, TObjectData & rhs) const
|
||||
{
|
||||
return lhs.dwCRC < rhs.dwCRC;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<TObjectData> TObjectDataVector;
|
||||
typedef TObjectDataVector::iterator TObjectDataIterator;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Object Dynamic Data
|
||||
typedef struct SAmbienceInstance : public CScreen
|
||||
{
|
||||
float fx, fy, fz;
|
||||
DWORD dwRange;
|
||||
float fMaxVolumeAreaPercentage;
|
||||
int iPlaySoundIndex;
|
||||
float fNextPlayTime;
|
||||
prt::TPropertyAmbience AmbienceData;
|
||||
|
||||
SAmbienceInstance();
|
||||
virtual ~SAmbienceInstance() {}
|
||||
void __Update(float fxCenter, float fyCenter, float fzCenter);
|
||||
void (SAmbienceInstance::*Update)(float fxCenter, float fyCenter, float fzCenter);
|
||||
void UpdateOnceSound(float fxCenter, float fyCenter, float fzCenter);
|
||||
void UpdateStepSound(float fxCenter, float fyCenter, float fzCenter);
|
||||
void UpdateLoopSound(float fxCenter, float fyCenter, float fzCenter);
|
||||
void Render();
|
||||
bool Picking();
|
||||
float __GetVolumeFromDistance(float fDistance);
|
||||
} TAmbienceInstance;
|
||||
|
||||
typedef struct SObjectInstance
|
||||
{
|
||||
DWORD dwType;
|
||||
CAttributeInstance * pAttributeInstance;
|
||||
|
||||
// Data For Tree
|
||||
CSpeedTreeWrapper * pTree;
|
||||
|
||||
// Data For Normal Object or Building
|
||||
BOOL isShadowFlag;
|
||||
CGraphicThingInstance * pThingInstance;
|
||||
|
||||
// Data for Effect
|
||||
DWORD dwEffectID;
|
||||
DWORD dwEffectInstanceIndex;
|
||||
|
||||
// Data For Ambience
|
||||
TAmbienceInstance * pAmbienceInstance;
|
||||
|
||||
// Dungeon
|
||||
CDungeonBlock * pDungeonBlock;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (pTree)
|
||||
pTree->Clear();
|
||||
|
||||
if (pThingInstance)
|
||||
pThingInstance->Clear();
|
||||
|
||||
if (pAttributeInstance)
|
||||
pAttributeInstance->Clear();
|
||||
|
||||
if (pAmbienceInstance)
|
||||
pAmbienceInstance->Clear();
|
||||
|
||||
if (pDungeonBlock)
|
||||
pDungeonBlock->Clear();
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void SetTree(float x, float y, float z, DWORD dwTreeCRC, const char* c_szTreeName);
|
||||
|
||||
void __Initialize()
|
||||
{
|
||||
dwType = prt::PROPERTY_TYPE_NONE;
|
||||
|
||||
dwEffectID = 0xffffffff;
|
||||
dwEffectInstanceIndex = 0xffffffff;
|
||||
isShadowFlag = false;
|
||||
|
||||
pTree=NULL;
|
||||
pThingInstance=NULL;
|
||||
pAttributeInstance=NULL;
|
||||
pAmbienceInstance=NULL;
|
||||
pDungeonBlock=NULL;
|
||||
}
|
||||
|
||||
SObjectInstance()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
virtual ~SObjectInstance()
|
||||
{
|
||||
}
|
||||
} TObjectInstance;
|
||||
|
||||
typedef std::vector<CSpeedTreeWrapper *> TTreeInstanceVector;
|
||||
typedef std::vector<CGraphicThingInstance *> TThingInstanceVector;
|
||||
typedef std::vector<CDungeonBlock *> TDungeonBlockInstanceVector;
|
||||
typedef std::vector<TObjectInstance *> TObjectInstanceVector;
|
||||
typedef std::vector<TAmbienceInstance *> TAmbienceInstanceVector;
|
||||
typedef std::map<CGraphicThingInstance *, DWORD> TGraphicThingInstanceCRCMap; // 최적화용 by 동현
|
||||
typedef std::set<int> TShowingPortalIDSet;
|
||||
|
||||
typedef struct SCRCWithNumber
|
||||
{
|
||||
DWORD dwCRC;
|
||||
DWORD dwNumber;
|
||||
} TCRCWithNumber;
|
||||
|
||||
typedef std::vector<TCRCWithNumber> TCRCWithNumberVector;
|
||||
|
||||
struct FFindIfCRC
|
||||
{
|
||||
|
||||
FFindIfCRC(DWORD dwCRC) { m_dwCRC = dwCRC; }
|
||||
|
||||
bool operator() (TCRCWithNumber & rCRCWithNumber)
|
||||
{
|
||||
if (rCRCWithNumber.dwCRC == m_dwCRC)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD m_dwCRC;
|
||||
};
|
||||
|
||||
struct CRCNumComp
|
||||
{
|
||||
bool operator () (TCRCWithNumber & lhs, TCRCWithNumber & rhs) const
|
||||
{
|
||||
return lhs.dwNumber > rhs.dwNumber;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
CArea();
|
||||
virtual ~CArea();
|
||||
|
||||
void CollectRenderingObject(std::vector<CGraphicThingInstance*>& rkVct_pkOpaqueThingInst);
|
||||
void CollectBlendRenderingObject(std::vector<CGraphicThingInstance*>& rkVct_pkBlendThingInst);
|
||||
|
||||
void SetMapOutDoor(CMapOutdoor * pOwnerOutdoorMap);
|
||||
void Clear();
|
||||
|
||||
bool Load(const char * c_szPathName);
|
||||
|
||||
DWORD GetObjectDataCount();
|
||||
bool GetObjectDataPointer(DWORD dwIndex, const TObjectData ** ppObjectData) const;
|
||||
|
||||
const DWORD GetObjectInstanceCount() const;
|
||||
const bool GetObjectInstancePointer(const DWORD & dwIndex, const TObjectInstance ** ppObjectInstance) const;
|
||||
|
||||
void EnablePortal(BOOL bFlag=TRUE);
|
||||
void ClearPortal();
|
||||
void AddShowingPortalID(int iNum);
|
||||
void RefreshPortal();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Update();
|
||||
void UpdateAroundAmbience(float fX, float fY, float fZ);
|
||||
|
||||
void Render();
|
||||
void RenderEffect();
|
||||
void RenderCollision();
|
||||
void RenderAmbience();
|
||||
void RenderDungeon();
|
||||
void Refresh();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SetCoordinate(const WORD & c_usCoordX, const WORD & c_usCoordY);
|
||||
void GetCoordinate(WORD * usCoordX, WORD * usCoordY);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DWORD DEBUG_GetRenderedCRCNum();
|
||||
TCRCWithNumberVector & DEBUG_GetRenderedCRCWithNumVector();
|
||||
DWORD DEBUG_GetRenderedGrapphicThingInstanceNum();
|
||||
|
||||
CMapOutdoor * GetOwner() { return m_pOwnerOutdoorMap; }
|
||||
|
||||
protected:
|
||||
|
||||
bool CheckObjectIndex(DWORD dwIndex) const;
|
||||
|
||||
bool __Load_LoadObject(const char * c_szFileName);
|
||||
bool __Load_LoadAmbience(const char * c_szFileName);
|
||||
void __Load_BuildObjectInstances();
|
||||
|
||||
void __UpdateAniThingList();
|
||||
void __UpdateEffectList();
|
||||
|
||||
void __LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName);
|
||||
|
||||
protected:
|
||||
void __Clear_DestroyObjectInstance(TObjectInstance * pObjectInstance);
|
||||
|
||||
void __SetObjectInstance(TObjectInstance * pObjectInstance, const TObjectData * c_pData);
|
||||
void __SetObjectInstance_SetTree(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty);
|
||||
void __SetObjectInstance_SetBuilding(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty);
|
||||
void __SetObjectInstance_SetEffect(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty);
|
||||
void __SetObjectInstance_SetAmbience(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty);
|
||||
void __SetObjectInstance_SetDungeonBlock(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty);
|
||||
|
||||
protected:
|
||||
// Static Data
|
||||
TObjectDataVector m_ObjectDataVector; // Area 상에 있는 오브젝트들
|
||||
|
||||
// Rendering Instances
|
||||
TObjectInstanceVector m_ObjectInstanceVector;
|
||||
|
||||
// Clone Instance Vector
|
||||
TTreeInstanceVector m_TreeCloneInstaceVector;
|
||||
TThingInstanceVector m_ThingCloneInstaceVector;
|
||||
TDungeonBlockInstanceVector m_DungeonBlockCloneInstanceVector;
|
||||
TThingInstanceVector m_AniThingCloneInstanceVector;
|
||||
TThingInstanceVector m_ShadowThingCloneInstaceVector;
|
||||
TAmbienceInstanceVector m_AmbienceCloneInstanceVector;
|
||||
TGraphicThingInstanceCRCMap m_GraphicThingInstanceCRCMap;
|
||||
TCRCWithNumberVector m_kRenderedThingInstanceCRCWithNumberVector;
|
||||
TThingInstanceVector m_kRenderedGrapphicThingInstanceVector;
|
||||
|
||||
// 좌표 : 심리스 맵 전체 중에서의 좌표... 둘다 0~999
|
||||
WORD m_wX;
|
||||
WORD m_wY;
|
||||
|
||||
// Owner COutdoorMap poineter
|
||||
CMapOutdoor * m_pOwnerOutdoorMap;
|
||||
|
||||
protected:
|
||||
static CDynamicPool<TObjectInstance> ms_ObjectInstancePool;
|
||||
static CDynamicPool<CAttributeInstance> ms_AttributeInstancePool;
|
||||
static CDynamicPool<TAmbienceInstance> ms_AmbienceInstancePool;
|
||||
static CDynamicPool<CDungeonBlock> ms_DungeonBlockInstancePool;
|
||||
|
||||
typedef std::map<DWORD, CEffectInstance*> TEffectInstanceMap;
|
||||
typedef TEffectInstanceMap::iterator TEffectInstanceIterator;
|
||||
TEffectInstanceMap m_EffectInstanceMap;
|
||||
|
||||
BOOL m_bPortalEnable;
|
||||
TShowingPortalIDSet m_kSet_ShowingPortalID;
|
||||
|
||||
public:
|
||||
static void DestroySystem();
|
||||
|
||||
static CArea* New();
|
||||
static void Delete(CArea* pkArea);
|
||||
|
||||
static CDynamicPool<CArea> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,340 @@
|
||||
// AreaLoaderThread.cpp: implementation of the CAreaLoaderThread class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
|
||||
#include "AreaLoaderThread.h"
|
||||
#include "AreaTerrain.h"
|
||||
#include "MapOutdoor.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEMP_CAreaLoaderThread::TEMP_CAreaLoaderThread() : m_bShutdowned(false), m_pArg(NULL), m_hThread(NULL), m_uThreadID(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TEMP_CAreaLoaderThread::~TEMP_CAreaLoaderThread()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool TEMP_CAreaLoaderThread::Create(void * arg)
|
||||
{
|
||||
Arg(arg);
|
||||
m_hThread = (HANDLE) _beginthreadex(NULL, 0, EntryPoint, this, 0, &m_uThreadID);
|
||||
|
||||
if (!m_hThread)
|
||||
return false;
|
||||
|
||||
SetThreadPriority(m_hThread, THREAD_PRIORITY_NORMAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
UINT TEMP_CAreaLoaderThread::Run(void * arg)
|
||||
{
|
||||
if (!Setup())
|
||||
return 0;
|
||||
|
||||
return (Execute(arg));
|
||||
}
|
||||
|
||||
/* Static */
|
||||
UINT CALLBACK TEMP_CAreaLoaderThread::EntryPoint(void * pThis)
|
||||
{
|
||||
TEMP_CAreaLoaderThread * pThread = (TEMP_CAreaLoaderThread *) pThis;
|
||||
return pThread->Run(pThread->Arg());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void TEMP_CAreaLoaderThread::Destroy()
|
||||
{
|
||||
if (m_hSemaphore)
|
||||
{
|
||||
CloseHandle(m_hSemaphore);
|
||||
m_hSemaphore = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
while(!m_pTerrainRequestDeque.empty())
|
||||
{
|
||||
CTerrain * pTerrain = m_pTerrainRequestDeque.front();
|
||||
delete pTerrain;
|
||||
pTerrain = NULL;
|
||||
m_pTerrainRequestDeque.pop_front();
|
||||
}
|
||||
|
||||
while(!m_pTerrainCompleteDeque.empty())
|
||||
{
|
||||
CTerrain * pTerrain = m_pTerrainCompleteDeque.front();
|
||||
delete pTerrain;
|
||||
pTerrain = NULL;
|
||||
m_pTerrainCompleteDeque.pop_front();
|
||||
}
|
||||
*/
|
||||
|
||||
/*stl_wipe(m_pTerrainRequestDeque);
|
||||
stl_wipe(m_pTerrainCompleteDeque);
|
||||
stl_wipe(m_pAreaRequestDeque);
|
||||
stl_wipe(m_pAreaCompleteDeque);*/
|
||||
}
|
||||
|
||||
UINT TEMP_CAreaLoaderThread::Setup()
|
||||
{
|
||||
m_hSemaphore = CreateSemaphore(NULL, // no security attributes
|
||||
0, // initial count
|
||||
65535, // maximum count
|
||||
NULL); // unnamed semaphore
|
||||
if (!m_hSemaphore)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TEMP_CAreaLoaderThread::Shutdown()
|
||||
{
|
||||
if (!m_hSemaphore)
|
||||
return;
|
||||
|
||||
BOOL bRet;
|
||||
|
||||
m_bShutdowned = true;
|
||||
|
||||
do
|
||||
{
|
||||
bRet = ReleaseSemaphore(m_hSemaphore, 1, NULL);
|
||||
}
|
||||
while (!bRet);
|
||||
|
||||
WaitForSingleObject(m_hThread, 10000); // 쓰레드가 종료 되기를 10초 기다림
|
||||
}
|
||||
|
||||
UINT TEMP_CAreaLoaderThread::Execute(void * pvArg)
|
||||
{
|
||||
bool bProcessTerrain = true;
|
||||
while (!m_bShutdowned)
|
||||
{
|
||||
DWORD dwWaitResult;
|
||||
|
||||
dwWaitResult = WaitForSingleObject(m_hSemaphore, INFINITE);
|
||||
|
||||
if (m_bShutdowned)
|
||||
break;
|
||||
|
||||
switch (dwWaitResult)
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
if (bProcessTerrain)
|
||||
ProcessTerrain();
|
||||
else
|
||||
ProcessArea();
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
TraceError("TEMP_CAreaLoaderThread::Execute: Timeout occured while time-out interval is INIFITE");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Destroy();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TEMP_CAreaLoaderThread::Request(CTerrain * pTerrain) // called in main thread
|
||||
{
|
||||
m_TerrainRequestMutex.Lock();
|
||||
m_pTerrainRequestDeque.push_back(pTerrain);
|
||||
m_TerrainRequestMutex.Unlock();
|
||||
|
||||
++m_iRestSemCount;
|
||||
|
||||
if (!ReleaseSemaphore(m_hSemaphore, m_iRestSemCount, NULL))
|
||||
TraceError("TEMP_CAreaLoaderThread::Request: ReleaseSemaphore error");
|
||||
|
||||
--m_iRestSemCount;
|
||||
}
|
||||
|
||||
bool TEMP_CAreaLoaderThread::Fetch(CTerrain ** ppTerrain) // called in main thread
|
||||
{
|
||||
m_TerrainCompleteMutex.Lock();
|
||||
|
||||
if (m_pTerrainCompleteDeque.empty())
|
||||
{
|
||||
m_TerrainCompleteMutex.Unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
*ppTerrain = m_pTerrainCompleteDeque.front();
|
||||
m_pTerrainCompleteDeque.pop_front();
|
||||
|
||||
m_TerrainCompleteMutex.Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TEMP_CAreaLoaderThread::Request(CArea * pArea) // called in main thread
|
||||
{
|
||||
m_AreaRequestMutex.Lock();
|
||||
m_pAreaRequestDeque.push_back(pArea);
|
||||
m_AreaRequestMutex.Unlock();
|
||||
|
||||
++m_iRestSemCount;
|
||||
|
||||
if (!ReleaseSemaphore(m_hSemaphore, m_iRestSemCount, NULL))
|
||||
TraceError("TEMP_CAreaLoaderThread::Request: ReleaseSemaphore error");
|
||||
|
||||
--m_iRestSemCount;
|
||||
}
|
||||
|
||||
bool TEMP_CAreaLoaderThread::Fetch(CArea ** ppArea) // called in main thread
|
||||
{
|
||||
m_AreaCompleteMutex.Lock();
|
||||
|
||||
if (m_pAreaCompleteDeque.empty())
|
||||
{
|
||||
m_AreaCompleteMutex.Unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
*ppArea = m_pAreaCompleteDeque.front();
|
||||
m_pAreaCompleteDeque.pop_front();
|
||||
|
||||
m_AreaCompleteMutex.Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TEMP_CAreaLoaderThread::ProcessArea() // called in loader thread
|
||||
{
|
||||
m_AreaRequestMutex.Lock();
|
||||
|
||||
if (m_pAreaRequestDeque.empty())
|
||||
{
|
||||
m_AreaRequestMutex.Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
CArea * pArea = m_pAreaRequestDeque.front();
|
||||
m_pAreaRequestDeque.pop_front();
|
||||
|
||||
Tracef("TEMP_CAreaLoaderThread::ProcessArea() RequestDeque Size : %d\n", m_pAreaRequestDeque.size());
|
||||
m_AreaRequestMutex.Unlock();
|
||||
|
||||
DWORD dwStartTime = ELTimer_GetMSec();
|
||||
|
||||
// Area Load
|
||||
WORD wAreaCoordX, wAreaCoordY;
|
||||
pArea->GetCoordinate(&wAreaCoordX, &wAreaCoordY);
|
||||
DWORD dwID = (DWORD) (wAreaCoordX) * 1000L + (DWORD) (wAreaCoordY);
|
||||
|
||||
const std::string & c_rStrMapName = pArea->GetOwner()->GetName();
|
||||
|
||||
char szAreaPathName[64+1];
|
||||
_snprintf(szAreaPathName, sizeof(szAreaPathName), "%s\\%06u\\", c_rStrMapName.c_str(), dwID);
|
||||
|
||||
pArea->Load(szAreaPathName);
|
||||
|
||||
Tracef("TEMP_CAreaLoaderThread::ProcessArea LoadArea : %d ms elapsed\n", ELTimer_GetMSec() - dwStartTime);
|
||||
|
||||
m_AreaCompleteMutex.Lock();
|
||||
m_pAreaCompleteDeque.push_back(pArea);
|
||||
m_AreaCompleteMutex.Unlock();
|
||||
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
}
|
||||
|
||||
void TEMP_CAreaLoaderThread::ProcessTerrain() // called in loader thread
|
||||
{
|
||||
m_TerrainRequestMutex.Lock();
|
||||
|
||||
if (m_pTerrainRequestDeque.empty())
|
||||
{
|
||||
m_TerrainRequestMutex.Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
CTerrain * pTerrain = m_pTerrainRequestDeque.front();
|
||||
m_pTerrainRequestDeque.pop_front();
|
||||
|
||||
Tracef("TEMP_CAreaLoaderThread::ProcessTerrain() RequestDeque Size : %d\n", m_pTerrainRequestDeque.size());
|
||||
m_TerrainRequestMutex.Unlock();
|
||||
|
||||
DWORD dwStartTime = ELTimer_GetMSec();
|
||||
|
||||
// Terrain Load
|
||||
WORD wCoordX, wCoordY;
|
||||
pTerrain->GetCoordinate(&wCoordX, &wCoordY);
|
||||
DWORD dwID = (DWORD) (wCoordX) * 1000L + (DWORD) (wCoordY);
|
||||
|
||||
const std::string & c_rStrMapName = pTerrain->GetOwner()->GetName();
|
||||
char filename[256];
|
||||
sprintf(filename, "%s\\%06u\\AreaProperty.txt", c_rStrMapName.c_str(), dwID);
|
||||
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(filename, stTokenVectorMap))
|
||||
return;
|
||||
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
|
||||
return;
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("areaname"))
|
||||
return;
|
||||
|
||||
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
|
||||
const std::string & c_rstrAreaName = stTokenVectorMap["areaname"][0];
|
||||
|
||||
if (c_rstrType != "AreaProperty")
|
||||
return;
|
||||
|
||||
char szRawHeightFieldname[64+1];
|
||||
char szWaterMapName[64+1];
|
||||
char szAttrMapName[64+1];
|
||||
char szShadowTexName[64+1];
|
||||
char szShadowMapName[64+1];
|
||||
char szMiniMapTexName[64+1];
|
||||
char szSplatName[64+1];
|
||||
|
||||
_snprintf(szRawHeightFieldname, sizeof(szRawHeightFieldname), "%s\\%06u\\height.raw", c_rStrMapName.c_str(), dwID);
|
||||
_snprintf(szSplatName, sizeof(szSplatName), "%s\\%06u\\tile.raw", c_rStrMapName.c_str(), dwID);
|
||||
_snprintf(szAttrMapName, sizeof(szAttrMapName), "%s\\%06u\\attr.atr", c_rStrMapName.c_str(), dwID);
|
||||
_snprintf(szWaterMapName, sizeof(szWaterMapName), "%s\\%06u\\water.wtr", c_rStrMapName.c_str(), dwID);
|
||||
_snprintf(szShadowTexName, sizeof(szShadowTexName), "%s\\%06u\\shadowmap.dds", c_rStrMapName.c_str(), dwID);
|
||||
_snprintf(szShadowMapName, sizeof(szShadowMapName), "%s\\%06u\\shadowmap.raw", c_rStrMapName.c_str(), dwID);
|
||||
_snprintf(szMiniMapTexName, sizeof(szMiniMapTexName), "%s\\%06u\\minimap.dds", c_rStrMapName.c_str(), dwID);
|
||||
|
||||
pTerrain->CopySettingFromGlobalSetting();
|
||||
|
||||
pTerrain->LoadWaterMap(szWaterMapName);
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->LoadHeightMap(szRawHeightFieldname);
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->LoadAttrMap(szAttrMapName);
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->RAW_LoadTileMap(szSplatName, true);
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->LoadShadowTexture(szShadowTexName);
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->LoadShadowMap(szShadowMapName);
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->LoadMiniMapTexture(szMiniMapTexName);
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->SetName(c_rstrAreaName.c_str());
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
pTerrain->CalculateTerrainPatch();
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
|
||||
pTerrain->SetReady();
|
||||
|
||||
Tracef("TEMP_CAreaLoaderThread::ProcessTerrain LoadTerrain : %d ms elapsed\n", ELTimer_GetMSec() - dwStartTime);
|
||||
|
||||
m_TerrainCompleteMutex.Lock();
|
||||
m_pTerrainCompleteDeque.push_back(pTerrain);
|
||||
m_TerrainCompleteMutex.Unlock();
|
||||
|
||||
Sleep(g_iLoadingDelayTime);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// AreaLoaderThread.h: interface for the CAreaLoaderThread class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_AREALOADERTHREAD_H__E43FBE42_42F4_4F0E_B9DA_D7B7C5EA0753__INCLUDED_)
|
||||
#define AFX_AREALOADERTHREAD_H__E43FBE42_42F4_4F0E_B9DA_D7B7C5EA0753__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../eterLib/Mutex.h"
|
||||
|
||||
class CTerrain;
|
||||
class CArea;
|
||||
|
||||
class TEMP_CAreaLoaderThread
|
||||
{
|
||||
public:
|
||||
TEMP_CAreaLoaderThread();
|
||||
virtual ~TEMP_CAreaLoaderThread();
|
||||
|
||||
bool Create(void * arg);
|
||||
void Shutdown();
|
||||
|
||||
void Request(CTerrain * pTerrain);
|
||||
|
||||
bool Fetch(CTerrain ** ppTerrian);
|
||||
|
||||
void Request(CArea * pArea);
|
||||
|
||||
bool Fetch(CArea ** ppArea);
|
||||
|
||||
protected:
|
||||
static UINT CALLBACK EntryPoint(void * pThis);
|
||||
UINT Run(void * arg);
|
||||
|
||||
void * Arg() const { return m_pArg; }
|
||||
void Arg(void * arg) { m_pArg = arg; }
|
||||
|
||||
HANDLE m_hThread;
|
||||
|
||||
private:
|
||||
void * m_pArg;
|
||||
unsigned m_uThreadID;
|
||||
|
||||
protected:
|
||||
UINT Setup();
|
||||
UINT Execute(void * pvArg);
|
||||
void Destroy();
|
||||
void ProcessTerrain();
|
||||
void ProcessArea();
|
||||
|
||||
private:
|
||||
std::deque<CTerrain *> m_pTerrainRequestDeque;
|
||||
Mutex m_TerrainRequestMutex;
|
||||
|
||||
std::deque<CTerrain *> m_pTerrainCompleteDeque;
|
||||
Mutex m_TerrainCompleteMutex;
|
||||
|
||||
std::deque<CArea *> m_pAreaRequestDeque;
|
||||
Mutex m_AreaRequestMutex;
|
||||
|
||||
std::deque<CArea *> m_pAreaCompleteDeque;
|
||||
Mutex m_AreaCompleteMutex;
|
||||
|
||||
HANDLE m_hSemaphore;
|
||||
int m_iRestSemCount;
|
||||
bool m_bShutdowned;
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_AREALOADERTHREAD_H__E43FBE42_42F4_4F0E_B9DA_D7B7C5EA0753__INCLUDED_)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,160 @@
|
||||
#pragma once
|
||||
|
||||
class CMapOutdoor;
|
||||
|
||||
#include "../PRTerrainLib/Terrain.h"
|
||||
#include "TerrainPatch.h"
|
||||
|
||||
class CTerrain : public CTerrainImpl, public CGraphicBase
|
||||
{
|
||||
public:
|
||||
|
||||
enum EBoundaryLoadPart
|
||||
{
|
||||
LOAD_INVALID,
|
||||
LOAD_NOBOUNDARY,
|
||||
LOAD_TOPLEFT,
|
||||
LOAD_TOP,
|
||||
LOAD_TOPRIGHT,
|
||||
LOAD_LEFT,
|
||||
LOAD_RIGHT,
|
||||
LOAD_BOTTOMLEFT,
|
||||
LOAD_BOTTOM,
|
||||
LOAD_BOTTOMRIGHT,
|
||||
LOAD_ALLBOUNDARY,
|
||||
};
|
||||
|
||||
CTerrain();
|
||||
virtual ~CTerrain();
|
||||
|
||||
virtual void Clear();
|
||||
|
||||
void SetMapOutDoor(CMapOutdoor * pOwnerOutdoorMap);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Loading
|
||||
bool RAW_LoadTileMap(const char * c_pszFileName, bool bBGLoading = false);
|
||||
|
||||
bool LoadHeightMap(const char * c_pszFileName);
|
||||
|
||||
void CalculateTerrainPatch();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CopySettingFromGlobalSetting();
|
||||
|
||||
WORD WE_GetHeightMapValue(short sX, short sY);
|
||||
|
||||
bool IsReady() { return m_bReady; }
|
||||
void SetReady(bool bReady = true) { m_bReady = bReady; }
|
||||
|
||||
// Height Map
|
||||
WORD * GetHeightMap() { return m_awRawHeightMap; }
|
||||
float GetHeight(int x, int y);
|
||||
|
||||
// Normal Map
|
||||
bool GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal);
|
||||
|
||||
// TileMap
|
||||
BYTE * RAW_GetTileMap() { return m_abyTileMap; }
|
||||
char * GetNormalMap() { return m_acNormalMap; }
|
||||
|
||||
// Attr
|
||||
bool LoadAttrMap(const char * c_pszFileName);
|
||||
BYTE * GetAttrMap() { return m_abyAttrMap; }
|
||||
BYTE GetAttr(WORD wCoordX, WORD wCoordY);
|
||||
bool isAttrOn(WORD wCoordX, WORD wCoordY, BYTE byAttrFlag);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Water
|
||||
BYTE * GetWaterMap() { return m_abyWaterMap; }
|
||||
void GetWaterHeight(BYTE byWaterNum, long * plWaterHeight);
|
||||
bool GetWaterHeight(WORD wCoordX, WORD wCoordY, long * plWaterHeight);
|
||||
|
||||
// Shadow Texture
|
||||
void LoadShadowTexture(const char * c_pszFileName);
|
||||
|
||||
// Shadow Map
|
||||
bool LoadShadowMap(const char * c_pszFileName);
|
||||
|
||||
// MiniMap
|
||||
void LoadMiniMapTexture(const char * c_pszFileName);
|
||||
inline LPDIRECT3DTEXTURE8 GetMiniMapTexture() { return m_lpMiniMapTexture; }
|
||||
|
||||
// Marked Area
|
||||
BOOL IsMarked() { return m_bMarked; }
|
||||
void AllocateMarkedSplats(BYTE * pbyAlphaMap);
|
||||
void DeallocateMarkedSplats();
|
||||
TTerrainSplatPatch & GetMarkedSplatPatch() { return m_MarkedSplatPatch; }
|
||||
|
||||
// Coordinate
|
||||
void GetCoordinate(WORD * usCoordX, WORD * usCoordY)
|
||||
{
|
||||
*usCoordX = m_wX;
|
||||
*usCoordY = m_wY;
|
||||
}
|
||||
|
||||
void SetCoordinate(WORD wCoordX, WORD wCoordY);
|
||||
|
||||
std::string & GetName() { return m_strName; }
|
||||
void SetName(const std::string c_strName) { m_strName = c_strName; }
|
||||
|
||||
CMapOutdoor * GetOwner() { return m_pOwnerOutdoorMap; }
|
||||
void RAW_GenerateSplat(bool bBGLoading = false);
|
||||
|
||||
protected:
|
||||
bool Initialize();
|
||||
void RAW_AllocateSplats(bool bBGLoading = false);
|
||||
void RAW_DeallocateSplats(bool bBGLoading = false);
|
||||
virtual void RAW_CountTiles();
|
||||
|
||||
LPDIRECT3DTEXTURE8 AddTexture32(BYTE byImageNum, BYTE * pbyImage, long lTextureWidth, long lTextureHeight);
|
||||
void PutImage32(BYTE * pbySrc, BYTE * pbyDst, long src_pitch, long dst_pitch, long lTextureWidth, long lTextureHeight, bool bResize = false);
|
||||
void PutImage16(BYTE * pbySrc, BYTE * pbyDst, long src_pitch, long dst_pitch, long lTextureWidth, long lTextureHeight, bool bResize = false);
|
||||
|
||||
protected:
|
||||
void CalculateNormal(long x, long y);
|
||||
|
||||
protected:
|
||||
std::string m_strName;
|
||||
WORD m_wX;
|
||||
WORD m_wY;
|
||||
|
||||
protected:
|
||||
bool m_bReady;
|
||||
|
||||
CGraphicImageInstance m_ShadowGraphicImageInstance;
|
||||
|
||||
//MiniMap
|
||||
CGraphicImageInstance m_MiniMapGraphicImageInstance;
|
||||
LPDIRECT3DTEXTURE8 m_lpMiniMapTexture;
|
||||
|
||||
|
||||
// Owner COutdoorMap poineter
|
||||
CMapOutdoor * m_pOwnerOutdoorMap;
|
||||
|
||||
// Picking
|
||||
D3DXVECTOR3 m_v3Pick;
|
||||
|
||||
DWORD m_dwNumTexturesShow;
|
||||
std::vector<DWORD> m_VectorNumShowTexture;
|
||||
|
||||
CTerrainPatch m_TerrainPatchList[PATCH_XCOUNT * PATCH_YCOUNT];
|
||||
|
||||
BOOL m_bMarked;
|
||||
TTerrainSplatPatch m_MarkedSplatPatch;
|
||||
LPDIRECT3DTEXTURE8 m_lpMarkedTexture;
|
||||
|
||||
public:
|
||||
CTerrainPatch * GetTerrainPatchPtr(BYTE byPatchNumX, BYTE byPatchNumY);
|
||||
|
||||
protected:
|
||||
void _CalculateTerrainPatch(BYTE byPatchNumX, BYTE byPatchNumY);
|
||||
|
||||
public:
|
||||
static void DestroySystem();
|
||||
|
||||
static CTerrain* New();
|
||||
static void Delete(CTerrain* pkTerrain);
|
||||
|
||||
static CDynamicPool<CTerrain> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,265 @@
|
||||
#include "StdAfx.h"
|
||||
#include "DungeonBlock.h"
|
||||
|
||||
#include "../eterlib/StateManager.h"
|
||||
|
||||
class CDungeonModelInstance : public CGrannyModelInstance
|
||||
{
|
||||
public:
|
||||
CDungeonModelInstance() {}
|
||||
virtual ~CDungeonModelInstance() {}
|
||||
|
||||
void RenderDungeonBlock()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetVertexShader(ms_pnt2VS);
|
||||
LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer();
|
||||
if (lpd3dRigidPNTVtxBuf)
|
||||
{
|
||||
STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex));
|
||||
RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDungeonBlockShadow()
|
||||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
|
||||
|
||||
STATEMANAGER.SetVertexShader(ms_pnt2VS);
|
||||
LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer();
|
||||
if (lpd3dRigidPNTVtxBuf)
|
||||
{
|
||||
STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex));
|
||||
RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT);
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct FUpdate
|
||||
{
|
||||
float fElapsedTime;
|
||||
D3DXMATRIX * pmatWorld;
|
||||
void operator() (CGrannyModelInstance * pInstance)
|
||||
{
|
||||
pInstance->Update(CGrannyModelInstance::ANIFPS_MIN);
|
||||
pInstance->UpdateLocalTime(fElapsedTime);
|
||||
pInstance->Deform(pmatWorld);
|
||||
}
|
||||
};
|
||||
|
||||
void CDungeonBlock::Update()
|
||||
{
|
||||
Transform();
|
||||
|
||||
FUpdate Update;
|
||||
Update.fElapsedTime = 0.0f;
|
||||
Update.pmatWorld = &m_worldMatrix;
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), Update);
|
||||
}
|
||||
|
||||
struct FRender
|
||||
{
|
||||
void operator() (CDungeonModelInstance * pInstance)
|
||||
{
|
||||
pInstance->RenderDungeonBlock();
|
||||
}
|
||||
};
|
||||
|
||||
void CDungeonBlock::Render()
|
||||
{
|
||||
// if (!isShow())
|
||||
// return;
|
||||
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRender());
|
||||
}
|
||||
|
||||
struct FRenderShadow
|
||||
{
|
||||
void operator() (CDungeonModelInstance * pInstance)
|
||||
{
|
||||
pInstance->RenderDungeonBlockShadow();
|
||||
}
|
||||
};
|
||||
|
||||
void CDungeonBlock::OnRenderShadow()
|
||||
{
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRenderShadow());
|
||||
}
|
||||
|
||||
struct FBoundBox
|
||||
{
|
||||
D3DXVECTOR3 * m_pv3Min;
|
||||
D3DXVECTOR3 * m_pv3Max;
|
||||
|
||||
FBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max)
|
||||
{
|
||||
m_pv3Min = pv3Min;
|
||||
m_pv3Max = pv3Max;
|
||||
}
|
||||
void operator() (CGrannyModelInstance * pInstance)
|
||||
{
|
||||
pInstance->GetBoundBox(m_pv3Min, m_pv3Max);
|
||||
}
|
||||
};
|
||||
|
||||
bool CDungeonBlock::GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius)
|
||||
{
|
||||
v3Center = m_v3Center;
|
||||
fRadius = m_fRadius;
|
||||
D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDungeonBlock::OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector)
|
||||
{
|
||||
assert(pscdVector);
|
||||
CStaticCollisionDataVector::const_iterator it;
|
||||
for(it = pscdVector->begin();it!=pscdVector->end();++it)
|
||||
{
|
||||
AddCollision(&(*it),&GetTransform());
|
||||
}
|
||||
}
|
||||
|
||||
void CDungeonBlock::OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance)
|
||||
{
|
||||
assert(pAttributeInstance);
|
||||
SetHeightInstance(pAttributeInstance);
|
||||
}
|
||||
|
||||
bool CDungeonBlock::OnGetObjectHeight(float fX, float fY, float * pfHeight)
|
||||
{
|
||||
if (m_pHeightAttributeInstance && m_pHeightAttributeInstance->GetHeight(fX, fY, pfHeight))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDungeonBlock::BuildBoundingSphere()
|
||||
{
|
||||
D3DXVECTOR3 v3Min, v3Max;
|
||||
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FBoundBox(&v3Min, &v3Max));
|
||||
|
||||
m_v3Center = (v3Min+v3Max) * 0.5f;
|
||||
const auto vv = (v3Max - v3Min);
|
||||
m_fRadius = D3DXVec3Length(&vv)*0.5f + 150.0f; // extra length for attached objects
|
||||
}
|
||||
|
||||
bool CDungeonBlock::Intersect(float * pfu, float * pfv, float * pft)
|
||||
{
|
||||
TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin();
|
||||
for (; itor != m_ModelInstanceContainer.end(); ++itor)
|
||||
{
|
||||
CDungeonModelInstance * pInstance = *itor;
|
||||
if (pInstance->Intersect(&CGraphicObjectInstance::GetTransform(), pfu, pfv, pft))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDungeonBlock::GetBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max)
|
||||
{
|
||||
pv3Min->x = +10000000.0f;
|
||||
pv3Min->y = +10000000.0f;
|
||||
pv3Min->z = +10000000.0f;
|
||||
pv3Max->x = -10000000.0f;
|
||||
pv3Max->y = -10000000.0f;
|
||||
pv3Max->z = -10000000.0f;
|
||||
|
||||
TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin();
|
||||
for (; itor != m_ModelInstanceContainer.end(); ++itor)
|
||||
{
|
||||
CDungeonModelInstance * pInstance = *itor;
|
||||
|
||||
D3DXVECTOR3 v3Min;
|
||||
D3DXVECTOR3 v3Max;
|
||||
pInstance->GetBoundBox(&v3Min, &v3Max);
|
||||
|
||||
pv3Min->x = min(v3Min.x, pv3Min->x);
|
||||
pv3Min->y = min(v3Min.x, pv3Min->y);
|
||||
pv3Min->z = min(v3Min.x, pv3Min->z);
|
||||
pv3Max->x = max(v3Max.x, pv3Max->x);
|
||||
pv3Max->y = max(v3Max.x, pv3Max->y);
|
||||
pv3Max->z = max(v3Max.x, pv3Max->z);
|
||||
}
|
||||
}
|
||||
|
||||
bool CDungeonBlock::Load(const char * c_szFileName)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_pThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName);
|
||||
|
||||
m_pThing->AddReference();
|
||||
if (m_pThing->GetModelCount() <= 0)
|
||||
{
|
||||
TraceError("CDungeonBlock::Load(filename=%s) - model count is %d\n", c_szFileName, m_pThing->GetModelCount());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ModelInstanceContainer.reserve(m_pThing->GetModelCount());
|
||||
|
||||
for (int i = 0; i < m_pThing->GetModelCount(); ++i)
|
||||
{
|
||||
CDungeonModelInstance * pModelInstance = new CDungeonModelInstance;
|
||||
pModelInstance->SetMainModelPointer(m_pThing->GetModelPointer(i), &m_kDeformableVertexBuffer);
|
||||
DWORD dwVertexCount = pModelInstance->GetVertexCount();
|
||||
m_kDeformableVertexBuffer.Destroy();
|
||||
m_kDeformableVertexBuffer.Create(
|
||||
dwVertexCount,
|
||||
D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1,
|
||||
D3DUSAGE_WRITEONLY,
|
||||
D3DPOOL_MANAGED);
|
||||
m_ModelInstanceContainer.push_back(pModelInstance);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDungeonBlock::__Initialize()
|
||||
{
|
||||
m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_fRadius = 0.0f;
|
||||
|
||||
m_pThing = NULL;
|
||||
}
|
||||
|
||||
void CDungeonBlock::Destroy()
|
||||
{
|
||||
if (m_pThing)
|
||||
{
|
||||
m_pThing->Release();
|
||||
m_pThing = NULL;
|
||||
}
|
||||
|
||||
stl_wipe(m_ModelInstanceContainer);
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CDungeonBlock::CDungeonBlock()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
CDungeonBlock::~CDungeonBlock()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EterLib/ResourceManager.h"
|
||||
#include "../EterLib/GrpObjectInstance.h"
|
||||
#include "../EterGrnLib/ModelInstance.h"
|
||||
#include "../EterGrnLib/Thing.h"
|
||||
|
||||
class CDungeonModelInstance;
|
||||
|
||||
class CDungeonBlock : public CGraphicObjectInstance
|
||||
{
|
||||
public:
|
||||
typedef std::vector<CDungeonModelInstance *> TModelInstanceContainer;
|
||||
enum
|
||||
{
|
||||
ID = THING_OBJECT
|
||||
};
|
||||
int GetType() const { return ID; }
|
||||
|
||||
public:
|
||||
CDungeonBlock();
|
||||
virtual ~CDungeonBlock();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void BuildBoundingSphere();
|
||||
bool Load(const char * c_szFileName);
|
||||
|
||||
bool Intersect(float * pfu, float * pfv, float * pft);
|
||||
void GetBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max);
|
||||
|
||||
void Update();
|
||||
void Render();
|
||||
|
||||
bool GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius);
|
||||
void OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector);
|
||||
void OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance);
|
||||
bool OnGetObjectHeight(float fX, float fY, float * pfHeight);
|
||||
|
||||
void OnRender() {}
|
||||
void OnBlendRender() {}
|
||||
void OnRenderToShadowMap() {}
|
||||
void OnRenderShadow();
|
||||
void OnRenderPCBlocker() {}
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
|
||||
protected:
|
||||
D3DXVECTOR3 m_v3Center;
|
||||
float m_fRadius;
|
||||
|
||||
CGraphicThing * m_pThing;
|
||||
TModelInstanceContainer m_ModelInstanceContainer;
|
||||
CGraphicVertexBuffer m_kDeformableVertexBuffer;
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
class IFlyEventHandler
|
||||
{
|
||||
public:
|
||||
IFlyEventHandler() {}
|
||||
virtual ~IFlyEventHandler() {}
|
||||
|
||||
// Call by ActorInstance
|
||||
virtual void OnSetFlyTarget() {}
|
||||
virtual void OnShoot(DWORD dwSkillIndex) {}
|
||||
|
||||
virtual void OnNoTarget() {}
|
||||
virtual void OnNoArrow() {}
|
||||
|
||||
// Call by FlyingInstance
|
||||
virtual void OnExplodingOutOfRange() {}
|
||||
virtual void OnExplodingAtBackground() {}
|
||||
virtual void OnExplodingAtAnotherTarget(DWORD dwSkillIndex, DWORD dwVID) {}
|
||||
virtual void OnExplodingAtTarget(DWORD dwSkillIndex) {}
|
||||
};
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "StdAfx.h"
|
||||
#include "FlyTarget.h"
|
||||
|
||||
CFlyTarget::CFlyTarget()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CFlyTarget::CFlyTarget(IFlyTargetableObject * pFlyTarget)
|
||||
{
|
||||
__Initialize();
|
||||
|
||||
m_eType=TYPE_OBJECT;
|
||||
m_pFlyTarget=pFlyTarget;
|
||||
m_pFlyTarget->AddFlyTargeter(this);
|
||||
}
|
||||
CFlyTarget::CFlyTarget(const D3DXVECTOR3& v3FlyTargetPosition)
|
||||
{
|
||||
__Initialize();
|
||||
|
||||
m_eType=TYPE_POSITION;
|
||||
m_v3FlyTargetPosition=v3FlyTargetPosition;
|
||||
}
|
||||
|
||||
CFlyTarget::CFlyTarget(const CFlyTarget& rhs)
|
||||
{
|
||||
__Initialize();
|
||||
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
CFlyTarget::~CFlyTarget()
|
||||
{
|
||||
if (m_pFlyTarget)
|
||||
m_pFlyTarget->RemoveFlyTargeter(this);
|
||||
}
|
||||
|
||||
void CFlyTarget::__Initialize()
|
||||
{
|
||||
m_v3FlyTargetPosition=D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
m_pFlyTarget=NULL;
|
||||
m_eType=TYPE_NONE;
|
||||
}
|
||||
|
||||
void CFlyTarget::Clear()
|
||||
{
|
||||
m_eType = TYPE_NONE;
|
||||
m_pFlyTarget = 0;
|
||||
}
|
||||
|
||||
bool CFlyTarget::IsObject()
|
||||
{
|
||||
return (TYPE_OBJECT==GetType());
|
||||
}
|
||||
|
||||
bool CFlyTarget::IsPosition()
|
||||
{
|
||||
return (TYPE_POSITION==GetType());
|
||||
}
|
||||
|
||||
bool CFlyTarget::IsValidTarget()
|
||||
{
|
||||
return (TYPE_NONE!=GetType());
|
||||
}
|
||||
|
||||
void CFlyTarget::NotifyTargetClear()
|
||||
{
|
||||
//if (m_eType == FLY_TARGET_TYPE_OBJECT)
|
||||
m_eType = TYPE_POSITION;
|
||||
m_pFlyTarget = 0;
|
||||
}
|
||||
|
||||
CFlyTarget::EType CFlyTarget::GetType()
|
||||
{
|
||||
return m_eType;
|
||||
}
|
||||
|
||||
IFlyTargetableObject* CFlyTarget::GetFlyTarget()
|
||||
{
|
||||
assert(TYPE_OBJECT==GetType() && "CFly::GetFlyTarget");
|
||||
return m_pFlyTarget;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3 & CFlyTarget::GetFlyTargetPosition() const
|
||||
{
|
||||
if (m_eType == TYPE_OBJECT)
|
||||
{
|
||||
m_v3FlyTargetPosition = m_pFlyTarget->OnGetFlyTargetPosition();
|
||||
}
|
||||
return m_v3FlyTargetPosition;
|
||||
}
|
||||
|
||||
CFlyTarget & CFlyTarget::operator = (const CFlyTarget & rhs)
|
||||
{
|
||||
if (m_pFlyTarget)
|
||||
{
|
||||
m_pFlyTarget->RemoveFlyTargeter(this);
|
||||
}
|
||||
m_eType = rhs.m_eType;
|
||||
m_v3FlyTargetPosition = rhs.m_v3FlyTargetPosition;
|
||||
m_pFlyTarget = rhs.m_pFlyTarget;
|
||||
if (m_pFlyTarget)
|
||||
{
|
||||
m_pFlyTarget->AddFlyTargeter(this);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CFlyTarget::GetFlyTargetData(CFlyTarget * pFlyTarget)
|
||||
{
|
||||
pFlyTarget->m_eType = m_eType;
|
||||
pFlyTarget->m_v3FlyTargetPosition = m_v3FlyTargetPosition;
|
||||
pFlyTarget->m_pFlyTarget = m_pFlyTarget;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
class IFlyTargetableObject
|
||||
{
|
||||
friend class CFlyTarget;
|
||||
public:
|
||||
IFlyTargetableObject() {}
|
||||
virtual ~IFlyTargetableObject() {}
|
||||
|
||||
virtual D3DXVECTOR3 OnGetFlyTargetPosition() = 0;
|
||||
virtual void OnShootDamage() = 0;
|
||||
|
||||
protected:
|
||||
inline void ClearFlyTargeter();
|
||||
private:
|
||||
std::set<CFlyTarget*> m_FlyTargeterSet;
|
||||
inline void AddFlyTargeter(CFlyTarget* pTargeter)
|
||||
{
|
||||
//if (m_FlyTargeterSet.find(pTargeter)!=m_FlyTargeterSet.end())
|
||||
m_FlyTargeterSet.insert(pTargeter);
|
||||
}
|
||||
inline void RemoveFlyTargeter(CFlyTarget* pTargeter)
|
||||
{
|
||||
//if (m_FlyTargeterSet.find(pTargeter)!=m_FlyTargeterSet.end())
|
||||
m_FlyTargeterSet.erase(pTargeter);
|
||||
}
|
||||
};
|
||||
|
||||
class CFlyTarget // final
|
||||
{
|
||||
public:
|
||||
enum EType
|
||||
{
|
||||
TYPE_NONE,
|
||||
TYPE_OBJECT,
|
||||
TYPE_POSITION,
|
||||
};
|
||||
|
||||
public:
|
||||
CFlyTarget();
|
||||
CFlyTarget(IFlyTargetableObject * pFlyTarget);
|
||||
CFlyTarget(const D3DXVECTOR3& v3FlyTargetPosition);
|
||||
CFlyTarget(const CFlyTarget& rhs);
|
||||
virtual ~CFlyTarget();
|
||||
|
||||
void Clear();
|
||||
bool IsObject();
|
||||
bool IsPosition();
|
||||
bool IsValidTarget();
|
||||
void NotifyTargetClear();
|
||||
|
||||
const D3DXVECTOR3 & GetFlyTargetPosition() const;
|
||||
EType GetType();
|
||||
|
||||
IFlyTargetableObject * GetFlyTarget();
|
||||
|
||||
CFlyTarget & operator = (const CFlyTarget & rhs);
|
||||
void GetFlyTargetData(CFlyTarget * pFlyTarget);
|
||||
|
||||
private:
|
||||
void __Initialize();
|
||||
|
||||
private:
|
||||
mutable D3DXVECTOR3 m_v3FlyTargetPosition;
|
||||
IFlyTargetableObject * m_pFlyTarget;
|
||||
|
||||
EType m_eType;
|
||||
};
|
||||
|
||||
inline void IFlyTargetableObject::ClearFlyTargeter()
|
||||
{
|
||||
std::set<CFlyTarget*>::iterator it;
|
||||
for(it = m_FlyTargeterSet.begin();it!=m_FlyTargeterSet.end();++it)
|
||||
{
|
||||
(*it)->NotifyTargetClear();
|
||||
}
|
||||
m_FlyTargeterSet.clear();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
#include "stdafx.h"
|
||||
#include "../eterLib/StateManager.h"
|
||||
#include "../eterLib/Camera.h"
|
||||
|
||||
#include "FlyingData.h"
|
||||
#include "FlyTrace.h"
|
||||
|
||||
CDynamicPool<CFlyTrace> CFlyTrace::ms_kPool;
|
||||
|
||||
void CFlyTrace::DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
}
|
||||
|
||||
CFlyTrace* CFlyTrace::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CFlyTrace::Delete(CFlyTrace* pkInst)
|
||||
{
|
||||
pkInst->Destroy();
|
||||
ms_kPool.Free(pkInst);
|
||||
}
|
||||
|
||||
CFlyTrace::CFlyTrace()
|
||||
{
|
||||
__Initialize();
|
||||
|
||||
/*
|
||||
// Code for texture
|
||||
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ray.jpg");
|
||||
m_ImageInstance.SetImagePointer(pImage);
|
||||
|
||||
CGraphicTexture * pTexture = m_ImageInstance.GetTexturePointer();
|
||||
m_lpTexture = pTexture->GetD3DTexture();
|
||||
*/
|
||||
}
|
||||
|
||||
CFlyTrace::~CFlyTrace()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
void CFlyTrace::__Initialize()
|
||||
{
|
||||
m_bRectShape=false;
|
||||
m_dwColor=0;
|
||||
m_fSize=0.0f;
|
||||
m_fTailLength=0.0f;
|
||||
}
|
||||
|
||||
void CFlyTrace::Destroy()
|
||||
{
|
||||
m_TimePositionDeque.clear();
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CFlyTrace::UpdateNewPosition(const D3DXVECTOR3 & v3Position)
|
||||
{
|
||||
m_TimePositionDeque.push_front(TTimePosition(CTimer::Instance().GetCurrentSecond(),v3Position));
|
||||
//Tracenf("%f %f",m_TimePositionDeque.back().first, CTimer::Instance().GetCurrentSecond());
|
||||
while(!m_TimePositionDeque.empty() && m_TimePositionDeque.back().first+m_fTailLength<CTimer::Instance().GetCurrentSecond())
|
||||
{
|
||||
m_TimePositionDeque.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void CFlyTrace::Create(const CFlyingData::TFlyingAttachData & rFlyingAttachData)
|
||||
{
|
||||
//assert(rFlyingAttachData.bHasTail);
|
||||
m_dwColor = rFlyingAttachData.dwTailColor;
|
||||
m_fTailLength = rFlyingAttachData.fTailLength;
|
||||
m_fSize = rFlyingAttachData.fTailSize;
|
||||
m_bRectShape = rFlyingAttachData.bRectShape;
|
||||
}
|
||||
|
||||
|
||||
void CFlyTrace::Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//1. 알파를 쓰려면 색깔만 줄수있다.
|
||||
//2. 텍스쳐를 쓰려면 알파 없다-_-
|
||||
|
||||
|
||||
struct TFlyVertex
|
||||
{
|
||||
D3DXVECTOR3 p;
|
||||
DWORD c;
|
||||
D3DXVECTOR2 t;
|
||||
TFlyVertex(){};
|
||||
TFlyVertex(const D3DXVECTOR3& p, DWORD c, const D3DXVECTOR2 & t):p(p),c(c),t(t){}
|
||||
};
|
||||
|
||||
struct TFlyVertexSet
|
||||
{
|
||||
TFlyVertex v[6];
|
||||
TFlyVertexSet(TFlyVertex * pv)
|
||||
{
|
||||
memcpy(v,pv,sizeof(v));
|
||||
}
|
||||
bool operator < (const TFlyVertexSet& ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TFlyVertexSet & operator = ( const TFlyVertexSet& rhs )
|
||||
{
|
||||
memcpy(v,rhs.v,sizeof(v));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<std::pair<float, TFlyVertexSet> > TFlyVertexSetVector;
|
||||
|
||||
void CFlyTrace::Render()
|
||||
{
|
||||
if (m_TimePositionDeque.size()<=1)
|
||||
return;
|
||||
TFlyVertexSetVector VSVector;
|
||||
|
||||
//STATEMANAGER.SaveRenderState(D3DRS_ZFUNC,D3DCMP_LESS);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZFUNC,D3DCMP_LESS);
|
||||
//STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE,FALSE);
|
||||
|
||||
D3DXMATRIX matWorld;
|
||||
D3DXMatrixIdentity(&matWorld);
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_WORLD, &matWorld);
|
||||
STATEMANAGER.SaveVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
//STATEMANAGER.SaveRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, /*(m_bUseTexture)?D3DTOP_SELECTARG2:*/D3DTOP_SELECTARG2);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, /*(m_bUseTexture)?D3DTOP_SELECTARG2:*/D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
|
||||
|
||||
D3DXMATRIX m;
|
||||
CScreen s;s.UpdateViewMatrix();
|
||||
CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCurrentCamera)
|
||||
return;
|
||||
|
||||
const D3DXMATRIX & M = pCurrentCamera->GetViewMatrix();
|
||||
D3DXMatrixIdentity(&m);
|
||||
D3DXVECTOR3 F(pCurrentCamera->GetView());
|
||||
m._31 = F.x;
|
||||
m._32 = F.y;
|
||||
m._33 = F.z;
|
||||
|
||||
Frustum & frustum = s.GetFrustum();
|
||||
//frustum.BuildViewFrustum(ms_matView * ms_matProj);
|
||||
|
||||
TTimePositionDeque::iterator it1, it2;
|
||||
it2 = it1 = m_TimePositionDeque.begin();
|
||||
++it2;
|
||||
for(;it2!=m_TimePositionDeque.end();++it2,++it1)
|
||||
{
|
||||
const D3DXVECTOR3& rkOld=it1->second;
|
||||
const D3DXVECTOR3& rkNew=it2->second;
|
||||
D3DXVECTOR3 B = rkNew - rkOld;
|
||||
|
||||
float radius = max(fabs(B.x),max(fabs(B.y),fabs(B.z)))/2;
|
||||
Vector3d c(it1->second.x+B.x*0.5f,
|
||||
it1->second.y+B.y*0.5f,
|
||||
it1->second.z+B.z*0.5f
|
||||
);
|
||||
if (frustum.ViewVolumeTest(c, radius)==VS_OUTSIDE)
|
||||
continue;
|
||||
|
||||
float rate1 = (1-(CTimer::Instance().GetCurrentSecond()-it1->first)/m_fTailLength);
|
||||
float rate2 = (1-(CTimer::Instance().GetCurrentSecond()-it2->first)/m_fTailLength);
|
||||
float size1 = m_fSize;
|
||||
float size2 = m_fSize;
|
||||
if (!m_bRectShape)
|
||||
{
|
||||
size1 *= rate1;
|
||||
size2 *= rate2;
|
||||
}
|
||||
TFlyVertex v[6] =
|
||||
{
|
||||
TFlyVertex(D3DXVECTOR3(0.0f,size1,0.0f), m_dwColor,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TFlyVertex(D3DXVECTOR3(-size1,0.0f,0.0f),m_dwColor,D3DXVECTOR2(0.0f,0.5f)),
|
||||
TFlyVertex(D3DXVECTOR3(size1,0.0f,0.0f), m_dwColor,D3DXVECTOR2(0.5f,0.0f)),
|
||||
TFlyVertex(D3DXVECTOR3(-size2,0.0f,0.0f),m_dwColor,D3DXVECTOR2(0.5f,1.0f)),
|
||||
TFlyVertex(D3DXVECTOR3(size2,0.0f,0.0f), m_dwColor,D3DXVECTOR2(1.0f,0.5f)),
|
||||
TFlyVertex(D3DXVECTOR3(0.0f,-size2,0.0f),m_dwColor,D3DXVECTOR2(1.0f,1.0f)),
|
||||
|
||||
/*TVertex(D3DXVECTOR3(0.0f,size1,0.0f), ((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(size1,0.0f,0.0f), ((DWORD)(0x40*rate1)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(size2,0.0f,0.0f), ((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),((DWORD)(0x40*rate2)<<24) + 0x0000ff,D3DXVECTOR2(0.0f,0.0f)),*/
|
||||
|
||||
/*TVertex(D3DXVECTOR3(0.0f,size1,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(size1,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(size2,0.0f,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),0x20ff0000,D3DXVECTOR2(0.0f,0.0f)),*/
|
||||
|
||||
/*TVertex(D3DXVECTOR3(0.0f,size1,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(-size1,0.0f,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(size1,0.0f,0.0f),0xffff0000,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(-size2,0.0f,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(size2,0.0f,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)),
|
||||
TVertex(D3DXVECTOR3(0.0f,-size2,0.0f),0xff0000ff,D3DXVECTOR2(0.0f,0.0f)),*/
|
||||
};
|
||||
|
||||
|
||||
D3DXVECTOR3 E(M._41,M._42,M._43);
|
||||
E = pCurrentCamera->GetEye();
|
||||
E-=it1->second;
|
||||
|
||||
D3DXVECTOR3 P;
|
||||
D3DXVec3Cross(&P, &B,&E);
|
||||
|
||||
D3DXVECTOR3 U;
|
||||
D3DXVec3Cross(&U,&F,&P);
|
||||
D3DXVec3Normalize(&U,&U);
|
||||
D3DXVECTOR3 R;
|
||||
D3DXVec3Cross(&R,&F,&U);
|
||||
//D3DXMatrixIdentity(&m);
|
||||
m._21 = U.x;
|
||||
m._22 = U.y;
|
||||
m._23 = U.z;
|
||||
m._11 = R.x;
|
||||
m._12 = R.y;
|
||||
m._13 = R.z;
|
||||
int i;
|
||||
for(i=0;i<6;i++)
|
||||
D3DXVec3TransformNormal(&v[i].p,&v[i].p,&m);
|
||||
for(i=0;i<3;i++)
|
||||
v[i].p += it1->second;
|
||||
for(;i<6;i++)
|
||||
v[i].p += it2->second;
|
||||
//for(i=0;i<6;i++)
|
||||
// Tracenf("#%d:%f %f %f", i, v[i].p.x,v[i].p.y,v[i].p.z);
|
||||
|
||||
VSVector.push_back(std::make_pair(-D3DXVec3Dot(&E,&pCurrentCamera->GetView()),TFlyVertexSet(v)));
|
||||
//OLD: STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, v, sizeof(TVertex));
|
||||
//OLD: STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v+1, sizeof(TVertex));
|
||||
}
|
||||
|
||||
std::sort(VSVector.begin(),VSVector.end());
|
||||
|
||||
for(TFlyVertexSetVector::iterator it = VSVector.begin();it!=VSVector.end();++it)
|
||||
{
|
||||
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 4, it->second.v, sizeof(TVertex));
|
||||
}
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
STATEMANAGER.RestoreVertexShader();
|
||||
STATEMANAGER.RestoreTransform(D3DTS_WORLD);
|
||||
//STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_BLENDOP);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
class CFlyTrace : public CScreen
|
||||
{
|
||||
public:
|
||||
CFlyTrace();
|
||||
virtual ~CFlyTrace();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void Create(const CFlyingData::TFlyingAttachData & rFlyingAttachData);
|
||||
|
||||
void UpdateNewPosition(const D3DXVECTOR3 & v3Position);
|
||||
|
||||
void Update();
|
||||
void Render();
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
|
||||
protected:
|
||||
typedef std::pair<float, D3DXVECTOR3> TTimePosition;
|
||||
typedef std::deque<TTimePosition> TTimePositionDeque;
|
||||
|
||||
//CGraphicImageInstance m_ImageInstance;
|
||||
//LPDIRECT3DTEXTURE8 m_lpTexture;
|
||||
|
||||
bool m_bRectShape;
|
||||
DWORD m_dwColor;
|
||||
float m_fSize;
|
||||
float m_fTailLength;
|
||||
|
||||
TTimePositionDeque m_TimePositionDeque;
|
||||
|
||||
public:
|
||||
static void DestroySystem();
|
||||
|
||||
static CFlyTrace* New();
|
||||
static void Delete(CFlyTrace* pkInst);
|
||||
|
||||
static CDynamicPool<CFlyTrace> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,353 @@
|
||||
#include "Stdafx.h"
|
||||
#include "../effectLib/EffectManager.h"
|
||||
|
||||
#include "FlyingData.h"
|
||||
|
||||
CDynamicPool<CFlyingData> CFlyingData::ms_kPool;
|
||||
|
||||
CFlyingData::CFlyingData()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CFlyingData::__Initialize()
|
||||
{
|
||||
m_v3AngVel = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
m_bIsHoming = false;
|
||||
m_fInitVel = 200.0f;
|
||||
m_fConeAngle = (0.0f);
|
||||
m_fRollAngle = 0.0f;
|
||||
m_fRange = 500.0f;
|
||||
m_v3Accel = D3DXVECTOR3(0,0,0.0f);// gravity direction :-z
|
||||
m_fHomingMaxAngle = 3.0f;
|
||||
m_fHomingStartTime = 0.0f;
|
||||
m_fGravity = 0;
|
||||
m_bSpreading = false;
|
||||
m_bMaintainParallel = false;
|
||||
|
||||
m_bHitOnBackground = false;
|
||||
m_bHitOnAnotherMonster = false;
|
||||
m_iPierceCount = 0;
|
||||
m_fCollisionSphereRadius = 0.0f;
|
||||
|
||||
m_fBombRange = 10.0f;
|
||||
SetBombEffect("");
|
||||
}
|
||||
|
||||
void CFlyingData::Destroy()
|
||||
{
|
||||
m_AttachDataVector.clear();
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CFlyingData::~CFlyingData()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CFlyingData::SetBombEffect(const char* szEffectName)
|
||||
{
|
||||
m_strBombEffectName = szEffectName;
|
||||
if (m_strBombEffectName.empty())
|
||||
{
|
||||
m_dwBombEffectID = 0;
|
||||
return;
|
||||
}
|
||||
StringPath(m_strBombEffectName);
|
||||
if (CEffectManager::Instance().RegisterEffect(m_strBombEffectName.c_str()),true)
|
||||
{
|
||||
m_dwBombEffectID = GetCaseCRC32(m_strBombEffectName.c_str(),m_strBombEffectName.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dwBombEffectID = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CFlyingData::TFlyingAttachData & CFlyingData::GetAttachDataReference(int iIndex)
|
||||
{
|
||||
return m_AttachDataVector[iIndex];
|
||||
}
|
||||
|
||||
DWORD CFlyingData::AttachFlyEffect(int iType, const std::string & strFilename, float fRoll, float fArg1, float fArg2)
|
||||
{
|
||||
TFlyingAttachData fad;
|
||||
memset(&fad,0, sizeof(fad));
|
||||
fad.iType = FLY_ATTACH_EFFECT;
|
||||
fad.iFlyType = iType;
|
||||
fad.fPeriod = 1.0f;
|
||||
fad.strFilename = strFilename;
|
||||
fad.fRoll = fRoll;
|
||||
fad.dwTailColor = 0xffffffff;
|
||||
fad.fTailLength = 1.0f;
|
||||
fad.fTailSize = 10.0f;
|
||||
|
||||
switch(iType)
|
||||
{
|
||||
case FLY_ATTACH_TYPE_MULTI_LINE:
|
||||
fad.fDistance = fArg1;
|
||||
break;
|
||||
case FLY_ATTACH_TYPE_SINE:
|
||||
case FLY_ATTACH_TYPE_EXP:
|
||||
fad.fPeriod=fArg1;
|
||||
fad.fAmplitude=fArg2;
|
||||
break;
|
||||
case FLY_ATTACH_TYPE_NONE:
|
||||
case FLY_ATTACH_TYPE_LINE:
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
m_AttachDataVector.push_back(fad);
|
||||
return m_AttachDataVector.size()-1;
|
||||
}
|
||||
|
||||
void CFlyingData::RemoveAttach(int iIndex)
|
||||
{
|
||||
assert(0<=iIndex && iIndex<(int)m_AttachDataVector.size());
|
||||
m_AttachDataVector.erase(m_AttachDataVector.begin()+iIndex);
|
||||
}
|
||||
|
||||
void CFlyingData::RemoveAllAttach()
|
||||
{
|
||||
m_AttachDataVector.clear();
|
||||
}
|
||||
|
||||
void CFlyingData::DuplicateAttach(int iIndex)
|
||||
{
|
||||
assert(0<=iIndex && iIndex<(int)m_AttachDataVector.size());
|
||||
m_AttachDataVector.push_back(m_AttachDataVector[iIndex]);
|
||||
}
|
||||
|
||||
bool CFlyingData::LoadScriptFile(const char* c_szFilename)
|
||||
{
|
||||
NANOBEGIN
|
||||
Destroy();
|
||||
|
||||
m_strFilename = c_szFilename;
|
||||
StringPath(m_strFilename);
|
||||
CTextFileLoader TextFileLoader;
|
||||
if (!TextFileLoader.Load(m_strFilename.c_str()))
|
||||
return false;
|
||||
|
||||
TextFileLoader.SetTop();
|
||||
int temp;
|
||||
|
||||
if (!TextFileLoader.GetTokenInteger("spreadingflag",&temp))
|
||||
{
|
||||
m_bSpreading = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bSpreading = temp?true:false;
|
||||
}
|
||||
|
||||
if (!TextFileLoader.GetTokenInteger("maintainparallelflag", &temp))
|
||||
{
|
||||
m_bMaintainParallel = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bMaintainParallel = temp?true:false;
|
||||
}
|
||||
|
||||
if (!TextFileLoader.GetTokenFloat("initialvelocity",&m_fInitVel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TextFileLoader.GetTokenFloat("coneangle", &m_fConeAngle);
|
||||
//if (!TextFileLoader.GetTokenFloat("coneangle", &m_fConeAngle))
|
||||
// m_fConeAngle = 0.0f;
|
||||
|
||||
TextFileLoader.GetTokenFloat("rollangle", &m_fRollAngle);
|
||||
//if (!TextFileLoader.GetTokenFloat("rollangle", &m_fRollAngle))
|
||||
// m_fRollAngle = 0.0f;
|
||||
|
||||
TextFileLoader.GetTokenVector3("angularvelocity",&m_v3AngVel);
|
||||
//if (!TextFileLoader.GetTokenVector3("angularvelocity",&m_v3AngVel))
|
||||
// m_v3AngVel = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
|
||||
TextFileLoader.GetTokenFloat("gravity",&m_fGravity);
|
||||
//if (!TextFileLoader.GetTokenFloat("gravity",&m_fGravity))
|
||||
//m_fGravity = 0.0f;
|
||||
|
||||
if (TextFileLoader.GetTokenInteger("hitonbackground",&temp))
|
||||
m_bHitOnBackground = temp?true:false;
|
||||
else
|
||||
m_bHitOnBackground = false;
|
||||
|
||||
if (TextFileLoader.GetTokenInteger("hitonanothermonster",&temp))
|
||||
m_bHitOnAnotherMonster = temp?true:false;
|
||||
else
|
||||
m_bHitOnAnotherMonster = false;
|
||||
|
||||
if (!TextFileLoader.GetTokenInteger("piercecount",&m_iPierceCount))
|
||||
m_iPierceCount = 0;
|
||||
|
||||
// if (!TextFileLoader.GetTokenFloat("collisionsphereradius",&m_fCollisionSphereRadius))
|
||||
// m_fCollisionSphereRadius = 0.0f;
|
||||
|
||||
TextFileLoader.GetTokenFloat("bombrange",&m_fBombRange);
|
||||
//if (!TextFileLoader.GetTokenFloat("bombrange",&m_fBombRange))
|
||||
// m_fBombRange = 10.0f;
|
||||
|
||||
if (!TextFileLoader.GetTokenString("bombeffect",&m_strBombEffectName))
|
||||
{
|
||||
m_strBombEffectName = "";
|
||||
}
|
||||
else if (!m_strBombEffectName.empty())
|
||||
{
|
||||
if (!IsGlobalFileName(m_strBombEffectName.c_str()))
|
||||
m_strBombEffectName = GetOnlyPathName(TextFileLoader.GetFileName()) + m_strBombEffectName;
|
||||
CEffectManager::Instance().RegisterEffect2(m_strBombEffectName.c_str(),&m_dwBombEffectID);
|
||||
}
|
||||
|
||||
if (!TextFileLoader.GetTokenInteger("homingflag", &temp))
|
||||
m_bIsHoming = false;
|
||||
else
|
||||
m_bIsHoming = temp?true:false;
|
||||
|
||||
if (!TextFileLoader.GetTokenFloat("homingstarttime",&m_fHomingStartTime))
|
||||
m_fHomingStartTime = 0.0f;
|
||||
|
||||
if (!TextFileLoader.GetTokenFloat("homingmaxangle",&m_fHomingMaxAngle))
|
||||
m_fHomingMaxAngle = 0.0f;
|
||||
|
||||
if (!TextFileLoader.GetTokenFloat("range",&m_fRange))
|
||||
return false;
|
||||
|
||||
if (!TextFileLoader.GetTokenVector3("acceleration",&m_v3Accel))
|
||||
m_v3Accel = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
|
||||
DWORD i;
|
||||
for(i=0;i<TextFileLoader.GetChildNodeCount();i++)
|
||||
{
|
||||
CTextFileLoader::CGotoChild GotoChild(&TextFileLoader, i);
|
||||
|
||||
std::string strNodeName;
|
||||
|
||||
TextFileLoader.GetCurrentNodeName(&strNodeName);
|
||||
|
||||
if (strNodeName=="attachdata")
|
||||
{
|
||||
TFlyingAttachData fad;
|
||||
|
||||
if (!TextFileLoader.GetTokenInteger("type",&fad.iType))
|
||||
continue;
|
||||
TextFileLoader.GetTokenInteger("flytype",&fad.iFlyType);
|
||||
if (!TextFileLoader.GetTokenString("attachfile",&fad.strFilename))
|
||||
{
|
||||
fad.strFilename = "";
|
||||
}
|
||||
else if (!fad.strFilename.empty())
|
||||
{
|
||||
if (!IsGlobalFileName(fad.strFilename.c_str()))
|
||||
fad.strFilename = GetOnlyPathName(TextFileLoader.GetFileName()) + fad.strFilename;
|
||||
CEffectManager::Instance().RegisterEffect(fad.strFilename.c_str());
|
||||
}
|
||||
|
||||
TextFileLoader.GetTokenInteger("tailflag",&temp);
|
||||
if (temp)
|
||||
{
|
||||
fad.bHasTail = true;
|
||||
TextFileLoader.GetTokenDoubleWord("tailcolor",&fad.dwTailColor);
|
||||
TextFileLoader.GetTokenFloat("taillength",&fad.fTailLength);
|
||||
TextFileLoader.GetTokenFloat("tailsize",&fad.fTailSize);
|
||||
TextFileLoader.GetTokenInteger("tailshaperect",&temp);
|
||||
fad.bRectShape = temp?true:false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fad.bHasTail = false;
|
||||
}
|
||||
|
||||
TextFileLoader.GetTokenFloat("roll",&fad.fRoll);
|
||||
TextFileLoader.GetTokenFloat("distance",&fad.fDistance);
|
||||
TextFileLoader.GetTokenFloat("period",&fad.fPeriod);
|
||||
TextFileLoader.GetTokenFloat("amplitude",&fad.fAmplitude);
|
||||
|
||||
m_AttachDataVector.push_back(fad);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceError("CFlyingData::LoadScriptFile Wrong Data : %s", m_strFilename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
NANOEND
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFlyingData::SaveScriptFile(const char* c_szFilename)
|
||||
{
|
||||
FILE* fp = fopen(c_szFilename,"w");
|
||||
if (!fp) return false;
|
||||
|
||||
PrintfTabs(fp, 0, "SpreadingFlag %d\n", m_bSpreading?1:0);
|
||||
PrintfTabs(fp, 0, "MaintainParallelFlag %d\n", m_bMaintainParallel?1:0);
|
||||
|
||||
PrintfTabs(fp, 0, "InitialVelocity %f\n", m_fInitVel);
|
||||
PrintfTabs(fp, 0, "ConeAngle %f\n", m_fConeAngle);
|
||||
PrintfTabs(fp, 0, "RollAngle %f\n", m_fRollAngle);
|
||||
PrintfTabs(fp, 0, "AngularVelocity %f %f %f\n", m_v3AngVel.x, m_v3AngVel.y, m_v3AngVel.z);
|
||||
PrintfTabs(fp, 0, "Gravity %f\n", m_fGravity);
|
||||
|
||||
PrintfTabs(fp, 0, "HitOnBackground %d\n",m_bHitOnBackground?1:0);
|
||||
PrintfTabs(fp, 0, "HitOnAnotherMonster %d\n",m_bHitOnAnotherMonster?1:0);
|
||||
PrintfTabs(fp, 0, "PierceCount %d\n",m_iPierceCount);
|
||||
PrintfTabs(fp, 0, "CollisionSphereRadius %f\n",m_fCollisionSphereRadius);
|
||||
|
||||
PrintfTabs(fp, 0, "BombRange %f\n", m_fBombRange);
|
||||
|
||||
std::string strGlobalPathName;
|
||||
StringPath(GetOnlyPathName(c_szFilename), strGlobalPathName);
|
||||
|
||||
std::string strLocalFileName;
|
||||
if (GetLocalFileName(strGlobalPathName.c_str(), m_strBombEffectName.c_str(), &strLocalFileName))
|
||||
PrintfTabs(fp, 0, "BombEffect \"%s\"\n", strLocalFileName.c_str());
|
||||
else
|
||||
PrintfTabs(fp, 0, "BombEffect \"%s\"\n", m_strBombEffectName.c_str());
|
||||
|
||||
PrintfTabs(fp, 0, "HomingFlag %d\n", m_bIsHoming?1:0);
|
||||
PrintfTabs(fp, 0, "HomingStartTime %f\n", m_fHomingStartTime);
|
||||
PrintfTabs(fp, 0, "HomingMaxAngle %f\n", m_fHomingMaxAngle);
|
||||
PrintfTabs(fp, 0, "Range %f\n", m_fRange);
|
||||
PrintfTabs(fp, 0, "Acceleration %f %f %f\n", m_v3Accel.x, m_v3Accel.y, m_v3Accel.z);
|
||||
|
||||
std::vector<TFlyingAttachData>::iterator it;
|
||||
for(it = m_AttachDataVector.begin();it!=m_AttachDataVector.end();++it)
|
||||
{
|
||||
PrintfTabs(fp, 0, "Group AttachData\n");
|
||||
PrintfTabs(fp, 0, "{\n");
|
||||
PrintfTabs(fp, 1, "Type %d\n", it->iType);
|
||||
PrintfTabs(fp, 1, "FlyType %d\n", it->iFlyType);
|
||||
if (GetLocalFileName(strGlobalPathName.c_str(), it->strFilename.c_str(), &strLocalFileName))
|
||||
PrintfTabs(fp, 1, "AttachFile \"%s\"\n", strLocalFileName.c_str());
|
||||
else
|
||||
PrintfTabs(fp, 1, "AttachFile \"%s\"\n", it->strFilename.c_str());
|
||||
//PrintfTabs(fp, 1, "AttachFile \"%s\"\n", it->strFilename);
|
||||
|
||||
PrintfTabs(fp, 1, "TailFlag %d\n", it->bHasTail?1:0);
|
||||
if (it->bHasTail)
|
||||
{
|
||||
PrintfTabs(fp, 1, "TailColor %ud\n", it->dwTailColor);
|
||||
PrintfTabs(fp, 1, "TailLength %f\n", it->fTailLength);
|
||||
PrintfTabs(fp, 1, "TailSize %f\n", it->fTailSize);
|
||||
PrintfTabs(fp, 1, "TailShapeRect %d\n", it->bRectShape?1:0);
|
||||
}
|
||||
|
||||
PrintfTabs(fp, 1, "Roll %f\n",it->fRoll );
|
||||
PrintfTabs(fp, 1, "Distance %f\n",it->fDistance );
|
||||
PrintfTabs(fp, 1, "Period %f\n",it->fPeriod );
|
||||
PrintfTabs(fp, 1, "Amplitude %f\n",it->fAmplitude );
|
||||
|
||||
PrintfTabs(fp, 0, "}\n");
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
class CFlyingData //: public CPooledObject<CFlyingData>
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
FLY_ATTACH_NONE,
|
||||
FLY_ATTACH_EFFECT,
|
||||
FLY_ATTACH_OBJECT, // NOT IMPLEMENTED
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FLY_ATTACH_TYPE_NONE,
|
||||
FLY_ATTACH_TYPE_LINE,
|
||||
FLY_ATTACH_TYPE_MULTI_LINE,
|
||||
FLY_ATTACH_TYPE_SINE,
|
||||
FLY_ATTACH_TYPE_EXP,
|
||||
};
|
||||
|
||||
struct TFlyingAttachData
|
||||
{
|
||||
int iType;
|
||||
int iFlyType;
|
||||
std::string strFilename;
|
||||
|
||||
bool bHasTail;
|
||||
DWORD dwTailColor;
|
||||
float fTailLength;
|
||||
float fTailSize;
|
||||
bool bRectShape;
|
||||
|
||||
float fRoll;
|
||||
// nothing for LINE
|
||||
// for MULTI_LINE
|
||||
float fDistance;
|
||||
// for SINE, EXP
|
||||
float fPeriod;
|
||||
float fAmplitude;
|
||||
};
|
||||
|
||||
friend class CFlyingInstance;
|
||||
|
||||
friend class CSceneFly;
|
||||
friend class CFlyTabPage;
|
||||
|
||||
CFlyingData();
|
||||
virtual ~CFlyingData();
|
||||
|
||||
void Destroy();
|
||||
|
||||
bool LoadScriptFile(const char* c_szFilename);
|
||||
bool SaveScriptFile(const char* c_szFilename);
|
||||
|
||||
const D3DXVECTOR3 & GetAcceleration() { return m_v3Accel; }
|
||||
|
||||
void SetBombEffect(const char* szEffectName);
|
||||
|
||||
DWORD AttachFlyEffect(int iType, const std::string & strFilename, float fRoll, float fArg1, float fArg2);
|
||||
|
||||
TFlyingAttachData & GetAttachDataReference(int iIndex);
|
||||
int GetAttachDataCount() { return m_AttachDataVector.size(); }
|
||||
|
||||
void DuplicateAttach(int iIndex);
|
||||
void RemoveAttach(int iIndex);
|
||||
void RemoveAllAttach();
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
|
||||
std::string m_strFilename;
|
||||
|
||||
bool m_bSpreading;
|
||||
bool m_bMaintainParallel;
|
||||
|
||||
float m_fInitVel;
|
||||
float m_fConeAngle;
|
||||
float m_fRollAngle;
|
||||
|
||||
D3DXVECTOR3 m_v3AngVel;
|
||||
|
||||
float m_fGravity;
|
||||
|
||||
float m_fBombRange;
|
||||
std::string m_strBombEffectName;
|
||||
DWORD m_dwBombEffectID;
|
||||
|
||||
bool m_bIsHoming;
|
||||
float m_fHomingMaxAngle;
|
||||
float m_fHomingStartTime;
|
||||
|
||||
bool m_bHitOnBackground;
|
||||
bool m_bHitOnAnotherMonster;
|
||||
int m_iPierceCount;
|
||||
float m_fCollisionSphereRadius;
|
||||
|
||||
float m_fRange;
|
||||
D3DXVECTOR3 m_v3Accel;
|
||||
|
||||
std::vector<TFlyingAttachData> m_AttachDataVector;
|
||||
|
||||
public:
|
||||
static CFlyingData * New() { return ms_kPool.Alloc(); }
|
||||
static void Delete(CFlyingData * pData) { pData->Destroy(); ms_kPool.Free(pData); }
|
||||
|
||||
static void DestroySystem() { ms_kPool.Destroy(); }
|
||||
|
||||
static CDynamicPool<CFlyingData> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,598 @@
|
||||
#include "Stdafx.h"
|
||||
#include "../eterLib/GrpMath.h"
|
||||
#include "../effectLib/EffectManager.h"
|
||||
|
||||
#include "MapManager.h"
|
||||
|
||||
#include "FlyingData.h"
|
||||
#include "FlyTrace.h"
|
||||
#include "FlyingInstance.h"
|
||||
#include "FlyingObjectManager.h"
|
||||
#include "FlyTarget.h"
|
||||
#include "FlyHandler.h"
|
||||
|
||||
CDynamicPool<CFlyingInstance> CFlyingInstance::ms_kPool;
|
||||
|
||||
CFlyingInstance::CFlyingInstance()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CFlyingInstance::~CFlyingInstance()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CFlyingInstance::__Initialize()
|
||||
{
|
||||
m_qAttachRotation=m_qRot=D3DXQUATERNION(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
m_v3Accel=m_v3LocalVelocity=m_v3Velocity=m_v3Position=D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_pHandler=NULL;
|
||||
m_pData=NULL;
|
||||
m_pOwner=NULL;
|
||||
|
||||
m_bAlive=false;
|
||||
m_canAttack=false;
|
||||
|
||||
m_dwSkillIndex = 0;
|
||||
|
||||
m_iPierceCount=0;
|
||||
|
||||
m_fStartTime=0.0f;
|
||||
m_fRemainRange=0.0f;
|
||||
|
||||
m_bTargetHitted = FALSE;
|
||||
m_HittedObjectSet.clear();
|
||||
}
|
||||
|
||||
void CFlyingInstance::Clear()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CFlyingInstance::Destroy()
|
||||
{
|
||||
m_FlyTarget.Clear();
|
||||
|
||||
ClearAttachInstance();
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
|
||||
void CFlyingInstance::BuildAttachInstance()
|
||||
{
|
||||
for(int i=0;i<m_pData->GetAttachDataCount();i++)
|
||||
{
|
||||
CFlyingData::TFlyingAttachData & rfad = m_pData->GetAttachDataReference(i);
|
||||
|
||||
switch(rfad.iType)
|
||||
{
|
||||
case CFlyingData::FLY_ATTACH_OBJECT:
|
||||
// NOT Implemented
|
||||
assert(!"FlyingInstance.cpp:BuildAttachInstance Not implemented FLY_ATTACH_OBJECT");
|
||||
break;
|
||||
case CFlyingData::FLY_ATTACH_EFFECT:
|
||||
{
|
||||
CEffectManager & rem = CEffectManager::Instance();
|
||||
TAttachEffectInstance aei;
|
||||
|
||||
DWORD dwCRC = GetCaseCRC32(rfad.strFilename.c_str(),rfad.strFilename.size());
|
||||
|
||||
aei.iAttachIndex = i;
|
||||
aei.dwEffectInstanceIndex = rem.GetEmptyIndex();
|
||||
|
||||
aei.pFlyTrace = NULL;
|
||||
if (rfad.bHasTail)
|
||||
{
|
||||
aei.pFlyTrace = CFlyTrace::New();
|
||||
aei.pFlyTrace->Create(rfad);
|
||||
}
|
||||
rem.CreateEffectInstance(aei.dwEffectInstanceIndex,dwCRC);
|
||||
|
||||
m_vecAttachEffectInstance.push_back(aei);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFlyingInstance::Create(CFlyingData* pData, const D3DXVECTOR3& c_rv3StartPos, const CFlyTarget & c_rkTarget, bool canAttack)
|
||||
{
|
||||
m_FlyTarget = c_rkTarget;
|
||||
m_canAttack = canAttack;
|
||||
|
||||
__SetDataPointer(pData, c_rv3StartPos);
|
||||
__SetTargetDirection(m_FlyTarget);
|
||||
}
|
||||
|
||||
void CFlyingInstance::__SetTargetDirection(const CFlyTarget& c_rkTarget)
|
||||
{
|
||||
D3DXVECTOR3 v3TargetPos=c_rkTarget.GetFlyTargetPosition();
|
||||
|
||||
// 임시 코드
|
||||
if (m_pData->m_bMaintainParallel)
|
||||
{
|
||||
v3TargetPos.z += 50.0f;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 v3TargetDir=v3TargetPos-m_v3Position;
|
||||
|
||||
D3DXVec3Normalize(&v3TargetDir, &v3TargetDir);
|
||||
__SetTargetNormalizedDirection(v3TargetDir);
|
||||
}
|
||||
|
||||
void CFlyingInstance::__SetTargetNormalizedDirection(const D3DXVECTOR3 & v3NomalizedDirection)
|
||||
{
|
||||
D3DXQUATERNION q = SafeRotationNormalizedArc(D3DXVECTOR3(0.0f,-1.0f,0.0f),v3NomalizedDirection);
|
||||
D3DXQuaternionMultiply(&m_qRot,&m_qRot,&q);
|
||||
Vec3TransformQuaternion(&m_v3Velocity,&m_v3LocalVelocity,&m_qRot);
|
||||
Vec3TransformQuaternion(&m_v3Accel, &m_pData->m_v3Accel, &m_qRot);
|
||||
}
|
||||
|
||||
// 2004. 3. 26. myevan. 기능을 몰라 일단 주석 처리. 적절한 네이밍이 필요. 게임에서 사용하지 않는다면 툴에서 툴 전용으로 상속받아 만들도록 하자
|
||||
void CFlyingInstance::SetFlyTarget(const CFlyTarget & cr_Target)
|
||||
{
|
||||
//m_pFlyTarget = pTarget;
|
||||
m_FlyTarget = cr_Target;
|
||||
//SetStartTargetPosition(m_FlyTarget.GetFlyTargetPosition());
|
||||
|
||||
__SetTargetDirection(m_FlyTarget);
|
||||
}
|
||||
|
||||
void CFlyingInstance::AdjustDirectionForHoming(const D3DXVECTOR3 & v3TargetPosition)
|
||||
{
|
||||
D3DXVECTOR3 vTargetDir(v3TargetPosition);
|
||||
vTargetDir -= m_v3Position;
|
||||
D3DXVec3Normalize(&vTargetDir,&vTargetDir);
|
||||
D3DXVECTOR3 vVel;
|
||||
D3DXVec3Normalize(&vVel, &m_v3Velocity);
|
||||
|
||||
const auto vv1 = (vVel - vTargetDir);
|
||||
if (D3DXVec3LengthSq(&vv1) < 0.001f)
|
||||
return;
|
||||
|
||||
D3DXQUATERNION q = SafeRotationNormalizedArc(vVel,vTargetDir);
|
||||
|
||||
if (m_pData->m_fHomingMaxAngle > 180)
|
||||
{
|
||||
Vec3TransformQuaternionSafe(&m_v3Velocity, &m_v3Velocity, &q);
|
||||
Vec3TransformQuaternionSafe(&m_v3Accel, &m_v3Accel, &q);
|
||||
D3DXQuaternionMultiply(&m_qRot, &q, &m_qRot);
|
||||
return;
|
||||
}
|
||||
|
||||
float c = cosf(D3DXToRadian(m_pData->m_fHomingMaxAngle));
|
||||
float s = sinf(D3DXToRadian(m_pData->m_fHomingMaxAngle));
|
||||
|
||||
if (q.w <= -1.0f + 0.0001f)
|
||||
{
|
||||
q.x = 0;
|
||||
q.y = 0;
|
||||
q.z = s;
|
||||
q.w = c;
|
||||
}
|
||||
else if (q.w <= c && q.w <= 1.0f - 0.0001f)
|
||||
{
|
||||
float factor = s / sqrtf(1.0f - q.w * q.w);
|
||||
q.x *= factor;
|
||||
q.y *= factor;
|
||||
q.z *= factor;
|
||||
q.w = c;
|
||||
}
|
||||
/*else
|
||||
{
|
||||
}*/
|
||||
Vec3TransformQuaternionSafe(&m_v3Velocity, &m_v3Velocity, &q);
|
||||
Vec3TransformQuaternionSafe(&m_v3Accel, &m_v3Accel, &q);
|
||||
D3DXQuaternionMultiply(&m_qRot, &m_qRot, &q);
|
||||
}
|
||||
|
||||
void CFlyingInstance::UpdateAttachInstance()
|
||||
{
|
||||
// Update Attach Rotation
|
||||
D3DXQUATERNION q;
|
||||
D3DXQuaternionRotationYawPitchRoll(&q,
|
||||
D3DXToRadian(m_pData->m_v3AngVel.y)*CTimer::Instance().GetElapsedSecond(),
|
||||
D3DXToRadian(m_pData->m_v3AngVel.x)*CTimer::Instance().GetElapsedSecond(),
|
||||
D3DXToRadian(m_pData->m_v3AngVel.z)*CTimer::Instance().GetElapsedSecond());
|
||||
|
||||
D3DXQuaternionMultiply(&m_qAttachRotation, &m_qAttachRotation, &q);
|
||||
D3DXQuaternionMultiply(&q, &m_qAttachRotation, &m_qRot);
|
||||
|
||||
CEffectManager & rem = CEffectManager::Instance();
|
||||
TAttachEffectInstanceVector::iterator it;
|
||||
for(it = m_vecAttachEffectInstance.begin();it!=m_vecAttachEffectInstance.end();++it)
|
||||
{
|
||||
CFlyingData::TFlyingAttachData & rfad = m_pData->GetAttachDataReference(it->iAttachIndex);
|
||||
assert(rfad.iType == CFlyingData::FLY_ATTACH_EFFECT);
|
||||
rem.SelectEffectInstance(it->dwEffectInstanceIndex);
|
||||
D3DXMATRIX m;
|
||||
switch(rfad.iFlyType)
|
||||
{
|
||||
case CFlyingData::FLY_ATTACH_TYPE_LINE:
|
||||
D3DXMatrixRotationQuaternion(&m,&m_qRot);
|
||||
//D3DXMatrixRotationQuaternion(&m,&q);
|
||||
m._41=m_v3Position.x;
|
||||
m._42=m_v3Position.y;
|
||||
m._43=m_v3Position.z;
|
||||
break;
|
||||
case CFlyingData::FLY_ATTACH_TYPE_MULTI_LINE:
|
||||
{
|
||||
D3DXVECTOR3 p(
|
||||
-sinf(D3DXToRadian(rfad.fRoll))*rfad.fDistance,
|
||||
0.0f,
|
||||
-cosf(D3DXToRadian(rfad.fRoll))*rfad.fDistance);
|
||||
//Vec3TransformQuaternionSafe(&p,&p,&m_qRot);
|
||||
Vec3TransformQuaternionSafe(&p,&p,&q);
|
||||
p+=m_v3Position;
|
||||
//D3DXMatrixRotationQuaternion(&m,&m_qRot);
|
||||
D3DXMatrixRotationQuaternion(&m,&q);
|
||||
m._41=p.x;
|
||||
m._42=p.y;
|
||||
m._43=p.z;
|
||||
}
|
||||
break;
|
||||
case CFlyingData::FLY_ATTACH_TYPE_SINE:
|
||||
{
|
||||
//Tracenf("%f",CTimer::Instance().GetCurrentSecond());
|
||||
float angle = (CTimer::Instance().GetCurrentSecond() - m_fStartTime)*2*3.1415926535897931f/rfad.fPeriod;
|
||||
D3DXVECTOR3 p(
|
||||
-sinf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*sinf(angle),
|
||||
0.0f,
|
||||
-cosf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*sinf(angle));
|
||||
Vec3TransformQuaternionSafe(&p,&p,&q);
|
||||
//Vec3TransformQuaternionSafe(&p,&p,&m_qRot);
|
||||
p+=m_v3Position;
|
||||
D3DXMatrixRotationQuaternion(&m,&q);
|
||||
//D3DXMatrixRotationQuaternion(&m,&m_qRot);
|
||||
m._41=p.x;
|
||||
m._42=p.y;
|
||||
m._43=p.z;
|
||||
//assert(!"NOT IMPLEMENTED");
|
||||
}
|
||||
break;
|
||||
case CFlyingData::FLY_ATTACH_TYPE_EXP:
|
||||
{
|
||||
float dt = CTimer::Instance().GetCurrentSecond() - m_fStartTime;
|
||||
float angle = dt/rfad.fPeriod;
|
||||
D3DXVECTOR3 p(
|
||||
-sinf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*exp(-angle)*angle,
|
||||
0.0f,
|
||||
-cosf(D3DXToRadian(rfad.fRoll))*rfad.fAmplitude*exp(-angle)*angle);
|
||||
//Vec3TransformQuaternionSafe(&p,&p,&m_qRot);
|
||||
Vec3TransformQuaternionSafe(&p,&p,&q);
|
||||
p+=m_v3Position;
|
||||
D3DXMatrixRotationQuaternion(&m,&q);
|
||||
//D3DXMatrixRotationQuaternion(&m,&m_qRot);
|
||||
m._41=p.x;
|
||||
m._42=p.y;
|
||||
m._43=p.z;
|
||||
//assert(!"NOT IMPLEMENTED");
|
||||
}
|
||||
break;
|
||||
}
|
||||
rem.SetEffectInstanceGlobalMatrix(m);
|
||||
if (it->pFlyTrace)
|
||||
it->pFlyTrace->UpdateNewPosition(D3DXVECTOR3(m._41,m._42,m._43));
|
||||
}
|
||||
}
|
||||
struct FCheckBackgroundDuringFlying {
|
||||
CDynamicSphereInstance s;
|
||||
bool bHit;
|
||||
FCheckBackgroundDuringFlying(const D3DXVECTOR3 & v1, const D3DXVECTOR3 & v2)
|
||||
{
|
||||
s.fRadius = 1.0f;
|
||||
s.v3LastPosition = v1;
|
||||
s.v3Position = v2;
|
||||
bHit = false;
|
||||
}
|
||||
void operator () (CGraphicObjectInstance * p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
if (!bHit && p->GetType() != ACTOR_OBJECT)
|
||||
{
|
||||
if (p->CollisionDynamicSphere(s))
|
||||
{
|
||||
bHit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool IsHitted()
|
||||
{
|
||||
return bHit;
|
||||
}
|
||||
};
|
||||
|
||||
struct FCheckAnotherMonsterDuringFlying {
|
||||
CDynamicSphereInstance s;
|
||||
CGraphicObjectInstance * pInst;
|
||||
const IActorInstance * pOwner;
|
||||
FCheckAnotherMonsterDuringFlying(const IActorInstance * pOwner, const D3DXVECTOR3 & v1, const D3DXVECTOR3 & v2)
|
||||
: pOwner(pOwner)
|
||||
{
|
||||
s.fRadius = 10.0f;
|
||||
s.v3LastPosition = v1;
|
||||
s.v3Position = v2;
|
||||
pInst = 0;
|
||||
}
|
||||
void operator () (CGraphicObjectInstance * p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
if (!pInst && p->GetType() == ACTOR_OBJECT)
|
||||
{
|
||||
IActorInstance * pa = (IActorInstance*) p;
|
||||
if (pa != pOwner && pa->TestCollisionWithDynamicSphere(s))
|
||||
{
|
||||
pInst = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool IsHitted()
|
||||
{
|
||||
return pInst!=0;
|
||||
}
|
||||
CGraphicObjectInstance * GetHittedObject()
|
||||
{
|
||||
return pInst;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
bool CFlyingInstance::Update()
|
||||
{
|
||||
if (!m_bAlive)
|
||||
return false;
|
||||
|
||||
if (m_pData->m_bIsHoming &&
|
||||
m_pData->m_fHomingStartTime + m_fStartTime < CTimer::Instance().GetCurrentSecond())
|
||||
{
|
||||
if (m_FlyTarget.IsObject())
|
||||
AdjustDirectionForHoming(m_FlyTarget.GetFlyTargetPosition());
|
||||
}
|
||||
|
||||
D3DXVECTOR3 v3LastPosition = m_v3Position;
|
||||
|
||||
m_v3Velocity += m_v3Accel*CTimer::Instance().GetElapsedSecond();
|
||||
m_v3Velocity.z+=m_pData->m_fGravity * CTimer::Instance().GetElapsedSecond();
|
||||
D3DXVECTOR3 v3Movement = m_v3Velocity * CTimer::Instance().GetElapsedSecond();
|
||||
float _fMoveDistance = D3DXVec3Length(&v3Movement);
|
||||
float fCollisionSphereRadius = max(_fMoveDistance*2, m_pData->m_fCollisionSphereRadius);
|
||||
m_fRemainRange -= _fMoveDistance;
|
||||
m_v3Position += v3Movement;
|
||||
|
||||
UpdateAttachInstance();
|
||||
|
||||
if (m_fRemainRange<0)
|
||||
{
|
||||
if (m_pHandler)
|
||||
m_pHandler->OnExplodingOutOfRange();
|
||||
|
||||
__Explode(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_FlyTarget.IsObject())
|
||||
{
|
||||
if (!m_bTargetHitted)
|
||||
{
|
||||
if (square_distance_between_linesegment_and_point(m_v3Position,v3LastPosition,m_FlyTarget.GetFlyTargetPosition())<m_pData->m_fBombRange*m_pData->m_fBombRange)
|
||||
{
|
||||
m_bTargetHitted = TRUE;
|
||||
|
||||
if (m_canAttack)
|
||||
{
|
||||
IFlyTargetableObject* pVictim=m_FlyTarget.GetFlyTarget();
|
||||
if (pVictim)
|
||||
{
|
||||
pVictim->OnShootDamage();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pHandler)
|
||||
{
|
||||
m_pHandler->OnExplodingAtTarget(m_dwSkillIndex);
|
||||
}
|
||||
|
||||
if (m_iPierceCount)
|
||||
{
|
||||
m_iPierceCount--;
|
||||
__Bomb();
|
||||
}
|
||||
else
|
||||
{
|
||||
__Explode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_FlyTarget.IsPosition())
|
||||
{
|
||||
if (square_distance_between_linesegment_and_point(m_v3Position,v3LastPosition,m_FlyTarget.GetFlyTargetPosition())<m_pData->m_fBombRange*m_pData->m_fBombRange)
|
||||
{
|
||||
__Explode();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3d vecStart, vecDir;
|
||||
vecStart.Set(v3LastPosition.x,v3LastPosition.y,v3LastPosition.z);
|
||||
vecDir.Set(v3Movement.x,v3Movement.y,v3Movement.z);
|
||||
|
||||
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
||||
|
||||
if (m_pData->m_bHitOnAnotherMonster)
|
||||
{
|
||||
FCheckAnotherMonsterDuringFlying kCheckAnotherMonsterDuringFlying(m_pOwner, v3LastPosition,m_v3Position);
|
||||
rkCullingMgr.ForInRange(vecStart,fCollisionSphereRadius, &kCheckAnotherMonsterDuringFlying);
|
||||
if (kCheckAnotherMonsterDuringFlying.IsHitted())
|
||||
{
|
||||
IActorInstance * pHittedInstance = (IActorInstance*)kCheckAnotherMonsterDuringFlying.GetHittedObject();
|
||||
if (m_HittedObjectSet.end() == m_HittedObjectSet.find(pHittedInstance))
|
||||
{
|
||||
m_HittedObjectSet.insert(pHittedInstance);
|
||||
|
||||
if (m_pHandler)
|
||||
{
|
||||
m_pHandler->OnExplodingAtAnotherTarget(m_dwSkillIndex, pHittedInstance->GetVirtualID());
|
||||
}
|
||||
|
||||
if (m_iPierceCount)
|
||||
{
|
||||
m_iPierceCount--;
|
||||
__Bomb();
|
||||
}
|
||||
else
|
||||
{
|
||||
__Explode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pData->m_bHitOnBackground)
|
||||
{
|
||||
// 지형 충돌
|
||||
|
||||
if (CFlyingManager::Instance().GetMapManagerPtr())
|
||||
{
|
||||
float fGroundHeight = CFlyingManager::Instance().GetMapManagerPtr()->GetTerrainHeight(m_v3Position.x,-m_v3Position.y);
|
||||
if (fGroundHeight>m_v3Position.z)
|
||||
{
|
||||
if (m_pHandler)
|
||||
m_pHandler->OnExplodingAtBackground();
|
||||
|
||||
__Explode();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 건물+나무 충돌
|
||||
|
||||
FCheckBackgroundDuringFlying kCheckBackgroundDuringFlying(v3LastPosition,m_v3Position);
|
||||
rkCullingMgr.ForInRange(vecStart,fCollisionSphereRadius, &kCheckBackgroundDuringFlying);
|
||||
|
||||
if (kCheckBackgroundDuringFlying.IsHitted())
|
||||
{
|
||||
if (m_pHandler)
|
||||
m_pHandler->OnExplodingAtBackground();
|
||||
|
||||
__Explode();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CFlyingInstance::ClearAttachInstance()
|
||||
{
|
||||
CEffectManager & rkEftMgr = CEffectManager::Instance();
|
||||
|
||||
TAttachEffectInstanceVector::iterator i;
|
||||
for(i = m_vecAttachEffectInstance.begin();i!=m_vecAttachEffectInstance.end();++i)
|
||||
{
|
||||
rkEftMgr.DestroyEffectInstance(i->dwEffectInstanceIndex);
|
||||
|
||||
if (i->pFlyTrace)
|
||||
CFlyTrace::Delete(i->pFlyTrace);
|
||||
|
||||
i->iAttachIndex=0;
|
||||
i->dwEffectInstanceIndex=0;
|
||||
i->pFlyTrace=NULL;
|
||||
}
|
||||
m_vecAttachEffectInstance.clear();
|
||||
}
|
||||
|
||||
void CFlyingInstance::__Explode(bool bBomb)
|
||||
{
|
||||
if (!m_bAlive)
|
||||
return;
|
||||
|
||||
m_bAlive = false;
|
||||
|
||||
if (bBomb)
|
||||
__Bomb();
|
||||
}
|
||||
|
||||
void CFlyingInstance::__Bomb()
|
||||
{
|
||||
CEffectManager & rkEftMgr = CEffectManager::Instance();
|
||||
if (!m_pData->m_dwBombEffectID)
|
||||
return;
|
||||
|
||||
DWORD dwEmptyIndex = rkEftMgr.GetEmptyIndex();
|
||||
rkEftMgr.CreateEffectInstance(dwEmptyIndex,m_pData->m_dwBombEffectID);
|
||||
|
||||
D3DXMATRIX m;
|
||||
// D3DXMatrixRotationQuaternion(&m,&m_qRot);
|
||||
D3DXMatrixIdentity(&m);
|
||||
m._41 = m_v3Position.x;
|
||||
m._42 = m_v3Position.y;
|
||||
m._43 = m_v3Position.z;
|
||||
rkEftMgr.SelectEffectInstance(dwEmptyIndex);
|
||||
rkEftMgr.SetEffectInstanceGlobalMatrix(m);
|
||||
}
|
||||
|
||||
void CFlyingInstance::Render()
|
||||
{
|
||||
if (!m_bAlive)
|
||||
return;
|
||||
RenderAttachInstance();
|
||||
}
|
||||
|
||||
void CFlyingInstance::RenderAttachInstance()
|
||||
{
|
||||
TAttachEffectInstanceVector::iterator it;
|
||||
for(it = m_vecAttachEffectInstance.begin();it!=m_vecAttachEffectInstance.end();++it)
|
||||
{
|
||||
if (it->pFlyTrace)
|
||||
it->pFlyTrace->Render();
|
||||
}
|
||||
}
|
||||
|
||||
void CFlyingInstance::SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition)
|
||||
{
|
||||
__SetDataPointer(pData, v3StartPosition);
|
||||
}
|
||||
|
||||
void CFlyingInstance::__SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition)
|
||||
{
|
||||
m_pData = pData;
|
||||
m_qRot = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f),
|
||||
m_v3Position = (v3StartPosition);
|
||||
m_bAlive = (true);
|
||||
|
||||
m_fStartTime = CTimer::Instance().GetCurrentSecond();
|
||||
|
||||
D3DXQuaternionRotationYawPitchRoll(&m_qRot,D3DXToRadian(pData->m_fRollAngle-90.0f),0.0f,D3DXToRadian(pData->m_fConeAngle));
|
||||
if (pData->m_bSpreading)
|
||||
{
|
||||
D3DXQUATERNION q1, q2;
|
||||
const auto vv1 = D3DXVECTOR3(0.0f, 0.0f, 1.0f), vv2 = D3DXVECTOR3(0.0f, -1.0f, 0.0f);
|
||||
D3DXQuaternionRotationAxis(&q2, &vv1,(frandom(-3.141592f/3,+3.141592f/3)+frandom(-3.141592f/3,+3.141592f/3))/2);
|
||||
D3DXQuaternionRotationAxis(&q1, &vv2, frandom(0,2*3.1415926535897931f));
|
||||
D3DXQuaternionMultiply(&q1,&q2,&q1);
|
||||
D3DXQuaternionMultiply(&m_qRot,&q1,&m_qRot);
|
||||
}
|
||||
m_v3Velocity = m_v3LocalVelocity = D3DXVECTOR3(0.0f,-pData->m_fInitVel,0.0f);
|
||||
m_v3Accel = pData->m_v3Accel;
|
||||
m_fRemainRange = pData->m_fRange;
|
||||
m_qAttachRotation = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f);
|
||||
|
||||
BuildAttachInstance();
|
||||
UpdateAttachInstance();
|
||||
|
||||
m_iPierceCount = pData->m_iPierceCount;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
#include "FlyTarget.h"
|
||||
#include "ActorInstanceInterface.h"
|
||||
|
||||
class CFlyingData;
|
||||
class CFlyTrace;
|
||||
class IFlyEventHandler;
|
||||
class CActorInstance;
|
||||
|
||||
class CFlyingInstance
|
||||
{
|
||||
public:
|
||||
// 2004. 3. 26. myevan. 적절한 네이밍이 필요. 게임에서 사용하지 않는다면 툴에서 툴 전용으로 상속받아 만들도록 하자
|
||||
void Clear(); // Destroy와 같다
|
||||
void SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition);
|
||||
void SetFlyTarget(const CFlyTarget & cr_Target); // Shot at Target
|
||||
|
||||
public:
|
||||
friend class CSceneFly;
|
||||
|
||||
struct TAttachEffectInstance
|
||||
{
|
||||
int iAttachIndex;
|
||||
DWORD dwEffectInstanceIndex;
|
||||
|
||||
CFlyTrace * pFlyTrace;
|
||||
};
|
||||
|
||||
CFlyingInstance();
|
||||
virtual ~CFlyingInstance();
|
||||
|
||||
void Destroy();
|
||||
void Create(CFlyingData* pData, const D3DXVECTOR3& c_rv3StartPos, const CFlyTarget & c_rkTarget, bool canAttack);
|
||||
|
||||
bool Update();
|
||||
void Render();
|
||||
|
||||
bool IsAlive() { return m_bAlive; }
|
||||
|
||||
const D3DXVECTOR3 & GetPosition() { return m_v3Position; }
|
||||
|
||||
void AdjustDirectionForHoming(const D3DXVECTOR3 & v3TargetPosition);
|
||||
|
||||
typedef std::vector<TAttachEffectInstance> TAttachEffectInstanceVector;
|
||||
|
||||
void BuildAttachInstance();
|
||||
void UpdateAttachInstance();
|
||||
void RenderAttachInstance();
|
||||
void ClearAttachInstance();
|
||||
|
||||
void SetEventHandler(IFlyEventHandler * pHandler) { m_pHandler = pHandler; }
|
||||
void ClearEventHandler() { m_pHandler = 0; }
|
||||
|
||||
void SetPierceCount(int iCount) { m_iPierceCount = iCount; }
|
||||
void SetOwner(IActorInstance * pOwner) { m_pOwner = pOwner; }
|
||||
void SetSkillIndex(DWORD dwIndex) { m_dwSkillIndex = dwIndex; }
|
||||
|
||||
// FIXME : 툴에서 사용하고 있습니다. 임시로 위로.. - [levites]
|
||||
void __Explode(bool bBomb=true);
|
||||
void __Bomb();
|
||||
|
||||
DWORD ID;
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
|
||||
void __SetDataPointer(CFlyingData * pData, const D3DXVECTOR3 & v3StartPosition);
|
||||
void __SetTargetDirection(const CFlyTarget& c_rkTarget);
|
||||
void __SetTargetNormalizedDirection(const D3DXVECTOR3 & v3NormalizedDirection ); // 시작 타겟 방향 설정
|
||||
|
||||
protected:
|
||||
|
||||
CFlyingData * m_pData;
|
||||
D3DXQUATERNION m_qRot;
|
||||
|
||||
float m_fStartTime;
|
||||
|
||||
bool m_bAlive;
|
||||
bool m_canAttack;
|
||||
|
||||
int m_iPierceCount;
|
||||
DWORD m_dwSkillIndex;
|
||||
|
||||
D3DXVECTOR3 m_v3Position;
|
||||
D3DXVECTOR3 m_v3Velocity;
|
||||
D3DXVECTOR3 m_v3LocalVelocity;
|
||||
D3DXVECTOR3 m_v3Accel;
|
||||
|
||||
float m_fRemainRange;
|
||||
|
||||
CFlyTarget m_FlyTarget;
|
||||
|
||||
D3DXQUATERNION m_qAttachRotation;
|
||||
TAttachEffectInstanceVector m_vecAttachEffectInstance;
|
||||
|
||||
IFlyEventHandler * m_pHandler;
|
||||
|
||||
IActorInstance * m_pOwner;
|
||||
|
||||
BOOL m_bTargetHitted;
|
||||
std::set<IActorInstance *> m_HittedObjectSet;
|
||||
|
||||
public:
|
||||
static CFlyingInstance * New() { return ms_kPool.Alloc(); }
|
||||
static void Delete(CFlyingInstance * pInstance) { pInstance->Destroy(); ms_kPool.Free(pInstance); }
|
||||
|
||||
static void DestroySystem() { ms_kPool.Destroy(); }
|
||||
|
||||
static CDynamicPool<CFlyingInstance> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,214 @@
|
||||
#include "Stdafx.h"
|
||||
|
||||
#include "FlyingData.h"
|
||||
#include "FlyingInstance.h"
|
||||
#include "FlyingObjectManager.h"
|
||||
|
||||
#include "ActorInstance.h"
|
||||
|
||||
CFlyingManager::CFlyingManager()
|
||||
{
|
||||
m_pMapManager = 0;
|
||||
}
|
||||
|
||||
CFlyingManager::~CFlyingManager()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CFlyingManager::__DestroyFlyingInstanceList()
|
||||
{
|
||||
TFlyingInstanceList::iterator i;
|
||||
for(i = m_kLst_pkFlyInst.begin(); i!=m_kLst_pkFlyInst.end(); ++i)
|
||||
{
|
||||
CFlyingInstance* pkFlyInst=*i;
|
||||
CFlyingInstance::Delete(pkFlyInst);
|
||||
}
|
||||
m_kLst_pkFlyInst.clear();
|
||||
}
|
||||
|
||||
void CFlyingManager::__DestroyFlyingDataMap()
|
||||
{
|
||||
TFlyingDataMap::iterator i;
|
||||
for(i = m_kMap_pkFlyData.begin(); i != m_kMap_pkFlyData.end(); ++i)
|
||||
{
|
||||
CFlyingData* pkFlyData=i->second;
|
||||
CFlyingData::Delete(pkFlyData);
|
||||
}
|
||||
m_kMap_pkFlyData.clear();
|
||||
}
|
||||
|
||||
|
||||
void CFlyingManager::DeleteAllInstances()
|
||||
{
|
||||
__DestroyFlyingInstanceList();
|
||||
}
|
||||
|
||||
void CFlyingManager::Destroy()
|
||||
{
|
||||
__DestroyFlyingInstanceList();
|
||||
__DestroyFlyingDataMap();
|
||||
|
||||
m_pMapManager = 0;
|
||||
}
|
||||
|
||||
bool CFlyingManager::RegisterFlyingData(const char* c_szFilename)
|
||||
{
|
||||
std::string s;
|
||||
StringPath(c_szFilename,s);
|
||||
DWORD dwRetCRC = GetCaseCRC32(s.c_str(),s.size());
|
||||
|
||||
if (m_kMap_pkFlyData.find(dwRetCRC) != m_kMap_pkFlyData.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CFlyingData * pFlyingData = CFlyingData::New();
|
||||
if (!pFlyingData->LoadScriptFile(c_szFilename))
|
||||
{
|
||||
Tracenf("CEffectManager::RegisterFlyingData %s - Failed to load flying data file", c_szFilename);
|
||||
CFlyingData::Delete(pFlyingData);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_kMap_pkFlyData.insert(std::make_pair(dwRetCRC,pFlyingData));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFlyingManager::RegisterFlyingData(const char* c_szFilename, DWORD & r_dwRetCRC)
|
||||
{
|
||||
std::string s;
|
||||
StringPath(c_szFilename,s);
|
||||
r_dwRetCRC = GetCaseCRC32(s.c_str(),s.size());
|
||||
|
||||
if (m_kMap_pkFlyData.find(r_dwRetCRC) != m_kMap_pkFlyData.end())
|
||||
{
|
||||
TraceError("CFlyingManager::RegisterFlyingData - Already exists flying data named [%s]", c_szFilename);
|
||||
return false;
|
||||
}
|
||||
|
||||
CFlyingData * pFlyingData = CFlyingData::New();
|
||||
if (!pFlyingData->LoadScriptFile(c_szFilename))
|
||||
{
|
||||
TraceError("CEffectManager::RegisterFlyingData %s - Failed to load flying data file", c_szFilename);
|
||||
CFlyingData::Delete(pFlyingData);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
m_kMap_pkFlyData.insert(std::make_pair(r_dwRetCRC,pFlyingData));
|
||||
return true;
|
||||
}
|
||||
|
||||
CFlyingInstance * CFlyingManager::CreateFlyingInstanceFlyTarget(const DWORD dwID,
|
||||
const D3DXVECTOR3 & v3StartPosition,
|
||||
const CFlyTarget & cr_FlyTarget,
|
||||
bool canAttack)
|
||||
{
|
||||
if (m_kMap_pkFlyData.find(dwID) == m_kMap_pkFlyData.end())
|
||||
{
|
||||
//TraceError("CFlyingManager::CreateFlyingInstanceFlyTarget - No data with CRC [%d]", dwID);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CFlyingInstance * pFlyingInstance = CFlyingInstance::New();
|
||||
pFlyingInstance->Create(m_kMap_pkFlyData[dwID], v3StartPosition, cr_FlyTarget, canAttack);
|
||||
|
||||
m_kLst_pkFlyInst.push_back(pFlyingInstance);
|
||||
|
||||
pFlyingInstance->ID = m_IDCounter++;
|
||||
return pFlyingInstance;
|
||||
}
|
||||
|
||||
void CFlyingManager::Update()
|
||||
{
|
||||
TFlyingInstanceList::iterator i=m_kLst_pkFlyInst.begin();
|
||||
|
||||
while (i!=m_kLst_pkFlyInst.end())
|
||||
{
|
||||
CFlyingInstance* pkFlyInst=*i;
|
||||
if (!pkFlyInst->Update())
|
||||
{
|
||||
CFlyingInstance::Delete(pkFlyInst);
|
||||
i=m_kLst_pkFlyInst.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFlyingManager::Render()
|
||||
{
|
||||
std::for_each(m_kLst_pkFlyInst.begin(), m_kLst_pkFlyInst.end(), std::mem_fn(&CFlyingInstance::Render));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool CFlyingManager::RegisterIndexedFlyData(DWORD dwIndex, BYTE byType, const char * c_szFileName)
|
||||
{
|
||||
DWORD dwCRC;
|
||||
if (!RegisterFlyingData(c_szFileName, dwCRC))
|
||||
{
|
||||
TraceError("CFlyingManager::RegisterIndexFlyData(dwIndex=%d, c_szFileName=%s) - Failed to load flying data file", dwIndex, c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
TIndexFlyData IndexFlyData;
|
||||
IndexFlyData.byType = byType;
|
||||
IndexFlyData.dwCRC = dwCRC;
|
||||
m_kMap_dwIndexFlyData.insert(std::make_pair(dwIndex, IndexFlyData));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CFlyingManager::CreateIndexedFly(DWORD dwIndex, CActorInstance * pStartActor, CActorInstance * pEndActor)
|
||||
{
|
||||
if (m_kMap_dwIndexFlyData.end() == m_kMap_dwIndexFlyData.find(dwIndex))
|
||||
{
|
||||
TraceError("CFlyingManager::CreateIndexedFly(dwIndex=%d) - Not registered index", dwIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
TPixelPosition posStart;
|
||||
pStartActor->GetPixelPosition(&posStart);
|
||||
|
||||
TIndexFlyData & rIndexFlyData = m_kMap_dwIndexFlyData[dwIndex];
|
||||
switch (rIndexFlyData.byType)
|
||||
{
|
||||
case INDEX_FLY_TYPE_NORMAL:
|
||||
{
|
||||
CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC,
|
||||
D3DXVECTOR3(posStart.x, posStart.y, posStart.z),
|
||||
pEndActor,
|
||||
false);
|
||||
break;
|
||||
}
|
||||
case INDEX_FLY_TYPE_FIRE_CRACKER:
|
||||
{
|
||||
float fRot = fmod(pStartActor->GetRotation() - 90.0f + 360.0f, 360.0f) + frandom(-30.0f, 30.0f);
|
||||
|
||||
float fDistance = frandom(2000.0f, 5000.0f);
|
||||
float fxRand = fDistance * cosf(D3DXToRadian(fRot));
|
||||
float fyRand = fDistance * sinf(D3DXToRadian(fRot));
|
||||
float fzRand = frandom(1000.0f, 2500.0f);
|
||||
|
||||
CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC,
|
||||
D3DXVECTOR3(posStart.x, posStart.y, posStart.z+200),
|
||||
D3DXVECTOR3(posStart.x + fxRand, posStart.y + fyRand, posStart.z + fzRand),
|
||||
false);
|
||||
break;
|
||||
}
|
||||
case INDEX_FLY_TYPE_AUTO_FIRE:
|
||||
{
|
||||
CreateFlyingInstanceFlyTarget(rIndexFlyData.dwCRC,
|
||||
D3DXVECTOR3(posStart.x, posStart.y, posStart.z+100.0f),
|
||||
pEndActor,
|
||||
false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include "FlyTarget.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
class CFlyingInstance;
|
||||
class CFlyingData;
|
||||
class CMapManager;
|
||||
class CActorInstance;
|
||||
|
||||
class CFlyingManager : public CSingleton<CFlyingManager>
|
||||
{
|
||||
public:
|
||||
enum EIndexFlyType
|
||||
{
|
||||
INDEX_FLY_TYPE_NORMAL,
|
||||
INDEX_FLY_TYPE_FIRE_CRACKER,
|
||||
INDEX_FLY_TYPE_AUTO_FIRE,
|
||||
};
|
||||
|
||||
public:
|
||||
CFlyingManager();
|
||||
virtual ~CFlyingManager();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void DeleteAllInstances();
|
||||
|
||||
bool RegisterFlyingData(const char* c_szFilename);
|
||||
bool RegisterFlyingData(const char* c_szFilename, DWORD & r_dwRetCRC);
|
||||
|
||||
CFlyingInstance * CreateFlyingInstanceFlyTarget(const DWORD dwID, const D3DXVECTOR3 & v3StartPosition, const CFlyTarget & cr_FlyTarget, bool canAttack);
|
||||
|
||||
void Update();
|
||||
void Render();
|
||||
|
||||
void SetMapManagerPtr(CMapManager * pMapManager) { m_pMapManager = pMapManager; }
|
||||
CMapManager * GetMapManagerPtr() { return m_pMapManager; }
|
||||
|
||||
public: // Controlled by Server
|
||||
bool RegisterIndexedFlyData(DWORD dwIndex, BYTE byType, const char * c_szFileName);
|
||||
void CreateIndexedFly(DWORD dwIndex, CActorInstance * pStartActor, CActorInstance * pEndActor);
|
||||
|
||||
private:
|
||||
void __DestroyFlyingInstanceList();
|
||||
void __DestroyFlyingDataMap();
|
||||
|
||||
typedef std::map<DWORD, CFlyingData *> TFlyingDataMap;
|
||||
typedef std::list<CFlyingInstance *> TFlyingInstanceList;
|
||||
|
||||
typedef struct SIndexFlyData
|
||||
{
|
||||
BYTE byType;
|
||||
DWORD dwCRC;
|
||||
} TIndexFlyData;
|
||||
typedef std::map<DWORD, TIndexFlyData> TIndexFlyDataMap;
|
||||
|
||||
TFlyingDataMap m_kMap_pkFlyData;
|
||||
TFlyingInstanceList m_kLst_pkFlyInst;
|
||||
TIndexFlyDataMap m_kMap_dwIndexFlyData;
|
||||
|
||||
CMapManager * m_pMapManager;
|
||||
|
||||
DWORD m_IDCounter;
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "StdAfx.h"
|
||||
#include "GameEventManager.h"
|
||||
|
||||
void CGameEventManager::SetCenterPosition(float fx, float fy, float fz)
|
||||
{
|
||||
m_CenterPosition.x = +fx;
|
||||
m_CenterPosition.y = -fy;
|
||||
m_CenterPosition.z = +fz;
|
||||
}
|
||||
|
||||
void CGameEventManager::Update()
|
||||
{
|
||||
}
|
||||
|
||||
void CGameEventManager::ProcessEventScreenWaving(CActorInstance * pActorInstance, const CRaceMotionData::TScreenWavingEventData * c_pData)
|
||||
{
|
||||
TPixelPosition PixelPosition;
|
||||
pActorInstance->GetPixelPosition(&PixelPosition);
|
||||
|
||||
float fdx = PixelPosition.x - m_CenterPosition.x;
|
||||
float fdy = PixelPosition.y - m_CenterPosition.y;
|
||||
float fdz = PixelPosition.z - m_CenterPosition.z;
|
||||
|
||||
if (fdx * fdx + fdy * fdy + fdz * fdz > c_pData->iAffectingRange * c_pData->iAffectingRange)
|
||||
return;
|
||||
|
||||
SetScreenEffectWaving(c_pData->fDurationTime, c_pData->iPower);
|
||||
}
|
||||
|
||||
CGameEventManager::CGameEventManager() : m_CenterPosition(0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
CGameEventManager::~CGameEventManager()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "ActorInstance.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGameEventManager
|
||||
//
|
||||
// Note : Game상에서 일어나는 폭발, 화면 흔들림, Range 무기들의 움직임과 타격 등의 Event
|
||||
// 를 종합적으로 관리하는 클래스. - [levites]
|
||||
//
|
||||
// Note : 게임상의 Cinematic Event 를 컨트롤하는 매니져로 사용한다. 2004.07.19 - [levites]
|
||||
//
|
||||
|
||||
class CGameEventManager : public CSingleton<CGameEventManager>, public CScreen
|
||||
{
|
||||
public:
|
||||
CGameEventManager();
|
||||
virtual ~CGameEventManager();
|
||||
|
||||
void SetCenterPosition(float fx, float fy, float fz);
|
||||
void Update();
|
||||
|
||||
void ProcessEventScreenWaving(CActorInstance * pActorInstance, const CRaceMotionData::TScreenWavingEventData * c_pData);
|
||||
|
||||
protected:
|
||||
TPixelPosition m_CenterPosition;
|
||||
};
|
||||
@@ -0,0 +1,362 @@
|
||||
#include "StdAfx.h"
|
||||
#include "GameType.h"
|
||||
#include "../effectLib/EffectManager.h"
|
||||
|
||||
extern float g_fGameFPS = 60.0f;
|
||||
|
||||
CDynamicPool<NRaceData::TCollisionData> NRaceData::g_CollisionDataPool;
|
||||
CDynamicPool<NRaceData::TAttachingEffectData> NRaceData::g_EffectDataPool;
|
||||
CDynamicPool<NRaceData::TAttachingObjectData> NRaceData::g_ObjectDataPool;
|
||||
|
||||
void NRaceData::DestroySystem()
|
||||
{
|
||||
g_CollisionDataPool.Destroy();
|
||||
g_EffectDataPool.Destroy();
|
||||
g_ObjectDataPool.Destroy();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Character Attaching Collision Data
|
||||
BOOL NRaceData::LoadAttackData(CTextFileLoader & rTextFileLoader, TAttackData * pData)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenInteger("attacktype", &pData->iAttackType))
|
||||
{
|
||||
pData->iAttackType = ATTACK_TYPE_SPLASH;
|
||||
}
|
||||
if (!rTextFileLoader.GetTokenInteger("hittingtype", &pData->iHittingType))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenFloat("stiffentime", &pData->fStiffenTime))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenFloat("invisibletime", &pData->fInvisibleTime))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenFloat("externalforce", &pData->fExternalForce))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenInteger("hitlimitcount", &pData->iHitLimitCount))
|
||||
{
|
||||
pData->iHitLimitCount = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NRaceData::THitData::Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenFloat("attackingstarttime", &fAttackStartTime))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenFloat("attackingendtime", &fAttackEndTime))
|
||||
return false;
|
||||
|
||||
if (!rTextFileLoader.GetTokenString("attackingbone", &strBoneName))
|
||||
strBoneName = "";
|
||||
if (!rTextFileLoader.GetTokenFloat("weaponlength",&fWeaponLength))
|
||||
fWeaponLength = 0.0f;
|
||||
|
||||
mapHitPosition.clear();
|
||||
|
||||
CTokenVector * tv;
|
||||
if (rTextFileLoader.GetTokenVector("hitposition",&tv))
|
||||
{
|
||||
CTokenVector::iterator it=tv->begin();
|
||||
|
||||
while(it!=tv->end())
|
||||
{
|
||||
float time;
|
||||
NRaceData::THitTimePosition hp;
|
||||
time = atof(it++->c_str());
|
||||
hp.v3LastPosition.x = atof(it++->c_str());
|
||||
hp.v3LastPosition.y = atof(it++->c_str());
|
||||
hp.v3LastPosition.z = atof(it++->c_str());
|
||||
hp.v3Position.x = atof(it++->c_str());
|
||||
hp.v3Position.y = atof(it++->c_str());
|
||||
hp.v3Position.z = atof(it++->c_str());
|
||||
|
||||
mapHitPosition[time] = hp;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL NRaceData::LoadMotionAttackData(CTextFileLoader & rTextFileLoader, TMotionAttackData * pData)
|
||||
{
|
||||
if (!LoadAttackData(rTextFileLoader, pData))
|
||||
return FALSE;
|
||||
|
||||
// NOTE : 기존의 AttackingType이 MotionType으로 바뀌었음
|
||||
// 기존 데이타의 경우 없으면 기존 것으로 읽게끔..
|
||||
if (!rTextFileLoader.GetTokenInteger("motiontype", &pData->iMotionType))
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenInteger("attackingtype", &pData->iMotionType))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pData->HitDataContainer.clear();
|
||||
|
||||
DWORD dwHitDataCount;
|
||||
if (!rTextFileLoader.GetTokenDoubleWord("hitdatacount", &dwHitDataCount))
|
||||
{
|
||||
pData->HitDataContainer.push_back(SHitData());
|
||||
THitData & rHitData = *(pData->HitDataContainer.rbegin());
|
||||
if (!rHitData.Load(rTextFileLoader))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (DWORD i = 0; i < dwHitDataCount; ++i)
|
||||
{
|
||||
if (!rTextFileLoader.SetChildNode(i))
|
||||
return FALSE;
|
||||
|
||||
pData->HitDataContainer.push_back(SHitData());
|
||||
THitData & rHitData = *(pData->HitDataContainer.rbegin());
|
||||
if (!rHitData.Load(rTextFileLoader))
|
||||
return FALSE;
|
||||
|
||||
rTextFileLoader.SetParentNode();
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL NRaceData::LoadCollisionData(CTextFileLoader & rTextFileLoader, TCollisionData * pCollisionData)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenInteger("collisiontype", &pCollisionData->iCollisionType))
|
||||
return false;
|
||||
|
||||
DWORD dwSphereDataCount;
|
||||
if (!rTextFileLoader.GetTokenDoubleWord("spheredatacount", &dwSphereDataCount))
|
||||
return false;
|
||||
|
||||
pCollisionData->SphereDataVector.clear();
|
||||
pCollisionData->SphereDataVector.resize(dwSphereDataCount);
|
||||
for (DWORD i = 0; i < dwSphereDataCount; ++i)
|
||||
{
|
||||
TSphereData & r = pCollisionData->SphereDataVector[i].GetAttribute();
|
||||
|
||||
if (!rTextFileLoader.SetChildNode("spheredata", i))
|
||||
return false;
|
||||
|
||||
if (!rTextFileLoader.GetTokenFloat("radius", &r.fRadius))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenPosition("position", &r.v3Position))
|
||||
return false;
|
||||
|
||||
rTextFileLoader.SetParentNode();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NRaceData::SaveEffectData(FILE * File, int iTabCount, const TAttachingEffectData & c_rEffectData)
|
||||
{
|
||||
PrintfTabs(File, iTabCount, "EffectScriptName \"%s\"\n", c_rEffectData.strFileName.c_str());
|
||||
|
||||
PrintfTabs(File, iTabCount, "EffectPosition %f %f %f\n", c_rEffectData.v3Position.x, c_rEffectData.v3Position.y, c_rEffectData.v3Position.z);
|
||||
PrintfTabs(File, iTabCount, "EffectRotation %f %f %f\n", c_rEffectData.v3Rotation.x, c_rEffectData.v3Rotation.y, c_rEffectData.v3Rotation.z);
|
||||
}
|
||||
|
||||
void NRaceData::SaveObjectData(FILE * File, int iTabCount, const TAttachingObjectData & c_rObjectData)
|
||||
{
|
||||
PrintfTabs(File, iTabCount, "ObjectScriptName \"%s\"\n", c_rObjectData.strFileName.c_str());
|
||||
}
|
||||
|
||||
BOOL NRaceData::LoadEffectData(CTextFileLoader & rTextFileLoader, TAttachingEffectData * pEffectData)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenString("effectscriptname",&pEffectData->strFileName))
|
||||
return false;
|
||||
|
||||
if (!rTextFileLoader.GetTokenPosition("effectposition",&pEffectData->v3Position))
|
||||
{
|
||||
pEffectData->v3Position = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
}
|
||||
|
||||
if (!rTextFileLoader.GetTokenPosition("effectrotation",&pEffectData->v3Rotation))
|
||||
{
|
||||
//pEffectData->qRotation = D3DXQUATERNION(0.0f,0.0f,0.0f,1.0f);
|
||||
pEffectData->v3Rotation = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
}
|
||||
|
||||
/*if (!*/
|
||||
// TODO DELETEME FIXME
|
||||
CEffectManager::Instance().RegisterEffect(pEffectData->strFileName.c_str());
|
||||
/*) return false;*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL NRaceData::LoadObjectData(CTextFileLoader & rTextFileLoader, TAttachingObjectData * pObjectData)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenString("objectscriptname",&pObjectData->strFileName))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NRaceData::SaveAttackData(FILE * File, int iTabCount, const TAttackData & c_rData)
|
||||
{
|
||||
PrintfTabs(File, iTabCount, "AttackType %d\n", c_rData.iAttackType);
|
||||
PrintfTabs(File, iTabCount, "HittingType %d\n", c_rData.iHittingType);
|
||||
PrintfTabs(File, iTabCount, "StiffenTime %f\n", c_rData.fStiffenTime);
|
||||
PrintfTabs(File, iTabCount, "InvisibleTime %f\n", c_rData.fInvisibleTime);
|
||||
PrintfTabs(File, iTabCount, "ExternalForce %f\n", c_rData.fExternalForce);
|
||||
PrintfTabs(File, iTabCount, "HitLimitCount %d\n", c_rData.iHitLimitCount);
|
||||
}
|
||||
|
||||
void NRaceData::SaveMotionAttackData(FILE * File, int iTabCount, const TMotionAttackData & c_rData)
|
||||
{
|
||||
SaveAttackData(File, iTabCount, c_rData);
|
||||
|
||||
PrintfTabs(File, iTabCount, "\n");
|
||||
PrintfTabs(File, iTabCount, "MotionType %d\n", c_rData.iMotionType);
|
||||
PrintfTabs(File, iTabCount, "HitDataCount %d\n", c_rData.HitDataContainer.size());
|
||||
|
||||
DWORD dwHitDataNumber = 0;
|
||||
THitDataContainer::const_iterator itor = c_rData.HitDataContainer.begin();
|
||||
for (; itor != c_rData.HitDataContainer.end(); ++itor, ++dwHitDataNumber)
|
||||
{
|
||||
const THitData & c_rHitData = *itor;
|
||||
|
||||
PrintfTabs(File, iTabCount, "Group HitData%02d\n", dwHitDataNumber);
|
||||
PrintfTabs(File, iTabCount, "{\n");
|
||||
PrintfTabs(File, iTabCount+1, "AttackingStartTime %f\n", c_rHitData.fAttackStartTime);
|
||||
PrintfTabs(File, iTabCount+1, "AttackingEndTime %f\n", c_rHitData.fAttackEndTime);
|
||||
|
||||
PrintfTabs(File, iTabCount+1, "AttackingBone \"%s\"\n", c_rHitData.strBoneName.c_str());
|
||||
PrintfTabs(File, iTabCount+1, "WeaponLength %f\n", c_rHitData.fWeaponLength);
|
||||
PrintfTabs(File, iTabCount+1, "List HitPosition\n");
|
||||
PrintfTabs(File, iTabCount+1, "{\n");
|
||||
|
||||
NRaceData::THitTimePositionMap::const_iterator it;
|
||||
for(it = c_rHitData.mapHitPosition.begin(); it!= c_rHitData.mapHitPosition.end();++it)
|
||||
{
|
||||
PrintfTabs(File, iTabCount+2, "%f %f %f %f %f %f %f\n", it->first,
|
||||
it->second.v3LastPosition.x, it->second.v3LastPosition.y, it->second.v3LastPosition.z,
|
||||
it->second.v3Position.x, it->second.v3Position.y, it->second.v3Position.z);
|
||||
}
|
||||
PrintfTabs(File, iTabCount+1, "}\n");
|
||||
PrintfTabs(File, iTabCount, "}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void NRaceData::SaveCollisionData(FILE * File, int iTabCount, const TCollisionData & c_rCollisionData)
|
||||
{
|
||||
PrintfTabs(File, iTabCount, "CollisionType %d\n", c_rCollisionData.iCollisionType);
|
||||
PrintfTabs(File, iTabCount, "\n");
|
||||
|
||||
const CSphereCollisionInstanceVector & c_rSphereDataVector = c_rCollisionData.SphereDataVector;
|
||||
|
||||
PrintfTabs(File, iTabCount, "SphereDataCount %d\n", c_rSphereDataVector.size());
|
||||
|
||||
for (DWORD i = 0; i < c_rSphereDataVector.size(); ++i)
|
||||
{
|
||||
const TSphereData & c_rAttr = c_rSphereDataVector[i].GetAttribute();
|
||||
|
||||
PrintfTabs(File, iTabCount, "Group SphereData%02d\n", i);
|
||||
|
||||
PrintfTabs(File, iTabCount, "{\n");
|
||||
|
||||
PrintfTabs(File, iTabCount+1, "Radius %f\n",
|
||||
c_rAttr.fRadius);
|
||||
|
||||
PrintfTabs(File, iTabCount+1, "Position %f %f %f\n",
|
||||
c_rAttr.v3Position.x,
|
||||
c_rAttr.v3Position.y,
|
||||
c_rAttr.v3Position.z);
|
||||
|
||||
PrintfTabs(File, iTabCount, "}\n");
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Attaching Data
|
||||
void NRaceData::SaveAttachingData(FILE * File, int iTabCount, const TAttachingDataVector & c_rAttachingDataVector)
|
||||
{
|
||||
DWORD dwAttachingDataCount = c_rAttachingDataVector.size();
|
||||
|
||||
PrintfTabs(File, iTabCount, "AttachingDataCount %d\n", dwAttachingDataCount);
|
||||
PrintfTabs(File, iTabCount, "\n");
|
||||
|
||||
for (DWORD i = 0; i < dwAttachingDataCount; ++i)
|
||||
{
|
||||
const NRaceData::TAttachingData & c_rAttachingData = c_rAttachingDataVector[i];
|
||||
|
||||
PrintfTabs(File, iTabCount, "Group AttachingData%02d\n", i);
|
||||
PrintfTabs(File, iTabCount, "{\n", i);
|
||||
|
||||
PrintfTabs(File, iTabCount+1, "AttachingDataType %d\n", c_rAttachingData.dwType);
|
||||
PrintfTabs(File, iTabCount+1, "\n", i);
|
||||
|
||||
PrintfTabs(File, iTabCount+1, "isAttaching %d\n", c_rAttachingData.isAttaching);
|
||||
PrintfTabs(File, iTabCount+1, "AttachingModelIndex %d\n", c_rAttachingData.dwAttachingModelIndex);
|
||||
PrintfTabs(File, iTabCount+1, "AttachingBoneName \"%s\"\n", c_rAttachingData.strAttachingBoneName.c_str());
|
||||
PrintfTabs(File, iTabCount+1, "\n");
|
||||
|
||||
switch (c_rAttachingData.dwType)
|
||||
{
|
||||
case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA:
|
||||
NRaceData::SaveCollisionData(File, iTabCount+1, *c_rAttachingData.pCollisionData);
|
||||
break;
|
||||
case NRaceData::ATTACHING_DATA_TYPE_EFFECT:
|
||||
NRaceData::SaveEffectData(File, iTabCount+1, *c_rAttachingData.pEffectData);
|
||||
break;
|
||||
case NRaceData::ATTACHING_DATA_TYPE_OBJECT:
|
||||
NRaceData::SaveObjectData(File, iTabCount+1, *c_rAttachingData.pObjectData);
|
||||
break;
|
||||
}
|
||||
|
||||
PrintfTabs(File, iTabCount, "}\n");
|
||||
|
||||
if (i != dwAttachingDataCount-1)
|
||||
PrintfTabs(File, iTabCount, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
BOOL NRaceData::LoadAttachingData(CTextFileLoader & rTextFileLoader, TAttachingDataVector * pAttachingDataVector)
|
||||
{
|
||||
DWORD dwDataCount;
|
||||
if (!rTextFileLoader.GetTokenDoubleWord("attachingdatacount", &dwDataCount))
|
||||
return false;
|
||||
|
||||
pAttachingDataVector->clear();
|
||||
pAttachingDataVector->resize(dwDataCount);
|
||||
|
||||
for (DWORD i = 0; i < dwDataCount; ++i)
|
||||
{
|
||||
NRaceData::TAttachingData & rAttachingData = pAttachingDataVector->at(i);
|
||||
if (!rTextFileLoader.SetChildNode("attachingdata", i))
|
||||
return false;
|
||||
|
||||
if (!rTextFileLoader.GetTokenDoubleWord("attachingdatatype", &rAttachingData.dwType))
|
||||
return false;
|
||||
|
||||
if (!rTextFileLoader.GetTokenInteger("isattaching", &rAttachingData.isAttaching))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenDoubleWord("attachingmodelindex", &rAttachingData.dwAttachingModelIndex))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenString("attachingbonename", &rAttachingData.strAttachingBoneName))
|
||||
return false;
|
||||
|
||||
switch (rAttachingData.dwType)
|
||||
{
|
||||
case NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA:
|
||||
rAttachingData.pCollisionData = g_CollisionDataPool.Alloc();
|
||||
if (!NRaceData::LoadCollisionData(rTextFileLoader, rAttachingData.pCollisionData))
|
||||
return false;
|
||||
break;
|
||||
case NRaceData::ATTACHING_DATA_TYPE_EFFECT:
|
||||
rAttachingData.pEffectData = g_EffectDataPool.Alloc();
|
||||
if (!NRaceData::LoadEffectData(rTextFileLoader, rAttachingData.pEffectData))
|
||||
return false;
|
||||
break;
|
||||
case NRaceData::ATTACHING_DATA_TYPE_OBJECT:
|
||||
rAttachingData.pObjectData = g_ObjectDataPool.Alloc();
|
||||
if (!NRaceData::LoadObjectData(rTextFileLoader, rAttachingData.pObjectData))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
rTextFileLoader.SetParentNode();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../eterLib/TextFileLoader.h"
|
||||
#include "../eterLib/CollisionData.h"
|
||||
|
||||
extern float g_fGameFPS;
|
||||
|
||||
extern std::string g_strResourcePath;
|
||||
extern std::string g_strImagePath;
|
||||
|
||||
// Motion Key
|
||||
#define MOTION_KEY DWORD
|
||||
#define MAKE_MOTION_KEY(mode, index) (((DWORD)(((BYTE)(mode)) << 24) | ((DWORD)((WORD)(index))) << 8) | ((DWORD)((BYTE)(0))))
|
||||
#define MAKE_RANDOM_MOTION_KEY(mode, index, type) (((DWORD)(((BYTE)(mode)) << 24) | ((DWORD)((WORD)(index))) << 8) | ((DWORD)((BYTE)(type))))
|
||||
#define GET_MOTION_MODE(key) ((BYTE)(((DWORD)(key) >> 24) & 0xFF))
|
||||
#define GET_MOTION_INDEX(key) ((WORD)(((DWORD)(key) >> 8) & 0xFFFF))
|
||||
#define GET_MOTION_SUB_INDEX(key) ((BYTE)(((DWORD)(key)) & 0xFF))
|
||||
/*
|
||||
#define MAKE_MOTION_KEY(mode, index) MAKELONG(index, mode)
|
||||
#define GET_MOTION_MODE(key) HIWORD(key)
|
||||
#define GET_MOTION_INDEX(key) LOWORD(key)
|
||||
*/
|
||||
|
||||
// Race Data
|
||||
namespace NRaceData
|
||||
{
|
||||
enum EJobs
|
||||
{
|
||||
JOB_WARRIOR,
|
||||
JOB_ASSASSIN,
|
||||
JOB_SURA,
|
||||
JOB_SHAMAN,
|
||||
JOB_MAX_NUM
|
||||
};
|
||||
|
||||
// Character Attacking Data
|
||||
enum EAttackType
|
||||
{
|
||||
ATTACK_TYPE_SPLASH,
|
||||
ATTACK_TYPE_SNIPE,
|
||||
};
|
||||
enum EHitType
|
||||
{
|
||||
HIT_TYPE_NONE,
|
||||
HIT_TYPE_GREAT,
|
||||
HIT_TYPE_GOOD,
|
||||
};
|
||||
enum EMotionType
|
||||
{
|
||||
MOTION_TYPE_NONE,
|
||||
MOTION_TYPE_NORMAL,
|
||||
MOTION_TYPE_COMBO,
|
||||
MOTION_TYPE_SKILL,
|
||||
};
|
||||
|
||||
typedef CDynamicSphereInstance THitTimePosition;
|
||||
typedef std::map<float, THitTimePosition> THitTimePositionMap;
|
||||
|
||||
typedef struct SAttackData
|
||||
{
|
||||
int iAttackType;
|
||||
int iHittingType;
|
||||
float fInvisibleTime;
|
||||
float fExternalForce;
|
||||
float fStiffenTime;
|
||||
int iHitLimitCount;
|
||||
} TAttackData;
|
||||
|
||||
typedef struct SHitData
|
||||
{
|
||||
float fAttackStartTime;
|
||||
float fAttackEndTime;
|
||||
|
||||
float fWeaponLength;
|
||||
std::string strBoneName;
|
||||
|
||||
THitTimePositionMap mapHitPosition;
|
||||
|
||||
bool Load(CTextFileLoader & rTextFileLoader);
|
||||
} THitData;
|
||||
|
||||
typedef std::vector<THitData> THitDataContainer;
|
||||
|
||||
typedef struct SMotionAttackData : public SAttackData
|
||||
{
|
||||
int iMotionType;
|
||||
|
||||
THitDataContainer HitDataContainer;
|
||||
} TMotionAttackData;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Character Attaching Collision Data
|
||||
enum ECollisionType
|
||||
{
|
||||
COLLISION_TYPE_NONE,
|
||||
|
||||
COLLISION_TYPE_BODY,
|
||||
COLLISION_TYPE_ATTACKING,
|
||||
COLLISION_TYPE_DEFENDING,
|
||||
COLLISION_TYPE_SPLASH,
|
||||
};
|
||||
enum ECollisionShape
|
||||
{
|
||||
COLLISION_SHAPE_SPHERE,
|
||||
COLLISION_SHAPE_CYLINDER,
|
||||
};
|
||||
|
||||
typedef struct SCollisionData
|
||||
{
|
||||
int iCollisionType;
|
||||
CSphereCollisionInstanceVector SphereDataVector;
|
||||
|
||||
SCollisionData() {}
|
||||
virtual ~SCollisionData() {}
|
||||
} TCollisionData;
|
||||
|
||||
typedef struct SAttachingEffectData
|
||||
{
|
||||
std::string strFileName;
|
||||
D3DXVECTOR3 v3Position;
|
||||
D3DXVECTOR3 v3Rotation;
|
||||
|
||||
SAttachingEffectData() {}
|
||||
virtual ~SAttachingEffectData() {}
|
||||
} TAttachingEffectData;
|
||||
|
||||
typedef struct SAttachingObjectData
|
||||
{
|
||||
std::string strFileName;
|
||||
|
||||
SAttachingObjectData() {}
|
||||
virtual ~SAttachingObjectData() {}
|
||||
} TAttachingObjectData;
|
||||
|
||||
typedef std::vector<TCollisionData> TCollisionDataVector;
|
||||
|
||||
void DestroySystem();
|
||||
|
||||
void SaveAttackData(FILE * File, int iTabCount, const TAttackData & c_rData);
|
||||
void SaveMotionAttackData(FILE * File, int iTabCount, const TMotionAttackData & c_rData);
|
||||
void SaveCollisionData(FILE * File, int iTabCount, const TCollisionData & c_rCollisionData);
|
||||
void SaveEffectData(FILE * File, int iTabCount, const TAttachingEffectData & c_rEffectData);
|
||||
void SaveObjectData(FILE * File, int iTabCount, const TAttachingObjectData & c_rObjectData);
|
||||
|
||||
BOOL LoadAttackData(CTextFileLoader & rTextFileLoader, TAttackData * pData);
|
||||
BOOL LoadMotionAttackData(CTextFileLoader & rTextFileLoader, TMotionAttackData * pData);
|
||||
BOOL LoadCollisionData(CTextFileLoader & rTextFileLoader, TCollisionData * pCollisionData);
|
||||
BOOL LoadEffectData(CTextFileLoader & rTextFileLoader, TAttachingEffectData * pEffectData);
|
||||
BOOL LoadObjectData(CTextFileLoader & rTextFileLoader, TAttachingObjectData * pObjectData);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Attaching Data
|
||||
enum EAttachingDataType
|
||||
{
|
||||
ATTACHING_DATA_TYPE_NONE,
|
||||
|
||||
ATTACHING_DATA_TYPE_COLLISION_DATA,
|
||||
ATTACHING_DATA_TYPE_EFFECT,
|
||||
ATTACHING_DATA_TYPE_OBJECT,
|
||||
|
||||
ATTACHING_DATA_TYPE_MAX_NUM,
|
||||
};
|
||||
|
||||
typedef struct SAttachingData
|
||||
{
|
||||
SAttachingData()
|
||||
: dwType(0)
|
||||
, isAttaching(false)
|
||||
, dwAttachingModelIndex(0)
|
||||
, pCollisionData(NULL)
|
||||
, pEffectData(NULL)
|
||||
, pObjectData(NULL)
|
||||
{}
|
||||
DWORD dwType;
|
||||
|
||||
BOOL isAttaching;
|
||||
DWORD dwAttachingModelIndex;
|
||||
std::string strAttachingBoneName;
|
||||
|
||||
TCollisionData * pCollisionData;
|
||||
TAttachingEffectData * pEffectData;
|
||||
TAttachingObjectData * pObjectData;
|
||||
} TAttachingData;
|
||||
|
||||
typedef std::vector<TAttachingData> TAttachingDataVector;
|
||||
|
||||
void SaveAttachingData(FILE * File, int iTabCount, const TAttachingDataVector & c_rAttachingDataVector);
|
||||
BOOL LoadAttachingData(CTextFileLoader & rTextFileLoader, TAttachingDataVector * pAttachingDataVector);
|
||||
|
||||
extern CDynamicPool<TCollisionData> g_CollisionDataPool;
|
||||
extern CDynamicPool<TAttachingEffectData> g_EffectDataPool;
|
||||
extern CDynamicPool<TAttachingObjectData> g_ObjectDataPool;
|
||||
};
|
||||
@@ -0,0 +1,434 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/lineintersect_utils.h"
|
||||
|
||||
#include "GameUtil.h"
|
||||
|
||||
bool DetectCollisionDynamicZCylinderVSDynamicZCylinder(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2)
|
||||
{
|
||||
CDynamicSphereInstance c_rCylinder1=c_rSphere1;
|
||||
CDynamicSphereInstance c_rCylinder2=c_rSphere2;
|
||||
|
||||
c_rCylinder1.v3Position.z=0;
|
||||
c_rCylinder1.v3LastPosition.z=0;
|
||||
|
||||
c_rCylinder2.v3Position.z=0;
|
||||
c_rCylinder2.v3LastPosition.z=0;
|
||||
|
||||
float r = c_rCylinder1.fRadius+c_rCylinder2.fRadius;
|
||||
float rsq = r*r;
|
||||
|
||||
// AABB check
|
||||
D3DXVECTOR3 mi1=c_rCylinder1.v3LastPosition, mi2 = c_rCylinder1.v3Position;
|
||||
D3DXVECTOR3 mi3=c_rCylinder2.v3LastPosition, mi4 = c_rCylinder2.v3Position;
|
||||
if (mi1.x>mi2.x) std::swap(mi1.x,mi2.x);
|
||||
if (mi1.y>mi2.y) std::swap(mi1.y,mi2.y);
|
||||
if (mi1.z>mi2.z) std::swap(mi1.z,mi2.z);
|
||||
if (mi3.x>mi4.x) std::swap(mi3.x,mi4.x);
|
||||
if (mi3.y>mi4.y) std::swap(mi3.y,mi4.y);
|
||||
if (mi3.z>mi4.z) std::swap(mi3.z,mi4.z);
|
||||
mi1.x -= c_rCylinder1.fRadius; mi1.y -= c_rCylinder1.fRadius; mi1.z -= c_rCylinder1.fRadius;
|
||||
mi2.x += c_rCylinder1.fRadius; mi2.y += c_rCylinder1.fRadius; mi2.z += c_rCylinder1.fRadius;
|
||||
mi3.x -= c_rCylinder2.fRadius; mi3.y -= c_rCylinder2.fRadius; mi3.z -= c_rCylinder2.fRadius;
|
||||
mi4.x += c_rCylinder2.fRadius; mi4.y += c_rCylinder2.fRadius; mi4.z += c_rCylinder2.fRadius;
|
||||
if (mi4.x<mi1.x || mi2.x<mi3.x) return false;
|
||||
if (mi4.y<mi1.y || mi2.y<mi3.y) return false;
|
||||
if (mi4.z<mi1.z || mi2.z<mi3.z) return false;
|
||||
|
||||
D3DXVECTOR3 vA, vB;
|
||||
IntersectLineSegments(c_rCylinder1.v3LastPosition, c_rCylinder1.v3Position,
|
||||
c_rCylinder2.v3LastPosition, c_rCylinder2.v3Position,
|
||||
vA, vB);
|
||||
const auto vv = (vA - vB);
|
||||
return (D3DXVec3LengthSq(&vv)<=rsq);
|
||||
}
|
||||
|
||||
bool DetectCollisionDynamicSphereVSDynamicSphere(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2)
|
||||
{
|
||||
float r = c_rSphere1.fRadius+c_rSphere2.fRadius;
|
||||
float rsq = r*r;
|
||||
|
||||
/*if (D3DXVec3LengthSq(&(c_rSphere1.v3Position -c_rSphere2.v3Position ))<=rsq) return true;
|
||||
if (D3DXVec3LengthSq(&(c_rSphere1.v3Position -c_rSphere2.v3LastPosition ))<=rsq) return true;
|
||||
if (D3DXVec3LengthSq(&(c_rSphere1.v3LastPosition -c_rSphere2.v3Position ))<=rsq) return true;
|
||||
if (D3DXVec3LengthSq(&(c_rSphere1.v3LastPosition -c_rSphere2.v3LastPosition ))<=rsq) return true;*/
|
||||
|
||||
/*
|
||||
if (square_distance_between_linesegment_and_point(
|
||||
c_rSphere1.v3Position,
|
||||
c_rSphere1.v3LastPosition,
|
||||
c_rSphere2.v3Position
|
||||
)<=rsq) return true;
|
||||
if (square_distance_between_linesegment_and_point(
|
||||
c_rSphere1.v3Position,
|
||||
c_rSphere1.v3LastPosition,
|
||||
c_rSphere2.v3LastPosition
|
||||
)<=rsq) return true;
|
||||
if (square_distance_between_linesegment_and_point(
|
||||
c_rSphere2.v3Position,
|
||||
c_rSphere2.v3LastPosition,
|
||||
c_rSphere1.v3Position
|
||||
)<=rsq) return true;
|
||||
if (square_distance_between_linesegment_and_point(
|
||||
c_rSphere2.v3Position,
|
||||
c_rSphere2.v3LastPosition,
|
||||
c_rSphere1.v3LastPosition
|
||||
)<=rsq) return true;
|
||||
|
||||
D3DXVECTOR3 da=c_rSphere1.v3Position-c_rSphere1.v3LastPosition;
|
||||
D3DXVECTOR3 db=c_rSphere2.v3Position-c_rSphere2.v3LastPosition;
|
||||
D3DXVECTOR3 n;
|
||||
float la = D3DXVec3Length(&da);
|
||||
float lb = D3DXVec3Length(&db);
|
||||
if (la==0||lb==0)
|
||||
{
|
||||
D3DXVECTOR3 vA, vB;
|
||||
IntersectLineSegments(
|
||||
c_rSphere1.v3LastPosition.x,c_rSphere1.v3LastPosition.y,c_rSphere1.v3LastPosition.z,
|
||||
c_rSphere1.v3Position.x, c_rSphere1.v3Position.y, c_rSphere1.v3Position.z,
|
||||
c_rSphere2.v3LastPosition.x,c_rSphere2.v3LastPosition.y,c_rSphere2.v3LastPosition.z,
|
||||
c_rSphere2.v3Position.x, c_rSphere2.v3Position.y, c_rSphere2.v3Position.z,
|
||||
false, 1.e-5f, vA.x, vA.y, vA.z, vB.x, vB.y, vB.z);
|
||||
return (D3DXVec3LengthSq(&(vA-vB))<=r*r);
|
||||
}
|
||||
D3DXVECTOR3 p=c_rSphere2.v3Position - c_rSphere1.v3LastPosition;
|
||||
D3DXVec3Cross(&n, &da, &db);
|
||||
float from_plane = D3DXVec3Dot(&n,&p)/la/lb;
|
||||
if (from_plane>r || from_plane<-r)
|
||||
return false;
|
||||
p-=(from_plane/la/lb)*n;
|
||||
float ta = D3DXVec3Dot(&p,&da)/la/la;
|
||||
float tb = D3DXVec3Dot(&p,&db)/lb/lb;
|
||||
|
||||
// FIXME 구 체크가 아니다
|
||||
|
||||
if (ta<0)
|
||||
return false;
|
||||
if (tb<0)
|
||||
return false;
|
||||
if (ta>1)
|
||||
return false;
|
||||
if (tb>1)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
*/
|
||||
//*/
|
||||
// using gpg line-collision
|
||||
|
||||
// AABB check
|
||||
|
||||
D3DXVECTOR3 mi1=c_rSphere1.v3LastPosition, mi2 = c_rSphere1.v3Position;
|
||||
D3DXVECTOR3 mi3=c_rSphere2.v3LastPosition, mi4 = c_rSphere2.v3Position;
|
||||
if (mi1.x>mi2.x) std::swap(mi1.x,mi2.x);
|
||||
if (mi1.y>mi2.y) std::swap(mi1.y,mi2.y);
|
||||
if (mi1.z>mi2.z) std::swap(mi1.z,mi2.z);
|
||||
if (mi3.x>mi4.x) std::swap(mi3.x,mi4.x);
|
||||
if (mi3.y>mi4.y) std::swap(mi3.y,mi4.y);
|
||||
if (mi3.z>mi4.z) std::swap(mi3.z,mi4.z);
|
||||
mi1.x -= c_rSphere1.fRadius; mi1.y -= c_rSphere1.fRadius; mi1.z -= c_rSphere1.fRadius;
|
||||
mi2.x += c_rSphere1.fRadius; mi2.y += c_rSphere1.fRadius; mi2.z += c_rSphere1.fRadius;
|
||||
mi3.x -= c_rSphere2.fRadius; mi3.y -= c_rSphere2.fRadius; mi3.z -= c_rSphere2.fRadius;
|
||||
mi4.x += c_rSphere2.fRadius; mi4.y += c_rSphere2.fRadius; mi4.z += c_rSphere2.fRadius;
|
||||
if (mi4.x<mi1.x || mi2.x<mi3.x) return false;
|
||||
if (mi4.y<mi1.y || mi2.y<mi3.y) return false;
|
||||
if (mi4.z<mi1.z || mi2.z<mi3.z) return false;
|
||||
|
||||
D3DXVECTOR3 vA, vB;/*
|
||||
IntersectLineSegments(
|
||||
c_rSphere1.v3LastPosition.x,c_rSphere1.v3LastPosition.y,c_rSphere1.v3LastPosition.z,
|
||||
c_rSphere1.v3Position.x, c_rSphere1.v3Position.y, c_rSphere1.v3Position.z,
|
||||
c_rSphere2.v3LastPosition.x,c_rSphere2.v3LastPosition.y,c_rSphere2.v3LastPosition.z,
|
||||
c_rSphere2.v3Position.x, c_rSphere2.v3Position.y, c_rSphere2.v3Position.z,
|
||||
false, 1.e-1f, vA.x, vA.y, vA.z, vB.x, vB.y, vB.z);*/
|
||||
IntersectLineSegments(c_rSphere1.v3LastPosition, c_rSphere1.v3Position,
|
||||
c_rSphere2.v3LastPosition, c_rSphere2.v3Position,
|
||||
vA, vB);
|
||||
const auto vvv = (vA - vB);
|
||||
return (D3DXVec3LengthSq(&vvv)<=rsq);
|
||||
//*/
|
||||
|
||||
/*
|
||||
// NOTE : AABB 체크 할 것
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
D3DXVECTOR3 v3Distance = c_rSphere1.v3Position - c_rSphere2.v3Position;
|
||||
float fDistance = D3DXVec3Length(&v3Distance);
|
||||
float fRadiusSummary = c_rSphere1.fRadius + c_rSphere2.fRadius;
|
||||
|
||||
if (fDistance < fRadiusSummary)
|
||||
return true;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
D3DXVECTOR3 v3LastDistance = c_rSphere1.v3LastPosition - c_rSphere2.v3LastPosition; // A
|
||||
D3DXVECTOR3 v3Advance = c_rSphere1.v3Advance - c_rSphere2.v3Advance; // B
|
||||
|
||||
float fdotAdvanceAdvance = D3DXVec3Dot(&v3Advance, &v3Advance);
|
||||
if (0.0f == fdotAdvanceAdvance)
|
||||
return false;
|
||||
|
||||
float fdotDistanceAdvance = D3DXVec3Dot(&v3LastDistance, &v3Advance);
|
||||
float fdotDistanceDistance = D3DXVec3Dot(&v3LastDistance, &v3LastDistance);
|
||||
float Value1 = fdotDistanceAdvance - fdotAdvanceAdvance * (fdotDistanceDistance - (fRadiusSummary * fRadiusSummary));
|
||||
if (Value1 < 0.0f)
|
||||
return false;
|
||||
|
||||
float Value2 = (-fdotDistanceAdvance - sqrtf(Value1)) / fdotAdvanceAdvance;
|
||||
if (Value2 < 0.0f)
|
||||
return false;
|
||||
if (Value2 >= 1.0f)
|
||||
return false;
|
||||
|
||||
return true;*/
|
||||
}
|
||||
|
||||
/*
|
||||
// Dynamic VS Static
|
||||
bool DetectCollisionDynamicSphereVSStaticPlane(const CDynamicSphereInstance & c_rSphere, const TPlaneData & c_rPlane)
|
||||
{
|
||||
D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position;
|
||||
D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position;
|
||||
|
||||
float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition);
|
||||
float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition);
|
||||
|
||||
if (fPosition1 >0.0f && fPosition2 < 0.0f || fPosition1 <0.0f && fPosition2 >0.0f || (fPosition1) <= c_rSphere.fRadius && fPosition1 >= -c_rSphere.fRadius)
|
||||
{
|
||||
D3DXVECTOR3 v3QuadPosition1 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[0];
|
||||
D3DXVECTOR3 v3QuadPosition2 = c_rSphere.v3Position - c_rPlane.v3QuadPosition[3];
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < c_rSphere.fRadius)
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < c_rSphere.fRadius)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < c_rSphere.fRadius)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < c_rSphere.fRadius)
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DetectCollisionDynamicSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere, const TSphereData & c_rSphereData)
|
||||
{
|
||||
D3DXVECTOR3 v3Distance = c_rSphere.v3Position - c_rSphereData.v3Position;
|
||||
float fDistanceSq = D3DXVec3LengthSq(&v3Distance);
|
||||
float fRadiusSummary = c_rSphere.fRadius + c_rSphereData.fRadius;
|
||||
if (fDistanceSq < fRadiusSummary*fRadiusSummary)
|
||||
return true;
|
||||
|
||||
//D3DXVECTOR3 v3LastDistance = c_rSphere.v3LastPosition - c_rSphereData.v3Position;
|
||||
//if (D3DXVec3Dot(&v3LastDistance, &v3Distance) < 0.0f)
|
||||
// return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DetectCollisionDynamicSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinderData)
|
||||
{
|
||||
if (c_rSphere.v3Position.z + c_rSphere.fRadius < c_rCylinderData.v3Position.z)
|
||||
return false;
|
||||
|
||||
if (c_rSphere.v3Position.z - c_rSphere.fRadius > c_rCylinderData.v3Position.z + c_rCylinderData.fHeight)
|
||||
return false;
|
||||
|
||||
D3DXVECTOR3 v3curDistance = c_rSphere.v3Position - c_rCylinderData.v3Position;
|
||||
float fDistance = D3DXVec3Length(&v3curDistance);
|
||||
|
||||
if (fDistance <= c_rSphere.fRadius + c_rCylinderData.fRadius)
|
||||
return true;
|
||||
|
||||
//D3DXVECTOR3 v3lastDistance = c_rSphere.v3LastPosition - c_rCylinderData.v3Position;
|
||||
|
||||
//if (D3DXVec3Dot(&v3curDistance, &v3lastDistance) < 0.0f)
|
||||
// return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
bool DetectCollisionDynamicSphereVSStaticBox(const TSphereInstance & c_rSphere, const TBoxData & c_rBoxData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
// Static VS Static
|
||||
/*
|
||||
bool DetectCollisionStaticSphereVSStaticSphere(const TSphereData & c_rSphere1, const TSphereData & c_rSphere2)
|
||||
{
|
||||
D3DXVECTOR3 v3Distance = c_rSphere1.v3Position - c_rSphere2.v3Position;
|
||||
float fDistance = D3DXVec3Length(&v3Distance);
|
||||
|
||||
if (fDistance < c_rSphere1.fRadius + c_rSphere2.fRadius)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DetectCollisionStaticSphereVSStaticCylinder(const TSphereData & c_rSphere, const TCylinderData & c_rCylinder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
/*bool DetectCollisionStaticSphereVSStaticBox(const TSphereData & c_rSphere, const TBoxData & c_rBox)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IsCWAcuteAngle(float begin, float end)
|
||||
{
|
||||
// 360 - src + dest // 시계 반대 방향
|
||||
// src - dest // 시계 방향
|
||||
return ((360.0f - begin + end) > (begin - end));
|
||||
}
|
||||
|
||||
bool IsCCWAcuteAngle(float begin, float end)
|
||||
{
|
||||
// abs(360 - dest + src) // 시계 방향
|
||||
// dest - src // 시계 반대 방향
|
||||
int fValue = abs((int) (360.0f - end + begin));
|
||||
return fValue >= (end - begin) ? true : false;
|
||||
}
|
||||
|
||||
bool IsCWRotation(float begin, float end)
|
||||
{
|
||||
return !IsCCWRotation(begin, end);
|
||||
}
|
||||
|
||||
bool IsCCWRotation(float begin, float end)
|
||||
{
|
||||
// 180
|
||||
// 270 90
|
||||
// 0
|
||||
//
|
||||
// 시계 반대
|
||||
return (begin - end < 0);
|
||||
}
|
||||
|
||||
float GetInterpolatedRotation(float begin, float end, float curRate)
|
||||
{
|
||||
if (IsCCWRotation(begin, end))
|
||||
{
|
||||
if (IsCCWAcuteAngle(begin, end))
|
||||
return GetLinearInterpolation(begin, end, curRate);
|
||||
|
||||
return (360.0f + GetLinearInterpolation(begin, end - 360.0f, curRate));
|
||||
}
|
||||
|
||||
if (IsCWAcuteAngle(begin, end))
|
||||
return GetLinearInterpolation(begin, end, curRate);
|
||||
|
||||
return GetLinearInterpolation(begin, end + 360.0f, curRate);
|
||||
}
|
||||
|
||||
float GetDegreeFromPosition(float x, float y)
|
||||
{
|
||||
D3DXVECTOR3 vtDir(floor(x), floor(y), 0.0f);
|
||||
D3DXVec3Normalize(&vtDir, &vtDir);
|
||||
|
||||
D3DXVECTOR3 vtStan(0, -1, 0);
|
||||
float ret = D3DXToDegree(acosf(D3DXVec3Dot(&vtDir, &vtStan)));
|
||||
|
||||
if (vtDir.x < 0.0f)
|
||||
ret = 360.0f - ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
float GetDegreeFromPosition2(float sx, float sy, float ex, float ey)
|
||||
{
|
||||
return GetDegreeFromPosition(ex - sx, ey - sy);
|
||||
}
|
||||
|
||||
float GetDegreeDifference(float fSource, float fTarget)
|
||||
{
|
||||
if (fSource < 180.0f)
|
||||
{
|
||||
if (fTarget < fSource)
|
||||
return fSource - fTarget;
|
||||
|
||||
else if(fTarget - fSource > 180.0f)
|
||||
return (360.0f - (fTarget - fSource));
|
||||
|
||||
return fTarget - fSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fTarget > fSource)
|
||||
return fTarget - fSource;
|
||||
|
||||
else if (fSource - fTarget > 180.0f)
|
||||
{
|
||||
return (360.0f - (fSource - fTarget));
|
||||
}
|
||||
|
||||
return fSource - fTarget;
|
||||
}
|
||||
}
|
||||
int GetRotatingDirection(float fSource, float fTarget)
|
||||
{
|
||||
if (fSource < 180.0f)
|
||||
{
|
||||
if (fTarget < fSource)
|
||||
return DEGREE_DIRECTION_RIGHT;
|
||||
|
||||
else if((360.0f - fTarget) + fSource < 180.0f)
|
||||
return DEGREE_DIRECTION_RIGHT;
|
||||
|
||||
return DEGREE_DIRECTION_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fTarget > fSource)
|
||||
{
|
||||
return DEGREE_DIRECTION_LEFT;
|
||||
}
|
||||
else if ((360.0f - fSource) + fTarget < 180.0f)
|
||||
{
|
||||
return DEGREE_DIRECTION_LEFT;
|
||||
}
|
||||
|
||||
return DEGREE_DIRECTION_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
float CameraRotationToCharacterRotation(float fCameraRotation)
|
||||
{
|
||||
return fmod((540.0f - fCameraRotation), 360.0f);
|
||||
}
|
||||
|
||||
float CharacterRotationToCameraRotation(float fCharacterRotation)
|
||||
{
|
||||
return fmod((540.0f - fCharacterRotation), 360.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
bool DetectCollisionDynamicSphereVSStaticPlane(const TSphereInstance & c_rSphere, const TPlaneData & c_rPlane)
|
||||
{
|
||||
D3DXVECTOR3 v3SpherePosition = c_rSphere.v3Position - c_rPlane.v3Position;
|
||||
D3DXVECTOR3 v3SphereLastPosition = c_rSphere.v3LastPosition - c_rPlane.v3Position;
|
||||
|
||||
float fPosition1 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SpherePosition);
|
||||
float fPosition2 = D3DXVec3Dot(&c_rPlane.v3Normal, &v3SphereLastPosition);
|
||||
|
||||
if (fPosition1 * fPosition2 < 0.0f || fabs(fPosition1) <= c_rSphere.fRadius)
|
||||
{
|
||||
float fT = -fPosition1 / D3DXVec3Dot(&c_rPlane.v3Normal, &c_rSphere.v3Advance);
|
||||
D3DXVECTOR3 v3CollisionPosition = c_rSphere.v3LastPosition + c_rSphere.v3Advance * fT;
|
||||
D3DXVECTOR3 v3QuadPosition1 = v3CollisionPosition - c_rPlane.v3BeginPosition;
|
||||
D3DXVECTOR3 v3QuadPosition2 = v3CollisionPosition - c_rPlane.v3EndPosition;
|
||||
D3DXVec3Normalize(&v3QuadPosition1, &v3QuadPosition1);
|
||||
D3DXVec3Normalize(&v3QuadPosition2, &v3QuadPosition2);
|
||||
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[0]) < 0.0f)
|
||||
if (D3DXVec3Dot(&v3QuadPosition1, &c_rPlane.v3InsideVector[1]) < 0.0f)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[2]) < 0.0f)
|
||||
if (D3DXVec3Dot(&v3QuadPosition2, &c_rPlane.v3InsideVector[3]) < 0.0f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
// Collision Detection
|
||||
// Dynamic VS Dynamic
|
||||
bool DetectCollisionDynamicSphereVSDynamicSphere(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2);
|
||||
bool DetectCollisionDynamicZCylinderVSDynamicZCylinder(const CDynamicSphereInstance & c_rSphere1, const CDynamicSphereInstance & c_rSphere2);
|
||||
// Dynamic VS Static
|
||||
//bool DetectCollisionDynamicSphereVSStaticPlane(const CDynamicSphereInstance & c_rSphere, const TPlaneData & c_rPlaneData);
|
||||
//bool DetectCollisionDynamicSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere, const TSphereData & c_rSphereData);
|
||||
//bool DetectCollisionDynamicSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinderData);
|
||||
//bool DetectCollisionDynamicSphereVSStaticBox(const TSphereInstance & c_rSphere, const TBoxData & c_rBoxData);
|
||||
// Static VS Static
|
||||
//bool DetectCollisionStaticSphereVSStaticSphere(const CDynamicSphereInstance & c_rSphere1, const TSphereData & c_rSphere2);
|
||||
//bool DetectCollisionStaticSphereVSStaticCylinder(const CDynamicSphereInstance & c_rSphere, const TCylinderData & c_rCylinder);
|
||||
//bool DetectCollisionStaticSphereVSStaticBox(const TSphereData & c_rSphere, const TBoxData & c_rBox);
|
||||
|
||||
// Rotation
|
||||
float GetDegreeFromPosition(float x, float y);
|
||||
float GetDegreeFromPosition2(float sx, float sy, float ex, float ey);
|
||||
|
||||
float GetInterpolatedRotation(float begin, float end, float curRate);
|
||||
bool IsSameDirectionRotation();
|
||||
bool IsCWRotation(float begin, float end);
|
||||
bool IsCCWRotation(float begin, float end);
|
||||
|
||||
bool IsCWAcuteAngle(float begin, float end);
|
||||
bool IsCCWAcuteAngle(float begin, float end);
|
||||
|
||||
// NOTE - Finally, this code is same with upper rotating direction code.
|
||||
enum EDegree_Direction
|
||||
{
|
||||
DEGREE_DIRECTION_SAME = 0,
|
||||
DEGREE_DIRECTION_RIGHT = 1,
|
||||
DEGREE_DIRECTION_LEFT = 2,
|
||||
};
|
||||
float GetDegreeDifference(float fSource, float fTarget);
|
||||
int GetRotatingDirection(float fSource, float fTarget);
|
||||
|
||||
// Converting Rotation
|
||||
float CameraRotationToCharacterRotation(float fCameraRotation);
|
||||
float CharacterRotationToCameraRotation(float fCharacterRotation);
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// 2004.07.05.myevan.궁신탄영 맵에 끼이는 문제해결
|
||||
class IBackground : public CSingleton<IBackground>
|
||||
{
|
||||
public:
|
||||
IBackground() {}
|
||||
virtual ~IBackground() {}
|
||||
|
||||
virtual bool IsBlock(int x, int y) = 0;
|
||||
};
|
||||
@@ -0,0 +1,464 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
|
||||
#include "ItemData.h"
|
||||
|
||||
CDynamicPool<CItemData> CItemData::ms_kPool;
|
||||
|
||||
extern DWORD GetDefaultCodePage();
|
||||
|
||||
CItemData* CItemData::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CItemData::Delete(CItemData* pkItemData)
|
||||
{
|
||||
pkItemData->Clear();
|
||||
ms_kPool.Free(pkItemData);
|
||||
}
|
||||
|
||||
void CItemData::DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
}
|
||||
|
||||
CGraphicThing * CItemData::GetModelThing()
|
||||
{
|
||||
return m_pModelThing;
|
||||
}
|
||||
|
||||
CGraphicThing * CItemData::GetSubModelThing()
|
||||
{
|
||||
if (m_pSubModelThing)
|
||||
return m_pSubModelThing;
|
||||
else
|
||||
return m_pModelThing;
|
||||
}
|
||||
|
||||
CGraphicThing * CItemData::GetDropModelThing()
|
||||
{
|
||||
return m_pDropModelThing;
|
||||
}
|
||||
|
||||
CGraphicSubImage * CItemData::GetIconImage()
|
||||
{
|
||||
if(m_pIconImage == NULL && m_strIconFileName.empty() == false)
|
||||
__SetIconImage(m_strIconFileName.c_str());
|
||||
return m_pIconImage;
|
||||
}
|
||||
|
||||
DWORD CItemData::GetLODModelThingCount()
|
||||
{
|
||||
return m_pLODModelThingVector.size();
|
||||
}
|
||||
|
||||
BOOL CItemData::GetLODModelThingPointer(DWORD dwIndex, CGraphicThing ** ppModelThing)
|
||||
{
|
||||
if (dwIndex >= m_pLODModelThingVector.size())
|
||||
return FALSE;
|
||||
|
||||
*ppModelThing = m_pLODModelThingVector[dwIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD CItemData::GetAttachingDataCount()
|
||||
{
|
||||
return m_AttachingDataVector.size();
|
||||
}
|
||||
|
||||
BOOL CItemData::GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData)
|
||||
{
|
||||
if (dwIndex >= GetAttachingDataCount())
|
||||
return FALSE;
|
||||
|
||||
if (NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA != m_AttachingDataVector[dwIndex].dwType)
|
||||
return FALSE;
|
||||
|
||||
*c_ppAttachingData = &m_AttachingDataVector[dwIndex];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CItemData::GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData)
|
||||
{
|
||||
if (dwIndex >= GetAttachingDataCount())
|
||||
return FALSE;
|
||||
|
||||
*c_ppAttachingData = &m_AttachingDataVector[dwIndex];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CItemData::SetSummary(const std::string& c_rstSumm)
|
||||
{
|
||||
m_strSummary=c_rstSumm;
|
||||
}
|
||||
|
||||
void CItemData::SetDescription(const std::string& c_rstDesc)
|
||||
{
|
||||
m_strDescription=c_rstDesc;
|
||||
}
|
||||
/*
|
||||
BOOL CItemData::LoadItemData(const char * c_szFileName)
|
||||
{
|
||||
CTextFileLoader TextFileLoader;
|
||||
|
||||
if (!TextFileLoader.Load(c_szFileName))
|
||||
{
|
||||
//Lognf(1, "CItemData::LoadItemData(c_szFileName=%s) - FAILED", c_szFileName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TextFileLoader.SetTop();
|
||||
|
||||
TextFileLoader.GetTokenString("modelfilename", &m_strModelFileName);
|
||||
TextFileLoader.GetTokenString("submodelfilename", &m_strSubModelFileName);
|
||||
TextFileLoader.GetTokenString("dropmodelfilename", &m_strDropModelFileName);
|
||||
TextFileLoader.GetTokenString("iconimagefilename", &m_strIconFileName);
|
||||
|
||||
char szDescriptionKey[32+1];
|
||||
_snprintf(szDescriptionKey, 32, "%ddescription", GetDefaultCodePage());
|
||||
if (!TextFileLoader.GetTokenString(szDescriptionKey, &m_strDescription))
|
||||
{
|
||||
TextFileLoader.GetTokenString("description", &m_strDescription);
|
||||
}
|
||||
|
||||
// LOD Model File Name List
|
||||
CTokenVector * pLODModelList;
|
||||
if (TextFileLoader.GetTokenVector("lodmodellist", &pLODModelList))
|
||||
{
|
||||
m_strLODModelFileNameVector.clear();
|
||||
m_strLODModelFileNameVector.resize(pLODModelList->size());
|
||||
|
||||
for (DWORD i = 0; i < pLODModelList->size(); ++i)
|
||||
{
|
||||
m_strLODModelFileNameVector[i] = pLODModelList->at(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Attaching Data
|
||||
// Item 에 Attaching Data 일단 없음.
|
||||
// if (TextFileLoader.SetChildNode("attachingdata"))
|
||||
// {
|
||||
// if (!NRaceData::LoadAttachingData(TextFileLoader, &m_AttachingDataVector))
|
||||
// return FALSE;
|
||||
//
|
||||
// TextFileLoader.SetParentNode();
|
||||
// }
|
||||
|
||||
__LoadFiles();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
void CItemData::SetDefaultItemData(const char * c_szIconFileName, const char * c_szModelFileName)
|
||||
{
|
||||
if(c_szModelFileName)
|
||||
{
|
||||
m_strModelFileName = c_szModelFileName;
|
||||
m_strDropModelFileName = c_szModelFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_strModelFileName = "";
|
||||
m_strDropModelFileName = "d:/ymir work/item/etc/item_bag.gr2";
|
||||
}
|
||||
m_strIconFileName = c_szIconFileName;
|
||||
|
||||
m_strSubModelFileName = "";
|
||||
m_strDescription = "";
|
||||
m_strSummary = "";
|
||||
memset(m_ItemTable.alSockets, 0, sizeof(m_ItemTable.alSockets));
|
||||
|
||||
__LoadFiles();
|
||||
}
|
||||
|
||||
void CItemData::__LoadFiles()
|
||||
{
|
||||
// Model File Name
|
||||
if (!m_strModelFileName.empty())
|
||||
m_pModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strModelFileName.c_str());
|
||||
|
||||
if (!m_strSubModelFileName.empty())
|
||||
m_pSubModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strSubModelFileName.c_str());
|
||||
|
||||
if (!m_strDropModelFileName.empty())
|
||||
m_pDropModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strDropModelFileName.c_str());
|
||||
|
||||
|
||||
if (!m_strLODModelFileNameVector.empty())
|
||||
{
|
||||
m_pLODModelThingVector.clear();
|
||||
m_pLODModelThingVector.resize(m_strLODModelFileNameVector.size());
|
||||
|
||||
for (DWORD i = 0; i < m_strLODModelFileNameVector.size(); ++i)
|
||||
{
|
||||
const std::string & c_rstrLODModelFileName = m_strLODModelFileNameVector[i];
|
||||
m_pLODModelThingVector[i] = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_rstrLODModelFileName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CItemData::__SetIconImage(const char * c_szFileName)
|
||||
{
|
||||
if (!CResourceManager::Instance().IsFileExist(c_szFileName))
|
||||
{
|
||||
TraceError("%s 파일이 없습니다.CItemData::__SetIconImage",c_szFileName);
|
||||
m_pIconImage = NULL;
|
||||
}
|
||||
else if (m_pIconImage == NULL)
|
||||
m_pIconImage = (CGraphicSubImage *)CResourceManager::Instance().GetResourcePointer(c_szFileName);
|
||||
}
|
||||
|
||||
void CItemData::SetItemTableData(TItemTable * pItemTable)
|
||||
{
|
||||
memcpy(&m_ItemTable, pItemTable, sizeof(TItemTable));
|
||||
}
|
||||
|
||||
const CItemData::TItemTable* CItemData::GetTable() const
|
||||
{
|
||||
return &m_ItemTable;
|
||||
}
|
||||
|
||||
DWORD CItemData::GetIndex() const
|
||||
{
|
||||
return m_ItemTable.dwVnum;
|
||||
}
|
||||
|
||||
const char * CItemData::GetName() const
|
||||
{
|
||||
return m_ItemTable.szLocaleName;
|
||||
}
|
||||
|
||||
const char * CItemData::GetDescription() const
|
||||
{
|
||||
return m_strDescription.c_str();
|
||||
}
|
||||
|
||||
const char * CItemData::GetSummary() const
|
||||
{
|
||||
return m_strSummary.c_str();
|
||||
}
|
||||
|
||||
|
||||
BYTE CItemData::GetType() const
|
||||
{
|
||||
return m_ItemTable.bType;
|
||||
}
|
||||
|
||||
BYTE CItemData::GetSubType() const
|
||||
{
|
||||
return m_ItemTable.bSubType;
|
||||
}
|
||||
|
||||
#define DEF_STR(x) #x
|
||||
|
||||
const char* CItemData::GetUseTypeString() const
|
||||
{
|
||||
if (GetType() != CItemData::ITEM_TYPE_USE)
|
||||
return "NOT_USE_TYPE";
|
||||
|
||||
switch (GetSubType())
|
||||
{
|
||||
case USE_TUNING:
|
||||
return DEF_STR(USE_TUNING);
|
||||
case USE_DETACHMENT:
|
||||
return DEF_STR(USE_DETACHMENT);
|
||||
case USE_CLEAN_SOCKET:
|
||||
return DEF_STR(USE_CLEAN_SOCKET);
|
||||
case USE_CHANGE_ATTRIBUTE:
|
||||
return DEF_STR(USE_CHANGE_ATTRIBUTE);
|
||||
case USE_ADD_ATTRIBUTE:
|
||||
return DEF_STR(USE_ADD_ATTRIBUTE);
|
||||
case USE_ADD_ATTRIBUTE2:
|
||||
return DEF_STR(USE_ADD_ATTRIBUTE2);
|
||||
case USE_ADD_ACCESSORY_SOCKET:
|
||||
return DEF_STR(USE_ADD_ACCESSORY_SOCKET);
|
||||
case USE_PUT_INTO_ACCESSORY_SOCKET:
|
||||
return DEF_STR(USE_PUT_INTO_ACCESSORY_SOCKET);
|
||||
case USE_PUT_INTO_BELT_SOCKET:
|
||||
return DEF_STR(USE_PUT_INTO_BELT_SOCKET);
|
||||
case USE_PUT_INTO_RING_SOCKET:
|
||||
return DEF_STR(USE_PUT_INTO_RING_SOCKET);
|
||||
}
|
||||
return "USE_UNKNOWN_TYPE";
|
||||
}
|
||||
|
||||
|
||||
DWORD CItemData::GetWeaponType() const
|
||||
{
|
||||
return m_ItemTable.bSubType;
|
||||
}
|
||||
|
||||
BYTE CItemData::GetSize() const
|
||||
{
|
||||
return m_ItemTable.bSize;
|
||||
}
|
||||
|
||||
BOOL CItemData::IsAntiFlag(DWORD dwFlag) const
|
||||
{
|
||||
return (dwFlag & m_ItemTable.dwAntiFlags) != 0;
|
||||
}
|
||||
|
||||
BOOL CItemData::IsFlag(DWORD dwFlag) const
|
||||
{
|
||||
return (dwFlag & m_ItemTable.dwFlags) != 0;
|
||||
}
|
||||
|
||||
BOOL CItemData::IsWearableFlag(DWORD dwFlag) const
|
||||
{
|
||||
return (dwFlag & m_ItemTable.dwWearFlags) != 0;
|
||||
}
|
||||
|
||||
BOOL CItemData::HasNextGrade() const
|
||||
{
|
||||
return 0 != m_ItemTable.dwRefinedVnum;
|
||||
}
|
||||
|
||||
DWORD CItemData::GetWearFlags() const
|
||||
{
|
||||
return m_ItemTable.dwWearFlags;
|
||||
}
|
||||
|
||||
DWORD CItemData::GetIBuyItemPrice() const
|
||||
{
|
||||
return m_ItemTable.dwIBuyItemPrice;
|
||||
}
|
||||
|
||||
DWORD CItemData::GetISellItemPrice() const
|
||||
{
|
||||
return m_ItemTable.dwISellItemPrice;
|
||||
}
|
||||
|
||||
|
||||
BOOL CItemData::GetLimit(BYTE byIndex, TItemLimit * pItemLimit) const
|
||||
{
|
||||
if (byIndex >= ITEM_LIMIT_MAX_NUM)
|
||||
{
|
||||
assert(byIndex < ITEM_LIMIT_MAX_NUM);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pItemLimit = m_ItemTable.aLimits[byIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CItemData::GetApply(BYTE byIndex, TItemApply * pItemApply) const
|
||||
{
|
||||
if (byIndex >= ITEM_APPLY_MAX_NUM)
|
||||
{
|
||||
assert(byIndex < ITEM_APPLY_MAX_NUM);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pItemApply = m_ItemTable.aApplies[byIndex];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
long CItemData::GetValue(BYTE byIndex) const
|
||||
{
|
||||
if (byIndex >= ITEM_VALUES_MAX_NUM)
|
||||
{
|
||||
assert(byIndex < ITEM_VALUES_MAX_NUM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_ItemTable.alValues[byIndex];
|
||||
}
|
||||
|
||||
long CItemData::SetSocket(BYTE byIndex,DWORD value)
|
||||
{
|
||||
if (byIndex >= ITEM_SOCKET_MAX_NUM)
|
||||
{
|
||||
assert(byIndex < ITEM_SOCKET_MAX_NUM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return m_ItemTable.alSockets[byIndex] = value;
|
||||
}
|
||||
|
||||
long CItemData::GetSocket(BYTE byIndex) const
|
||||
{
|
||||
if (byIndex >= ITEM_SOCKET_MAX_NUM)
|
||||
{
|
||||
assert(byIndex < ITEM_SOCKET_MAX_NUM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return m_ItemTable.alSockets[byIndex];
|
||||
}
|
||||
|
||||
//서버와 동일 서버 함수 변경시 같이 변경!!(이후에 합친다)
|
||||
//SocketCount = 1 이면 초급무기
|
||||
//SocketCount = 2 이면 중급무기
|
||||
//SocketCount = 3 이면 고급무기
|
||||
int CItemData::GetSocketCount() const
|
||||
{
|
||||
return m_ItemTable.bGainSocketPct;
|
||||
}
|
||||
|
||||
DWORD CItemData::GetIconNumber() const
|
||||
{
|
||||
return m_ItemTable.dwVnum;
|
||||
//!@#
|
||||
// return m_ItemTable.dwIconNumber;
|
||||
}
|
||||
|
||||
UINT CItemData::GetSpecularPoweru() const
|
||||
{
|
||||
return m_ItemTable.bSpecular;
|
||||
}
|
||||
|
||||
float CItemData::GetSpecularPowerf() const
|
||||
{
|
||||
UINT uSpecularPower=GetSpecularPoweru();
|
||||
|
||||
return float(uSpecularPower) / 100.0f;
|
||||
}
|
||||
|
||||
//refine 값은 아이템번호 끝자리와 일치한다-_-(테이블이용으로 바꿀 예정)
|
||||
UINT CItemData::GetRefine() const
|
||||
{
|
||||
return GetIndex()%10;
|
||||
}
|
||||
|
||||
BOOL CItemData::IsEquipment() const
|
||||
{
|
||||
switch (GetType())
|
||||
{
|
||||
case ITEM_TYPE_WEAPON:
|
||||
case ITEM_TYPE_ARMOR:
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CItemData::Clear()
|
||||
{
|
||||
m_strSummary = "";
|
||||
m_strModelFileName = "";
|
||||
m_strSubModelFileName = "";
|
||||
m_strDropModelFileName = "";
|
||||
m_strIconFileName = "";
|
||||
m_strLODModelFileNameVector.clear();
|
||||
|
||||
m_pModelThing = NULL;
|
||||
m_pSubModelThing = NULL;
|
||||
m_pDropModelThing = NULL;
|
||||
m_pIconImage = NULL;
|
||||
m_pLODModelThingVector.clear();
|
||||
|
||||
memset(&m_ItemTable, 0, sizeof(m_ItemTable));
|
||||
}
|
||||
|
||||
CItemData::CItemData()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CItemData::~CItemData()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
#pragma once
|
||||
|
||||
// NOTE : Item의 통합 관리 클래스다.
|
||||
// Icon, Model (droped on ground), Game Data
|
||||
|
||||
#include "../eterLib/GrpSubImage.h"
|
||||
#include "../eterGrnLib/Thing.h"
|
||||
|
||||
class CItemData
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ITEM_NAME_MAX_LEN = 24,
|
||||
ITEM_LIMIT_MAX_NUM = 2,
|
||||
ITEM_VALUES_MAX_NUM = 6,
|
||||
ITEM_SMALL_DESCR_MAX_LEN = 256,
|
||||
ITEM_APPLY_MAX_NUM = 3,
|
||||
ITEM_SOCKET_MAX_NUM = 3,
|
||||
};
|
||||
|
||||
enum EItemType
|
||||
{
|
||||
ITEM_TYPE_NONE, //0
|
||||
ITEM_TYPE_WEAPON, //1//무기
|
||||
ITEM_TYPE_ARMOR, //2//갑옷
|
||||
ITEM_TYPE_USE, //3//아이템 사용
|
||||
ITEM_TYPE_AUTOUSE, //4
|
||||
ITEM_TYPE_MATERIAL, //5
|
||||
ITEM_TYPE_SPECIAL, //6 //스페셜 아이템
|
||||
ITEM_TYPE_TOOL, //7
|
||||
ITEM_TYPE_LOTTERY, //8//복권
|
||||
ITEM_TYPE_ELK, //9//돈
|
||||
ITEM_TYPE_METIN, //10
|
||||
ITEM_TYPE_CONTAINER, //11
|
||||
ITEM_TYPE_FISH, //12//낚시
|
||||
ITEM_TYPE_ROD, //13
|
||||
ITEM_TYPE_RESOURCE, //14
|
||||
ITEM_TYPE_CAMPFIRE, //15
|
||||
ITEM_TYPE_UNIQUE, //16
|
||||
ITEM_TYPE_SKILLBOOK, //17
|
||||
ITEM_TYPE_QUEST, //18
|
||||
ITEM_TYPE_POLYMORPH, //19
|
||||
ITEM_TYPE_TREASURE_BOX, //20//보물상자
|
||||
ITEM_TYPE_TREASURE_KEY, //21//보물상자 열쇠
|
||||
ITEM_TYPE_SKILLFORGET, //22
|
||||
ITEM_TYPE_GIFTBOX, //23
|
||||
ITEM_TYPE_PICK, //24
|
||||
ITEM_TYPE_HAIR, //25//머리
|
||||
ITEM_TYPE_TOTEM, //26//토템
|
||||
ITEM_TYPE_BLEND, //27//생성될때 랜덤하게 속성이 붙는 약물
|
||||
ITEM_TYPE_COSTUME, //28//코스츔 아이템 (2011년 8월 추가된 코스츔 시스템용 아이템)
|
||||
ITEM_TYPE_DS, //29 //용혼석
|
||||
ITEM_TYPE_SPECIAL_DS, //30 // 특수한 용혼석 (DS_SLOT에 착용하는 UNIQUE 아이템이라 생각하면 됨)
|
||||
ITEM_TYPE_EXTRACT, //31 추출도구.
|
||||
ITEM_TYPE_SECONDARY_COIN, //32 명도전.
|
||||
ITEM_TYPE_RING, //33 반지 (유니크 슬롯이 아닌 순수 반지 슬롯)
|
||||
ITEM_TYPE_BELT, //34 벨트
|
||||
|
||||
ITEM_TYPE_MAX_NUM,
|
||||
};
|
||||
|
||||
enum EWeaponSubTypes
|
||||
{
|
||||
WEAPON_SWORD,
|
||||
WEAPON_DAGGER, //이도류
|
||||
WEAPON_BOW,
|
||||
WEAPON_TWO_HANDED,
|
||||
WEAPON_BELL,
|
||||
WEAPON_FAN,
|
||||
WEAPON_ARROW,
|
||||
WEAPON_NUM_TYPES,
|
||||
|
||||
WEAPON_NONE = WEAPON_NUM_TYPES+1,
|
||||
};
|
||||
|
||||
enum EMaterialSubTypes
|
||||
{
|
||||
MATERIAL_LEATHER,
|
||||
MATERIAL_BLOOD,
|
||||
MATERIAL_ROOT,
|
||||
MATERIAL_NEEDLE,
|
||||
MATERIAL_JEWEL,
|
||||
MATERIAL_DS_REFINE_NORMAL,
|
||||
MATERIAL_DS_REFINE_BLESSED,
|
||||
MATERIAL_DS_REFINE_HOLLY,
|
||||
};
|
||||
|
||||
enum EArmorSubTypes
|
||||
{
|
||||
ARMOR_BODY,
|
||||
ARMOR_HEAD,
|
||||
ARMOR_SHIELD,
|
||||
ARMOR_WRIST,
|
||||
ARMOR_FOOTS,
|
||||
ARMOR_NECK,
|
||||
ARMOR_EAR,
|
||||
ARMOR_NUM_TYPES
|
||||
};
|
||||
|
||||
enum ECostumeSubTypes
|
||||
{
|
||||
COSTUME_BODY, //0 갑옷(main look)
|
||||
COSTUME_HAIR, //1 헤어(탈착가능)
|
||||
COSTUME_NUM_TYPES,
|
||||
};
|
||||
|
||||
enum EUseSubTypes
|
||||
{
|
||||
USE_POTION, // 0
|
||||
USE_TALISMAN,
|
||||
USE_TUNING,
|
||||
USE_MOVE,
|
||||
USE_TREASURE_BOX,
|
||||
USE_MONEYBAG,
|
||||
USE_BAIT,
|
||||
USE_ABILITY_UP,
|
||||
USE_AFFECT,
|
||||
USE_CREATE_STONE,
|
||||
USE_SPECIAL, // 10
|
||||
USE_POTION_NODELAY,
|
||||
USE_CLEAR,
|
||||
USE_INVISIBILITY,
|
||||
USE_DETACHMENT,
|
||||
USE_BUCKET,
|
||||
USE_POTION_CONTINUE,
|
||||
USE_CLEAN_SOCKET,
|
||||
USE_CHANGE_ATTRIBUTE,
|
||||
USE_ADD_ATTRIBUTE,
|
||||
USE_ADD_ACCESSORY_SOCKET, // 20
|
||||
USE_PUT_INTO_ACCESSORY_SOCKET,
|
||||
USE_ADD_ATTRIBUTE2,
|
||||
USE_RECIPE,
|
||||
USE_CHANGE_ATTRIBUTE2,
|
||||
USE_BIND,
|
||||
USE_UNBIND,
|
||||
USE_TIME_CHARGE_PER,
|
||||
USE_TIME_CHARGE_FIX, // 28
|
||||
USE_PUT_INTO_BELT_SOCKET, // 29 벨트 소켓에 사용할 수 있는 아이템
|
||||
USE_PUT_INTO_RING_SOCKET, // 30 반지 소켓에 사용할 수 있는 아이템 (유니크 반지 말고, 새로 추가된 반지 슬롯)
|
||||
};
|
||||
|
||||
enum EDragonSoulSubType
|
||||
{
|
||||
DS_SLOT1,
|
||||
DS_SLOT2,
|
||||
DS_SLOT3,
|
||||
DS_SLOT4,
|
||||
DS_SLOT5,
|
||||
DS_SLOT6,
|
||||
DS_SLOT_NUM_TYPES = 6,
|
||||
};
|
||||
|
||||
enum EMetinSubTypes
|
||||
{
|
||||
METIN_NORMAL,
|
||||
METIN_GOLD,
|
||||
};
|
||||
|
||||
enum ELimitTypes
|
||||
{
|
||||
LIMIT_NONE,
|
||||
|
||||
LIMIT_LEVEL,
|
||||
LIMIT_STR,
|
||||
LIMIT_DEX,
|
||||
LIMIT_INT,
|
||||
LIMIT_CON,
|
||||
LIMIT_PCBANG,
|
||||
|
||||
/// 착용 여부와 상관 없이 실시간으로 시간 차감 (socket0에 소멸 시간이 박힘: unix_timestamp 타입)
|
||||
LIMIT_REAL_TIME,
|
||||
|
||||
/// 아이템을 맨 처음 사용(혹은 착용) 한 순간부터 리얼타임 타이머 시작
|
||||
/// 최초 사용 전에는 socket0에 사용가능시간(초단위, 0이면 프로토의 limit value값 사용) 값이 쓰여있다가
|
||||
/// 아이템 사용시 socket1에 사용 횟수가 박히고 socket0에 unix_timestamp 타입의 소멸시간이 박힘.
|
||||
LIMIT_REAL_TIME_START_FIRST_USE,
|
||||
|
||||
/// 아이템을 착용 중일 때만 사용 시간이 차감되는 아이템
|
||||
/// socket0에 남은 시간이 초단위로 박힘. (아이템 최초 사용시 해당 값이 0이면 프로토의 limit value값을 socket0에 복사)
|
||||
LIMIT_TIMER_BASED_ON_WEAR,
|
||||
|
||||
LIMIT_MAX_NUM
|
||||
};
|
||||
|
||||
enum EItemAntiFlag
|
||||
{
|
||||
ITEM_ANTIFLAG_FEMALE = (1 << 0), // 여성 사용 불가
|
||||
ITEM_ANTIFLAG_MALE = (1 << 1), // 남성 사용 불가
|
||||
ITEM_ANTIFLAG_WARRIOR = (1 << 2), // 무사 사용 불가
|
||||
ITEM_ANTIFLAG_ASSASSIN = (1 << 3), // 자객 사용 불가
|
||||
ITEM_ANTIFLAG_SURA = (1 << 4), // 수라 사용 불가
|
||||
ITEM_ANTIFLAG_SHAMAN = (1 << 5), // 무당 사용 불가
|
||||
ITEM_ANTIFLAG_GET = (1 << 6), // 집을 수 없음
|
||||
ITEM_ANTIFLAG_DROP = (1 << 7), // 버릴 수 없음
|
||||
ITEM_ANTIFLAG_SELL = (1 << 8), // 팔 수 없음
|
||||
ITEM_ANTIFLAG_EMPIRE_A = (1 << 9), // A 제국 사용 불가
|
||||
ITEM_ANTIFLAG_EMPIRE_B = (1 << 10), // B 제국 사용 불가
|
||||
ITEM_ANTIFLAG_EMPIRE_R = (1 << 11), // C 제국 사용 불가
|
||||
ITEM_ANTIFLAG_SAVE = (1 << 12), // 저장되지 않음
|
||||
ITEM_ANTIFLAG_GIVE = (1 << 13), // 거래 불가
|
||||
ITEM_ANTIFLAG_PKDROP = (1 << 14), // PK시 떨어지지 않음
|
||||
ITEM_ANTIFLAG_STACK = (1 << 15), // 합칠 수 없음
|
||||
ITEM_ANTIFLAG_MYSHOP = (1 << 16), // 개인 상점에 올릴 수 없음
|
||||
};
|
||||
|
||||
enum EItemFlag
|
||||
{
|
||||
ITEM_FLAG_REFINEABLE = (1 << 0), // 개량 가능
|
||||
ITEM_FLAG_SAVE = (1 << 1),
|
||||
ITEM_FLAG_STACKABLE = (1 << 2), // 여러개 합칠 수 있음
|
||||
ITEM_FLAG_COUNT_PER_1GOLD = (1 << 3), // 가격이 개수 / 가격으로 변함
|
||||
ITEM_FLAG_SLOW_QUERY = (1 << 4), // 게임 종료시에만 SQL에 쿼리함
|
||||
ITEM_FLAG_RARE = (1 << 5),
|
||||
ITEM_FLAG_UNIQUE = (1 << 6),
|
||||
ITEM_FLAG_MAKECOUNT = (1 << 7),
|
||||
ITEM_FLAG_IRREMOVABLE = (1 << 8),
|
||||
ITEM_FLAG_CONFIRM_WHEN_USE = (1 << 9),
|
||||
ITEM_FLAG_QUEST_USE = (1 << 10), // 퀘스트 스크립트 돌리는지?
|
||||
ITEM_FLAG_QUEST_USE_MULTIPLE= (1 << 11), // 퀘스트 스크립트 돌리는지?
|
||||
ITEM_FLAG_UNUSED03 = (1 << 12), // UNUSED03
|
||||
ITEM_FLAG_LOG = (1 << 13), // 사용시 로그를 남기는 아이템인가?
|
||||
ITEM_FLAG_APPLICABLE = (1 << 14),
|
||||
};
|
||||
|
||||
enum EWearPositions
|
||||
{
|
||||
WEAR_BODY, // 0
|
||||
WEAR_HEAD, // 1
|
||||
WEAR_FOOTS, // 2
|
||||
WEAR_WRIST, // 3
|
||||
WEAR_WEAPON, // 4
|
||||
WEAR_NECK, // 5
|
||||
WEAR_EAR, // 6
|
||||
WEAR_UNIQUE1, // 7
|
||||
WEAR_UNIQUE2, // 8
|
||||
WEAR_ARROW, // 9
|
||||
WEAR_SHIELD, // 10
|
||||
WEAR_MAX_NUM,
|
||||
};
|
||||
|
||||
enum EItemWearableFlag
|
||||
{
|
||||
WEARABLE_BODY = (1 << 0),
|
||||
WEARABLE_HEAD = (1 << 1),
|
||||
WEARABLE_FOOTS = (1 << 2),
|
||||
WEARABLE_WRIST = (1 << 3),
|
||||
WEARABLE_WEAPON = (1 << 4),
|
||||
WEARABLE_NECK = (1 << 5),
|
||||
WEARABLE_EAR = (1 << 6),
|
||||
WEARABLE_UNIQUE = (1 << 7),
|
||||
WEARABLE_SHIELD = (1 << 8),
|
||||
WEARABLE_ARROW = (1 << 9),
|
||||
};
|
||||
|
||||
enum EApplyTypes
|
||||
{
|
||||
APPLY_NONE, // 0
|
||||
APPLY_MAX_HP, // 1
|
||||
APPLY_MAX_SP, // 2
|
||||
APPLY_CON, // 3
|
||||
APPLY_INT, // 4
|
||||
APPLY_STR, // 5
|
||||
APPLY_DEX, // 6
|
||||
APPLY_ATT_SPEED, // 7
|
||||
APPLY_MOV_SPEED, // 8
|
||||
APPLY_CAST_SPEED, // 9
|
||||
APPLY_HP_REGEN, // 10
|
||||
APPLY_SP_REGEN, // 11
|
||||
APPLY_POISON_PCT, // 12
|
||||
APPLY_STUN_PCT, // 13
|
||||
APPLY_SLOW_PCT, // 14
|
||||
APPLY_CRITICAL_PCT, // 15
|
||||
APPLY_PENETRATE_PCT, // 16
|
||||
APPLY_ATTBONUS_HUMAN, // 17
|
||||
APPLY_ATTBONUS_ANIMAL, // 18
|
||||
APPLY_ATTBONUS_ORC, // 19
|
||||
APPLY_ATTBONUS_MILGYO, // 20
|
||||
APPLY_ATTBONUS_UNDEAD, // 21
|
||||
APPLY_ATTBONUS_DEVIL, // 22
|
||||
APPLY_STEAL_HP, // 23
|
||||
APPLY_STEAL_SP, // 24
|
||||
APPLY_MANA_BURN_PCT, // 25
|
||||
APPLY_DAMAGE_SP_RECOVER, // 26
|
||||
APPLY_BLOCK, // 27
|
||||
APPLY_DODGE, // 28
|
||||
APPLY_RESIST_SWORD, // 29
|
||||
APPLY_RESIST_TWOHAND, // 30
|
||||
APPLY_RESIST_DAGGER, // 31
|
||||
APPLY_RESIST_BELL, // 32
|
||||
APPLY_RESIST_FAN, // 33
|
||||
APPLY_RESIST_BOW, // 34
|
||||
APPLY_RESIST_FIRE, // 35
|
||||
APPLY_RESIST_ELEC, // 36
|
||||
APPLY_RESIST_MAGIC, // 37
|
||||
APPLY_RESIST_WIND, // 38
|
||||
APPLY_REFLECT_MELEE, // 39
|
||||
APPLY_REFLECT_CURSE, // 40
|
||||
APPLY_POISON_REDUCE, // 41
|
||||
APPLY_KILL_SP_RECOVER, // 42
|
||||
APPLY_EXP_DOUBLE_BONUS, // 43
|
||||
APPLY_GOLD_DOUBLE_BONUS, // 44
|
||||
APPLY_ITEM_DROP_BONUS, // 45
|
||||
APPLY_POTION_BONUS, // 46
|
||||
APPLY_KILL_HP_RECOVER, // 47
|
||||
APPLY_IMMUNE_STUN, // 48
|
||||
APPLY_IMMUNE_SLOW, // 49
|
||||
APPLY_IMMUNE_FALL, // 50
|
||||
APPLY_SKILL, // 51
|
||||
APPLY_BOW_DISTANCE, // 52
|
||||
APPLY_ATT_GRADE_BONUS, // 53
|
||||
APPLY_DEF_GRADE_BONUS, // 54
|
||||
APPLY_MAGIC_ATT_GRADE, // 55
|
||||
APPLY_MAGIC_DEF_GRADE, // 56
|
||||
APPLY_CURSE_PCT, // 57
|
||||
APPLY_MAX_STAMINA, // 58
|
||||
APPLY_ATT_BONUS_TO_WARRIOR, // 59
|
||||
APPLY_ATT_BONUS_TO_ASSASSIN,// 60
|
||||
APPLY_ATT_BONUS_TO_SURA, // 61
|
||||
APPLY_ATT_BONUS_TO_SHAMAN, // 62
|
||||
APPLY_ATT_BONUS_TO_MONSTER, // 63
|
||||
APPLY_MALL_ATTBONUS, // 64 공격력 +x%
|
||||
APPLY_MALL_DEFBONUS, // 65 방어력 +x%
|
||||
APPLY_MALL_EXPBONUS, // 66 경험치 +x%
|
||||
APPLY_MALL_ITEMBONUS, // 67 아이템 드롭율 x/10배
|
||||
APPLY_MALL_GOLDBONUS, // 68 돈 드롭율 x/10배
|
||||
APPLY_MAX_HP_PCT, // 69 최대 생명력 +x%
|
||||
APPLY_MAX_SP_PCT, // 70 최대 정신력 +x%
|
||||
APPLY_SKILL_DAMAGE_BONUS, // 71 스킬 데미지 * (100+x)%
|
||||
APPLY_NORMAL_HIT_DAMAGE_BONUS, // 72 평타 데미지 * (100+x)%
|
||||
APPLY_SKILL_DEFEND_BONUS, // 73 스킬 데미지 방어 * (100-x)%
|
||||
APPLY_NORMAL_HIT_DEFEND_BONUS, // 74 평타 데미지 방어 * (100-x)%
|
||||
APPLY_EXTRACT_HP_PCT, //75
|
||||
APPLY_PC_BANG_EXP_BONUS, //76
|
||||
APPLY_PC_BANG_DROP_BONUS, //77
|
||||
APPLY_RESIST_WARRIOR, //78
|
||||
APPLY_RESIST_ASSASSIN , //79
|
||||
APPLY_RESIST_SURA, //80
|
||||
APPLY_RESIST_SHAMAN, //81
|
||||
APPLY_ENERGY, //82
|
||||
APPLY_DEF_GRADE, // 83 방어력. DEF_GRADE_BONUS는 클라에서 두배로 보여지는 의도된 버그(...)가 있다.
|
||||
APPLY_COSTUME_ATTR_BONUS, // 84 코스튬 아이템에 붙은 속성치 보너스
|
||||
APPLY_MAGIC_ATTBONUS_PER, // 85 마법 공격력 +x%
|
||||
APPLY_MELEE_MAGIC_ATTBONUS_PER, // 86 마법 + 밀리 공격력 +x%
|
||||
|
||||
APPLY_RESIST_ICE, // 87 냉기 저항
|
||||
APPLY_RESIST_EARTH, // 88 대지 저항
|
||||
APPLY_RESIST_DARK, // 89 어둠 저항
|
||||
|
||||
APPLY_ANTI_CRITICAL_PCT, //90 크리티컬 저항
|
||||
APPLY_ANTI_PENETRATE_PCT, //91 관통타격 저항
|
||||
|
||||
MAX_APPLY_NUM, //
|
||||
};
|
||||
|
||||
enum EImmuneFlags
|
||||
{
|
||||
IMMUNE_PARA = (1 << 0),
|
||||
IMMUNE_CURSE = (1 << 1),
|
||||
IMMUNE_STUN = (1 << 2),
|
||||
IMMUNE_SLEEP = (1 << 3),
|
||||
IMMUNE_SLOW = (1 << 4),
|
||||
IMMUNE_POISON = (1 << 5),
|
||||
IMMUNE_TERROR = (1 << 6),
|
||||
};
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
typedef struct SItemLimit
|
||||
{
|
||||
BYTE bType;
|
||||
long lValue;
|
||||
} TItemLimit;
|
||||
|
||||
typedef struct SItemApply
|
||||
{
|
||||
BYTE bType;
|
||||
long lValue;
|
||||
} TItemApply;
|
||||
|
||||
typedef struct SItemTable
|
||||
{
|
||||
DWORD dwVnum;
|
||||
DWORD dwVnumRange;
|
||||
char szName[ITEM_NAME_MAX_LEN + 1];
|
||||
char szLocaleName[ITEM_NAME_MAX_LEN + 1];
|
||||
BYTE bType;
|
||||
BYTE bSubType;
|
||||
|
||||
BYTE bWeight;
|
||||
BYTE bSize;
|
||||
|
||||
DWORD dwAntiFlags;
|
||||
DWORD dwFlags;
|
||||
DWORD dwWearFlags;
|
||||
DWORD dwImmuneFlag;
|
||||
|
||||
DWORD dwIBuyItemPrice;
|
||||
DWORD dwISellItemPrice;
|
||||
|
||||
TItemLimit aLimits[ITEM_LIMIT_MAX_NUM];
|
||||
TItemApply aApplies[ITEM_APPLY_MAX_NUM];
|
||||
long alValues[ITEM_VALUES_MAX_NUM];
|
||||
long alSockets[ITEM_SOCKET_MAX_NUM];
|
||||
DWORD dwRefinedVnum;
|
||||
WORD wRefineSet;
|
||||
BYTE bAlterToMagicItemPct;
|
||||
BYTE bSpecular;
|
||||
BYTE bGainSocketPct;
|
||||
} TItemTable;
|
||||
|
||||
// typedef struct SItemTable
|
||||
// {
|
||||
// DWORD dwVnum;
|
||||
// char szItemName[ITEM_NAME_MAX_LEN + 1];
|
||||
// BYTE bType;
|
||||
// BYTE bSubType;
|
||||
// BYTE bSize;
|
||||
// DWORD dwAntiFlags;
|
||||
// DWORD dwFlags;
|
||||
// DWORD dwWearFlags;
|
||||
// DWORD dwIBuyItemPrice;
|
||||
// DWORD dwISellItemPrice;
|
||||
// TItemLimit aLimits[ITEM_LIMIT_MAX_NUM];
|
||||
// TItemApply aApplies[ITEM_APPLY_MAX_NUM];
|
||||
// long alValues[ITEM_VALUES_MAX_NUM];
|
||||
// long alSockets[ITEM_SOCKET_MAX_NUM];
|
||||
// DWORD dwRefinedVnum;
|
||||
// BYTE bSpecular;
|
||||
// DWORD dwIconNumber;
|
||||
// } TItemTable;
|
||||
#pragma pack(pop)
|
||||
|
||||
public:
|
||||
CItemData();
|
||||
virtual ~CItemData();
|
||||
|
||||
void Clear();
|
||||
void SetSummary(const std::string& c_rstSumm);
|
||||
void SetDescription(const std::string& c_rstDesc);
|
||||
|
||||
CGraphicThing * GetModelThing();
|
||||
CGraphicThing * GetSubModelThing();
|
||||
CGraphicThing * GetDropModelThing();
|
||||
CGraphicSubImage * GetIconImage();
|
||||
|
||||
DWORD GetLODModelThingCount();
|
||||
BOOL GetLODModelThingPointer(DWORD dwIndex, CGraphicThing ** ppModelThing);
|
||||
|
||||
DWORD GetAttachingDataCount();
|
||||
BOOL GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData);
|
||||
BOOL GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData);
|
||||
|
||||
/////
|
||||
const TItemTable* GetTable() const;
|
||||
DWORD GetIndex() const;
|
||||
const char * GetName() const;
|
||||
const char * GetDescription() const;
|
||||
const char * GetSummary() const;
|
||||
BYTE GetType() const;
|
||||
BYTE GetSubType() const;
|
||||
UINT GetRefine() const;
|
||||
const char* GetUseTypeString() const;
|
||||
DWORD GetWeaponType() const;
|
||||
BYTE GetSize() const;
|
||||
BOOL IsAntiFlag(DWORD dwFlag) const;
|
||||
BOOL IsFlag(DWORD dwFlag) const;
|
||||
BOOL IsWearableFlag(DWORD dwFlag) const;
|
||||
BOOL HasNextGrade() const;
|
||||
DWORD GetWearFlags() const;
|
||||
DWORD GetIBuyItemPrice() const;
|
||||
DWORD GetISellItemPrice() const;
|
||||
BOOL GetLimit(BYTE byIndex, TItemLimit * pItemLimit) const;
|
||||
BOOL GetApply(BYTE byIndex, TItemApply * pItemApply) const;
|
||||
long GetValue(BYTE byIndex) const;
|
||||
long GetSocket(BYTE byIndex) const;
|
||||
long SetSocket(BYTE byIndex,DWORD value);
|
||||
int GetSocketCount() const;
|
||||
DWORD GetIconNumber() const;
|
||||
|
||||
UINT GetSpecularPoweru() const;
|
||||
float GetSpecularPowerf() const;
|
||||
|
||||
/////
|
||||
|
||||
BOOL IsEquipment() const;
|
||||
|
||||
/////
|
||||
|
||||
//BOOL LoadItemData(const char * c_szFileName);
|
||||
void SetDefaultItemData(const char * c_szIconFileName, const char * c_szModelFileName = NULL);
|
||||
void SetItemTableData(TItemTable * pItemTable);
|
||||
|
||||
protected:
|
||||
void __LoadFiles();
|
||||
void __SetIconImage(const char * c_szFileName);
|
||||
|
||||
protected:
|
||||
std::string m_strModelFileName;
|
||||
std::string m_strSubModelFileName;
|
||||
std::string m_strDropModelFileName;
|
||||
std::string m_strIconFileName;
|
||||
std::string m_strDescription;
|
||||
std::string m_strSummary;
|
||||
std::vector<std::string> m_strLODModelFileNameVector;
|
||||
|
||||
CGraphicThing * m_pModelThing;
|
||||
CGraphicThing * m_pSubModelThing;
|
||||
CGraphicThing * m_pDropModelThing;
|
||||
CGraphicSubImage * m_pIconImage;
|
||||
std::vector<CGraphicThing *> m_pLODModelThingVector;
|
||||
|
||||
NRaceData::TAttachingDataVector m_AttachingDataVector;
|
||||
DWORD m_dwVnum;
|
||||
TItemTable m_ItemTable;
|
||||
|
||||
public:
|
||||
static void DestroySystem();
|
||||
|
||||
static CItemData* New();
|
||||
static void Delete(CItemData* pkItemData);
|
||||
|
||||
static CDynamicPool<CItemData> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,404 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterPack/EterPackManager.h"
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
|
||||
#include "ItemManager.h"
|
||||
|
||||
static DWORD s_adwItemProtoKey[4] =
|
||||
{
|
||||
173217,
|
||||
72619434,
|
||||
408587239,
|
||||
27973291
|
||||
};
|
||||
|
||||
BOOL CItemManager::SelectItemData(DWORD dwIndex)
|
||||
{
|
||||
TItemMap::iterator f = m_ItemMap.find(dwIndex);
|
||||
|
||||
if (m_ItemMap.end() == f)
|
||||
{
|
||||
int n = m_vec_ItemRange.size();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
CItemData * p = m_vec_ItemRange[i];
|
||||
const CItemData::TItemTable * pTable = p->GetTable();
|
||||
if ((pTable->dwVnum < dwIndex) &&
|
||||
dwIndex < (pTable->dwVnum + pTable->dwVnumRange))
|
||||
{
|
||||
m_pSelectedItemData = p;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
Tracef(" CItemManager::SelectItemData - FIND ERROR [%d]\n", dwIndex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_pSelectedItemData = f->second;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CItemData * CItemManager::GetSelectedItemDataPointer()
|
||||
{
|
||||
return m_pSelectedItemData;
|
||||
}
|
||||
|
||||
BOOL CItemManager::GetItemDataPointer(DWORD dwItemID, CItemData ** ppItemData)
|
||||
{
|
||||
if (0 == dwItemID)
|
||||
return FALSE;
|
||||
|
||||
TItemMap::iterator f = m_ItemMap.find(dwItemID);
|
||||
|
||||
if (m_ItemMap.end() == f)
|
||||
{
|
||||
int n = m_vec_ItemRange.size();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
CItemData * p = m_vec_ItemRange[i];
|
||||
const CItemData::TItemTable * pTable = p->GetTable();
|
||||
if ((pTable->dwVnum < dwItemID) &&
|
||||
dwItemID < (pTable->dwVnum + pTable->dwVnumRange))
|
||||
{
|
||||
*ppItemData = p;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
Tracef(" CItemManager::GetItemDataPointer - FIND ERROR [%d]\n", dwItemID);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*ppItemData = f->second;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CItemData * CItemManager::MakeItemData(DWORD dwIndex)
|
||||
{
|
||||
TItemMap::iterator f = m_ItemMap.find(dwIndex);
|
||||
|
||||
if (m_ItemMap.end() == f)
|
||||
{
|
||||
CItemData * pItemData = CItemData::New();
|
||||
|
||||
m_ItemMap.insert(TItemMap::value_type(dwIndex, pItemData));
|
||||
|
||||
return pItemData;
|
||||
}
|
||||
|
||||
return f->second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Load Item Table
|
||||
|
||||
bool CItemManager::LoadItemList(const char * c_szFileName)
|
||||
{
|
||||
CMappedFile File;
|
||||
LPCVOID pData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pData))
|
||||
return false;
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(File.Size(), pData);
|
||||
|
||||
CTokenVector TokenVector;
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &TokenVector, "\t"))
|
||||
continue;
|
||||
|
||||
if (!(TokenVector.size() == 3 || TokenVector.size() == 4))
|
||||
{
|
||||
TraceError(" CItemManager::LoadItemList(%s) - StrangeLine in %d\n", c_szFileName, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string & c_rstrID = TokenVector[0];
|
||||
//const std::string & c_rstrType = TokenVector[1];
|
||||
const std::string & c_rstrIcon = TokenVector[2];
|
||||
|
||||
DWORD dwItemVNum=atoi(c_rstrID.c_str());
|
||||
|
||||
CItemData * pItemData = MakeItemData(dwItemVNum);
|
||||
|
||||
extern BOOL USE_VIETNAM_CONVERT_WEAPON_VNUM;
|
||||
if (USE_VIETNAM_CONVERT_WEAPON_VNUM)
|
||||
{
|
||||
extern DWORD Vietnam_ConvertWeaponVnum(DWORD vnum);
|
||||
DWORD dwMildItemVnum = Vietnam_ConvertWeaponVnum(dwItemVNum);
|
||||
if (dwMildItemVnum == dwItemVNum)
|
||||
{
|
||||
if (4 == TokenVector.size())
|
||||
{
|
||||
const std::string & c_rstrModelFileName = TokenVector[3];
|
||||
pItemData->SetDefaultItemData(c_rstrIcon.c_str(), c_rstrModelFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
pItemData->SetDefaultItemData(c_rstrIcon.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwMildBaseVnum = dwMildItemVnum / 10 * 10;
|
||||
char szMildIconPath[MAX_PATH];
|
||||
sprintf(szMildIconPath, "icon/item/%.5d.tga", dwMildBaseVnum);
|
||||
if (4 == TokenVector.size())
|
||||
{
|
||||
char szMildModelPath[MAX_PATH];
|
||||
sprintf(szMildModelPath, "d:/ymir work/item/weapon/%.5d.gr2", dwMildBaseVnum);
|
||||
pItemData->SetDefaultItemData(szMildIconPath, szMildModelPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
pItemData->SetDefaultItemData(szMildIconPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (4 == TokenVector.size())
|
||||
{
|
||||
const std::string & c_rstrModelFileName = TokenVector[3];
|
||||
pItemData->SetDefaultItemData(c_rstrIcon.c_str(), c_rstrModelFileName.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
pItemData->SetDefaultItemData(c_rstrIcon.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string& __SnapString(const std::string& c_rstSrc, std::string& rstTemp)
|
||||
{
|
||||
UINT uSrcLen=c_rstSrc.length();
|
||||
if (uSrcLen<2)
|
||||
return c_rstSrc;
|
||||
|
||||
if (c_rstSrc[0]!='"')
|
||||
return c_rstSrc;
|
||||
|
||||
UINT uLeftCut=1;
|
||||
|
||||
UINT uRightCut=uSrcLen;
|
||||
if (c_rstSrc[uSrcLen-1]=='"')
|
||||
uRightCut=uSrcLen-1;
|
||||
|
||||
rstTemp=c_rstSrc.substr(uLeftCut, uRightCut-uLeftCut);
|
||||
return rstTemp;
|
||||
}
|
||||
|
||||
bool CItemManager::LoadItemDesc(const char* c_szFileName)
|
||||
{
|
||||
const VOID* pvData;
|
||||
CMappedFile kFile;
|
||||
if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
|
||||
{
|
||||
Tracenf("CItemManager::LoadItemDesc(c_szFileName=%s) - Load Error", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
CMemoryTextFileLoader kTextFileLoader;
|
||||
kTextFileLoader.Bind(kFile.Size(), pvData);
|
||||
|
||||
std::string stTemp;
|
||||
|
||||
CTokenVector kTokenVector;
|
||||
for (DWORD i = 0; i < kTextFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!kTextFileLoader.SplitLineByTab(i, &kTokenVector))
|
||||
continue;
|
||||
|
||||
while (kTokenVector.size()<ITEMDESC_COL_NUM)
|
||||
kTokenVector.push_back("");
|
||||
|
||||
//assert(kTokenVector.size()==ITEMDESC_COL_NUM);
|
||||
|
||||
DWORD dwVnum=atoi(kTokenVector[ITEMDESC_COL_VNUM].c_str());
|
||||
const std::string& c_rstDesc=kTokenVector[ITEMDESC_COL_DESC];
|
||||
const std::string& c_rstSumm=kTokenVector[ITEMDESC_COL_SUMM];
|
||||
TItemMap::iterator f = m_ItemMap.find(dwVnum);
|
||||
if (m_ItemMap.end() == f)
|
||||
continue;
|
||||
|
||||
CItemData* pkItemDataFind = f->second;
|
||||
|
||||
pkItemDataFind->SetDescription(__SnapString(c_rstDesc, stTemp));
|
||||
pkItemDataFind->SetSummary(__SnapString(c_rstSumm, stTemp));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD GetHashCode( const char* pString )
|
||||
{
|
||||
unsigned long i,len;
|
||||
unsigned long ch;
|
||||
unsigned long result;
|
||||
|
||||
len = strlen( pString );
|
||||
result = 5381;
|
||||
for( i=0; i<len; i++ )
|
||||
{
|
||||
ch = (unsigned long)pString[i];
|
||||
result = ((result<< 5) + result) + ch; // hash * 33 + ch
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CItemManager::LoadItemTable(const char* c_szFileName)
|
||||
{
|
||||
CMappedFile file;
|
||||
LPCVOID pvData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(file, c_szFileName, &pvData))
|
||||
return false;
|
||||
|
||||
DWORD dwFourCC, dwElements, dwDataSize;
|
||||
DWORD dwVersion=0;
|
||||
DWORD dwStride=0;
|
||||
|
||||
file.Read(&dwFourCC, sizeof(DWORD));
|
||||
|
||||
if (dwFourCC == MAKEFOURCC('M', 'I', 'P', 'X'))
|
||||
{
|
||||
file.Read(&dwVersion, sizeof(DWORD));
|
||||
file.Read(&dwStride, sizeof(DWORD));
|
||||
|
||||
if (dwVersion != 1)
|
||||
{
|
||||
TraceError("CPythonItem::LoadItemTable: invalid item_proto[%s] VERSION[%d]", c_szFileName, dwVersion);
|
||||
return false;
|
||||
}
|
||||
if (dwStride != sizeof(CItemData::TItemTable))
|
||||
{
|
||||
TraceError("CPythonItem::LoadItemTable: invalid item_proto[%s] STRIDE[%d] != sizeof(SItemTable)",
|
||||
c_szFileName, dwStride, sizeof(CItemData::TItemTable));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (dwFourCC != MAKEFOURCC('M', 'I', 'P', 'T'))
|
||||
{
|
||||
TraceError("CPythonItem::LoadItemTable: invalid item proto type %s", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
file.Read(&dwElements, sizeof(DWORD));
|
||||
file.Read(&dwDataSize, sizeof(DWORD));
|
||||
|
||||
BYTE * pbData = new BYTE[dwDataSize];
|
||||
file.Read(pbData, dwDataSize);
|
||||
|
||||
/////
|
||||
|
||||
CLZObject zObj;
|
||||
|
||||
if (!CLZO::Instance().Decompress(zObj, pbData, s_adwItemProtoKey))
|
||||
{
|
||||
delete [] pbData;
|
||||
return false;
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
char szName[64+1];
|
||||
|
||||
CItemData::TItemTable * table = (CItemData::TItemTable *) zObj.GetBuffer();
|
||||
std::map<DWORD,DWORD> itemNameMap;
|
||||
|
||||
for (DWORD i = 0; i < dwElements; ++i, ++table)
|
||||
{
|
||||
CItemData * pItemData;
|
||||
DWORD dwVnum = table->dwVnum;
|
||||
|
||||
TItemMap::iterator f = m_ItemMap.find(dwVnum);
|
||||
if (m_ItemMap.end() == f)
|
||||
{
|
||||
_snprintf(szName, sizeof(szName), "icon/item/%05d.tga", dwVnum);
|
||||
|
||||
if (CResourceManager::Instance().IsFileExist(szName) == false)
|
||||
{
|
||||
std::map<DWORD, DWORD>::iterator itVnum = itemNameMap.find(GetHashCode(table->szName));
|
||||
|
||||
if (itVnum != itemNameMap.end())
|
||||
_snprintf(szName, sizeof(szName), "icon/item/%05d.tga", itVnum->second);
|
||||
else
|
||||
_snprintf(szName, sizeof(szName), "icon/item/%05d.tga", dwVnum-dwVnum % 10);
|
||||
|
||||
if (CResourceManager::Instance().IsFileExist(szName) == false)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
TraceError("%16s(#%-5d) cannot find icon file. setting to default.", table->szName, dwVnum);
|
||||
#endif
|
||||
const DWORD EmptyBowl = 27995;
|
||||
_snprintf(szName, sizeof(szName), "icon/item/%05d.tga", EmptyBowl);
|
||||
}
|
||||
}
|
||||
|
||||
pItemData = CItemData::New();
|
||||
|
||||
pItemData->SetDefaultItemData(szName);
|
||||
m_ItemMap.insert(TItemMap::value_type(dwVnum, pItemData));
|
||||
}
|
||||
else
|
||||
{
|
||||
pItemData = f->second;
|
||||
}
|
||||
if (itemNameMap.find(GetHashCode(table->szName)) == itemNameMap.end())
|
||||
itemNameMap.insert(std::map<DWORD,DWORD>::value_type(GetHashCode(table->szName),table->dwVnum));
|
||||
pItemData->SetItemTableData(table);
|
||||
if (0 != table->dwVnumRange)
|
||||
{
|
||||
m_vec_ItemRange.push_back(pItemData);
|
||||
}
|
||||
}
|
||||
|
||||
//!@#
|
||||
// CItemData::TItemTable * table = (CItemData::TItemTable *) zObj.GetBuffer();
|
||||
// for (DWORD i = 0; i < dwElements; ++i, ++table)
|
||||
// {
|
||||
// CItemData * pItemData;
|
||||
// DWORD dwVnum = table->dwVnum;
|
||||
//
|
||||
// TItemMap::iterator f = m_ItemMap.find(dwVnum);
|
||||
//
|
||||
// if (m_ItemMap.end() == f)
|
||||
// {
|
||||
// pItemData = CItemData::New();
|
||||
//
|
||||
// pItemData->LoadItemData(_getf("d:/ymir work/item/%05d.msm", dwVnum));
|
||||
// m_ItemMap.insert(TItemMap::value_type(dwVnum, pItemData));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// pItemData = f->second;
|
||||
// }
|
||||
// pItemData->SetItemTableData(table);
|
||||
// }
|
||||
|
||||
delete [] pbData;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CItemManager::Destroy()
|
||||
{
|
||||
TItemMap::iterator i;
|
||||
for (i=m_ItemMap.begin(); i!=m_ItemMap.end(); ++i)
|
||||
CItemData::Delete(i->second);
|
||||
|
||||
m_ItemMap.clear();
|
||||
}
|
||||
|
||||
CItemManager::CItemManager() : m_pSelectedItemData(NULL)
|
||||
{
|
||||
}
|
||||
CItemManager::~CItemManager()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "ItemData.h"
|
||||
|
||||
class CItemManager : public CSingleton<CItemManager>
|
||||
{
|
||||
public:
|
||||
enum EItemDescCol
|
||||
{
|
||||
ITEMDESC_COL_VNUM,
|
||||
ITEMDESC_COL_NAME,
|
||||
ITEMDESC_COL_DESC,
|
||||
ITEMDESC_COL_SUMM,
|
||||
ITEMDESC_COL_NUM,
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::map<DWORD, CItemData*> TItemMap;
|
||||
typedef std::map<std::string, CItemData*> TItemNameMap;
|
||||
|
||||
public:
|
||||
CItemManager();
|
||||
virtual ~CItemManager();
|
||||
|
||||
void Destroy();
|
||||
|
||||
BOOL SelectItemData(DWORD dwIndex);
|
||||
CItemData * GetSelectedItemDataPointer();
|
||||
|
||||
BOOL GetItemDataPointer(DWORD dwItemID, CItemData ** ppItemData);
|
||||
|
||||
/////
|
||||
bool LoadItemDesc(const char* c_szFileName);
|
||||
bool LoadItemList(const char* c_szFileName);
|
||||
bool LoadItemTable(const char* c_szFileName);
|
||||
CItemData * MakeItemData(DWORD dwIndex);
|
||||
|
||||
protected:
|
||||
TItemMap m_ItemMap;
|
||||
std::vector<CItemData*> m_vec_ItemRange;
|
||||
CItemData * m_pSelectedItemData;
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapBase.h"
|
||||
|
||||
CMapBase::CMapBase()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CMapBase::~CMapBase()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CMapBase::Clear()
|
||||
{
|
||||
m_strName = "";
|
||||
m_eType = MAPTYPE_INVALID;
|
||||
mc_pEnvironmentData = NULL;
|
||||
Leave();
|
||||
}
|
||||
|
||||
bool CMapBase::Enter()
|
||||
{
|
||||
m_bReady = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapBase::Leave()
|
||||
{
|
||||
m_bReady = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapBase::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
mc_pEnvironmentData = c_pEnvironmentData;
|
||||
OnSetEnvironmentDataPtr();
|
||||
}
|
||||
|
||||
void CMapBase::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
mc_pEnvironmentData = c_pEnvironmentData;
|
||||
OnResetEnvironmentDataPtr();
|
||||
}
|
||||
|
||||
void CMapBase::Render()
|
||||
{
|
||||
if (IsReady())
|
||||
OnRender();
|
||||
}
|
||||
|
||||
bool CMapBase::LoadProperty()
|
||||
{
|
||||
std::string strFileName = GetName() + "\\MapProperty.txt";
|
||||
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(strFileName.c_str(), stTokenVectorMap))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - LoadMultipleTextData ERROR 파일이 없을 가능성이 많습니다.", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'scripttype' - FAILED", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("maptype"))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'maptype' - FAILED", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: 이미 존재하는 맵 데이터와 동일한 데이터를 사용하는 맵을 새로 추가할 때, 맵 배포 용량을 줄이기 위한 작업.
|
||||
// MapProperty.txt 파일에 ParentMapName 값이 설정되어 있다면, 실제 모든 데이터는 ParentMap에서 읽어온다.
|
||||
// 데이터의 부분공유(부분 오버라이트?) 기능은 필요 없대서, Parent Map에서 모든 데이터를 읽어옴.
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("parentmapname"))
|
||||
{
|
||||
m_strParentMapName = stTokenVectorMap["parentmapname"][0];
|
||||
}
|
||||
|
||||
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
|
||||
const std::string & c_rstrMapType = stTokenVectorMap["maptype"][0];
|
||||
|
||||
if (0 != c_rstrType.compare("MapProperty"))
|
||||
{
|
||||
TraceError("CMapBase::LoadProperty(FileName=%s) - Resourse Type ERROR", strFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == c_rstrMapType.compare("Indoor"))
|
||||
SetType(MAPTYPE_INDOOR);
|
||||
else if (0 == c_rstrMapType.compare("Outdoor"))
|
||||
SetType(MAPTYPE_OUTDOOR);
|
||||
else if (0 == c_rstrMapType.compare("Invalid"))
|
||||
SetType(MAPTYPE_OUTDOOR);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
class CMapBase : public CScreen
|
||||
{
|
||||
public:
|
||||
enum EMAPTYPE
|
||||
{
|
||||
MAPTYPE_INVALID,
|
||||
MAPTYPE_INDOOR,
|
||||
MAPTYPE_OUTDOOR,
|
||||
};
|
||||
|
||||
public:
|
||||
CMapBase();
|
||||
virtual ~CMapBase();
|
||||
|
||||
virtual void Clear();
|
||||
virtual bool Initialize() = 0;
|
||||
virtual bool Destroy() = 0;
|
||||
virtual bool Load(float x, float y, float z) = 0;
|
||||
|
||||
virtual bool Update(float fX, float fY, float fZ) = 0;
|
||||
virtual void UpdateAroundAmbience(float fX, float fY, float fZ) = 0;
|
||||
virtual float GetHeight(float fx, float fy) = 0;
|
||||
virtual void OnBeginEnvironment() = 0; // 렌더링 할 때 불려지며 여기서 Environment에 관련 있는 것들을 셋팅 한다.
|
||||
|
||||
virtual void ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight) = 0;
|
||||
|
||||
protected:
|
||||
virtual void OnRender() = 0;
|
||||
virtual void OnSetEnvironmentDataPtr() = 0; // Environment 데이터가 설정될 때 불려진다.
|
||||
virtual void OnResetEnvironmentDataPtr() = 0;
|
||||
|
||||
public:
|
||||
void Render();
|
||||
void SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData);
|
||||
void ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData);
|
||||
bool Enter();
|
||||
bool Leave();
|
||||
bool IsReady() { return m_bReady; }
|
||||
|
||||
bool LoadProperty();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Setting
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
EMAPTYPE GetType() const { return m_eType; }
|
||||
void SetType(EMAPTYPE eType) { m_eType = eType; }
|
||||
|
||||
const std::string & GetName() const { return m_strName; }
|
||||
void SetName(const std::string & cr_strName) { m_strName = cr_strName; }
|
||||
|
||||
bool IsCopiedMap() const { return m_strParentMapName.length() > 0; } // "원본 데이터는 따로 있는" 복사 맵인가?
|
||||
const std::string& GetParentMapName() const { return m_strParentMapName; } // 원본 데이터를 갖고있는 맵의 이름을 리턴 (복사맵의 경우 필수로 세팅되어야 함)
|
||||
const std::string& GetMapDataDirectory() const { return IsCopiedMap() ? m_strParentMapName : m_strName; }
|
||||
|
||||
protected:
|
||||
EMAPTYPE m_eType; // 맵 종류... 현재는 Indoor와 Ourdoor가 있다.
|
||||
std::string m_strName; // 맵 이름. 맵 이름이 맵 식별자가 될 수 있을까?
|
||||
std::string m_strParentMapName; // 원본 맵의 이름. 이 값이 세팅되어 있다면 실제 모든 맵 데이터는 ParentMap/* 경로에서 읽어온다. 맵의 일부만 읽어오는 기능은 필요없대서 패스.
|
||||
bool m_bReady;
|
||||
|
||||
const TEnvironmentData * mc_pEnvironmentData;
|
||||
};
|
||||
@@ -0,0 +1,638 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/StateManager.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
#include "MapManager.h"
|
||||
#include "MapOutdoor.h"
|
||||
|
||||
#include "PropertyLoader.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 기본 함수
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool CMapManager::IsMapOutdoor()
|
||||
{
|
||||
if (m_pkMap)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CMapOutdoor& CMapManager::GetMapOutdoorRef()
|
||||
{
|
||||
assert(NULL!=m_pkMap);
|
||||
return *m_pkMap;
|
||||
}
|
||||
|
||||
|
||||
CMapManager::CMapManager() : mc_pcurEnvironmentData(NULL)
|
||||
{
|
||||
m_pkMap = NULL;
|
||||
m_isSoftwareTilingEnableReserved=false;
|
||||
|
||||
// Initialize();
|
||||
}
|
||||
|
||||
CMapManager::~CMapManager()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool CMapManager::IsSoftwareTilingEnable()
|
||||
{
|
||||
return CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE;
|
||||
}
|
||||
|
||||
void CMapManager::ReserveSoftwareTilingEnable(bool isEnable)
|
||||
{
|
||||
m_isSoftwareTilingEnableReserved=isEnable;
|
||||
}
|
||||
|
||||
|
||||
void CMapManager::Initialize()
|
||||
{
|
||||
mc_pcurEnvironmentData = NULL;
|
||||
__LoadMapInfoVector();
|
||||
}
|
||||
|
||||
void CMapManager::Create()
|
||||
{
|
||||
assert(NULL==m_pkMap && "CMapManager::Create");
|
||||
if (m_pkMap)
|
||||
{
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=m_isSoftwareTilingEnableReserved;
|
||||
|
||||
m_pkMap = (CMapOutdoor*)AllocMap();
|
||||
|
||||
assert(NULL!=m_pkMap && "CMapManager::Create MAP is NULL");
|
||||
|
||||
}
|
||||
|
||||
void CMapManager::Destroy()
|
||||
{
|
||||
stl_wipe_second(m_EnvironmentDataMap);
|
||||
|
||||
if (m_pkMap)
|
||||
{
|
||||
m_pkMap->Clear();
|
||||
delete m_pkMap;
|
||||
m_pkMap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CMapManager::Clear()
|
||||
{
|
||||
if (m_pkMap)
|
||||
m_pkMap->Clear();
|
||||
}
|
||||
|
||||
CMapBase * CMapManager::AllocMap()
|
||||
{
|
||||
return new CMapOutdoor;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Map
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMapManager::LoadProperty()
|
||||
{
|
||||
CPropertyLoader PropertyLoader;
|
||||
PropertyLoader.SetPropertyManager(&m_PropertyManager);
|
||||
PropertyLoader.Create("*.*", "Property");
|
||||
}
|
||||
|
||||
bool CMapManager::LoadMap(const std::string & c_rstrMapName, float x, float y, float z)
|
||||
{
|
||||
CMapOutdoor& rkMap = GetMapOutdoorRef();
|
||||
|
||||
rkMap.Leave();
|
||||
rkMap.SetName(c_rstrMapName);
|
||||
rkMap.LoadProperty();
|
||||
|
||||
if ( CMapBase::MAPTYPE_INDOOR == rkMap.GetType())
|
||||
{
|
||||
TraceError("CMapManager::LoadMap() Indoor Map Load Failed");
|
||||
return false;
|
||||
}
|
||||
else if (CMapBase::MAPTYPE_OUTDOOR == rkMap.GetType())
|
||||
{
|
||||
if (!rkMap.Load(x, y, z))
|
||||
{
|
||||
TraceError("CMapManager::LoadMap() Outdoor Map Load Failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisterEnvironmentData(0, rkMap.GetEnvironmentDataName().c_str());
|
||||
|
||||
SetEnvironmentData(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceError("CMapManager::LoadMap() Invalid Map Type");
|
||||
return false;
|
||||
}
|
||||
|
||||
rkMap.Enter();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapManager::IsMapReady()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return false;
|
||||
|
||||
return m_pkMap->IsReady();
|
||||
}
|
||||
|
||||
bool CMapManager::UnloadMap(const std::string c_strMapName)
|
||||
{
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
if (c_strMapName != rkMap.GetName() && "" != rkMap.GetName())
|
||||
{
|
||||
LogBoxf("%s: Unload Map Failed", c_strMapName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapManager::UpdateMap(float fx, float fy, float fz)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.Update(fx, -fy, fz);
|
||||
}
|
||||
|
||||
void CMapManager::UpdateAroundAmbience(float fx, float fy, float fz)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.UpdateAroundAmbience(fx, -fy, fz);
|
||||
}
|
||||
|
||||
float CMapManager::GetHeight(float fx, float fy)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
TraceError("CMapManager::GetHeight(%f, %f) - 맵이 생성되지 않은 상태에서 접근", fx, fy);
|
||||
return 0.0f;
|
||||
}
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetHeight(fx, fy);
|
||||
}
|
||||
|
||||
float CMapManager::GetTerrainHeight(float fx, float fy)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
TraceError("CMapManager::GetTerrainHeight(%f, %f) - 맵이 생성되지 않은 상태에서 접근", fx, fy);
|
||||
return 0.0f;
|
||||
}
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetTerrainHeight(fx, fy);
|
||||
}
|
||||
|
||||
bool CMapManager::GetWaterHeight(int iX, int iY, long * plWaterHeight)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
TraceError("CMapManager::GetTerrainHeight(%f, %f) - 맵이 생성되지 않은 상태에서 접근", iX, iY);
|
||||
return false;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetWaterHeight(iX, iY, plWaterHeight);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Environment
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMapManager::BeginEnvironment()
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
if (!mc_pcurEnvironmentData)
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
// Light always on
|
||||
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE);
|
||||
|
||||
// Fog
|
||||
STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, mc_pcurEnvironmentData->bFogEnable);
|
||||
|
||||
// Material
|
||||
STATEMANAGER.SetMaterial(&mc_pcurEnvironmentData->Material);
|
||||
|
||||
// Directional Light
|
||||
if (mc_pcurEnvironmentData->bDirLightsEnable[ENV_DIRLIGHT_BACKGROUND])
|
||||
{
|
||||
ms_lpd3dDevice->LightEnable(0, TRUE);
|
||||
|
||||
rkMap.ApplyLight((DWORD)mc_pcurEnvironmentData, mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]);
|
||||
}
|
||||
else
|
||||
ms_lpd3dDevice->LightEnable(0, FALSE);
|
||||
|
||||
if (mc_pcurEnvironmentData->bFogEnable)
|
||||
{
|
||||
DWORD dwFogColor = mc_pcurEnvironmentData->FogColor;
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, dwFogColor);
|
||||
|
||||
if (mc_pcurEnvironmentData->bDensityFog)
|
||||
{
|
||||
float fDensity = 0.00015f;
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP); // pixel fog
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGDENSITY, *((DWORD *) &fDensity)); // vertex fog
|
||||
}
|
||||
else
|
||||
{
|
||||
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
|
||||
rkForest.SetFog(
|
||||
mc_pcurEnvironmentData->GetFogNearDistance(),
|
||||
mc_pcurEnvironmentData->GetFogFarDistance()
|
||||
);
|
||||
|
||||
float fFogNear=mc_pcurEnvironmentData->GetFogNearDistance();
|
||||
float fFogFar=mc_pcurEnvironmentData->GetFogFarDistance();
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); // vertex fox
|
||||
STATEMANAGER.SetRenderState(D3DRS_RANGEFOGENABLE, TRUE); // vertex fox
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGSTART, *((DWORD *) &fFogNear)); // USED BY D3DFOG_LINEAR
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGEND, *((DWORD *) &fFogFar)); // USED BY D3DFOG_LINEAR
|
||||
}
|
||||
}
|
||||
|
||||
rkMap.OnBeginEnvironment();
|
||||
}
|
||||
|
||||
void CMapManager::EndEnvironment()
|
||||
{
|
||||
if (!mc_pcurEnvironmentData)
|
||||
return;
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE);
|
||||
}
|
||||
|
||||
void CMapManager::SetEnvironmentData(int nEnvDataIndex)
|
||||
{
|
||||
const TEnvironmentData * c_pEnvironmenData;
|
||||
|
||||
if (GetEnvironmentData(nEnvDataIndex, &c_pEnvironmenData))
|
||||
SetEnvironmentDataPtr(c_pEnvironmenData);
|
||||
}
|
||||
|
||||
void CMapManager::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
if (!c_pEnvironmentData)
|
||||
{
|
||||
assert(!"null environment data");
|
||||
TraceError("null environment data");
|
||||
return;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
|
||||
mc_pcurEnvironmentData = c_pEnvironmentData;
|
||||
|
||||
|
||||
rkMap.SetEnvironmentDataPtr(mc_pcurEnvironmentData);
|
||||
}
|
||||
|
||||
void CMapManager::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
return;
|
||||
|
||||
if (!c_pEnvironmentData)
|
||||
{
|
||||
assert(!"null environment data");
|
||||
TraceError("null environment data");
|
||||
return;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
|
||||
mc_pcurEnvironmentData = c_pEnvironmentData;
|
||||
rkMap.ResetEnvironmentDataPtr(mc_pcurEnvironmentData);
|
||||
}
|
||||
|
||||
void CMapManager::BlendEnvironmentData(const TEnvironmentData * c_pEnvironmentData, int iTransitionTime)
|
||||
{
|
||||
}
|
||||
|
||||
bool CMapManager::RegisterEnvironmentData(DWORD dwIndex, const char * c_szFileName)
|
||||
{
|
||||
TEnvironmentData * pEnvironmentData = AllocEnvironmentData();
|
||||
|
||||
if (!LoadEnvironmentData(c_szFileName, pEnvironmentData))
|
||||
{
|
||||
DeleteEnvironmentData(pEnvironmentData);
|
||||
return false;
|
||||
}
|
||||
|
||||
TEnvironmentDataMap::iterator f=m_EnvironmentDataMap.find(dwIndex);
|
||||
if (m_EnvironmentDataMap.end()==f)
|
||||
{
|
||||
m_EnvironmentDataMap.insert(TEnvironmentDataMap::value_type(dwIndex, pEnvironmentData));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete f->second;
|
||||
f->second=pEnvironmentData;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapManager::GetCurrentEnvironmentData(const TEnvironmentData ** c_ppEnvironmentData)
|
||||
{
|
||||
*c_ppEnvironmentData = mc_pcurEnvironmentData;
|
||||
}
|
||||
|
||||
bool CMapManager::GetEnvironmentData(DWORD dwIndex, const TEnvironmentData ** c_ppEnvironmentData)
|
||||
{
|
||||
TEnvironmentDataMap::iterator itor = m_EnvironmentDataMap.find(dwIndex);
|
||||
|
||||
if (m_EnvironmentDataMap.end() == itor)
|
||||
{
|
||||
*c_ppEnvironmentData = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
*c_ppEnvironmentData = itor->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapManager::RefreshPortal()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor & rMap = GetMapOutdoorRef();
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!rMap.GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
|
||||
pArea->RefreshPortal();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapManager::ClearPortal()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor & rMap = GetMapOutdoorRef();
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!rMap.GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
|
||||
pArea->ClearPortal();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapManager::AddShowingPortalID(int iID)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor & rMap = GetMapOutdoorRef();
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!rMap.GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
|
||||
pArea->AddShowingPortalID(iID);
|
||||
}
|
||||
}
|
||||
|
||||
TEnvironmentData * CMapManager::AllocEnvironmentData()
|
||||
{
|
||||
TEnvironmentData * pEnvironmentData = new TEnvironmentData;
|
||||
Environment_Init(*pEnvironmentData);
|
||||
return pEnvironmentData;
|
||||
}
|
||||
|
||||
void CMapManager::DeleteEnvironmentData(TEnvironmentData * pEnvironmentData)
|
||||
{
|
||||
delete pEnvironmentData;
|
||||
pEnvironmentData = NULL;
|
||||
}
|
||||
|
||||
BOOL CMapManager::LoadEnvironmentData(const char * c_szFileName, TEnvironmentData * pEnvironmentData)
|
||||
{
|
||||
if (!pEnvironmentData)
|
||||
return FALSE;
|
||||
|
||||
return (BOOL)Environment_Load(*pEnvironmentData, c_szFileName);
|
||||
}
|
||||
|
||||
DWORD CMapManager::GetShadowMapColor(float fx, float fy)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetShadowMapColor(fx, fy);
|
||||
}
|
||||
|
||||
std::vector<int> & CMapManager::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
static std::vector<int> s_emptyVector;
|
||||
*piPatch = 0;
|
||||
*piSplat = 0;
|
||||
return s_emptyVector;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetRenderedSplatNum(piPatch, piSplat, pfSplatRatio);
|
||||
}
|
||||
|
||||
CArea::TCRCWithNumberVector & CMapManager::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum)
|
||||
{
|
||||
if (!m_pkMap)
|
||||
{
|
||||
static CArea::TCRCWithNumberVector s_emptyVector;
|
||||
*pdwGraphicThingInstanceNum = 0;
|
||||
*pdwCRCNum = 0;
|
||||
return s_emptyVector;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetRenderedGraphicThingInstanceNum(pdwGraphicThingInstanceNum, pdwCRCNum);
|
||||
}
|
||||
|
||||
bool CMapManager::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetNormal(ix, iy, pv3Normal);
|
||||
}
|
||||
|
||||
bool CMapManager::isPhysicalCollision(const D3DXVECTOR3 & c_rvCheckPosition)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.isAttrOn(c_rvCheckPosition.x, -c_rvCheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK);
|
||||
}
|
||||
|
||||
bool CMapManager::isAttrOn(float fX, float fY, BYTE byAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.isAttrOn(fX, fY, byAttr);
|
||||
}
|
||||
|
||||
bool CMapManager::GetAttr(float fX, float fY, BYTE * pbyAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetAttr(fX, fY, pbyAttr);
|
||||
}
|
||||
|
||||
bool CMapManager::isAttrOn(int iX, int iY, BYTE byAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.isAttrOn(iX, iY, byAttr);
|
||||
}
|
||||
|
||||
bool CMapManager::GetAttr(int iX, int iY, BYTE * pbyAttr)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetAttr(iX, iY, pbyAttr);
|
||||
}
|
||||
|
||||
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
|
||||
/*
|
||||
bool CMapManager::BGLoadingEnable()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return false;
|
||||
return ((CMapOutdoor*)m_pMap)->BGLoadingEnable();
|
||||
}
|
||||
|
||||
void CMapManager::BGLoadingEnable(bool bBGLoadingEnable)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
((CMapOutdoor*)m_pMap)->BGLoadingEnable(bBGLoadingEnable);
|
||||
}
|
||||
*/
|
||||
|
||||
void CMapManager::SetTerrainRenderSort(CMapOutdoor::ETerrainRenderSort eTerrainRenderSort)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.SetTerrainRenderSort(eTerrainRenderSort);
|
||||
}
|
||||
|
||||
void CMapManager::SetTransparentTree(bool bTransparenTree)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.SetTransparentTree(bTransparenTree);
|
||||
}
|
||||
|
||||
CMapOutdoor::ETerrainRenderSort CMapManager::GetTerrainRenderSort()
|
||||
{
|
||||
if (!IsMapReady())
|
||||
return CMapOutdoor::DISTANCE_SORT;
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
return rkMap.GetTerrainRenderSort();
|
||||
}
|
||||
|
||||
void CMapManager::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY)
|
||||
{
|
||||
if (!IsMapReady())
|
||||
{
|
||||
*pdwBaseX = 0;
|
||||
*pdwBaseY = 0;
|
||||
}
|
||||
|
||||
CMapOutdoor& rkMap=GetMapOutdoorRef();
|
||||
rkMap.GetBaseXY(pdwBaseX, pdwBaseY);
|
||||
}
|
||||
|
||||
void CMapManager::__LoadMapInfoVector()
|
||||
{
|
||||
CMappedFile kFile;
|
||||
LPCVOID pData;
|
||||
if (!CEterPackManager::Instance().Get(kFile, m_stAtlasInfoFileName.c_str(), &pData))
|
||||
if (!CEterPackManager::Instance().Get(kFile, "AtlasInfo.txt", &pData))
|
||||
return;
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(kFile.Size(), pData);
|
||||
|
||||
char szMapName[256];
|
||||
int x, y;
|
||||
int width, height;
|
||||
for (UINT uLineIndex=0; uLineIndex<textFileLoader.GetLineCount(); ++uLineIndex)
|
||||
{
|
||||
const std::string& c_rstLine=textFileLoader.GetLineString(uLineIndex);
|
||||
sscanf(c_rstLine.c_str(), "%s %d %d %d %d",
|
||||
szMapName,
|
||||
&x, &y, &width, &height);
|
||||
|
||||
if ('\0'==szMapName[0])
|
||||
continue;
|
||||
|
||||
TMapInfo kMapInfo;
|
||||
kMapInfo.m_strName = szMapName;
|
||||
kMapInfo.m_dwBaseX = x;
|
||||
kMapInfo.m_dwBaseY = y;
|
||||
|
||||
kMapInfo.m_dwSizeX = width;
|
||||
kMapInfo.m_dwSizeY = height;
|
||||
|
||||
kMapInfo.m_dwEndX = kMapInfo.m_dwBaseX + kMapInfo.m_dwSizeX * CTerrainImpl::TERRAIN_XSIZE;
|
||||
kMapInfo.m_dwEndY = kMapInfo.m_dwBaseY + kMapInfo.m_dwSizeY * CTerrainImpl::TERRAIN_YSIZE;
|
||||
|
||||
m_kVct_kMapInfo.push_back(kMapInfo);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
#pragma once
|
||||
|
||||
class CMapBase;
|
||||
#include "MapOutdoor.h"
|
||||
#include "PropertyManager.h"
|
||||
|
||||
// VICTIM_COLLISION_TEST
|
||||
#include "PhysicsObject.h"
|
||||
// VICTIM_COLLISION_TEST_END
|
||||
|
||||
// Map Manager
|
||||
class CMapManager : public CScreen, public IPhysicsWorld
|
||||
{
|
||||
public:
|
||||
CMapManager();
|
||||
virtual ~CMapManager();
|
||||
|
||||
bool IsMapOutdoor();
|
||||
CMapOutdoor& GetMapOutdoorRef();
|
||||
|
||||
bool IsSoftwareTilingEnable();
|
||||
void ReserveSoftwareTilingEnable(bool isEnable);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Contructor / Destructor
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Initialize();
|
||||
void Destroy();
|
||||
|
||||
void Create(); // AllocMap 호출 해서 m_pMap 을 만듬
|
||||
|
||||
virtual void Clear();
|
||||
virtual CMapBase * AllocMap();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Map 관리 함수
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool IsMapReady();
|
||||
|
||||
virtual bool LoadMap(const std::string & c_rstrMapName, float x, float y, float z);
|
||||
bool UnloadMap(const std::string c_strMapName);
|
||||
|
||||
bool UpdateMap(float fx, float fy, float fz);
|
||||
void UpdateAroundAmbience(float fx, float fy, float fz);
|
||||
float GetHeight(float fx, float fy);
|
||||
float GetTerrainHeight(float fx, float fy);
|
||||
bool GetWaterHeight(int iX, int iY, long * plWaterHeight);
|
||||
|
||||
bool GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Environment
|
||||
///
|
||||
// NOTE : 다음 Environment로 서서히 블렌딩 시킨다
|
||||
// 아직 세부 구현은 되어있지 않음. 이 함수들은 Protected로 넣고,
|
||||
// MapManager에 TimeControl 부분을 구현하도록 한다. - [levites]
|
||||
void SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData);
|
||||
void ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData);
|
||||
void SetEnvironmentData(int nEnvDataIndex);
|
||||
|
||||
void BeginEnvironment();
|
||||
void EndEnvironment();
|
||||
|
||||
void BlendEnvironmentData(const TEnvironmentData * c_pEnvironmentData, int iTransitionTime);
|
||||
|
||||
void GetCurrentEnvironmentData(const TEnvironmentData ** c_ppEnvironmentData);
|
||||
bool RegisterEnvironmentData(DWORD dwIndex, const char * c_szFileName);
|
||||
bool GetEnvironmentData(DWORD dwIndex, const TEnvironmentData ** c_ppEnvironmentData);
|
||||
|
||||
// Portal
|
||||
void RefreshPortal();
|
||||
void ClearPortal();
|
||||
void AddShowingPortalID(int iID);
|
||||
|
||||
// External interface
|
||||
void LoadProperty();
|
||||
|
||||
DWORD GetShadowMapColor(float fx, float fy);
|
||||
|
||||
// VICITM_COLLISION_TEST
|
||||
virtual bool isPhysicalCollision(const D3DXVECTOR3 & c_rvCheckPosition);
|
||||
// VICITM_COLLISION_TEST_END
|
||||
|
||||
bool isAttrOn(float fX, float fY, BYTE byAttr);
|
||||
bool GetAttr(float fX, float fY, BYTE * pbyAttr);
|
||||
bool isAttrOn(int iX, int iY, BYTE byAttr);
|
||||
bool GetAttr(int iX, int iY, BYTE * pbyAttr);
|
||||
|
||||
std::vector<int> & GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio);
|
||||
CArea::TCRCWithNumberVector & GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum);
|
||||
|
||||
protected:
|
||||
TEnvironmentData * AllocEnvironmentData();
|
||||
void DeleteEnvironmentData(TEnvironmentData * pEnvironmentData);
|
||||
BOOL LoadEnvironmentData(const char * c_szFileName, TEnvironmentData * pEnvironmentData);
|
||||
|
||||
protected:
|
||||
CPropertyManager m_PropertyManager;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Environment
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
TEnvironmentDataMap m_EnvironmentDataMap;
|
||||
const TEnvironmentData * mc_pcurEnvironmentData;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Map
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CMapOutdoor * m_pkMap;
|
||||
CSpeedTreeForestDirectX8 m_Forest;
|
||||
|
||||
public:
|
||||
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
|
||||
//bool BGLoadingEnable();
|
||||
//void BGLoadingEnable(bool bBGLoadingEnable);
|
||||
void SetTerrainRenderSort(CMapOutdoor::ETerrainRenderSort eTerrainRenderSort);
|
||||
CMapOutdoor::ETerrainRenderSort GetTerrainRenderSort();
|
||||
|
||||
void GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY);
|
||||
|
||||
public:
|
||||
void SetTransparentTree(bool bTransparenTree);
|
||||
|
||||
public:
|
||||
typedef struct
|
||||
{
|
||||
std::string m_strName;
|
||||
DWORD m_dwBaseX;
|
||||
DWORD m_dwBaseY;
|
||||
DWORD m_dwSizeX;
|
||||
DWORD m_dwSizeY;
|
||||
DWORD m_dwEndX;
|
||||
DWORD m_dwEndY;
|
||||
} TMapInfo;
|
||||
typedef std::vector<TMapInfo> TMapInfoVector;
|
||||
typedef TMapInfoVector::iterator TMapInfoVectorIterator;
|
||||
|
||||
protected:
|
||||
TMapInfoVector m_kVct_kMapInfo;
|
||||
|
||||
bool m_isSoftwareTilingEnableReserved;
|
||||
|
||||
protected:
|
||||
void __LoadMapInfoVector();
|
||||
|
||||
protected:
|
||||
struct FFindMapName
|
||||
{
|
||||
std::string strNametoFind;
|
||||
FFindMapName(const std::string & c_rMapName)
|
||||
{
|
||||
strNametoFind = c_rMapName;
|
||||
stl_lowers(strNametoFind);
|
||||
}
|
||||
bool operator() (TMapInfo & rMapInfo)
|
||||
{
|
||||
if (rMapInfo.m_strName == strNametoFind)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
public:
|
||||
void SetAtlasInfoFileName(const char* filename)
|
||||
{
|
||||
m_stAtlasInfoFileName = filename;
|
||||
}
|
||||
private:
|
||||
std::string m_stAtlasInfoFileName;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,779 @@
|
||||
#pragma once
|
||||
|
||||
#include "../eterLib/SkyBox.h"
|
||||
#include "../eterLib/LensFlare.h"
|
||||
#include "../eterLib/ScreenFilter.h"
|
||||
|
||||
#include "../PRTerrainLib/TerrainType.h"
|
||||
#include "../PRTerrainLib/TextureSet.h"
|
||||
|
||||
#include "../SpeedTreeLib/SpeedTreeForestDirectX8.h"
|
||||
|
||||
#include "MapBase.h"
|
||||
#include "Area.h"
|
||||
#include "AreaTerrain.h"
|
||||
#include "AreaLoaderThread.h"
|
||||
|
||||
#include "MonsterAreaInfo.h"
|
||||
|
||||
|
||||
#define LOAD_SIZE_WIDTH 1
|
||||
|
||||
#define AROUND_AREA_NUM 1+(LOAD_SIZE_WIDTH*2)*(LOAD_SIZE_WIDTH*2)*2
|
||||
#define MAX_PREPARE_SIZE 9
|
||||
#define MAX_MAPSIZE 256 // 0 ~ 255, cellsize 200 = 64km
|
||||
|
||||
#define TERRAINPATCH_LODMAX 3
|
||||
|
||||
typedef struct SOutdoorMapCoordinate
|
||||
{
|
||||
short m_sTerrainCoordX; // Terrain 좌표
|
||||
short m_sTerrainCoordY;
|
||||
} TOutdoorMapCoordinate;
|
||||
|
||||
typedef std::map<const std::string, TOutdoorMapCoordinate> TOutdoorMapCoordinateMap;
|
||||
|
||||
class CTerrainPatchProxy;
|
||||
class CTerrainQuadtreeNode;
|
||||
|
||||
class CMapOutdoor : public CMapBase
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
VIEW_NONE = 0,
|
||||
VIEW_PART,
|
||||
VIEW_ALL,
|
||||
};
|
||||
|
||||
enum EPart
|
||||
{
|
||||
PART_TERRAIN,
|
||||
PART_OBJECT,
|
||||
PART_CLOUD,
|
||||
PART_WATER,
|
||||
PART_TREE,
|
||||
PART_SKY,
|
||||
PART_NUM,
|
||||
};
|
||||
|
||||
enum ETerrainRenderSort
|
||||
{
|
||||
DISTANCE_SORT,
|
||||
TEXTURE_SORT,
|
||||
};
|
||||
|
||||
public:
|
||||
CMapOutdoor();
|
||||
virtual ~CMapOutdoor();
|
||||
|
||||
virtual void OnBeginEnvironment();
|
||||
|
||||
protected:
|
||||
bool Initialize();
|
||||
void InitializeFog();
|
||||
|
||||
virtual bool Destroy();
|
||||
virtual void OnSetEnvironmentDataPtr();
|
||||
virtual void OnResetEnvironmentDataPtr();
|
||||
|
||||
virtual void OnRender();
|
||||
|
||||
virtual void OnPreAssignTerrainPtr() {};
|
||||
|
||||
public:
|
||||
void SetInverseViewAndDynamicShaodwMatrices();
|
||||
virtual bool Load(float x, float y, float z);
|
||||
virtual float GetHeight(float x, float y);
|
||||
virtual float GetCacheHeight(float x, float y);
|
||||
|
||||
virtual bool Update(float fX, float fY, float fZ);
|
||||
virtual void UpdateAroundAmbience(float fX, float fY, float fZ);
|
||||
|
||||
public:
|
||||
void Clear();
|
||||
|
||||
void SetVisiblePart(int ePart, bool isVisible);
|
||||
void SetSplatLimit(int iSplatNum);
|
||||
std::vector<int> & GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio);
|
||||
CArea::TCRCWithNumberVector & GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum);
|
||||
|
||||
bool LoadSetting(const char * c_szFileName);
|
||||
|
||||
void ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight);
|
||||
void SetEnvironmentScreenFilter();
|
||||
void SetEnvironmentSkyBox();
|
||||
void SetEnvironmentLensFlare();
|
||||
|
||||
void CreateCharacterShadowTexture();
|
||||
void ReleaseCharacterShadowTexture();
|
||||
void SetShadowTextureSize(WORD size);
|
||||
|
||||
bool BeginRenderCharacterShadowToTexture();
|
||||
void EndRenderCharacterShadowToTexture();
|
||||
void RenderWater();
|
||||
void RenderMarkedArea();
|
||||
void RecurseRenderAttr(CTerrainQuadtreeNode *Node, bool bCullEnable=TRUE);
|
||||
void DrawPatchAttr(long patchnum);
|
||||
void ClearGuildArea();
|
||||
void RegisterGuildArea(int isx, int isy, int iex, int iey);
|
||||
|
||||
void VisibleMarkedArea();
|
||||
void DisableMarkedArea();
|
||||
|
||||
void UpdateSky();
|
||||
void RenderCollision();
|
||||
void RenderSky();
|
||||
void RenderCloud();
|
||||
void RenderBeforeLensFlare();
|
||||
void RenderAfterLensFlare();
|
||||
void RenderScreenFiltering();
|
||||
|
||||
void SetWireframe(bool bWireFrame);
|
||||
bool IsWireframe();
|
||||
|
||||
bool GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt);
|
||||
bool GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt);
|
||||
bool GetPickingPoint(D3DXVECTOR3 * v3IntersectPt);
|
||||
void GetTerrainCount(short * psTerrainCountX, short * psTerrainCountY)
|
||||
{
|
||||
*psTerrainCountX = m_sTerrainCountX;
|
||||
*psTerrainCountY = m_sTerrainCountY;
|
||||
}
|
||||
|
||||
bool SetTerrainCount(short sTerrainCountX, short sTerrainCountY);
|
||||
|
||||
// Shadow
|
||||
void SetDrawShadow(bool bDrawShadow);
|
||||
void SetDrawCharacterShadow(bool bDrawChrShadow);
|
||||
|
||||
DWORD GetShadowMapColor(float fx, float fy);
|
||||
|
||||
protected:
|
||||
bool __PickTerrainHeight(float& fPos, const D3DXVECTOR3& v3Start, const D3DXVECTOR3& v3End, float fStep, float fRayRange, float fLimitRange, D3DXVECTOR3* pv3Pick);
|
||||
|
||||
virtual void __ClearGarvage();
|
||||
virtual void __UpdateGarvage();
|
||||
|
||||
virtual bool LoadTerrain(WORD wTerrainCoordX, WORD wTerrainCoordY, WORD wCellCoordX, WORD wCellCoordY);
|
||||
virtual bool LoadArea(WORD wAreaCoordX, WORD wAreaCoordY, WORD wCellCoordX, WORD wCellCoordY);
|
||||
virtual void UpdateAreaList(long lCenterX, long lCenterY);
|
||||
bool isTerrainLoaded(WORD wX, WORD wY);
|
||||
bool isAreaLoaded(WORD wX, WORD wY);
|
||||
|
||||
void AssignTerrainPtr(); // 현재 좌표에서 주위(ex. 3x3)에 있는 것들의 포인터를 연결한다. (업데이트 시 불려짐)
|
||||
|
||||
void SaveAlphaFogOperation();
|
||||
void RestoreAlphaFogOperation();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// New
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 여러가지 맵들을 얻는다.
|
||||
void GetHeightMap(const BYTE & c_rucTerrainNum, WORD ** pwHeightMap);
|
||||
void GetNormalMap(const BYTE & c_rucTerrainNum, char ** pucNormalMap);
|
||||
|
||||
// Water
|
||||
void GetWaterMap(const BYTE & c_rucTerrainNum, BYTE ** pucWaterMap);
|
||||
void GetWaterHeight(BYTE byTerrainNum, BYTE byWaterNum, long * plWaterHeight);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Terrain
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
protected:
|
||||
// 데이터
|
||||
CTerrain * m_pTerrain[AROUND_AREA_NUM]; // Terrain
|
||||
CTerrainPatchProxy * m_pTerrainPatchProxyList; // CTerrain을 랜더링 할때 실제로 랜더링하는 폴리곤 패치들... Seamless Map 을 위해 CTerrain으로부터 독립...
|
||||
|
||||
long m_lViewRadius; // 시야 거리.. 셀단위임..
|
||||
float m_fHeightScale; // 높이 스케일... 1.0일때 0~655.35미터까지 표현 가능.
|
||||
|
||||
short m_sTerrainCountX, m_sTerrainCountY; // seamless map 안에 들어가는 Terrain개수
|
||||
|
||||
TOutdoorMapCoordinate m_CurCoordinate; // 현재의 좌표
|
||||
|
||||
long m_lCurCoordStartX, m_lCurCoordStartY;
|
||||
TOutdoorMapCoordinate m_PrevCoordinate; // 현재의 좌표
|
||||
TOutdoorMapCoordinateMap m_EntryPointMap;
|
||||
|
||||
WORD m_wPatchCount;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Index Buffer
|
||||
#ifdef WORLD_EDITOR
|
||||
WORD * m_pwIndices; /* temp Index buffer */
|
||||
|
||||
CGraphicIndexBuffer m_IndexBuffer;
|
||||
WORD m_wNumIndices;
|
||||
#else
|
||||
WORD * m_pwaIndices[TERRAINPATCH_LODMAX];
|
||||
|
||||
CGraphicIndexBuffer m_IndexBuffer[TERRAINPATCH_LODMAX];
|
||||
WORD m_wNumIndices[TERRAINPATCH_LODMAX];
|
||||
#endif
|
||||
virtual void DestroyTerrain();
|
||||
|
||||
void CreateTerrainPatchProxyList();
|
||||
void DestroyTerrainPatchProxyList();
|
||||
|
||||
void UpdateTerrain(float fX, float fY);
|
||||
|
||||
void ConvertTerrainToTnL(long lx, long ly);
|
||||
|
||||
void AssignPatch(long lPatchNum, long lx0, long ly0, long lx1, long ly1);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Index Buffer
|
||||
void ADDLvl1TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl1M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
void ADDLvl2M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp);
|
||||
|
||||
public:
|
||||
BOOL GetTerrainPointer(BYTE c_ucTerrainNum, CTerrain ** ppTerrain);
|
||||
float GetTerrainHeight(float fx, float fy);
|
||||
bool GetWaterHeight(int iX, int iY, long * plWaterHeight);
|
||||
bool GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal);
|
||||
|
||||
void RenderTerrain();
|
||||
|
||||
const long GetViewRadius() { return m_lViewRadius; }
|
||||
const float GetHeightScale() { return m_fHeightScale; }
|
||||
|
||||
const TOutdoorMapCoordinate & GetEntryPoint(const std::string & c_rstrEntryPointName) const;
|
||||
void SetEntryPoint(const std::string & c_rstrEntryPointName, const TOutdoorMapCoordinate & c_rOutdoorMapCoordinate);
|
||||
const TOutdoorMapCoordinate & GetCurCoordinate() { return m_CurCoordinate; }
|
||||
const TOutdoorMapCoordinate & GetPrevCoordinate() { return m_PrevCoordinate; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Area
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
protected:
|
||||
CArea * m_pArea[AROUND_AREA_NUM]; // Data
|
||||
|
||||
virtual void DestroyArea();
|
||||
|
||||
void __UpdateArea(D3DXVECTOR3& v3Player);
|
||||
#ifdef WORLD_EDITOR
|
||||
void __NEW_WorldEditor_UpdateArea();
|
||||
#endif
|
||||
void __Game_UpdateArea(D3DXVECTOR3& v3Player);
|
||||
|
||||
void __BuildDynamicSphereInstanceVector();
|
||||
|
||||
void __CollectShadowReceiver(D3DXVECTOR3& v3Target, D3DXVECTOR3& v3Light);
|
||||
void __CollectCollisionPCBlocker(D3DXVECTOR3& v3Eye, D3DXVECTOR3& v3Target, float fDistance);
|
||||
void __CollectCollisionShadowReceiver(D3DXVECTOR3& v3Target, D3DXVECTOR3& v3Light);
|
||||
void __UpdateAroundAreaList();
|
||||
bool __IsInShadowReceiverList(CGraphicObjectInstance* pkObjInstTest);
|
||||
bool __IsInPCBlockerList(CGraphicObjectInstance* pkObjInstTest);
|
||||
|
||||
void ConvertToMapCoords(float fx, float fy, int *iCellX, int *iCellY, BYTE * pucSubCellX, BYTE * pucSubCellY, WORD * pwTerrainNumX, WORD * pwTerrainNumY);
|
||||
|
||||
public:
|
||||
BOOL GetAreaPointer(const BYTE c_ucAreaNum, CArea ** ppArea);
|
||||
void RenderArea(bool bRenderAmbience = true);
|
||||
void RenderBlendArea();
|
||||
void RenderDungeon();
|
||||
void RenderEffect();
|
||||
void RenderPCBlocker();
|
||||
void RenderTree();
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// For Grass
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
float GetHeight(float* pPos);
|
||||
bool GetBrushColor(float fX, float fY, float* pLowColor, float* pHighColor);
|
||||
bool isAttrOn(float fX, float fY, BYTE byAttr);
|
||||
bool GetAttr(float fX, float fY, BYTE * pbyAttr);
|
||||
bool isAttrOn(int iX, int iY, BYTE byAttr);
|
||||
bool GetAttr(int iX, int iY, BYTE * pbyAttr);
|
||||
|
||||
void SetMaterialDiffuse(float fr, float fg, float fb);
|
||||
void SetMaterialAmbient(float fr, float fg, float fb);
|
||||
void SetTerrainMaterial(const PR_MATERIAL * pMaterial);
|
||||
|
||||
bool GetTerrainNum(float fx, float fy, BYTE * pbyTerrainNum);
|
||||
bool GetTerrainNumFromCoord(WORD wCoordX, WORD wCoordY, BYTE * pbyTerrainNum);
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// New
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
long m_lCenterX, m_lCenterY; // Terrain 좌표 내의 셀 좌표...
|
||||
long m_lOldReadX, m_lOldReadY; /* Last center */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Octree
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTerrainQuadtreeNode * m_pRootNode;
|
||||
|
||||
void BuildQuadTree();
|
||||
CTerrainQuadtreeNode * AllocQuadTreeNode(long x0, long y0, long x1, long y1);
|
||||
void SubDivideNode(CTerrainQuadtreeNode * Node);
|
||||
void UpdateQuadTreeHeights(CTerrainQuadtreeNode *Node);
|
||||
|
||||
|
||||
void FreeQuadTree();
|
||||
|
||||
struct TPatchDrawStruct
|
||||
{
|
||||
float fDistance;
|
||||
BYTE byTerrainNum;
|
||||
long lPatchNum;
|
||||
CTerrainPatchProxy * pTerrainPatchProxy;
|
||||
|
||||
bool operator<( const TPatchDrawStruct & rhs) const
|
||||
{
|
||||
return fDistance < rhs.fDistance;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::vector<BYTE> TTerrainNumVector;
|
||||
struct FSortPatchDrawStructWithTerrainNum
|
||||
{
|
||||
static TTerrainNumVector m_TerrainNumVector;
|
||||
FSortPatchDrawStructWithTerrainNum()
|
||||
{
|
||||
m_TerrainNumVector.clear();
|
||||
}
|
||||
|
||||
bool operator () (const TPatchDrawStruct & lhs, const TPatchDrawStruct & rhs)
|
||||
{
|
||||
DWORD lhsTerrainNumOrder = 0, rhsTerrainNumOrder = 0;
|
||||
bool blhsOrderFound = false;
|
||||
bool brhsOrderFound = false;
|
||||
|
||||
TTerrainNumVector::iterator lhsIterator = std::find(m_TerrainNumVector.begin(), m_TerrainNumVector.end(), lhs.byTerrainNum);
|
||||
TTerrainNumVector::iterator rhsIterator = std::find(m_TerrainNumVector.begin(), m_TerrainNumVector.end(), rhs.byTerrainNum);
|
||||
|
||||
if (lhsIterator != m_TerrainNumVector.end())
|
||||
{
|
||||
blhsOrderFound = true;
|
||||
lhsTerrainNumOrder = lhsIterator - m_TerrainNumVector.begin();
|
||||
}
|
||||
if (rhsIterator != m_TerrainNumVector.end())
|
||||
{
|
||||
brhsOrderFound = true;
|
||||
rhsTerrainNumOrder = rhsIterator - m_TerrainNumVector.begin();
|
||||
}
|
||||
if (!brhsOrderFound)
|
||||
{
|
||||
m_TerrainNumVector.push_back(rhs.byTerrainNum);
|
||||
rhsTerrainNumOrder = m_TerrainNumVector.size() -1;
|
||||
}
|
||||
if (!blhsOrderFound)
|
||||
{
|
||||
lhsIterator = std::find(m_TerrainNumVector.begin(), m_TerrainNumVector.end(), lhs.byTerrainNum);
|
||||
if (lhsIterator != m_TerrainNumVector.end())
|
||||
{
|
||||
blhsOrderFound = true;
|
||||
lhsTerrainNumOrder = lhsIterator - m_TerrainNumVector.begin();
|
||||
}
|
||||
if (!blhsOrderFound)
|
||||
{
|
||||
m_TerrainNumVector.push_back(lhs.byTerrainNum);
|
||||
lhsTerrainNumOrder = m_TerrainNumVector.size() -1;
|
||||
}
|
||||
}
|
||||
|
||||
return lhsTerrainNumOrder < rhsTerrainNumOrder;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<std::pair<float, long> > m_PatchVector;
|
||||
std::vector<TPatchDrawStruct> m_PatchDrawStructVector;
|
||||
|
||||
void SetPatchDrawVector();
|
||||
|
||||
void NEW_DrawWireFrame(CTerrainPatchProxy * pTerrainPatchProxy, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType);
|
||||
|
||||
void DrawWireFrame(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType);
|
||||
void DrawWater(long patchnum);
|
||||
|
||||
bool m_bDrawWireFrame;
|
||||
bool m_bDrawShadow;
|
||||
bool m_bDrawChrShadow;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Water
|
||||
D3DXMATRIX m_matBump;
|
||||
void LoadWaterTexture();
|
||||
void UnloadWaterTexture();
|
||||
//Water
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Alpha Fog
|
||||
CGraphicImageInstance m_AlphaFogImageInstance;
|
||||
D3DXMATRIX m_matAlphaFogTexture;
|
||||
// Alpha Fog
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Character Shadow
|
||||
LPDIRECT3DTEXTURE8 m_lpCharacterShadowMapTexture;
|
||||
LPDIRECT3DSURFACE8 m_lpCharacterShadowMapRenderTargetSurface;
|
||||
LPDIRECT3DSURFACE8 m_lpCharacterShadowMapDepthSurface;
|
||||
D3DVIEWPORT8 m_ShadowMapViewport;
|
||||
WORD m_wShadowMapSize;
|
||||
|
||||
// Backup Device Context
|
||||
LPDIRECT3DSURFACE8 m_lpBackupRenderTargetSurface;
|
||||
LPDIRECT3DSURFACE8 m_lpBackupDepthSurface;
|
||||
D3DVIEWPORT8 m_BackupViewport;
|
||||
|
||||
// Character Shadow
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// View Frustum Culling
|
||||
D3DXPLANE m_plane[6];
|
||||
|
||||
void BuildViewFrustum(D3DXMATRIX & mat);
|
||||
|
||||
CTextureSet m_TextureSet;
|
||||
|
||||
protected:
|
||||
CSkyBox m_SkyBox;
|
||||
CLensFlare m_LensFlare;
|
||||
CScreenFilter m_ScreenFilter;
|
||||
|
||||
protected:
|
||||
void SetIndexBuffer();
|
||||
void SelectIndexBuffer(BYTE byLODLevel, WORD * pwPrimitiveCount, D3DPRIMITIVETYPE * pePrimitiveType);
|
||||
|
||||
D3DXMATRIX m_matWorldForCommonUse;
|
||||
D3DXMATRIX m_matViewInverse;
|
||||
|
||||
D3DXMATRIX m_matSplatAlpha;
|
||||
D3DXMATRIX m_matStaticShadow;
|
||||
D3DXMATRIX m_matDynamicShadow;
|
||||
D3DXMATRIX m_matDynamicShadowScale;
|
||||
D3DXMATRIX m_matLightView;
|
||||
|
||||
float m_fTerrainTexCoordBase;
|
||||
float m_fWaterTexCoordBase;
|
||||
|
||||
float m_fXforDistanceCaculation, m_fYforDistanceCaculation;
|
||||
|
||||
protected:
|
||||
typedef std::vector<CTerrain *> TTerrainPtrVector;
|
||||
typedef TTerrainPtrVector::iterator TTerrainPtrVectorIterator;
|
||||
typedef std::vector<CArea *> TAreaPtrVector;
|
||||
typedef TAreaPtrVector::iterator TAreaPtrVectorIterator;
|
||||
|
||||
TTerrainPtrVector m_TerrainVector;
|
||||
TTerrainPtrVector m_TerrainDeleteVector;
|
||||
TTerrainPtrVector m_TerrainLoadRequestVector;
|
||||
TTerrainPtrVector m_TerrainLoadWaitVector;
|
||||
TTerrainPtrVectorIterator m_TerrainPtrVectorIterator;
|
||||
|
||||
TAreaPtrVector m_AreaVector;
|
||||
TAreaPtrVector m_AreaDeleteVector;
|
||||
TAreaPtrVector m_AreaLoadRequestVector;
|
||||
TAreaPtrVector m_AreaLoadWaitVector;
|
||||
TAreaPtrVectorIterator m_AreaPtrVectorIterator;
|
||||
|
||||
struct FPushToDeleteVector
|
||||
{
|
||||
enum EDeleteDir
|
||||
{
|
||||
DELETE_LEFT,
|
||||
DELETE_RIGHT,
|
||||
DELETE_TOP,
|
||||
DELETE_BOTTOM,
|
||||
};
|
||||
|
||||
EDeleteDir m_eLRDeleteDir;
|
||||
EDeleteDir m_eTBDeleteDir;
|
||||
TOutdoorMapCoordinate m_CurCoordinate;
|
||||
|
||||
FPushToDeleteVector(EDeleteDir eLRDeleteDir, EDeleteDir eTBDeleteDir, TOutdoorMapCoordinate CurCoord)
|
||||
{
|
||||
m_eLRDeleteDir = eLRDeleteDir;
|
||||
m_eTBDeleteDir = eTBDeleteDir;
|
||||
m_CurCoordinate = CurCoord;
|
||||
}
|
||||
};
|
||||
|
||||
struct FPushTerrainToDeleteVector : public FPushToDeleteVector
|
||||
{
|
||||
TTerrainPtrVector m_ReturnTerrainVector;
|
||||
|
||||
FPushTerrainToDeleteVector(EDeleteDir eLRDeleteDir, EDeleteDir eTBDeleteDir, TOutdoorMapCoordinate CurCoord)
|
||||
: FPushToDeleteVector(eLRDeleteDir, eTBDeleteDir, CurCoord)
|
||||
{
|
||||
m_ReturnTerrainVector.clear();
|
||||
}
|
||||
|
||||
void operator() (CTerrain * pTerrain);
|
||||
};
|
||||
|
||||
struct FPushAreaToDeleteVector : public FPushToDeleteVector
|
||||
{
|
||||
TAreaPtrVector m_ReturnAreaVector;
|
||||
|
||||
FPushAreaToDeleteVector(EDeleteDir eLRDeleteDir, EDeleteDir eTBDeleteDir, TOutdoorMapCoordinate CurCoord)
|
||||
: FPushToDeleteVector(eLRDeleteDir, eTBDeleteDir, CurCoord)
|
||||
{
|
||||
m_ReturnAreaVector.clear();
|
||||
}
|
||||
|
||||
void operator() (CArea * pArea);
|
||||
};
|
||||
|
||||
protected:
|
||||
void InitializeVisibleParts();
|
||||
bool IsVisiblePart(int ePart);
|
||||
|
||||
float __GetNoFogDistance();
|
||||
float __GetFogDistance();
|
||||
|
||||
|
||||
protected:
|
||||
DWORD m_dwVisiblePartFlags;
|
||||
|
||||
int m_iRenderedSplatNumSqSum;
|
||||
int m_iRenderedSplatNum;
|
||||
int m_iRenderedPatchNum;
|
||||
std::vector<int> m_RenderedTextureNumVector;
|
||||
int m_iSplatLimit;
|
||||
|
||||
protected:
|
||||
int m_iPatchTerrainVertexCount;
|
||||
int m_iPatchWaterVertexCount;
|
||||
|
||||
int m_iPatchTerrainVertexSize;
|
||||
int m_iPatchWaterVertexSize;
|
||||
|
||||
DWORD m_dwRenderedCRCNum;
|
||||
DWORD m_dwRenderedGraphicThingInstanceNum;
|
||||
|
||||
std::list<RECT> m_rkList_kGuildArea;
|
||||
|
||||
protected:
|
||||
void __RenderTerrain_RecurseRenderQuadTree(CTerrainQuadtreeNode *Node, bool bCullCheckNeed = true);
|
||||
int __RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(const D3DXVECTOR3 & c_v3Center, const float & c_fRadius);
|
||||
|
||||
void __RenderTerrain_AppendPatch(const D3DXVECTOR3& c_rv3Center, float fDistance, long lPatchNum);
|
||||
|
||||
void __RenderTerrain_RenderSoftwareTransformPatch();
|
||||
void __RenderTerrain_RenderHardwareTransformPatch();
|
||||
|
||||
protected:
|
||||
void __HardwareTransformPatch_RenderPatchSplat(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType);
|
||||
void __HardwareTransformPatch_RenderPatchNone(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType);
|
||||
|
||||
|
||||
protected:
|
||||
struct SoftwareTransformPatch_SData
|
||||
{
|
||||
enum
|
||||
{
|
||||
SPLAT_VB_NUM = 8,
|
||||
NONE_VB_NUM = 8,
|
||||
};
|
||||
|
||||
IDirect3DVertexBuffer8* m_pkVBSplat[SPLAT_VB_NUM];
|
||||
IDirect3DVertexBuffer8* m_pkVBNone[NONE_VB_NUM];
|
||||
DWORD m_dwSplatPos;
|
||||
DWORD m_dwNonePos;
|
||||
DWORD m_dwLightVersion;
|
||||
} m_kSTPD;
|
||||
|
||||
struct SoftwareTransformPatch_SRenderState {
|
||||
D3DXMATRIX m_m4Proj;
|
||||
D3DXMATRIX m_m4Frustum;
|
||||
D3DXMATRIX m_m4DynamicShadow;
|
||||
D3DLIGHT8 m_kLight;
|
||||
D3DMATERIAL8 m_kMtrl;
|
||||
D3DXVECTOR3 m_v3Player;
|
||||
DWORD m_dwFogColor;
|
||||
float m_fScreenHalfWidth;
|
||||
float m_fScreenHalfHeight;
|
||||
|
||||
float m_fFogNearDistance;
|
||||
float m_fFogFarDistance;
|
||||
float m_fFogNearTransZ;
|
||||
float m_fFogFarTransZ;
|
||||
float m_fFogLenInv;
|
||||
};
|
||||
|
||||
struct SoftwareTransformPatch_STVertex
|
||||
{
|
||||
D3DXVECTOR4 kPosition;
|
||||
};
|
||||
|
||||
struct SoftwareTransformPatch_STLVertex
|
||||
{
|
||||
D3DXVECTOR4 kPosition;
|
||||
DWORD dwDiffuse;
|
||||
DWORD dwFog;
|
||||
D3DXVECTOR2 kTexTile;
|
||||
D3DXVECTOR2 kTexAlpha;
|
||||
D3DXVECTOR2 kTexStaticShadow;
|
||||
D3DXVECTOR2 kTexDynamicShadow;
|
||||
};
|
||||
|
||||
|
||||
void __SoftwareTransformPatch_ApplyRenderState();
|
||||
void __SoftwareTransformPatch_RestoreRenderState(DWORD dwFogEnable);
|
||||
|
||||
void __SoftwareTransformPatch_Initialize();
|
||||
bool __SoftwareTransformPatch_Create();
|
||||
void __SoftwareTransformPatch_Destroy();
|
||||
void __SoftwareTransformPatch_BuildPipeline(SoftwareTransformPatch_SRenderState& rkTPRS);
|
||||
void __SoftwareTransformPatch_BuildPipeline_BuildFogFuncTable(SoftwareTransformPatch_SRenderState& rkTPRS);
|
||||
bool __SoftwareTransformPatch_SetTransform(SoftwareTransformPatch_SRenderState& rkTPRS, SoftwareTransformPatch_STLVertex* akTransVertex, CTerrainPatchProxy& rkTerrainPatchProxy, UINT uTerrainX, UINT uTerrainY, bool isFogEnable, bool isDynamicShadow);
|
||||
|
||||
bool __SoftwareTransformPatch_SetSplatStream(SoftwareTransformPatch_STLVertex* akTransVertex);
|
||||
bool __SoftwareTransformPatch_SetShadowStream(SoftwareTransformPatch_STLVertex* akTransVertex);
|
||||
|
||||
void __SoftwareTransformPatch_ApplyStaticShadowRenderState();
|
||||
void __SoftwareTransformPatch_RestoreStaticShadowRenderState();
|
||||
|
||||
void __SoftwareTransformPatch_ApplyFogShadowRenderState();
|
||||
void __SoftwareTransformPatch_RestoreFogShadowRenderState();
|
||||
void __SoftwareTransformPatch_ApplyDynamicShadowRenderState();
|
||||
void __SoftwareTransformPatch_RestoreDynamicShadowRenderState();
|
||||
void __SoftwareTransformPatch_RenderPatchSplat(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType, bool isFogEnable);
|
||||
void __SoftwareTransformPatch_RenderPatchNone(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType);
|
||||
|
||||
|
||||
protected:
|
||||
std::vector<CGraphicObjectInstance *> m_ShadowReceiverVector;
|
||||
std::vector<CGraphicObjectInstance *> m_PCBlockerVector;
|
||||
|
||||
protected:
|
||||
float m_fOpaqueWaterDepth;
|
||||
CGraphicImageInstance m_WaterInstances[30];
|
||||
|
||||
public:
|
||||
float GetOpaqueWaterDepth() { return m_fOpaqueWaterDepth; }
|
||||
void SetOpaqueWaterDepth(float fOpaqueWaterDepth) { m_fOpaqueWaterDepth = fOpaqueWaterDepth; }
|
||||
void SetTerrainRenderSort(ETerrainRenderSort eTerrainRenderSort) { m_eTerrainRenderSort = eTerrainRenderSort;}
|
||||
ETerrainRenderSort GetTerrainRenderSort() { return m_eTerrainRenderSort; }
|
||||
|
||||
protected:
|
||||
ETerrainRenderSort m_eTerrainRenderSort;
|
||||
|
||||
protected:
|
||||
CGraphicImageInstance m_attrImageInstance;
|
||||
CGraphicImageInstance m_BuildingTransparentImageInstance;
|
||||
D3DXMATRIX m_matBuildingTransparent;
|
||||
|
||||
protected:
|
||||
CDynamicPool<CMonsterAreaInfo> m_kPool_kMonsterAreaInfo;
|
||||
TMonsterAreaInfoPtrVector m_MonsterAreaInfoPtrVector;
|
||||
TMonsterAreaInfoPtrVectorIterator m_MonsterAreaInfoPtrVectorIterator;
|
||||
|
||||
public:
|
||||
bool LoadMonsterAreaInfo();
|
||||
|
||||
CMonsterAreaInfo * AddMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY);
|
||||
void RemoveAllMonsterAreaInfo();
|
||||
|
||||
DWORD GetMonsterAreaInfoCount() { return m_MonsterAreaInfoPtrVector.size(); }
|
||||
bool GetMonsterAreaInfoFromVectorIndex(DWORD dwMonsterAreaInfoVectorIndex, CMonsterAreaInfo ** ppMonsterAreaInfo);
|
||||
|
||||
CMonsterAreaInfo * AddNewMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY,
|
||||
CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType,
|
||||
DWORD dwVID, DWORD dwCount, CMonsterAreaInfo::EMonsterDir eMonsterDir);
|
||||
|
||||
public:
|
||||
void GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY);
|
||||
void SetBaseXY(DWORD dwBaseX, DWORD dwBaseY);
|
||||
|
||||
void SetTransparentTree(bool bTransparentTree) { m_bTransparentTree = bTransparentTree;}
|
||||
void EnableTerrainOnlyForHeight(bool bFlag) { m_bEnableTerrainOnlyForHeight = bFlag; }
|
||||
void EnablePortal(bool bFlag);
|
||||
bool IsEnablePortal() { return m_bEnablePortal; }
|
||||
|
||||
protected:
|
||||
DWORD m_dwBaseX;
|
||||
DWORD m_dwBaseY;
|
||||
|
||||
D3DXVECTOR3 m_v3Player;
|
||||
|
||||
bool m_bShowEntirePatchTextureCount;
|
||||
bool m_bTransparentTree;
|
||||
bool m_bEnableTerrainOnlyForHeight;
|
||||
bool m_bEnablePortal;
|
||||
|
||||
// XMas
|
||||
private:
|
||||
struct SXMasTree
|
||||
{
|
||||
CSpeedTreeWrapper* m_pkTree;
|
||||
int m_iEffectID;
|
||||
} m_kXMas;
|
||||
|
||||
void __XMasTree_Initialize();
|
||||
void __XMasTree_Create(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName);
|
||||
|
||||
public:
|
||||
void XMasTree_Destroy();
|
||||
void XMasTree_Set(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName);
|
||||
|
||||
// Special Effect
|
||||
private:
|
||||
typedef std::map<DWORD, int> TSpecialEffectMap;
|
||||
TSpecialEffectMap m_kMap_dwID_iEffectID;
|
||||
|
||||
public:
|
||||
void SpecialEffect_Create(DWORD dwID, float x, float y, float z, const char* c_szEffName);
|
||||
void SpecialEffect_Delete(DWORD dwID);
|
||||
void SpecialEffect_Destroy();
|
||||
|
||||
private:
|
||||
struct SHeightCache
|
||||
{
|
||||
struct SItem
|
||||
{
|
||||
DWORD m_dwKey;
|
||||
float m_fHeight;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HASH_SIZE = 100,
|
||||
};
|
||||
|
||||
std::vector<SItem> m_akVct_kItem[HASH_SIZE];
|
||||
|
||||
bool m_isUpdated;
|
||||
} m_kHeightCache;
|
||||
|
||||
void __HeightCache_Init();
|
||||
void __HeightCache_Update();
|
||||
|
||||
public:
|
||||
void SetEnvironmentDataName(const std::string& strEnvironmentDataName);
|
||||
std::string& GetEnvironmentDataName();
|
||||
|
||||
protected:
|
||||
std::string m_settings_envDataName;
|
||||
std::string m_envDataName;
|
||||
|
||||
private:
|
||||
bool m_bSettingTerrainVisible;
|
||||
};
|
||||
@@ -0,0 +1,165 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/StateManager.h"
|
||||
#include "../eterlib/Camera.h"
|
||||
|
||||
#include "MapOutdoor.h"
|
||||
|
||||
static int recreate = false;
|
||||
|
||||
void CMapOutdoor::SetShadowTextureSize(WORD size)
|
||||
{
|
||||
if (m_wShadowMapSize != size)
|
||||
{
|
||||
recreate = true;
|
||||
Tracenf("ShadowTextureSize changed %d -> %d", m_wShadowMapSize, size);
|
||||
}
|
||||
|
||||
m_wShadowMapSize = size;
|
||||
}
|
||||
|
||||
void CMapOutdoor::CreateCharacterShadowTexture()
|
||||
{
|
||||
extern bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW;
|
||||
|
||||
if (GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW)
|
||||
return;
|
||||
|
||||
ReleaseCharacterShadowTexture();
|
||||
|
||||
if (IsLowTextureMemory())
|
||||
SetShadowTextureSize(128);
|
||||
|
||||
m_ShadowMapViewport.X = 1;
|
||||
m_ShadowMapViewport.Y = 1;
|
||||
m_ShadowMapViewport.Width = m_wShadowMapSize - 2;
|
||||
m_ShadowMapViewport.Height = m_wShadowMapSize - 2;
|
||||
m_ShadowMapViewport.MinZ = 0.0f;
|
||||
m_ShadowMapViewport.MaxZ = 1.0f;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wShadowMapSize, m_wShadowMapSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &m_lpCharacterShadowMapTexture)))
|
||||
{
|
||||
TraceError("CMapOutdoor Unable to create Character Shadow render target texture\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(m_lpCharacterShadowMapTexture->GetSurfaceLevel(0, &m_lpCharacterShadowMapRenderTargetSurface)))
|
||||
{
|
||||
TraceError("CMapOutdoor Unable to GetSurfaceLevel Character Shadow render target texture\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wShadowMapSize, m_wShadowMapSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpCharacterShadowMapDepthSurface)))
|
||||
{
|
||||
TraceError("CMapOutdoor Unable to create Character Shadow depth Surface\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::ReleaseCharacterShadowTexture()
|
||||
{
|
||||
SAFE_RELEASE(m_lpCharacterShadowMapRenderTargetSurface);
|
||||
SAFE_RELEASE(m_lpCharacterShadowMapDepthSurface);
|
||||
SAFE_RELEASE(m_lpCharacterShadowMapTexture);
|
||||
}
|
||||
|
||||
DWORD dwLightEnable = FALSE;
|
||||
|
||||
bool CMapOutdoor::BeginRenderCharacterShadowToTexture()
|
||||
{
|
||||
D3DXMATRIX matLightView, matLightProj;
|
||||
|
||||
CCamera* pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
|
||||
if (!pCurrentCamera)
|
||||
return false;
|
||||
|
||||
if (recreate)
|
||||
{
|
||||
CreateCharacterShadowTexture();
|
||||
recreate = false;
|
||||
}
|
||||
|
||||
D3DXVECTOR3 v3Target = pCurrentCamera->GetTarget();
|
||||
|
||||
D3DXVECTOR3 v3Eye(v3Target.x - 1.732f * 1250.0f,
|
||||
v3Target.y - 1250.0f,
|
||||
v3Target.z + 2.0f * 1.732f * 1250.0f);
|
||||
|
||||
const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
D3DXMatrixLookAtRH(&matLightView,
|
||||
&v3Eye,
|
||||
&v3Target,
|
||||
&vv);
|
||||
|
||||
D3DXMatrixOrthoRH(&matLightProj, 2550.0f, 2550.0f, 1.0f, 15000.0f);
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_VIEW, &matLightView);
|
||||
STATEMANAGER.SaveTransform(D3DTS_PROJECTION, &matLightProj);
|
||||
|
||||
dwLightEnable = STATEMANAGER.GetRenderState(D3DRS_LIGHTING);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFF808080);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
|
||||
bool bSuccess = true;
|
||||
|
||||
// Backup Device Context
|
||||
if (FAILED(ms_lpd3dDevice->GetRenderTarget(&m_lpBackupRenderTargetSurface)))
|
||||
{
|
||||
TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Save Window Render Target\n");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->GetDepthStencilSurface(&m_lpBackupDepthSurface)))
|
||||
{
|
||||
TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Save Window Depth Surface\n");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->SetRenderTarget(m_lpCharacterShadowMapRenderTargetSurface, m_lpCharacterShadowMapDepthSurface)))
|
||||
{
|
||||
TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Set Shadow Map Render Target\n");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0xFF, 0xFF, 0xFF), 1.0f, 0)))
|
||||
{
|
||||
TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Clear Render Target");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->GetViewport(&m_BackupViewport)))
|
||||
{
|
||||
TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Save Window Viewport\n");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->SetViewport(&m_ShadowMapViewport)))
|
||||
{
|
||||
TraceError("CMapOutdoor::BeginRenderCharacterShadowToTexture : Unable to Set Shadow Map viewport\n");
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void CMapOutdoor::EndRenderCharacterShadowToTexture()
|
||||
{
|
||||
ms_lpd3dDevice->SetViewport(&m_BackupViewport);
|
||||
|
||||
ms_lpd3dDevice->SetRenderTarget(m_lpBackupRenderTargetSurface, m_lpBackupDepthSurface);
|
||||
|
||||
SAFE_RELEASE(m_lpBackupRenderTargetSurface);
|
||||
SAFE_RELEASE(m_lpBackupDepthSurface);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_VIEW);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_PROJECTION);
|
||||
|
||||
// Restore Device Context
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, dwLightEnable);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
|
||||
void CMapOutdoor::SetIndexBuffer()
|
||||
{
|
||||
void * pIndices;
|
||||
long x, y;
|
||||
|
||||
DWORD dwIndexNum = TERRAIN_PATCHSIZE * TERRAIN_PATCHSIZE * 4;
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
m_pwIndices = new WORD[dwIndexNum];
|
||||
if (!m_pwIndices)
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer is NULL");
|
||||
|
||||
memset(m_pwIndices, 0, sizeof(WORD) * dwIndexNum);
|
||||
if (!m_IndexBuffer.Create(dwIndexNum, D3DFMT_INDEX16))
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error");
|
||||
|
||||
WORD count = 0;
|
||||
WORD count2 = 0;
|
||||
long ry = 0;
|
||||
|
||||
BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1;
|
||||
|
||||
for (y = 0; y < TERRAIN_PATCHSIZE; y++)
|
||||
{
|
||||
if (ry % 2 == 0)
|
||||
{
|
||||
m_pwIndices[count++] = count2;
|
||||
m_pwIndices[count++] = count2+ucNumLineWarp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwIndices[count++] = count2+ucNumLineWarp;
|
||||
m_pwIndices[count++] = count2;
|
||||
}
|
||||
|
||||
for (x = 0; x < TERRAIN_PATCHSIZE; x++)
|
||||
{
|
||||
if (ry % 2 == 1)
|
||||
{
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp-1);
|
||||
m_pwIndices[count++] = (WORD) (count2-1);
|
||||
count2 -= (short) 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwIndices[count++] = (WORD) (count2+1);
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp+1);
|
||||
count2 += (short) 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (y < TERRAIN_PATCHSIZE-1)
|
||||
{
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp);
|
||||
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp);
|
||||
count2 += ucNumLineWarp;
|
||||
}
|
||||
ry++;
|
||||
}
|
||||
|
||||
m_wNumIndices = count;
|
||||
if (!m_IndexBuffer.Lock((void **) &pIndices))
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error");
|
||||
memcpy(pIndices, m_pwIndices, count * sizeof(WORD));
|
||||
m_IndexBuffer.Unlock();
|
||||
|
||||
delete [] m_pwIndices;
|
||||
m_pwIndices = NULL;
|
||||
#else
|
||||
WORD count[TERRAINPATCH_LODMAX], count2[TERRAINPATCH_LODMAX];
|
||||
BYTE uci;
|
||||
for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci)
|
||||
{
|
||||
m_pwaIndices[uci] = new WORD[dwIndexNum];
|
||||
memset(m_pwaIndices[uci], 0, sizeof(WORD) * dwIndexNum);
|
||||
count[uci] = 0;
|
||||
count2[uci] = 0;
|
||||
if ( !m_IndexBuffer[uci].Create(dwIndexNum, D3DFMT_INDEX16) )
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error");
|
||||
}
|
||||
|
||||
BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1;
|
||||
|
||||
for (y = 0; y < TERRAIN_PATCHSIZE; y++)
|
||||
{
|
||||
if (y%2 == 0)
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = count2[0];
|
||||
m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp;
|
||||
m_pwaIndices[0][(count[0])++] = count2[0];
|
||||
}
|
||||
|
||||
for (x = 0; x < TERRAIN_PATCHSIZE; x++)
|
||||
{
|
||||
if (y%2 == 0)
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+1);
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp+1);
|
||||
count2[0] += (short) 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp-1);
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]-1);
|
||||
count2[0] -= (short) 1;
|
||||
}
|
||||
|
||||
if (0 == x%2)
|
||||
{
|
||||
if (0 == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl1TL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == x)
|
||||
ADDLvl1TR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl1T(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
}
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl1BL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == x)
|
||||
ADDLvl1BR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl1B(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
}
|
||||
else if (0 == y%2)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl1L(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 2) == x)
|
||||
ADDLvl1R(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl1M(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
|
||||
}
|
||||
count2[1] += 2;
|
||||
}
|
||||
|
||||
if (0 == x%4)
|
||||
{
|
||||
if (0 == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl2TL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == x)
|
||||
ADDLvl2TR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl2T(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
}
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == y)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl2BL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == x)
|
||||
ADDLvl2BR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl2B(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
}
|
||||
else if (0 == y%4)
|
||||
{
|
||||
if (0 == x)
|
||||
ADDLvl2L(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else if ((TERRAIN_PATCHSIZE - 4) == x)
|
||||
ADDLvl2R(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
else
|
||||
ADDLvl2M(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
|
||||
}
|
||||
count2[2] += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (y < TERRAIN_PATCHSIZE-1)
|
||||
{
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp);
|
||||
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp);
|
||||
count2[0] += ucNumLineWarp;
|
||||
if (0 == y%2)
|
||||
count2[1] += 2;
|
||||
if (0 == y%4)
|
||||
count2[2] += 4;
|
||||
}
|
||||
}
|
||||
|
||||
for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci)
|
||||
{
|
||||
m_wNumIndices[uci] = count[uci];
|
||||
if( !m_IndexBuffer[uci].Lock((void **) &pIndices) )
|
||||
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error");
|
||||
memcpy(pIndices, m_pwaIndices[uci], count[uci] * sizeof(WORD));
|
||||
m_IndexBuffer[uci].Unlock();
|
||||
delete [] m_pwaIndices[uci];
|
||||
m_pwaIndices[uci] = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl1M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1TL(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1TR(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2;
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1BL(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4;
|
||||
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
ADDLvl1M(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
|
||||
ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
|
||||
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
|
||||
ADDLvl1BR(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
|
||||
}
|
||||
|
||||
void CMapOutdoor::ADDLvl2M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
|
||||
{
|
||||
pIndices[rwCount++] = c_rwCurCount;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
|
||||
pIndices[rwCount++] = c_rwCurCount + 4;
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "AreaTerrain.h"
|
||||
#include "AreaLoaderThread.h"
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
//CAreaLoaderThread CMapOutdoor::ms_AreaLoaderThread;
|
||||
|
||||
bool CMapOutdoor::Load(float x, float y, float z)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
CEterPackManager& rkPackMgr=CEterPackManager::Instance();
|
||||
{
|
||||
static std::string s_strOldPathName="";
|
||||
|
||||
// 2004.08.09.myevan.Pack파일을 찾을때.. 폴더명만으로는 그냥 리턴되는 부분이 있다
|
||||
std::string c_rstrNewPathName=GetName()+"\\cache";
|
||||
|
||||
s_strOldPathName=c_rstrNewPathName;
|
||||
}
|
||||
|
||||
std::string strFileName = GetMapDataDirectory() + "\\Setting.txt";
|
||||
|
||||
if (!LoadSetting(strFileName.c_str()))
|
||||
TraceError("CMapOutdoor::Load : LoadSetting(%s) Failed", strFileName.c_str());
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
if (!LoadMonsterAreaInfo())
|
||||
TraceError("CMapOutdoor::Load - LoadMonsterAreaInfo ERROR");
|
||||
#endif
|
||||
|
||||
CreateTerrainPatchProxyList();
|
||||
BuildQuadTree();
|
||||
LoadWaterTexture();
|
||||
CreateCharacterShadowTexture();
|
||||
|
||||
m_lOldReadX = -1;
|
||||
|
||||
// TODO: SetRenderingDevice에서 Environment로 부터 라이트 속성을 넘겨줘야 스태틱 라이트가 제대로 작동한다.
|
||||
CSpeedTreeForestDirectX8::Instance().SetRenderingDevice(ms_lpd3dDevice);
|
||||
|
||||
Update(x, y, z);
|
||||
|
||||
__HeightCache_Init();
|
||||
|
||||
// LOCAL_ENVIRONMENT_DATA
|
||||
std::string local_envDataName = GetMapDataDirectory() + "\\" + m_settings_envDataName;
|
||||
if (rkPackMgr.isExist(local_envDataName.c_str()))
|
||||
{
|
||||
m_envDataName = local_envDataName;
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string& c_rstrEnvironmentRoot = "d:/ymir work/environment/";
|
||||
const std::string& c_rstrMapName = GetName();
|
||||
m_envDataName = c_rstrEnvironmentRoot + m_settings_envDataName;
|
||||
|
||||
if (0 == m_envDataName.compare(c_rstrEnvironmentRoot))
|
||||
{
|
||||
const std::string& strAppendName = c_rstrMapName.substr(c_rstrMapName.size() - 2, 2);
|
||||
m_envDataName = c_rstrEnvironmentRoot + strAppendName + ".msenv";
|
||||
}
|
||||
}
|
||||
// LOCAL_ENVIRONMENT_DATA_END
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string& CMapOutdoor::GetEnvironmentDataName()
|
||||
{
|
||||
return m_envDataName;
|
||||
}
|
||||
|
||||
|
||||
bool CMapOutdoor::isTerrainLoaded(WORD wX, WORD wY)
|
||||
{
|
||||
for (DWORD i = 0; i < m_TerrainVector.size(); ++i)
|
||||
{
|
||||
CTerrain * pTerrain = m_TerrainVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pTerrain->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX == wX && usCoordY == wY)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::isAreaLoaded(WORD wX, WORD wY)
|
||||
{
|
||||
for (DWORD i = 0; i < m_AreaVector.size(); ++i)
|
||||
{
|
||||
CArea * pArea = m_AreaVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pArea->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX == wX && usCoordY == wY)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 현재 좌표를 기반으로 주위(ex. 3x3)에 있는 Terrain과 Area포인터를
|
||||
// m_pTerrain과 m_pArea에 연결한다.
|
||||
void CMapOutdoor::AssignTerrainPtr()
|
||||
{
|
||||
// 월드에디터에서 화면을 죽죽죽 넘길 때 터레인을 저장해야 하기
|
||||
// 때문에 이 virtual method를 호출 한다. 이 메소드는 CMapOutDoor에서는 아무 행동도
|
||||
// 하지 않는다.
|
||||
OnPreAssignTerrainPtr();
|
||||
|
||||
short sReferenceCoordMinX, sReferenceCoordMaxX, sReferenceCoordMinY, sReferenceCoordMaxY;
|
||||
sReferenceCoordMinX = max(m_CurCoordinate.m_sTerrainCoordX - LOAD_SIZE_WIDTH, 0);
|
||||
sReferenceCoordMaxX = min(m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH, m_sTerrainCountX - 1);
|
||||
sReferenceCoordMinY = max(m_CurCoordinate.m_sTerrainCoordY - LOAD_SIZE_WIDTH, 0);
|
||||
sReferenceCoordMaxY = min(m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH, m_sTerrainCountY - 1);
|
||||
|
||||
DWORD i;
|
||||
for (i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
m_pArea[i] = NULL;
|
||||
m_pTerrain[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < m_TerrainVector.size(); ++i)
|
||||
{
|
||||
CTerrain * pTerrain = m_TerrainVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pTerrain->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX >= sReferenceCoordMinX &&
|
||||
usCoordX <= sReferenceCoordMaxX &&
|
||||
usCoordY >= sReferenceCoordMinY &&
|
||||
usCoordY <= sReferenceCoordMaxY)
|
||||
{
|
||||
m_pTerrain[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
|
||||
(usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pTerrain;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < m_AreaVector.size(); ++i)
|
||||
{
|
||||
CArea * pArea = m_AreaVector[i];
|
||||
WORD usCoordX, usCoordY;
|
||||
pArea->GetCoordinate(&usCoordX, &usCoordY);
|
||||
|
||||
if (usCoordX >= sReferenceCoordMinX &&
|
||||
usCoordX <= sReferenceCoordMaxX &&
|
||||
usCoordY >= sReferenceCoordMinY &&
|
||||
usCoordY <= sReferenceCoordMaxY)
|
||||
{
|
||||
m_pArea[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
|
||||
(usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CMapOutdoor::LoadArea(WORD wAreaCoordX, WORD wAreaCoordY, WORD wCellCoordX, WORD wCellCoordY)
|
||||
{
|
||||
if (isAreaLoaded(wAreaCoordX, wAreaCoordY))
|
||||
return true;
|
||||
#ifdef _DEBUG
|
||||
DWORD dwStartTime = ELTimer_GetMSec();
|
||||
#endif
|
||||
unsigned long ulID = (unsigned long) (wAreaCoordX) * 1000L + (unsigned long) (wAreaCoordY);
|
||||
char szAreaPathName[64+1];
|
||||
_snprintf(szAreaPathName, sizeof(szAreaPathName), "%s\\%06u\\", GetMapDataDirectory().c_str(), ulID);
|
||||
|
||||
CArea * pArea = CArea::New();
|
||||
pArea->SetMapOutDoor(this);
|
||||
#ifdef _DEBUG
|
||||
Tracef("CMapOutdoor::LoadArea1 %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
dwStartTime = ELTimer_GetMSec();
|
||||
#endif
|
||||
|
||||
pArea->SetCoordinate(wAreaCoordX, wAreaCoordY);
|
||||
if ( !pArea->Load(szAreaPathName) )
|
||||
TraceError(" CMapOutdoor::LoadArea(%d, %d) LoadShadowMap ERROR", wAreaCoordX, wAreaCoordY);
|
||||
#ifdef _DEBUG
|
||||
Tracef("CMapOutdoor::LoadArea2 %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
dwStartTime = ELTimer_GetMSec();
|
||||
#endif
|
||||
|
||||
m_AreaVector.push_back(pArea);
|
||||
|
||||
pArea->EnablePortal(m_bEnablePortal);
|
||||
#ifdef _DEBUG
|
||||
Tracef("CMapOutdoor::LoadArea3 %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::LoadTerrain(WORD wTerrainCoordX, WORD wTerrainCoordY, WORD wCellCoordX, WORD wCellCoordY)
|
||||
{
|
||||
if (isTerrainLoaded(wTerrainCoordX, wTerrainCoordY))
|
||||
return true;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
DWORD dwStartTime = ELTimer_GetMSec();
|
||||
|
||||
unsigned long ulID = (unsigned long) (wTerrainCoordX) * 1000L + (unsigned long) (wTerrainCoordY);
|
||||
char filename[256];
|
||||
sprintf(filename, "%s\\%06u\\AreaProperty.txt", GetMapDataDirectory().c_str(), ulID);
|
||||
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(filename, stTokenVectorMap))
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty Read Error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 1\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("areaname"))
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 2\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
|
||||
const std::string & c_rstrAreaName = stTokenVectorMap["areaname"][0];
|
||||
|
||||
if (c_rstrType != "AreaProperty")
|
||||
{
|
||||
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 3\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CTerrain * pTerrain = CTerrain::New();
|
||||
|
||||
pTerrain->Clear();
|
||||
pTerrain->SetMapOutDoor(this);
|
||||
|
||||
pTerrain->SetCoordinate(wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
pTerrain->CopySettingFromGlobalSetting();
|
||||
|
||||
char szRawHeightFieldname[64+1];
|
||||
char szWaterMapName[64+1];
|
||||
char szAttrMapName[64+1];
|
||||
char szShadowTexName[64+1];
|
||||
char szShadowMapName[64+1];
|
||||
char szMiniMapTexName[64+1];
|
||||
char szSplatName[64+1];
|
||||
|
||||
_snprintf(szRawHeightFieldname, sizeof(szRawHeightFieldname), "%s\\%06u\\height.raw", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szSplatName, sizeof(szSplatName), "%s\\%06u\\tile.raw", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szAttrMapName, sizeof(szAttrMapName), "%s\\%06u\\attr.atr", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szWaterMapName, sizeof(szWaterMapName), "%s\\%06u\\water.wtr", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szShadowTexName, sizeof(szShadowTexName), "%s\\%06u\\shadowmap.dds", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szShadowMapName, sizeof(szShadowMapName), "%s\\%06u\\shadowmap.raw", GetMapDataDirectory().c_str(), ulID);
|
||||
_snprintf(szMiniMapTexName, sizeof(szMiniMapTexName), "%s\\%06u\\minimap.dds", GetMapDataDirectory().c_str(), ulID);
|
||||
|
||||
if(!pTerrain->LoadWaterMap(szWaterMapName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadWaterMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
if (!pTerrain->LoadHeightMap(szRawHeightFieldname))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadHeightMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
if (!pTerrain->LoadAttrMap(szAttrMapName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadAttrMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
if (!pTerrain->RAW_LoadTileMap(szSplatName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) RAW_LoadTileMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
pTerrain->LoadShadowTexture(szShadowTexName);
|
||||
|
||||
if (!pTerrain->LoadShadowMap(szShadowMapName))
|
||||
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadShadowMap ERROR", wTerrainCoordX, wTerrainCoordY);
|
||||
|
||||
pTerrain->LoadMiniMapTexture(szMiniMapTexName);
|
||||
pTerrain->SetName(c_rstrAreaName.c_str());
|
||||
pTerrain->CalculateTerrainPatch();
|
||||
|
||||
pTerrain->SetReady();
|
||||
|
||||
Tracef("CMapOutdoor::LoadTerrain %d\n", ELTimer_GetMSec() - dwStartTime);
|
||||
|
||||
m_TerrainVector.push_back(pTerrain);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::LoadSetting(const char * c_szFileName)
|
||||
{
|
||||
NANOBEGIN
|
||||
CTokenVectorMap stTokenVectorMap;
|
||||
|
||||
if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LoadMultipleTextData", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'scripttype' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("viewradius"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'viewradius' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("cellscale"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'cellscale' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("heightscale"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'heightscale' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("mapsize"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'mapsize' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() == stTokenVectorMap.find("textureset"))
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'textureset' - FAILED", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("terrainvisible"))
|
||||
{
|
||||
m_bSettingTerrainVisible = (bool) (atoi(stTokenVectorMap["terrainvisible"][0].c_str()) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bSettingTerrainVisible = true;
|
||||
}
|
||||
|
||||
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
|
||||
const std::string & c_rstrViewRadius = stTokenVectorMap["viewradius"][0];
|
||||
//const std::string & c_rstrCellScale = stTokenVectorMap["cellscale"][0];
|
||||
const std::string & c_rstrHeightScale = stTokenVectorMap["heightscale"][0];
|
||||
const std::string & c_rstrMapSizeX = stTokenVectorMap["mapsize"][0];
|
||||
const std::string & c_rstrMapSizeY = stTokenVectorMap["mapsize"][1];
|
||||
|
||||
std::string strTextureSet;
|
||||
TTokenVector & rkVec_strToken = stTokenVectorMap["textureset"];
|
||||
if (!rkVec_strToken.empty())
|
||||
{
|
||||
strTextureSet = rkVec_strToken[0];
|
||||
}
|
||||
|
||||
if (c_rstrType != "MapSetting")
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - Resourse Type ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lViewRadius = atol(c_rstrViewRadius.c_str());
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
m_lViewRadius <<= 1;
|
||||
#endif
|
||||
|
||||
if (0L >= m_lViewRadius)
|
||||
{
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - VIEWRADIUS IS NOT GREATER THAN 0", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_fHeightScale = atof(c_rstrHeightScale.c_str());
|
||||
|
||||
SetTerrainCount(atoi(c_rstrMapSizeX.c_str()), atoi(c_rstrMapSizeY.c_str()));
|
||||
|
||||
m_fTerrainTexCoordBase = 1.0f / (float) (CTerrainImpl::PATCH_XSIZE * CTerrainImpl::CELLSCALE);
|
||||
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("baseposition"))
|
||||
{
|
||||
const std::string & c_rstrMapBaseX = stTokenVectorMap["baseposition"][0];
|
||||
const std::string & c_rstrMapBaseY = stTokenVectorMap["baseposition"][1];
|
||||
SetBaseXY((DWORD)atol(c_rstrMapBaseX.c_str()), (DWORD)atol(c_rstrMapBaseY.c_str()));
|
||||
}
|
||||
|
||||
std::string stTextureSetFileName = strTextureSet;
|
||||
|
||||
// TextureSet 이 이미 붙어 있을 경우 안붙인다.
|
||||
if (0 != stTextureSetFileName.find_first_of("textureset", 0))
|
||||
stTextureSetFileName = "textureset\\"+strTextureSet;
|
||||
|
||||
if (!m_TextureSet.Load(stTextureSetFileName.c_str(), m_fTerrainTexCoordBase))
|
||||
{
|
||||
#ifdef WORLD_EDITOR
|
||||
// TextureSet 이 적용되어 있지 않아도 진행
|
||||
LogBox("TextureSet 이 적용되어있지 않은 맵 입니다.\n지형 텍스춰 작업에 주의하시기 바랍니다.");
|
||||
#else
|
||||
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LOAD TEXTURE SET(%s) ERROR", c_szFileName, stTextureSetFileName.c_str());
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
CTerrain::SetTextureSet(&m_TextureSet);
|
||||
|
||||
if (stTokenVectorMap.end() != stTokenVectorMap.find("environment"))
|
||||
{
|
||||
const CTokenVector & c_rEnvironmentVector = stTokenVectorMap["environment"];
|
||||
if (!c_rEnvironmentVector.empty())
|
||||
m_settings_envDataName = c_rEnvironmentVector[0];
|
||||
else
|
||||
TraceError("CMapOutdoor::LoadSetting(c_szFileName=%s) - Failed to load environment data\n", c_szFileName);
|
||||
}
|
||||
|
||||
m_fWaterTexCoordBase = 1.0f / (float)(CTerrainImpl::CELLSCALE * 4);
|
||||
|
||||
D3DXMatrixScaling(&m_matSplatAlpha,
|
||||
+m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_XSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2),
|
||||
-m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_YSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2),
|
||||
0.0f);
|
||||
m_matSplatAlpha._41 = m_fTerrainTexCoordBase * 4.6f;
|
||||
m_matSplatAlpha._42 = m_fTerrainTexCoordBase * 4.6f;
|
||||
|
||||
D3DXMatrixScaling(&m_matStaticShadow,
|
||||
+m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_XSIZE / static_cast<float>(CTerrainImpl::XSIZE)),
|
||||
-m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_YSIZE / static_cast<float>(CTerrainImpl::XSIZE)),
|
||||
0.0f);
|
||||
m_matStaticShadow._41 = 0.0f;
|
||||
m_matStaticShadow._42 = 0.0f;
|
||||
|
||||
D3DXMatrixScaling(&m_matDynamicShadowScale, 1.0f / 2550.0f, -1.0f / 2550.0f, 1.0f);
|
||||
m_matDynamicShadowScale._41 = 0.5f;
|
||||
m_matDynamicShadowScale._42 = 0.5f;
|
||||
|
||||
// Transform
|
||||
D3DXMatrixScaling(&m_matBuildingTransparent, 1.0f / ((float)ms_iWidth), -1.0f / ((float)ms_iHeight), 1.0f);
|
||||
m_matBuildingTransparent._41 = 0.5f;
|
||||
m_matBuildingTransparent._42 = 0.5f;
|
||||
NANOEND
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CMapOutdoor::LoadMonsterAreaInfo()
|
||||
{
|
||||
RemoveAllMonsterAreaInfo();
|
||||
|
||||
char c_szFileName[256];
|
||||
sprintf(c_szFileName, "%s\\regen.txt", GetMapDataDirectory().c_str());
|
||||
|
||||
LPCVOID pModelData;
|
||||
CMappedFile File;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData))
|
||||
{
|
||||
//TraceError(" CMapOutdoorAccessor::LoadMonsterAreaInfo Load File %s ERROR", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
CTokenVector stTokenVector;
|
||||
|
||||
textFileLoader.Bind(File.Size(), pModelData);
|
||||
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
|
||||
// Start or End
|
||||
if (0 == stTokenVector[0].compare("m") || 0 == stTokenVector[0].compare("g"))
|
||||
{
|
||||
if (stTokenVector.size() < 11)
|
||||
{
|
||||
TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo File Format ERROR! continue....");
|
||||
continue;
|
||||
}
|
||||
|
||||
CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType;
|
||||
if (0 == stTokenVector[0].compare("m"))
|
||||
{
|
||||
eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER;
|
||||
}
|
||||
else if (0 == stTokenVector[0].compare("g"))
|
||||
{
|
||||
eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo Data ERROR! continue....");
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string & c_rstrOriginX = stTokenVector[1].c_str();
|
||||
const std::string & c_rstrOriginY = stTokenVector[2].c_str();
|
||||
const std::string & c_rstrSizeX = stTokenVector[3].c_str();
|
||||
const std::string & c_rstrSizeY = stTokenVector[4].c_str();
|
||||
const std::string & c_rstrZ = stTokenVector[5].c_str();
|
||||
const std::string & c_rstrDir = stTokenVector[6].c_str();
|
||||
const std::string & c_rstrTime = stTokenVector[7].c_str();
|
||||
const std::string & c_rstrPercent = stTokenVector[8].c_str();
|
||||
const std::string & c_rstrCount = stTokenVector[9].c_str();
|
||||
const std::string & c_rstrVID = stTokenVector[10].c_str();
|
||||
|
||||
long lOriginX, lOriginY, lSizeX, lSizeY, lZ, lTime, lPercent;
|
||||
CMonsterAreaInfo::EMonsterDir eMonsterDir;
|
||||
DWORD dwMonsterCount;
|
||||
DWORD dwMonsterVID;
|
||||
|
||||
lOriginX = atol(c_rstrOriginX.c_str());
|
||||
lOriginY = atol(c_rstrOriginY.c_str());
|
||||
lSizeX = atol(c_rstrSizeX.c_str());
|
||||
lSizeY = atol(c_rstrSizeY.c_str());
|
||||
lZ = atol(c_rstrZ.c_str());
|
||||
eMonsterDir = (CMonsterAreaInfo::EMonsterDir) atoi(c_rstrDir.c_str());
|
||||
lTime = atol(c_rstrTime.c_str());
|
||||
lPercent = atol(c_rstrPercent.c_str());
|
||||
dwMonsterCount = (DWORD) atoi(c_rstrCount.c_str());
|
||||
dwMonsterVID = (DWORD) atoi(c_rstrVID.c_str());
|
||||
|
||||
// lOriginX -= m_dwBaseX / 100;
|
||||
// lOriginY -= m_dwBaseY / 100;
|
||||
|
||||
CMonsterAreaInfo * pMonsterAreaInfo = AddMonsterAreaInfo(lOriginX, lOriginY, lSizeX, lSizeY);
|
||||
pMonsterAreaInfo->SetMonsterAreaInfoType(eMonsterAreaInfoType);
|
||||
if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER == eMonsterAreaInfoType)
|
||||
pMonsterAreaInfo->SetMonsterVID(dwMonsterVID);
|
||||
else if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP == eMonsterAreaInfoType)
|
||||
pMonsterAreaInfo->SetMonsterGroupID(dwMonsterVID);
|
||||
pMonsterAreaInfo->SetMonsterCount(dwMonsterCount);
|
||||
pMonsterAreaInfo->SetMonsterDirection(eMonsterDir);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "TerrainQuadtree.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// QuadTree
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMapOutdoor::BuildQuadTree()
|
||||
{
|
||||
FreeQuadTree();
|
||||
|
||||
// m_wPatchCount는 ConvertPatchSplat에서도 정한다, 안전을 위해 여기서 체크한다.
|
||||
if (0 == m_wPatchCount)
|
||||
{
|
||||
TraceError("MapOutdoor::BuildQuadTree : m_wPatchCount is zero, you must call ConvertPatchSplat before call this method.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pRootNode = AllocQuadTreeNode(0, 0, m_wPatchCount - 1, m_wPatchCount - 1);
|
||||
if (!m_pRootNode)
|
||||
TraceError("CMapOutdoor::BuildQuadTree() RootNode is NULL");
|
||||
|
||||
if (m_pRootNode->Size > 1)
|
||||
SubDivideNode(m_pRootNode);
|
||||
}
|
||||
|
||||
CTerrainQuadtreeNode * CMapOutdoor::AllocQuadTreeNode(long x0, long y0, long x1, long y1)
|
||||
{
|
||||
CTerrainQuadtreeNode * Node;
|
||||
long xsize, ysize;
|
||||
|
||||
xsize = x1-x0+1;
|
||||
ysize = y1-y0+1;
|
||||
if ((xsize == 0) || (ysize == 0))
|
||||
return NULL;
|
||||
|
||||
Node = new CTerrainQuadtreeNode;
|
||||
Node->x0 = x0;
|
||||
Node->y0 = y0;
|
||||
Node->x1 = x1;
|
||||
Node->y1 = y1;
|
||||
|
||||
if (ysize > xsize)
|
||||
Node->Size = ysize;
|
||||
else
|
||||
Node->Size = xsize;
|
||||
|
||||
Node->PatchNum = y0 * m_wPatchCount + x0;
|
||||
|
||||
/*
|
||||
const float fTerrainMin = -(float) (m_lViewRadius * m_lCellScale);
|
||||
|
||||
minx = fTerrainMin + x0 * c_byPatchSize * m_lCellScale;
|
||||
maxx = fTerrainMin + (x1 + 1) * c_byPatchSize * m_lCellScale;
|
||||
miny = fTerrainMin + y0 * c_byPatchSize * m_lCellScale;
|
||||
maxy = fTerrainMin + (y1 + 1) * c_byPatchSize * m_lCellScale;
|
||||
minz = 0.0f;
|
||||
maxz = 0.0f;
|
||||
|
||||
/ * Set up 8 vertices that belong to the bounding box * /
|
||||
Node->center.x = minx + (maxx - minx) * 0.5f;
|
||||
Node->center.y = miny + (maxy - miny) * 0.5f;
|
||||
Node->center.z = minz + (maxz - minz) * 0.5f;
|
||||
|
||||
Node->radius = sqrtf(
|
||||
(maxx-minx)*(maxx-minx)+
|
||||
(maxy-miny)*(maxy-miny)+
|
||||
(maxz-minz)*(maxz-minz)
|
||||
)/2.0f;
|
||||
*/
|
||||
|
||||
Node->center.x = 0.0f;
|
||||
Node->center.y = 0.0f;
|
||||
Node->center.z = 0.0f;
|
||||
|
||||
Node->radius = 0.0f;
|
||||
|
||||
return Node;
|
||||
}
|
||||
|
||||
|
||||
void CMapOutdoor::SubDivideNode(CTerrainQuadtreeNode * Node)
|
||||
{
|
||||
long nw_size;
|
||||
CTerrainQuadtreeNode * tempnode;
|
||||
|
||||
nw_size = Node->Size / 2;
|
||||
|
||||
Node->NW_Node = AllocQuadTreeNode (Node->x0, Node->y0, Node->x0 + nw_size-1, Node->y0 + nw_size-1);
|
||||
Node->NE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0, Node->x1, Node->y0 + nw_size-1);
|
||||
Node->SW_Node = AllocQuadTreeNode (Node->x0, Node->y0 + nw_size, Node->x0 + nw_size-1, Node->y1);
|
||||
Node->SE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0 + nw_size, Node->x1, Node->y1);
|
||||
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->NW_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->NE_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->SW_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
tempnode = (CTerrainQuadtreeNode *) Node->SE_Node;
|
||||
if ((tempnode != NULL) && (tempnode->Size > 1))
|
||||
SubDivideNode (tempnode);
|
||||
}
|
||||
|
||||
/*
|
||||
void CMapOutdoor::RecurseDeleteQuadTree(CTerrainQuadtreeNode *Node)
|
||||
{
|
||||
if (Node == NULL)
|
||||
return;
|
||||
|
||||
if (Node->NW_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->NW_Node);
|
||||
Node->NW_Node = NULL;
|
||||
}
|
||||
if (Node->NE_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->NE_Node);
|
||||
Node->NE_Node = NULL;
|
||||
}
|
||||
if (Node->SW_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->SW_Node);
|
||||
Node->SW_Node = NULL;
|
||||
}
|
||||
if (Node->SE_Node != NULL)
|
||||
{
|
||||
RecurseDeleteQuadTree(Node->SE_Node);
|
||||
Node->SE_Node = NULL;
|
||||
}
|
||||
|
||||
free(Node);
|
||||
}
|
||||
*/
|
||||
|
||||
void CMapOutdoor::FreeQuadTree()
|
||||
{
|
||||
if (NULL == m_pRootNode)
|
||||
return;
|
||||
|
||||
if (m_pRootNode->NW_Node)
|
||||
{
|
||||
delete m_pRootNode->NW_Node;
|
||||
m_pRootNode->NW_Node = NULL;
|
||||
}
|
||||
if (m_pRootNode->NE_Node)
|
||||
{
|
||||
delete m_pRootNode->NE_Node;
|
||||
m_pRootNode->NE_Node = NULL;
|
||||
}
|
||||
if (m_pRootNode->SW_Node)
|
||||
{
|
||||
delete m_pRootNode->SW_Node;
|
||||
m_pRootNode->SW_Node = NULL;
|
||||
}
|
||||
if (m_pRootNode->SE_Node)
|
||||
{
|
||||
delete m_pRootNode->SE_Node;
|
||||
m_pRootNode->SE_Node = NULL;
|
||||
}
|
||||
|
||||
delete m_pRootNode;
|
||||
m_pRootNode = NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,964 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "TerrainPatch.h"
|
||||
#include "AreaTerrain.h"
|
||||
#include "TerrainQuadtree.h"
|
||||
|
||||
#include "../eterlib/Camera.h"
|
||||
#include "../eterlib/StateManager.h"
|
||||
|
||||
|
||||
#define MAX_RENDER_SPALT 150
|
||||
|
||||
CArea::TCRCWithNumberVector m_dwRenderedCRCWithNumberVector;
|
||||
|
||||
CMapOutdoor::TTerrainNumVector CMapOutdoor::FSortPatchDrawStructWithTerrainNum::m_TerrainNumVector;
|
||||
|
||||
void CMapOutdoor::RenderTerrain()
|
||||
{
|
||||
if (!IsVisiblePart(PART_TERRAIN))
|
||||
return;
|
||||
|
||||
if (!m_bSettingTerrainVisible)
|
||||
return;
|
||||
|
||||
// Inserted by levites
|
||||
if (!m_pTerrainPatchProxyList)
|
||||
return;
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
auto vv = ms_matView * ms_matProj;
|
||||
BuildViewFrustum(vv);
|
||||
|
||||
D3DXVECTOR3 v3Eye = pCamera->GetEye();
|
||||
m_fXforDistanceCaculation = -v3Eye.x;
|
||||
m_fYforDistanceCaculation = -v3Eye.y;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Push
|
||||
m_PatchVector.clear();
|
||||
|
||||
__RenderTerrain_RecurseRenderQuadTree(m_pRootNode);
|
||||
|
||||
// 거리순 정렬
|
||||
std::sort(m_PatchVector.begin(),m_PatchVector.end());
|
||||
|
||||
// 그리기 위한 벡터 세팅
|
||||
if (CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE)
|
||||
__RenderTerrain_RenderSoftwareTransformPatch();
|
||||
else
|
||||
__RenderTerrain_RenderHardwareTransformPatch();
|
||||
}
|
||||
|
||||
void CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree(CTerrainQuadtreeNode *Node, bool bCullCheckNeed)
|
||||
{
|
||||
if (bCullCheckNeed)
|
||||
{
|
||||
switch (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius))
|
||||
{
|
||||
case VIEW_ALL:
|
||||
// all child nodes need not cull check
|
||||
bCullCheckNeed = false;
|
||||
break;
|
||||
case VIEW_PART:
|
||||
break;
|
||||
case VIEW_NONE:
|
||||
// no need to render
|
||||
return;
|
||||
}
|
||||
// if no need cull check more
|
||||
// -> bCullCheckNeed = false;
|
||||
}
|
||||
|
||||
if (Node->Size == 1)
|
||||
{
|
||||
D3DXVECTOR3 v3Center = Node->center;
|
||||
float fDistance = fMAX(fabs(v3Center.x + m_fXforDistanceCaculation), fabs(-v3Center.y + m_fYforDistanceCaculation));
|
||||
__RenderTerrain_AppendPatch(v3Center, fDistance, Node->PatchNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Node->NW_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->NW_Node, bCullCheckNeed);
|
||||
if (Node->NE_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->NE_Node, bCullCheckNeed);
|
||||
if (Node->SW_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->SW_Node, bCullCheckNeed);
|
||||
if (Node->SE_Node != NULL)
|
||||
__RenderTerrain_RecurseRenderQuadTree(Node->SE_Node, bCullCheckNeed);
|
||||
}
|
||||
}
|
||||
|
||||
int CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(const D3DXVECTOR3 & c_v3Center, const float & c_fRadius)
|
||||
{
|
||||
const int count = 6;
|
||||
|
||||
D3DXVECTOR3 center = c_v3Center;
|
||||
center.y = -center.y;
|
||||
|
||||
int i;
|
||||
|
||||
float distance[count];
|
||||
for(i = 0; i < count; ++i)
|
||||
{
|
||||
distance[i] = D3DXPlaneDotCoord(&m_plane[i], ¢er);
|
||||
if (distance[i] <= -c_fRadius)
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
for(i = 0; i < count;++i)
|
||||
{
|
||||
if (distance[i] <= c_fRadius)
|
||||
return VIEW_PART;
|
||||
}
|
||||
|
||||
return VIEW_ALL;
|
||||
}
|
||||
|
||||
void CMapOutdoor::__RenderTerrain_AppendPatch(const D3DXVECTOR3& c_rv3Center, float fDistance, long lPatchNum)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__RenderTerrain_AppendPatch");
|
||||
if (!m_pTerrainPatchProxyList[lPatchNum].isUsed())
|
||||
return;
|
||||
|
||||
m_pTerrainPatchProxyList[lPatchNum].SetCenterPosition(c_rv3Center);
|
||||
m_PatchVector.push_back(std::make_pair(fDistance, lPatchNum));
|
||||
}
|
||||
|
||||
void CMapOutdoor::ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight)
|
||||
{
|
||||
m_kSTPD.m_dwLightVersion=dwVersion;
|
||||
STATEMANAGER.SetLight(0, &c_rkLight);
|
||||
}
|
||||
|
||||
// 2004. 2. 17. myevan. 모든 부분을 보이게 초기화 한다
|
||||
void CMapOutdoor::InitializeVisibleParts()
|
||||
{
|
||||
m_dwVisiblePartFlags=0xffffffff;
|
||||
}
|
||||
|
||||
// 2004. 2. 17. myevan. 특정 부분을 보이게 하거나 감추는 함수
|
||||
void CMapOutdoor::SetVisiblePart(int ePart, bool isVisible)
|
||||
{
|
||||
DWORD dwMask=(1<<ePart);
|
||||
if (isVisible)
|
||||
{
|
||||
m_dwVisiblePartFlags|=dwMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwReverseMask=~dwMask;
|
||||
m_dwVisiblePartFlags&=dwReverseMask;
|
||||
}
|
||||
}
|
||||
|
||||
// 2004. 2. 17. myevan. 특정 부분이 보이는지 알아내는 함수
|
||||
bool CMapOutdoor::IsVisiblePart(int ePart)
|
||||
{
|
||||
DWORD dwMask=(1<<ePart);
|
||||
if (dwMask & m_dwVisiblePartFlags)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Splat 개수 제한
|
||||
void CMapOutdoor::SetSplatLimit(int iSplatNum)
|
||||
{
|
||||
m_iSplatLimit = iSplatNum;
|
||||
}
|
||||
|
||||
std::vector<int> & CMapOutdoor::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio)
|
||||
{
|
||||
*piPatch = m_iRenderedPatchNum;
|
||||
*piSplat = m_iRenderedSplatNum;
|
||||
*pfSplatRatio = m_iRenderedSplatNumSqSum/float(m_iRenderedPatchNum);
|
||||
|
||||
return m_RenderedTextureNumVector;
|
||||
}
|
||||
|
||||
CArea::TCRCWithNumberVector & CMapOutdoor::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum)
|
||||
{
|
||||
*pdwGraphicThingInstanceNum = m_dwRenderedGraphicThingInstanceNum;
|
||||
*pdwCRCNum = m_dwRenderedCRCNum;
|
||||
|
||||
return m_dwRenderedCRCWithNumberVector;
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderBeforeLensFlare()
|
||||
{
|
||||
m_LensFlare.DrawBeforeFlare();
|
||||
|
||||
if (!mc_pEnvironmentData)
|
||||
{
|
||||
TraceError("CMapOutdoor::RenderBeforeLensFlare mc_pEnvironmentData is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
m_LensFlare.Compute(mc_pEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction);
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderAfterLensFlare()
|
||||
{
|
||||
m_LensFlare.AdjustBrightness();
|
||||
m_LensFlare.DrawFlare();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderCollision()
|
||||
{
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
pArea->RenderCollision();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderScreenFiltering()
|
||||
{
|
||||
m_ScreenFilter.Render();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderSky()
|
||||
{
|
||||
if (IsVisiblePart(PART_SKY))
|
||||
m_SkyBox.Render();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderCloud()
|
||||
{
|
||||
if (IsVisiblePart(PART_CLOUD))
|
||||
m_SkyBox.RenderCloud();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderTree()
|
||||
{
|
||||
if (IsVisiblePart(PART_TREE))
|
||||
CSpeedTreeForestDirectX8::Instance().Render();
|
||||
}
|
||||
|
||||
void CMapOutdoor::SetInverseViewAndDynamicShaodwMatrices()
|
||||
{
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
m_matViewInverse = pCamera->GetInverseViewMatrix();
|
||||
|
||||
D3DXVECTOR3 v3Target = pCamera->GetTarget();
|
||||
|
||||
D3DXVECTOR3 v3LightEye(v3Target.x - 1.732f * 1250.0f,
|
||||
v3Target.y - 1250.0f,
|
||||
v3Target.z + 2.0f * 1.732f * 1250.0f);
|
||||
|
||||
const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
D3DXMatrixLookAtRH(&m_matLightView, &v3LightEye, &v3Target, &vv);
|
||||
m_matDynamicShadow = m_matViewInverse * m_matLightView * m_matDynamicShadowScale;
|
||||
}
|
||||
|
||||
void CMapOutdoor::OnRender()
|
||||
{
|
||||
#ifdef __PERFORMANCE_CHECKER__
|
||||
DWORD t1=ELTimer_GetMSec();
|
||||
SetInverseViewAndDynamicShaodwMatrices();
|
||||
|
||||
SetBlendOperation();
|
||||
DWORD t2=ELTimer_GetMSec();
|
||||
RenderArea();
|
||||
DWORD t3=ELTimer_GetMSec();
|
||||
if (!m_bEnableTerrainOnlyForHeight)
|
||||
RenderTerrain();
|
||||
DWORD t4=ELTimer_GetMSec();
|
||||
RenderTree();
|
||||
DWORD t5=ELTimer_GetMSec();
|
||||
DWORD tEnd=ELTimer_GetMSec();
|
||||
|
||||
if (tEnd-t1<7)
|
||||
return;
|
||||
|
||||
static FILE* fp=fopen("perf_map_render.txt", "w");
|
||||
fprintf(fp, "MAP.Total %d (Time %d)\n", tEnd-t1, ELTimer_GetMSec());
|
||||
fprintf(fp, "MAP.ENV %d\n", t2-t1);
|
||||
fprintf(fp, "MAP.OBJ %d\n", t3-t2);
|
||||
fprintf(fp, "MAP.TRN %d\n", t4-t3);
|
||||
fprintf(fp, "MAP.TRE %d\n", t5-t4);
|
||||
|
||||
#else
|
||||
SetInverseViewAndDynamicShaodwMatrices();
|
||||
|
||||
SetBlendOperation();
|
||||
RenderArea();
|
||||
RenderTree();
|
||||
if (!m_bEnableTerrainOnlyForHeight)
|
||||
RenderTerrain();
|
||||
RenderBlendArea();
|
||||
#endif
|
||||
}
|
||||
|
||||
struct FAreaRenderShadow
|
||||
{
|
||||
void operator () (CGraphicObjectInstance * pInstance)
|
||||
{
|
||||
pInstance->RenderShadow();
|
||||
pInstance->Hide();
|
||||
}
|
||||
};
|
||||
|
||||
struct FPCBlockerHide
|
||||
{
|
||||
void operator () (CGraphicObjectInstance * pInstance)
|
||||
{
|
||||
pInstance->Hide();
|
||||
}
|
||||
};
|
||||
|
||||
struct FRenderPCBlocker
|
||||
{
|
||||
void operator () (CGraphicObjectInstance * pInstance)
|
||||
{
|
||||
pInstance->Show();
|
||||
CGraphicThingInstance* pThingInstance = dynamic_cast <CGraphicThingInstance*> (pInstance);
|
||||
if (pThingInstance != NULL)
|
||||
{
|
||||
if (pThingInstance->HaveBlendThing())
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
pThingInstance->BlendRender();
|
||||
return;
|
||||
}
|
||||
}
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
pInstance->RenderPCBlocker();
|
||||
}
|
||||
};
|
||||
|
||||
void CMapOutdoor::RenderEffect()
|
||||
{
|
||||
if (!IsVisiblePart(PART_OBJECT))
|
||||
return;
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->RenderEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CMapOutdoor_LessThingInstancePtrRenderOrder
|
||||
{
|
||||
bool operator() (CGraphicThingInstance* pkLeft, CGraphicThingInstance* pkRight)
|
||||
{
|
||||
//TODO : Camera위치기반으로 소팅
|
||||
CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
const D3DXVECTOR3 & c_rv3CameraPos = pCurrentCamera->GetEye();
|
||||
const D3DXVECTOR3 & c_v3LeftPos = pkLeft->GetPosition();
|
||||
const D3DXVECTOR3 & c_v3RightPos = pkRight->GetPosition();
|
||||
const auto vv = D3DXVECTOR3(c_rv3CameraPos - c_v3RightPos);
|
||||
const auto vv2 = D3DXVECTOR3(c_rv3CameraPos - c_v3LeftPos);
|
||||
|
||||
return D3DXVec3LengthSq(&vv2) < D3DXVec3LengthSq(&vv);
|
||||
}
|
||||
};
|
||||
|
||||
struct CMapOutdoor_FOpaqueThingInstanceRender
|
||||
{
|
||||
inline void operator () (CGraphicThingInstance * pkThingInst)
|
||||
{
|
||||
pkThingInst->Render();
|
||||
}
|
||||
};
|
||||
struct CMapOutdoor_FBlendThingInstanceRender
|
||||
{
|
||||
inline void operator () (CGraphicThingInstance * pkThingInst)
|
||||
{
|
||||
pkThingInst->BlendRender();
|
||||
}
|
||||
};
|
||||
|
||||
void CMapOutdoor::RenderArea(bool bRenderAmbience)
|
||||
{
|
||||
if (!IsVisiblePart(PART_OBJECT))
|
||||
return;
|
||||
|
||||
m_dwRenderedCRCNum = 0;
|
||||
m_dwRenderedGraphicThingInstanceNum = 0;
|
||||
m_dwRenderedCRCWithNumberVector.clear();
|
||||
|
||||
// NOTE - 20041201.levites.던젼 그림자 추가
|
||||
for (int j = 0; j < AROUND_AREA_NUM; ++j)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(j, &pArea))
|
||||
{
|
||||
pArea->RenderDungeon();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WORLD_EDITOR
|
||||
// PCBlocker
|
||||
std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FPCBlockerHide());
|
||||
|
||||
// Shadow Receiver
|
||||
if (m_bDrawShadow && m_bDrawChrShadow)
|
||||
{
|
||||
if (mc_pEnvironmentData != NULL)
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
// Transform
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow);
|
||||
STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF);
|
||||
|
||||
std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow());
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
if (mc_pEnvironmentData != NULL)
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, mc_pEnvironmentData->FogColor);
|
||||
}
|
||||
#endif
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
||||
|
||||
bool m_isDisableSortRendering=false;
|
||||
|
||||
if (m_isDisableSortRendering)
|
||||
{
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->Render();
|
||||
|
||||
m_dwRenderedCRCNum += pArea->DEBUG_GetRenderedCRCNum();
|
||||
m_dwRenderedGraphicThingInstanceNum += pArea->DEBUG_GetRenderedGrapphicThingInstanceNum();
|
||||
|
||||
CArea::TCRCWithNumberVector & rCRCWithNumberVector = pArea->DEBUG_GetRenderedCRCWithNumVector();
|
||||
|
||||
CArea::TCRCWithNumberVector::iterator aIterator = rCRCWithNumberVector.begin();
|
||||
while (aIterator != rCRCWithNumberVector.end())
|
||||
{
|
||||
DWORD dwCRC = (*aIterator++).dwCRC;
|
||||
|
||||
CArea::TCRCWithNumberVector::iterator aCRCWithNumberVectorIterator =
|
||||
std::find_if(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::FFindIfCRC(dwCRC));
|
||||
|
||||
if ( m_dwRenderedCRCWithNumberVector.end() == aCRCWithNumberVectorIterator)
|
||||
{
|
||||
CArea::TCRCWithNumber aCRCWithNumber;
|
||||
aCRCWithNumber.dwCRC = dwCRC;
|
||||
aCRCWithNumber.dwNumber = 1;
|
||||
m_dwRenderedCRCWithNumberVector.push_back(aCRCWithNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
CArea::TCRCWithNumber & rCRCWithNumber = *aCRCWithNumberVectorIterator;
|
||||
rCRCWithNumber.dwNumber += 1;
|
||||
}
|
||||
}
|
||||
#ifdef WORLD_EDITOR
|
||||
if (bRenderAmbience)
|
||||
pArea->RenderAmbience();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::CRCNumComp());
|
||||
}
|
||||
else
|
||||
{
|
||||
static std::vector<CGraphicThingInstance*> s_kVct_pkOpaqueThingInstSort;
|
||||
s_kVct_pkOpaqueThingInstSort.clear();
|
||||
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->CollectRenderingObject(s_kVct_pkOpaqueThingInstSort);
|
||||
#ifdef WORLD_EDITOR
|
||||
if (bRenderAmbience)
|
||||
pArea->RenderAmbience();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::sort(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder());
|
||||
std::for_each(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_FOpaqueThingInstanceRender());
|
||||
}
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
|
||||
#ifndef WORLD_EDITOR
|
||||
// Shadow Receiver
|
||||
if (m_bDrawShadow && m_bDrawChrShadow)
|
||||
{
|
||||
std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), std::mem_fn(&CGraphicObjectInstance::Show));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderBlendArea()
|
||||
{
|
||||
if (!IsVisiblePart(PART_OBJECT))
|
||||
return;
|
||||
|
||||
static std::vector<CGraphicThingInstance*> s_kVct_pkBlendThingInstSort;
|
||||
s_kVct_pkBlendThingInstSort.clear();
|
||||
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (GetAreaPointer(i, &pArea))
|
||||
{
|
||||
pArea->CollectBlendRenderingObject(s_kVct_pkBlendThingInstSort);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_kVct_pkBlendThingInstSort.size() != 0)
|
||||
{
|
||||
|
||||
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
//// Transform
|
||||
//STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow);
|
||||
//STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
|
||||
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
//STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF);
|
||||
|
||||
////std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow());
|
||||
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR);
|
||||
|
||||
//STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
|
||||
std::sort(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder());
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
std::for_each(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_FBlendThingInstanceRender());
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
}
|
||||
}
|
||||
void CMapOutdoor::RenderDungeon()
|
||||
{
|
||||
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
||||
{
|
||||
CArea * pArea;
|
||||
if (!GetAreaPointer(i, &pArea))
|
||||
continue;
|
||||
pArea->RenderDungeon();
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderPCBlocker()
|
||||
{
|
||||
#ifndef WORLD_EDITOR
|
||||
// PCBlocker
|
||||
if (m_PCBlockerVector.size() != 0)
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matBuildingTransparent);
|
||||
STATEMANAGER.SetTexture(1, m_BuildingTransparentImageInstance.GetTexturePointer()->GetD3DTexture());
|
||||
|
||||
std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FRenderPCBlocker());
|
||||
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::SelectIndexBuffer(BYTE byLODLevel, WORD * pwPrimitiveCount, D3DPRIMITIVETYPE * pePrimitiveType)
|
||||
{
|
||||
#ifdef WORLD_EDITOR
|
||||
*pwPrimitiveCount = m_wNumIndices - 2;
|
||||
*pePrimitiveType = D3DPT_TRIANGLESTRIP;
|
||||
STATEMANAGER.SetIndices(m_IndexBuffer.GetD3DIndexBuffer(), 0);
|
||||
#else
|
||||
if (0 == byLODLevel)
|
||||
{
|
||||
*pwPrimitiveCount = m_wNumIndices[byLODLevel] - 2;
|
||||
*pePrimitiveType = D3DPT_TRIANGLESTRIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pwPrimitiveCount = m_wNumIndices[byLODLevel]/3;
|
||||
*pePrimitiveType = D3DPT_TRIANGLELIST;
|
||||
}
|
||||
STATEMANAGER.SetIndices(m_IndexBuffer[byLODLevel].GetD3DIndexBuffer(), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMapOutdoor::SetPatchDrawVector()
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SetPatchDrawVector");
|
||||
|
||||
m_PatchDrawStructVector.clear();
|
||||
|
||||
std::vector<std::pair<float, long> >::iterator aDistancePatchVectorIterator;
|
||||
|
||||
TPatchDrawStruct aPatchDrawStruct;
|
||||
|
||||
aDistancePatchVectorIterator = m_PatchVector.begin();
|
||||
while(aDistancePatchVectorIterator != m_PatchVector.end())
|
||||
{
|
||||
std::pair<float, long> adistancePatchPair = *aDistancePatchVectorIterator;
|
||||
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[adistancePatchPair.second];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
long lPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (lPatchNum < 0)
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
BYTE byTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == byTerrainNum)
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
CTerrain * pTerrain;
|
||||
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
||||
{
|
||||
++aDistancePatchVectorIterator;
|
||||
continue;
|
||||
}
|
||||
|
||||
aPatchDrawStruct.fDistance = adistancePatchPair.first;
|
||||
aPatchDrawStruct.byTerrainNum = byTerrainNum;
|
||||
aPatchDrawStruct.lPatchNum = lPatchNum;
|
||||
aPatchDrawStruct.pTerrainPatchProxy = pTerrainPatchProxy;
|
||||
|
||||
m_PatchDrawStructVector.push_back(aPatchDrawStruct);
|
||||
|
||||
++aDistancePatchVectorIterator;
|
||||
}
|
||||
|
||||
std::stable_sort(m_PatchDrawStructVector.begin(), m_PatchDrawStructVector.end(), FSortPatchDrawStructWithTerrainNum());
|
||||
}
|
||||
|
||||
float CMapOutdoor::__GetNoFogDistance()
|
||||
{
|
||||
return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.5f;
|
||||
}
|
||||
|
||||
float CMapOutdoor::__GetFogDistance()
|
||||
{
|
||||
return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.75f;
|
||||
}
|
||||
|
||||
struct FPatchNumMatch
|
||||
{
|
||||
long m_lPatchNumToCheck;
|
||||
FPatchNumMatch(long lPatchNum)
|
||||
{
|
||||
m_lPatchNumToCheck = lPatchNum;
|
||||
}
|
||||
bool operator() (std::pair<long, BYTE> aPair)
|
||||
{
|
||||
return m_lPatchNumToCheck == aPair.first;
|
||||
}
|
||||
};
|
||||
|
||||
void CMapOutdoor::NEW_DrawWireFrame(CTerrainPatchProxy * pTerrainPatchProxy, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
|
||||
{
|
||||
DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
||||
|
||||
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
}
|
||||
|
||||
void CMapOutdoor::DrawWireFrame(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::DrawWireFrame");
|
||||
|
||||
CTerrainPatchProxy * pTerrainPatchProxy= &m_pTerrainPatchProxyList[patchnum];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (sPatchNum < 0)
|
||||
return;
|
||||
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == ucTerrainNum)
|
||||
return;
|
||||
|
||||
DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
||||
|
||||
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
}
|
||||
|
||||
// Attr
|
||||
void CMapOutdoor::RenderMarkedArea()
|
||||
{
|
||||
if (!m_pTerrainPatchProxyList)
|
||||
return;
|
||||
|
||||
m_matWorldForCommonUse._41 = 0.0f;
|
||||
m_matWorldForCommonUse._42 = 0.0f;
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse);
|
||||
|
||||
WORD wPrimitiveCount;
|
||||
D3DPRIMITIVETYPE eType;
|
||||
SelectIndexBuffer(0, &wPrimitiveCount, &eType);
|
||||
|
||||
D3DXMATRIX matTexTransform, matTexTransformTemp;
|
||||
|
||||
D3DXMatrixScaling(&matTexTransform, m_fTerrainTexCoordBase * 32.0f, -m_fTerrainTexCoordBase * 32.0f, 0.0f);
|
||||
D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &matTexTransform);
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransform);
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &matTexTransform);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
static long lStartTime = timeGetTime();
|
||||
float fTime = float((timeGetTime() - lStartTime)%3000) / 3000.0f;
|
||||
float fAlpha = fabs(fTime - 0.5f) / 2.0f + 0.1f;
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, fAlpha));
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
STATEMANAGER.SetTexture(0, m_attrImageInstance.GetTexturePointer()->GetD3DTexture());
|
||||
|
||||
RecurseRenderAttr(m_pRootNode);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MINFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MAGFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MIPFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
}
|
||||
|
||||
void CMapOutdoor::RecurseRenderAttr(CTerrainQuadtreeNode *Node, bool bCullEnable)
|
||||
{
|
||||
if (bCullEnable)
|
||||
{
|
||||
if (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius)==VIEW_NONE)
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
if (Node->Size == 1)
|
||||
{
|
||||
DrawPatchAttr(Node->PatchNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Node->NW_Node != NULL)
|
||||
RecurseRenderAttr(Node->NW_Node, bCullEnable);
|
||||
if (Node->NE_Node != NULL)
|
||||
RecurseRenderAttr(Node->NE_Node, bCullEnable);
|
||||
if (Node->SW_Node != NULL)
|
||||
RecurseRenderAttr(Node->SW_Node, bCullEnable);
|
||||
if (Node->SE_Node != NULL)
|
||||
RecurseRenderAttr(Node->SE_Node, bCullEnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::DrawPatchAttr(long patchnum)
|
||||
{
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum];
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (sPatchNum < 0)
|
||||
return;
|
||||
|
||||
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == ucTerrainNum)
|
||||
return;
|
||||
|
||||
// Deal with this material buffer
|
||||
CTerrain * pTerrain;
|
||||
if (!GetTerrainPointer(ucTerrainNum, &pTerrain))
|
||||
return;
|
||||
|
||||
if (!pTerrain->IsMarked())
|
||||
return;
|
||||
|
||||
WORD wCoordX, wCoordY;
|
||||
pTerrain->GetCoordinate(&wCoordX, &wCoordY);
|
||||
|
||||
m_matWorldForCommonUse._41 = -(float) (wCoordX * CTerrainImpl::XSIZE * CTerrainImpl::CELLSCALE);
|
||||
m_matWorldForCommonUse._42 = (float) (wCoordY * CTerrainImpl::YSIZE * CTerrainImpl::CELLSCALE);
|
||||
|
||||
D3DXMATRIX matTexTransform, matTexTransformTemp;
|
||||
D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &m_matWorldForCommonUse);
|
||||
D3DXMatrixMultiply(&matTexTransform, &matTexTransform, &m_matStaticShadow);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matTexTransform);
|
||||
|
||||
TTerrainSplatPatch & rAttrSplatPatch = pTerrain->GetMarkedSplatPatch();
|
||||
STATEMANAGER.SetTexture(1, rAttrSplatPatch.Splats[0].pd3dTexture);
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL);
|
||||
STATEMANAGER.SetStreamSource(0, pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr()->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize);
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices - 2);
|
||||
#else
|
||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices[0] - 2);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,696 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
|
||||
#include "../eterlib/StateManager.h"
|
||||
|
||||
void CMapOutdoor::__RenderTerrain_RenderHardwareTransformPatch()
|
||||
{
|
||||
DWORD dwFogColor;
|
||||
float fFogFarDistance;
|
||||
float fFogNearDistance;
|
||||
if (mc_pEnvironmentData)
|
||||
{
|
||||
dwFogColor=mc_pEnvironmentData->FogColor;
|
||||
fFogNearDistance=mc_pEnvironmentData->GetFogNearDistance();
|
||||
fFogFarDistance=mc_pEnvironmentData->GetFogFarDistance();
|
||||
}
|
||||
else
|
||||
{
|
||||
dwFogColor=0xffffffff;
|
||||
fFogNearDistance=5000.0f;
|
||||
fFogFarDistance=10000.0f;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Render State & TextureStageState
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, dwFogColor);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
if (GetAsyncKeyState(VK_CAPITAL))
|
||||
{
|
||||
CSpeedTreeWrapper::ms_bSelfShadowOn = false;
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_GAUSSIANCUBIC);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_GAUSSIANCUBIC);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_GAUSSIANCUBIC);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_GAUSSIANCUBIC);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_GAUSSIANCUBIC);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_GAUSSIANCUBIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSpeedTreeWrapper::ms_bSelfShadowOn = true;
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
#else
|
||||
CSpeedTreeWrapper::ms_bSelfShadowOn = true;
|
||||
STATEMANAGER.SetBestFiltering(0);
|
||||
STATEMANAGER.SetBestFiltering(1);
|
||||
#endif
|
||||
|
||||
m_matWorldForCommonUse._41 = 0.0f;
|
||||
m_matWorldForCommonUse._42 = 0.0f;
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse);
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &m_matWorldForCommonUse);
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matWorldForCommonUse);
|
||||
|
||||
// Render State & TextureStageState
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL);
|
||||
|
||||
m_iRenderedSplatNumSqSum = 0;
|
||||
m_iRenderedPatchNum = 0;
|
||||
m_iRenderedSplatNum = 0;
|
||||
m_RenderedTextureNumVector.clear();
|
||||
|
||||
std::pair<float, long> fog_far(fFogFarDistance+1600.0f, 0);
|
||||
std::pair<float, long> fog_near(fFogNearDistance-3200.0f, 0);
|
||||
|
||||
std::vector<std::pair<float ,long> >::iterator far_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_far);
|
||||
std::vector<std::pair<float ,long> >::iterator near_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_near);
|
||||
|
||||
// NOTE: Word Editor 툴에서는 fog far보다 멀리있는 물체를 텍스쳐 없이 그리는 작업을 하지 않음
|
||||
#ifdef WORLD_EDITOR
|
||||
near_it = m_PatchVector.begin();
|
||||
far_it = m_PatchVector.end();
|
||||
#endif
|
||||
|
||||
WORD wPrimitiveCount;
|
||||
D3DPRIMITIVETYPE ePrimitiveType;
|
||||
|
||||
BYTE byCUrrentLODLevel = 0;
|
||||
|
||||
float fLODLevel1Distance = __GetNoFogDistance();
|
||||
float fLODLevel2Distance = __GetFogDistance();
|
||||
|
||||
SelectIndexBuffer(0, &wPrimitiveCount, &ePrimitiveType);
|
||||
|
||||
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
|
||||
std::vector<std::pair<float, long> >::iterator it = m_PatchVector.begin();
|
||||
|
||||
// NOTE: 맵툴에서는 view ~ fog near 사이의 지형을 fog disabled 상태로 그리는 작업을 하지 않음.
|
||||
#ifndef WORLD_EDITOR
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
|
||||
for( ; it != near_it; ++it)
|
||||
{
|
||||
if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 1;
|
||||
SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 2;
|
||||
SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
|
||||
__HardwareTransformPatch_RenderPatchSplat(it->second, wPrimitiveCount, ePrimitiveType);
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
if (m_bDrawWireFrame)
|
||||
DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType);
|
||||
}
|
||||
#endif
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
|
||||
|
||||
if (m_iRenderedSplatNum < m_iSplatLimit)
|
||||
{
|
||||
for(it = near_it; it != far_it; ++it)
|
||||
{
|
||||
if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 1;
|
||||
SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 2;
|
||||
SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
|
||||
__HardwareTransformPatch_RenderPatchSplat(it->second, wPrimitiveCount, ePrimitiveType);
|
||||
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
if (m_bDrawWireFrame)
|
||||
DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType);
|
||||
}
|
||||
}
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, FALSE);
|
||||
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, FALSE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
if (m_iRenderedSplatNum < m_iSplatLimit)
|
||||
{
|
||||
for(it = far_it; it != m_PatchVector.end(); ++it)
|
||||
{
|
||||
if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 1;
|
||||
SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 2;
|
||||
SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
|
||||
__HardwareTransformPatch_RenderPatchNone(it->second, wPrimitiveCount, ePrimitiveType);
|
||||
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
if (m_bDrawWireFrame)
|
||||
DrawWireFrame(it->second, wPrimitiveCount, ePrimitiveType);
|
||||
}
|
||||
}
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
||||
|
||||
std::sort(m_RenderedTextureNumVector.begin(),m_RenderedTextureNumVector.end());
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Render State & TextureStageState
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
|
||||
|
||||
// Render State & TextureStageState
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
void CMapOutdoor::__HardwareTransformPatch_RenderPatchSplat(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "__HardwareTransformPatch_RenderPatchSplat");
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (sPatchNum < 0)
|
||||
return;
|
||||
|
||||
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == ucTerrainNum)
|
||||
return;
|
||||
|
||||
CTerrain * pTerrain;
|
||||
if (!GetTerrainPointer(ucTerrainNum, &pTerrain))
|
||||
return;
|
||||
|
||||
DWORD dwFogColor;
|
||||
if (mc_pEnvironmentData)
|
||||
dwFogColor=mc_pEnvironmentData->FogColor;
|
||||
else
|
||||
dwFogColor=0xffffffff;
|
||||
|
||||
WORD wCoordX, wCoordY;
|
||||
pTerrain->GetCoordinate(&wCoordX, &wCoordY);
|
||||
|
||||
TTerrainSplatPatch & rTerrainSplatPatch = pTerrain->GetTerrainSplatPatch();
|
||||
|
||||
D3DXMATRIX matTexTransform, matSplatAlphaTexTransform, matSplatColorTexTransform;
|
||||
m_matWorldForCommonUse._41 = -(float) (wCoordX * CTerrainImpl::TERRAIN_XSIZE);
|
||||
m_matWorldForCommonUse._42 = (float) (wCoordY * CTerrainImpl::TERRAIN_YSIZE);
|
||||
D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &m_matWorldForCommonUse);
|
||||
D3DXMatrixMultiply(&matSplatAlphaTexTransform, &matTexTransform, &m_matSplatAlpha);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matSplatAlphaTexTransform);
|
||||
|
||||
D3DXMATRIX matTiling;
|
||||
D3DXMatrixScaling(&matTiling, 1.0f/640.0f, -1.0f/640.0f, 0.0f);
|
||||
matTiling._41=0.0f;
|
||||
matTiling._42=0.0f;
|
||||
|
||||
D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &matTiling);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform);
|
||||
|
||||
CGraphicVertexBuffer* pkVB=pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr();
|
||||
if (!pkVB)
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
|
||||
int iPrevRenderedSplatNum=m_iRenderedSplatNum;
|
||||
|
||||
#ifdef WORLD_EDITOR
|
||||
|
||||
int nRenderTextureCount = 0;
|
||||
|
||||
// if (!m_bShowEntirePatchTextureCount && !(GetAsyncKeyState(VK_LCONTROL) & 0x8000) )
|
||||
if (1)
|
||||
{
|
||||
for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j)
|
||||
{
|
||||
TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j];
|
||||
|
||||
if (!rSplat.Active)
|
||||
continue;
|
||||
|
||||
if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0)
|
||||
continue;
|
||||
|
||||
++nRenderTextureCount;
|
||||
}
|
||||
|
||||
DWORD dwTextureFactor = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR);
|
||||
|
||||
int TextureCountThreshold = 8;
|
||||
DWORD dwTFactor = 0xFFFFFFFF;
|
||||
|
||||
if (GetAsyncKeyState(VK_LSHIFT) & 0x8000)
|
||||
{
|
||||
if (GetAsyncKeyState(VK_1) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 2;
|
||||
dwTFactor = 0xFF0000FF;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_2) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 3;
|
||||
dwTFactor = 0xFF00FF00;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_3) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 4;
|
||||
dwTFactor = 0xFF00FFFF;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_4) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 5;
|
||||
dwTFactor = 0xFFFF0000;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_5) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 6;
|
||||
dwTFactor = 0xFFFFFF00;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_6) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 7;
|
||||
dwTFactor = 0xFFFF00ff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (nRenderTextureCount>=TextureCountThreshold)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTFactor);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactor);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0번 텍스처
|
||||
if ( 0 < rTerrainSplatPatch.PatchTileCount[sPatchNum][0] )
|
||||
{
|
||||
DWORD dwTextureFactorFor0Texture = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR);
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFF88FF88);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactorFor0Texture);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
}
|
||||
|
||||
for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j)
|
||||
{
|
||||
TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j];
|
||||
|
||||
if (!rSplat.Active)
|
||||
continue;
|
||||
|
||||
DWORD dwTextureCount = rTerrainSplatPatch.PatchTileCount[sPatchNum][j];
|
||||
if (dwTextureCount == 0)
|
||||
continue;
|
||||
|
||||
DWORD dwTextureFactorForTextureBalance = 0xFFFFFFFF;
|
||||
|
||||
if (!(GetAsyncKeyState(VK_LSHIFT) & 0x8000))
|
||||
{
|
||||
const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j);
|
||||
|
||||
D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform);
|
||||
|
||||
STATEMANAGER.SetTexture(0, rTexture.pd3dTexture);
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dwTextureCount < 71)
|
||||
{
|
||||
dwTextureFactorForTextureBalance = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR);
|
||||
if (dwTextureCount < 51)
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFFFF0000);
|
||||
else
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xFF0000FF);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j);
|
||||
|
||||
D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform);
|
||||
|
||||
STATEMANAGER.SetTexture(0, rTexture.pd3dTexture);
|
||||
}
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
if (dwTextureCount < 71)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactorForTextureBalance);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int>::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j);
|
||||
if (aIterator == m_RenderedTextureNumVector.end())
|
||||
m_RenderedTextureNumVector.push_back(j);
|
||||
++m_iRenderedSplatNum;
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int TextureCountThreshold = 6;
|
||||
DWORD dwTFactor = 0xFFFF00FF;
|
||||
|
||||
if (GetAsyncKeyState(VK_LSHIFT) & 0x8000)
|
||||
{
|
||||
if (GetAsyncKeyState(VK_1) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 1;
|
||||
dwTFactor = 0xFF0000FF;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_2) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 2;
|
||||
dwTFactor = 0xFF00FF00;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_3) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 3;
|
||||
dwTFactor = 0xFF00FFFF;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_4) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 4;
|
||||
dwTFactor = 0xFFFF0000;
|
||||
}
|
||||
else if (GetAsyncKeyState(VK_5) & 0x8000)
|
||||
{
|
||||
TextureCountThreshold = 5;
|
||||
dwTFactor = 0xFFFFFF00;
|
||||
}
|
||||
}
|
||||
|
||||
for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j)
|
||||
{
|
||||
TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j];
|
||||
|
||||
if (!rSplat.Active)
|
||||
continue;
|
||||
|
||||
if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0)
|
||||
continue;
|
||||
|
||||
DWORD dwTextureFactor;
|
||||
|
||||
if (nRenderTextureCount>=TextureCountThreshold)
|
||||
{
|
||||
dwTextureFactor = STATEMANAGER.GetRenderState(D3DRS_TEXTUREFACTOR);
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTFactor);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j);
|
||||
|
||||
D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform);
|
||||
|
||||
STATEMANAGER.SetTexture(0, rTexture.pd3dTexture);
|
||||
}
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
if (nRenderTextureCount>=TextureCountThreshold)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, dwTextureFactor);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
|
||||
}
|
||||
|
||||
++nRenderTextureCount;
|
||||
|
||||
std::vector<int>::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j);
|
||||
if (aIterator == m_RenderedTextureNumVector.end())
|
||||
m_RenderedTextureNumVector.push_back(j);
|
||||
++m_iRenderedSplatNum;
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
bool isFirst=true;
|
||||
for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j)
|
||||
{
|
||||
TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j];
|
||||
|
||||
if (!rSplat.Active)
|
||||
continue;
|
||||
|
||||
if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0)
|
||||
continue;
|
||||
|
||||
const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j);
|
||||
|
||||
D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform);
|
||||
if (isFirst)
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTexture(0, rTexture.pd3dTexture);
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
isFirst=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, rTexture.pd3dTexture);
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
}
|
||||
|
||||
std::vector<int>::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j);
|
||||
if (aIterator == m_RenderedTextureNumVector.end())
|
||||
m_RenderedTextureNumVector.push_back(j);
|
||||
++m_iRenderedSplatNum;
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
if (GetAsyncKeyState(VK_CAPITAL) & 0x8000)
|
||||
{
|
||||
TTerainSplat & rSplat = rTerrainSplatPatch.Splats[200];
|
||||
|
||||
if (rSplat.Active)
|
||||
{
|
||||
const TTerrainTexture & rTexture = m_TextureSet.GetTexture(1);
|
||||
|
||||
D3DXMatrixMultiply(&matSplatColorTexTransform, &m_matViewInverse, &rTexture.m_matTransform);
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matSplatColorTexTransform);
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
// 그림자
|
||||
if (m_bDrawShadow)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF);
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
|
||||
|
||||
D3DXMATRIX matShadowTexTransform;
|
||||
D3DXMatrixMultiply(&matShadowTexTransform, &matTexTransform, &m_matStaticShadow);
|
||||
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE0, &matShadowTexTransform);
|
||||
STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture());
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
if (m_bDrawChrShadow)
|
||||
{
|
||||
STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matDynamicShadow);
|
||||
|
||||
STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
else
|
||||
{
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
}
|
||||
|
||||
ms_faceCount += wPrimitiveCount;
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
++m_iRenderedSplatNum;
|
||||
|
||||
if (m_bDrawChrShadow)
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
}
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, dwFogColor);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
}
|
||||
++m_iRenderedPatchNum;
|
||||
|
||||
int iCurRenderedSplatNum=m_iRenderedSplatNum-iPrevRenderedSplatNum;
|
||||
|
||||
m_iRenderedSplatNumSqSum+=iCurRenderedSplatNum*iCurRenderedSplatNum;
|
||||
|
||||
}
|
||||
|
||||
void CMapOutdoor::__HardwareTransformPatch_RenderPatchNone(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "__HardwareTransformPatch_RenderPatchNone");
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
CGraphicVertexBuffer* pkVB=pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr();
|
||||
if (!pkVB)
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
}
|
||||
@@ -0,0 +1,806 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "TerrainPatch.h"
|
||||
#include "TerrainQuadtree.h"
|
||||
|
||||
#include "../eterlib/Camera.h"
|
||||
#include "../eterlib/StateManager.h"
|
||||
|
||||
struct SoftwareTransformPatch_SSplatVertex
|
||||
{
|
||||
D3DXVECTOR4 kPosition;
|
||||
DWORD dwDiffuse;
|
||||
DWORD dwSpecular;
|
||||
D3DXVECTOR2 kTex1;
|
||||
D3DXVECTOR2 kTex2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void CMapOutdoor::__RenderTerrain_RenderSoftwareTransformPatch()
|
||||
{
|
||||
SoftwareTransformPatch_SRenderState kTPRS;
|
||||
|
||||
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
|
||||
|
||||
__SoftwareTransformPatch_ApplyRenderState();
|
||||
|
||||
__SoftwareTransformPatch_BuildPipeline(kTPRS);
|
||||
|
||||
std::pair<float, long> fog_far(kTPRS.m_fFogFarDistance+800.0f, 0);
|
||||
std::pair<float, long> fog_near(kTPRS.m_fFogNearDistance-3200.0f, 0);
|
||||
|
||||
std::vector<std::pair<float ,long> >::iterator far_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_far);
|
||||
std::vector<std::pair<float ,long> >::iterator near_it = std::upper_bound(m_PatchVector.begin(),m_PatchVector.end(),fog_near);
|
||||
|
||||
WORD wPrimitiveCount;
|
||||
D3DPRIMITIVETYPE ePrimitiveType;
|
||||
|
||||
BYTE byCUrrentLODLevel = 0;
|
||||
|
||||
float fLODLevel1Distance = __GetNoFogDistance();
|
||||
float fLODLevel2Distance = __GetFogDistance();
|
||||
|
||||
SelectIndexBuffer(0, &wPrimitiveCount, &ePrimitiveType);
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX2);
|
||||
|
||||
std::vector<std::pair<float, long> >::iterator it = m_PatchVector.begin();
|
||||
|
||||
for( ; it != near_it; ++it)
|
||||
{
|
||||
if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 1;
|
||||
SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 2;
|
||||
SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
|
||||
__SoftwareTransformPatch_RenderPatchSplat(kTPRS, it->second, wPrimitiveCount, ePrimitiveType, false);
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (m_iRenderedSplatNum < m_iSplatLimit)
|
||||
{
|
||||
for(it = near_it; it != far_it; ++it)
|
||||
{
|
||||
if (byCUrrentLODLevel == 0 && fLODLevel1Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 1;
|
||||
SelectIndexBuffer(1, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
else if (byCUrrentLODLevel == 1 && fLODLevel2Distance <= it->first)
|
||||
{
|
||||
byCUrrentLODLevel = 2;
|
||||
SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
|
||||
__SoftwareTransformPatch_RenderPatchSplat(kTPRS, it->second, wPrimitiveCount, ePrimitiveType, true);
|
||||
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZRHW);
|
||||
|
||||
if (IsFastTNL())
|
||||
{
|
||||
if (byCUrrentLODLevel != 2)
|
||||
{
|
||||
byCUrrentLODLevel = 2;
|
||||
SelectIndexBuffer(2, &wPrimitiveCount, &ePrimitiveType);
|
||||
}
|
||||
|
||||
if (m_iRenderedSplatNum < m_iSplatLimit)
|
||||
{
|
||||
for(it = far_it; it != m_PatchVector.end(); ++it)
|
||||
{
|
||||
__SoftwareTransformPatch_RenderPatchNone(kTPRS, it->second, wPrimitiveCount, ePrimitiveType);
|
||||
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Render State & TextureStageState
|
||||
__SoftwareTransformPatch_RestoreRenderState(dwFogEnable);
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_RenderPatchSplat(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType, bool isFogEnable)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SoftwareTransformPatch_RenderPatchSplat");
|
||||
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
bool isDynamicShadow = pTerrainPatchProxy->IsIn(rkTPRS.m_v3Player, 3000.0f);
|
||||
|
||||
if (!m_bDrawChrShadow)
|
||||
isDynamicShadow = false;
|
||||
|
||||
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
|
||||
if (sPatchNum < 0)
|
||||
return;
|
||||
|
||||
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
|
||||
if (0xFF == ucTerrainNum)
|
||||
return;
|
||||
|
||||
CTerrain * pTerrain;
|
||||
if (!GetTerrainPointer(ucTerrainNum, &pTerrain))
|
||||
return;
|
||||
|
||||
WORD wCoordX, wCoordY;
|
||||
pTerrain->GetCoordinate(&wCoordX, &wCoordY);
|
||||
|
||||
TTerrainSplatPatch & rTerrainSplatPatch = pTerrain->GetTerrainSplatPatch();
|
||||
|
||||
SoftwareTransformPatch_STLVertex akTransVertex[CTerrainPatch::TERRAIN_VERTEX_COUNT];
|
||||
if (!__SoftwareTransformPatch_SetTransform(rkTPRS, akTransVertex, *pTerrainPatchProxy, wCoordX, wCoordY, isFogEnable, isDynamicShadow))
|
||||
return;
|
||||
|
||||
if (!__SoftwareTransformPatch_SetSplatStream(akTransVertex))
|
||||
return;
|
||||
|
||||
if (isFogEnable)
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
}
|
||||
|
||||
int iPrevRenderedSplatNum=m_iRenderedSplatNum;
|
||||
|
||||
bool isFirst=true;
|
||||
for (DWORD j = 1; j < pTerrain->GetNumTextures(); ++j)
|
||||
{
|
||||
TTerainSplat & rSplat = rTerrainSplatPatch.Splats[j];
|
||||
|
||||
if (!rSplat.Active)
|
||||
continue;
|
||||
|
||||
if (rTerrainSplatPatch.PatchTileCount[sPatchNum][j] == 0)
|
||||
continue;
|
||||
|
||||
const TTerrainTexture & rTexture = m_TextureSet.GetTexture(j);
|
||||
|
||||
if (isFirst)
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
|
||||
STATEMANAGER.SetTexture(0, rTexture.pd3dTexture);
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
isFirst=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, rTexture.pd3dTexture);
|
||||
STATEMANAGER.SetTexture(1, rSplat.pd3dTexture);
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
}
|
||||
|
||||
std::vector<int>::iterator aIterator = std::find(m_RenderedTextureNumVector.begin(), m_RenderedTextureNumVector.end(), (int)j);
|
||||
if (aIterator == m_RenderedTextureNumVector.end())
|
||||
m_RenderedTextureNumVector.push_back(j);
|
||||
++m_iRenderedSplatNum;
|
||||
if (m_iRenderedSplatNum >= m_iSplatLimit)
|
||||
break;
|
||||
}
|
||||
|
||||
// ±×¸²ÀÚ
|
||||
if (m_bDrawShadow)
|
||||
{
|
||||
__SoftwareTransformPatch_SetShadowStream(akTransVertex);
|
||||
__SoftwareTransformPatch_ApplyStaticShadowRenderState();
|
||||
|
||||
if (isDynamicShadow)
|
||||
__SoftwareTransformPatch_ApplyDynamicShadowRenderState();
|
||||
else
|
||||
__SoftwareTransformPatch_ApplyFogShadowRenderState();
|
||||
|
||||
if (isFogEnable)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, TRUE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF);
|
||||
STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture());
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, rkTPRS.m_dwFogColor);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture());
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
}
|
||||
|
||||
if (isDynamicShadow)
|
||||
__SoftwareTransformPatch_RestoreDynamicShadowRenderState();
|
||||
else
|
||||
__SoftwareTransformPatch_RestoreFogShadowRenderState();
|
||||
|
||||
ms_faceCount += wPrimitiveCount;
|
||||
++m_iRenderedSplatNum;
|
||||
|
||||
|
||||
|
||||
__SoftwareTransformPatch_RestoreStaticShadowRenderState();
|
||||
}
|
||||
|
||||
++m_iRenderedPatchNum;
|
||||
|
||||
int iCurRenderedSplatNum=m_iRenderedSplatNum-iPrevRenderedSplatNum;
|
||||
|
||||
m_iRenderedSplatNumSqSum+=iCurRenderedSplatNum*iCurRenderedSplatNum;
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_RenderPatchNone(SoftwareTransformPatch_SRenderState& rkTPRS, long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SoftwareTransformPatch_RenderPatchNone");
|
||||
|
||||
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum];
|
||||
|
||||
if (!pTerrainPatchProxy->isUsed())
|
||||
return;
|
||||
|
||||
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
|
||||
if (sPatchNum < 0)
|
||||
return;
|
||||
|
||||
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
|
||||
if (0xFF == ucTerrainNum)
|
||||
return;
|
||||
|
||||
CTerrain * pTerrain;
|
||||
if (!GetTerrainPointer(ucTerrainNum, &pTerrain))
|
||||
return;
|
||||
|
||||
WORD wCoordX, wCoordY;
|
||||
pTerrain->GetCoordinate(&wCoordX, &wCoordY);
|
||||
|
||||
SoftwareTransformPatch_SSourceVertex* akSrcVertex=pTerrainPatchProxy->SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
if (!akSrcVertex)
|
||||
return;
|
||||
|
||||
float fScreenHalfWidth=rkTPRS.m_fScreenHalfWidth;
|
||||
float fScreenHalfHeight=rkTPRS.m_fScreenHalfHeight;
|
||||
|
||||
D3DXMATRIX m4Frustum=rkTPRS.m_m4Frustum;
|
||||
|
||||
SoftwareTransformPatch_STVertex akTransVertex[CTerrainPatch::TERRAIN_VERTEX_COUNT];
|
||||
|
||||
D3DXVECTOR4* akPosition=(D3DXVECTOR4*)akTransVertex;
|
||||
D3DXVECTOR4* pkPosition;
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
pkPosition=akPosition+uIndex;
|
||||
D3DXVec3Transform(pkPosition, &akSrcVertex[uIndex].kPosition, &m4Frustum);
|
||||
pkPosition->w=1.0f/pkPosition->w;
|
||||
pkPosition->z*=pkPosition->w;
|
||||
pkPosition->y=(pkPosition->y*pkPosition->w-1.0f)*fScreenHalfHeight;
|
||||
pkPosition->x=(pkPosition->x*pkPosition->w+1.0f)*fScreenHalfWidth;
|
||||
}
|
||||
|
||||
|
||||
IDirect3DVertexBuffer8* pkVB=m_kSTPD.m_pkVBNone[m_kSTPD.m_dwNonePos++];
|
||||
m_kSTPD.m_dwNonePos%=SoftwareTransformPatch_SData::NONE_VB_NUM;
|
||||
if (!pkVB)
|
||||
return;
|
||||
|
||||
DWORD dwVBSize=sizeof(SoftwareTransformPatch_STVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT;
|
||||
SoftwareTransformPatch_STVertex* akDstVertex;
|
||||
if (FAILED(
|
||||
pkVB->Lock(0, dwVBSize, (BYTE**)&akDstVertex, D3DLOCK_DISCARD)
|
||||
)) return;
|
||||
|
||||
memcpy(akDstVertex, akTransVertex, dwVBSize);
|
||||
|
||||
pkVB->Unlock();
|
||||
|
||||
STATEMANAGER.SetStreamSource(0, pkVB, sizeof(SoftwareTransformPatch_STVertex));
|
||||
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
|
||||
ms_faceCount += wPrimitiveCount;
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_ApplyStaticShadowRenderState()
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_ApplyDynamicShadowRenderState()
|
||||
{
|
||||
STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_ApplyFogShadowRenderState()
|
||||
{
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
}
|
||||
void CMapOutdoor::__SoftwareTransformPatch_RestoreStaticShadowRenderState()
|
||||
{
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_RestoreDynamicShadowRenderState()
|
||||
{
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_RestoreFogShadowRenderState()
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_ApplyRenderState()
|
||||
{
|
||||
DWORD dwFogColor=0xffffffff;
|
||||
if (mc_pEnvironmentData)
|
||||
dwFogColor=mc_pEnvironmentData->FogColor;
|
||||
|
||||
BOOL isSoftwareVertexClipping=FALSE;
|
||||
if (!IsTLVertexClipping())
|
||||
isSoftwareVertexClipping=TRUE;
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, isSoftwareVertexClipping);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000000);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, dwFogColor);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
STATEMANAGER.SetBestFiltering(0);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SetBestFiltering(1);
|
||||
|
||||
CSpeedTreeWrapper::ms_bSelfShadowOn = true;
|
||||
|
||||
// Render State & TextureStageState
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
m_iRenderedSplatNumSqSum = 0;
|
||||
m_iRenderedPatchNum = 0;
|
||||
m_iRenderedSplatNum = 0;
|
||||
m_RenderedTextureNumVector.clear();
|
||||
|
||||
m_matWorldForCommonUse._41 = 0.0f;
|
||||
m_matWorldForCommonUse._42 = 0.0f;
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse);
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_RestoreRenderState(DWORD dwFogEnable)
|
||||
{
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
|
||||
|
||||
std::sort(m_RenderedTextureNumVector.begin(),m_RenderedTextureNumVector.end());
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SOFTWAREVERTEXPROCESSING);
|
||||
|
||||
// Render State & TextureStageState
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_BuildPipeline(SoftwareTransformPatch_SRenderState& rkTPRS)
|
||||
{
|
||||
memset(&rkTPRS, 0, sizeof(rkTPRS));
|
||||
|
||||
if (mc_pEnvironmentData)
|
||||
{
|
||||
rkTPRS.m_dwFogColor = mc_pEnvironmentData->FogColor;
|
||||
rkTPRS.m_fFogNearDistance = mc_pEnvironmentData->GetFogNearDistance();
|
||||
rkTPRS.m_fFogFarDistance = mc_pEnvironmentData->GetFogFarDistance();
|
||||
}
|
||||
else
|
||||
{
|
||||
rkTPRS.m_dwFogColor = 0xffffffff;
|
||||
rkTPRS.m_fFogNearDistance = 5000.0f;
|
||||
rkTPRS.m_fFogFarDistance = 10000.0f;
|
||||
}
|
||||
|
||||
UINT uScreenWidth;
|
||||
UINT uScreenHeight;
|
||||
CScreen::GetBackBufferSize(&uScreenWidth, &uScreenHeight);
|
||||
|
||||
rkTPRS.m_fScreenHalfWidth = +float(uScreenWidth) / 2.0f;
|
||||
rkTPRS.m_fScreenHalfHeight = -float(uScreenHeight) / 2.0f;
|
||||
|
||||
STATEMANAGER.GetLight(0, &rkTPRS.m_kLight);
|
||||
STATEMANAGER.GetMaterial(&rkTPRS.m_kMtrl);
|
||||
|
||||
D3DXMATRIX m4View;STATEMANAGER.GetTransform(D3DTS_VIEW, &m4View);
|
||||
D3DXMATRIX m4Proj;STATEMANAGER.GetTransform(D3DTS_PROJECTION, &m4Proj);
|
||||
|
||||
D3DXMatrixMultiply(&rkTPRS.m_m4Frustum, &m4View, &m4Proj);
|
||||
|
||||
rkTPRS.m_v3Player.x = +m_v3Player.x;
|
||||
rkTPRS.m_v3Player.y = -m_v3Player.y;
|
||||
rkTPRS.m_v3Player.z = +m_v3Player.z;
|
||||
|
||||
rkTPRS.m_m4Proj = m4Proj;
|
||||
rkTPRS.m_m4DynamicShadow = m_matLightView * m_matDynamicShadowScale;
|
||||
|
||||
D3DXVECTOR3 kFogNearVector;
|
||||
const auto farvv = D3DXVECTOR3(0.0f, 0.0f, -rkTPRS.m_fFogNearDistance);
|
||||
D3DXVec3TransformCoord(&kFogNearVector, &farvv, &rkTPRS.m_m4Proj);
|
||||
|
||||
D3DXVECTOR3 kFogFarVector;
|
||||
const auto nearvv = D3DXVECTOR3(0.0f, 0.0f, -rkTPRS.m_fFogFarDistance);
|
||||
D3DXVec3TransformCoord(&kFogFarVector, &nearvv, &rkTPRS.m_m4Proj);
|
||||
|
||||
float fFogNear = kFogNearVector.z;
|
||||
float fFogFar = kFogFarVector.z;
|
||||
float fFogLenInv = 1.0f / (fFogFar-fFogNear);
|
||||
|
||||
rkTPRS.m_fFogNearTransZ = fFogNear;
|
||||
rkTPRS.m_fFogFarTransZ = fFogFar;
|
||||
rkTPRS.m_fFogLenInv = fFogLenInv;
|
||||
|
||||
}
|
||||
|
||||
bool CMapOutdoor::__SoftwareTransformPatch_SetTransform(SoftwareTransformPatch_SRenderState& rkTPRS, SoftwareTransformPatch_STLVertex* akTransVertex, CTerrainPatchProxy& rkTerrainPatchProxy, UINT uTerrainX, UINT uTerrainY, bool isFogEnable, bool isDynamicShadow)
|
||||
{
|
||||
SoftwareTransformPatch_SSourceVertex* akSrcVertex=rkTerrainPatchProxy.SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
if (!akSrcVertex)
|
||||
return false;
|
||||
|
||||
rkTerrainPatchProxy.SoftwareTransformPatch_UpdateTerrainLighting(
|
||||
m_kSTPD.m_dwLightVersion,
|
||||
rkTPRS.m_kLight, rkTPRS.m_kMtrl);
|
||||
|
||||
D3DXVECTOR3* pkSrcPosition;
|
||||
|
||||
float fTilePatternX=+1/640.0f;
|
||||
float fTilePatternY=-1/640.0f;
|
||||
|
||||
float fTerrainBaseX=-(float) (uTerrainX * CTerrainImpl::TERRAIN_XSIZE)+m_fTerrainTexCoordBase * 12.30769f;
|
||||
float fTerrainBaseY=+(float) (uTerrainY * CTerrainImpl::TERRAIN_YSIZE)+m_fTerrainTexCoordBase * 12.30769f;
|
||||
|
||||
float fScreenHalfWidth=rkTPRS.m_fScreenHalfWidth;
|
||||
float fScreenHalfHeight=rkTPRS.m_fScreenHalfHeight;
|
||||
|
||||
float fAlphaPatternX=m_matSplatAlpha._11;
|
||||
float fAlphaPatternY=m_matSplatAlpha._22;
|
||||
float fAlphaBiasX=m_matSplatAlpha._41;
|
||||
float fAlphaBiasY=m_matSplatAlpha._42;
|
||||
float fShadowPatternX=+m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_XSIZE / static_cast<float>(CTerrainImpl::XSIZE));
|
||||
float fShadowPatternY=-m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_YSIZE / static_cast<float>(CTerrainImpl::YSIZE));
|
||||
|
||||
D3DXMATRIX m4Frustum=rkTPRS.m_m4Frustum;
|
||||
|
||||
if (isFogEnable)
|
||||
{
|
||||
float fFogCur;
|
||||
float fFogFar=rkTPRS.m_fFogFarTransZ;
|
||||
float fFogLenInv=rkTPRS.m_fFogLenInv;
|
||||
|
||||
float fLocalX;
|
||||
float fLocalY;
|
||||
|
||||
SoftwareTransformPatch_STLVertex kWorkVertex;
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
pkSrcPosition=&akSrcVertex[uIndex].kPosition;
|
||||
D3DXVec3Transform(&kWorkVertex.kPosition, pkSrcPosition, &m4Frustum);
|
||||
fLocalX=pkSrcPosition->x+fTerrainBaseX;
|
||||
fLocalY=pkSrcPosition->y+fTerrainBaseY;
|
||||
kWorkVertex.kPosition.w=1.0f/kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.x*=kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.y*=kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.z*=kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.x=(kWorkVertex.kPosition.x+1.0f)*fScreenHalfWidth;
|
||||
kWorkVertex.kPosition.y=(kWorkVertex.kPosition.y-1.0f)*fScreenHalfHeight;
|
||||
kWorkVertex.dwDiffuse=akSrcVertex[uIndex].dwDiffuse;
|
||||
kWorkVertex.kTexTile.x=pkSrcPosition->x*fTilePatternX;
|
||||
kWorkVertex.kTexTile.y=pkSrcPosition->y*fTilePatternY;
|
||||
kWorkVertex.kTexAlpha.x=fLocalX*fAlphaPatternX+fAlphaBiasX;
|
||||
kWorkVertex.kTexAlpha.y=fLocalY*fAlphaPatternY+fAlphaBiasY;
|
||||
kWorkVertex.kTexStaticShadow.x=fLocalX*fShadowPatternX;
|
||||
kWorkVertex.kTexStaticShadow.y=fLocalY*fShadowPatternY;
|
||||
kWorkVertex.kTexDynamicShadow.x=0.0f;
|
||||
kWorkVertex.kTexDynamicShadow.y=0.0f;
|
||||
|
||||
fFogCur=(fFogFar-kWorkVertex.kPosition.z)*fFogLenInv;
|
||||
if (fFogCur<0.0f)
|
||||
kWorkVertex.dwFog=kWorkVertex.dwDiffuse=0x0000000|(kWorkVertex.dwDiffuse&0xffffff);
|
||||
else if (fFogCur>1.0f)
|
||||
kWorkVertex.dwFog=kWorkVertex.dwDiffuse=0xFF000000|(kWorkVertex.dwDiffuse&0xffffff);
|
||||
else
|
||||
kWorkVertex.dwFog=kWorkVertex.dwDiffuse=BYTE(255.0f*fFogCur)<<24|(kWorkVertex.dwDiffuse&0xffffff);
|
||||
|
||||
*(akTransVertex+uIndex)=kWorkVertex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float fLocalX;
|
||||
float fLocalY;
|
||||
|
||||
SoftwareTransformPatch_STLVertex kWorkVertex;
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
pkSrcPosition=&akSrcVertex[uIndex].kPosition;
|
||||
D3DXVec3Transform(&kWorkVertex.kPosition, pkSrcPosition, &m4Frustum);
|
||||
fLocalX=pkSrcPosition->x+fTerrainBaseX;
|
||||
fLocalY=pkSrcPosition->y+fTerrainBaseY;
|
||||
kWorkVertex.kPosition.w=1.0f/kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.x*=kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.y*=kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.z*=kWorkVertex.kPosition.w;
|
||||
kWorkVertex.kPosition.x=(kWorkVertex.kPosition.x+1.0f)*fScreenHalfWidth;
|
||||
kWorkVertex.kPosition.y=(kWorkVertex.kPosition.y-1.0f)*fScreenHalfHeight;
|
||||
kWorkVertex.dwDiffuse=akSrcVertex[uIndex].dwDiffuse;
|
||||
kWorkVertex.dwFog=0xffffffff;
|
||||
kWorkVertex.kTexTile.x=pkSrcPosition->x*fTilePatternX;
|
||||
kWorkVertex.kTexTile.y=pkSrcPosition->y*fTilePatternY;
|
||||
kWorkVertex.kTexAlpha.x=fLocalX*fAlphaPatternX+fAlphaBiasX;
|
||||
kWorkVertex.kTexAlpha.y=fLocalY*fAlphaPatternY+fAlphaBiasY;
|
||||
kWorkVertex.kTexStaticShadow.x=fLocalX*fShadowPatternX;
|
||||
kWorkVertex.kTexStaticShadow.y=fLocalY*fShadowPatternY;
|
||||
kWorkVertex.kTexDynamicShadow.x=0.0f;
|
||||
kWorkVertex.kTexDynamicShadow.y=0.0f;
|
||||
|
||||
*(akTransVertex+uIndex)=kWorkVertex;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDynamicShadow)
|
||||
{
|
||||
D3DXMATRIX m4DynamicShadow=rkTPRS.m_m4DynamicShadow;
|
||||
|
||||
D3DXVECTOR3 v3Shadow;
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
D3DXVec3TransformCoord(&v3Shadow, &akSrcVertex[uIndex].kPosition, &m4DynamicShadow);
|
||||
akTransVertex[uIndex].kTexDynamicShadow.x=v3Shadow.x;
|
||||
akTransVertex[uIndex].kTexDynamicShadow.y=v3Shadow.y;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::__SoftwareTransformPatch_SetSplatStream(SoftwareTransformPatch_STLVertex* akSrcVertex)
|
||||
{
|
||||
IDirect3DVertexBuffer8* pkVB=m_kSTPD.m_pkVBSplat[m_kSTPD.m_dwSplatPos++];
|
||||
m_kSTPD.m_dwSplatPos%=SoftwareTransformPatch_SData::SPLAT_VB_NUM;
|
||||
if (!pkVB)
|
||||
return false;
|
||||
|
||||
DWORD dwVBSize=sizeof(SoftwareTransformPatch_SSplatVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT;
|
||||
SoftwareTransformPatch_SSplatVertex* akDstVertex;
|
||||
if (FAILED(
|
||||
pkVB->Lock(0, dwVBSize, (BYTE**)&akDstVertex, 0)//D3DLOCK_DISCARD)
|
||||
)) return false;
|
||||
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
*(akDstVertex+uIndex)=*((SoftwareTransformPatch_SSplatVertex*)(akSrcVertex+uIndex));
|
||||
|
||||
pkVB->Unlock();
|
||||
|
||||
STATEMANAGER.SetStreamSource(0, pkVB, sizeof(SoftwareTransformPatch_SSplatVertex));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMapOutdoor::__SoftwareTransformPatch_SetShadowStream(SoftwareTransformPatch_STLVertex* akSrcVertex)
|
||||
{
|
||||
IDirect3DVertexBuffer8* pkVB=m_kSTPD.m_pkVBSplat[m_kSTPD.m_dwSplatPos++];
|
||||
m_kSTPD.m_dwSplatPos%=SoftwareTransformPatch_SData::SPLAT_VB_NUM;
|
||||
if (!pkVB)
|
||||
return false;
|
||||
|
||||
DWORD dwVBSize=sizeof(SoftwareTransformPatch_SSplatVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT;
|
||||
SoftwareTransformPatch_SSplatVertex* akDstVertex;
|
||||
if (FAILED(
|
||||
pkVB->Lock(0, dwVBSize, (BYTE**)&akDstVertex, 0)//D3DLOCK_DISCARD)
|
||||
)) return false;
|
||||
|
||||
SoftwareTransformPatch_STLVertex* pkSrcVertex;
|
||||
SoftwareTransformPatch_SSplatVertex* pkDstVertex;
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
pkSrcVertex=akSrcVertex+uIndex;
|
||||
pkDstVertex=akDstVertex+uIndex;
|
||||
pkDstVertex->kPosition=pkSrcVertex->kPosition;
|
||||
pkDstVertex->dwDiffuse=pkSrcVertex->dwDiffuse;
|
||||
pkDstVertex->dwSpecular=pkSrcVertex->dwFog;
|
||||
pkDstVertex->kTex1=pkSrcVertex->kTexStaticShadow;
|
||||
pkDstVertex->kTex2=pkSrcVertex->kTexDynamicShadow;
|
||||
}
|
||||
pkVB->Unlock();
|
||||
|
||||
|
||||
ms_lpd3dDevice->SetStreamSource(0, pkVB, sizeof(SoftwareTransformPatch_SSplatVertex));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_Initialize()
|
||||
{
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex)
|
||||
m_kSTPD.m_pkVBSplat[uIndex]=NULL;
|
||||
m_kSTPD.m_dwSplatPos=0;
|
||||
}
|
||||
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex)
|
||||
m_kSTPD.m_pkVBNone[uIndex]=NULL;
|
||||
m_kSTPD.m_dwNonePos=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CMapOutdoor::__SoftwareTransformPatch_Create()
|
||||
{
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex)
|
||||
{
|
||||
assert(NULL==m_kSTPD.m_pkVBSplat[uIndex]);
|
||||
if (FAILED(
|
||||
ms_lpd3dDevice->CreateVertexBuffer(
|
||||
sizeof(SoftwareTransformPatch_SSplatVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT,
|
||||
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
|
||||
D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX2,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
&m_kSTPD.m_pkVBSplat[uIndex]
|
||||
)
|
||||
)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex)
|
||||
{
|
||||
assert(NULL==m_kSTPD.m_pkVBNone[uIndex]);
|
||||
if (FAILED(
|
||||
ms_lpd3dDevice->CreateVertexBuffer(
|
||||
sizeof(SoftwareTransformPatch_STVertex)*CTerrainPatch::TERRAIN_VERTEX_COUNT,
|
||||
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
|
||||
D3DFVF_XYZRHW,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
&m_kSTPD.m_pkVBNone[uIndex]
|
||||
)
|
||||
)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapOutdoor::__SoftwareTransformPatch_Destroy()
|
||||
{
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::SPLAT_VB_NUM; ++uIndex)
|
||||
{
|
||||
if (m_kSTPD.m_pkVBSplat[uIndex])
|
||||
m_kSTPD.m_pkVBSplat[uIndex]->Release();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (UINT uIndex=0; uIndex!=SoftwareTransformPatch_SData::NONE_VB_NUM; ++uIndex)
|
||||
{
|
||||
if (m_kSTPD.m_pkVBNone[uIndex])
|
||||
m_kSTPD.m_pkVBNone[uIndex]->Release();
|
||||
}
|
||||
}
|
||||
__SoftwareTransformPatch_Initialize();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,170 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/StateManager.h"
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
|
||||
#include "MapOutdoor.h"
|
||||
#include "TerrainPatch.h"
|
||||
|
||||
void CMapOutdoor::LoadWaterTexture()
|
||||
{
|
||||
UnloadWaterTexture();
|
||||
char buf[256];
|
||||
for (int i = 0; i < 30; ++i)
|
||||
{
|
||||
sprintf(buf, "d:/ymir Work/special/water/%02d.dds", i+1);
|
||||
m_WaterInstances[i].SetImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(buf));
|
||||
}
|
||||
}
|
||||
|
||||
void CMapOutdoor::UnloadWaterTexture()
|
||||
{
|
||||
for (int i = 0; i < 30; ++i)
|
||||
m_WaterInstances[i].Destroy();
|
||||
}
|
||||
|
||||
void CMapOutdoor::RenderWater()
|
||||
{
|
||||
if (m_PatchVector.empty())
|
||||
return;
|
||||
|
||||
if (!IsVisiblePart(PART_WATER))
|
||||
return;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RenderState
|
||||
D3DXMATRIX matTexTransformWater;
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE);
|
||||
|
||||
STATEMANAGER.SetTexture(0, m_WaterInstances[((ELTimer_GetMSec() / 70) % 30)].GetTexturePointer()->GetD3DTexture());
|
||||
|
||||
D3DXMatrixScaling(&matTexTransformWater, m_fWaterTexCoordBase, -m_fWaterTexCoordBase, 0.0f);
|
||||
D3DXMatrixMultiply(&matTexTransformWater, &m_matViewInverse, &matTexTransformWater);
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransformWater);
|
||||
STATEMANAGER.SaveVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE);
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
|
||||
STATEMANAGER.SetTexture(1,NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
// RenderState
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 물 위 아래 애니시키기...
|
||||
static float s_fWaterHeightCurrent = 0;
|
||||
static float s_fWaterHeightBegin = 0;
|
||||
static float s_fWaterHeightEnd = 0;
|
||||
static DWORD s_dwLastHeightChangeTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
static DWORD s_dwBlendtime = 300;
|
||||
|
||||
// 1.5초 마다 변경
|
||||
if ((CTimer::Instance().GetCurrentMillisecond() - s_dwLastHeightChangeTime) > s_dwBlendtime)
|
||||
{
|
||||
s_dwBlendtime = random_range(1000, 3000);
|
||||
|
||||
if (s_fWaterHeightEnd == 0)
|
||||
s_fWaterHeightEnd = -random_range(0, 15);
|
||||
else
|
||||
s_fWaterHeightEnd = 0;
|
||||
|
||||
s_fWaterHeightBegin = s_fWaterHeightCurrent;
|
||||
s_dwLastHeightChangeTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
}
|
||||
|
||||
s_fWaterHeightCurrent = s_fWaterHeightBegin + (s_fWaterHeightEnd - s_fWaterHeightBegin) * (float) ((CTimer::Instance().GetCurrentMillisecond() - s_dwLastHeightChangeTime) / (float) s_dwBlendtime);
|
||||
m_matWorldForCommonUse._43 = s_fWaterHeightCurrent;
|
||||
|
||||
m_matWorldForCommonUse._41 = 0.0f;
|
||||
m_matWorldForCommonUse._42 = 0.0f;
|
||||
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse);
|
||||
|
||||
float fFogDistance = __GetFogDistance();
|
||||
|
||||
std::vector<std::pair<float, long> >::iterator i;
|
||||
|
||||
for(i = m_PatchVector.begin();i != m_PatchVector.end(); ++i)
|
||||
{
|
||||
if (i->first<fFogDistance)
|
||||
DrawWater(i->second);
|
||||
}
|
||||
|
||||
STATEMANAGER.SetTexture(0, NULL);
|
||||
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
|
||||
for(i = m_PatchVector.begin();i != m_PatchVector.end(); ++i)
|
||||
{
|
||||
if (i->first>=fFogDistance)
|
||||
DrawWater(i->second);
|
||||
}
|
||||
|
||||
// 렌더링 한 후에는 물 z 위치를 복구
|
||||
m_matWorldForCommonUse._43 = 0.0f;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RenderState
|
||||
STATEMANAGER.RestoreVertexShader();
|
||||
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DIFFUSEMATERIALSOURCE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
}
|
||||
|
||||
void CMapOutdoor::DrawWater(long patchnum)
|
||||
{
|
||||
assert(NULL!=m_pTerrainPatchProxyList);
|
||||
if (!m_pTerrainPatchProxyList)
|
||||
return;
|
||||
|
||||
CTerrainPatchProxy& rkTerrainPatchProxy = m_pTerrainPatchProxyList[patchnum];
|
||||
|
||||
if (!rkTerrainPatchProxy.isUsed())
|
||||
return;
|
||||
|
||||
if (!rkTerrainPatchProxy.isWaterExists())
|
||||
return;
|
||||
|
||||
CGraphicVertexBuffer* pkVB=rkTerrainPatchProxy.GetWaterVertexBufferPointer();
|
||||
if (!pkVB)
|
||||
return;
|
||||
|
||||
if (!pkVB->GetD3DVertexBuffer())
|
||||
return;
|
||||
|
||||
UINT uPriCount=rkTerrainPatchProxy.GetWaterFaceCount();
|
||||
if (!uPriCount)
|
||||
return;
|
||||
|
||||
STATEMANAGER.SetStreamSource(0, pkVB->GetD3DVertexBuffer(), sizeof(SWaterVertex));
|
||||
STATEMANAGER.DrawPrimitive(D3DPT_TRIANGLELIST, 0, uPriCount);
|
||||
|
||||
ms_faceCount += uPriCount;
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterBase/Filename.h"
|
||||
#include "Property.h"
|
||||
|
||||
float SEnvironmentData::GetFogNearDistance() const
|
||||
{
|
||||
return m_fFogNearDistance;
|
||||
}
|
||||
|
||||
float SEnvironmentData::GetFogFarDistance() const
|
||||
{
|
||||
return m_fFogFarDistance;
|
||||
}
|
||||
|
||||
float SPixelPosition_CalculateDistanceSq3d(const TPixelPosition& c_rkPPosLeft, const TPixelPosition& c_rkPPosRight)
|
||||
{
|
||||
float dx=c_rkPPosLeft.x-c_rkPPosRight.x;
|
||||
float dy=c_rkPPosLeft.y-c_rkPPosRight.y;
|
||||
float dz=c_rkPPosLeft.z-c_rkPPosRight.z;
|
||||
|
||||
return dx*dx+dy*dy+dz*dz;
|
||||
}
|
||||
|
||||
namespace prt
|
||||
{
|
||||
|
||||
DWORD GetPropertyType(const char * c_szTypeName)
|
||||
{
|
||||
for (DWORD i = 0; i < PROPERTY_TYPE_MAX_NUM; ++i)
|
||||
{
|
||||
if (!strcmp(c_szPropertyTypeName[i], c_szTypeName))
|
||||
return i;
|
||||
}
|
||||
|
||||
return PROPERTY_TYPE_NONE;
|
||||
}
|
||||
|
||||
const char * GetPropertyExtension(DWORD dwType)
|
||||
{
|
||||
if (dwType >= PROPERTY_TYPE_MAX_NUM)
|
||||
return c_szPropertyExtension[0];
|
||||
|
||||
return c_szPropertyExtension[dwType];
|
||||
}
|
||||
|
||||
const char * IntegerNumberToString(int iNumber)
|
||||
{
|
||||
static char szString[16+1];
|
||||
_snprintf(szString, sizeof(szString), "%d", iNumber);
|
||||
return szString;
|
||||
}
|
||||
|
||||
const char * FloatNumberToString(float fNumber)
|
||||
{
|
||||
static char szString[16+1];
|
||||
_snprintf(szString, sizeof(szString), "%f", fNumber);
|
||||
return szString;
|
||||
}
|
||||
|
||||
bool PropertyTreeDataToString(TPropertyTree * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
|
||||
pProperty->PutString("PropertyType", "Tree");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
|
||||
pProperty->PutString("TreeFile", pData->strFileName.c_str());
|
||||
pProperty->PutString("TreeSize", FloatNumberToString(pData->fSize));
|
||||
pProperty->PutString("TreeVariance", FloatNumberToString(pData->fVariance));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyTreeStringToData(CProperty * pProperty, TPropertyTree * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Tree"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszTreeName;
|
||||
const char * c_pszTreeSize;
|
||||
const char * c_pszTreeVariance;
|
||||
if (!pProperty->GetString("TreeFile", &c_pszTreeName))
|
||||
return false;
|
||||
if (!pProperty->GetString("TreeSize", &c_pszTreeSize))
|
||||
return false;
|
||||
if (!pProperty->GetString("TreeVariance", &c_pszTreeVariance))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszTreeName;
|
||||
pData->fSize = atof(c_pszTreeSize);
|
||||
pData->fVariance = atof(c_pszTreeVariance);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyBuildingDataToString(TPropertyBuilding * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
|
||||
pProperty->PutString("PropertyType", "Building");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("BuildingFile", pData->strFileName.c_str());
|
||||
pProperty->PutString("ShadowFlag", IntegerNumberToString(pData->isShadowFlag));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyBuildingStringToData(CProperty * pProperty, TPropertyBuilding * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Building"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszBuildingName;
|
||||
if (!pProperty->GetString("BuildingFile", &c_pszBuildingName))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszBuildingName;
|
||||
pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + ".mdatr";
|
||||
|
||||
const char * c_pszShadowFlag;
|
||||
if (!pProperty->GetString("ShadowFlag", &c_pszShadowFlag))
|
||||
{
|
||||
pData->isShadowFlag = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->isShadowFlag = atoi(c_pszShadowFlag);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PropertyEffectDataToString(TPropertyEffect * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
|
||||
pProperty->PutString("PropertyType", "Effect");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("EffectFile", pData->strFileName.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyEffectStringToData(CProperty * pProperty, TPropertyEffect * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Effect"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszEffectName;
|
||||
if (!pProperty->GetString("EffectFile", &c_pszEffectName))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszEffectName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyAmbienceDataToString(TPropertyAmbience * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
pProperty->PutString("PropertyType", "Ambience");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("PlayType", pData->strPlayType.c_str());
|
||||
pProperty->PutString("PlayInterval", FloatNumberToString(pData->fPlayInterval));
|
||||
pProperty->PutString("PlayIntervalVariation", FloatNumberToString(pData->fPlayIntervalVariation));
|
||||
pProperty->PutString("MaxVolumeAreaPercentage", FloatNumberToString(pData->fMaxVolumeAreaPercentage));
|
||||
|
||||
CTokenVector AmbienceSoundVector;
|
||||
std::vector<std::string>::iterator itor = pData->AmbienceSoundVector.begin();
|
||||
for (; itor != pData->AmbienceSoundVector.end(); ++itor)
|
||||
{
|
||||
std::string & rstrToken = *itor;
|
||||
AmbienceSoundVector.push_back(rstrToken.c_str());
|
||||
}
|
||||
pProperty->PutVector("AmbienceSoundVector", AmbienceSoundVector);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyAmbienceStringToData(CProperty * pProperty, TPropertyAmbience * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "Ambience"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszPlayType;
|
||||
const char * c_pszPlayInterval;
|
||||
const char * c_pszPlayIntervalVariation;
|
||||
const char * c_pszMaxVolumeAreaPercentage = NULL;
|
||||
CTokenVector AmbienceSoundVector;
|
||||
if (!pProperty->GetString("PlayType", &c_pszPlayType))
|
||||
return false;
|
||||
if (!pProperty->GetString("PlayInterval", &c_pszPlayInterval))
|
||||
return false;
|
||||
if (!pProperty->GetString("PlayIntervalVariation", &c_pszPlayIntervalVariation))
|
||||
return false;
|
||||
if (!pProperty->GetString("MaxVolumeAreaPercentage", &c_pszMaxVolumeAreaPercentage))
|
||||
{
|
||||
pData->fMaxVolumeAreaPercentage = 0.0f;
|
||||
}
|
||||
if (!pProperty->GetVector("AmbienceSoundVector", AmbienceSoundVector))
|
||||
return false;
|
||||
|
||||
pData->strPlayType = c_pszPlayType;
|
||||
pData->fPlayInterval = atof(c_pszPlayInterval);
|
||||
pData->fPlayIntervalVariation = atof(c_pszPlayIntervalVariation);
|
||||
if (c_pszMaxVolumeAreaPercentage)
|
||||
pData->fMaxVolumeAreaPercentage = atof(c_pszMaxVolumeAreaPercentage);
|
||||
for (CTokenVector::iterator itor = AmbienceSoundVector.begin(); itor != AmbienceSoundVector.end(); ++itor)
|
||||
pData->AmbienceSoundVector.push_back(*itor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyDungeonBlockDataToString(TPropertyDungeonBlock * pData, CProperty * pProperty)
|
||||
{
|
||||
pProperty->Clear();
|
||||
pProperty->PutString("PropertyType", "DungeonBlock");
|
||||
pProperty->PutString("PropertyName", pData->strName.c_str());
|
||||
pProperty->PutString("DungeonBlockFile", pData->strFileName.c_str());
|
||||
return true;
|
||||
}
|
||||
bool PropertyDungeonBlockStringToData(CProperty * pProperty, TPropertyDungeonBlock * pData)
|
||||
{
|
||||
const char * c_pszPropertyType;
|
||||
const char * c_pszPropertyName;
|
||||
|
||||
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
|
||||
return false;
|
||||
|
||||
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
|
||||
return false;
|
||||
|
||||
if (strcmp(c_pszPropertyType, "DungeonBlock"))
|
||||
return false;
|
||||
|
||||
pData->strName = c_pszPropertyName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char * c_pszDungeonBlockFileName = NULL;
|
||||
if (!pProperty->GetString("dungeonblockfile", &c_pszDungeonBlockFileName))
|
||||
return false;
|
||||
|
||||
pData->strFileName = c_pszDungeonBlockFileName;
|
||||
pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + std::string(".mdatr");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace prt;
|
||||
@@ -0,0 +1,222 @@
|
||||
#ifndef __MapType_Header__
|
||||
#define __MapType_Header__
|
||||
|
||||
class CProperty;
|
||||
|
||||
#include "../eterLib/SkyBox.h"
|
||||
#include "../mileslib/SoundManager.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// Property
|
||||
namespace prt
|
||||
{
|
||||
enum EPropertyType
|
||||
{
|
||||
PROPERTY_TYPE_NONE,
|
||||
PROPERTY_TYPE_TREE,
|
||||
PROPERTY_TYPE_BUILDING,
|
||||
PROPERTY_TYPE_EFFECT,
|
||||
PROPERTY_TYPE_AMBIENCE,
|
||||
PROPERTY_TYPE_DUNGEON_BLOCK,
|
||||
PROPERTY_TYPE_MAX_NUM,
|
||||
};
|
||||
|
||||
const char c_szPropertyTypeName[PROPERTY_TYPE_MAX_NUM][32] =
|
||||
{
|
||||
"None",
|
||||
"Tree",
|
||||
"Building",
|
||||
"Effect",
|
||||
"Ambience",
|
||||
"DungeonBlock"
|
||||
};
|
||||
|
||||
const char c_szPropertyExtension[PROPERTY_TYPE_MAX_NUM][16] =
|
||||
{
|
||||
".pr",
|
||||
".prt",
|
||||
".prb",
|
||||
".pre",
|
||||
".pra",
|
||||
".prd"
|
||||
};
|
||||
|
||||
DWORD GetPropertyType(const char * c_szTypeName);
|
||||
const char * GetPropertyExtension(DWORD dwType);
|
||||
|
||||
struct TPropertyTree
|
||||
{
|
||||
std::string strName;
|
||||
std::string strFileName;
|
||||
|
||||
float fSize;
|
||||
float fVariance;
|
||||
};
|
||||
|
||||
struct TPropertyBuilding
|
||||
{
|
||||
std::string strName;
|
||||
std::string strFileName;
|
||||
std::string strAttributeDataFileName;
|
||||
BOOL isShadowFlag;
|
||||
};
|
||||
|
||||
struct TPropertyEffect
|
||||
{
|
||||
std::string strName;
|
||||
std::string strFileName;
|
||||
};
|
||||
|
||||
enum EAmbiencePlayType
|
||||
{
|
||||
AMBIENCE_PLAY_TYPE_ONCE,
|
||||
AMBIENCE_PLAY_TYPE_STEP,
|
||||
AMBIENCE_PLAY_TYPE_LOOP,
|
||||
AMBIENCE_PLAY_TYPE_MAX_NUM,
|
||||
};
|
||||
|
||||
const char c_szPlayTypeName[AMBIENCE_PLAY_TYPE_MAX_NUM][8] =
|
||||
{
|
||||
"ONCE",
|
||||
"STEP",
|
||||
"LOOP",
|
||||
};
|
||||
|
||||
struct TPropertyAmbience
|
||||
{
|
||||
std::string strName;
|
||||
std::string strPlayType;
|
||||
|
||||
float fPlayInterval;
|
||||
float fPlayIntervalVariation;
|
||||
float fMaxVolumeAreaPercentage;
|
||||
std::vector<std::string> AmbienceSoundVector;
|
||||
};
|
||||
|
||||
struct TPropertyDungeonBlock
|
||||
{
|
||||
std::string strName;
|
||||
std::string strFileName;
|
||||
std::string strAttributeDataFileName;
|
||||
};
|
||||
|
||||
bool PropertyTreeDataToString(TPropertyTree * pData, CProperty * pProperty);
|
||||
bool PropertyTreeStringToData(CProperty * pProperty, TPropertyTree * pData);
|
||||
bool PropertyBuildingDataToString(TPropertyBuilding * pData, CProperty * pProperty);
|
||||
bool PropertyBuildingStringToData(CProperty * pProperty, TPropertyBuilding * pData);
|
||||
bool PropertyEffectDataToString(TPropertyEffect * pData, CProperty * pProperty);
|
||||
bool PropertyEffectStringToData(CProperty * pProperty, TPropertyEffect * pData);
|
||||
bool PropertyAmbienceDataToString(TPropertyAmbience * pData, CProperty * pProperty);
|
||||
bool PropertyAmbienceStringToData(CProperty * pProperty, TPropertyAmbience * pData);
|
||||
bool PropertyDungeonBlockDataToString(TPropertyDungeonBlock * pData, CProperty * pProperty);
|
||||
bool PropertyDungeonBlockStringToData(CProperty * pProperty, TPropertyDungeonBlock * pData);
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// Environment
|
||||
//
|
||||
enum
|
||||
{
|
||||
ENV_DIRLIGHT_BACKGROUND,
|
||||
ENV_DIRLIGHT_CHARACTER,
|
||||
ENV_DIRLIGHT_NUM
|
||||
};
|
||||
|
||||
typedef struct SEnvironmentData
|
||||
{
|
||||
// Light
|
||||
BOOL bDirLightsEnable[ENV_DIRLIGHT_NUM];
|
||||
D3DLIGHT8 DirLights[ENV_DIRLIGHT_NUM];
|
||||
|
||||
// Material
|
||||
D3DMATERIAL8 Material;
|
||||
|
||||
// Fog
|
||||
BOOL bFogEnable;
|
||||
BOOL bDensityFog;
|
||||
|
||||
float m_fFogNearDistance;
|
||||
float m_fFogFarDistance;
|
||||
|
||||
float GetFogNearDistance() const;
|
||||
float GetFogFarDistance() const;
|
||||
|
||||
D3DXCOLOR FogColor;
|
||||
|
||||
// Filtering
|
||||
BOOL bFilteringEnable;
|
||||
D3DXCOLOR FilteringColor;
|
||||
BYTE byFilteringAlphaSrc;
|
||||
BYTE byFilteringAlphaDest;
|
||||
|
||||
// Wind
|
||||
float fWindStrength;
|
||||
float fWindRandom;
|
||||
|
||||
// SkyBox
|
||||
D3DXVECTOR3 v3SkyBoxScale;
|
||||
BOOL bSkyBoxTextureRenderMode;
|
||||
|
||||
BYTE bySkyBoxGradientLevelUpper;
|
||||
BYTE bySkyBoxGradientLevelLower;
|
||||
|
||||
std::string strSkyBoxFaceFileName[6]; //order : front/back/left/right/top/bottom
|
||||
|
||||
|
||||
D3DXVECTOR2 v2CloudScale;
|
||||
float fCloudHeight;
|
||||
D3DXVECTOR2 v2CloudTextureScale;
|
||||
D3DXVECTOR2 v2CloudSpeed;
|
||||
std::string strCloudTextureFileName;
|
||||
TGradientColor CloudGradientColor;
|
||||
|
||||
std::vector<TGradientColor> SkyBoxGradientColorVector;
|
||||
|
||||
// LensFlare
|
||||
BOOL bLensFlareEnable;
|
||||
D3DXCOLOR LensFlareBrightnessColor;
|
||||
float fLensFlareMaxBrightness;
|
||||
|
||||
BOOL bMainFlareEnable;
|
||||
std::string strMainFlareTextureFileName;
|
||||
float fMainFlareSize;
|
||||
|
||||
BOOL bReserve; // 외부에서 설정을 고치지 않음
|
||||
} TEnvironmentData;
|
||||
|
||||
typedef std::map<DWORD, TEnvironmentData*> TEnvironmentDataMap;
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct SScreenPosition {
|
||||
int x;
|
||||
int y;
|
||||
} TScreenPosition;
|
||||
|
||||
typedef D3DXVECTOR3 TPixelPosition;
|
||||
|
||||
float SPixelPosition_CalculateDistanceSq3d(const TPixelPosition& c_rkPPosLeft, const TPixelPosition& c_rkPPosRight);
|
||||
|
||||
typedef struct SCellPosition
|
||||
{
|
||||
SCellPosition()
|
||||
{
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
}
|
||||
|
||||
SCellPosition(int x, int y)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
} TCellPosition;
|
||||
|
||||
const int c_Section_xAttributeCellSize = 50;
|
||||
const int c_Section_yAttributeCellSize = 50;
|
||||
const int c_Section_xCellSize = 100;
|
||||
const int c_Section_yCellSize = 100;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,306 @@
|
||||
#include "StdAfx.h"
|
||||
#include "MapUtil.h"
|
||||
|
||||
void Environment_Init(SEnvironmentData& envData)
|
||||
{
|
||||
for (int i = 0; i < ENV_DIRLIGHT_NUM; ++i)
|
||||
{
|
||||
envData.bDirLightsEnable[i] = false;
|
||||
envData.DirLights[i].Type = D3DLIGHT_DIRECTIONAL;
|
||||
envData.DirLights[i].Direction = D3DXVECTOR3(0.5f, 0.5f, -0.5f);
|
||||
envData.DirLights[i].Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
envData.DirLights[i].Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
envData.DirLights[i].Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
envData.DirLights[i].Ambient = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
envData.DirLights[i].Range = 0.0f; // Used by Point Light & Spot Light
|
||||
envData.DirLights[i].Falloff = 1.0f; // Used by Spot Light
|
||||
envData.DirLights[i].Theta = 0.0f; // Used by Spot Light
|
||||
envData.DirLights[i].Phi = 0.0f; // Used by Spot Light
|
||||
envData.DirLights[i].Attenuation0 = 0.0f;
|
||||
envData.DirLights[i].Attenuation1 = 1.0f;
|
||||
envData.DirLights[i].Attenuation2 = 0.0f;
|
||||
}
|
||||
|
||||
envData.Material.Diffuse = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
envData.Material.Ambient = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
envData.Material.Emissive = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);
|
||||
envData.Material.Specular = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
envData.Material.Power = 0.0f;
|
||||
|
||||
envData.bFogEnable = FALSE;
|
||||
envData.bDensityFog = FALSE;
|
||||
envData.m_fFogNearDistance = 25600.0f * 0.5f;
|
||||
envData.m_fFogFarDistance = 25600.0f * 0.7f;
|
||||
envData.FogColor = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
envData.bFilteringEnable = FALSE;
|
||||
envData.FilteringColor = D3DXCOLOR(0.3f, 0.1f, 0.1f, 0.0f);
|
||||
envData.byFilteringAlphaSrc = D3DBLEND_ONE;
|
||||
envData.byFilteringAlphaDest = D3DBLEND_ONE;
|
||||
|
||||
envData.fWindStrength = 0.2f;
|
||||
envData.fWindRandom = 0.0f;
|
||||
|
||||
envData.v3SkyBoxScale = D3DXVECTOR3(3500.0f, 3500.0f, 3500.0f);
|
||||
envData.bySkyBoxGradientLevelUpper = 0;
|
||||
envData.bySkyBoxGradientLevelLower = 0;
|
||||
envData.bSkyBoxTextureRenderMode = FALSE;
|
||||
|
||||
envData.v2CloudScale = D3DXVECTOR2(200000.0f, 200000.0f);
|
||||
envData.fCloudHeight = 30000.0f;
|
||||
envData.v2CloudTextureScale = D3DXVECTOR2(4.0f, 4.0f);
|
||||
envData.v2CloudSpeed = D3DXVECTOR2(0.001f, 0.001f);
|
||||
envData.strCloudTextureFileName = "";
|
||||
envData.CloudGradientColor.m_FirstColor = .0f;
|
||||
envData.CloudGradientColor.m_SecondColor = .0f;
|
||||
|
||||
envData.SkyBoxGradientColorVector.clear();
|
||||
|
||||
envData.bLensFlareEnable = FALSE;
|
||||
envData.LensFlareBrightnessColor = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
envData.fLensFlareMaxBrightness = 1.0f;
|
||||
|
||||
envData.bMainFlareEnable = FALSE;
|
||||
envData.strMainFlareTextureFileName = "";
|
||||
envData.fMainFlareSize = 0.2f;
|
||||
|
||||
envData.bReserve = FALSE;
|
||||
}
|
||||
|
||||
bool Environment_Load(SEnvironmentData& envData, const char* envFileName)
|
||||
{
|
||||
CTextFileLoader textLoader;
|
||||
|
||||
if (!textLoader.Load(envFileName))
|
||||
return false;
|
||||
|
||||
textLoader.SetTop();
|
||||
|
||||
textLoader.GetTokenBoolean("reserved", &envData.bReserve);
|
||||
|
||||
if (textLoader.SetChildNode("directionallight"))
|
||||
{
|
||||
D3DVECTOR v3Dir;
|
||||
textLoader.GetTokenDirection("direction", &v3Dir);
|
||||
|
||||
if (textLoader.SetChildNode("background"))
|
||||
{
|
||||
envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Direction = v3Dir;
|
||||
textLoader.GetTokenBoolean("enable", &envData.bDirLightsEnable[ENV_DIRLIGHT_BACKGROUND]);
|
||||
textLoader.GetTokenColor("diffuse", &envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Diffuse);
|
||||
textLoader.GetTokenColor("ambient", &envData.DirLights[ENV_DIRLIGHT_BACKGROUND].Ambient);
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
|
||||
if (textLoader.SetChildNode("character"))
|
||||
{
|
||||
envData.DirLights[ENV_DIRLIGHT_CHARACTER].Direction = v3Dir;
|
||||
textLoader.GetTokenBoolean("enable", &envData.bDirLightsEnable[ENV_DIRLIGHT_CHARACTER]);
|
||||
textLoader.GetTokenColor("diffuse", &envData.DirLights[ENV_DIRLIGHT_CHARACTER].Diffuse);
|
||||
textLoader.GetTokenColor("ambient", &envData.DirLights[ENV_DIRLIGHT_CHARACTER].Ambient);
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
|
||||
if (textLoader.SetChildNode("material"))
|
||||
{
|
||||
textLoader.GetTokenColor("diffuse", &envData.Material.Diffuse);
|
||||
textLoader.GetTokenColor("ambient", &envData.Material.Ambient);
|
||||
textLoader.GetTokenColor("emissive", &envData.Material.Emissive);
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
|
||||
if (textLoader.SetChildNode("fog"))
|
||||
{
|
||||
textLoader.GetTokenBoolean("enable", &envData.bFogEnable);
|
||||
textLoader.GetTokenBoolean("isdensity", &envData.bDensityFog);
|
||||
textLoader.GetTokenFloat("neardistance", &envData.m_fFogNearDistance);
|
||||
textLoader.GetTokenFloat("fardistance", &envData.m_fFogFarDistance);
|
||||
textLoader.GetTokenColor("color", &envData.FogColor);
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
|
||||
if (textLoader.SetChildNode("filter"))
|
||||
{
|
||||
textLoader.GetTokenBoolean("enable", (BOOL *) &envData.bFilteringEnable);
|
||||
textLoader.GetTokenColor("color", &envData.FilteringColor);
|
||||
textLoader.GetTokenByte("alphasrc", &envData.byFilteringAlphaSrc);
|
||||
textLoader.GetTokenByte("alphadest", &envData.byFilteringAlphaDest);
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
|
||||
if (textLoader.SetChildNode("skybox"))
|
||||
{
|
||||
textLoader.GetTokenBoolean("btexturerendermode", (BOOL *) &envData.bSkyBoxTextureRenderMode);
|
||||
textLoader.GetTokenVector3("scale", &envData.v3SkyBoxScale);
|
||||
textLoader.GetTokenByte("gradientlevelupper", &envData.bySkyBoxGradientLevelUpper);
|
||||
textLoader.GetTokenByte("gradientlevellower", &envData.bySkyBoxGradientLevelLower);
|
||||
|
||||
textLoader.GetTokenString("frontfacefilename", &envData.strSkyBoxFaceFileName[0]);
|
||||
textLoader.GetTokenString("backfacefilename", &envData.strSkyBoxFaceFileName[1]);
|
||||
textLoader.GetTokenString("leftfacefilename", &envData.strSkyBoxFaceFileName[2]);
|
||||
textLoader.GetTokenString("rightfacefilename", &envData.strSkyBoxFaceFileName[3]);
|
||||
textLoader.GetTokenString("topfacefilename", &envData.strSkyBoxFaceFileName[4]);
|
||||
textLoader.GetTokenString("bottomfacefilename", &envData.strSkyBoxFaceFileName[5]);
|
||||
|
||||
|
||||
textLoader.GetTokenVector2("cloudscale", &envData.v2CloudScale);
|
||||
textLoader.GetTokenFloat("cloudheight", &envData.fCloudHeight);
|
||||
textLoader.GetTokenVector2("cloudtexturescale", &envData.v2CloudTextureScale);
|
||||
textLoader.GetTokenVector2("cloudspeed", &envData.v2CloudSpeed);
|
||||
textLoader.GetTokenString("cloudtexturefilename", &envData.strCloudTextureFileName);
|
||||
|
||||
CTokenVector * pTokenVectorCloudColor;
|
||||
if(textLoader.GetTokenVector("cloudcolor", &pTokenVectorCloudColor))
|
||||
if ( 0 == pTokenVectorCloudColor->size()%8)
|
||||
{
|
||||
envData.CloudGradientColor.m_FirstColor.r = atof(pTokenVectorCloudColor->at(0).c_str());
|
||||
envData.CloudGradientColor.m_FirstColor.g = atof(pTokenVectorCloudColor->at(1).c_str());
|
||||
envData.CloudGradientColor.m_FirstColor.b = atof(pTokenVectorCloudColor->at(2).c_str());
|
||||
envData.CloudGradientColor.m_FirstColor.a = atof(pTokenVectorCloudColor->at(3).c_str());
|
||||
|
||||
envData.CloudGradientColor.m_SecondColor.r = atof(pTokenVectorCloudColor->at(4).c_str());
|
||||
envData.CloudGradientColor.m_SecondColor.g = atof(pTokenVectorCloudColor->at(5).c_str());
|
||||
envData.CloudGradientColor.m_SecondColor.b = atof(pTokenVectorCloudColor->at(6).c_str());
|
||||
envData.CloudGradientColor.m_SecondColor.a = atof(pTokenVectorCloudColor->at(7).c_str());
|
||||
}
|
||||
|
||||
BYTE byGradientCount = envData.bySkyBoxGradientLevelUpper+envData.bySkyBoxGradientLevelLower;
|
||||
CTokenVector * pTokenVector;
|
||||
if (textLoader.GetTokenVector("gradient", &pTokenVector))
|
||||
if (0 == pTokenVector->size()%8)
|
||||
if (byGradientCount == pTokenVector->size()/8)
|
||||
{
|
||||
envData.SkyBoxGradientColorVector.clear();
|
||||
envData.SkyBoxGradientColorVector.resize(byGradientCount);
|
||||
for (DWORD i = 0; i < byGradientCount; ++i)
|
||||
{
|
||||
envData.SkyBoxGradientColorVector[i].m_FirstColor.r = atof(pTokenVector->at(i*8+0).c_str());
|
||||
envData.SkyBoxGradientColorVector[i].m_FirstColor.g = atof(pTokenVector->at(i*8+1).c_str());
|
||||
envData.SkyBoxGradientColorVector[i].m_FirstColor.b = atof(pTokenVector->at(i*8+2).c_str());
|
||||
envData.SkyBoxGradientColorVector[i].m_FirstColor.a = atof(pTokenVector->at(i*8+3).c_str());
|
||||
|
||||
envData.SkyBoxGradientColorVector[i].m_SecondColor.r = atof(pTokenVector->at(i*8+4).c_str());
|
||||
envData.SkyBoxGradientColorVector[i].m_SecondColor.g = atof(pTokenVector->at(i*8+5).c_str());
|
||||
envData.SkyBoxGradientColorVector[i].m_SecondColor.b = atof(pTokenVector->at(i*8+6).c_str());
|
||||
envData.SkyBoxGradientColorVector[i].m_SecondColor.a = atof(pTokenVector->at(i*8+7).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
|
||||
if (textLoader.SetChildNode("lensflare"))
|
||||
{
|
||||
textLoader.GetTokenBoolean("enable", &envData.bLensFlareEnable);
|
||||
textLoader.GetTokenColor("brightnesscolor", &envData.LensFlareBrightnessColor);
|
||||
textLoader.GetTokenFloat("maxbrightness", &envData.fLensFlareMaxBrightness);
|
||||
textLoader.GetTokenBoolean("mainflareenable", &envData.bMainFlareEnable);
|
||||
textLoader.GetTokenString("mainflaretexturefilename", &envData.strMainFlareTextureFileName);
|
||||
textLoader.GetTokenFloat("mainflaresize", &envData.fMainFlareSize);
|
||||
|
||||
textLoader.SetParentNode();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetInterpolatedPosition(float curPositionRate, TPixelPosition * PixelPosition)
|
||||
{
|
||||
}
|
||||
|
||||
float GetLinearInterpolation(float begin, float end, float curRate)
|
||||
{
|
||||
return (end - begin) * curRate + begin;
|
||||
}
|
||||
|
||||
void PixelPositionToAttributeCellPosition(TPixelPosition PixelPosition, TCellPosition * pAttrCellPosition)
|
||||
{
|
||||
pAttrCellPosition->x = PixelPosition.x / c_Section_xAttributeCellSize;
|
||||
pAttrCellPosition->y = PixelPosition.y / c_Section_yAttributeCellSize;
|
||||
}
|
||||
|
||||
void AttributeCellPositionToPixelPosition(TCellPosition AttrCellPosition, TPixelPosition * pPixelPosition)
|
||||
{
|
||||
pPixelPosition->x = AttrCellPosition.x * c_Section_xAttributeCellSize;
|
||||
pPixelPosition->y = AttrCellPosition.y * c_Section_yAttributeCellSize;
|
||||
}
|
||||
|
||||
float GetPixelPositionDistance(const TPixelPosition & c_rsrcPosition, const TPixelPosition & c_rdstPosition)
|
||||
{
|
||||
int idx = c_rsrcPosition.x - c_rdstPosition.x;
|
||||
int idy = c_rsrcPosition.y - c_rdstPosition.y;
|
||||
|
||||
return sqrtf(float(idx*idx + idy*idy));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
CEaseOutInterpolation::CEaseOutInterpolation()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CEaseOutInterpolation::~CEaseOutInterpolation()
|
||||
{
|
||||
}
|
||||
|
||||
void CEaseOutInterpolation::Initialize()
|
||||
{
|
||||
m_fRemainingTime = 0.0f;
|
||||
m_fValue = 0.0f;
|
||||
m_fSpeed = 0.0f;
|
||||
m_fAcceleration = 0.0f;
|
||||
m_fStartValue = 0.0f;
|
||||
m_fLastValue = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
BOOL CEaseOutInterpolation::Setup(float fStart, float fEnd, float fTime)
|
||||
{
|
||||
//for safety
|
||||
if( fabs(fTime) < FLT_EPSILON )
|
||||
{
|
||||
fTime = 0.01f;
|
||||
}
|
||||
|
||||
m_fValue = fStart;
|
||||
m_fStartValue = fStart;
|
||||
m_fLastValue = fStart;
|
||||
|
||||
m_fSpeed = (2.0f * (fEnd - fStart)) / fTime;
|
||||
m_fAcceleration = 2.0f * (fEnd - fStart) / (fTime * fTime) - 2.0f * m_fSpeed / fTime;
|
||||
m_fRemainingTime = fTime;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CEaseOutInterpolation::Interpolate(float fElapsedTime)
|
||||
{
|
||||
m_fLastValue = m_fValue;
|
||||
|
||||
m_fRemainingTime -= fElapsedTime;
|
||||
m_fSpeed += m_fAcceleration * fElapsedTime;
|
||||
m_fValue += m_fSpeed * fElapsedTime;
|
||||
|
||||
if (!isPlaying())
|
||||
{
|
||||
m_fValue = 0.0f;
|
||||
m_fLastValue = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CEaseOutInterpolation::isPlaying()
|
||||
{
|
||||
return m_fRemainingTime > 0.0f;
|
||||
}
|
||||
|
||||
float CEaseOutInterpolation::GetValue()
|
||||
{
|
||||
return m_fValue;
|
||||
}
|
||||
|
||||
float CEaseOutInterpolation::GetChangingValue()
|
||||
{
|
||||
return m_fValue - m_fLastValue;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
void Environment_Init(SEnvironmentData& envData);
|
||||
bool Environment_Load(SEnvironmentData& envData, const char* envFileName);
|
||||
|
||||
|
||||
void GetInterpolatedPosition(float curPositionRate, TPixelPosition * PixelPosition);
|
||||
float GetLinearInterpolation(float begin, float end, float curRate);
|
||||
|
||||
void PixelPositionToAttributeCellPosition(TPixelPosition PixelPosition, TCellPosition * pAttrCellPosition);
|
||||
void AttributeCellPositionToPixelPosition(TCellPosition AttrCellPosition, TPixelPosition * pPixelPosition);
|
||||
|
||||
float GetPixelPositionDistance(const TPixelPosition & c_rsrcPosition, const TPixelPosition & c_rdstPosition);
|
||||
|
||||
class CEaseOutInterpolation
|
||||
{
|
||||
public:
|
||||
CEaseOutInterpolation();
|
||||
virtual ~CEaseOutInterpolation();
|
||||
|
||||
void Initialize();
|
||||
|
||||
BOOL Setup(float fStart, float fEnd, float fTime);
|
||||
void Interpolate(float fElapsedTime);
|
||||
BOOL isPlaying();
|
||||
|
||||
float GetValue();
|
||||
float GetChangingValue();
|
||||
|
||||
protected:
|
||||
float m_fRemainingTime;
|
||||
float m_fValue;
|
||||
float m_fSpeed;
|
||||
float m_fAcceleration;
|
||||
|
||||
float m_fStartValue;
|
||||
float m_fLastValue;
|
||||
};
|
||||
@@ -0,0 +1,148 @@
|
||||
// MonsterAreaInfo.cpp: implementation of the CMonsterAreaInfo class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "MonsterAreaInfo.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CMonsterAreaInfo::CMonsterAreaInfo()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CMonsterAreaInfo::~CMonsterAreaInfo()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::Clear()
|
||||
{
|
||||
SetOrigin(-1, -1);
|
||||
SetSize(-1, -1);
|
||||
RemoveAllMonsters();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetOrigin(long lOriginX, long lOriginY)
|
||||
{
|
||||
m_lOriginX = lOriginX;
|
||||
m_lOriginY = lOriginY;
|
||||
SetLRTB();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetSize(long lSizeX, long lSizeY)
|
||||
{
|
||||
m_lSizeX = lSizeX;
|
||||
m_lSizeY = lSizeY;
|
||||
SetLRTB();
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::GetOrigin(long * plOriginX, long * plOriginY)
|
||||
{
|
||||
*plOriginX = m_lOriginX;
|
||||
*plOriginY = m_lOriginY;
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::GetSize(long * plSizeX, long * plSizeY)
|
||||
{
|
||||
*plSizeX = m_lSizeX;
|
||||
*plSizeY = m_lSizeY;
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetLRTB()
|
||||
{
|
||||
m_lLeft = m_lOriginX - m_lSizeX;
|
||||
m_lTop = m_lOriginY - m_lSizeY;
|
||||
m_lRight = m_lOriginX + m_lSizeX;
|
||||
m_lBottom = m_lOriginY + m_lSizeY;
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetMonsterCount(DWORD dwCount)
|
||||
{
|
||||
m_dwMonsterCount = dwCount;
|
||||
|
||||
if (m_TempMonsterPosVector.size() == dwCount)
|
||||
return;
|
||||
|
||||
m_TempMonsterPosVector.clear();
|
||||
m_TempMonsterPosVector.resize(dwCount);
|
||||
|
||||
for (DWORD dwI = 0; dwI < dwCount; ++dwI)
|
||||
{
|
||||
m_TempMonsterPosVector[dwI].x = (float)random_range(m_lLeft, m_lRight);
|
||||
m_TempMonsterPosVector[dwI].y = (float)random_range(m_lTop, m_lBottom);
|
||||
}
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::SetMonsterDirection(EMonsterDir eMonsterDir)
|
||||
{
|
||||
m_eMonsterDir = eMonsterDir;
|
||||
D3DXMATRIX matRotation;
|
||||
D3DXVECTOR3 v3Direction(0.0f, 1.0f, 0.0f);
|
||||
float fDegree = 0.0f;
|
||||
switch(m_eMonsterDir)
|
||||
{
|
||||
case DIR_RANDOM:
|
||||
fDegree = (float) random_range(0, 7) * 45.0f;
|
||||
break;
|
||||
case DIR_NORTH:
|
||||
fDegree = 0.0f;
|
||||
break;
|
||||
case DIR_NORTHEAST:
|
||||
fDegree = 45.0f;
|
||||
break;
|
||||
case DIR_EAST:
|
||||
fDegree = 90.0f;
|
||||
break;
|
||||
case DIR_SOUTHEAST:
|
||||
fDegree = 135.0f;
|
||||
break;
|
||||
case DIR_SOUTH:
|
||||
fDegree = 180.0f;
|
||||
break;
|
||||
case DIR_SOUTHWEST:
|
||||
fDegree = 225.0f;
|
||||
break;
|
||||
case DIR_WEST:
|
||||
fDegree = 270.0f;
|
||||
break;
|
||||
case DIR_NORTHWEST:
|
||||
fDegree = 315.0f;
|
||||
break;
|
||||
}
|
||||
D3DXMatrixRotationZ(&matRotation, -D3DXToRadian(fDegree));
|
||||
D3DXVec3TransformCoord(&v3Direction, &v3Direction, &matRotation);
|
||||
m_v2Monsterdirection.x = v3Direction.x;
|
||||
m_v2Monsterdirection.y = v3Direction.y;
|
||||
D3DXVec2Normalize(&m_v2Monsterdirection, &m_v2Monsterdirection);
|
||||
}
|
||||
|
||||
void CMonsterAreaInfo::RemoveAllMonsters()
|
||||
{
|
||||
SetMonsterAreaInfoType(MONSTERAREAINFOTYPE_INVALID);
|
||||
|
||||
SetMonsterGroupID(0);
|
||||
|
||||
m_strGroupName.assign("이름없음");
|
||||
m_strLeaderName.assign("이름없음");
|
||||
SetMonsterGroupFollowerCount(0);
|
||||
|
||||
SetMonsterVID(0);
|
||||
m_strMonsterName.assign("이름없음");
|
||||
|
||||
SetMonsterCount(0);
|
||||
SetMonsterDirection(DIR_NORTH);
|
||||
|
||||
m_TempMonsterPosVector.clear();
|
||||
}
|
||||
|
||||
D3DXVECTOR2 CMonsterAreaInfo::GetTempMonsterPos(DWORD dwIndex)
|
||||
{
|
||||
if (dwIndex >= m_TempMonsterPosVector.size())
|
||||
return D3DXVECTOR2(0.0f, 0.0f);
|
||||
return m_TempMonsterPosVector[dwIndex];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
// MonsterAreaInfo.h: interface for the CMonsterAreaInfo class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_MONSTERAREAINFO_H__B177E257_2EB2_4CE5_89D3_D06B5618BE1B__INCLUDED_)
|
||||
#define AFX_MONSTERAREAINFO_H__B177E257_2EB2_4CE5_89D3_D06B5618BE1B__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CMonsterAreaInfo
|
||||
{
|
||||
public:
|
||||
enum EMonsterAreaInfoType
|
||||
{
|
||||
MONSTERAREAINFOTYPE_INVALID,
|
||||
MONSTERAREAINFOTYPE_MONSTER,
|
||||
MONSTERAREAINFOTYPE_GROUP,
|
||||
};
|
||||
enum EMonsterDir
|
||||
{
|
||||
DIR_RANDOM = 0,
|
||||
DIR_NORTH,
|
||||
DIR_NORTHEAST,
|
||||
DIR_EAST,
|
||||
DIR_SOUTHEAST,
|
||||
DIR_SOUTH,
|
||||
DIR_SOUTHWEST,
|
||||
DIR_WEST,
|
||||
DIR_NORTHWEST
|
||||
};
|
||||
|
||||
CMonsterAreaInfo();
|
||||
virtual ~CMonsterAreaInfo();
|
||||
|
||||
void SetID(DWORD dwID) { m_dwID = dwID; }
|
||||
DWORD GetID() { return m_dwID; }
|
||||
|
||||
void Clear();
|
||||
|
||||
//
|
||||
void SetOrigin(long lOriginX, long lOriginY);
|
||||
void GetOrigin(long * plOriginX, long * plOriginY);
|
||||
|
||||
void SetSize(long lSizeX, long lSizeY);
|
||||
void GetSize(long * plSizeX, long * plSizeY);
|
||||
|
||||
long GetLeft() { return m_lLeft; }
|
||||
long GetTop() { return m_lTop; }
|
||||
long GetRight() { return m_lRight; }
|
||||
long GetBottom() { return m_lBottom; }
|
||||
|
||||
public:
|
||||
void SetMonsterAreaInfoType(EMonsterAreaInfoType eMonsterAreaInfoType) { m_eMonsterAreaInfoType = eMonsterAreaInfoType; }
|
||||
EMonsterAreaInfoType GetMonsterAreaInfoType() { return m_eMonsterAreaInfoType; }
|
||||
|
||||
public:
|
||||
void SetMonsterGroupID(DWORD dwGroupID) { m_dwGroupID = dwGroupID;}
|
||||
void SetMonsterGroupName(std::string strGroupName) { m_strGroupName = strGroupName; }
|
||||
void SetMonsterGroupLeaderName(std::string strGroupLeaderName) { m_strLeaderName = strGroupLeaderName; }
|
||||
void SetMonsterGroupFollowerCount(DWORD dwFollowerCount) { m_dwFollowerCount = dwFollowerCount; }
|
||||
|
||||
DWORD GetMonsterGroupID() { return m_dwGroupID; }
|
||||
std::string GetMonsterGroupName() { return m_strGroupName; }
|
||||
std::string GetMonsterGroupLeaderName() { return m_strLeaderName; }
|
||||
DWORD GetMonsterGroupFollowerCount() { return m_dwFollowerCount; }
|
||||
|
||||
public:
|
||||
void SetMonsterName(std::string strMonsterName) { m_strMonsterName = strMonsterName; }
|
||||
void SetMonsterVID(DWORD dwVID) { m_dwVID = dwVID; }
|
||||
|
||||
std::string GetMonsterName() { return m_strMonsterName; }
|
||||
DWORD GetMonsterVID() { return m_dwVID; }
|
||||
|
||||
public:
|
||||
void SetMonsterCount(DWORD dwCount);
|
||||
void SetMonsterDirection(EMonsterDir eMonsterDir);
|
||||
void RemoveAllMonsters();
|
||||
|
||||
DWORD GetMonsterCount() { return m_dwMonsterCount; }
|
||||
EMonsterDir GetMonsterDir() { return m_eMonsterDir; }
|
||||
D3DXVECTOR2 GetMonsterDirVector() { return m_v2Monsterdirection; }
|
||||
D3DXVECTOR2 GetTempMonsterPos(DWORD dwIndex);
|
||||
|
||||
protected:
|
||||
void SetLRTB();
|
||||
|
||||
protected:
|
||||
EMonsterAreaInfoType m_eMonsterAreaInfoType;
|
||||
|
||||
// Group Type Á¤º¸
|
||||
DWORD m_dwGroupID;
|
||||
std::string m_strGroupName;
|
||||
std::string m_strLeaderName;
|
||||
DWORD m_dwFollowerCount;
|
||||
|
||||
// Monster Type Á¤º¸
|
||||
DWORD m_dwVID;
|
||||
std::string m_strMonsterName;
|
||||
|
||||
// °øÅë Á¤º¸
|
||||
DWORD m_dwMonsterCount;
|
||||
EMonsterDir m_eMonsterDir;
|
||||
D3DXVECTOR2 m_v2Monsterdirection;
|
||||
|
||||
DWORD m_dwID;
|
||||
|
||||
long m_lOriginX;
|
||||
long m_lOriginY;
|
||||
long m_lSizeX;
|
||||
long m_lSizeY;
|
||||
|
||||
long m_lLeft;
|
||||
long m_lRight;
|
||||
long m_lTop;
|
||||
long m_lBottom;
|
||||
|
||||
std::vector<D3DXVECTOR2> m_TempMonsterPosVector;
|
||||
};
|
||||
|
||||
typedef std::vector<CMonsterAreaInfo *> TMonsterAreaInfoPtrVector;
|
||||
typedef TMonsterAreaInfoPtrVector::iterator TMonsterAreaInfoPtrVectorIterator;
|
||||
|
||||
#endif // !defined(AFX_MONSTERAREAINFO_H__B177E257_2EB2_4CE5_89D3_D06B5618BE1B__INCLUDED_)
|
||||
@@ -0,0 +1,177 @@
|
||||
#include "StdAfx.h"
|
||||
#include "PhysicsObject.h"
|
||||
|
||||
const float c_fFrameTime = 0.02f;
|
||||
const float EPSILON = 0.001f;
|
||||
|
||||
IPhysicsWorld* IPhysicsWorld::ms_pWorld = NULL;
|
||||
IObjectManager* IObjectManager::ms_ObjManager = NULL;
|
||||
|
||||
void CPhysicsObject::Update(float fElapsedTime)
|
||||
{
|
||||
if (m_xPushingPosition.isPlaying())
|
||||
m_xPushingPosition.Interpolate(fElapsedTime);
|
||||
if (m_yPushingPosition.isPlaying())
|
||||
m_yPushingPosition.Interpolate(fElapsedTime);
|
||||
}
|
||||
|
||||
void CPhysicsObject::Accumulate(D3DXVECTOR3 * pv3Position)
|
||||
{
|
||||
// If object is moving, give minor power to object.
|
||||
float fForce = 0.0f;
|
||||
|
||||
if (fabs(m_v3Velocity.x) < EPSILON ||
|
||||
fabs(m_v3Velocity.y) < EPSILON ||
|
||||
fabs(m_v3Velocity.z) < EPSILON )
|
||||
{
|
||||
fForce -= (m_fMass * m_fFriction);
|
||||
}
|
||||
|
||||
m_v3Acceleration = m_v3Direction * (fForce / m_fMass);
|
||||
m_v3Velocity += m_v3Acceleration;
|
||||
if (m_v3Velocity.x * m_v3Direction.x < EPSILON)
|
||||
{
|
||||
m_v3Velocity.x = 0.0f;
|
||||
m_v3Direction.x = 0.0f;
|
||||
}
|
||||
if (m_v3Velocity.y * m_v3Direction.y < EPSILON)
|
||||
{
|
||||
m_v3Velocity.y = 0.0f;
|
||||
m_v3Direction.y = 0.0f;
|
||||
}
|
||||
if (m_v3Velocity.z * m_v3Direction.z < EPSILON)
|
||||
{
|
||||
m_v3Velocity.z = 0.0f;
|
||||
m_v3Direction.z = 0.0f;
|
||||
}
|
||||
|
||||
pv3Position->x += m_v3Velocity.x;
|
||||
pv3Position->y += m_v3Velocity.y;
|
||||
pv3Position->z += m_v3Velocity.z;
|
||||
}
|
||||
|
||||
void CPhysicsObject::IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition, float fForce)
|
||||
{
|
||||
// Accumulate Acceleration by External Force
|
||||
m_v3Acceleration = m_v3Direction * (fForce / m_fMass);
|
||||
m_v3Velocity = m_v3Acceleration;
|
||||
/*
|
||||
Tracenf("force %f, mass %f, accel (%f, %f, %f)", fForce, m_fMass,
|
||||
m_v3Acceleration.x,
|
||||
m_v3Acceleration.y,
|
||||
m_v3Acceleration.z);
|
||||
*/
|
||||
// NOTE : 최종 위치를 구해둔다. 근데 100보다 크다면? ;
|
||||
const int LoopValue = 100;
|
||||
D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f);
|
||||
|
||||
for(int i = 0; i < LoopValue; ++i)
|
||||
{
|
||||
Accumulate(&v3Movement);
|
||||
|
||||
// VICTIM_COLLISION_TEST
|
||||
IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld();
|
||||
if (pWorld)
|
||||
{
|
||||
if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement))
|
||||
{
|
||||
Initialize();
|
||||
return;
|
||||
|
||||
//for (float fRatio = 0.0f; fRatio < 1.0f; fRatio += 0.1f)
|
||||
//{
|
||||
// // 좀더 정밀하게 체크한다
|
||||
// if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement * fRatio))
|
||||
// {
|
||||
// v3Movement = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//break;
|
||||
}
|
||||
}
|
||||
// VICTIM_COLLISION_TEST_END
|
||||
|
||||
if (fabs(m_v3Velocity.x) < EPSILON &&
|
||||
fabs(m_v3Velocity.y) < EPSILON &&
|
||||
fabs(m_v3Velocity.z) < EPSILON )
|
||||
break;
|
||||
}
|
||||
|
||||
SetLastPosition(v3Movement, float(LoopValue) * c_fFrameTime);
|
||||
|
||||
if( m_pActorInstance )
|
||||
{
|
||||
IObjectManager* pObjectManager = IObjectManager::GetObjectManager();
|
||||
pObjectManager->AdjustCollisionWithOtherObjects( m_pActorInstance );
|
||||
}
|
||||
}
|
||||
|
||||
void CPhysicsObject::SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime)
|
||||
{
|
||||
m_v3LastPosition.x = float(c_rPosition.x);
|
||||
m_v3LastPosition.y = float(c_rPosition.y);
|
||||
m_v3LastPosition.z = float(c_rPosition.z);
|
||||
m_xPushingPosition.Setup(0.0f, c_rPosition.x, fBlendingTime);
|
||||
m_yPushingPosition.Setup(0.0f, c_rPosition.y, fBlendingTime);
|
||||
}
|
||||
|
||||
void CPhysicsObject::GetLastPosition(TPixelPosition * pPosition)
|
||||
{
|
||||
pPosition->x = (m_v3LastPosition.x);
|
||||
pPosition->y = (m_v3LastPosition.y);
|
||||
pPosition->z = (m_v3LastPosition.z);
|
||||
}
|
||||
|
||||
void CPhysicsObject::SetDirection(const D3DXVECTOR3 & c_rv3Direction)
|
||||
{
|
||||
m_v3Direction.x = c_rv3Direction.x;
|
||||
m_v3Direction.y = c_rv3Direction.y;
|
||||
m_v3Direction.z = c_rv3Direction.z;
|
||||
}
|
||||
|
||||
float CPhysicsObject::GetXMovement()
|
||||
{
|
||||
return m_xPushingPosition.GetChangingValue();
|
||||
}
|
||||
|
||||
float CPhysicsObject::GetYMovement()
|
||||
{
|
||||
return m_yPushingPosition.GetChangingValue();
|
||||
}
|
||||
|
||||
bool CPhysicsObject::isBlending()
|
||||
{
|
||||
// NOTE : IncreaseExternalForce() 에 의해 밀리는 처리중인가?
|
||||
if (0.0f != D3DXVec3Length(&m_v3Velocity))
|
||||
return true;
|
||||
|
||||
// NOTE : SetLastPosition() 에 의해 밀리는 처리중인가?
|
||||
if (m_xPushingPosition.isPlaying() ||
|
||||
m_yPushingPosition.isPlaying())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPhysicsObject::Initialize()
|
||||
{
|
||||
m_fMass = 1.0f;
|
||||
m_fFriction = 0.3f;
|
||||
m_v3Direction = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_v3Acceleration = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_v3Velocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
m_v3LastPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
m_xPushingPosition.Initialize();
|
||||
m_yPushingPosition.Initialize();
|
||||
}
|
||||
|
||||
CPhysicsObject::CPhysicsObject()
|
||||
{
|
||||
m_pActorInstance = NULL;
|
||||
}
|
||||
|
||||
CPhysicsObject::~CPhysicsObject()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#include "MapUtil.h"
|
||||
|
||||
class IPhysicsWorld
|
||||
{
|
||||
public:
|
||||
IPhysicsWorld()
|
||||
{
|
||||
assert(ms_pWorld == NULL);
|
||||
ms_pWorld = this;
|
||||
}
|
||||
|
||||
virtual ~IPhysicsWorld()
|
||||
{
|
||||
if (this == ms_pWorld)
|
||||
ms_pWorld = NULL;
|
||||
}
|
||||
|
||||
static IPhysicsWorld* GetPhysicsWorld()
|
||||
{
|
||||
return ms_pWorld;
|
||||
}
|
||||
|
||||
virtual bool isPhysicalCollision(const D3DXVECTOR3 & c_rvCheckPosition) = 0;
|
||||
|
||||
private:
|
||||
static IPhysicsWorld* ms_pWorld;
|
||||
};
|
||||
|
||||
class CActorInstance;
|
||||
//NOTE : 맘에 안들지만 Dependency Inversion을 막고 이전과 동일한 interface를 유지하기 위해서 이방식대로 간다
|
||||
//하지만 제대로 설계를 한다면 world와 live object들의 관리는 조금더 base project에서 (gamelib이나 더 base project에서 해야 한다 )
|
||||
class IObjectManager
|
||||
{
|
||||
public:
|
||||
IObjectManager()
|
||||
{
|
||||
assert(ms_ObjManager == NULL);
|
||||
ms_ObjManager = this;
|
||||
}
|
||||
|
||||
virtual ~IObjectManager()
|
||||
{
|
||||
if (this == ms_ObjManager)
|
||||
ms_ObjManager = NULL;
|
||||
}
|
||||
|
||||
static IObjectManager* GetObjectManager()
|
||||
{
|
||||
return ms_ObjManager;
|
||||
}
|
||||
|
||||
virtual void AdjustCollisionWithOtherObjects(CActorInstance* pInst ) = 0;
|
||||
|
||||
private:
|
||||
static IObjectManager* ms_ObjManager;
|
||||
};
|
||||
|
||||
class CPhysicsObject
|
||||
{
|
||||
public:
|
||||
CPhysicsObject();
|
||||
virtual ~CPhysicsObject();
|
||||
|
||||
void Initialize();
|
||||
|
||||
void Update(float fElapsedTime);
|
||||
|
||||
bool isBlending();
|
||||
|
||||
void SetDirection(const D3DXVECTOR3 & c_rv3Direction);
|
||||
void IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition, float fForce);
|
||||
void SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime);
|
||||
void GetLastPosition(TPixelPosition * pPosition);
|
||||
|
||||
float GetXMovement();
|
||||
float GetYMovement();
|
||||
void ClearSavingMovement();
|
||||
|
||||
void SetActorInstance( CActorInstance* pInst ) { m_pActorInstance = pInst; }
|
||||
CActorInstance* GetActorInstance() { return m_pActorInstance; }
|
||||
|
||||
protected:
|
||||
void Accumulate(D3DXVECTOR3 * pv3Position);
|
||||
|
||||
protected:
|
||||
float m_fMass;
|
||||
float m_fFriction;
|
||||
D3DXVECTOR3 m_v3Direction;
|
||||
D3DXVECTOR3 m_v3Acceleration;
|
||||
D3DXVECTOR3 m_v3Velocity;
|
||||
|
||||
D3DXVECTOR3 m_v3LastPosition;
|
||||
CEaseOutInterpolation m_xPushingPosition;
|
||||
CEaseOutInterpolation m_yPushingPosition;
|
||||
|
||||
CActorInstance* m_pActorInstance;
|
||||
};
|
||||
@@ -0,0 +1,269 @@
|
||||
#include "StdAfx.h"
|
||||
#include <string.h>
|
||||
#include "../eterBase/TempFile.h"
|
||||
|
||||
#include "PropertyManager.h"
|
||||
#include "Property.h"
|
||||
/*
|
||||
* CProperty 파일 포맷
|
||||
*
|
||||
* 0 ~ 4 bytes: fourcc
|
||||
* 5 ~ 6 bytes: \r\n
|
||||
*
|
||||
* 그 이후의 바이트들은 텍스트 파일 로더와 같은 구조
|
||||
*/
|
||||
CProperty::CProperty(const char * c_pszFileName) : mc_pFileName(NULL), m_dwCRC(0)
|
||||
{
|
||||
m_stFileName = c_pszFileName;
|
||||
StringPath(m_stFileName);
|
||||
|
||||
mc_pFileName = strrchr(m_stFileName.c_str(), '/');
|
||||
|
||||
if (!mc_pFileName)
|
||||
mc_pFileName = m_stFileName.c_str();
|
||||
else
|
||||
++mc_pFileName;
|
||||
}
|
||||
|
||||
CProperty::~CProperty()
|
||||
{
|
||||
}
|
||||
|
||||
DWORD CProperty::GetCRC()
|
||||
{
|
||||
return m_dwCRC;
|
||||
}
|
||||
|
||||
const char * CProperty::GetFileName()
|
||||
{
|
||||
return (m_stFileName.c_str());
|
||||
}
|
||||
|
||||
bool CProperty::GetString(const char * c_pszKey, const char ** c_ppString)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
|
||||
|
||||
// printf("GetString %s %d\n", stTempKey.c_str(), m_stTokenMap.size());
|
||||
|
||||
if (m_stTokenMap.end() == it)
|
||||
return false;
|
||||
|
||||
*c_ppString = it->second[0].c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CProperty::GetSize()
|
||||
{
|
||||
return m_stTokenMap.size();
|
||||
}
|
||||
|
||||
bool CProperty::GetVector(const char * c_pszKey, CTokenVector & rTokenVector)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
|
||||
|
||||
if (m_stTokenMap.end() == it)
|
||||
return false;
|
||||
|
||||
// NOTE : 튕김 현상 발견
|
||||
// std::copy(rTokenVector.begin(), it->second.begin(), it->second.end());
|
||||
// NOTE : 레퍼런스에는 이런 식으로 하게끔 되어 있음
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// template <class InputIterator, class OutputIterator>
|
||||
// OutputIterator copy(InputIterator first, InputIterator last,
|
||||
// OutputIterator result);
|
||||
//
|
||||
// vector<int> V(5);
|
||||
// iota(V.begin(), V.end(), 1);
|
||||
// list<int> L(V.size());
|
||||
// copy(V.begin(), V.end(), L.begin());
|
||||
// assert(equal(V.begin(), V.end(), L.begin()));
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 헌데 그래도 튕김. - [levites]
|
||||
// std::copy(it->second.begin(), it->second.end(), rTokenVector.begin());
|
||||
|
||||
// 결국 이렇게.. - [levites]
|
||||
// 현재 사용하는 곳 : WorldEditor/Dialog/MapObjectPropertyPageBuilding.cpp
|
||||
CTokenVector & rSourceTokenVector = it->second;
|
||||
CTokenVector::iterator itor = rSourceTokenVector.begin();
|
||||
for (; itor != rSourceTokenVector.end(); ++itor)
|
||||
{
|
||||
rTokenVector.push_back(*itor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProperty::PutString(const char * c_pszKey, const char * c_pszString)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
|
||||
// 이미 있는걸 지움
|
||||
CTokenVectorMap::iterator itor = m_stTokenMap.find(stTempKey);
|
||||
|
||||
if (itor != m_stTokenMap.end())
|
||||
m_stTokenMap.erase(itor);
|
||||
|
||||
CTokenVector tokenVector;
|
||||
tokenVector.push_back(c_pszString);
|
||||
|
||||
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, tokenVector));
|
||||
}
|
||||
|
||||
void CProperty::PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector)
|
||||
{
|
||||
std::string stTempKey = c_pszKey;
|
||||
stl_lowers(stTempKey);
|
||||
|
||||
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, c_rTokenVector));
|
||||
}
|
||||
|
||||
void GetTimeString(char * str, time_t ct)
|
||||
{
|
||||
struct tm tm;
|
||||
tm = *localtime(&ct);
|
||||
|
||||
_snprintf(str, 15, "%04d%02d%02d%02d%02d%02d",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
}
|
||||
|
||||
bool CProperty::Save(const char * c_pszFileName)
|
||||
{
|
||||
CTempFile file;
|
||||
|
||||
DWORD fourcc = MAKEFOURCC('Y', 'P', 'R', 'T');
|
||||
file.Write(&fourcc, sizeof(DWORD));
|
||||
file.Write("\r\n", 2);
|
||||
|
||||
if (0 == m_stCRC.length())
|
||||
{
|
||||
char szCRC[MAX_PATH + 16 + 1];
|
||||
|
||||
GetTimeString(szCRC, time(0));
|
||||
strcpy(szCRC + strlen(szCRC), c_pszFileName);
|
||||
|
||||
m_dwCRC = CPropertyManager::Instance().GetUniqueCRC(szCRC);
|
||||
_snprintf(szCRC, sizeof(szCRC), "%u", m_dwCRC);
|
||||
|
||||
m_stCRC.assign(szCRC);
|
||||
}
|
||||
|
||||
file.Write(m_stCRC.c_str(), m_stCRC.length());
|
||||
file.Write("\r\n", 2);
|
||||
|
||||
CTokenVectorMap::iterator itor = m_stTokenMap.begin();
|
||||
char buf[4096 + 1];
|
||||
|
||||
while (itor != m_stTokenMap.end())
|
||||
{
|
||||
CTokenVector & tokenVector = itor->second;
|
||||
|
||||
int len = _snprintf(buf, sizeof(buf), "%s\t", itor->first.c_str());
|
||||
file.Write(buf, len);
|
||||
|
||||
for (DWORD i = 0; i < tokenVector.size(); ++i)
|
||||
{
|
||||
len = _snprintf(buf, sizeof(buf), "\t\"%s\"", tokenVector[i].c_str());
|
||||
file.Write(buf, len);
|
||||
}
|
||||
|
||||
file.Write("\r\n", 2);
|
||||
++itor;
|
||||
}
|
||||
|
||||
file.Close();
|
||||
return CPropertyManager::Instance().Put(c_pszFileName, file.GetFileName());
|
||||
}
|
||||
|
||||
bool CProperty::ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName)
|
||||
{
|
||||
const char * pcData = (const char *) c_pvData;
|
||||
|
||||
if (*(DWORD *) pcData != MAKEFOURCC('Y', 'P', 'R', 'T'))
|
||||
return false;
|
||||
|
||||
pcData += sizeof(DWORD);
|
||||
|
||||
if (*pcData != '\r' || *(pcData + 1) != '\n')
|
||||
{
|
||||
TraceError("CProperty::ReadFromMemory: File format error after FourCC: %s\n", c_pszFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
pcData += 2;
|
||||
|
||||
CTokenVector stTokenVector;
|
||||
/*
|
||||
char szTimeStamp[64];
|
||||
memcpy(szTimeStamp, pcData, 14);
|
||||
szTimeStamp[14] = '\0';
|
||||
pcData += 14;
|
||||
|
||||
if (*pcData != '\r' || *(pcData + 1) != '\n')
|
||||
{
|
||||
TraceError("CProperty::ReadFromMemory: File format error after TimeStamp: %s\n", c_pszFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string m_stTimeStamp;
|
||||
|
||||
m_stTimeStamp = szTimeStamp;
|
||||
|
||||
int iTimeStampLen = 14 + _snprintf(szTimeStamp + 14, 64 - 14, "%s", mc_pFileName);
|
||||
m_dwCRC = GetCRC32(szTimeStamp, iTimeStampLen);
|
||||
|
||||
char tmp[64];
|
||||
sprintf(tmp, "%u", m_dwCRC);
|
||||
m_stCRC.assign(tmp);
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2 + 14 + 2), pcData);
|
||||
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
std::string stKey = stTokenVector[0];
|
||||
|
||||
stTokenVector.erase(stTokenVector.begin());
|
||||
PutVector(stKey.c_str(), stTokenVector);
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2), pcData);
|
||||
|
||||
m_stCRC = textFileLoader.GetLineString(0);
|
||||
m_dwCRC = atoi(m_stCRC.c_str());
|
||||
|
||||
for (DWORD i = 1; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
if (!textFileLoader.SplitLine(i, &stTokenVector))
|
||||
continue;
|
||||
|
||||
stl_lowers(stTokenVector[0]);
|
||||
std::string stKey = stTokenVector[0];
|
||||
|
||||
stTokenVector.erase(stTokenVector.begin());
|
||||
PutVector(stKey.c_str(), stTokenVector);
|
||||
}
|
||||
|
||||
//Tracef("Property: %s\n", c_pszFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CProperty::Clear()
|
||||
{
|
||||
m_stTokenMap.clear();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class CProperty
|
||||
{
|
||||
public:
|
||||
CProperty(const char * c_pszFileName);
|
||||
~CProperty();
|
||||
|
||||
void Clear();
|
||||
bool ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName);
|
||||
|
||||
const char * GetFileName();
|
||||
|
||||
bool GetVector(const char * c_pszKey, CTokenVector & rTokenVector);
|
||||
bool GetString(const char * c_pszKey, const char ** c_ppString);
|
||||
|
||||
void PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector);
|
||||
void PutString(const char * c_pszKey, const char * c_pszString);
|
||||
|
||||
bool Save(const char * c_pszFileName);
|
||||
|
||||
DWORD GetSize();
|
||||
DWORD GetCRC();
|
||||
|
||||
protected:
|
||||
std::string m_stFileName;
|
||||
std::string m_stCRC;
|
||||
const char * mc_pFileName;
|
||||
DWORD m_dwCRC;
|
||||
|
||||
CTokenVectorMap m_stTokenMap;
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "StdAfx.h"
|
||||
#include "PropertyLoader.h"
|
||||
#include "PropertyManager.h"
|
||||
#include "Property.h"
|
||||
|
||||
bool CPropertyLoader::OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName)
|
||||
{
|
||||
std::string stPathName = "";
|
||||
stPathName += c_szPathName;
|
||||
stPathName += c_szFileName;
|
||||
|
||||
CPropertyLoader PropertyLoader;
|
||||
PropertyLoader.SetPropertyManager(m_pPropertyManager);
|
||||
PropertyLoader.Create(c_szFilter, stPathName.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyLoader::OnFile(const char* c_szPathName, const char* c_szFileName)
|
||||
{
|
||||
RegisterFile(c_szPathName, c_szFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CPropertyLoader::RegisterFile(const char * c_szPathName, const char * c_szFileName)
|
||||
{
|
||||
std::string strFileName = "";
|
||||
strFileName += c_szPathName;
|
||||
strFileName += c_szFileName;
|
||||
|
||||
std::string stExt;
|
||||
GetFileExtension(strFileName.c_str(), strFileName.length(), &stExt);
|
||||
|
||||
stl_lowers(stExt);
|
||||
stl_lowers(strFileName);
|
||||
|
||||
// 패스를 소문자로 만들고 \\ 는 / 로 바꾼다.
|
||||
StringPath(strFileName);
|
||||
|
||||
// 예약된 CRC 처리 (지워진 CRC)
|
||||
if (0 == strFileName.compare("property/reserve"))
|
||||
{
|
||||
m_pPropertyManager->LoadReservedCRC(strFileName.c_str());
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CProperty * pProperty;
|
||||
|
||||
if (m_pPropertyManager->Register(strFileName.c_str(), &pProperty))
|
||||
return pProperty->GetCRC();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CPropertyLoader::SetPropertyManager(CPropertyManager * pPropertyManager)
|
||||
{
|
||||
m_pPropertyManager = pPropertyManager;
|
||||
}
|
||||
|
||||
CPropertyLoader::CPropertyLoader()
|
||||
{
|
||||
m_pPropertyManager = NULL;
|
||||
}
|
||||
|
||||
CPropertyLoader::~CPropertyLoader()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "../eterbase/FileDir.h"
|
||||
|
||||
class CPropertyManager;
|
||||
|
||||
class CPropertyLoader : public CDir
|
||||
{
|
||||
public:
|
||||
CPropertyLoader();
|
||||
virtual ~CPropertyLoader();
|
||||
|
||||
void SetPropertyManager(CPropertyManager * pPropertyManager);
|
||||
DWORD RegisterFile(const char* c_szPathName, const char* c_szFileName);
|
||||
|
||||
virtual bool OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName);
|
||||
virtual bool OnFile(const char* c_szPathName, const char* c_szFileName);
|
||||
|
||||
protected:
|
||||
CPropertyManager * m_pPropertyManager;
|
||||
};
|
||||
@@ -0,0 +1,255 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterPack/EterPackManager.h"
|
||||
|
||||
#include "PropertyManager.h"
|
||||
#include "Property.h"
|
||||
|
||||
CPropertyManager::CPropertyManager() : m_isFileMode(true)
|
||||
{
|
||||
}
|
||||
|
||||
CPropertyManager::~CPropertyManager()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
bool CPropertyManager::Initialize(const char * c_pszPackFileName)
|
||||
{
|
||||
if (c_pszPackFileName)
|
||||
{
|
||||
if (!m_pack.Create(m_fileDict, c_pszPackFileName, "", true))
|
||||
{
|
||||
LogBoxf("Cannot open property pack file (filename %s)", c_pszPackFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isFileMode = false;
|
||||
|
||||
TDataPositionMap & indexMap = m_pack.GetIndexMap();
|
||||
|
||||
TDataPositionMap::iterator itor = indexMap.begin();
|
||||
|
||||
typedef std::map<DWORD, TEterPackIndex *> TDataPositionMap;
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (indexMap.end() != itor)
|
||||
{
|
||||
TEterPackIndex * pIndex = itor->second;
|
||||
++itor;
|
||||
|
||||
if (!stricmp("property/reserve", pIndex->filename))
|
||||
{
|
||||
LoadReservedCRC(pIndex->filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Register(pIndex->filename))
|
||||
continue;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isFileMode = true;
|
||||
// NOTE : 여기서 Property를 등록시키면 WorldEditor에서 이상이 생김 ;
|
||||
// 또한, Property Tree List에도 등록을 시켜야 되기 때문에 바깥쪽에서.. - [levites]
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::BuildPack()
|
||||
{
|
||||
if (!m_pack.Create(m_fileDict, "property", ""))
|
||||
return false;
|
||||
|
||||
WIN32_FIND_DATA fdata;
|
||||
HANDLE hFind = FindFirstFile("property\\*", &fdata);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
continue;
|
||||
|
||||
char szSourceFileName[256 + 1];
|
||||
_snprintf(szSourceFileName, sizeof(szSourceFileName), "property\\%s", fdata.cFileName);
|
||||
|
||||
m_pack.Put(fdata.cFileName, szSourceFileName,COMPRESSED_TYPE_NONE,"");
|
||||
}
|
||||
while (FindNextFile(hFind, &fdata));
|
||||
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::LoadReservedCRC(const char * c_pszFileName)
|
||||
{
|
||||
CMappedFile file;
|
||||
LPCVOID c_pvData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
|
||||
return false;
|
||||
|
||||
CMemoryTextFileLoader textFileLoader;
|
||||
textFileLoader.Bind(file.Size(), c_pvData);
|
||||
|
||||
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
|
||||
{
|
||||
const char * pszLine = textFileLoader.GetLineString(i).c_str();
|
||||
|
||||
if (!pszLine || !*pszLine)
|
||||
continue;
|
||||
|
||||
ReserveCRC(atoi(pszLine));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPropertyManager::ReserveCRC(DWORD dwCRC)
|
||||
{
|
||||
m_ReservedCRCSet.insert(dwCRC);
|
||||
}
|
||||
|
||||
DWORD CPropertyManager::GetUniqueCRC(const char * c_szSeed)
|
||||
{
|
||||
std::string stTmp = c_szSeed;
|
||||
|
||||
while (1)
|
||||
{
|
||||
DWORD dwCRC = GetCRC32(stTmp.c_str(), stTmp.length());
|
||||
|
||||
if (m_ReservedCRCSet.find(dwCRC) == m_ReservedCRCSet.end() &&
|
||||
m_PropertyByCRCMap.find(dwCRC) == m_PropertyByCRCMap.end())
|
||||
return dwCRC;
|
||||
|
||||
char szAdd[2];
|
||||
_snprintf(szAdd, sizeof(szAdd), "%d", random() % 10);
|
||||
stTmp += szAdd;
|
||||
}
|
||||
}
|
||||
|
||||
bool CPropertyManager::Register(const char * c_pszFileName, CProperty ** ppProperty)
|
||||
{
|
||||
CMappedFile file;
|
||||
LPCVOID c_pvData;
|
||||
|
||||
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
|
||||
return false;
|
||||
|
||||
CProperty * pProperty = new CProperty(c_pszFileName);
|
||||
|
||||
if (!pProperty->ReadFromMemory(c_pvData, file.Size(), c_pszFileName))
|
||||
{
|
||||
delete pProperty;
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwCRC = pProperty->GetCRC();
|
||||
|
||||
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
|
||||
|
||||
if (m_PropertyByCRCMap.end() != itor)
|
||||
{
|
||||
Tracef("Property already registered, replace %s to %s\n",
|
||||
itor->second->GetFileName(),
|
||||
c_pszFileName);
|
||||
|
||||
delete itor->second;
|
||||
itor->second = pProperty;
|
||||
}
|
||||
else
|
||||
m_PropertyByCRCMap.insert(TPropertyCRCMap::value_type(dwCRC, pProperty));
|
||||
|
||||
if (ppProperty)
|
||||
*ppProperty = pProperty;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Get(const char * c_pszFileName, CProperty ** ppProperty)
|
||||
{
|
||||
return Register(c_pszFileName, ppProperty);
|
||||
}
|
||||
|
||||
bool CPropertyManager::Get(DWORD dwCRC, CProperty ** ppProperty)
|
||||
{
|
||||
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
|
||||
|
||||
if (m_PropertyByCRCMap.end() == itor)
|
||||
return false;
|
||||
|
||||
*ppProperty = itor->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Put(const char * c_pszFileName, const char * c_pszSourceFileName)
|
||||
{
|
||||
if (!CopyFile(c_pszSourceFileName, c_pszFileName, FALSE))
|
||||
return false;
|
||||
|
||||
if (!m_isFileMode) // 팩 파일에도 넣음
|
||||
{
|
||||
if (!m_pack.Put(c_pszFileName, NULL, COMPRESSED_TYPE_NONE,""))
|
||||
{
|
||||
assert(!"CPropertyManager::Put cannot write to pack file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Register(c_pszFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Erase(DWORD dwCRC)
|
||||
{
|
||||
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
|
||||
|
||||
if (m_PropertyByCRCMap.end() == itor)
|
||||
return false;
|
||||
|
||||
CProperty * pProperty = itor->second;
|
||||
m_PropertyByCRCMap.erase(itor);
|
||||
|
||||
DeleteFile(pProperty->GetFileName());
|
||||
ReserveCRC(pProperty->GetCRC());
|
||||
|
||||
if (!m_isFileMode) // 파일 모드가 아니면 팩에서도 지움
|
||||
m_pack.Delete(pProperty->GetFileName());
|
||||
|
||||
FILE * fp = fopen("property/reserve", "a+");
|
||||
|
||||
if (!fp)
|
||||
LogBox("예약 CRC 파일을 열 수 없습니다.");
|
||||
else
|
||||
{
|
||||
char szCRC[64 + 1];
|
||||
_snprintf(szCRC, sizeof(szCRC), "%u\r\n", pProperty->GetCRC());
|
||||
|
||||
fputs(szCRC, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
delete pProperty;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPropertyManager::Erase(const char * c_pszFileName)
|
||||
{
|
||||
CProperty * pProperty = NULL;
|
||||
|
||||
if (Get(c_pszFileName, &pProperty))
|
||||
return Erase(pProperty->GetCRC());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPropertyManager::Clear()
|
||||
{
|
||||
stl_wipe_second(m_PropertyByCRCMap);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "../eterPack/EterPack.h"
|
||||
|
||||
class CPropertyManager : public CSingleton<CPropertyManager>
|
||||
{
|
||||
public:
|
||||
CPropertyManager();
|
||||
virtual ~CPropertyManager();
|
||||
|
||||
void Clear();
|
||||
|
||||
void SetPack(CEterPack * pPack);
|
||||
bool BuildPack();
|
||||
|
||||
bool LoadReservedCRC(const char * c_pszFileName);
|
||||
void ReserveCRC(DWORD dwCRC);
|
||||
DWORD GetUniqueCRC(const char * c_szSeed);
|
||||
|
||||
bool Initialize(const char * c_pszPackFileName = NULL);
|
||||
bool Register(const char * c_pszFileName, CProperty ** ppProperty = NULL);
|
||||
|
||||
bool Get(DWORD dwCRC, CProperty ** ppProperty);
|
||||
bool Get(const char * c_pszFileName, CProperty ** ppProperty);
|
||||
|
||||
// bool Add(const char * c_pszFileName);
|
||||
// bool Remove(DWORD dwCRC);
|
||||
|
||||
bool Put(const char * c_pszFileName, const char * c_pszSourceFileName);
|
||||
|
||||
bool Erase(DWORD dwCRC);
|
||||
bool Erase(const char * c_pszFileName);
|
||||
|
||||
protected:
|
||||
typedef std::map<DWORD, CProperty *> TPropertyCRCMap;
|
||||
typedef std::set<DWORD> TCRCSet;
|
||||
|
||||
bool m_isFileMode;
|
||||
TPropertyCRCMap m_PropertyByCRCMap;
|
||||
TCRCSet m_ReservedCRCSet;
|
||||
CEterPack m_pack;
|
||||
CEterFileDict m_fileDict;
|
||||
};
|
||||
@@ -0,0 +1,598 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
#include "../eterLib/AttributeInstance.h"
|
||||
#include "../eterBase/Utils.h"
|
||||
#include "RaceData.h"
|
||||
#include "RaceMotionData.h"
|
||||
#include "../eterBase/Filename.h"
|
||||
|
||||
CDynamicPool<CRaceData> CRaceData::ms_kPool;
|
||||
CDynamicPool<CRaceData::TMotionModeData> CRaceData::ms_MotionModeDataPool;
|
||||
|
||||
const std::string& CRaceData::GetSmokeBone()
|
||||
{
|
||||
return m_strSmokeBoneName;
|
||||
}
|
||||
|
||||
DWORD CRaceData::GetSmokeEffectID(UINT eSmoke)
|
||||
{
|
||||
if(eSmoke>=SMOKE_NUM)
|
||||
{
|
||||
TraceError("CRaceData::GetSmokeEffectID(eSmoke=%d)", eSmoke);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_adwSmokeEffectID[eSmoke];
|
||||
}
|
||||
|
||||
CRaceData::SHair* CRaceData::FindHair(UINT eHair)
|
||||
{
|
||||
std::map<DWORD, SHair>::iterator f=m_kMap_dwHairKey_kHair.find(eHair);
|
||||
if (m_kMap_dwHairKey_kHair.end()==f)
|
||||
{
|
||||
if (eHair != 0)
|
||||
TraceError("Hair number %d is not exist.",eHair);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &f->second;
|
||||
}
|
||||
|
||||
void CRaceData::SetHairSkin(UINT eHair, UINT ePart, const char * c_szModelFileName, const char* c_szSrcFileName, const char* c_szDstFileName)
|
||||
{
|
||||
SSkin kSkin;
|
||||
kSkin.m_ePart=ePart;
|
||||
kSkin.m_stSrcFileName=c_szSrcFileName;
|
||||
kSkin.m_stDstFileName=c_szDstFileName;
|
||||
|
||||
CFileNameHelper::ChangeDosPath(kSkin.m_stSrcFileName);
|
||||
m_kMap_dwHairKey_kHair[eHair].m_kVct_kSkin.push_back(kSkin);
|
||||
m_kMap_dwHairKey_kHair[eHair].m_stModelFileName = c_szModelFileName;
|
||||
}
|
||||
|
||||
CRaceData::SShape* CRaceData::FindShape(UINT eShape)
|
||||
{
|
||||
std::map<DWORD, SShape>::iterator f=m_kMap_dwShapeKey_kShape.find(eShape);
|
||||
if (m_kMap_dwShapeKey_kShape.end()==f)
|
||||
return NULL;
|
||||
|
||||
return &f->second;
|
||||
}
|
||||
|
||||
void CRaceData::SetShapeModel(UINT eShape, const char* c_szModelFileName)
|
||||
{
|
||||
m_kMap_dwShapeKey_kShape[eShape].m_stModelFileName=c_szModelFileName;
|
||||
}
|
||||
|
||||
void CRaceData::AppendShapeSkin(UINT eShape, UINT ePart, const char* c_szSrcFileName, const char* c_szDstFileName)
|
||||
{
|
||||
SSkin kSkin;
|
||||
kSkin.m_ePart=ePart;
|
||||
kSkin.m_stSrcFileName=c_szSrcFileName;
|
||||
kSkin.m_stDstFileName=c_szDstFileName;
|
||||
|
||||
CFileNameHelper::ChangeDosPath(kSkin.m_stSrcFileName);
|
||||
m_kMap_dwShapeKey_kShape[eShape].m_kVct_kSkin.push_back(kSkin);
|
||||
}
|
||||
|
||||
CRaceData* CRaceData::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CRaceData::Delete(CRaceData* pkRaceData)
|
||||
{
|
||||
pkRaceData->Destroy();
|
||||
ms_kPool.Free(pkRaceData);
|
||||
}
|
||||
|
||||
void CRaceData::CreateSystem(UINT uCapacity, UINT uMotModeCapacity)
|
||||
{
|
||||
ms_MotionModeDataPool.Create(uMotModeCapacity);
|
||||
ms_kPool.Create(uCapacity);
|
||||
}
|
||||
|
||||
void CRaceData::DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
ms_MotionModeDataPool.Destroy();
|
||||
}
|
||||
|
||||
BOOL CRaceData::CreateMotionModeIterator(TMotionModeDataIterator & itor)
|
||||
{
|
||||
if (m_pMotionModeDataMap.empty())
|
||||
return FALSE;
|
||||
|
||||
itor = m_pMotionModeDataMap.begin();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
BOOL CRaceData::NextMotionModeIterator(TMotionModeDataIterator & itor)
|
||||
{
|
||||
++itor;
|
||||
|
||||
return m_pMotionModeDataMap.end() != itor;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetMotionKey(WORD wMotionModeIndex, WORD wMotionIndex, MOTION_KEY * pMotionKey)
|
||||
{
|
||||
TMotionModeData * pMotionModeData;
|
||||
if (!GetMotionModeDataPointer(wMotionModeIndex, &pMotionModeData))
|
||||
return FALSE;
|
||||
|
||||
if (pMotionModeData->MotionVectorMap.end() == pMotionModeData->MotionVectorMap.find(wMotionIndex))
|
||||
{
|
||||
WORD wGeneralMode=CRaceMotionData::MODE_GENERAL;
|
||||
|
||||
switch(wMotionModeIndex)
|
||||
{
|
||||
case CRaceMotionData::MODE_HORSE_ONEHAND_SWORD:
|
||||
case CRaceMotionData::MODE_HORSE_TWOHAND_SWORD:
|
||||
case CRaceMotionData::MODE_HORSE_DUALHAND_SWORD:
|
||||
case CRaceMotionData::MODE_HORSE_FAN:
|
||||
case CRaceMotionData::MODE_HORSE_BELL:
|
||||
case CRaceMotionData::MODE_HORSE_BOW:
|
||||
wGeneralMode=CRaceMotionData::MODE_HORSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
wGeneralMode=CRaceMotionData::MODE_GENERAL;
|
||||
break;
|
||||
}
|
||||
|
||||
TMotionModeData * pMotionModeGeneralData;
|
||||
if (!GetMotionModeDataPointer(wGeneralMode, &pMotionModeGeneralData))
|
||||
return FALSE;
|
||||
|
||||
if (pMotionModeGeneralData->MotionVectorMap.end() == pMotionModeGeneralData->MotionVectorMap.find(wMotionIndex))
|
||||
return FALSE;
|
||||
|
||||
*pMotionKey = MAKE_MOTION_KEY(wGeneralMode, wMotionIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
*pMotionKey = MAKE_MOTION_KEY(wMotionModeIndex, wMotionIndex);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetMotionModeDataPointer(WORD wMotionMode, TMotionModeData ** ppMotionModeData)
|
||||
{
|
||||
TMotionModeDataIterator itor = m_pMotionModeDataMap.find(wMotionMode);
|
||||
if (itor == m_pMotionModeDataMap.end())
|
||||
return FALSE;
|
||||
|
||||
*ppMotionModeData = itor->second;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetModelDataPointer(DWORD dwModelIndex, const TModelData ** c_ppModelData)
|
||||
{
|
||||
TModelDataMapIterator itor = m_ModelDataMap.find(dwModelIndex);
|
||||
if (m_ModelDataMap.end() == itor)
|
||||
return false;
|
||||
|
||||
*c_ppModelData = &itor->second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, TMotionVector ** ppMotionVector)
|
||||
{
|
||||
TMotionModeData * pMotionModeData;
|
||||
if (!GetMotionModeDataPointer(wMotionMode, &pMotionModeData))
|
||||
return FALSE;
|
||||
|
||||
TMotionVectorMap::iterator itor = pMotionModeData->MotionVectorMap.find(wMotionIndex);
|
||||
if (pMotionModeData->MotionVectorMap.end() == itor)
|
||||
return FALSE;
|
||||
|
||||
*ppMotionVector = &itor->second;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetMotionDataPointer(WORD wMotionMode, WORD wMotionIndex, WORD wMotionSubIndex, CRaceMotionData ** c_ppMotionData)
|
||||
{
|
||||
const TMotionVector * c_pMotionVector;
|
||||
if (!GetMotionVectorPointer(wMotionMode, wMotionIndex, &c_pMotionVector))
|
||||
return FALSE;
|
||||
|
||||
if (wMotionSubIndex >= c_pMotionVector->size())
|
||||
return FALSE;
|
||||
|
||||
const TMotion & c_rMotion = c_pMotionVector->at(wMotionSubIndex);
|
||||
|
||||
if (!c_rMotion.pMotionData)
|
||||
return FALSE;
|
||||
|
||||
*c_ppMotionData = c_rMotion.pMotionData;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetMotionDataPointer(DWORD dwMotionKey, CRaceMotionData ** c_ppMotionData)
|
||||
{
|
||||
return GetMotionDataPointer(GET_MOTION_MODE(dwMotionKey), GET_MOTION_INDEX(dwMotionKey), GET_MOTION_SUB_INDEX(dwMotionKey), c_ppMotionData);
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, const TMotionVector ** c_ppMotionVector)
|
||||
{
|
||||
TMotionVector * pMotionVector;
|
||||
if (!GetMotionVectorPointer(wMotionMode, wMotionIndex, &pMotionVector))
|
||||
return FALSE;
|
||||
|
||||
*c_ppMotionVector = pMotionVector;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD CRaceData::GetAttachingDataCount()
|
||||
{
|
||||
return m_AttachingDataVector.size();
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData)
|
||||
{
|
||||
if (dwIndex >= GetAttachingDataCount())
|
||||
return FALSE;
|
||||
|
||||
*c_ppAttachingData = &m_AttachingDataVector[dwIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData)
|
||||
{
|
||||
if (dwIndex >= GetAttachingDataCount())
|
||||
return FALSE;
|
||||
|
||||
if (NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA != m_AttachingDataVector[dwIndex].dwType)
|
||||
return FALSE;
|
||||
|
||||
*c_ppAttachingData = &m_AttachingDataVector[dwIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetBodyCollisionDataPointer(const NRaceData::TAttachingData ** c_ppAttachingData)
|
||||
{
|
||||
for (DWORD i = 0; i < m_AttachingDataVector.size(); ++i)
|
||||
{
|
||||
const NRaceData::TAttachingData * pAttachingData = &m_AttachingDataVector[i];
|
||||
|
||||
if (NRaceData::ATTACHING_DATA_TYPE_COLLISION_DATA == pAttachingData->dwType)
|
||||
if (NRaceData::COLLISION_TYPE_BODY == pAttachingData->pCollisionData->iCollisionType)
|
||||
{
|
||||
*c_ppAttachingData = pAttachingData;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CRaceData::SetRace(DWORD dwRaceIndex)
|
||||
{
|
||||
m_dwRaceIndex = dwRaceIndex;
|
||||
}
|
||||
|
||||
void CRaceData::RegisterAttachingBoneName(DWORD dwPartIndex, const char * c_szBoneName)
|
||||
{
|
||||
m_AttachingBoneNameMap.insert(TAttachingBoneNameMap::value_type(dwPartIndex, c_szBoneName));
|
||||
}
|
||||
|
||||
void CRaceData::RegisterMotionMode(WORD wMotionModeIndex)
|
||||
{
|
||||
TMotionModeData * pMotionModeData = ms_MotionModeDataPool.Alloc();
|
||||
pMotionModeData->wMotionModeIndex = wMotionModeIndex;
|
||||
pMotionModeData->MotionVectorMap.clear();
|
||||
m_pMotionModeDataMap.insert(TMotionModeDataMap::value_type(wMotionModeIndex, pMotionModeData));
|
||||
}
|
||||
|
||||
CGraphicThing* CRaceData::NEW_RegisterMotion(CRaceMotionData* pkMotionData, WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage)
|
||||
{
|
||||
CGraphicThing * pMotionThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName);
|
||||
|
||||
TMotionModeData * pMotionModeData;
|
||||
if (!GetMotionModeDataPointer(wMotionModeIndex, &pMotionModeData))
|
||||
{
|
||||
AssertLog("Failed getting motion mode data!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TMotion kMotion;
|
||||
kMotion.byPercentage = byPercentage;
|
||||
kMotion.pMotion = pMotionThing;
|
||||
kMotion.pMotionData = pkMotionData;
|
||||
pMotionModeData->MotionVectorMap[wMotionIndex].push_back(kMotion);
|
||||
|
||||
return pMotionThing;
|
||||
}
|
||||
|
||||
CGraphicThing* CRaceData::RegisterMotionData(WORD wMotionMode, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage)
|
||||
{
|
||||
CRaceMotionData * pRaceMotionData = CRaceMotionData::New();
|
||||
if (!pRaceMotionData->LoadMotionData(c_szFileName))
|
||||
{
|
||||
TraceError("CRaceData::RegisterMotionData - LoadMotionData(c_szFileName=%s) ERROR", c_szFileName);
|
||||
CRaceMotionData::Delete(pRaceMotionData);
|
||||
pRaceMotionData = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 2004. 3. 15. myevan. 원래는 모션내 인덱스 정보가 있어야 한다.
|
||||
pRaceMotionData->SetName(wMotionIndex);
|
||||
|
||||
/////
|
||||
|
||||
// FIXME : 이미 GR2가 로드 되어 있을 경우에는 어떻게 해야 하는가?
|
||||
// 현재는 똑같은 것이 하나 더 추가 되어 버린다. - [levites]
|
||||
|
||||
return NEW_RegisterMotion(pRaceMotionData, wMotionMode, wMotionIndex, pRaceMotionData->GetMotionFileName(), byPercentage);
|
||||
|
||||
// 2004.09.03.myevan.새로운함수로 대처
|
||||
//TMotion Motion;
|
||||
//Motion.byPercentage = byPercentage;
|
||||
//Motion.pMotion = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(pRaceMotionData->GetMotionFileName());
|
||||
//Motion.pMotionData = pRaceMotionData;
|
||||
//__OLD_RegisterMotion(wMotionMode, wMotionIndex, Motion);
|
||||
//return true;
|
||||
}
|
||||
|
||||
|
||||
void CRaceData::OLD_RegisterMotion(WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage)
|
||||
{
|
||||
CGraphicThing * pThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName);
|
||||
|
||||
TMotion Motion;
|
||||
Motion.byPercentage = byPercentage;
|
||||
Motion.pMotion = pThing;
|
||||
Motion.pMotionData = NULL;
|
||||
__OLD_RegisterMotion(wMotionModeIndex, wMotionIndex, Motion);
|
||||
}
|
||||
|
||||
void CRaceData::__OLD_RegisterMotion(WORD wMotionMode, WORD wMotionIndex, const TMotion & rMotion)
|
||||
{
|
||||
TMotionModeData * pMotionModeData;
|
||||
if (!GetMotionModeDataPointer(wMotionMode, &pMotionModeData))
|
||||
{
|
||||
AssertLog("Failed getting motion mode data!");
|
||||
return;
|
||||
}
|
||||
|
||||
TMotionVectorMap::iterator itor = pMotionModeData->MotionVectorMap.find(wMotionIndex);
|
||||
if (pMotionModeData->MotionVectorMap.end() == itor)
|
||||
{
|
||||
TMotionVector MotionVector;
|
||||
MotionVector.push_back(rMotion);
|
||||
|
||||
pMotionModeData->MotionVectorMap.insert(TMotionVectorMap::value_type(wMotionIndex, MotionVector));
|
||||
}
|
||||
else
|
||||
{
|
||||
TMotionVector & rMotionVector = itor->second;
|
||||
rMotionVector.push_back(rMotion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CRaceData::SetMotionRandomWeight(WORD wMotionModeIndex, WORD wMotionIndex, WORD wMotionSubIndex, BYTE byPercentage)
|
||||
{
|
||||
TMotionModeData * pMotionModeData;
|
||||
|
||||
if (!GetMotionModeDataPointer(wMotionModeIndex, &pMotionModeData))
|
||||
{
|
||||
//AssertLog("Failed getting motion mode data!");
|
||||
return false;
|
||||
}
|
||||
|
||||
TMotionVectorMap::iterator itor = pMotionModeData->MotionVectorMap.find(wMotionIndex);
|
||||
|
||||
if (pMotionModeData->MotionVectorMap.end() != itor)
|
||||
{
|
||||
TMotionVector & rMotionVector = itor->second;
|
||||
if (wMotionSubIndex < rMotionVector.size())
|
||||
{
|
||||
rMotionVector[wMotionSubIndex].byPercentage = byPercentage;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceError("CRaceData::SetMotionRandomWeight(wMotionModeIndex=%d, wMotionIndex=%d, wMotionSubIndex=%d, byPercentage=%d) - Find Motion(wMotionIndex=%d) FAILED",
|
||||
wMotionModeIndex, wMotionIndex, wMotionSubIndex, byPercentage, wMotionModeIndex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRaceData::RegisterNormalAttack(WORD wMotionModeIndex, WORD wMotionIndex)
|
||||
{
|
||||
m_NormalAttackIndexMap.insert(TNormalAttackIndexMap::value_type(wMotionModeIndex, wMotionIndex));
|
||||
}
|
||||
BOOL CRaceData::GetNormalAttackIndex(WORD wMotionModeIndex, WORD * pwMotionIndex)
|
||||
{
|
||||
TNormalAttackIndexMap::iterator itor = m_NormalAttackIndexMap.find(wMotionModeIndex);
|
||||
|
||||
if (m_NormalAttackIndexMap.end() == itor)
|
||||
return FALSE;
|
||||
|
||||
*pwMotionIndex = itor->second;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CRaceData::ReserveComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboCount)
|
||||
{
|
||||
TComboData ComboData;
|
||||
ComboData.ComboIndexVector.clear();
|
||||
ComboData.ComboIndexVector.resize(dwComboCount);
|
||||
m_ComboAttackDataMap.insert(TComboAttackDataMap::value_type(MAKE_COMBO_KEY(wMotionModeIndex, wComboType), ComboData));
|
||||
}
|
||||
|
||||
void CRaceData::RegisterComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboIndex, WORD wMotionIndex)
|
||||
{
|
||||
TComboAttackDataIterator itor = m_ComboAttackDataMap.find(MAKE_COMBO_KEY(wMotionModeIndex, wComboType));
|
||||
if (m_ComboAttackDataMap.end() == itor)
|
||||
return;
|
||||
|
||||
TComboIndexVector & rComboIndexVector = itor->second.ComboIndexVector;
|
||||
if (dwComboIndex >= rComboIndexVector.size())
|
||||
{
|
||||
AssertLog("CRaceData::RegisterCombo - Strange combo index!");
|
||||
return;
|
||||
}
|
||||
|
||||
rComboIndexVector[dwComboIndex] = wMotionIndex;
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetComboDataPointer(WORD wMotionModeIndex, WORD wComboType, TComboData ** ppComboData)
|
||||
{
|
||||
TComboAttackDataIterator itor = m_ComboAttackDataMap.find(MAKE_COMBO_KEY(wMotionModeIndex, wComboType));
|
||||
|
||||
if (m_ComboAttackDataMap.end() == itor)
|
||||
return FALSE;
|
||||
|
||||
*ppComboData = &itor->second;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const char * CRaceData::GetBaseModelFileName() const
|
||||
{
|
||||
return m_strBaseModelFileName.c_str();
|
||||
}
|
||||
|
||||
const char * CRaceData::GetAttributeFileName() const
|
||||
{
|
||||
return m_strAttributeFileName.c_str();
|
||||
}
|
||||
|
||||
const char* CRaceData::GetMotionListFileName() const
|
||||
{
|
||||
return m_strMotionListFileName.c_str();
|
||||
}
|
||||
|
||||
CGraphicThing * CRaceData::GetBaseModelThing()
|
||||
{
|
||||
if (!m_pBaseModelThing)
|
||||
{
|
||||
m_pBaseModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(m_strBaseModelFileName.c_str());
|
||||
}
|
||||
|
||||
return m_pBaseModelThing;
|
||||
}
|
||||
|
||||
CGraphicThing * CRaceData::GetLODModelThing()
|
||||
{
|
||||
if (!m_pLODModelThing)
|
||||
{
|
||||
std::string strLODFileName = CFileNameHelper::NoExtension(m_strBaseModelFileName) + "_lod_01.gr2";
|
||||
if (CResourceManager::Instance().IsFileExist(strLODFileName.c_str()))
|
||||
{
|
||||
m_pLODModelThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(strLODFileName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return m_pLODModelThing;
|
||||
}
|
||||
|
||||
CAttributeData * CRaceData::GetAttributeDataPtr()
|
||||
{
|
||||
if (m_strAttributeFileName.empty())
|
||||
return NULL;
|
||||
|
||||
if (!CResourceManager::Instance().IsFileExist(m_strAttributeFileName.c_str()))
|
||||
return NULL;
|
||||
|
||||
return (CAttributeData *)CResourceManager::Instance().GetResourcePointer(m_strAttributeFileName.c_str());
|
||||
}
|
||||
|
||||
BOOL CRaceData::GetAttachingBoneName(DWORD dwPartIndex, const char ** c_pszBoneName)
|
||||
{
|
||||
TAttachingBoneNameMap::iterator itor = m_AttachingBoneNameMap.find(dwPartIndex);
|
||||
if (itor == m_AttachingBoneNameMap.end())
|
||||
return FALSE;
|
||||
|
||||
const std::string & c_rstrBoneName = itor->second;
|
||||
|
||||
*c_pszBoneName = c_rstrBoneName.c_str();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceData::IsTree()
|
||||
{
|
||||
return !m_strTreeFileName.empty();
|
||||
}
|
||||
|
||||
const char * CRaceData::GetTreeFileName()
|
||||
{
|
||||
return m_strTreeFileName.c_str();
|
||||
}
|
||||
|
||||
void CRaceData::Destroy()
|
||||
{
|
||||
m_kMap_dwHairKey_kHair.clear();
|
||||
m_kMap_dwShapeKey_kShape.clear();
|
||||
|
||||
m_strBaseModelFileName = "";
|
||||
m_strTreeFileName = "";
|
||||
m_strAttributeFileName = "";
|
||||
m_strMotionListFileName = "motlist.txt";
|
||||
|
||||
m_AttachingBoneNameMap.clear();
|
||||
m_ModelDataMap.clear();
|
||||
|
||||
m_NormalAttackIndexMap.clear();
|
||||
m_ComboAttackDataMap.clear();
|
||||
|
||||
TMotionModeDataMap::iterator itorMode = m_pMotionModeDataMap.begin();
|
||||
for (; itorMode != m_pMotionModeDataMap.end(); ++itorMode)
|
||||
{
|
||||
TMotionModeData * pMotionModeData = itorMode->second;
|
||||
|
||||
TMotionVectorMap::iterator itorMotion = pMotionModeData->MotionVectorMap.begin();
|
||||
for (; itorMotion != pMotionModeData->MotionVectorMap.end(); ++itorMotion)
|
||||
{
|
||||
TMotionVector & rMotionVector = itorMotion->second;
|
||||
for (DWORD i = 0; i < rMotionVector.size(); ++i)
|
||||
{
|
||||
CRaceMotionData::Delete(rMotionVector[i].pMotionData);
|
||||
}
|
||||
}
|
||||
|
||||
ms_MotionModeDataPool.Free(pMotionModeData);
|
||||
}
|
||||
m_pMotionModeDataMap.clear();
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CRaceData::__Initialize()
|
||||
{
|
||||
m_strMotionListFileName = "motlist.txt";
|
||||
|
||||
m_pBaseModelThing = NULL;
|
||||
m_pLODModelThing = NULL;
|
||||
|
||||
m_dwRaceIndex = 0;
|
||||
|
||||
memset(m_adwSmokeEffectID, 0, sizeof(m_adwSmokeEffectID));
|
||||
}
|
||||
|
||||
CRaceData::CRaceData()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
CRaceData::~CRaceData()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
#pragma once
|
||||
|
||||
#include "../eterGrnLib/Thing.h"
|
||||
|
||||
class CRaceMotionData;
|
||||
class CAttributeData;
|
||||
|
||||
#define COMBO_KEY DWORD
|
||||
#define MAKE_COMBO_KEY(motion_mode, combo_type) ( (DWORD(motion_mode) << 16) | (DWORD(combo_type)) )
|
||||
#define COMBO_KEY_GET_MOTION_MODE(key) ( WORD(DWORD(key) >> 16 & 0xFFFF) )
|
||||
#define COMBO_KEY_GET_COMBO_TYPE(key) ( WORD(DWORD(key) & 0xFFFF) )
|
||||
|
||||
class CRaceData
|
||||
{
|
||||
public:
|
||||
enum EParts
|
||||
{
|
||||
// Share index with server
|
||||
// ECharacterEquipmentPart도 수정해주세요.
|
||||
//패킷 크기가 변합니다 서버와 상의후 추가해주세요.
|
||||
PART_MAIN,
|
||||
PART_WEAPON,
|
||||
PART_HEAD,
|
||||
PART_WEAPON_LEFT,
|
||||
PART_HAIR,
|
||||
|
||||
PART_MAX_NUM,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SMOKE_NUM = 4,
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Graphic Resource
|
||||
|
||||
// Model
|
||||
typedef std::map<WORD, CGraphicThing*> TGraphicThingMap;
|
||||
typedef std::map<DWORD, std::string> TAttachingBoneNameMap;
|
||||
|
||||
// Motion
|
||||
typedef struct SMotion
|
||||
{
|
||||
BYTE byPercentage;
|
||||
CGraphicThing * pMotion;
|
||||
CRaceMotionData * pMotionData;
|
||||
} TMotion;
|
||||
typedef std::vector<TMotion> TMotionVector;
|
||||
typedef std::map<WORD, TMotionVector> TMotionVectorMap;
|
||||
|
||||
typedef struct SMotionModeData
|
||||
{
|
||||
WORD wMotionModeIndex;
|
||||
|
||||
TMotionVectorMap MotionVectorMap;
|
||||
|
||||
SMotionModeData() {}
|
||||
virtual ~SMotionModeData() {}
|
||||
} TMotionModeData;
|
||||
typedef std::map<WORD, TMotionModeData*> TMotionModeDataMap;
|
||||
typedef TMotionModeDataMap::iterator TMotionModeDataIterator;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Model Data
|
||||
typedef struct SModelData
|
||||
{
|
||||
NRaceData::TAttachingDataVector AttachingDataVector;
|
||||
} TModelData;
|
||||
typedef std::map<DWORD, TModelData> TModelDataMap;
|
||||
typedef TModelDataMap::iterator TModelDataMapIterator;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Motion Data
|
||||
typedef std::map<DWORD, CRaceMotionData*> TMotionDataMap;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Combo Data
|
||||
typedef std::vector<DWORD> TComboIndexVector;
|
||||
typedef struct SComboAttackData
|
||||
{
|
||||
TComboIndexVector ComboIndexVector;
|
||||
} TComboData;
|
||||
typedef std::map<DWORD, DWORD> TNormalAttackIndexMap;
|
||||
typedef std::map<COMBO_KEY, TComboData> TComboAttackDataMap;
|
||||
typedef TComboAttackDataMap::iterator TComboAttackDataIterator;
|
||||
|
||||
struct SSkin
|
||||
{
|
||||
int m_ePart;
|
||||
|
||||
std::string m_stSrcFileName;
|
||||
std::string m_stDstFileName;
|
||||
|
||||
SSkin()
|
||||
{
|
||||
m_ePart=0;
|
||||
}
|
||||
SSkin(const SSkin& c_rkSkin)
|
||||
{
|
||||
Copy(c_rkSkin);
|
||||
}
|
||||
void operator=(const SSkin& c_rkSkin)
|
||||
{
|
||||
Copy(c_rkSkin);
|
||||
}
|
||||
void Copy(const SSkin& c_rkSkin)
|
||||
{
|
||||
m_ePart=c_rkSkin.m_ePart;
|
||||
m_stSrcFileName=c_rkSkin.m_stSrcFileName;
|
||||
m_stDstFileName=c_rkSkin.m_stDstFileName;
|
||||
}
|
||||
};
|
||||
|
||||
struct SHair
|
||||
{
|
||||
std::string m_stModelFileName;
|
||||
std::vector<SSkin> m_kVct_kSkin;
|
||||
};
|
||||
|
||||
struct SShape
|
||||
{
|
||||
std::string m_stModelFileName;
|
||||
std::vector<SSkin> m_kVct_kSkin;
|
||||
};
|
||||
|
||||
public:
|
||||
static CRaceData* New();
|
||||
static void Delete(CRaceData* pkRaceData);
|
||||
static void CreateSystem(UINT uCapacity, UINT uMotModeCapacity);
|
||||
static void DestroySystem();
|
||||
|
||||
public:
|
||||
CRaceData();
|
||||
virtual ~CRaceData();
|
||||
|
||||
void Destroy();
|
||||
|
||||
// Codes For Client
|
||||
const char* GetBaseModelFileName() const;
|
||||
const char* GetAttributeFileName() const;
|
||||
const char* GetMotionListFileName() const;
|
||||
CGraphicThing * GetBaseModelThing();
|
||||
CGraphicThing * GetLODModelThing();
|
||||
CAttributeData * GetAttributeDataPtr();
|
||||
BOOL GetAttachingBoneName(DWORD dwPartIndex, const char ** c_pszBoneName);
|
||||
BOOL CreateMotionModeIterator(TMotionModeDataIterator & itor);
|
||||
BOOL NextMotionModeIterator(TMotionModeDataIterator & itor);
|
||||
|
||||
BOOL GetMotionKey(WORD wMotionModeIndex, WORD wMotionIndex, MOTION_KEY * pMotionKey);
|
||||
|
||||
BOOL GetMotionModeDataPointer(WORD wMotionMode, TMotionModeData ** ppMotionModeData);
|
||||
BOOL GetModelDataPointer(DWORD dwModelIndex, const TModelData ** c_ppModelData);
|
||||
BOOL GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, const TMotionVector ** c_ppMotionVector);
|
||||
BOOL GetMotionDataPointer(WORD wMotionMode, WORD wMotionIndex, WORD wMotionSubIndex, CRaceMotionData** ppMotionData);
|
||||
BOOL GetMotionDataPointer(DWORD dwMotionKey, CRaceMotionData ** ppMotionData);
|
||||
|
||||
DWORD GetAttachingDataCount();
|
||||
BOOL GetAttachingDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData);
|
||||
BOOL GetCollisionDataPointer(DWORD dwIndex, const NRaceData::TAttachingData ** c_ppAttachingData);
|
||||
BOOL GetBodyCollisionDataPointer(const NRaceData::TAttachingData ** c_ppAttachingData);
|
||||
|
||||
BOOL IsTree();
|
||||
const char * GetTreeFileName();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Setup by Script
|
||||
BOOL LoadRaceData(const char * c_szFileName);
|
||||
|
||||
CGraphicThing* RegisterMotionData(WORD wMotionMode, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage = 100);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Setup by Python
|
||||
void SetRace(DWORD dwRaceIndex);
|
||||
void RegisterAttachingBoneName(DWORD dwPartIndex, const char * c_szBoneName);
|
||||
|
||||
void RegisterMotionMode(WORD wMotionModeIndex);
|
||||
void SetMotionModeParent(WORD wParentMotionModeIndex, WORD wMotionModeIndex);
|
||||
void OLD_RegisterMotion(WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage = 100);
|
||||
CGraphicThing* NEW_RegisterMotion(CRaceMotionData* pkMotionData, WORD wMotionModeIndex, WORD wMotionIndex, const char * c_szFileName, BYTE byPercentage = 100);
|
||||
bool SetMotionRandomWeight(WORD wMotionModeIndex, WORD wMotionIndex, WORD wMotionSubIndex, BYTE byPercentage);
|
||||
|
||||
void RegisterNormalAttack(WORD wMotionModeIndex, WORD wMotionIndex);
|
||||
BOOL GetNormalAttackIndex(WORD wMotionModeIndex, WORD * pwMotionIndex);
|
||||
|
||||
void ReserveComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboCount);
|
||||
void RegisterComboAttack(WORD wMotionModeIndex, WORD wComboType, DWORD dwComboIndex, WORD wMotionIndex);
|
||||
BOOL GetComboDataPointer(WORD wMotionModeIndex, WORD wComboType, TComboData ** ppComboData);
|
||||
|
||||
void SetShapeModel(UINT eShape, const char* c_szModelFileName);
|
||||
void AppendShapeSkin(UINT eShape, UINT ePart, const char* c_szSrcFileName, const char* c_szDstFileName);
|
||||
|
||||
void SetHairSkin(UINT eHair, UINT ePart, const char* c_szModelFileName, const char* c_szSrcFileName, const char* c_szDstFileName);
|
||||
|
||||
/////
|
||||
|
||||
DWORD GetSmokeEffectID(UINT eSmoke);
|
||||
|
||||
const std::string& GetSmokeBone();
|
||||
|
||||
SHair* FindHair(UINT eHair);
|
||||
SShape* FindShape(UINT eShape);
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
|
||||
void __OLD_RegisterMotion(WORD wMotionMode, WORD wMotionIndex, const TMotion & rMotion);
|
||||
|
||||
BOOL GetMotionVectorPointer(WORD wMotionMode, WORD wMotionIndex, TMotionVector ** ppMotionVector);
|
||||
|
||||
protected:
|
||||
DWORD m_dwRaceIndex;
|
||||
DWORD m_adwSmokeEffectID[SMOKE_NUM];
|
||||
|
||||
CGraphicThing * m_pBaseModelThing;
|
||||
CGraphicThing * m_pLODModelThing;
|
||||
|
||||
std::string m_strBaseModelFileName;
|
||||
std::string m_strTreeFileName;
|
||||
std::string m_strAttributeFileName;
|
||||
std::string m_strMotionListFileName;
|
||||
std::string m_strSmokeBoneName;
|
||||
|
||||
TModelDataMap m_ModelDataMap;
|
||||
TMotionModeDataMap m_pMotionModeDataMap;
|
||||
TAttachingBoneNameMap m_AttachingBoneNameMap;
|
||||
TComboAttackDataMap m_ComboAttackDataMap;
|
||||
TNormalAttackIndexMap m_NormalAttackIndexMap;
|
||||
|
||||
std::map<DWORD, SHair> m_kMap_dwHairKey_kHair;
|
||||
std::map<DWORD, SShape> m_kMap_dwShapeKey_kShape;
|
||||
|
||||
NRaceData::TAttachingDataVector m_AttachingDataVector;
|
||||
|
||||
protected:
|
||||
static CDynamicPool<TMotionModeData> ms_MotionModeDataPool;
|
||||
static CDynamicPool<CRaceData> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,186 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
|
||||
#include "RaceData.h"
|
||||
#include "RaceMotionData.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL CRaceData::LoadRaceData(const char * c_szFileName)
|
||||
{
|
||||
CTextFileLoader TextFileLoader;
|
||||
if (!TextFileLoader.Load(c_szFileName))
|
||||
return FALSE;
|
||||
|
||||
TextFileLoader.SetTop();
|
||||
|
||||
TextFileLoader.GetTokenString("basemodelfilename", &m_strBaseModelFileName);
|
||||
TextFileLoader.GetTokenString("treefilename", &m_strTreeFileName);
|
||||
TextFileLoader.GetTokenString("attributefilename", &m_strAttributeFileName);
|
||||
TextFileLoader.GetTokenString("smokebonename", &m_strSmokeBoneName);
|
||||
TextFileLoader.GetTokenString("motionlistfilename", &m_strMotionListFileName);
|
||||
|
||||
if (!m_strTreeFileName.empty())
|
||||
{
|
||||
CFileNameHelper::StringPath(m_strTreeFileName);
|
||||
}
|
||||
|
||||
CTokenVector* pSmokeTokenVector;
|
||||
if (TextFileLoader.GetTokenVector("smokefilename", &pSmokeTokenVector))
|
||||
{
|
||||
if (pSmokeTokenVector->size()%2!=0)
|
||||
{
|
||||
TraceError("SmokeFileName ArgCount[%d]%2==0", pSmokeTokenVector->size());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT uLineCount=pSmokeTokenVector->size()/2;
|
||||
|
||||
for (UINT uLine=0; uLine<uLineCount; ++uLine)
|
||||
{
|
||||
int eSmoke=atoi(pSmokeTokenVector->at(uLine*2+0).c_str());
|
||||
if (eSmoke<0 || eSmoke>=SMOKE_NUM)
|
||||
{
|
||||
TraceError("SmokeFileName SmokeNum[%d] OUT OF RANGE", eSmoke);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const std::string& c_rstrEffectFileName = pSmokeTokenVector->at(uLine*2+1);
|
||||
|
||||
DWORD& rdwCRCEft=m_adwSmokeEffectID[eSmoke];
|
||||
if (!CEffectManager::Instance().RegisterEffect2(c_rstrEffectFileName.c_str(), &rdwCRCEft))
|
||||
{
|
||||
TraceError("CRaceData::RegisterEffect2(%s) ERROR", c_rstrEffectFileName.c_str());
|
||||
rdwCRCEft=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TextFileLoader.SetChildNode("shapedata"))
|
||||
{
|
||||
std::string strPathName;
|
||||
DWORD dwShapeDataCount = 0;
|
||||
if (TextFileLoader.GetTokenString("pathname", &strPathName) &&
|
||||
TextFileLoader.GetTokenDoubleWord("shapedatacount", &dwShapeDataCount))
|
||||
{
|
||||
for (DWORD i = 0; i < dwShapeDataCount; ++i)
|
||||
{
|
||||
if (!TextFileLoader.SetChildNode("shapedata", i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Temporary - 이벤트를 위한 임시 기능
|
||||
TextFileLoader.GetTokenString("specialpath", &strPathName);
|
||||
/////////////////////////
|
||||
|
||||
DWORD dwShapeIndex;
|
||||
if (!TextFileLoader.GetTokenDoubleWord("shapeindex", &dwShapeIndex))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// LOCAL_PATH_SUPPORT
|
||||
std::string strModel;
|
||||
if (TextFileLoader.GetTokenString("model", &strModel))
|
||||
{
|
||||
SetShapeModel(dwShapeIndex, (strPathName + strModel).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TextFileLoader.GetTokenString("local_model", &strModel))
|
||||
continue;
|
||||
|
||||
SetShapeModel(dwShapeIndex, strModel.c_str());
|
||||
}
|
||||
// END_OF_LOCAL_PATH_SUPPORT
|
||||
|
||||
|
||||
|
||||
std::string strSourceSkin;
|
||||
std::string strTargetSkin;
|
||||
|
||||
// LOCAL_PATH_SUPPORT
|
||||
if (TextFileLoader.GetTokenString("local_sourceskin", &strSourceSkin) &&
|
||||
TextFileLoader.GetTokenString("local_targetskin", &strTargetSkin))
|
||||
{
|
||||
AppendShapeSkin(dwShapeIndex, 0, strSourceSkin.c_str(), strTargetSkin.c_str());
|
||||
}
|
||||
// END_OF_LOCAL_PATH_SUPPORT
|
||||
|
||||
if (TextFileLoader.GetTokenString("sourceskin", &strSourceSkin) &&
|
||||
TextFileLoader.GetTokenString("targetskin", &strTargetSkin))
|
||||
{
|
||||
AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str());
|
||||
}
|
||||
|
||||
if (TextFileLoader.GetTokenString("sourceskin2", &strSourceSkin) &&
|
||||
TextFileLoader.GetTokenString("targetskin2", &strTargetSkin))
|
||||
{
|
||||
AppendShapeSkin(dwShapeIndex, 0, (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str());
|
||||
}
|
||||
|
||||
TextFileLoader.SetParentNode();
|
||||
}
|
||||
}
|
||||
|
||||
TextFileLoader.SetParentNode();
|
||||
}
|
||||
|
||||
if (TextFileLoader.SetChildNode("hairdata"))
|
||||
{
|
||||
std::string strPathName;
|
||||
DWORD dwHairDataCount = 0;
|
||||
if (TextFileLoader.GetTokenString("pathname", &strPathName) &&
|
||||
TextFileLoader.GetTokenDoubleWord("hairdatacount", &dwHairDataCount))
|
||||
{
|
||||
|
||||
for (DWORD i = 0; i < dwHairDataCount; ++i)
|
||||
{
|
||||
if (!TextFileLoader.SetChildNode("hairdata", i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Temporary - 이벤트를 위한 임시 기능
|
||||
TextFileLoader.GetTokenString("specialpath", &strPathName);
|
||||
/////////////////////////
|
||||
|
||||
DWORD dwShapeIndex;
|
||||
if (!TextFileLoader.GetTokenDoubleWord("hairindex", &dwShapeIndex))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string strModel;
|
||||
std::string strSourceSkin;
|
||||
std::string strTargetSkin;
|
||||
if (TextFileLoader.GetTokenString("model", &strModel) &&
|
||||
TextFileLoader.GetTokenString("sourceskin", &strSourceSkin) &&
|
||||
TextFileLoader.GetTokenString("targetskin", &strTargetSkin))
|
||||
{
|
||||
SetHairSkin(dwShapeIndex, 0, (strPathName + strModel).c_str(), (strPathName + strSourceSkin).c_str(), (strPathName + strTargetSkin).c_str());
|
||||
}
|
||||
|
||||
TextFileLoader.SetParentNode();
|
||||
}
|
||||
}
|
||||
|
||||
TextFileLoader.SetParentNode();
|
||||
}
|
||||
|
||||
|
||||
if (TextFileLoader.SetChildNode("attachingdata"))
|
||||
{
|
||||
if (!NRaceData::LoadAttachingData(TextFileLoader, &m_AttachingDataVector))
|
||||
return FALSE;
|
||||
|
||||
TextFileLoader.SetParentNode();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
#include "StdAfx.h"
|
||||
#include "RaceManager.h"
|
||||
#include "RaceMotionData.h"
|
||||
#include "../EterPack/EterPackManager.h"
|
||||
|
||||
bool __IsGuildRace(unsigned race)
|
||||
{
|
||||
if (race >= 14000 && race < 15000)
|
||||
return true;
|
||||
|
||||
if (20043 == race)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __IsNPCRace(unsigned race)
|
||||
{
|
||||
if (race > 9000)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void __GetRaceResourcePathes(unsigned race, std::vector <std::string>& vec_stPathes)
|
||||
{
|
||||
if (__IsGuildRace(race))
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
}
|
||||
else if (__IsNPCRace(race))
|
||||
{
|
||||
if (race >= 30000)
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
}
|
||||
else
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
}
|
||||
}
|
||||
// 만우절 이벤트용 예외 몬스터
|
||||
else if (8507 == race || 8510 == race)
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
}
|
||||
else if (race > 8000)
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
}
|
||||
else if (race > 2000)
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
}
|
||||
else if (race>=1400 && race<=1700)
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
}
|
||||
else
|
||||
{
|
||||
vec_stPathes.push_back ("d:/ymir work/monster/");
|
||||
vec_stPathes.push_back ("d:/ymir work/monster2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc/");
|
||||
vec_stPathes.push_back ("d:/ymir work/npc2/");
|
||||
vec_stPathes.push_back ("d:/ymir work/guild/");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CRaceData* CRaceManager::__LoadRaceData(DWORD dwRaceIndex)
|
||||
{
|
||||
std::map<DWORD, std::string>::iterator fRaceName=m_kMap_dwRaceKey_stRaceName.find(dwRaceIndex);
|
||||
if (m_kMap_dwRaceKey_stRaceName.end()==fRaceName)
|
||||
return NULL;
|
||||
|
||||
const std::string& c_rstRaceName=fRaceName->second;
|
||||
|
||||
if (c_rstRaceName.empty())
|
||||
return NULL;
|
||||
|
||||
// LOAD_LOCAL_RESOURCE
|
||||
if (c_rstRaceName[0] == '#')
|
||||
{
|
||||
const char* pathName = c_rstRaceName.c_str() + 1;
|
||||
char shapeFileName[256];
|
||||
char motionListFileName[256];
|
||||
_snprintf(shapeFileName, sizeof(shapeFileName), "%sshape.msm", pathName);
|
||||
_snprintf(motionListFileName, sizeof(motionListFileName), "%smotlist.txt", pathName);
|
||||
|
||||
CRaceData * pRaceData = CRaceData::New();
|
||||
pRaceData->SetRace(dwRaceIndex);
|
||||
if (!pRaceData->LoadRaceData(shapeFileName))
|
||||
{
|
||||
TraceError("CRaceManager::RegisterRacePath(race=%u).LoadRaceData(%s)", dwRaceIndex, shapeFileName);
|
||||
CRaceData::Delete(pRaceData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__LoadRaceMotionList(*pRaceData, pathName, motionListFileName);
|
||||
|
||||
return pRaceData;
|
||||
}
|
||||
// END_OF_LOAD_LOCAL_RESOURCE
|
||||
std::vector <std::string> vec_stFullPathName;
|
||||
__GetRaceResourcePathes(dwRaceIndex, vec_stFullPathName);
|
||||
|
||||
CRaceData * pRaceData = CRaceData::New();
|
||||
pRaceData->SetRace(dwRaceIndex);
|
||||
|
||||
for (int i = 0; i < vec_stFullPathName.size(); i++)
|
||||
{
|
||||
std::string stFullPathName = vec_stFullPathName[i];
|
||||
{
|
||||
std::map<std::string, std::string>::iterator fRaceSrcName=m_kMap_stRaceName_stSrcName.find(c_rstRaceName);
|
||||
if (m_kMap_stRaceName_stSrcName.end()==fRaceSrcName)
|
||||
stFullPathName+=c_rstRaceName;
|
||||
else
|
||||
stFullPathName+=fRaceSrcName->second;
|
||||
}
|
||||
|
||||
stFullPathName+="/";
|
||||
|
||||
std::string stMSMFileName=stFullPathName;
|
||||
stMSMFileName+=c_rstRaceName;
|
||||
stMSMFileName+=".msm";
|
||||
|
||||
if (!pRaceData->LoadRaceData(stMSMFileName.c_str()))
|
||||
{
|
||||
if (i != vec_stFullPathName.size() - 1)
|
||||
{
|
||||
TraceError("CRaceManager::RegisterRacePath : RACE[%u] LOAD MSMFILE[%s] ERROR. Will Find Another Path.", dwRaceIndex, stMSMFileName.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
TraceError("CRaceManager::RegisterRacePath : RACE[%u] LOAD MSMFILE[%s] ERROR", dwRaceIndex, stMSMFileName.c_str());
|
||||
CRaceData::Delete(pRaceData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::string stMotionListFileName=stFullPathName;
|
||||
stMotionListFileName+=pRaceData->GetMotionListFileName();
|
||||
|
||||
__LoadRaceMotionList(*pRaceData, stFullPathName.c_str(), stMotionListFileName.c_str());
|
||||
|
||||
return pRaceData;
|
||||
}
|
||||
TraceError("CRaceManager::RegisterRacePath : RACE[%u] HAVE NO PATH ERROR", dwRaceIndex);
|
||||
CRaceData::Delete(pRaceData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CRaceManager::__LoadRaceMotionList(CRaceData& rkRaceData, const char* pathName, const char* motionListFileName)
|
||||
{
|
||||
static std::map<std::string, DWORD> s_kMap_stType_dwIndex;
|
||||
static bool s_isInit=false;
|
||||
|
||||
if (!s_isInit)
|
||||
{
|
||||
s_isInit=true;
|
||||
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SPAWN", CRaceMotionData::NAME_SPAWN));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("WAIT", CRaceMotionData::NAME_WAIT));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("WAIT1", CRaceMotionData::NAME_WAIT));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("WAIT2", CRaceMotionData::NAME_WAIT));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("WALK", CRaceMotionData::NAME_WALK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("WALK1", CRaceMotionData::NAME_WALK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("WALK2", CRaceMotionData::NAME_WALK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("RUN", CRaceMotionData::NAME_RUN));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("RUN1", CRaceMotionData::NAME_RUN));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("RUN2", CRaceMotionData::NAME_RUN));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("STOP", CRaceMotionData::NAME_STOP));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("DEAD", CRaceMotionData::NAME_DEAD));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("COMBO_ATTACK", CRaceMotionData::NAME_COMBO_ATTACK_1));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("COMBO_ATTACK1", CRaceMotionData::NAME_COMBO_ATTACK_2));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("COMBO_ATTACK2", CRaceMotionData::NAME_COMBO_ATTACK_3));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("NORMAL_ATTACK", CRaceMotionData::NAME_NORMAL_ATTACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("NORMAL_ATTACK1", CRaceMotionData::NAME_NORMAL_ATTACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("NORMAL_ATTACK2", CRaceMotionData::NAME_NORMAL_ATTACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_DAMAGE", CRaceMotionData::NAME_DAMAGE));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_DAMAGE1", CRaceMotionData::NAME_DAMAGE));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_DAMAGE2", CRaceMotionData::NAME_DAMAGE));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_DAMAGE3", CRaceMotionData::NAME_DAMAGE));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_DEAD", CRaceMotionData::NAME_DEAD));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_DEAD1", CRaceMotionData::NAME_DEAD));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_DEAD2", CRaceMotionData::NAME_DEAD));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_KNOCKDOWN", CRaceMotionData::NAME_DAMAGE_FLYING));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_KNOCKDOWN1", CRaceMotionData::NAME_DAMAGE_FLYING));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_STANDUP", CRaceMotionData::NAME_STAND_UP));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("FRONT_STANDUP1", CRaceMotionData::NAME_STAND_UP));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_DAMAGE", CRaceMotionData::NAME_DAMAGE_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_DAMAGE1", CRaceMotionData::NAME_DAMAGE_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_DEAD", CRaceMotionData::NAME_DEAD_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_DEAD1", CRaceMotionData::NAME_DEAD_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_DEAD2", CRaceMotionData::NAME_DEAD_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_KNOCKDOWN", CRaceMotionData::NAME_DAMAGE_FLYING_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_KNOCKDOWN1", CRaceMotionData::NAME_DAMAGE_FLYING_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_STANDUP", CRaceMotionData::NAME_STAND_UP_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("BACK_STANDUP1", CRaceMotionData::NAME_STAND_UP_BACK));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SPECIAL", CRaceMotionData::NAME_SPECIAL_1));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SPECIAL1", CRaceMotionData::NAME_SPECIAL_2));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SPECIAL2", CRaceMotionData::NAME_SPECIAL_3));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SPECIAL3", CRaceMotionData::NAME_SPECIAL_4));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SPECIAL4", CRaceMotionData::NAME_SPECIAL_5));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SPECIAL5", CRaceMotionData::NAME_SPECIAL_6));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL1", CRaceMotionData::NAME_SKILL+121));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL2", CRaceMotionData::NAME_SKILL+122));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL3", CRaceMotionData::NAME_SKILL+123));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL4", CRaceMotionData::NAME_SKILL+124));
|
||||
s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL5", CRaceMotionData::NAME_SKILL+125));
|
||||
}
|
||||
|
||||
const void* pvData;
|
||||
CMappedFile kMappedFile;
|
||||
if (!CEterPackManager::Instance().Get(kMappedFile, motionListFileName, &pvData))
|
||||
return false;
|
||||
|
||||
|
||||
CMemoryTextFileLoader kTextFileLoader;
|
||||
kTextFileLoader.Bind(kMappedFile.Size(), pvData);
|
||||
|
||||
rkRaceData.RegisterMotionMode(CRaceMotionData::MODE_GENERAL);
|
||||
|
||||
char szMode[256];
|
||||
char szType[256];
|
||||
char szFile[256];
|
||||
int nPercent = 0;
|
||||
|
||||
bool isSpawn=false;
|
||||
|
||||
static std::string stSpawnMotionFileName;
|
||||
static std::string stMotionFileName;
|
||||
|
||||
stSpawnMotionFileName = "";
|
||||
stMotionFileName = "";
|
||||
|
||||
UINT uLineCount=kTextFileLoader.GetLineCount();
|
||||
for (UINT uLineIndex=0; uLineIndex<uLineCount; ++uLineIndex)
|
||||
{
|
||||
DWORD motionType = CRaceMotionData::NAME_NONE;
|
||||
|
||||
const std::string& c_rstLine=kTextFileLoader.GetLineString(uLineIndex);
|
||||
sscanf(c_rstLine.c_str(), "%s %s %s %d", szMode, szType, szFile, &nPercent);
|
||||
|
||||
std::map<std::string, DWORD>::iterator fTypeIndex=s_kMap_stType_dwIndex.find(szType);
|
||||
|
||||
if (s_kMap_stType_dwIndex.end() == fTypeIndex)
|
||||
{
|
||||
// 모션 목록에 WAIT, WAIT4, WAIT20 이런 식으로 등록되어 있을 때,
|
||||
// WAIT4, WAIT20을 WAIT로 인식할 수 있도록 처리
|
||||
const size_t c_cutLengthLimit = 2;
|
||||
bool bFound = false;
|
||||
|
||||
if (c_cutLengthLimit < strlen(szType) + 1)
|
||||
{
|
||||
for (size_t i = 1; i <= c_cutLengthLimit; ++i)
|
||||
{
|
||||
std::string typeName = std::string(szType).substr(0, strlen(szType) - i);
|
||||
fTypeIndex = s_kMap_stType_dwIndex.find(typeName);
|
||||
|
||||
if (s_kMap_stType_dwIndex.end() != fTypeIndex)
|
||||
{
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (false == bFound)
|
||||
continue;
|
||||
}
|
||||
|
||||
motionType = fTypeIndex->second;
|
||||
|
||||
stMotionFileName = pathName;
|
||||
stMotionFileName += szFile;
|
||||
|
||||
rkRaceData.RegisterMotionData(CRaceMotionData::MODE_GENERAL, motionType, stMotionFileName.c_str(), nPercent);
|
||||
|
||||
switch (motionType)
|
||||
{
|
||||
case CRaceMotionData::NAME_SPAWN:
|
||||
isSpawn=true;
|
||||
break;
|
||||
case CRaceMotionData::NAME_DAMAGE:
|
||||
stSpawnMotionFileName=stMotionFileName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isSpawn && stSpawnMotionFileName!="")
|
||||
{
|
||||
rkRaceData.RegisterMotionData(CRaceMotionData::MODE_GENERAL, CRaceMotionData::NAME_SPAWN, stSpawnMotionFileName.c_str(), nPercent);
|
||||
}
|
||||
|
||||
rkRaceData.RegisterNormalAttack(CRaceMotionData::MODE_GENERAL, CRaceMotionData::NAME_NORMAL_ATTACK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRaceManager::RegisterRaceSrcName(const char * c_szName, const char * c_szSrcName)
|
||||
{
|
||||
m_kMap_stRaceName_stSrcName.insert(std::map<std::string, std::string>::value_type(c_szName, c_szSrcName));
|
||||
}
|
||||
|
||||
void CRaceManager::RegisterRaceName(DWORD dwRaceIndex, const char * c_szName)
|
||||
{
|
||||
m_kMap_dwRaceKey_stRaceName.insert(std::map<DWORD, std::string>::value_type(dwRaceIndex, c_szName));
|
||||
}
|
||||
|
||||
void CRaceManager::CreateRace(DWORD dwRaceIndex)
|
||||
{
|
||||
if (m_RaceDataMap.end() != m_RaceDataMap.find(dwRaceIndex))
|
||||
{
|
||||
TraceError("RaceManager::CreateRace : Race %u already created", dwRaceIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
CRaceData * pRaceData = CRaceData::New();
|
||||
pRaceData->SetRace(dwRaceIndex);
|
||||
m_RaceDataMap.insert(TRaceDataMap::value_type(dwRaceIndex, pRaceData));
|
||||
|
||||
Tracenf("CRaceManager::CreateRace(dwRaceIndex=%d)", dwRaceIndex);
|
||||
}
|
||||
|
||||
void CRaceManager::SelectRace(DWORD dwRaceIndex)
|
||||
{
|
||||
TRaceDataIterator itor = m_RaceDataMap.find(dwRaceIndex);
|
||||
if (m_RaceDataMap.end() == itor)
|
||||
{
|
||||
assert(!"Failed to select race data!");
|
||||
return;
|
||||
}
|
||||
|
||||
m_pSelectedRaceData = itor->second;
|
||||
}
|
||||
|
||||
CRaceData * CRaceManager::GetSelectedRaceDataPointer()
|
||||
{
|
||||
return m_pSelectedRaceData;
|
||||
}
|
||||
|
||||
BOOL CRaceManager::GetRaceDataPointer(DWORD dwRaceIndex, CRaceData ** ppRaceData)
|
||||
{
|
||||
TRaceDataIterator itor = m_RaceDataMap.find(dwRaceIndex);
|
||||
|
||||
if (m_RaceDataMap.end() == itor)
|
||||
{
|
||||
CRaceData* pRaceData = __LoadRaceData(dwRaceIndex);
|
||||
|
||||
if (pRaceData)
|
||||
{
|
||||
m_RaceDataMap.insert(TRaceDataMap::value_type(dwRaceIndex, pRaceData));
|
||||
*ppRaceData = pRaceData;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TraceError("CRaceManager::GetRaceDataPointer: cannot load data by dwRaceIndex %lu", dwRaceIndex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*ppRaceData = itor->second;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CRaceManager::SetPathName(const char * c_szPathName)
|
||||
{
|
||||
m_strPathName = c_szPathName;
|
||||
}
|
||||
|
||||
const char * CRaceManager::GetFullPathFileName(const char * c_szFileName)
|
||||
{
|
||||
static std::string s_stFileName;
|
||||
|
||||
if (c_szFileName[0] != '.')
|
||||
{
|
||||
s_stFileName = m_strPathName;
|
||||
s_stFileName += c_szFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_stFileName = c_szFileName;
|
||||
}
|
||||
|
||||
return s_stFileName.c_str();
|
||||
}
|
||||
|
||||
|
||||
void CRaceManager::Create()
|
||||
{
|
||||
CRaceMotionData::CreateSystem(2048);
|
||||
CRaceData::CreateSystem(256, 512);
|
||||
}
|
||||
|
||||
void CRaceManager::__Initialize()
|
||||
{
|
||||
m_pSelectedRaceData = NULL;
|
||||
}
|
||||
|
||||
void CRaceManager::__DestroyRaceDataMap()
|
||||
{
|
||||
TRaceDataMap::iterator i;
|
||||
for (i=m_RaceDataMap.begin(); i!=m_RaceDataMap.end(); ++i)
|
||||
CRaceData::Delete(i->second);
|
||||
|
||||
m_RaceDataMap.clear();
|
||||
}
|
||||
|
||||
void CRaceManager::Destroy()
|
||||
{
|
||||
__DestroyRaceDataMap();
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CRaceManager::CRaceManager()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CRaceManager::~CRaceManager()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include "RaceData.h"
|
||||
|
||||
class CRaceManager : public CSingleton<CRaceManager>
|
||||
{
|
||||
public:
|
||||
typedef std::map<DWORD, CRaceData *> TRaceDataMap;
|
||||
typedef TRaceDataMap::iterator TRaceDataIterator;
|
||||
|
||||
public:
|
||||
CRaceManager();
|
||||
virtual ~CRaceManager();
|
||||
|
||||
void Create();
|
||||
void Destroy();
|
||||
|
||||
void RegisterRaceName(DWORD dwRaceIndex, const char * c_szName);
|
||||
void RegisterRaceSrcName(const char * c_szName, const char * c_szSrcName);
|
||||
|
||||
void SetPathName(const char * c_szPathName);
|
||||
const char * GetFullPathFileName(const char* c_szFileName);
|
||||
|
||||
// Handling
|
||||
void CreateRace(DWORD dwRaceIndex);
|
||||
void SelectRace(DWORD dwRaceIndex);
|
||||
CRaceData * GetSelectedRaceDataPointer();
|
||||
// Handling
|
||||
|
||||
BOOL GetRaceDataPointer(DWORD dwRaceIndex, CRaceData ** ppRaceData);
|
||||
|
||||
|
||||
protected:
|
||||
CRaceData* __LoadRaceData(DWORD dwRaceIndex);
|
||||
bool __LoadRaceMotionList(CRaceData& rkRaceData, const char* pathName, const char* motionListFileName);
|
||||
|
||||
void __Initialize();
|
||||
void __DestroyRaceDataMap();
|
||||
|
||||
protected:
|
||||
TRaceDataMap m_RaceDataMap;
|
||||
|
||||
std::map<std::string, std::string> m_kMap_stRaceName_stSrcName;
|
||||
std::map<DWORD, std::string> m_kMap_dwRaceKey_stRaceName;
|
||||
|
||||
private:
|
||||
std::string m_strPathName;
|
||||
CRaceData * m_pSelectedRaceData;
|
||||
};
|
||||
@@ -0,0 +1,617 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../EffectLib/EffectManager.h"
|
||||
#include "FlyingObjectManager.h"
|
||||
#include "RaceMotionData.h"
|
||||
|
||||
CDynamicPool<CRaceMotionData> CRaceMotionData::ms_kPool;
|
||||
|
||||
void CRaceMotionData::CreateSystem(UINT uCapacity)
|
||||
{
|
||||
ms_kPool.Create(uCapacity);
|
||||
}
|
||||
|
||||
void CRaceMotionData::DestroySystem()
|
||||
{
|
||||
ms_kPool.Clear();
|
||||
}
|
||||
|
||||
CRaceMotionData* CRaceMotionData::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CRaceMotionData::Delete(CRaceMotionData* pkData)
|
||||
{
|
||||
pkData->Destroy();
|
||||
|
||||
ms_kPool.Free(pkData);
|
||||
}
|
||||
|
||||
void CRaceMotionData::SetName(UINT eName)
|
||||
{
|
||||
m_eName=eName;
|
||||
|
||||
switch (m_eName)
|
||||
{
|
||||
case NAME_NONE:
|
||||
SetType(TYPE_NONE);
|
||||
break;
|
||||
case NAME_WAIT:
|
||||
case NAME_INTRO_WAIT:
|
||||
case NAME_STOP:
|
||||
SetType(TYPE_WAIT);
|
||||
break;
|
||||
case NAME_WALK:
|
||||
case NAME_RUN:
|
||||
SetType(TYPE_MOVE);
|
||||
break;
|
||||
case NAME_DAMAGE:
|
||||
case NAME_DAMAGE_BACK:
|
||||
SetType(TYPE_DAMAGE);
|
||||
break;
|
||||
case NAME_DAMAGE_FLYING:
|
||||
case NAME_DAMAGE_FLYING_BACK:
|
||||
SetType(TYPE_KNOCKDOWN);
|
||||
break;
|
||||
case NAME_STAND_UP:
|
||||
case NAME_STAND_UP_BACK:
|
||||
SetType(TYPE_STANDUP);
|
||||
break;
|
||||
case NAME_SPAWN:
|
||||
case NAME_CHANGE_WEAPON:
|
||||
case NAME_INTRO_SELECTED:
|
||||
case NAME_INTRO_NOT_SELECTED:
|
||||
case NAME_SPECIAL_1:
|
||||
case NAME_SPECIAL_2:
|
||||
case NAME_SPECIAL_3:
|
||||
case NAME_SPECIAL_4:
|
||||
case NAME_SPECIAL_5:
|
||||
case NAME_SPECIAL_6:
|
||||
case NAME_CLAP:
|
||||
case NAME_DANCE_1:
|
||||
case NAME_DANCE_2:
|
||||
case NAME_DANCE_3:
|
||||
case NAME_DANCE_4:
|
||||
case NAME_DANCE_5:
|
||||
case NAME_DANCE_6:
|
||||
case NAME_CONGRATULATION:
|
||||
case NAME_FORGIVE:
|
||||
case NAME_ANGRY:
|
||||
case NAME_ATTRACTIVE:
|
||||
case NAME_SAD:
|
||||
case NAME_SHY:
|
||||
case NAME_CHEERUP:
|
||||
case NAME_BANTER:
|
||||
case NAME_JOY:
|
||||
case NAME_CHEERS_1:
|
||||
case NAME_CHEERS_2:
|
||||
case NAME_KISS_WITH_WARRIOR:
|
||||
case NAME_KISS_WITH_ASSASSIN:
|
||||
case NAME_KISS_WITH_SURA:
|
||||
case NAME_KISS_WITH_SHAMAN:
|
||||
case NAME_FRENCH_KISS_WITH_WARRIOR:
|
||||
case NAME_FRENCH_KISS_WITH_ASSASSIN:
|
||||
case NAME_FRENCH_KISS_WITH_SURA:
|
||||
case NAME_FRENCH_KISS_WITH_SHAMAN:
|
||||
case NAME_SLAP_HIT_WITH_WARRIOR:
|
||||
case NAME_SLAP_HIT_WITH_ASSASSIN:
|
||||
case NAME_SLAP_HIT_WITH_SURA:
|
||||
case NAME_SLAP_HIT_WITH_SHAMAN:
|
||||
case NAME_SLAP_HURT_WITH_WARRIOR:
|
||||
case NAME_SLAP_HURT_WITH_ASSASSIN:
|
||||
case NAME_SLAP_HURT_WITH_SURA:
|
||||
case NAME_SLAP_HURT_WITH_SHAMAN:
|
||||
case NAME_DIG:
|
||||
SetType(TYPE_EVENT);
|
||||
break;
|
||||
case NAME_DEAD:
|
||||
case NAME_DEAD_BACK:
|
||||
SetType(TYPE_DIE);
|
||||
break;
|
||||
case NAME_NORMAL_ATTACK:
|
||||
SetType(TYPE_ATTACK);
|
||||
break;
|
||||
case NAME_COMBO_ATTACK_1:
|
||||
case NAME_COMBO_ATTACK_2:
|
||||
case NAME_COMBO_ATTACK_3:
|
||||
case NAME_COMBO_ATTACK_4:
|
||||
case NAME_COMBO_ATTACK_5:
|
||||
case NAME_COMBO_ATTACK_6:
|
||||
case NAME_COMBO_ATTACK_7:
|
||||
case NAME_COMBO_ATTACK_8:
|
||||
SetType(TYPE_COMBO);
|
||||
break;
|
||||
case NAME_FISHING_THROW:
|
||||
case NAME_FISHING_WAIT:
|
||||
case NAME_FISHING_REACT:
|
||||
case NAME_FISHING_CATCH:
|
||||
case NAME_FISHING_FAIL:
|
||||
case NAME_FISHING_STOP:
|
||||
SetType(TYPE_FISHING);
|
||||
break;
|
||||
default:
|
||||
if (eName>=NAME_SKILL && eName<=NAME_SKILL+SKILL_NUM)
|
||||
SetType(TYPE_SKILL);
|
||||
else
|
||||
TraceError("CRaceMotionData::SetName - UNKNOWN NAME %d", eName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void CRaceMotionData::SetType(UINT eType)
|
||||
{
|
||||
m_eType=eType;
|
||||
|
||||
switch (m_eType)
|
||||
{
|
||||
case TYPE_ATTACK:
|
||||
case TYPE_COMBO:
|
||||
case TYPE_SKILL:
|
||||
m_isLock=TRUE;
|
||||
break;
|
||||
default:
|
||||
m_isLock=FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UINT CRaceMotionData::GetType() const
|
||||
{
|
||||
return m_eType;
|
||||
}
|
||||
|
||||
bool CRaceMotionData::IsLock() const
|
||||
{
|
||||
return m_isLock ? true : false;
|
||||
}
|
||||
|
||||
int CRaceMotionData::GetLoopCount() const
|
||||
{
|
||||
return m_iLoopCount;
|
||||
}
|
||||
|
||||
float CRaceMotionData::GetMotionDuration()
|
||||
{
|
||||
return m_fMotionDuration;
|
||||
}
|
||||
|
||||
void CRaceMotionData::SetMotionDuration(float fDuration)
|
||||
{
|
||||
m_fMotionDuration = fDuration;
|
||||
}
|
||||
|
||||
// Combo
|
||||
BOOL CRaceMotionData::IsComboInputTimeData() const
|
||||
{
|
||||
return m_isComboMotion;
|
||||
}
|
||||
|
||||
float CRaceMotionData::GetComboInputStartTime() const
|
||||
{
|
||||
assert(m_isComboMotion);
|
||||
return m_ComboInputData.fInputStartTime;
|
||||
}
|
||||
|
||||
float CRaceMotionData::GetNextComboTime() const
|
||||
{
|
||||
assert(m_isComboMotion);
|
||||
return m_ComboInputData.fNextComboTime;
|
||||
}
|
||||
|
||||
float CRaceMotionData::GetComboInputEndTime() const
|
||||
{
|
||||
assert(m_isComboMotion);
|
||||
return m_ComboInputData.fInputEndTime;
|
||||
}
|
||||
|
||||
// Attacking
|
||||
BOOL CRaceMotionData::isAttackingMotion() const
|
||||
{
|
||||
return m_isAttackingMotion;
|
||||
}
|
||||
|
||||
const NRaceData::TMotionAttackData * CRaceMotionData::GetMotionAttackDataPointer() const
|
||||
{
|
||||
return & m_MotionAttackData;
|
||||
}
|
||||
|
||||
const NRaceData::TMotionAttackData & CRaceMotionData::GetMotionAttackDataReference() const
|
||||
{
|
||||
assert(m_isAttackingMotion);
|
||||
return m_MotionAttackData;
|
||||
}
|
||||
|
||||
BOOL CRaceMotionData::HasSplashMotionEvent() const
|
||||
{
|
||||
return m_hasSplashEvent;
|
||||
}
|
||||
|
||||
// Skill
|
||||
BOOL CRaceMotionData::IsCancelEnableSkill() const
|
||||
{
|
||||
return m_bCancelEnableSkill;
|
||||
}
|
||||
|
||||
// Loop
|
||||
BOOL CRaceMotionData::IsLoopMotion() const
|
||||
{
|
||||
return m_isLoopMotion;
|
||||
}
|
||||
|
||||
float CRaceMotionData::GetLoopStartTime() const
|
||||
{
|
||||
return m_fLoopStartTime;
|
||||
}
|
||||
|
||||
float CRaceMotionData::GetLoopEndTime() const
|
||||
{
|
||||
return m_fLoopEndTime;
|
||||
}
|
||||
|
||||
// Motion Event Data
|
||||
DWORD CRaceMotionData::GetMotionEventDataCount() const
|
||||
{
|
||||
return m_MotionEventDataVector.size();
|
||||
}
|
||||
|
||||
BOOL CRaceMotionData::GetMotionEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionEventData ** c_ppData) const
|
||||
{
|
||||
if (byIndex >= m_MotionEventDataVector.size())
|
||||
return FALSE;
|
||||
|
||||
*c_ppData = m_MotionEventDataVector[byIndex];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CRaceMotionData::GetMotionAttackingEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionAttackingEventData ** c_ppData) const
|
||||
{
|
||||
if (byIndex >= m_MotionEventDataVector.size())
|
||||
return FALSE;
|
||||
|
||||
const CRaceMotionData::TMotionEventData * pData = m_MotionEventDataVector[byIndex];
|
||||
const CRaceMotionData::TMotionAttackingEventData * pAttackingEvent = (const CRaceMotionData::TMotionAttackingEventData *)pData;
|
||||
|
||||
if (MOTION_EVENT_TYPE_SPECIAL_ATTACKING == pAttackingEvent->iType)
|
||||
return FALSE;
|
||||
|
||||
*c_ppData = pAttackingEvent;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int CRaceMotionData::GetEventType(DWORD dwIndex) const
|
||||
{
|
||||
if (dwIndex >= m_MotionEventDataVector.size())
|
||||
return MOTION_EVENT_TYPE_NONE;
|
||||
|
||||
return m_MotionEventDataVector[dwIndex]->iType;
|
||||
}
|
||||
|
||||
float CRaceMotionData::GetEventStartTime(DWORD dwIndex) const
|
||||
{
|
||||
if (dwIndex >= m_MotionEventDataVector.size())
|
||||
return 0.0f;
|
||||
|
||||
return m_MotionEventDataVector[dwIndex]->fStartingTime;
|
||||
}
|
||||
|
||||
const NSound::TSoundInstanceVector * CRaceMotionData::GetSoundInstanceVectorPointer() const
|
||||
{
|
||||
return &m_SoundInstanceVector;
|
||||
}
|
||||
|
||||
void CRaceMotionData::SetAccumulationPosition(const TPixelPosition & c_rPos)
|
||||
{
|
||||
m_accumulationPosition = c_rPos;
|
||||
m_isAccumulationMotion = TRUE;
|
||||
}
|
||||
|
||||
bool CRaceMotionData::LoadMotionData(const char * c_szFileName)
|
||||
{
|
||||
const float c_fFrameTime = 1.0f / g_fGameFPS;
|
||||
|
||||
CTextFileLoader* pkTextFileLoader=CTextFileLoader::Cache(c_szFileName);
|
||||
if (!pkTextFileLoader)
|
||||
return false;
|
||||
|
||||
CTextFileLoader& rkTextFileLoader=*pkTextFileLoader;
|
||||
|
||||
if (rkTextFileLoader.IsEmpty())
|
||||
return false;
|
||||
|
||||
rkTextFileLoader.SetTop();
|
||||
|
||||
if (!rkTextFileLoader.GetTokenString("motionfilename", &m_strMotionFileName))
|
||||
return false;
|
||||
|
||||
if (!rkTextFileLoader.GetTokenFloat("motionduration", &m_fMotionDuration))
|
||||
return false;
|
||||
|
||||
CTokenVector * pTokenVector;
|
||||
|
||||
if (rkTextFileLoader.GetTokenVector("accumulation", &pTokenVector))
|
||||
{
|
||||
if (pTokenVector->size() != 3)
|
||||
{
|
||||
TraceError("CRaceMotioNData::LoadMotionData : syntax error on accumulation, vector size %d", pTokenVector->size());
|
||||
return false;
|
||||
}
|
||||
|
||||
TPixelPosition pos(atof(pTokenVector->at(0).c_str()),
|
||||
atof(pTokenVector->at(1).c_str()),
|
||||
atof(pTokenVector->at(2).c_str()));
|
||||
|
||||
SetAccumulationPosition(pos);
|
||||
}
|
||||
|
||||
std::string strNodeName;
|
||||
for (DWORD i = 0; i < rkTextFileLoader.GetChildNodeCount(); ++i)
|
||||
{
|
||||
CTextFileLoader::CGotoChild GotoChild(&rkTextFileLoader, i);
|
||||
|
||||
rkTextFileLoader.GetCurrentNodeName(&strNodeName);
|
||||
|
||||
if (0 == strNodeName.compare("comboinputdata"))
|
||||
{
|
||||
m_isComboMotion = TRUE;
|
||||
|
||||
if (!rkTextFileLoader.GetTokenFloat("preinputtime", &m_ComboInputData.fInputStartTime))
|
||||
return false;
|
||||
if (!rkTextFileLoader.GetTokenFloat("directinputtime", &m_ComboInputData.fNextComboTime))
|
||||
return false;
|
||||
if (!rkTextFileLoader.GetTokenFloat("inputlimittime", &m_ComboInputData.fInputEndTime))
|
||||
return false;
|
||||
}
|
||||
else if (0 == strNodeName.compare("attackingdata"))
|
||||
{
|
||||
m_isAttackingMotion = TRUE;
|
||||
|
||||
if (!NRaceData::LoadMotionAttackData(rkTextFileLoader, &m_MotionAttackData))
|
||||
return false;
|
||||
}
|
||||
else if (0 == strNodeName.compare("loopdata"))
|
||||
{
|
||||
m_isLoopMotion = TRUE;
|
||||
if (!rkTextFileLoader.GetTokenInteger("motionloopcount", &m_iLoopCount))
|
||||
{
|
||||
m_iLoopCount = -1;
|
||||
}
|
||||
if (!rkTextFileLoader.GetTokenInteger("loopcancelenable", &m_bCancelEnableSkill))
|
||||
{
|
||||
m_bCancelEnableSkill = FALSE;
|
||||
}
|
||||
if (!rkTextFileLoader.GetTokenFloat("loopstarttime", &m_fLoopStartTime))
|
||||
return false;
|
||||
if (!rkTextFileLoader.GetTokenFloat("loopendtime", &m_fLoopEndTime))
|
||||
return false;
|
||||
}
|
||||
else if (0 == strNodeName.compare("motioneventdata"))
|
||||
{
|
||||
DWORD dwMotionEventDataCount;
|
||||
|
||||
if (!rkTextFileLoader.GetTokenDoubleWord("motioneventdatacount", &dwMotionEventDataCount))
|
||||
continue;
|
||||
|
||||
stl_wipe(m_MotionEventDataVector);
|
||||
|
||||
m_MotionEventDataVector.resize(dwMotionEventDataCount, NULL);
|
||||
|
||||
for (DWORD j = 0; j < m_MotionEventDataVector.size(); ++j)
|
||||
{
|
||||
if (!rkTextFileLoader.SetChildNode("event", j))
|
||||
return false;
|
||||
|
||||
int iType;
|
||||
if (!rkTextFileLoader.GetTokenInteger("motioneventtype", &iType))
|
||||
return false;
|
||||
|
||||
TMotionEventData * pData = NULL;
|
||||
switch(iType)
|
||||
{
|
||||
case MOTION_EVENT_TYPE_FLY:
|
||||
pData = new TMotionFlyEventData;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_EFFECT:
|
||||
pData = new TMotionEffectEventData;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_SCREEN_WAVING:
|
||||
pData = new TScreenWavingEventData;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_SPECIAL_ATTACKING:
|
||||
pData = new TMotionAttackingEventData;
|
||||
m_hasSplashEvent = TRUE;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_SOUND:
|
||||
pData = new TMotionSoundEventData;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_CHARACTER_SHOW:
|
||||
pData = new TMotionCharacterShowEventData;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_CHARACTER_HIDE:
|
||||
pData = new TMotionCharacterHideEventData;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_WARP:
|
||||
pData = new TMotionWarpEventData;
|
||||
break;
|
||||
case MOTION_EVENT_TYPE_EFFECT_TO_TARGET:
|
||||
pData = new TMotionEffectToTargetEventData;
|
||||
break;
|
||||
default:
|
||||
assert(!" CRaceMotionData::LoadMotionData - Strange Event Type");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
m_MotionEventDataVector[j] = pData;
|
||||
m_MotionEventDataVector[j]->Load(rkTextFileLoader);
|
||||
m_MotionEventDataVector[j]->iType = iType;
|
||||
if (!rkTextFileLoader.GetTokenFloat("startingtime", &m_MotionEventDataVector[j]->fStartingTime))
|
||||
return false;
|
||||
|
||||
m_MotionEventDataVector[j]->dwFrame = (m_MotionEventDataVector[j]->fStartingTime / c_fFrameTime);
|
||||
|
||||
rkTextFileLoader.SetParentNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string strSoundFileNameTemp=c_szFileName;
|
||||
strSoundFileNameTemp = CFileNameHelper::NoExtension(strSoundFileNameTemp);
|
||||
strSoundFileNameTemp+= ".mss";
|
||||
|
||||
if (strSoundFileNameTemp.length() > 13)
|
||||
{
|
||||
const char * c_szHeader = &strSoundFileNameTemp[13];
|
||||
|
||||
m_strSoundScriptDataFileName = "sound/";
|
||||
m_strSoundScriptDataFileName += c_szHeader;
|
||||
|
||||
LoadSoundScriptData(m_strSoundScriptDataFileName.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#ifdef WORLD_EDITOR
|
||||
bool CRaceMotionData::SaveMotionData(const char * c_szFileName)
|
||||
{
|
||||
FILE * File;
|
||||
|
||||
SetFileAttributes(c_szFileName, FILE_ATTRIBUTE_NORMAL);
|
||||
File = fopen(c_szFileName, "w");
|
||||
|
||||
if (!File)
|
||||
{
|
||||
TraceError("CRaceMotionData::SaveMotionData : cannot open file for writing (filename: %s)", c_szFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(File, "ScriptType MotionData\n");
|
||||
fprintf(File, "\n");
|
||||
|
||||
fprintf(File, "MotionFileName \"%s\"\n", m_strMotionFileName.c_str());
|
||||
fprintf(File, "MotionDuration %f\n", m_fMotionDuration);
|
||||
|
||||
if (m_isAccumulationMotion)
|
||||
fprintf(File, "Accumulation %.2f\t%.2f\t%.2f\n", m_accumulationPosition.x, m_accumulationPosition.y, m_accumulationPosition.z);
|
||||
|
||||
fprintf(File, "\n");
|
||||
|
||||
if (m_isComboMotion)
|
||||
{
|
||||
fprintf(File, "Group ComboInputData\n");
|
||||
fprintf(File, "{\n");
|
||||
fprintf(File, " PreInputTime %f\n", m_ComboInputData.fInputStartTime);
|
||||
fprintf(File, " DirectInputTime %f\n", m_ComboInputData.fNextComboTime);
|
||||
fprintf(File, " InputLimitTime %f\n", m_ComboInputData.fInputEndTime);
|
||||
fprintf(File, "}\n");
|
||||
fprintf(File, "\n");
|
||||
}
|
||||
|
||||
if (m_isAttackingMotion)
|
||||
{
|
||||
fprintf(File, "Group AttackingData\n");
|
||||
fprintf(File, "{\n");
|
||||
NRaceData::SaveMotionAttackData(File, 1, m_MotionAttackData);
|
||||
fprintf(File, "}\n");
|
||||
fprintf(File, "\n");
|
||||
}
|
||||
|
||||
if (m_isLoopMotion)
|
||||
{
|
||||
fprintf(File, "Group LoopData\n");
|
||||
fprintf(File, "{\n");
|
||||
fprintf(File, " MotionLoopCount %d\n", m_iLoopCount);
|
||||
fprintf(File, " LoopCancelEnable %d\n", m_bCancelEnableSkill);
|
||||
fprintf(File, " LoopStartTime %f\n", m_fLoopStartTime);
|
||||
fprintf(File, " LoopEndTime %f\n", m_fLoopEndTime);
|
||||
fprintf(File, "}\n");
|
||||
fprintf(File, "\n");
|
||||
}
|
||||
|
||||
if (!m_MotionEventDataVector.empty())
|
||||
{
|
||||
fprintf(File, "Group MotionEventData\n");
|
||||
fprintf(File, "{\n");
|
||||
fprintf(File, " MotionEventDataCount %d\n", m_MotionEventDataVector.size());
|
||||
|
||||
for (DWORD j = 0; j < m_MotionEventDataVector.size(); ++j)
|
||||
{
|
||||
TMotionEventData * c_pData = m_MotionEventDataVector[j];
|
||||
|
||||
fprintf(File, " Group Event%02d\n", j);
|
||||
fprintf(File, " {\n");
|
||||
fprintf(File, " MotionEventType %d\n", c_pData->iType);
|
||||
fprintf(File, " StartingTime %f\n", c_pData->fStartingTime);
|
||||
c_pData->Save(File, 2);
|
||||
fprintf(File, " }\n");
|
||||
}
|
||||
fprintf(File, "}\n");
|
||||
}
|
||||
|
||||
fclose(File);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
bool CRaceMotionData::LoadSoundScriptData(const char * c_szFileName)
|
||||
{
|
||||
NSound::TSoundDataVector SoundDataVector;
|
||||
if (!NSound::LoadSoundInformationPiece(c_szFileName, SoundDataVector))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NSound::DataToInstance(SoundDataVector, &m_SoundInstanceVector);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char * CRaceMotionData::GetMotionFileName() const
|
||||
{
|
||||
return m_strMotionFileName.c_str();
|
||||
}
|
||||
|
||||
const char * CRaceMotionData::GetSoundScriptFileName() const
|
||||
{
|
||||
return m_strSoundScriptDataFileName.c_str();
|
||||
}
|
||||
|
||||
void CRaceMotionData::Initialize()
|
||||
{
|
||||
m_iLoopCount = 0;
|
||||
m_fMotionDuration = 0.0f;
|
||||
m_accumulationPosition.x = 0.0f;
|
||||
m_accumulationPosition.y = 0.0f;
|
||||
m_accumulationPosition.z = 0.0f;
|
||||
m_fLoopStartTime = 0.0f;
|
||||
m_fLoopEndTime = 0.0f;
|
||||
|
||||
m_isAccumulationMotion = FALSE;
|
||||
m_isComboMotion = FALSE;
|
||||
m_isLoopMotion = FALSE;
|
||||
m_isAttackingMotion = FALSE;
|
||||
m_bCancelEnableSkill = FALSE;
|
||||
|
||||
m_hasSplashEvent = FALSE;
|
||||
|
||||
m_isLock = FALSE;
|
||||
|
||||
m_eType=TYPE_NONE;
|
||||
m_eName=NAME_NONE;
|
||||
|
||||
m_MotionEventDataVector.clear();
|
||||
m_SoundInstanceVector.clear();
|
||||
}
|
||||
|
||||
void CRaceMotionData::Destroy()
|
||||
{
|
||||
stl_wipe(m_MotionEventDataVector);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CRaceMotionData::CRaceMotionData()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CRaceMotionData::~CRaceMotionData()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
#pragma once
|
||||
|
||||
#include "../milesLib/Type.h"
|
||||
#include "RaceMotionDataEvent.h"
|
||||
|
||||
class CRaceMotionData
|
||||
{
|
||||
public:
|
||||
enum EType
|
||||
{
|
||||
TYPE_NONE,
|
||||
TYPE_WAIT,
|
||||
TYPE_MOVE,
|
||||
TYPE_ATTACK,
|
||||
TYPE_COMBO,
|
||||
TYPE_DAMAGE,
|
||||
TYPE_KNOCKDOWN,
|
||||
TYPE_DIE,
|
||||
TYPE_SKILL,
|
||||
TYPE_STANDUP,
|
||||
TYPE_EVENT,
|
||||
TYPE_FISHING,
|
||||
TYPE_NUM,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SKILL_NUM = 255,
|
||||
};
|
||||
|
||||
enum EMode
|
||||
{
|
||||
MODE_RESERVED,
|
||||
MODE_GENERAL,
|
||||
|
||||
MODE_ONEHAND_SWORD,
|
||||
MODE_TWOHAND_SWORD,
|
||||
MODE_DUALHAND_SWORD,
|
||||
MODE_BOW,
|
||||
MODE_FAN,
|
||||
MODE_BELL,
|
||||
MODE_FISHING,
|
||||
|
||||
MODE_HORSE,
|
||||
MODE_HORSE_ONEHAND_SWORD,
|
||||
MODE_HORSE_TWOHAND_SWORD,
|
||||
MODE_HORSE_DUALHAND_SWORD,
|
||||
MODE_HORSE_BOW,
|
||||
MODE_HORSE_FAN,
|
||||
MODE_HORSE_BELL,
|
||||
|
||||
MODE_WEDDING_DRESS,
|
||||
|
||||
MODE_MAX_NUM,
|
||||
};
|
||||
|
||||
enum EName
|
||||
{
|
||||
NAME_NONE, // 0 없음
|
||||
NAME_WAIT, // 1 대기 (00.msa)
|
||||
NAME_WALK, // 2 걷기 (02.msa)
|
||||
NAME_RUN, // 3 뛰기 (03.msa)
|
||||
NAME_CHANGE_WEAPON, // 4 무기바꾸기
|
||||
NAME_DAMAGE, // 5 정면맞기 (30.msa)
|
||||
NAME_DAMAGE_FLYING, // 6 정면날아가기 (32.msa)
|
||||
NAME_STAND_UP, // 7 정면일어나기 (33.msa)
|
||||
NAME_DAMAGE_BACK, // 8 후면맞기 (34.msa)
|
||||
NAME_DAMAGE_FLYING_BACK, // 9 후면날아가기 (35.msa)
|
||||
NAME_STAND_UP_BACK, // 10 후면일어나기 (36.msa)
|
||||
NAME_DEAD, // 11 죽기 (31.msa)
|
||||
NAME_DEAD_BACK, // 12 후면죽기 (37.msa)
|
||||
NAME_NORMAL_ATTACK, // 13 공격 (20.msa)
|
||||
NAME_COMBO_ATTACK_1, // 14 콤보 공격
|
||||
NAME_COMBO_ATTACK_2, // 15 콤보 공격
|
||||
NAME_COMBO_ATTACK_3, // 16 콤보 공격
|
||||
NAME_COMBO_ATTACK_4, // 17 콤보 공격
|
||||
NAME_COMBO_ATTACK_5, // 18 콤보 공격
|
||||
NAME_COMBO_ATTACK_6, // 19 콤보 공격
|
||||
NAME_COMBO_ATTACK_7, // 20 콤보 공격
|
||||
NAME_COMBO_ATTACK_8, // 21 콤보 공격
|
||||
NAME_INTRO_WAIT, // 22 선택화면 대기
|
||||
NAME_INTRO_SELECTED, // 23 선택화면 선택
|
||||
NAME_INTRO_NOT_SELECTED, // 24 선택화면 비선택
|
||||
NAME_SPAWN, // 25 소환
|
||||
NAME_FISHING_THROW, // 26 낚시 던지기
|
||||
NAME_FISHING_WAIT, // 27 낚시 대기
|
||||
NAME_FISHING_STOP, // 28 낚시 그만두기
|
||||
NAME_FISHING_REACT, // 29 낚시 반응
|
||||
NAME_FISHING_CATCH, // 30 낚시 잡기
|
||||
NAME_FISHING_FAIL, // 31 낚시 실패
|
||||
NAME_STOP, // 32 말 멈추기
|
||||
NAME_SPECIAL_1, // 33 몬스터/NPC 특수 동작 (24.msa)
|
||||
NAME_SPECIAL_2, // 34 몬스터/NPC 특수 동작 (25.msa)
|
||||
NAME_SPECIAL_3,
|
||||
NAME_SPECIAL_4,
|
||||
NAME_SPECIAL_5,
|
||||
NAME_SPECIAL_6,
|
||||
NAME_SKILL = 50,
|
||||
NAME_SKILL_END = NAME_SKILL+SKILL_NUM,
|
||||
|
||||
// CLAP
|
||||
NAME_CLAP,
|
||||
|
||||
// CHEERS
|
||||
NAME_CHEERS_1,
|
||||
NAME_CHEERS_2,
|
||||
|
||||
// KISS
|
||||
NAME_KISS_START,
|
||||
NAME_KISS_WITH_WARRIOR = NAME_KISS_START + 0,
|
||||
NAME_KISS_WITH_ASSASSIN = NAME_KISS_START + 1,
|
||||
NAME_KISS_WITH_SURA = NAME_KISS_START + 2,
|
||||
NAME_KISS_WITH_SHAMAN = NAME_KISS_START + 3,
|
||||
|
||||
// FRENCH_KISS
|
||||
NAME_FRENCH_KISS_START,
|
||||
NAME_FRENCH_KISS_WITH_WARRIOR = NAME_FRENCH_KISS_START + 0,
|
||||
NAME_FRENCH_KISS_WITH_ASSASSIN = NAME_FRENCH_KISS_START + 1,
|
||||
NAME_FRENCH_KISS_WITH_SURA = NAME_FRENCH_KISS_START + 2,
|
||||
NAME_FRENCH_KISS_WITH_SHAMAN = NAME_FRENCH_KISS_START + 3,
|
||||
|
||||
// SLAP
|
||||
NAME_SLAP_HIT_START,
|
||||
NAME_SLAP_HIT_WITH_WARRIOR = NAME_SLAP_HIT_START + 0,
|
||||
NAME_SLAP_HIT_WITH_ASSASSIN = NAME_SLAP_HIT_START + 1,
|
||||
NAME_SLAP_HIT_WITH_SURA = NAME_SLAP_HIT_START + 2,
|
||||
NAME_SLAP_HIT_WITH_SHAMAN = NAME_SLAP_HIT_START + 3,
|
||||
|
||||
NAME_SLAP_HURT_START,
|
||||
NAME_SLAP_HURT_WITH_WARRIOR = NAME_SLAP_HURT_START + 0,
|
||||
NAME_SLAP_HURT_WITH_ASSASSIN = NAME_SLAP_HURT_START + 1,
|
||||
NAME_SLAP_HURT_WITH_SURA = NAME_SLAP_HURT_START + 2,
|
||||
NAME_SLAP_HURT_WITH_SHAMAN = NAME_SLAP_HURT_START + 3,
|
||||
|
||||
NAME_DIG,
|
||||
|
||||
NAME_DANCE_1,
|
||||
NAME_DANCE_2,
|
||||
NAME_DANCE_3,
|
||||
NAME_DANCE_4,
|
||||
NAME_DANCE_5,
|
||||
NAME_DANCE_6, // 강남스타일
|
||||
|
||||
NAME_DANCE_END = NAME_DANCE_1 + 16,
|
||||
|
||||
NAME_CONGRATULATION,
|
||||
NAME_FORGIVE,
|
||||
NAME_ANGRY,
|
||||
NAME_ATTRACTIVE,
|
||||
NAME_SAD,
|
||||
NAME_SHY,
|
||||
NAME_CHEERUP,
|
||||
NAME_BANTER,
|
||||
NAME_JOY,
|
||||
|
||||
NAME_MAX_NUM,
|
||||
};
|
||||
|
||||
enum EMotionEventType
|
||||
{
|
||||
MOTION_EVENT_TYPE_NONE,
|
||||
|
||||
MOTION_EVENT_TYPE_EFFECT,
|
||||
MOTION_EVENT_TYPE_SCREEN_WAVING,
|
||||
MOTION_EVENT_TYPE_SCREEN_FLASHING,
|
||||
MOTION_EVENT_TYPE_SPECIAL_ATTACKING,
|
||||
MOTION_EVENT_TYPE_SOUND,
|
||||
MOTION_EVENT_TYPE_FLY,
|
||||
MOTION_EVENT_TYPE_CHARACTER_SHOW,
|
||||
MOTION_EVENT_TYPE_CHARACTER_HIDE,
|
||||
MOTION_EVENT_TYPE_WARP,
|
||||
MOTION_EVENT_TYPE_EFFECT_TO_TARGET,
|
||||
|
||||
MOTION_EVENT_TYPE_MAX_NUM,
|
||||
};
|
||||
|
||||
typedef struct SComboInputData
|
||||
{
|
||||
float fInputStartTime;
|
||||
float fNextComboTime;
|
||||
float fInputEndTime;
|
||||
} TComboInputData;
|
||||
|
||||
typedef struct NMotionEvent::SMotionEventData TMotionEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataScreenWaving TScreenWavingEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataScreenFlashing TScreenFlashingEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataEffect TMotionEffectEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataFly TMotionFlyEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataAttack TMotionAttackingEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataSound TMotionSoundEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataCharacterShow TMotionCharacterShowEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataCharacterHide TMotionCharacterHideEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataWarp TMotionWarpEventData;
|
||||
typedef struct NMotionEvent::SMotionEventDataEffectToTarget TMotionEffectToTargetEventData;
|
||||
typedef std::vector<TMotionEventData*> TMotionEventDataVector;
|
||||
|
||||
public:
|
||||
static CRaceMotionData* New();
|
||||
static void Delete(CRaceMotionData* pkData);
|
||||
|
||||
static void CreateSystem(UINT uCapacity);
|
||||
static void DestroySystem();
|
||||
|
||||
public:
|
||||
CRaceMotionData();
|
||||
virtual ~CRaceMotionData();
|
||||
|
||||
void Initialize();
|
||||
void Destroy();
|
||||
|
||||
void SetName(UINT eName);
|
||||
|
||||
UINT GetType() const; // 모션 타입 얻기
|
||||
bool IsLock() const; // 락된 모션 인가? (다른 모션에 캔슬되지 않음)
|
||||
|
||||
int GetLoopCount() const;
|
||||
|
||||
const char * GetMotionFileName() const;
|
||||
const char * GetSoundScriptFileName() const;
|
||||
|
||||
void SetMotionDuration(float fDur);
|
||||
float GetMotionDuration();
|
||||
|
||||
bool IsAccumulationMotion();
|
||||
void SetAccumulationPosition(const TPixelPosition & c_rPos);
|
||||
const TPixelPosition & GetAccumulationPosition() { return m_accumulationPosition; }
|
||||
|
||||
BOOL IsComboInputTimeData() const; // 콤보 입력 타이밍 데이터가 있는가?
|
||||
|
||||
float GetComboInputStartTime() const;
|
||||
float GetNextComboTime() const;
|
||||
float GetComboInputEndTime() const;
|
||||
|
||||
// Attacking
|
||||
BOOL isAttackingMotion() const;
|
||||
const NRaceData::TMotionAttackData * GetMotionAttackDataPointer() const;
|
||||
const NRaceData::TMotionAttackData & GetMotionAttackDataReference() const;
|
||||
BOOL HasSplashMotionEvent() const;
|
||||
|
||||
// Skill
|
||||
BOOL IsCancelEnableSkill() const;
|
||||
|
||||
// Loop
|
||||
BOOL IsLoopMotion() const;
|
||||
float GetLoopStartTime() const;
|
||||
float GetLoopEndTime() const;
|
||||
|
||||
// Motion Event Data
|
||||
DWORD GetMotionEventDataCount() const;
|
||||
BOOL GetMotionEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionEventData ** c_ppData) const;
|
||||
BOOL GetMotionAttackingEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionAttackingEventData ** c_ppMotionEventData) const;
|
||||
int GetEventType(DWORD dwIndex) const;
|
||||
float GetEventStartTime(DWORD dwIndex) const;
|
||||
|
||||
// Sound Data
|
||||
const NSound::TSoundInstanceVector * GetSoundInstanceVectorPointer() const;
|
||||
|
||||
// File
|
||||
#ifdef WORLD_EDITOR
|
||||
bool SaveMotionData(const char * c_szFileName);
|
||||
#endif
|
||||
bool LoadMotionData(const char * c_szFileName);
|
||||
bool LoadSoundScriptData(const char * c_szFileName);
|
||||
|
||||
protected:
|
||||
void SetType(UINT eType);
|
||||
|
||||
protected:
|
||||
UINT m_eType;
|
||||
UINT m_eName;
|
||||
BOOL m_isLock;
|
||||
int m_iLoopCount;
|
||||
|
||||
std::string m_strMotionFileName;
|
||||
std::string m_strSoundScriptDataFileName;
|
||||
float m_fMotionDuration;
|
||||
|
||||
BOOL m_isAccumulationMotion;
|
||||
TPixelPosition m_accumulationPosition;
|
||||
|
||||
BOOL m_isComboMotion;
|
||||
TComboInputData m_ComboInputData;
|
||||
|
||||
BOOL m_isLoopMotion;
|
||||
float m_fLoopStartTime;
|
||||
float m_fLoopEndTime;
|
||||
|
||||
BOOL m_isAttackingMotion;
|
||||
NRaceData::TMotionAttackData m_MotionAttackData;
|
||||
|
||||
BOOL m_bCancelEnableSkill;
|
||||
|
||||
TMotionEventDataVector m_MotionEventDataVector;
|
||||
NSound::TSoundInstanceVector m_SoundInstanceVector;
|
||||
|
||||
private:
|
||||
BOOL m_hasSplashEvent;
|
||||
|
||||
protected:
|
||||
static CDynamicPool<CRaceMotionData> ms_kPool;
|
||||
};
|
||||
@@ -0,0 +1,290 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EffectLib/EffectManager.h"
|
||||
#include "FlyingObjectManager.h"
|
||||
|
||||
namespace NMotionEvent
|
||||
{
|
||||
typedef struct SMotionEventData
|
||||
{
|
||||
int iType;
|
||||
DWORD dwFrame;
|
||||
float fStartingTime;
|
||||
float fDurationTime;
|
||||
|
||||
SMotionEventData() : dwFrame(0), fStartingTime(0.0f), fDurationTime(0.0f) {}
|
||||
virtual ~SMotionEventData() {}
|
||||
|
||||
virtual void Save(FILE * File, int iTabs) = 0;
|
||||
virtual bool Load(CTextFileLoader & rTextFileLoader) { return true; }
|
||||
} TMotionEventData;
|
||||
|
||||
// Screen Waving
|
||||
typedef struct SMotionEventDataScreenWaving : public SMotionEventData
|
||||
{
|
||||
int iPower;
|
||||
int iAffectingRange;
|
||||
|
||||
SMotionEventDataScreenWaving() {}
|
||||
virtual ~SMotionEventDataScreenWaving() {}
|
||||
|
||||
void Save(FILE * File, int iTabs)
|
||||
{
|
||||
PrintfTabs(File, iTabs, "\n");
|
||||
PrintfTabs(File, iTabs, "DuringTime %f\n", fDurationTime);
|
||||
PrintfTabs(File, iTabs, "Power %d\n", iPower);
|
||||
PrintfTabs(File, iTabs, "AffectingRange %d\n", iAffectingRange);
|
||||
}
|
||||
bool Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenFloat("duringtime", &fDurationTime))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenInteger("power", &iPower))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenInteger("affectingrange", &iAffectingRange))
|
||||
iAffectingRange = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
} TMotionEventDataScreenWaving;
|
||||
|
||||
// Screen Flashing
|
||||
typedef struct SMotionEventDataScreenFlashing : public SMotionEventData
|
||||
{
|
||||
D3DXCOLOR FlashingColor;
|
||||
|
||||
SMotionEventDataScreenFlashing() {}
|
||||
virtual ~SMotionEventDataScreenFlashing() {}
|
||||
|
||||
void Save(FILE * File, int iTabs) {}
|
||||
bool Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} TMotionEventDataScreenFlashing;
|
||||
|
||||
// Effect
|
||||
typedef struct SMotionEventDataEffect : public SMotionEventData
|
||||
{
|
||||
BOOL isAttaching;
|
||||
BOOL isFollowing;
|
||||
BOOL isIndependent;
|
||||
std::string strAttachingBoneName;
|
||||
D3DXVECTOR3 v3EffectPosition;
|
||||
|
||||
DWORD dwEffectIndex;
|
||||
std::string strEffectFileName;
|
||||
|
||||
SMotionEventDataEffect() {}
|
||||
virtual ~SMotionEventDataEffect() {}
|
||||
|
||||
void Save(FILE * File, int iTabs)
|
||||
{
|
||||
PrintfTabs(File, iTabs, "\n");
|
||||
PrintfTabs(File, iTabs, "IndependentFlag %d\n", isIndependent);
|
||||
PrintfTabs(File, iTabs, "AttachingEnable %d\n", isAttaching);
|
||||
PrintfTabs(File, iTabs, "AttachingBoneName \"%s\"\n", strAttachingBoneName.c_str());
|
||||
PrintfTabs(File, iTabs, "FollowingEnable %d\n", isFollowing);
|
||||
PrintfTabs(File, iTabs, "EffectFileName \"%s\"\n", strEffectFileName.c_str());
|
||||
PrintfTabs(File, iTabs, "EffectPosition %f %f %f\n", v3EffectPosition.x, v3EffectPosition.y, v3EffectPosition.z);
|
||||
}
|
||||
virtual bool Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenBoolean("independentflag", &isIndependent))
|
||||
isIndependent = FALSE;
|
||||
if (!rTextFileLoader.GetTokenBoolean("attachingenable", &isAttaching))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenString("attachingbonename", &strAttachingBoneName))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenString("effectfilename", &strEffectFileName))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenPosition("effectposition", &v3EffectPosition))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenBoolean("followingenable", &isFollowing))
|
||||
{
|
||||
isFollowing = FALSE;
|
||||
}
|
||||
dwEffectIndex = GetCaseCRC32(strEffectFileName.c_str(), strEffectFileName.length());
|
||||
CEffectManager::Instance().RegisterEffect(strEffectFileName.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
} TMotionEventDataEffect;
|
||||
|
||||
// Effect To Target
|
||||
typedef struct SMotionEventDataEffectToTarget : public SMotionEventData
|
||||
{
|
||||
DWORD dwEffectIndex;
|
||||
|
||||
std::string strEffectFileName;
|
||||
D3DXVECTOR3 v3EffectPosition;
|
||||
BOOL isFollowing;
|
||||
BOOL isFishingEffect;
|
||||
|
||||
SMotionEventDataEffectToTarget() {}
|
||||
virtual ~SMotionEventDataEffectToTarget() {}
|
||||
|
||||
void Save(FILE * File, int iTabs)
|
||||
{
|
||||
PrintfTabs(File, iTabs, "\n");
|
||||
PrintfTabs(File, iTabs, "EffectFileName \"%s\"\n", strEffectFileName.c_str());
|
||||
PrintfTabs(File, iTabs, "EffectPosition %f %f %f\n", v3EffectPosition.x, v3EffectPosition.y, v3EffectPosition.z);
|
||||
PrintfTabs(File, iTabs, "FollowingEnable %d\n", isFollowing);
|
||||
PrintfTabs(File, iTabs, "FishingEffectFlag %d\n", isFishingEffect);
|
||||
}
|
||||
virtual bool Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenString("effectfilename", &strEffectFileName))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenPosition("effectposition", &v3EffectPosition))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenBoolean("followingenable", &isFollowing))
|
||||
{
|
||||
isFollowing = FALSE;
|
||||
}
|
||||
if (!rTextFileLoader.GetTokenBoolean("fishingeffectflag", &isFishingEffect))
|
||||
{
|
||||
isFishingEffect = FALSE;
|
||||
}
|
||||
dwEffectIndex = GetCaseCRC32(strEffectFileName.c_str(), strEffectFileName.length());
|
||||
#ifndef _DEBUG
|
||||
CEffectManager::Instance().RegisterEffect(strEffectFileName.c_str());
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
} TMotionEventDataEffectToTarget;
|
||||
|
||||
// Fly
|
||||
typedef struct SMotionEventDataFly : public SMotionEventData
|
||||
{
|
||||
BOOL isAttaching;
|
||||
std::string strAttachingBoneName;
|
||||
D3DXVECTOR3 v3FlyPosition;
|
||||
|
||||
DWORD dwFlyIndex;
|
||||
std::string strFlyFileName;
|
||||
|
||||
SMotionEventDataFly() {}
|
||||
virtual ~SMotionEventDataFly() {}
|
||||
|
||||
void Save(FILE * File, int iTabs)
|
||||
{
|
||||
PrintfTabs(File, iTabs, "\n");
|
||||
PrintfTabs(File, iTabs, "AttachingEnable %d\n", isAttaching);
|
||||
PrintfTabs(File, iTabs, "AttachingBoneName \"%s\"\n", strAttachingBoneName.c_str());
|
||||
PrintfTabs(File, iTabs, "FlyFileName \"%s\"\n", strFlyFileName.c_str());
|
||||
PrintfTabs(File, iTabs, "FlyPosition %f %f %f\n", v3FlyPosition.x, v3FlyPosition.y, v3FlyPosition.z);
|
||||
}
|
||||
bool Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenBoolean("attachingenable", &isAttaching))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenString("attachingbonename", &strAttachingBoneName))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenString("flyfilename", &strFlyFileName))
|
||||
return false;
|
||||
if (!rTextFileLoader.GetTokenPosition("flyposition", &v3FlyPosition))
|
||||
return false;
|
||||
dwFlyIndex = GetCaseCRC32(strFlyFileName.c_str(), strFlyFileName.length());
|
||||
|
||||
#ifndef _DEBUG
|
||||
// Register Fly
|
||||
CFlyingManager::Instance().RegisterFlyingData(strFlyFileName.c_str());
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
} TMotionEventDataFly;
|
||||
|
||||
// Attacking
|
||||
typedef struct SMotionEventDataAttack : public SMotionEventData
|
||||
{
|
||||
NRaceData::TCollisionData CollisionData;
|
||||
NRaceData::TAttackData AttackData;
|
||||
BOOL isEnableHitProcess;
|
||||
|
||||
SMotionEventDataAttack() {}
|
||||
virtual ~SMotionEventDataAttack() {}
|
||||
|
||||
void Save(FILE * File, int iTabs)
|
||||
{
|
||||
PrintfTabs(File, iTabs, "DuringTime %f\n", fDurationTime);
|
||||
PrintfTabs(File, iTabs, "EnableHitProcess %d\n", isEnableHitProcess);
|
||||
PrintfTabs(File, iTabs, "\n");
|
||||
|
||||
NRaceData::SaveAttackData(File, iTabs, AttackData);
|
||||
NRaceData::SaveCollisionData(File, iTabs, CollisionData);
|
||||
}
|
||||
bool Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenFloat("duringtime", &fDurationTime))
|
||||
return false;
|
||||
|
||||
if (!rTextFileLoader.GetTokenBoolean("enablehitprocess", &isEnableHitProcess))
|
||||
{
|
||||
isEnableHitProcess = TRUE;
|
||||
}
|
||||
|
||||
if (!NRaceData::LoadAttackData(rTextFileLoader, &AttackData))
|
||||
return false;
|
||||
|
||||
if (!NRaceData::LoadCollisionData(rTextFileLoader, &CollisionData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
} TMotionEventDataAttacking;
|
||||
|
||||
// Sound
|
||||
typedef struct SMotionEventDataSound : public SMotionEventData
|
||||
{
|
||||
std::string strSoundFileName; // Direct Sound Node
|
||||
|
||||
SMotionEventDataSound() {}
|
||||
virtual ~SMotionEventDataSound() {}
|
||||
|
||||
void Save(FILE * File, int iTabs)
|
||||
{
|
||||
PrintfTabs(File, iTabs, "\n");
|
||||
PrintfTabs(File, iTabs, "SoundFileName \"%s\"\n", strSoundFileName.c_str());
|
||||
}
|
||||
bool Load(CTextFileLoader & rTextFileLoader)
|
||||
{
|
||||
if (!rTextFileLoader.GetTokenString("soundfilename", &strSoundFileName))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
} TMotionEventDataSound;
|
||||
|
||||
// Character Show
|
||||
typedef struct SMotionEventDataCharacterShow : public SMotionEventData
|
||||
{
|
||||
SMotionEventDataCharacterShow() {}
|
||||
virtual ~SMotionEventDataCharacterShow() {}
|
||||
|
||||
void Save(FILE * File, int iTabs) {}
|
||||
void Load() {}
|
||||
} TMotionEventDataCharacterShow;
|
||||
|
||||
// Character Hide
|
||||
typedef struct SMotionEventDataCharacterHide : public SMotionEventData
|
||||
{
|
||||
SMotionEventDataCharacterHide() {}
|
||||
virtual ~SMotionEventDataCharacterHide() {}
|
||||
|
||||
void Save(FILE * File, int iTabs) {}
|
||||
void Load() {}
|
||||
} TMotionEventDataCharacterHide;
|
||||
|
||||
// Warp
|
||||
typedef struct SMotionEventDataWarp : public SMotionEventData
|
||||
{
|
||||
SMotionEventDataWarp() {}
|
||||
virtual ~SMotionEventDataWarp() {}
|
||||
|
||||
void Save(FILE * File, int iTabs) {}
|
||||
void Load() {}
|
||||
} TMotionWarpEventData;
|
||||
};
|
||||
@@ -0,0 +1,353 @@
|
||||
#include "StdAfx.h"
|
||||
#include "SnowEnvironment.h"
|
||||
|
||||
#include "../EterLib/StateManager.h"
|
||||
#include "../EterLib/Camera.h"
|
||||
#include "../EterLib/ResourceManager.h"
|
||||
#include "SnowParticle.h"
|
||||
|
||||
void CSnowEnvironment::Enable()
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
m_bSnowEnable = TRUE;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Disable()
|
||||
{
|
||||
m_bSnowEnable = FALSE;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Update(const D3DXVECTOR3 & c_rv3Pos)
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
if (m_kVct_pkParticleSnow.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
m_v3Center=c_rv3Pos;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Deform()
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
if (m_kVct_pkParticleSnow.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
const D3DXVECTOR3 & c_rv3Pos=m_v3Center;
|
||||
|
||||
static long s_lLastTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
long lcurTime = CTimer::Instance().GetCurrentMillisecond();
|
||||
float fElapsedTime = float(lcurTime - s_lLastTime) / 1000.0f;
|
||||
s_lLastTime = lcurTime;
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
const D3DXVECTOR3 & c_rv3View = pCamera->GetView();
|
||||
|
||||
D3DXVECTOR3 v3ChangedPos = c_rv3View * 3500.0f + c_rv3Pos;
|
||||
v3ChangedPos.z = c_rv3Pos.z;
|
||||
|
||||
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
|
||||
for (; itor != m_kVct_pkParticleSnow.end();)
|
||||
{
|
||||
CSnowParticle * pSnow = *itor;
|
||||
pSnow->Update(fElapsedTime, v3ChangedPos);
|
||||
|
||||
if (!pSnow->IsActivate())
|
||||
{
|
||||
CSnowParticle::Delete(pSnow);
|
||||
|
||||
itor = m_kVct_pkParticleSnow.erase(itor);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itor;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bSnowEnable)
|
||||
{
|
||||
for (int p = 0; p < min(10, m_dwParticleMaxNum - m_kVct_pkParticleSnow.size()); ++p)
|
||||
{
|
||||
CSnowParticle * pSnowParticle = CSnowParticle::New();
|
||||
pSnowParticle->Init(v3ChangedPos);
|
||||
m_kVct_pkParticleSnow.push_back(pSnowParticle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSnowEnvironment::__BeginBlur()
|
||||
{
|
||||
if (!m_bBlurEnable)
|
||||
return;
|
||||
|
||||
ms_lpd3dDevice->GetRenderTarget(&m_lpOldSurface);
|
||||
ms_lpd3dDevice->GetDepthStencilSurface(&m_lpOldDepthStencilSurface);
|
||||
ms_lpd3dDevice->SetRenderTarget(m_lpSnowRenderTargetSurface, m_lpSnowDepthSurface);
|
||||
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L);
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
|
||||
}
|
||||
|
||||
void CSnowEnvironment::__ApplyBlur()
|
||||
{
|
||||
if (!m_bBlurEnable)
|
||||
return;
|
||||
|
||||
// {
|
||||
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
||||
// STATEMANAGER.SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
// STATEMANAGER.SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
// STATEMANAGER.SetRenderState( D3DRS_COLORVERTEX ,TRUE);
|
||||
// STATEMANAGER.SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE , D3DMCS_COLOR1 );
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
// DWORD alphaColor = 0xFFFFFF | ((DWORD)(0.6f*255.0f) << 24);
|
||||
//
|
||||
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, alphaColor, 0,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, alphaColor, 1,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, alphaColor, 0,1) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, alphaColor, 1,1) };
|
||||
// //누적 블러 텍스쳐를 찍는다.
|
||||
// STATEMANAGER.SetTexture(0,m_lpAccumTexture);
|
||||
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
||||
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// STATEMANAGER.SetRenderTarget(m_lpAccumRenderTargetSurface, m_lpAccumDepthSurface);
|
||||
//
|
||||
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, 0xFFFFFF, 0,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, 0xFFFFFF, 1,0) ,
|
||||
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, 0xFFFFFF, 0,1) ,
|
||||
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, 0xFFFFFF, 1,1) };
|
||||
//
|
||||
// STATEMANAGER.SetTexture(0,m_lpSnowTexture);
|
||||
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
|
||||
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
||||
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
||||
// }
|
||||
|
||||
///////////////
|
||||
{
|
||||
ms_lpd3dDevice->SetRenderTarget(m_lpOldSurface, m_lpOldDepthStencilSurface);
|
||||
|
||||
STATEMANAGER.SetTexture(0,m_lpSnowTexture);
|
||||
STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
|
||||
D3DSURFACE_DESC desc;
|
||||
m_lpOldSurface->GetDesc(&desc);
|
||||
float sx = (float)desc.Width ;
|
||||
float sy = (float)desc.Height;
|
||||
SAFE_RELEASE( m_lpOldSurface );
|
||||
SAFE_RELEASE( m_lpOldDepthStencilSurface );
|
||||
|
||||
BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f ,0xFFFFFF, 0,0) ,
|
||||
BlurVertex(D3DXVECTOR3(sx,0.0f,0.0f),1.0f ,0xFFFFFF, 1,0) ,
|
||||
BlurVertex(D3DXVECTOR3(0.0f,sy,0.0f),1.0f ,0xFFFFFF, 0,1) ,
|
||||
BlurVertex(D3DXVECTOR3(sx,sy,0.0f),1.0f ,0xFFFFFF, 1,1) };
|
||||
|
||||
STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
||||
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
||||
}
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Render()
|
||||
{
|
||||
if (!m_bSnowEnable)
|
||||
{
|
||||
if (m_kVct_pkParticleSnow.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
__BeginBlur();
|
||||
|
||||
DWORD dwParticleCount = min(m_dwParticleMaxNum, m_kVct_pkParticleSnow.size());
|
||||
|
||||
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
||||
if (!pCamera)
|
||||
return;
|
||||
|
||||
const D3DXVECTOR3 & c_rv3Up = pCamera->GetUp();
|
||||
const D3DXVECTOR3 & c_rv3Cross = pCamera->GetCross();
|
||||
|
||||
SParticleVertex * pv3Verticies;
|
||||
if (SUCCEEDED(m_pVB->Lock(0, sizeof(SParticleVertex)*dwParticleCount*4, (BYTE **) &pv3Verticies, D3DLOCK_DISCARD)))
|
||||
{
|
||||
int i = 0;
|
||||
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
|
||||
for (; i < dwParticleCount && itor != m_kVct_pkParticleSnow.end(); ++i, ++itor)
|
||||
{
|
||||
CSnowParticle * pSnow = *itor;
|
||||
pSnow->SetCameraVertex(c_rv3Up, c_rv3Cross);
|
||||
pSnow->GetVerticies(pv3Verticies[i*4+0],
|
||||
pv3Verticies[i*4+1],
|
||||
pv3Verticies[i*4+2],
|
||||
pv3Verticies[i*4+3]);
|
||||
}
|
||||
m_pVB->Unlock();
|
||||
}
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
m_pImageInstance->GetGraphicImagePointer()->GetTextureReference().SetTextureStage(0);
|
||||
STATEMANAGER.SetIndices(m_pIB, 0);
|
||||
STATEMANAGER.SetStreamSource(0, m_pVB, sizeof(SParticleVertex));
|
||||
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
|
||||
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, dwParticleCount*4, 0, dwParticleCount*2);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
|
||||
__ApplyBlur();
|
||||
}
|
||||
|
||||
bool CSnowEnvironment::__CreateBlurTexture()
|
||||
{
|
||||
if (!m_bBlurEnable)
|
||||
return true;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpSnowTexture)))
|
||||
return false;
|
||||
if (FAILED(m_lpSnowTexture->GetSurfaceLevel(0, &m_lpSnowRenderTargetSurface)))
|
||||
return false;
|
||||
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpSnowDepthSurface)))
|
||||
return false;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpAccumTexture)))
|
||||
return false;
|
||||
if (FAILED(m_lpAccumTexture->GetSurfaceLevel(0, &m_lpAccumRenderTargetSurface)))
|
||||
return false;
|
||||
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpAccumDepthSurface)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSnowEnvironment::__CreateGeometry()
|
||||
{
|
||||
if (FAILED(ms_lpd3dDevice->CreateVertexBuffer(sizeof(SParticleVertex)*m_dwParticleMaxNum*4,
|
||||
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
|
||||
D3DFVF_XYZ | D3DFVF_TEX1,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
&m_pVB)))
|
||||
return false;
|
||||
|
||||
if (FAILED(ms_lpd3dDevice->CreateIndexBuffer(sizeof(WORD)*m_dwParticleMaxNum*6,
|
||||
D3DUSAGE_WRITEONLY,
|
||||
D3DFMT_INDEX16,
|
||||
D3DPOOL_MANAGED,
|
||||
&m_pIB)))
|
||||
return false;
|
||||
|
||||
WORD* dstIndices;
|
||||
if (FAILED(m_pIB->Lock(0, sizeof(WORD)*m_dwParticleMaxNum*6, (BYTE**)&dstIndices, 0)))
|
||||
return false;
|
||||
|
||||
const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
|
||||
for (int i = 0; i < m_dwParticleMaxNum; ++i)
|
||||
{
|
||||
for (int j = 0; j < 6; ++j)
|
||||
{
|
||||
dstIndices[i*6 + j] = i*4 + c_awFillRectIndices[j];
|
||||
}
|
||||
}
|
||||
|
||||
m_pIB->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSnowEnvironment::Create()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (!__CreateBlurTexture())
|
||||
return false;
|
||||
|
||||
if (!__CreateGeometry())
|
||||
return false;
|
||||
|
||||
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/snow.dds");
|
||||
m_pImageInstance = CGraphicImageInstance::New();
|
||||
m_pImageInstance->SetImagePointer(pImage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSnowEnvironment::Destroy()
|
||||
{
|
||||
SAFE_RELEASE(m_lpSnowTexture);
|
||||
SAFE_RELEASE(m_lpSnowRenderTargetSurface);
|
||||
SAFE_RELEASE(m_lpSnowDepthSurface);
|
||||
SAFE_RELEASE(m_lpAccumTexture);
|
||||
SAFE_RELEASE(m_lpAccumRenderTargetSurface);
|
||||
SAFE_RELEASE(m_lpAccumDepthSurface);
|
||||
SAFE_RELEASE(m_pVB);
|
||||
SAFE_RELEASE(m_pIB);
|
||||
|
||||
stl_wipe(m_kVct_pkParticleSnow);
|
||||
CSnowParticle::DestroyPool();
|
||||
|
||||
if (m_pImageInstance)
|
||||
{
|
||||
CGraphicImageInstance::Delete(m_pImageInstance);
|
||||
m_pImageInstance = NULL;
|
||||
}
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CSnowEnvironment::__Initialize()
|
||||
{
|
||||
m_bSnowEnable = FALSE;
|
||||
m_lpSnowTexture = NULL;
|
||||
m_lpSnowRenderTargetSurface = NULL;
|
||||
m_lpSnowDepthSurface = NULL;
|
||||
m_lpAccumTexture = NULL;
|
||||
m_lpAccumRenderTargetSurface = NULL;
|
||||
m_lpAccumDepthSurface = NULL;
|
||||
m_pVB = NULL;
|
||||
m_pIB = NULL;
|
||||
m_pImageInstance = NULL;
|
||||
|
||||
m_kVct_pkParticleSnow.reserve(m_dwParticleMaxNum);
|
||||
}
|
||||
|
||||
CSnowEnvironment::CSnowEnvironment()
|
||||
{
|
||||
m_bBlurEnable = FALSE;
|
||||
m_dwParticleMaxNum = 3000;
|
||||
m_wBlurTextureSize = 512;
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
CSnowEnvironment::~CSnowEnvironment()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "../EterLib/GrpScreen.h"
|
||||
|
||||
class CSnowParticle;
|
||||
|
||||
class CSnowEnvironment : public CScreen
|
||||
{
|
||||
public:
|
||||
CSnowEnvironment();
|
||||
virtual ~CSnowEnvironment();
|
||||
|
||||
bool Create();
|
||||
void Destroy();
|
||||
|
||||
void Enable();
|
||||
void Disable();
|
||||
|
||||
void Update(const D3DXVECTOR3 & c_rv3Pos);
|
||||
void Deform();
|
||||
void Render();
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
bool __CreateBlurTexture();
|
||||
bool __CreateGeometry();
|
||||
void __BeginBlur();
|
||||
void __ApplyBlur();
|
||||
|
||||
protected:
|
||||
LPDIRECT3DSURFACE8 m_lpOldSurface;
|
||||
LPDIRECT3DSURFACE8 m_lpOldDepthStencilSurface;
|
||||
|
||||
LPDIRECT3DTEXTURE8 m_lpSnowTexture;
|
||||
LPDIRECT3DSURFACE8 m_lpSnowRenderTargetSurface;
|
||||
LPDIRECT3DSURFACE8 m_lpSnowDepthSurface;
|
||||
|
||||
LPDIRECT3DTEXTURE8 m_lpAccumTexture;
|
||||
LPDIRECT3DSURFACE8 m_lpAccumRenderTargetSurface;
|
||||
LPDIRECT3DSURFACE8 m_lpAccumDepthSurface;
|
||||
|
||||
LPDIRECT3DVERTEXBUFFER8 m_pVB;
|
||||
LPDIRECT3DINDEXBUFFER8 m_pIB;
|
||||
|
||||
D3DXVECTOR3 m_v3Center;
|
||||
|
||||
WORD m_wBlurTextureSize;
|
||||
CGraphicImageInstance * m_pImageInstance;
|
||||
std::vector<CSnowParticle*> m_kVct_pkParticleSnow;
|
||||
|
||||
DWORD m_dwParticleMaxNum;
|
||||
BOOL m_bBlurEnable;
|
||||
|
||||
BOOL m_bSnowEnable;
|
||||
};
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "StdAfx.h"
|
||||
#include "SnowParticle.h"
|
||||
|
||||
const float c_fSnowDistance = 70000.0f;
|
||||
|
||||
std::vector<CSnowParticle*> CSnowParticle::ms_kVct_SnowParticlePool;
|
||||
|
||||
void CSnowParticle::SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross)
|
||||
{
|
||||
m_v3Up = rv3Up*m_fHalfWidth;
|
||||
m_v3Cross = rv3Cross*m_fHalfHeight;
|
||||
}
|
||||
|
||||
bool CSnowParticle::IsActivate()
|
||||
{
|
||||
return m_bActivate;
|
||||
}
|
||||
|
||||
void CSnowParticle::Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos)
|
||||
{
|
||||
m_v3Position += m_v3Velocity * fElapsedTime;
|
||||
|
||||
m_v3Position.x += m_v3Cross.x * sin(m_fcurRadian) / 10.0f;
|
||||
m_v3Position.y += m_v3Cross.y * sin(m_fcurRadian) / 10.0f;
|
||||
m_fcurRadian += m_fPeriod * fElapsedTime;
|
||||
|
||||
if (m_v3Position.z < c_rv3Pos.z - 500.0f)
|
||||
m_bActivate = false;
|
||||
else if (abs(m_v3Position.x - c_rv3Pos.x) > c_fSnowDistance)
|
||||
m_bActivate = false;
|
||||
else if (abs(m_v3Position.y - c_rv3Pos.y) > c_fSnowDistance)
|
||||
m_bActivate = false;
|
||||
}
|
||||
|
||||
void CSnowParticle::GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2,
|
||||
SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4)
|
||||
{
|
||||
rv3Vertex1.v3Pos = m_v3Position - m_v3Cross - m_v3Up;
|
||||
rv3Vertex1.u = 0.0f;
|
||||
rv3Vertex1.v = 0.0f;
|
||||
|
||||
rv3Vertex2.v3Pos = m_v3Position + m_v3Cross - m_v3Up;
|
||||
rv3Vertex2.u = 1.0f;
|
||||
rv3Vertex2.v = 0.0f;
|
||||
|
||||
rv3Vertex3.v3Pos = m_v3Position - m_v3Cross + m_v3Up;
|
||||
rv3Vertex3.u = 0.0f;
|
||||
rv3Vertex3.v = 1.0f;
|
||||
|
||||
rv3Vertex4.v3Pos = m_v3Position + m_v3Cross + m_v3Up;
|
||||
rv3Vertex4.u = 1.0f;
|
||||
rv3Vertex4.v = 1.0f;
|
||||
}
|
||||
|
||||
void CSnowParticle::Init(const D3DXVECTOR3 & c_rv3Pos)
|
||||
{
|
||||
float fRot = frandom(0.0f, 36000.0f) / 100.0f;
|
||||
float fDistance = frandom(0.0f, c_fSnowDistance) / 10.0f;
|
||||
|
||||
m_v3Position.x = c_rv3Pos.x + fDistance*sin((double)D3DXToRadian(fRot));
|
||||
m_v3Position.y = c_rv3Pos.y + fDistance*cos((double)D3DXToRadian(fRot));
|
||||
m_v3Position.z = c_rv3Pos.z + frandom(1500.0f, 2000.0f);
|
||||
m_v3Velocity.x = 0.0f;
|
||||
m_v3Velocity.y = 0.0f;
|
||||
m_v3Velocity.z = frandom(-50.0f, -200.0f);
|
||||
m_fHalfWidth = frandom(2.0f, 7.0f);
|
||||
m_fHalfHeight = m_fHalfWidth;
|
||||
m_bActivate = true;
|
||||
m_bChangedSize = false;
|
||||
|
||||
m_fPeriod = frandom(1.5f, 5.0f);
|
||||
m_fcurRadian = frandom(-1.6f, 1.6f);
|
||||
m_fAmplitude = frandom(1.0f, 3.0f);
|
||||
}
|
||||
|
||||
CSnowParticle * CSnowParticle::New()
|
||||
{
|
||||
if (ms_kVct_SnowParticlePool.empty())
|
||||
{
|
||||
return new CSnowParticle;
|
||||
}
|
||||
|
||||
CSnowParticle * pParticle = ms_kVct_SnowParticlePool.back();
|
||||
ms_kVct_SnowParticlePool.pop_back();
|
||||
return pParticle;
|
||||
}
|
||||
|
||||
void CSnowParticle::Delete(CSnowParticle * pSnowParticle)
|
||||
{
|
||||
ms_kVct_SnowParticlePool.push_back(pSnowParticle);
|
||||
}
|
||||
|
||||
void CSnowParticle::DestroyPool()
|
||||
{
|
||||
stl_wipe(ms_kVct_SnowParticlePool);
|
||||
}
|
||||
|
||||
CSnowParticle::CSnowParticle()
|
||||
{
|
||||
}
|
||||
CSnowParticle::~CSnowParticle()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
struct SParticleVertex
|
||||
{
|
||||
D3DXVECTOR3 v3Pos;
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct BlurVertex
|
||||
{
|
||||
D3DXVECTOR3 pos;
|
||||
FLOAT rhw;
|
||||
DWORD color;
|
||||
FLOAT tu, tv;
|
||||
|
||||
static const DWORD FVF;
|
||||
|
||||
BlurVertex(D3DXVECTOR3 p, float w,DWORD c,float u,float v):pos(p),rhw(w),color(c),tu(u),tv(v) {}
|
||||
~BlurVertex(){};
|
||||
};
|
||||
|
||||
class CSnowParticle
|
||||
{
|
||||
public:
|
||||
CSnowParticle();
|
||||
~CSnowParticle();
|
||||
|
||||
static CSnowParticle * New();
|
||||
static void Delete(CSnowParticle * pSnowParticle);
|
||||
static void DestroyPool();
|
||||
|
||||
void Init(const D3DXVECTOR3 & c_rv3Pos);
|
||||
|
||||
void SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross);
|
||||
bool IsActivate();
|
||||
|
||||
void Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos);
|
||||
void GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2,
|
||||
SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4);
|
||||
|
||||
protected:
|
||||
bool m_bActivate;
|
||||
bool m_bChangedSize;
|
||||
float m_fHalfWidth;
|
||||
float m_fHalfHeight;
|
||||
|
||||
D3DXVECTOR3 m_v3Velocity;
|
||||
D3DXVECTOR3 m_v3Position;
|
||||
|
||||
D3DXVECTOR3 m_v3Up;
|
||||
D3DXVECTOR3 m_v3Cross;
|
||||
|
||||
float m_fPeriod;
|
||||
float m_fcurRadian;
|
||||
float m_fAmplitude;
|
||||
|
||||
public:
|
||||
static std::vector<CSnowParticle*> ms_kVct_SnowParticlePool;
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// gamelib.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef __INC_YMIR_GAMELIB__
|
||||
#define __INC_YMIR_GAMELIB__
|
||||
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#pragma warning(disable:4710) // not inlined
|
||||
#pragma warning(disable:4786) // character 255 ³Ñ¾î°¡´Â°Å ²ô±â
|
||||
#pragma warning(disable:4244) // type conversion possible lose of data
|
||||
|
||||
#pragma warning(disable:4018)
|
||||
#pragma warning(disable:4245)
|
||||
#pragma warning(disable:4512)
|
||||
#pragma warning(disable:4201)
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
#pragma warning(disable:4201 4512 4238 4239)
|
||||
#endif
|
||||
|
||||
#include "../eterBase/Utils.h"
|
||||
#include "../eterBase/CRC32.h"
|
||||
#include "../eterBase/Random.h"
|
||||
|
||||
#include "../eterLib/StdAfx.h"
|
||||
#include "../milesLib/StdAfx.h"
|
||||
#include "../effectLib/StdAfx.h"
|
||||
|
||||
#include "GameType.h"
|
||||
#include "GameUtil.h"
|
||||
#include "MapType.h"
|
||||
#include "MapUtil.h"
|
||||
#include "Interface.h"
|
||||
|
||||
//#include "FlyingObjectManager.h"
|
||||
//#include "FlyingData.h"
|
||||
//#include "FlyingInstance.h"
|
||||
|
||||
|
||||
// Octree
|
||||
//#include "Octree.h"
|
||||
|
||||
// Item
|
||||
//#include "ItemData.h"
|
||||
//#include "ItemManager.h"
|
||||
|
||||
// Actor
|
||||
//#include "WeaponTrace.h"
|
||||
//#include "PhysicsObject.h"
|
||||
//#include "RaceMotionData.h"
|
||||
//#include "RaceData.h"
|
||||
//#include "ActorInstance.h"
|
||||
//#include "RaceManager.h"
|
||||
|
||||
// Property
|
||||
//#include "Property.h"
|
||||
//#include "PropertyManager.h"
|
||||
//#include "PropertyLoader.h"
|
||||
|
||||
// Map
|
||||
//#include "Area.h"
|
||||
|
||||
// Path Finder
|
||||
//#include "PathFinder.h"
|
||||
|
||||
// Game Event Manager
|
||||
//#include "GameEventManager.h"
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,180 @@
|
||||
// TerrainDecal.cpp: implementation of the CTerrainDecal class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "../eterLib/StateManager.h"
|
||||
#include "../PRTerrainLib/StdAfx.h"
|
||||
|
||||
#include "TerrainDecal.h"
|
||||
#include "MapOutdoor.h"
|
||||
#include "AreaTerrain.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CTerrainDecal::CTerrainDecal(CMapOutdoor * pMapOutdoor):m_pMapOutdoor(pMapOutdoor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CTerrainDecal::~CTerrainDecal()
|
||||
{
|
||||
CDecal::Clear();
|
||||
}
|
||||
|
||||
void CTerrainDecal::Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth)
|
||||
{
|
||||
Clear();
|
||||
m_v3Center = v3Center;
|
||||
m_v3Normal = v3Normal;
|
||||
|
||||
D3DXVECTOR3 v3Binormal;
|
||||
D3DXVec3Normalize(&v3Normal, &v3Normal);
|
||||
D3DXVec3Normalize(&v3Tangent, &v3Tangent);
|
||||
D3DXVec3Cross(&v3Binormal, &m_v3Normal, &v3Tangent);
|
||||
D3DXVec3Normalize(&v3Binormal, &v3Binormal);
|
||||
|
||||
// Calculate boundary planes
|
||||
float fd = D3DXVec3Dot(&m_v3Center, &v3Tangent);
|
||||
m_v4LeftPlane = D3DXPLANE(v3Tangent.x, v3Tangent.y, v3Tangent.z, fWidth * 0.5f - fd);
|
||||
m_v4RightPlane = D3DXPLANE(-v3Tangent.x, -v3Tangent.y, -v3Tangent.z, fWidth * 0.5f + fd);
|
||||
|
||||
fd = D3DXVec3Dot(&m_v3Center, &v3Binormal);
|
||||
m_v4BottomPlane = D3DXPLANE(v3Binormal.x, v3Binormal.y, v3Binormal.z, fHeight * 0.5f - fd);
|
||||
m_v4TopPlane = D3DXPLANE(-v3Binormal.x, -v3Binormal.y, -v3Binormal.z, fHeight * 0.5f + fd);
|
||||
|
||||
fd = D3DXVec3Dot(&m_v3Center, &m_v3Normal);
|
||||
m_v4FrontPlane = D3DXPLANE(-m_v3Normal.x, -m_v3Normal.y, -m_v3Normal.z, fDepth + fd);
|
||||
m_v4BackPlane = D3DXPLANE(m_v3Normal.x, m_v3Normal.y, m_v3Normal.z, fDepth - fd);
|
||||
|
||||
// Begin with empty mesh
|
||||
m_dwVertexCount = 0;
|
||||
m_dwPrimitiveCount = 0;
|
||||
|
||||
// Add this point, determine which surfaces may be affected by this decal and call ClipMesh().
|
||||
|
||||
float fSearchRadius = fMAX(fWidth, fHeight);// 0.75f >= sqrtf(2)/2;
|
||||
float fMinX = v3Center.x - fSearchRadius;
|
||||
float fMaxX = v3Center.x + fSearchRadius;
|
||||
float fMinY = fabs(v3Center.y) - fSearchRadius;
|
||||
float fMaxY = fabs(v3Center.y) + fSearchRadius;
|
||||
|
||||
DWORD dwAffectedPrimitiveCount = 0;
|
||||
D3DXVECTOR3 v3AffectedVertex[MAX_SEARCH_VERTICES];
|
||||
D3DXVECTOR3 v3AffectedNormal[MAX_SEARCH_VERTICES];
|
||||
memset(v3AffectedVertex, 0, sizeof(v3AffectedVertex));
|
||||
memset(v3AffectedNormal, 0, sizeof(v3AffectedNormal));
|
||||
|
||||
SearchAffectedTerrainMesh(fMinX, fMaxX, fMinY, fMaxY, &dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal);
|
||||
|
||||
ClipMesh(dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal);
|
||||
|
||||
// Assign texture mapping coordinates
|
||||
float fOne_over_w = 1.0f / fWidth;
|
||||
float fOne_over_h = 1.0f / fHeight;
|
||||
for (DWORD dwi = 0; dwi < m_dwVertexCount; ++dwi)
|
||||
{
|
||||
D3DXVECTOR3 v3 = m_Vertices[dwi].position - m_v3Center;
|
||||
float fu = -D3DXVec3Dot(&v3, &v3Binormal) * fOne_over_w + 0.5f;
|
||||
float fv = -D3DXVec3Dot(&v3, &v3Tangent) * fOne_over_h + 0.5f;
|
||||
m_Vertices[dwi].texCoord = D3DXVECTOR2(fu, fv);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void CTerrainDecal::Update()
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
void CTerrainDecal::Render()
|
||||
{
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
CDecal::Render();
|
||||
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
|
||||
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
}
|
||||
|
||||
void CTerrainDecal::SearchAffectedTerrainMesh(float fMinX,
|
||||
float fMaxX,
|
||||
float fMinY,
|
||||
float fMaxY,
|
||||
DWORD * pdwAffectedPrimitiveCount,
|
||||
D3DXVECTOR3 * pv3AffectedVertex,
|
||||
D3DXVECTOR3 * pv3AffectedNormal)
|
||||
{
|
||||
if (!m_pMapOutdoor)
|
||||
return;
|
||||
int iMinX, iMaxX, iMinY, iMaxY;
|
||||
PR_FLOAT_TO_INT(fMinX, iMinX);
|
||||
PR_FLOAT_TO_INT(fMaxX, iMaxX);
|
||||
PR_FLOAT_TO_INT(fMinY, iMinY);
|
||||
PR_FLOAT_TO_INT(fMaxY, iMaxY);
|
||||
|
||||
iMinX -= iMinX % CTerrainImpl::CELLSCALE;
|
||||
iMaxX -= iMaxX % CTerrainImpl::CELLSCALE;
|
||||
iMinY -= iMinY % CTerrainImpl::CELLSCALE;
|
||||
iMaxY -= iMaxY % CTerrainImpl::CELLSCALE;
|
||||
|
||||
for(int iy = iMinY; iy <= iMaxY; iy += CTerrainImpl::CELLSCALE)
|
||||
{
|
||||
if (iy < 0)
|
||||
continue;
|
||||
WORD wTerrainNumY = iy / CTerrainImpl::TERRAIN_YSIZE;
|
||||
for(int ix = iMinX; ix <= iMaxX; ix += CTerrainImpl::CELLSCALE)
|
||||
{
|
||||
if (ix < 0)
|
||||
continue;
|
||||
WORD wTerrainNumX = ix / CTerrainImpl::TERRAIN_YSIZE;
|
||||
|
||||
BYTE byTerrainNum;
|
||||
if (!m_pMapOutdoor->GetTerrainNumFromCoord(wTerrainNumX, wTerrainNumY, &byTerrainNum))
|
||||
continue;
|
||||
CTerrain * pTerrain;
|
||||
if (!m_pMapOutdoor->GetTerrainPointer(byTerrainNum, &pTerrain))
|
||||
continue;
|
||||
|
||||
float fHeightLT = pTerrain->GetHeight(ix, iy) + m_cfDecalEpsilon;
|
||||
float fHeightRT = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy) + m_cfDecalEpsilon;
|
||||
float fHeightLB = pTerrain->GetHeight(ix, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon;
|
||||
float fHeightRB = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon;
|
||||
|
||||
*pdwAffectedPrimitiveCount += 2;
|
||||
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy), fHeightLT);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB);
|
||||
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy - CTerrainImpl::CELLSCALE), fHeightRB);
|
||||
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// TerrainDecal.h: interface for the CTerrainDecal class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_TERRAINDECAL_H__8E387316_FCCF_446F_AB82_82721F7AC08C__INCLUDED_)
|
||||
#define AFX_TERRAINDECAL_H__8E387316_FCCF_446F_AB82_82721F7AC08C__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../eterlib/Decal.h"
|
||||
|
||||
class CMapOutdoor;
|
||||
|
||||
class CTerrainDecal : public CDecal
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_SEARCH_VERTICES = 1024,
|
||||
};
|
||||
|
||||
CTerrainDecal(CMapOutdoor * pMapOutdoor = NULL);
|
||||
virtual ~CTerrainDecal();
|
||||
|
||||
virtual void Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth);
|
||||
// virtual void Update();
|
||||
virtual void Render();
|
||||
|
||||
void SetMapOutdoor(CMapOutdoor * pMapOutdoor) { m_pMapOutdoor = pMapOutdoor; }
|
||||
|
||||
protected:
|
||||
|
||||
void SearchAffectedTerrainMesh(float fMinX,
|
||||
float fMaxX,
|
||||
float fMinY,
|
||||
float fMaxY,
|
||||
DWORD * pdwAffectedPrimitiveCount,
|
||||
D3DXVECTOR3 * pv3AffectedVertex,
|
||||
D3DXVECTOR3 * pv3AffectedNormal);
|
||||
|
||||
CMapOutdoor * m_pMapOutdoor;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_TERRAINDECAL_H__8E387316_FCCF_446F_AB82_82721F7AC08C__INCLUDED_)
|
||||
@@ -0,0 +1,240 @@
|
||||
// TerrainPatch.cpp: implementation of the CTerrainPatch class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "TerrainPatch.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CTerrainPatch::SSoftwareTransformPatch::SSoftwareTransformPatch()
|
||||
{
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
CTerrainPatch::SSoftwareTransformPatch::~SSoftwareTransformPatch()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CTerrainPatch::SSoftwareTransformPatch::Create()
|
||||
{
|
||||
assert(NULL==m_akTerrainVertex);
|
||||
m_akTerrainVertex=new SoftwareTransformPatch_SSourceVertex[TERRAIN_VERTEX_COUNT];
|
||||
}
|
||||
|
||||
void CTerrainPatch::SSoftwareTransformPatch::Destroy()
|
||||
{
|
||||
if (m_akTerrainVertex)
|
||||
delete [] m_akTerrainVertex;
|
||||
|
||||
__Initialize();
|
||||
}
|
||||
|
||||
void CTerrainPatch::SSoftwareTransformPatch::__Initialize()
|
||||
{
|
||||
m_akTerrainVertex=NULL;
|
||||
}
|
||||
|
||||
bool CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=TRUE;
|
||||
|
||||
void CTerrainPatch::Clear()
|
||||
{
|
||||
m_kHT.m_kVB.Destroy();
|
||||
m_kST.Destroy();
|
||||
|
||||
m_WaterVertexBuffer.Destroy();
|
||||
ClearID();
|
||||
SetUse(false);
|
||||
|
||||
m_bWaterExist = false;
|
||||
m_bNeedUpdate = true;
|
||||
|
||||
m_dwWaterPriCount = 0;
|
||||
m_byType = PATCH_TYPE_PLAIN;
|
||||
|
||||
m_fMinX = m_fMaxX = m_fMinY = m_fMaxY = m_fMinZ = m_fMaxZ = 0.0f;
|
||||
|
||||
m_dwVersion=0;
|
||||
}
|
||||
|
||||
void CTerrainPatch::BuildWaterVertexBuffer(SWaterVertex* akSrcVertex, UINT uWaterVertexCount)
|
||||
{
|
||||
CGraphicVertexBuffer& rkVB=m_WaterVertexBuffer;
|
||||
|
||||
if (!rkVB.Create(uWaterVertexCount, D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
|
||||
return;
|
||||
|
||||
SWaterVertex* akDstWaterVertex;
|
||||
if (rkVB.Lock((void **) &akDstWaterVertex))
|
||||
{
|
||||
UINT uVBSize=sizeof(SWaterVertex)*uWaterVertexCount;
|
||||
memcpy(akDstWaterVertex, akSrcVertex, uVBSize);
|
||||
m_dwWaterPriCount=uWaterVertexCount/3;
|
||||
|
||||
rkVB.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CTerrainPatch::BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
|
||||
{
|
||||
if (SOFTWARE_TRANSFORM_PATCH_ENABLE)
|
||||
__BuildSoftwareTerrainVertexBuffer(akSrcVertex);
|
||||
else
|
||||
__BuildHardwareTerrainVertexBuffer(akSrcVertex);
|
||||
}
|
||||
|
||||
void CTerrainPatch::__BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
|
||||
{
|
||||
//DWORD dwVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
|
||||
|
||||
m_kST.Create();
|
||||
|
||||
SoftwareTransformPatch_SSourceVertex* akDstVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
for (UINT uIndex=0; uIndex!=TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
*((HardwareTransformPatch_SSourceVertex*)(akDstVertex+uIndex))=*(akSrcVertex+uIndex);
|
||||
akDstVertex[uIndex].dwDiffuse=0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void CTerrainPatch::__BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
|
||||
{
|
||||
|
||||
CGraphicVertexBuffer& rkVB=m_kHT.m_kVB;
|
||||
if (!rkVB.Create(TERRAIN_VERTEX_COUNT, D3DFVF_XYZ | D3DFVF_NORMAL, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
|
||||
return;
|
||||
|
||||
HardwareTransformPatch_SSourceVertex* akDstVertex;
|
||||
if (rkVB.Lock((void **) &akDstVertex))
|
||||
{
|
||||
UINT uVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
|
||||
|
||||
memcpy(akDstVertex, akSrcVertex, uVBSize);
|
||||
rkVB.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CTerrainPatch::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
|
||||
{
|
||||
if (m_dwVersion==dwVersion)
|
||||
return;
|
||||
|
||||
m_dwVersion=dwVersion;
|
||||
|
||||
SoftwareTransformPatch_SSourceVertex* akSrcVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
if (!akSrcVertex)
|
||||
return;
|
||||
|
||||
D3DXVECTOR3 kLightDir=c_rkLight.Direction;
|
||||
|
||||
|
||||
DWORD dwDot;
|
||||
DWORD dwAmbientR=(c_rkMtrl.Ambient.r*c_rkLight.Ambient.r+c_rkMtrl.Emissive.r)*255.0f;
|
||||
DWORD dwAmbientG=(c_rkMtrl.Ambient.g*c_rkLight.Ambient.g+c_rkMtrl.Emissive.g)*255.0f;
|
||||
DWORD dwAmbientB=(c_rkMtrl.Ambient.b*c_rkLight.Ambient.b+c_rkMtrl.Emissive.b)*255.0f;
|
||||
DWORD dwDiffuseR=(c_rkMtrl.Diffuse.r*c_rkLight.Diffuse.r)*255.0f;
|
||||
DWORD dwDiffuseG=(c_rkMtrl.Diffuse.g*c_rkLight.Diffuse.g)*255.0f;
|
||||
DWORD dwDiffuseB=(c_rkMtrl.Diffuse.b*c_rkLight.Diffuse.b)*255.0f;
|
||||
|
||||
if (dwDiffuseR>255-dwAmbientR)
|
||||
dwDiffuseR=255-dwAmbientR;
|
||||
|
||||
if (dwDiffuseG+dwAmbientG>255)
|
||||
dwDiffuseG=255-dwAmbientG;
|
||||
|
||||
if (dwDiffuseB+dwAmbientB>255)
|
||||
dwDiffuseB=255-dwAmbientB;
|
||||
|
||||
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
|
||||
{
|
||||
float fDot=D3DXVec3Dot(&akSrcVertex[uIndex].kNormal, &kLightDir);
|
||||
|
||||
const float N=0xffffff;
|
||||
const int S=24;
|
||||
if (fDot<0.0f)
|
||||
dwDot=(N*-fDot);
|
||||
else
|
||||
dwDot=(N*+fDot);
|
||||
|
||||
akSrcVertex[uIndex].dwDiffuse=(0xff000000)|
|
||||
(((dwDiffuseR*dwDot>>S)+dwAmbientR)<<16)|
|
||||
(((dwDiffuseG*dwDot>>S)+dwAmbientG)<<8)|
|
||||
((dwDiffuseB*dwDot>>S)+dwAmbientB);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UINT CTerrainPatch::GetWaterFaceCount()
|
||||
{
|
||||
return m_dwWaterPriCount;
|
||||
}
|
||||
|
||||
CTerrainPatchProxy::CTerrainPatchProxy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CTerrainPatchProxy::~CTerrainPatchProxy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CTerrainPatchProxy::SetCenterPosition(const D3DXVECTOR3& c_rv3Center)
|
||||
{
|
||||
m_v3Center=c_rv3Center;
|
||||
}
|
||||
|
||||
bool CTerrainPatchProxy::IsIn(const D3DXVECTOR3& c_rv3Target, float fRadius)
|
||||
{
|
||||
float dx=m_v3Center.x-c_rv3Target.x;
|
||||
float dy=m_v3Center.y-c_rv3Target.y;
|
||||
float fDist=dx*dx+dy*dy;
|
||||
float fCheck=fRadius*fRadius;
|
||||
|
||||
if (fDist<fCheck)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CTerrainPatchProxy::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
m_pTerrainPatch->SoftwareTransformPatch_UpdateTerrainLighting(dwVersion, c_rkLight, c_rkMtrl);
|
||||
}
|
||||
|
||||
CGraphicVertexBuffer* CTerrainPatchProxy::HardwareTransformPatch_GetVertexBufferPtr()
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
return m_pTerrainPatch->HardwareTransformPatch_GetVertexBufferPtr();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SoftwareTransformPatch_SSourceVertex* CTerrainPatchProxy::SoftwareTransformPatch_GetTerrainVertexDataPtr()
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
return m_pTerrainPatch->SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UINT CTerrainPatchProxy::GetWaterFaceCount()
|
||||
{
|
||||
if (m_pTerrainPatch)
|
||||
return m_pTerrainPatch->GetWaterFaceCount();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CTerrainPatchProxy::Clear()
|
||||
{
|
||||
m_bUsed = false;
|
||||
m_sPatchNum = 0;
|
||||
m_byTerrainNum = 0xFF;
|
||||
|
||||
m_pTerrainPatch = NULL;
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
// TerrainPatch.h: interface for the CTerrainPatch class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_TERRAINPATCH_H__CDD52438_D542_433C_8748_3A15C910A65E__INCLUDED_)
|
||||
#define AFX_TERRAINPATCH_H__CDD52438_D542_433C_8748_3A15C910A65E__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "../eterlib/GrpVertexBuffer.h"
|
||||
#include "../PRTerrainLib/Terrain.h"
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct HardwareTransformPatch_SSourceVertex
|
||||
{
|
||||
D3DXVECTOR3 kPosition;
|
||||
D3DXVECTOR3 kNormal;
|
||||
};
|
||||
|
||||
struct SoftwareTransformPatch_SSourceVertex
|
||||
{
|
||||
D3DXVECTOR3 kPosition;
|
||||
D3DXVECTOR3 kNormal;
|
||||
DWORD dwDiffuse;
|
||||
};
|
||||
|
||||
struct SWaterVertex
|
||||
{
|
||||
float x, y, z; // position
|
||||
DWORD dwDiffuse;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class CTerrainPatch
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PATCH_TYPE_PLAIN = 0,
|
||||
PATCH_TYPE_HILL,
|
||||
PATCH_TYPE_CLIFF,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TERRAIN_VERTEX_COUNT = (CTerrainImpl::PATCH_XSIZE+1)*(CTerrainImpl::PATCH_YSIZE+1)
|
||||
};
|
||||
|
||||
static bool SOFTWARE_TRANSFORM_PATCH_ENABLE;
|
||||
|
||||
public:
|
||||
CTerrainPatch() { Clear(); }
|
||||
~CTerrainPatch() { Clear(); }
|
||||
|
||||
void Clear();
|
||||
|
||||
void ClearID() { SetID(0xFFFFFFFF); }
|
||||
|
||||
void SetMinX(float fMinX) { m_fMinX = fMinX; }
|
||||
float GetMinX() { return m_fMinX; }
|
||||
|
||||
void SetMaxX(float fMaxX) { m_fMaxX = fMaxX; }
|
||||
float GetMaxX() { return m_fMaxX; }
|
||||
|
||||
void SetMinY(float fMinY) { m_fMinY = fMinY; }
|
||||
float GetMinY() { return m_fMinY; }
|
||||
|
||||
void SetMaxY(float fMaxY) { m_fMaxY = fMaxY; }
|
||||
float GetMaxY() { return m_fMaxY; }
|
||||
|
||||
void SetMinZ(float fMinZ) { m_fMinZ = fMinZ; }
|
||||
float GetMinZ() { return m_fMinZ; }
|
||||
|
||||
void SetMaxZ(float fMaxZ) { m_fMaxZ = fMaxZ; }
|
||||
float GetMaxZ() { return m_fMaxZ; }
|
||||
|
||||
bool IsUse() { return m_bUse; }
|
||||
void SetUse(bool bUse) { m_bUse = bUse; }
|
||||
|
||||
bool IsWaterExist() { return m_bWaterExist; }
|
||||
void SetWaterExist(bool bWaterExist) { m_bWaterExist = bWaterExist; }
|
||||
|
||||
DWORD GetID() { return m_dwID; }
|
||||
void SetID(DWORD dwID) { m_dwID = dwID; }
|
||||
|
||||
void SetType(BYTE byType) { m_byType = byType; }
|
||||
BYTE GetType() { return m_byType; }
|
||||
|
||||
void NeedUpdate(bool bNeedUpdate) { m_bNeedUpdate = bNeedUpdate;}
|
||||
bool NeedUpdate() { return m_bNeedUpdate; }
|
||||
|
||||
UINT GetWaterFaceCount();
|
||||
|
||||
void SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl);
|
||||
|
||||
void BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex);
|
||||
void BuildWaterVertexBuffer(SWaterVertex* akSrcVertex, UINT uWaterVertexCount);
|
||||
|
||||
protected:
|
||||
void __BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex);
|
||||
void __BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex);
|
||||
|
||||
private:
|
||||
float m_fMinX;
|
||||
float m_fMaxX;
|
||||
float m_fMinY;
|
||||
float m_fMaxY;
|
||||
float m_fMinZ;
|
||||
float m_fMaxZ;
|
||||
bool m_bUse;
|
||||
bool m_bWaterExist;
|
||||
DWORD m_dwID;
|
||||
DWORD m_dwWaterPriCount;
|
||||
|
||||
CGraphicVertexBuffer m_WaterVertexBuffer;
|
||||
BYTE m_byType;
|
||||
|
||||
bool m_bNeedUpdate;
|
||||
DWORD m_dwVersion;
|
||||
|
||||
public:
|
||||
CGraphicVertexBuffer* GetWaterVertexBufferPointer() { return &m_WaterVertexBuffer;}
|
||||
|
||||
public:
|
||||
CGraphicVertexBuffer* HardwareTransformPatch_GetVertexBufferPtr() {return &m_kHT.m_kVB;}
|
||||
|
||||
protected:
|
||||
struct SHardwareTransformPatch
|
||||
{
|
||||
CGraphicVertexBuffer m_kVB;
|
||||
} m_kHT;
|
||||
|
||||
|
||||
public:
|
||||
SoftwareTransformPatch_SSourceVertex* SoftwareTransformPatch_GetTerrainVertexDataPtr()
|
||||
{return m_kST.m_akTerrainVertex;}
|
||||
|
||||
protected:
|
||||
struct SSoftwareTransformPatch
|
||||
{
|
||||
SoftwareTransformPatch_SSourceVertex* m_akTerrainVertex;
|
||||
|
||||
SSoftwareTransformPatch();
|
||||
~SSoftwareTransformPatch();
|
||||
|
||||
void Create();
|
||||
void Destroy();
|
||||
|
||||
void __Initialize();
|
||||
} m_kST;
|
||||
|
||||
};
|
||||
|
||||
class CTerrainPatchProxy
|
||||
{
|
||||
public:
|
||||
CTerrainPatchProxy();
|
||||
virtual ~CTerrainPatchProxy();
|
||||
|
||||
void Clear();
|
||||
|
||||
void SetCenterPosition(const D3DXVECTOR3& c_rv3Center);
|
||||
|
||||
bool IsIn(const D3DXVECTOR3& c_rv3Target, float fRadius);
|
||||
|
||||
bool isUsed() { return m_bUsed; }
|
||||
void SetUsed(bool bUsed) { m_bUsed = bUsed; }
|
||||
|
||||
short GetPatchNum() { return m_sPatchNum; }
|
||||
void SetPatchNum(short sPatchNum) { m_sPatchNum = sPatchNum; }
|
||||
|
||||
BYTE GetTerrainNum() { return m_byTerrainNum; }
|
||||
void SetTerrainNum(BYTE byTerrainNum) { m_byTerrainNum = byTerrainNum; }
|
||||
|
||||
void SetTerrainPatch(CTerrainPatch * pTerrainPatch) { m_pTerrainPatch = pTerrainPatch;}
|
||||
|
||||
bool isWaterExists();
|
||||
|
||||
UINT GetWaterFaceCount();
|
||||
|
||||
float GetMinX();
|
||||
float GetMaxX();
|
||||
float GetMinY();
|
||||
float GetMaxY();
|
||||
float GetMinZ();
|
||||
float GetMaxZ();
|
||||
|
||||
// Vertex Buffer
|
||||
CGraphicVertexBuffer * GetWaterVertexBufferPointer();
|
||||
SoftwareTransformPatch_SSourceVertex* SoftwareTransformPatch_GetTerrainVertexDataPtr();
|
||||
CGraphicVertexBuffer* HardwareTransformPatch_GetVertexBufferPtr();
|
||||
|
||||
void SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl);
|
||||
|
||||
protected:
|
||||
bool m_bUsed;
|
||||
short m_sPatchNum; // Patch Number
|
||||
|
||||
BYTE m_byTerrainNum;
|
||||
|
||||
CTerrainPatch * m_pTerrainPatch;
|
||||
|
||||
D3DXVECTOR3 m_v3Center;
|
||||
};
|
||||
|
||||
inline bool CTerrainPatchProxy::isWaterExists()
|
||||
{
|
||||
return m_pTerrainPatch->IsWaterExist();
|
||||
}
|
||||
|
||||
inline float CTerrainPatchProxy::GetMinX()
|
||||
{
|
||||
return m_pTerrainPatch->GetMinX();
|
||||
}
|
||||
|
||||
inline float CTerrainPatchProxy::GetMaxX()
|
||||
{
|
||||
return m_pTerrainPatch->GetMaxX();
|
||||
}
|
||||
|
||||
inline float CTerrainPatchProxy::GetMinY()
|
||||
{
|
||||
return m_pTerrainPatch->GetMinY();
|
||||
}
|
||||
|
||||
inline float CTerrainPatchProxy::GetMaxY()
|
||||
{
|
||||
return m_pTerrainPatch->GetMaxY();
|
||||
}
|
||||
|
||||
inline float CTerrainPatchProxy::GetMinZ()
|
||||
{
|
||||
return m_pTerrainPatch->GetMinZ();
|
||||
}
|
||||
|
||||
inline float CTerrainPatchProxy::GetMaxZ()
|
||||
{
|
||||
return m_pTerrainPatch->GetMaxZ();
|
||||
}
|
||||
|
||||
inline CGraphicVertexBuffer * CTerrainPatchProxy::GetWaterVertexBufferPointer()
|
||||
{
|
||||
return m_pTerrainPatch->GetWaterVertexBufferPointer();
|
||||
}
|
||||
|
||||
#endif // !defined(AFX_TERRAINPATCH_H__CDD52438_D542_433C_8748_3A15C910A65E__INCLUDED_)
|
||||
@@ -0,0 +1,46 @@
|
||||
// TerrainQuadtreeNode.cpp: implementation of the CTerrainQuadtreeNode class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "TerrainQuadtree.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CTerrainQuadtree
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CTerrainQuadtreeNode
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CTerrainQuadtreeNode::CTerrainQuadtreeNode():NW_Node(NULL), NE_Node(NULL), SW_Node(NULL), SE_Node(NULL), center(-1.0f, -1.0f, -1.0f)
|
||||
{
|
||||
x0 = y0 = x1 = y1 = 0;
|
||||
Size = 0;
|
||||
PatchNum = 0;
|
||||
radius = 0.0f;
|
||||
m_byLODLevel = 0;
|
||||
}
|
||||
|
||||
CTerrainQuadtreeNode::~CTerrainQuadtreeNode()
|
||||
{
|
||||
if (NW_Node)
|
||||
{
|
||||
delete NW_Node;
|
||||
NW_Node = NULL;
|
||||
}
|
||||
if (NE_Node)
|
||||
{
|
||||
delete NE_Node;
|
||||
NE_Node = NULL;
|
||||
}
|
||||
if (SW_Node)
|
||||
{
|
||||
delete SW_Node;
|
||||
SW_Node = NULL;
|
||||
}
|
||||
if (SE_Node)
|
||||
{
|
||||
delete SE_Node;
|
||||
SE_Node = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// TerrainQuadtreeNode.h: interface for the CTerrainQuadtreeNode class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_)
|
||||
#define AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CTerrainQuadtreeNode
|
||||
{
|
||||
public:
|
||||
CTerrainQuadtreeNode();
|
||||
virtual ~CTerrainQuadtreeNode();
|
||||
|
||||
public:
|
||||
long x0, y0, x1, y1;
|
||||
CTerrainQuadtreeNode * NW_Node;
|
||||
CTerrainQuadtreeNode * NE_Node;
|
||||
CTerrainQuadtreeNode * SW_Node;
|
||||
CTerrainQuadtreeNode * SE_Node;
|
||||
long Size;
|
||||
long PatchNum;
|
||||
D3DXVECTOR3 center;
|
||||
float radius;
|
||||
BYTE m_byLODLevel;
|
||||
};
|
||||
|
||||
|
||||
#endif // !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_)
|
||||
@@ -0,0 +1,490 @@
|
||||
#include "StdAfx.h"
|
||||
#include "../eterLib/ResourceManager.h"
|
||||
#include "../eterLib/StateManager.h"
|
||||
|
||||
#include "WeaponTrace.h"
|
||||
|
||||
CDynamicPool<CWeaponTrace> CWeaponTrace::ms_kPool;
|
||||
|
||||
void CWeaponTrace::DestroySystem()
|
||||
{
|
||||
ms_kPool.Destroy();
|
||||
}
|
||||
|
||||
void CWeaponTrace::Delete(CWeaponTrace* pkWTDel)
|
||||
{
|
||||
assert(pkWTDel!=NULL && "CWeaponTrace::Delete");
|
||||
|
||||
pkWTDel->Clear();
|
||||
ms_kPool.Free(pkWTDel);
|
||||
}
|
||||
|
||||
CWeaponTrace* CWeaponTrace::New()
|
||||
{
|
||||
return ms_kPool.Alloc();
|
||||
}
|
||||
|
||||
void CWeaponTrace::Update(float fReachScale)
|
||||
{
|
||||
float fElapsedTime = CTimer::Instance().GetCurrentSecond() - m_fLastUpdate;
|
||||
m_fLastUpdate = CTimer::Instance().GetCurrentSecond();
|
||||
|
||||
if (!m_pInstance)
|
||||
return;
|
||||
{
|
||||
// 잔상을 남기는 시간 범위 내의 점들만 유지합니다.
|
||||
TTimePointList::iterator it;
|
||||
for(it=m_ShortTimePointList.begin();it!=m_ShortTimePointList.end();++it)
|
||||
{
|
||||
it->first += fElapsedTime;
|
||||
if (it->first>m_fLifeTime)
|
||||
{
|
||||
it++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it!=m_ShortTimePointList.end())
|
||||
m_ShortTimePointList.erase(it,m_ShortTimePointList.end());
|
||||
for(it=m_LongTimePointList.begin();it!=m_LongTimePointList.end();++it)
|
||||
{
|
||||
it->first += fElapsedTime;
|
||||
if (it->first>m_fLifeTime)
|
||||
{
|
||||
it++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (it!=m_LongTimePointList.end())
|
||||
m_LongTimePointList.erase(it, m_LongTimePointList.end());
|
||||
}
|
||||
|
||||
if (m_isPlaying && m_fz>=0.0001f)
|
||||
{
|
||||
D3DXMATRIX * pMatrix;
|
||||
if (m_pInstance->GetCompositeBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pMatrix))
|
||||
{
|
||||
D3DXMATRIX * pBoneMat;
|
||||
m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, m_iBoneIndex, &pBoneMat);
|
||||
D3DXMATRIX mat = *pMatrix;
|
||||
mat._41 = pBoneMat->_41;
|
||||
mat._42 = pBoneMat->_42;
|
||||
mat._43 = pBoneMat->_43;
|
||||
// 현재 위치를 추가합니다.
|
||||
D3DXMATRIX matPoint;
|
||||
D3DXMATRIX matTranslation;
|
||||
D3DXMATRIX matRotation;
|
||||
|
||||
//D3DXMatrixTranslation(&matTranslation, 0.0f, m_fLength, 0.0f);
|
||||
D3DXMatrixTranslation(&matTranslation, 0.0f, 0.0f, m_fLength*fReachScale);
|
||||
D3DXMatrixRotationZ(&matRotation, D3DXToRadian(m_fRotation));
|
||||
|
||||
|
||||
matPoint = /**pMatrix*/mat * matRotation;
|
||||
/*TPDTVertex PDTVertex;
|
||||
PDTVertex.position.x = m_fx + matPoint._41;
|
||||
PDTVertex.position.y = m_fy + matPoint._42;
|
||||
PDTVertex.position.z = m_fz + matPoint._43;
|
||||
PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f);
|
||||
m_PDTVertexVector.push_back(PDTVertex);*/
|
||||
m_ShortTimePointList.push_front(
|
||||
TTimePoint(
|
||||
0.0f,
|
||||
D3DXVECTOR3(
|
||||
m_fx + matPoint._41,
|
||||
m_fy + matPoint._42,
|
||||
m_fz + matPoint._43
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
matPoint = matTranslation * matPoint;
|
||||
/*PDTVertex.position.x = m_fx + matPoint._41;
|
||||
PDTVertex.position.y = m_fy + matPoint._42;
|
||||
PDTVertex.position.z = m_fz + matPoint._43;
|
||||
PDTVertex.diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.1f);
|
||||
m_PDTVertexVector.push_back(PDTVertex);*/
|
||||
m_LongTimePointList.push_front(
|
||||
TTimePoint(
|
||||
0.0f,
|
||||
D3DXVECTOR3(
|
||||
m_fx + matPoint._41,
|
||||
m_fy + matPoint._42,
|
||||
m_fz + matPoint._43
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//if (!BuildVertex())
|
||||
// return;
|
||||
}
|
||||
|
||||
bool CWeaponTrace::BuildVertex()
|
||||
{
|
||||
const int max_size = 300;
|
||||
// calculate speed
|
||||
float h[max_size];
|
||||
float stk[max_size];
|
||||
int sp=0;
|
||||
D3DXVECTOR3 r[max_size];
|
||||
|
||||
if (m_LongTimePointList.size()<=1)
|
||||
return false;
|
||||
|
||||
|
||||
//Tracef("## %f %f %f\n", m_LongTimePointList[0].second.x, m_LongTimePointList[0].second.y, m_LongTimePointList[0].second.z);
|
||||
|
||||
/*m_LongTimePointList.clear();
|
||||
m_LongTimePointList.push_back(TTimePoint(0.00,D3DXVECTOR3(0,0,0)));
|
||||
m_LongTimePointList.push_back(TTimePoint(0.01,D3DXVECTOR3(0,1,0)));
|
||||
m_LongTimePointList.push_back(TTimePoint(0.04,D3DXVECTOR3(0,1,0)));
|
||||
m_LongTimePointList.push_back(TTimePoint(0.05,D3DXVECTOR3(0,0,0)));
|
||||
m_ShortTimePointList = m_LongTimePointList;
|
||||
|
||||
*/
|
||||
std::vector<TPDTVertex> m_ShortVertexVector, m_LongVertexVector;
|
||||
|
||||
float length = min(m_fLifeTime, m_LongTimePointList.back().first);
|
||||
|
||||
int n = m_LongTimePointList.size()-1;
|
||||
assert(n<max_size-1);
|
||||
|
||||
// cubic spline
|
||||
|
||||
for(int loop = 0; loop<=1; ++loop)
|
||||
{
|
||||
TTimePointList & Input = (loop) ? m_LongTimePointList : m_ShortTimePointList;
|
||||
std::vector<TPDTVertex> & Output = (loop) ? m_LongVertexVector : m_ShortVertexVector;
|
||||
TTimePointList::iterator it;
|
||||
int i;
|
||||
|
||||
for(i=0;i<n;++i)
|
||||
{
|
||||
h[i] = Input[i+1].first - Input[i].first;
|
||||
r[i] = (Input[i+1].second - Input[i].second)*(3/h[i]);
|
||||
}
|
||||
r[n] = D3DXVECTOR3(0.0f,0.0f,0.0f);
|
||||
for(i=n;i>0;i--)
|
||||
{
|
||||
r[i]+=r[i-1];
|
||||
}
|
||||
|
||||
float rate = 0.5f;
|
||||
r[0] *= 0.5f;
|
||||
stk[sp++] = rate;
|
||||
for(i=1;i<n;i++)
|
||||
{
|
||||
r[i]-=r[i-1];
|
||||
rate = 1/(4-rate);
|
||||
r[i] *= rate;
|
||||
stk[sp++]=rate;
|
||||
}
|
||||
r[n]-=r[n-1];
|
||||
rate = 1/(2-rate);
|
||||
r[n]*=rate;
|
||||
|
||||
for(i=n-1;i>=0;i--)
|
||||
{
|
||||
r[i] -= stk[--sp] * r[i+1];
|
||||
}
|
||||
|
||||
int base = 0;
|
||||
D3DXVECTOR3 a,b,c,d;
|
||||
D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second;
|
||||
float timebase=0,timenext=h[base], dt=m_fSamplingTime;
|
||||
a = Input[base].second;
|
||||
b = r[base];
|
||||
c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] )
|
||||
* (1/(h[base]*h[base]));
|
||||
d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base])
|
||||
* (1/(h[base]*h[base]*h[base]));
|
||||
|
||||
for(float t = 0; t<=length; t+=dt)
|
||||
{
|
||||
while (t>timenext)
|
||||
{
|
||||
timebase = timenext;
|
||||
base++;
|
||||
if (base>=n) break;
|
||||
D3DXVECTOR3 v3Tmp = Input[base+1].second-Input[base].second;
|
||||
a = Input[base].second;
|
||||
b = r[base];
|
||||
c = ( 3*v3Tmp - r[base+1]*h[base] - (2*h[base])*r[base] )
|
||||
* (1/(h[base]*h[base]));
|
||||
d = ( -2*v3Tmp + (r[base+1]+r[base])*h[base])
|
||||
* (1/(h[base]*h[base]*h[base]));
|
||||
|
||||
timenext+=h[base];
|
||||
if (loop)
|
||||
{
|
||||
//Tracef("%f:%f %f %f\n",Input[base].first,Input[base].second.x,Input[base].second.y,Input[base].second.z);
|
||||
}
|
||||
}
|
||||
if (base>n) break;
|
||||
float cc = t - timebase;
|
||||
|
||||
TPDTVertex v;
|
||||
//v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?max(1.0f-(t/m_fLifeTime),0.0f)/2:0.0f );
|
||||
float ttt = min(max((t+Input[0].first)/m_fLifeTime,0.0f),1.0f);
|
||||
v.diffuse = D3DXCOLOR(0.3f,0.8f,1.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)/2.5-0.1f,0.0f),1.0f):0.0f );
|
||||
//v.diffuse = D3DXCOLOR(0.0f,0.0f,0.0f, (loop)?min(max((1.0f-ttt)*(1.0f-ttt)-0.1f,0.0f),1.0f):0.0f );
|
||||
//v.diffuse = 0xffffffff;
|
||||
v.position = a+cc*(b+cc*(c+cc*d)); // next position
|
||||
v.texCoord.x = t/m_fLifeTime;
|
||||
v.texCoord.y = loop ? 0 : 1;
|
||||
Output.push_back(v);
|
||||
if (loop)
|
||||
{
|
||||
// Tracef("%f %f %f\n", timebase,t,timenext);
|
||||
//Tracef("a:%f %f %f\nb:%f %f %f \nc:%f %f %f \nd:%f %f %f, \n",,a.x,a.y,a.z,b.x,b.y,b.z,c.x,c.y,c.z,d.x,d.y,d.z);
|
||||
|
||||
//Tracef("%f %f %f\n",v.position.x,v.position.y,v.position.z);
|
||||
/*D3DXMATRIX * pBoneMat;
|
||||
m_pInstance->GetBoneMatrix(m_dwModelInstanceIndex, 55, &pBoneMat);
|
||||
D3DXVECTOR3 vbone(m_fx+pBoneMat->_41,m_fy+pBoneMat->_42,m_fz+pBoneMat->_43);
|
||||
float len = D3DXVec3Length(&(v.position-vbone));*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build vertex
|
||||
|
||||
m_PDTVertexVector.clear();
|
||||
|
||||
/*
|
||||
TTimePointList::iterator lit1,lit2, sit1,sit2;
|
||||
|
||||
lit2 = lit1 = m_LongTimePointList.begin();
|
||||
++lit2;
|
||||
|
||||
sit2 = sit1 = m_ShortTimePointList.begin();
|
||||
++sit2;
|
||||
*/
|
||||
std::vector<TPDTVertex>::iterator lit,sit;
|
||||
for(lit = m_LongVertexVector.begin(), sit = m_ShortVertexVector.begin();
|
||||
lit != m_LongVertexVector.end();
|
||||
++lit,++sit)
|
||||
{
|
||||
m_PDTVertexVector.push_back(*lit);
|
||||
m_PDTVertexVector.push_back(*sit);
|
||||
/*float len = D3DXVec3Length(&(lit->position - sit->position));
|
||||
if (len>160)
|
||||
Tracef("dist:%f\n",len);*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWeaponTrace::Render()
|
||||
{
|
||||
//if (!m_isPlaying)
|
||||
// return;
|
||||
//if (m_CurvingTraceVector.size() < 4)
|
||||
// return;
|
||||
|
||||
if (!BuildVertex())
|
||||
return;
|
||||
|
||||
if (m_PDTVertexVector.size()<4)
|
||||
return;
|
||||
|
||||
|
||||
LPDIRECT3DTEXTURE8 lpTexture=NULL;
|
||||
|
||||
// Have to optimize
|
||||
D3DXMATRIX matWorld;
|
||||
D3DXMatrixIdentity(&matWorld);
|
||||
|
||||
STATEMANAGER.SaveTransform(D3DTS_WORLD, &matWorld);
|
||||
STATEMANAGER.SaveVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAREF, 0x00000011);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
||||
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
|
||||
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
|
||||
//STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, (m_bUseTexture)?D3DTOP_SELECTARG2:D3DTOP_SELECTARG1);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
STATEMANAGER.SetTexture(0, lpTexture);
|
||||
STATEMANAGER.SetTexture(1, NULL);
|
||||
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,
|
||||
int(m_PDTVertexVector.size() - 2),
|
||||
&m_PDTVertexVector[0],
|
||||
sizeof(TPDTVertex));
|
||||
|
||||
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZFUNC);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHATESTENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAREF);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHAFUNC);
|
||||
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
|
||||
|
||||
STATEMANAGER.RestoreTransform(D3DTS_WORLD);
|
||||
STATEMANAGER.RestoreVertexShader();
|
||||
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
||||
}
|
||||
|
||||
void CWeaponTrace::UseAlpha()
|
||||
{
|
||||
m_bUseTexture = false;
|
||||
}
|
||||
|
||||
void CWeaponTrace::UseTexture()
|
||||
{
|
||||
m_bUseTexture = true;
|
||||
}
|
||||
|
||||
void CWeaponTrace::SetTexture(const char * c_szFileName)
|
||||
{
|
||||
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("lot_ade10-2.tga");
|
||||
m_ImageInstance.SetImagePointer(pImage);
|
||||
|
||||
//CGraphicTexture * pTexture = m_ImageInstance.GetTexturePointer();
|
||||
//m_lpTexture = pTexture->GetD3DTexture();
|
||||
}
|
||||
|
||||
bool CWeaponTrace::SetWeaponInstance(CGraphicThingInstance * pInstance, DWORD dwModelIndex, const char * c_szBoneName)
|
||||
{
|
||||
pInstance->Update();
|
||||
pInstance->DeformNoSkin();
|
||||
|
||||
D3DXVECTOR3 v3Min;
|
||||
D3DXVECTOR3 v3Max;
|
||||
if (!pInstance->GetBoundBox(dwModelIndex, &v3Min, &v3Max))
|
||||
return false;
|
||||
|
||||
m_iBoneIndex = 0;
|
||||
m_dwModelInstanceIndex = dwModelIndex;
|
||||
|
||||
m_pInstance = pInstance;
|
||||
D3DXMATRIX * pmat;
|
||||
pInstance->GetBoneMatrix(dwModelIndex, 0, &pmat);
|
||||
D3DXVECTOR3 v3Bone(pmat->_41,pmat->_42,pmat->_43);
|
||||
|
||||
const auto vv1 = (v3Bone - v3Min);
|
||||
const auto vv2 = (v3Bone - v3Max);
|
||||
m_fLength =
|
||||
sqrtf(
|
||||
fMAX(
|
||||
D3DXVec3LengthSq(&vv1),
|
||||
D3DXVec3LengthSq(&vv2)
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWeaponTrace::SetPosition(float fx, float fy, float fz)
|
||||
{
|
||||
m_fx = fx;
|
||||
m_fy = fy;
|
||||
m_fz = fz;
|
||||
}
|
||||
|
||||
void CWeaponTrace::SetRotation(float fRotation)
|
||||
{
|
||||
m_fRotation = fRotation;
|
||||
}
|
||||
|
||||
void CWeaponTrace::SetLifeTime(float fLifeTime)
|
||||
{
|
||||
m_fLifeTime = fLifeTime;
|
||||
}
|
||||
|
||||
void CWeaponTrace::SetSamplingTime(float fSamplingTime)
|
||||
{
|
||||
m_fSamplingTime = fSamplingTime;
|
||||
}
|
||||
|
||||
void CWeaponTrace::TurnOn()
|
||||
{
|
||||
m_isPlaying = TRUE;
|
||||
}
|
||||
void CWeaponTrace::TurnOff()
|
||||
{
|
||||
m_isPlaying = FALSE;
|
||||
//Clear();
|
||||
}
|
||||
|
||||
void CWeaponTrace::Clear()
|
||||
{
|
||||
//m_PDTVertexVector.clear();
|
||||
//m_CurvingTraceVector.clear();
|
||||
|
||||
m_ShortTimePointList.clear();
|
||||
m_LongTimePointList.clear();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void CWeaponTrace::Initialize()
|
||||
{
|
||||
m_pInstance = NULL;
|
||||
m_dwModelInstanceIndex = 0;
|
||||
|
||||
m_fx = 0.0f;
|
||||
m_fy = 0.0f;
|
||||
m_fz = 0.0f;
|
||||
m_fRotation = 0.0f;
|
||||
|
||||
m_fLifeTime = 0.18f;
|
||||
//m_fLifeTime = 3.0f;
|
||||
m_fSamplingTime = 0.003f;
|
||||
//m_fLifeTime = 3.0f;
|
||||
//m_fSamplingTime = 0.003f;
|
||||
|
||||
m_isPlaying = FALSE;
|
||||
|
||||
m_bUseTexture = false;
|
||||
|
||||
m_iBoneIndex = 0;
|
||||
|
||||
m_fLastUpdate = CTimer::Instance().GetCurrentSecond();
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
//const int c_iSplineCount = 8;
|
||||
//m_SplineValueVector.clear();
|
||||
//m_SplineValueVector.resize(c_iSplineCount);
|
||||
|
||||
//for (int i = 0; i < c_iSplineCount; ++i)
|
||||
//{
|
||||
// float fValue = float(i) / float(c_iSplineCount);
|
||||
// m_SplineValueVector[i].fValue1 = fValue;
|
||||
// m_SplineValueVector[i].fValue2 = fValue * fValue;
|
||||
// m_SplineValueVector[i].fValue3 = fValue * fValue * fValue;
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
CWeaponTrace::CWeaponTrace()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
CWeaponTrace::~CWeaponTrace()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
// change CatMull to cubic spline
|
||||
#include "../eterGrnLib/ThingInstance.h"
|
||||
|
||||
class CWeaponTrace
|
||||
{
|
||||
/*
|
||||
public:
|
||||
typedef struct SSplineValue
|
||||
{
|
||||
float fValue1;
|
||||
float fValue2;
|
||||
float fValue3;
|
||||
} TSplineValue;
|
||||
*/
|
||||
public:
|
||||
static void DestroySystem();
|
||||
static void Delete(CWeaponTrace* pkWTDel);
|
||||
static CWeaponTrace* New();
|
||||
|
||||
public:
|
||||
CWeaponTrace();
|
||||
virtual ~CWeaponTrace();
|
||||
|
||||
void Clear();
|
||||
|
||||
void TurnOn();
|
||||
void TurnOff();
|
||||
|
||||
void UseAlpha();
|
||||
void UseTexture();
|
||||
|
||||
void SetTexture(const char * c_szFileName);
|
||||
bool SetWeaponInstance(CGraphicThingInstance * pInstance, DWORD dwModelIndex, const char * c_szBoneName);
|
||||
void SetPosition(float fx, float fy, float fz);
|
||||
void SetRotation(float fRotation);
|
||||
|
||||
void SetLifeTime(float fLifeTime);
|
||||
void SetSamplingTime(float fSamplingTime);
|
||||
|
||||
void Update(float fReachScale);
|
||||
void Render();
|
||||
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
bool BuildVertex();
|
||||
|
||||
protected:
|
||||
|
||||
float m_fLastUpdate;
|
||||
|
||||
typedef std::pair<float, D3DXVECTOR3> TTimePoint;
|
||||
typedef std::deque<TTimePoint> TTimePointList;
|
||||
TTimePointList m_ShortTimePointList;
|
||||
TTimePointList m_LongTimePointList;
|
||||
|
||||
std::vector<TPDTVertex> m_PDTVertexVector;
|
||||
|
||||
float m_fLifeTime;
|
||||
float m_fSamplingTime;
|
||||
|
||||
//std::vector<TPDTVertex> m_PDTVertexVector;
|
||||
//std::vector<TPDTVertex> m_CurvingTraceVector;
|
||||
//std::vector<TSplineValue> m_SplineValueVector;
|
||||
|
||||
CGraphicThingInstance * m_pInstance;
|
||||
DWORD m_dwModelInstanceIndex;
|
||||
|
||||
CGraphicImageInstance m_ImageInstance;
|
||||
|
||||
float m_fx;
|
||||
float m_fy;
|
||||
float m_fz;
|
||||
float m_fRotation;
|
||||
float m_fLength;
|
||||
|
||||
BOOL m_isPlaying;
|
||||
bool m_bUseTexture;
|
||||
|
||||
int m_iBoneIndex;
|
||||
|
||||
protected:
|
||||
static CDynamicPool<CWeaponTrace> ms_kPool;
|
||||
};
|
||||
Reference in New Issue
Block a user