431 lines
No EOL
13 KiB
C++
431 lines
No EOL
13 KiB
C++
#include "StdAfx.h"
|
||
#include "DnWorldBrokenProp.h"
|
||
#include "DnTableDB.h"
|
||
#include "DnWorld.h"
|
||
#include "DnWeapon.h"
|
||
#include "DnDamageBase.h"
|
||
#include "DnProjectile.h"
|
||
#include "TaskManager.h"
|
||
#include "DnPartyTask.h"
|
||
#include "DnItemTask.h"
|
||
#include "DNUserSession.h"
|
||
#include "DnPropState.h"
|
||
#include "DnPropCondition.h"
|
||
#include "DnPropStateDoAction.h"
|
||
#include "DnPropStateTrigger.h"
|
||
#include "DnPropCondiDurability.h"
|
||
#include "DNLogConnection.h"
|
||
#include "DNGameTask.h"
|
||
#include "DnPlayerActor.h"
|
||
#include "DnCannonMonsterActor.h"
|
||
#include "DnMonsterActor.h"
|
||
#include "DnStateBlow.h"
|
||
|
||
CDnWorldBrokenProp::CDnWorldBrokenProp( CMultiRoom *pRoom )
|
||
: CDnWorldActProp( pRoom )
|
||
//, CDnDamageBase( DamageObjectTypeEnum::Prop )
|
||
{
|
||
m_nDurability = 0;
|
||
//m_nBreakActionCount = 0;
|
||
m_bHittable = false;
|
||
m_bNoDamage = false;
|
||
|
||
m_nItemDropGroupTableID = 0;
|
||
m_pLastHitObject = NULL;
|
||
m_bBroken = false;
|
||
|
||
m_nLastHitUniqueID = -1;
|
||
|
||
m_iLastRandomSeed = 0;
|
||
m_bHitted = false;
|
||
m_pBrokenActionState = NULL;
|
||
m_pTriggerActionState = NULL;
|
||
m_LastDamageTime = 0;
|
||
}
|
||
|
||
CDnWorldBrokenProp::~CDnWorldBrokenProp()
|
||
{
|
||
SAFE_DELETE_VEC( m_VecDropItemList );
|
||
ReleasePostCustomParam();
|
||
}
|
||
|
||
bool CDnWorldBrokenProp::InitializeTable( int nTableID )
|
||
{
|
||
if( CDnWorldActProp::InitializeTable( nTableID ) == false ) return false;
|
||
|
||
//*
|
||
//DNTableFileFormat* pSox = GetDNTable( CDnTableDB::TPROP );
|
||
//m_nDurability = pSox->GetFieldFromLablePtr( nTableID, "_Durability" )->GetInteger();
|
||
|
||
//m_nItemDropTableID = pSox->GetFieldFromLablePtr( nTableID, "_ItemDropTableIndex" )->GetInteger();
|
||
//if( m_nItemDropTableID > 0 ) {
|
||
// CDnDropItem::CalcDropItemList( GetRoom(), m_nItemDropTableID, m_VecDropItemList );
|
||
|
||
// for( DWORD i=0; i<m_VecDropItemList.size(); i++ ) {
|
||
// CDnDropItem::PreInitializeItem( GetRoom(), m_VecDropItemList[i].nItemID );
|
||
// }
|
||
//}
|
||
//*/
|
||
|
||
if( GetData() ) {
|
||
BrokenStruct *pStruct = (BrokenStruct *)GetData();
|
||
m_nDurability = pStruct->nDurability;
|
||
|
||
if( -1 != m_nDurability )
|
||
{
|
||
if( 0 == m_nDurability ) m_nDurability = 1;
|
||
m_nItemDropGroupTableID = pStruct->nItemDropGroupTableID;
|
||
if( m_nItemDropGroupTableID > 0 ) {
|
||
CDnDropItem::CalcDropItemList( GetRoom(), Dungeon::Difficulty::Max, m_nItemDropGroupTableID, m_VecDropItemList );
|
||
|
||
if (m_VecDropItemList.empty()){
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>α<EFBFBD>
|
||
// g_pLogConnection->QueryLogStage(GetRoom()->GetRoomID(), pTask->GetMapTableID(), 0, 0, nTableID); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>α<EFBFBD> 090226
|
||
}
|
||
else {
|
||
for( DWORD i=0; i<m_VecDropItemList.size(); i++ ) {
|
||
#if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
if( CDnDropItem::PreInitializeItem( GetRoom(), m_VecDropItemList[i].nItemID, m_VecDropItemList[i].nEnchantID ) == false )
|
||
#else // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
if( CDnDropItem::PreInitializeItem( GetRoom(), m_VecDropItemList[i].nItemID ) == false )
|
||
#endif // #if defined(PRE_ADD_STAGE_CLEAR_ENCHANT_REWARD)
|
||
{
|
||
m_VecDropItemList.erase( m_VecDropItemList.begin() + i );
|
||
i--;
|
||
continue;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>α<EFBFBD>
|
||
// g_pLogConnection->QueryLogStage(GetRoom()->GetRoomID(), pTask->GetMapTableID(), 0, m_VecDropItemList[i].nItemID, nTableID); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>α<EFBFBD> 090226
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
bool CDnWorldBrokenProp::Initialize( CEtWorldSector *pParentSector, const char *szPropName, EtVector3 &vPos, EtVector3 &vRotate, EtVector3 &vScale )
|
||
{
|
||
// FSM <20><> BrokenProp<6F><70> <20>°<EFBFBD> <20>ʱ<EFBFBD>ȭ <20><><EFBFBD>ش<EFBFBD>..
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1 <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> broken<65><6E> <20>ƴ<EFBFBD>..
|
||
if( -1 == m_nDurability )
|
||
return true;
|
||
|
||
// state <20><><EFBFBD><EFBFBD>
|
||
CDnPropState* pNormalState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::NORMAL );
|
||
CDnPropState* pHitActionState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::DO_ACTION );
|
||
CDnPropState* pItemDropState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::ITEM_DROP );
|
||
CDnPropState* pTriggerState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::TRIGGER );
|
||
CDnPropState* pBrokenActionState = CDnPropState::Create( GetMySmartPtr(), CDnPropState::DO_ACTION );
|
||
static_cast<CDnPropStateDoAction*>(pHitActionState)->AddActionName( "Hit" );
|
||
m_pBrokenActionState = static_cast<CDnPropStateDoAction*>(pBrokenActionState);
|
||
static_cast<CDnPropStateTrigger*>(pTriggerState)->SetFuncName( "CDnWorldProp::OnBrokenProp" );
|
||
m_pTriggerActionState = static_cast<CDnPropStateTrigger*>(pTriggerState);
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
CDnPropCondition* pHitCondition = CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::IS_HIT );
|
||
CDnPropCondition* pNULLCondition = CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::NULL_CONDITION );
|
||
CDnPropCondition* pDurabilityCondition = CDnPropCondition::Create( GetMySmartPtr(), CDnPropCondition::COMPARE_DURABILITY );
|
||
static_cast<CDnPropCondiDurability*>(pDurabilityCondition)->Initialize( 0, CDnPropCondiDurability::LESS_EQUAL );
|
||
|
||
m_pFSM->AddCondition( pHitCondition );
|
||
m_pFSM->AddCondition( pNULLCondition );
|
||
m_pFSM->AddCondition( pDurabilityCondition );
|
||
|
||
m_pFSM->AddState( pNormalState );
|
||
m_pFSM->AddState( pHitActionState );
|
||
m_pFSM->AddState( pItemDropState );
|
||
m_pFSM->AddState( pTriggerState);
|
||
m_pFSM->AddState( pBrokenActionState );
|
||
|
||
pNormalState->AddTransitState( pHitActionState, pHitCondition );
|
||
pHitActionState->AddTransitState( pNormalState, pNULLCondition );
|
||
pNormalState->AddTransitState( pTriggerState, pDurabilityCondition );
|
||
pTriggerState->AddTransitState( pItemDropState, pNULLCondition );
|
||
pItemDropState->AddTransitState( pBrokenActionState, pNULLCondition );
|
||
|
||
m_pFSM->SetEntryState( pNormalState );
|
||
|
||
bool bResult = CDnWorldActProp::Initialize( pParentSector, szPropName, vPos, vRotate, vScale );
|
||
if( !bResult )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
bool CDnWorldBrokenProp::CreateObject()
|
||
{
|
||
bool bResult = CDnWorldActProp::CreateObject();
|
||
|
||
if( m_pBrokenActionState )
|
||
{
|
||
if( -1 == m_nDurability )
|
||
return true;
|
||
|
||
if( bResult ) {
|
||
char szTemp[16];
|
||
for( int i=0; ; i++ ) {
|
||
sprintf_s( szTemp, "Break_%c", 'a' + i );
|
||
if( IsExistAction( szTemp ) == false ) break;
|
||
|
||
m_pBrokenActionState->AddActionName( szTemp );
|
||
//m_nBreakActionCount++;
|
||
}
|
||
}
|
||
}
|
||
|
||
return bResult;
|
||
}
|
||
|
||
void CDnWorldBrokenProp::UpdatePropBreakToHitter( CDnDamageBase* pHitter )
|
||
{
|
||
if( pHitter )
|
||
{
|
||
DnActorHandle hActor = pHitter->GetActorHandle();
|
||
if( hActor )
|
||
{
|
||
if ( hActor->IsPlayerActor() )
|
||
{
|
||
CDnPlayerActor *pPlayer = static_cast<CDnPlayerActor *>(hActor.GetPointer());
|
||
pPlayer->UpdatePropBreak();
|
||
}
|
||
else
|
||
if( CDnActorState::Cannon == hActor->GetActorType() )
|
||
{
|
||
CDnCannonMonsterActor* pCannonMonsterActor = static_cast<CDnCannonMonsterActor*>(hActor.GetPointer());
|
||
DnActorHandle hPlayerActor = pCannonMonsterActor->GetMasterPlayerActor();
|
||
if( hPlayerActor && hPlayerActor->IsPlayerActor() )
|
||
{
|
||
CDnPlayerActor* pPlayer = static_cast<CDnPlayerActor*>(hPlayerActor.GetPointer());
|
||
pPlayer->UpdatePropBreak();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDnWorldBrokenProp::CalcDamage( CDnDamageBase *pHitter, CDnDamageBase::SHitParam &HitParam )
|
||
{
|
||
|
||
// if( m_nDurability <= 0 ) return;
|
||
if( m_bDestroy == true ) return;
|
||
if( m_bBroken ) return;
|
||
|
||
m_pLastHitObject = pHitter;
|
||
m_LastDamageTime = HitParam.RemainTime;
|
||
m_nLastHitUniqueID = HitParam.iUniqueID;
|
||
|
||
m_nDurability -= (int)( HitParam.fDurability * 100.f );
|
||
|
||
// NOTE: Ʈ<><C6AE><EFBFBD>ſ<EFBFBD><C5BF><EFBFBD> IsBroken() <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.. <20>ٸ<EFBFBD> <20>Լ<EFBFBD><D4BC>鵵 üũ<C3BC>غ<EFBFBD><D8BA><EFBFBD> <20>ҵ<EFBFBD>.
|
||
// Ʈ<><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><>Ȳ<EFBFBD><C8B2> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD> <20><><EFBFBD>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD> üũ<C3BC><C5A9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if( m_nDurability <= 0 )
|
||
{
|
||
m_bBroken = true;
|
||
|
||
//<2F><>ȯ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ã<>Ƽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ؾ<EFBFBD> <20><>.
|
||
DnActorHandle hHitterActor;
|
||
|
||
if (pHitter)
|
||
hHitterActor = pHitter->GetActorHandle();
|
||
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if (hHitterActor && hHitterActor->IsMonsterActor())
|
||
{
|
||
DnActorHandle hMasterActor;
|
||
CDnMonsterActor* pMonsterActor = NULL;
|
||
|
||
pMonsterActor = static_cast<CDnMonsterActor*>(hHitterActor.GetPointer());
|
||
|
||
if (pMonsterActor)
|
||
hMasterActor = pMonsterActor->GetSummonerPlayerActor();
|
||
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ã<><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, hHitterActor<6F><72> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ͷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
if (hMasterActor)
|
||
hHitterActor = hMasterActor;
|
||
}
|
||
|
||
m_pTriggerActionState->AddFuncParam( "LastBrokenPropActor", hHitterActor ? hHitterActor->GetUniqueID() : -1 );
|
||
|
||
m_pFSM->Process( 0, 0.0f );
|
||
|
||
UpdatePropBreakToHitter( pHitter );
|
||
// SetLastAccessActor( pHitter->GetActorHandle() );
|
||
}
|
||
|
||
//if( m_nDurability <= 0 ) {
|
||
// CDnWorld::GetInstance(GetRoom()).OnTriggerEventCallback( "CDnWorldProp::OnBrokenProp", m_LocalTime, 0.f );
|
||
// m_bBroken = true;
|
||
// m_nDurability = 0;
|
||
|
||
// if( m_nBreakActionCount > 0 ) {
|
||
// char szTemp[32];
|
||
// sprintf_s( szTemp, "Break_%c", 'a' + _rand(GetRoom())%m_nBreakActionCount );
|
||
// SetActionQueue( szTemp );
|
||
// }
|
||
|
||
// // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~
|
||
// DropItems();
|
||
//}
|
||
//else {
|
||
// SetActionQueue( "Hit" );
|
||
//}
|
||
|
||
if( HitParam.hWeapon ) {
|
||
if( HitParam.hWeapon->GetWeaponType() & CDnWeapon::Projectile ) {
|
||
CDnProjectile *pProjectile = static_cast<CDnProjectile *>(HitParam.hWeapon.GetPointer());
|
||
if( pProjectile ) pProjectile->OnDamageSuccess( CDnActor::Identity(), HitParam );
|
||
else HitParam.hWeapon->SetDestroy();
|
||
}
|
||
}
|
||
|
||
DnActorHandle hHitterActor;
|
||
if (pHitter)
|
||
hHitterActor = pHitter->GetActorHandle();
|
||
|
||
if (hHitterActor && hHitterActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_179))
|
||
{
|
||
DnActorHandle hTargetActor;
|
||
|
||
DNVector(DnBlowHandle) vlhBlows;
|
||
hHitterActor->GetStateBlow()->GetStateBlowFromBlowIndex( STATE_BLOW::BLOW_179, vlhBlows );
|
||
|
||
int iNumBlow = (int)vlhBlows.size();
|
||
for( int i = 0; i < iNumBlow; ++i )
|
||
{
|
||
DnBlowHandle hBlow = vlhBlows.at(i);
|
||
if (hBlow)
|
||
hBlow->OnTargetHit(hTargetActor);
|
||
}
|
||
}
|
||
}
|
||
|
||
void CDnWorldBrokenProp::OnDamage( CDnDamageBase *pHitter, CDnDamageBase::SHitParam &HitParam )
|
||
{
|
||
if( -1 == m_nDurability )
|
||
return;
|
||
|
||
int nSeed = CRandom::Seed(GetRoom());
|
||
_srand( GetRoom(), nSeed );
|
||
m_iLastRandomSeed = nSeed;
|
||
|
||
CalcDamage( pHitter, HitParam );
|
||
|
||
// <20><> <20>κе<CEBA> MPTransAction <20><> <20><><EFBFBD>ӹް<D3B9> <20>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD> <20><>¿ <20><> <20><><EFBFBD><EFBFBD>..
|
||
switch( pHitter->GetDamageObjectType() )
|
||
{
|
||
case CDnDamageBase::DamageObjectTypeEnum::Actor:
|
||
{
|
||
DnActorHandle hActor = pHitter->GetActorHandle();
|
||
if( !hActor ) break;
|
||
// Request Damage
|
||
BYTE pBuffer[128];
|
||
CPacketCompressStream Stream( pBuffer, 128 );
|
||
|
||
DWORD dwUniqueID = hActor->GetUniqueID();
|
||
DWORD dwWeaponUniqueID = -1;
|
||
INT64 nWeaponSerialID = -1;
|
||
bool bSendWeaponSerialID = false;
|
||
|
||
if( HitParam.hWeapon ) {
|
||
if( HitParam.hWeapon->GetSerialID() == -1 )
|
||
dwWeaponUniqueID = HitParam.hWeapon->GetUniqueID();
|
||
else {
|
||
bSendWeaponSerialID = true;
|
||
nWeaponSerialID = HitParam.hWeapon->GetSerialID();
|
||
}
|
||
}
|
||
|
||
Stream.Write( &nSeed, sizeof(int) );
|
||
Stream.Write( &dwUniqueID, sizeof(DWORD) );
|
||
|
||
Stream.Write( &m_nDurability, sizeof(int) );
|
||
Stream.Write( &bSendWeaponSerialID, sizeof(bool) );
|
||
if( bSendWeaponSerialID ) Stream.Write( &nWeaponSerialID, sizeof(INT64) );
|
||
else Stream.Write( &dwWeaponUniqueID, sizeof(DWORD) );
|
||
Stream.Write( &HitParam.vPosition, sizeof(EtVector3), CPacketCompressStream::VECTOR3_BIT );
|
||
Stream.Write( &HitParam.vViewVec, sizeof(EtVector3), CPacketCompressStream::VECTOR3_SHORT );
|
||
|
||
OnDamageWriteAdditionalPacket( HitParam, &Stream );
|
||
|
||
Send( eProp::SC_ONDAMAGE, &Stream );
|
||
}
|
||
break;
|
||
case CDnDamageBase::DamageObjectTypeEnum::Prop:
|
||
break;
|
||
}
|
||
|
||
m_bHitted = true;
|
||
}
|
||
|
||
|
||
bool CDnWorldBrokenProp::IsHittedAndReset( void )
|
||
{
|
||
bool bResult = m_bHitted;
|
||
|
||
m_bHitted = false;
|
||
|
||
return bResult;
|
||
}
|
||
|
||
|
||
bool CDnWorldBrokenProp::IsHittable( CDnDamageBase *pHitter, LOCAL_TIME LocalTime, int iHitUniqueID /*= -1*/ )
|
||
{
|
||
if( m_bBroken ) return false;
|
||
|
||
if( false == IsShow() ) return false;
|
||
|
||
if( m_pLastHitObject == pHitter )
|
||
{
|
||
if( -1 != m_nLastHitUniqueID )
|
||
{
|
||
if( m_nLastHitUniqueID == iHitUniqueID )
|
||
{
|
||
if( m_LastDamageTime > LocalTime ) return false;
|
||
}
|
||
}
|
||
else
|
||
if( m_LastDamageTime > LocalTime ) return false;
|
||
}
|
||
if( m_bNoDamage ) return false;
|
||
|
||
return m_bHittable;
|
||
}
|
||
|
||
void CDnWorldBrokenProp::OnSignal( SignalTypeEnum Type, void *pPtr, LOCAL_TIME LocalTime, LOCAL_TIME SignalStartTime, LOCAL_TIME SignalEndTime, int nSignalIndex )
|
||
{
|
||
switch( Type ) {
|
||
case STE_CanHit:
|
||
{
|
||
CanHitStruct *pStruct = (CanHitStruct *)pPtr;
|
||
m_bHittable = ( pStruct->bHittable == TRUE ) ? true : false;
|
||
}
|
||
break;
|
||
}
|
||
CDnWorldActProp::OnSignal( Type, pPtr, LocalTime, SignalStartTime, SignalEndTime, nSignalIndex );
|
||
}
|
||
|
||
// BrokenProp <20><> <20><><EFBFBD>Խÿ<D4BD><C3BF><EFBFBD> <20><><EFBFBD>߾<EFBFBD><DFBE>ָ<EFBFBD> <20>ȴ<EFBFBD>.
|
||
void CDnWorldBrokenProp::OnSyncComplete( CDNUserSession* pBreakIntoGameSession/*=NULL*/ )
|
||
{
|
||
if( !pBreakIntoGameSession )
|
||
return;
|
||
|
||
CmdShow( true, pBreakIntoGameSession );
|
||
|
||
CDnWorldActProp::OnSyncComplete( pBreakIntoGameSession );
|
||
}
|
||
|
||
|
||
void CDnWorldBrokenProp::_OnLifeTimeEnd( LOCAL_TIME LocalTime, float fDelta )
|
||
{
|
||
m_nDurability = 0;
|
||
m_bBroken = true;
|
||
m_pBrokenActionState->UseCmdAction( true );
|
||
m_pFSM->Process( 0, 0.0f );
|
||
} |