1
0
forked from metin2/client
client/GameLib/ActorInstanceAttach.cpp

607 lines
16 KiB
C++
Raw Normal View History

#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();
//<2F><><EFBFBD>չ<EFBFBD><D5B9><EFBFBD>(<28>ڰ<EFBFBD> <20>̵<EFBFBD><CCB5><EFBFBD>) <20>޼<EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD>.
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 : (<28>̵<EFBFBD><CCB5><EFBFBD>ó<EFBFBD><C3B3>)<29>ܵ<EFBFBD><DCB5><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>°<EFBFBD> <20>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
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.<2E><><EFBFBD><EFBFBD><E2BDBA>ŧ<EFBFBD><C5A7>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SetShape<70><65><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ش<EFBFBD>.)
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 : ù<><C3B9>° <20><><EFBFBD>ڴ<EFBFBD> Part<72><74> <20><>ȣ<EFBFBD><C8A3>.
// Base<73><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<>ΰ<EFBFBD>? - [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::void_mem_fun(&CWeaponTrace::UseTexture)
);
}
void CActorInstance::UseAlphaWeaponTrace()
{
for_each(
m_WeaponTraceVector.begin(),
m_WeaponTraceVector.end(),
std::void_mem_fun(&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();
}