DragonNest/Server/DNGameServer/DnDropItem.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

725 lines
No EOL
23 KiB
C++
Raw Permalink Blame History

#include "StdAfx.h"
#include "DnDropItem.h"
#include "DnWorld.h"
#include "DnWorldGrid.h"
#include "DnWorldSector.h"
#include "DnTableDB.h"
#include "PerfCheck.h"
#include "GameSendPacket.h"
#include "TaskManager.h"
#include "Task.h"
#include "DNGameRoom.h"
#include "DNUserSession.h"
#include "NavigationMesh.h"
#include "DNGameDataManager.h"
#include "DnGameTask.h"
DECL_DN_SMART_PTR_STATIC( CDnDropItem, MAX_SESSION_COUNT, 100 )
float CEtOctreeNode<DnDropItemHandle>::s_fMinRadius = 500.0f;
STATIC_DECL_INIT( CDnDropItem, bool, s_bActive ) = { false, };
STATIC_DECL_INIT( CDnDropItem, DWORD, s_dwUniqueCount ) = { 0, };
STATIC_DECL_INIT( CDnDropItem, std::vector<DnDropItemHandle>, s_hVecPreLoadItemList );
#define DROPITEM_LIFETIME 180.f
CDnDropItem::CDnDropItem( CMultiRoom *pRoom, DWORD dwUniqueID, bool bProcess )
: CDnUnknownRenderObject( pRoom, bProcess )
{
CDnActionBase::Initialize( this );
m_nItemID = -1;
m_nOverlapCount = 1;
m_nRandomSeed = 0;
m_cOption = 0;
m_dwUniqueID = dwUniqueID;
m_fDistance = 0.f;
m_fLifeTime = DROPITEM_LIFETIME;
m_nRotate = 0;
m_fDisappearTime = 0.f;
m_bDisappear = false;
m_pCurCell = NULL;
m_dwOwnerUniqueID = -1;
m_Rank = ITEMRANK_D;
m_bReversionItem = false;
m_bReversionLock = false;
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
m_nEnchantID = 0;
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
if( bProcess ) InsertDropItem();
}
CDnDropItem::~CDnDropItem()
{
RemoveDropItem();
}
int CDnDropItem::GetRoomRand( CMultiRoom* pRoom )
{
return _roomrand(pRoom);
}
bool CDnDropItem::IsActive( CMultiRoom *pRoom )
{
return STATIC_INSTANCE_( s_bActive );
}
bool CDnDropItem::InitializeClass( CMultiRoom *pRoom )
{
if( !CDnWorld::IsActive(pRoom) ) return false;
/*
CDnWorldGrid *pGrid = (CDnWorldGrid*)CDnWorld::GetInstance(pRoom).GetGrid();
float fSize = max( pGrid->GetGridX() * pGrid->GetGridWidth() * 100.f, pGrid->GetGridY() * pGrid->GetGridHeight() * 100.f );
if( CDnWorld::IsActive(pRoom) ) {
float fMaxMultiply = 0.f;
for( DWORD i=0; i<CDnWorld::GetInstance(pRoom).GetGrid()->GetActiveSectorCount(); i++ ) {
float fTemp = CDnWorld::GetInstance(pRoom).GetGrid()->GetActiveSector(i)->GetHeightMultiply();
if( fTemp > fMaxMultiply ) fMaxMultiply = fTemp;
}
fSize = max( fSize, fMaxMultiply * 65535.f );
}
*/
float fCenter, fSize;
CDnWorld::GetInstance(pRoom).CalcWorldSize( fCenter, fSize );
STATIC_INSTANCE_(s_bActive) = true;
STATIC_INSTANCE_(s_dwUniqueCount) = 0;
return true;
}
void CDnDropItem::ProcessClass( CMultiRoom *pRoom, LOCAL_TIME LocalTime, float fDelta )
{
for( DWORD i=0; i<STATIC_INSTANCE_(s_pVecProcessList).size(); i++ ) {
STATIC_INSTANCE_(s_pVecProcessList)[i]->SyncClassTime( LocalTime );
STATIC_INSTANCE_(s_pVecProcessList)[i]->Process( LocalTime, fDelta );
if( STATIC_INSTANCE_(s_pVecProcessList)[i]->IsDestroy() ) {
STATIC_INSTANCE_(s_pVecProcessList)[i]->Release();
i--;
}
}
}
void CDnDropItem::ReleaseClass( CMultiRoom *pRoom )
{
STATIC_INSTANCE_(s_bActive) = false;
SAFE_RELEASE_SPTRVEC( STATIC_INSTANCE_(s_hVecPreLoadItemList) );
DeleteAllObject( pRoom );
STATIC_INSTANCE_(s_pVecProcessList).clear();
}
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
DnDropItemHandle CDnDropItem::DropItem( CMultiRoom *pRoom, EtVector3 &vPos, DWORD dwUniqueID, int nItemID, int nSeed, char cOption, int nOverlapCount, int nRotate, UINT nOwnerUniqueID, int nEnchantID )
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
DnDropItemHandle CDnDropItem::DropItem( CMultiRoom *pRoom, EtVector3 &vPos, DWORD dwUniqueID, int nItemID, int nSeed, char cOption, int nOverlapCount, int nRotate, UINT nOwnerUniqueID )
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
{
CDnDropItem *pDropItem = new CDnDropItem(pRoom,dwUniqueID,true);
CTask *pTask = CTaskManager::GetInstance(pRoom).GetTask( "ItemTask" );
pDropItem->InitializeRoom( pTask->GetRoom() );
if( cOption == -1 ) {
TItemData *pItemData = g_pDataManager->GetItemData(nItemID);
if( pItemData ) {
if ((pItemData->nType == ITEMTYPE_WEAPON) || (pItemData->nType == ITEMTYPE_PARTS)) {
if( pItemData->nTypeParam[0] > 0 ) {
TPotentialData *pPotential = g_pDataManager->GetPotentialData( pItemData->nTypeParam[0] );
if( pPotential && pPotential->nTotalProb > 0 ) {
int nRand = GetRoomRand(pRoom) % pPotential->nTotalProb;
for (int i = 0; i < (int)pPotential->pVecItemData.size(); i++){
if (nRand < pPotential->pVecItemData[i]->nPotentailOffset){
cOption = i + 1;
break;
}
}
}
}
}
}
}
if( cOption == -1 ) cOption = 0;
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
pDropItem->Initialize( vPos, nItemID, nSeed, cOption, nOverlapCount, nRotate, false, nEnchantID );
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
pDropItem->Initialize( vPos, nItemID, nSeed, cOption, nOverlapCount, nRotate );
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
pDropItem->SetOwnerUniqueID( nOwnerUniqueID );
return pDropItem->GetDropItemHandle();
}
void CDnDropItem::CalcCoinLump( CMultiRoom *pRoom, int nCoin, int nMin, int nMax, std::vector<int> &nVecResult )
{
int nResult = ( nMax - nMin ) + 1;
if( nResult <= 0 ) nResult = 1;
nResult = nMin + GetRoomRand(pRoom)%nResult;
if( nCoin < nResult ) nResult = nCoin;
int nRemainder = nCoin;
int nValue;
nVecResult.clear();
for( int i=0; i<nResult; i++ ) {
if( i == nResult - 1 ) nValue = nRemainder;
else {
nValue = ( GetRoomRand(pRoom) % nRemainder ) + 1;
if( nValue > nRemainder ) nValue = nRemainder;
}
nRemainder -= nValue;
nVecResult.push_back( nValue );
if( nRemainder == 0 ) break;
}
}
void CDnDropItem::CalcDropItemList( CMultiRoom *pRoom, TDUNGEONDIFFICULTY Difficulty, int nItemDropGroupTableID, DNVector(CDnItem::DropItemStruct) &VecList, bool bIncreaseUniqueID )
{
DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TITEMDROPGROUP );
std::vector<int> nVecList;
pSox->GetItemIDListFromField( "_DropGroupID", nItemDropGroupTableID, nVecList );
if( nVecList.empty() )
return;
if( Difficulty == Dungeon::Difficulty::Max )
{
CDnGameTask *pTask = (CDnGameTask *)CTaskManager::GetInstance(pRoom).GetTask( "GameTask" );
if( !pTask )
Difficulty = Dungeon::Difficulty::Easy;
else
Difficulty = pTask->GetStageDifficulty();
}
for( DWORD i=0; i<nVecList.size(); i++ ) {
int nItemID = nVecList[i];
if( pSox->GetFieldFromLablePtr( nItemID, "_Difficulty" )->GetInteger() != Difficulty ) continue;
INT64 nProb = (INT64)( pSox->GetFieldFromLablePtr( nItemID, "_Expectation" )->GetFloat() * 1000000000 );
while( nProb > 0 ) {
if( GetRoomRand(pRoom)%1000000000 < nProb ) {
int nItemTableID = pSox->GetFieldFromLablePtr( nItemID, "_DropID" )->GetInteger();
if( nItemTableID < 1 ) continue;
CDnDropItem::CalcDropItemList( pRoom, nItemTableID, VecList, bIncreaseUniqueID );
}
nProb -= 1000000000;
}
}
}
void CDnDropItem::CalcDropItemList( CMultiRoom *pRoom, int nItemDropTableID, DNVector(CDnItem::DropItemStruct) &VecList, bool bIncreaseUniqueID )
{
DNTableFileFormat* pSox = pSox = GetDNTable( CDnTableDB::TITEMDROP );
if( !pSox->IsExistItem( nItemDropTableID ) ) return;
CDnItem::DropItemStruct Struct;
// <20><> <20><><EFBFBD><EFBFBD>
int nMin = pSox->GetFieldFromLablePtr( nItemDropTableID, "_GoldMin" )->GetInteger();
int nMax = pSox->GetFieldFromLablePtr( nItemDropTableID, "_GoldMax" )->GetInteger();
int nProb = pSox->GetFieldFromLablePtr( nItemDropTableID, "_GoldProb" )->GetInteger();
if( GetRoomRand(pRoom)%1000000000 < nProb ) {
int nLumpMin = pSox->GetFieldFromLablePtr( nItemDropTableID, "_GoldLumpMin" )->GetInteger();
int nLumpMax = pSox->GetFieldFromLablePtr( nItemDropTableID, "_GoldLumpMax" )->GetInteger();
int nAmount = ( nMax - nMin ) + 1;
if( nAmount <= 0 ) nAmount = 1;
int nCoin = nMin + GetRoomRand(pRoom)%nAmount;
std::vector<int> nVecLumpCoin;
CalcCoinLump( pRoom, nCoin, nLumpMin, nLumpMax, nVecLumpCoin );
for( DWORD i=0; i<nVecLumpCoin.size(); i++ ) {
Struct.nItemID = 0;
Struct.nSeed = abs( GetRoomRand(pRoom) );
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
Struct.nEnchantID = 0;
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
Struct.nCount = nVecLumpCoin[i];
Struct.dwUniqueID = ( bIncreaseUniqueID ) ? STATIC_INSTANCE_(CDnDropItem::s_dwUniqueCount)++ : 0;
VecList.push_back( Struct );
}
}
int nDepth = ITEMDROP_DEPTH;
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
CalcDropItems( pRoom, nItemDropTableID, VecList, nDepth, bIncreaseUniqueID, nItemDropTableID );
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
CalcDropItems( pRoom, nItemDropTableID, VecList, nDepth, bIncreaseUniqueID );
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
/*
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int nCompoundItemCount = pSox->GetFieldFromLablePtr( nItemDropTableID, "_ItemMaxCompound" )->GetInteger();
std::vector<int> nVecItemIndex;
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
char szLabel[64];
for( DWORD i=0; i<20; i++ ) {
sprintf_s( szLabel, "_Item%dIndex", i + 1 );
if( pSox->GetFieldFromLablePtr( nItemDropTableID, szLabel )->GetInteger() == 0 ) continue;
nVecItemIndex.push_back( (int)i + 1 );
}
// <20><><EFBFBD><EFBFBD>
int nDropItemID;
std::vector<int> nVecRandomArray;
int nValue;
while( !nVecItemIndex.empty() ) {
nValue = _rand(pRoom)%(int)nVecItemIndex.size();
nVecRandomArray.push_back( nVecItemIndex[nValue] );
nVecItemIndex.erase( nVecItemIndex.begin() + nValue );
}
nVecItemIndex = nVecRandomArray;
for( DWORD i=0; i<nVecItemIndex.size(); i++ ) {
sprintf_s( szLabel, "_Item%dIndex", nVecItemIndex[i] );
nDropItemID = pSox->GetFieldFromLablePtr( nItemDropTableID, szLabel )->GetInteger();
sprintf_s( szLabel, "_Item%dProb", nVecItemIndex[i] );
nProb = (int)( pSox->GetFieldFromLablePtr( nItemDropTableID, szLabel )->GetFloat() * 1000000000.0 );
if( _rand(pRoom)%1000000000 >= nProb ) continue;
sprintf_s( szLabel, "_Item%dCountMin", nVecItemIndex[i] );
nMin = pSox->GetFieldFromLablePtr( nItemDropTableID, szLabel )->GetInteger();
sprintf_s( szLabel, "_Item%dCountMax", nVecItemIndex[i] );
nMax = pSox->GetFieldFromLablePtr( nItemDropTableID, szLabel )->GetInteger();
if( nMin == 0 && nMax == 0 ) continue;
if( nMin > nMax ) continue;
int nAmount = ( nMax - nMin ) + 1;
if( nAmount <= 0 ) nAmount = 1;
Struct.nItemID = nDropItemID;
Struct.nSeed = abs( _rand(pRoom) );
Struct.nCount = nMin + _rand(pRoom)%nAmount;
Struct.dwUniqueID = STATIC_INSTANCE_(CDnDropItem::s_dwUniqueCount)++;
VecList.push_back( Struct );
nCompoundItemCount--;
if( nCompoundItemCount <= 0 ) break;
}
*/
}
namespace DropItemNameSpace {
struct DropTempStruct {
bool bIsGroup;
int nItemID;
int nCount;
int nOffset;
};
}
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
void CDnDropItem::CalcDropItems( CMultiRoom *pRoom, int nDropItemTableID, DNVector(CDnItem::DropItemStruct) &VecResult, int &nDepth, bool bIncreaseUniqueID, int nBaseDropItemTableID )
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
void CDnDropItem::CalcDropItems( CMultiRoom *pRoom, int nDropItemTableID, DNVector(CDnItem::DropItemStruct) &VecResult, int &nDepth, bool bIncreaseUniqueID )
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
{
nDepth -= 1;
if( nDepth < 0 ) return;
using namespace DropItemNameSpace;
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
DNTableFileFormat* pSox = pSox = GetDNTable( CDnTableDB::TITEMDROP );
if( !pSox->IsExistItem( nDropItemTableID ) )
{
return;
}
DNVector(DropTempStruct) VecList;
char szLabel[64];
int nOffset = 0;
DropTempStruct Struct;
for( DWORD i=0; i<20; i++ ) {
sprintf_s( szLabel, "_IsGroup%d", i + 1 );
bool bGroup = ( pSox->GetFieldFromLablePtr( nDropItemTableID, szLabel )->GetInteger() == 1 ) ? true : false;
sprintf_s( szLabel, "_Item%dIndex", i + 1 );
int nIndex = pSox->GetFieldFromLablePtr( nDropItemTableID, szLabel )->GetInteger();
if( nIndex < 1 ) continue;
sprintf_s( szLabel, "_Item%dProb", i + 1 );
int nProb = pSox->GetFieldFromLablePtr( nDropItemTableID, szLabel )->GetInteger();
if( nProb <= 0 ) continue;
sprintf_s( szLabel, "_Item%dInfo", i + 1 );
int nInfo = pSox->GetFieldFromLablePtr( nDropItemTableID, szLabel )->GetInteger();
if( !bGroup ) {
if( nInfo < 1 ) continue;
if( !g_pDataManager->GetItemData( nIndex ) ) continue;
}
nOffset += nProb;
Struct.bIsGroup = bGroup;
Struct.nItemID = nIndex;
Struct.nCount = nInfo;
Struct.nOffset = nOffset;
VecList.push_back( Struct );
}
int nSeed = GetRoomRand(pRoom)%1000000000;
int nPrevOffset = 0;
for( DWORD i=0; i<VecList.size(); i++ ) {
if( nSeed >= nPrevOffset && nSeed < VecList[i].nOffset ) {
if( VecList[i].bIsGroup )
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
CalcDropItems( pRoom, VecList[i].nItemID, VecResult, nDepth, bIncreaseUniqueID, nBaseDropItemTableID );
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
CalcDropItems( pRoom, VecList[i].nItemID, VecResult, nDepth, bIncreaseUniqueID );
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
else {
CDnItem::DropItemStruct Result;
Result.nItemID = VecList[i].nItemID;
Result.nSeed = abs( GetRoomRand(pRoom) );
Result.nCount = VecList[i].nCount;
Result.cOption = 0;
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
Result.nEnchantID = 0;
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
TItemData *pItemData = g_pDataManager->GetItemData(Result.nItemID);
if( pItemData ) {
if ((pItemData->nType == ITEMTYPE_WEAPON) || (pItemData->nType == ITEMTYPE_PARTS)) {
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
Result.nEnchantID = CDnDropItem::GetDropItemEnchantID(pRoom, nBaseDropItemTableID);
if(Result.nEnchantID < 0)
{
g_Log.Log(LogType::_ERROR, L"[CalcDropItems] Get DropItemEnchantID Error(TableID[%d])", nBaseDropItemTableID);
Result.nEnchantID = 0;
}
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
if( pItemData->nTypeParam[0] > 0 ) {
TPotentialData *pPotential = g_pDataManager->GetPotentialData( pItemData->nTypeParam[0] );
if( pPotential && pPotential->nTotalProb > 0 ) {
int nRand = Result.nSeed % pPotential->nTotalProb;
for (int j = 0; j < (int)pPotential->pVecItemData.size(); j++){
if (nRand < pPotential->pVecItemData[j]->nPotentailOffset){
Result.cOption = j + 1;
break;
}
}
}
}
}
}
Result.dwUniqueID = ( bIncreaseUniqueID ) ? STATIC_INSTANCE_(CDnDropItem::s_dwUniqueCount)++ : 0;
VecResult.push_back( Result );
}
break;
}
nPrevOffset = VecList[i].nOffset;
}
}
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
bool CDnDropItem::PreInitializeItem( CMultiRoom *pRoom, int nItemID, int nEnchantID )
{
for( DWORD i=0; i<STATIC_INSTANCE_(s_hVecPreLoadItemList).size(); i++ ) {
if( STATIC_INSTANCE_(s_hVecPreLoadItemList)[i]->GetItemID() == nItemID ) return true;
}
CDnDropItem *pDropItem = new CDnDropItem( pRoom, -1, false );
if( pDropItem->Initialize( EtVector3( 0.f, 0.f, 0.f ), nItemID, 0, 0, 1, 0, true, nEnchantID ) == false ) {
SAFE_DELETE( pDropItem );
return false;
}
STATIC_INSTANCE_(s_hVecPreLoadItemList).push_back( pDropItem->GetMySmartPtr() );
return true;
}
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
bool CDnDropItem::PreInitializeItem( CMultiRoom *pRoom, int nItemID )
{
for( DWORD i=0; i<STATIC_INSTANCE_(s_hVecPreLoadItemList).size(); i++ ) {
if( STATIC_INSTANCE_(s_hVecPreLoadItemList)[i]->GetItemID() == nItemID ) return true;
}
CDnDropItem *pDropItem = new CDnDropItem( pRoom, -1, false );
if( pDropItem->Initialize( EtVector3( 0.f, 0.f, 0.f ), nItemID, 0, 0, 1, 0, true ) == false ) {
SAFE_DELETE( pDropItem );
return false;
}
STATIC_INSTANCE_(s_hVecPreLoadItemList).push_back( pDropItem->GetMySmartPtr() );
return true;
}
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
bool CDnDropItem::Initialize( EtVector3 &vPos, int nItemID, int nRandomSeed, char cOption, int nCount, int nRotate, bool bPreInitialize, int nEnchantID )
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
bool CDnDropItem::Initialize( EtVector3 &vPos, int nItemID, int nRandomSeed, char cOption, int nCount, int nRotate, bool bPreInitialize )
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
{
TItemData *pData = g_pDataManager->GetItemData( nItemID );
if( nItemID > 0 && !pData ) return false;
m_nOverlapCount = nCount;
m_nItemID = nItemID;
m_nRandomSeed = nRandomSeed;
m_cOption = cOption;
m_Cross.m_vPosition = vPos;
m_nRotate = nRotate;
m_Rank = ITEMRANK_D;
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
m_nEnchantID = nEnchantID;
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
if( pData )
m_Rank = (eItemRank)pData->cRank;
if( !bPreInitialize ) {
m_Cross.RotateYaw( (float)nRotate );
m_fDistance = 50.f + ( 10 * ( m_nRandomSeed % 11 ) );
int nIndex = GetElementIndex( "Disappear" );
if( nIndex != -1 ) {
m_fDisappearTime = GetElement( nIndex )->dwLength / 60.f;
}
else m_bDisappear = true;
}
return true;
}
void CDnDropItem::Process( LOCAL_TIME LocalTime, float fDelta )
{
float fPrevFrame = m_fPrevFrame;
CDnActionBase::ProcessAction( LocalTime, fDelta );
if( m_fDistance > 0.f )
{
float fValue = 100.f * fDelta;
m_fDistance -= fValue;
if( m_fDistance <= 0.f ) {
fValue += m_fDistance;
m_fDistance = 0.f;
}
if( GetGameRoom()->bIsPvPRoom() )
fValue = 0.f;
NavigationMesh *pNavMesh = INSTANCE(CDnWorld).GetNavMesh( m_Cross.m_vPosition );
if( !pNavMesh ) {
ProcessAttributeMovement( fValue );
}
else {
if( m_pCurCell == NULL ) {
m_pCurCell = pNavMesh->FindClosestCell( m_Cross.m_vPosition );
if( ( m_pCurCell == NULL ) || ( !m_pCurCell->IsPointInCellCollumn( m_Cross.m_vPosition ) ) ) {
m_pCurCell = NULL;
ProcessAttributeMovement( fValue );
}
}
if( m_pCurCell ) {
EtVector3 vPrevPos = m_Cross.m_vPosition;
m_Cross.MoveLocalZAxis( fValue );
int nSide = -1;
NavigationCell *pLastCell = NULL;
m_pCurCell->FindLastCollision( vPrevPos, m_Cross.m_vPosition, &pLastCell, nSide );
if( nSide != -1 )
{
if( pLastCell->Link( nSide ) == NULL )
{
EtVector2 vMoveDir2D( m_Cross.m_vPosition.x - vPrevPos.x, m_Cross.m_vPosition.z - vPrevPos.z );
float fMoveLength = EtVec2Length( &vMoveDir2D );
vMoveDir2D /= fMoveLength;
EtVector2 vWallDir2D = pLastCell->Side( nSide )->EndPointB() - pLastCell->Side( nSide )->EndPointA();
EtVec2Normalize( &vWallDir2D, &vWallDir2D );
fMoveLength *= EtVec2Dot( &vWallDir2D, &vMoveDir2D );
m_Cross.m_vPosition.x = vPrevPos.x + fMoveLength * vWallDir2D.x;
m_Cross.m_vPosition.z = vPrevPos.z + fMoveLength * vWallDir2D.y;
int nNewSide = -1;
m_pCurCell->FindLastCollision( vPrevPos, m_Cross.m_vPosition, &pLastCell, nNewSide );
if( nNewSide != -1 )
{
if( pLastCell->Link( nNewSide ) )
{
NavigationCell *pNewCell;
pNewCell = pLastCell->Link( nNewSide );
if( pNewCell->IsPointInCellCollumn( m_Cross.m_vPosition ) )
{
m_pCurCell = pNewCell;
}
else
{
m_Cross.m_vPosition.x = vPrevPos.x;
m_Cross.m_vPosition.z = vPrevPos.z;
}
}
else if( !m_pCurCell->IsPointInCellCollumn( m_Cross.m_vPosition ) )
{
m_Cross.m_vPosition.x = vPrevPos.x;
m_Cross.m_vPosition.z = vPrevPos.z;
}
}
}
else
{
m_pCurCell = pLastCell->Link( nSide );
}
}
if( m_pCurCell->GetType() == NavigationCell::CT_PROP )
m_Cross.m_vPosition.y = m_pCurCell->GetPlane()->SolveForY( m_Cross.m_vPosition.x, m_Cross.m_vPosition.z );
else
m_Cross.m_vPosition.y = CDnWorld::GetInstance(GetRoom()).GetHeight( m_Cross.m_vPosition );
}
}
}
ProcessLifeTime( LocalTime, fDelta );
}
void CDnDropItem::ProcessAttributeMovement( float fDistance )
{
EtVector3 vPrevPos = m_Cross.m_vPosition;
m_Cross.MoveLocalZAxis( fDistance );
if( CDnWorld::GetInstance(GetRoom()).GetAttribute( m_Cross.m_vPosition ) != 0 ) {
m_Cross.m_vPosition = vPrevPos;
}
m_Cross.m_vPosition.y = CDnWorld::GetInstance(GetRoom()).GetHeight( m_Cross.m_vPosition );
}
void CDnDropItem::ProcessLifeTime( LOCAL_TIME LocalTime, float fDelta )
{
if( GetGameRoom()->GetGameTaskType() == GameTaskType::Farm )
return;
if( m_fLifeTime <= 0.f ) return;
if( m_Rank >= ITEMRANK_B ) return;
if(m_bReversionLock) return;
m_fLifeTime -= fDelta;
if( !m_bDisappear && m_fLifeTime <= m_fDisappearTime ) {
m_bDisappear = true;
SetActionQueue( "Disappear", 0, 20.f );
}
if( m_fLifeTime <= 0.f ) SetDestroy();
}
void CDnDropItem::SyncClassTime( LOCAL_TIME LocalTime )
{
CDnActionBase::m_LocalTime = LocalTime;
}
void CDnDropItem::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex )
{
switch( Type ) {
case STE_Destroy:
SetDestroy();
break;
}
}
void CDnDropItem::GetBoundingSphere( SSphere &Sphere, bool bActorSize/* = false*/ )
{
Sphere.Center = m_Cross.m_vPosition;
Sphere.fRadius = 30.f;
}
void CDnDropItem::InsertDropItem()
{
if( GetRoom() )
static_cast<CDNGameRoom*>(GetRoom())->AddDropItem( m_dwUniqueID, GetMySmartPtr() );
}
void CDnDropItem::RemoveDropItem()
{
if( GetRoom() )
static_cast<CDNGameRoom*>(GetRoom())->EraseDropItem( GetUniqueID() );
}
void CDnDropItem::Send( DWORD dwProtocol, DnActorHandle hActor, CMemoryStream *pStream, GlobalEnum::ClientSessionTypeEnum SessionType )
{
DWORD dwUniqueID = GetUniqueID();
BYTE *pBuffer = ( pStream ) ? (BYTE*)pStream->GetBuffer() : NULL;
int nSize = ( pStream ) ? pStream->Tell() : 0;
if( m_pRoom )
{
for( DWORD i=0; i<m_pRoom->GetUserCount(); i++ ) {
CDNUserSession *pStruct = m_pRoom->GetUserData(i);
if( pStruct->GetSessionID() == hActor->GetUniqueID() ) {
SendGameDropItemMsg( pStruct, dwUniqueID, (USHORT)dwProtocol, pBuffer, nSize );
break;
}
}
}
}
void CDnDropItem::Send( DWORD dwProtocol, CMemoryStream *pStream, GlobalEnum::ClientSessionTypeEnum SessionType, bool bImmediate )
{
DWORD dwUniqueID = GetUniqueID();
BYTE *pBuffer = ( pStream ) ? (BYTE*)pStream->GetBuffer() : NULL;
int nSize = ( pStream ) ? pStream->Tell() : 0;
if( m_pRoom )
{
for( DWORD i=0; i<m_pRoom->GetUserCount(); i++ ) {
CDNUserSession *pStruct = m_pRoom->GetUserData(i);
SendGameDropItemMsg( pStruct, dwUniqueID, (USHORT)dwProtocol, pBuffer, nSize );
}
}
}
void CDnDropItem::SetReversionItem(bool bSet)
{
m_bReversionItem = bSet;
}
void CDnDropItem::LockReversionItem(bool bLock)
{
m_bReversionLock = bLock;
}
void CDnDropItem::MakeItemStruct( TItem &ItemInfo )
{
ItemInfo.nItemID = m_nItemID;
ItemInfo.nRandomSeed = m_nRandomSeed;
ItemInfo.cOption = m_cOption;
ItemInfo.wCount = m_nOverlapCount;
}
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
int CDnDropItem::GetDropItemEnchantID( CMultiRoom *pRoom, int nItemDropTableID)
{
if(!pRoom)
return 0;
if(nItemDropTableID <= 0)
return 0;
TItemDropEnchantData* pItemDropEnchantData = g_pDataManager->GetDropItemEnchant(nItemDropTableID);
if(!pItemDropEnchantData) return 0;
int nTotalProb = 0;
std::vector<int> nVecOffset;
for(int i = 0; i < pItemDropEnchantData->nEnchantCount;i++)
{
nVecOffset.push_back(nTotalProb + pItemDropEnchantData->nEnchantProb[i]);
nTotalProb = nTotalProb + pItemDropEnchantData->nEnchantProb[i];
}
int nSeed = GetRoomRand(pRoom)%nTotalProb;
for(int i=0; i <pItemDropEnchantData->nEnchantCount; i++)
{
if(nSeed < nVecOffset[i])
{
return pItemDropEnchantData->nEnchantOption[i];
}
}
return 0;
}
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)