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

298 lines
9.9 KiB
C++

#include "stdafx.h"
#include "SecondarySkillEventHandlerServer.h"
#include "DNUserSession.h"
#include "DNDBConnection.h"
#include "SecondarySkill.h"
#include "DNGameDataManager.h"
#include "SecondarySkillRecipe.h"
#include "ManufactureSkill.h"
#include "SecondarySkillRepositoryServer.h"
#if defined( _GAMESERVER )
#include "DNGameRoom.h"
#include "DnItemTask.h"
#include "DnDropItem.h"
#endif // #if defined( _GAMESERVER )
#include "NpcReputationProcessor.h"
#include "DNMissionSystem.h"
#if defined(PRE_ADD_TOTAL_LEVEL_SKILL)
#if defined(_GAMESERVER)
#include "DnBlow.h"
#endif // _GAMESERVER
#endif // PRE_ADD_TOTAL_LEVEL_SKILL
#if defined( PRE_ADD_SECONDARY_SKILL )
CSecondarySkillEventHandlerServer::CSecondarySkillEventHandlerServer( CDNUserSession* pSession )
:m_pSession(pSession)
{
}
bool CSecondarySkillEventHandlerServer::OnCreate( CSecondarySkill* pSkill )
{
_ASSERT( m_pSession->CheckDBConnection() );
if( m_pSession->CheckDBConnection() == false )
return false;
// 클라이언트에 패킷 전송
m_pSession->SendCreateSecondarySkill( ERROR_NONE, pSkill->GetSkillID() );
// DB M/W 요청
m_pSession->GetDBConnection()->QueryAddSecondarySkill( m_pSession, pSkill->GetSkillID(), pSkill->GetType() );
return true;
}
bool CSecondarySkillEventHandlerServer::OnDelete( CSecondarySkill* pSkill )
{
_ASSERT( m_pSession->CheckDBConnection() );
if( m_pSession->CheckDBConnection() == false )
return false;
// 클라이언트에 패킷 전송
m_pSession->SendDelSecondarySkill( ERROR_NONE, pSkill->GetSkillID() );
// DB M/W 요청
m_pSession->GetDBConnection()->QueryDeleteSecondarySkill( m_pSession, pSkill->GetSkillID() );
return true;
}
bool CSecondarySkillEventHandlerServer::OnAddRecipe( CSecondarySkillRecipe* pRecipe, bool bIsCash )
{
_ASSERT( m_pSession->CheckDBConnection() );
if( m_pSession->CheckDBConnection() == false )
return false;
// 클라이언트에 패킷 전송
m_pSession->SendAddSecondarySkillRecipe( ERROR_NONE, pRecipe );
// DB M/W 요청
m_pSession->GetDBConnection()->QueryAddSecondarySkillRecipe( m_pSession, bIsCash, pRecipe->GetItemSerial(), pRecipe->GetSkillID() );
return true;
}
bool CSecondarySkillEventHandlerServer::OnDeleteRecipe( CSecondarySkillRecipe* pRecipe )
{
_ASSERT( m_pSession->CheckDBConnection() );
if( m_pSession->CheckDBConnection() == false )
return false;
// 클라이언트에 패킷 전송
m_pSession->SendDeleteSecondarySkillRecipe( ERROR_NONE, pRecipe->GetSkillID(), pRecipe->GetItemID() );
// DB M/W 요청
m_pSession->GetDBConnection()->QueryDeleteSecondarySkillRecipe( m_pSession, pRecipe->GetItemSerial() );
return true;
}
bool CSecondarySkillEventHandlerServer::OnExtractRecipe( CSecondarySkillRecipe* pRecipe, bool bIsCash )
{
_ASSERT( m_pSession->CheckDBConnection() );
if( m_pSession->CheckDBConnection() == false )
return false;
// 클라이언트에 패킷 전송
m_pSession->SendExtractSecondarySkillRecipe( ERROR_NONE, pRecipe->GetSkillID(), pRecipe->GetItemID() );
m_pSession->SendDeleteSecondarySkillRecipe( ERROR_NONE, pRecipe->GetSkillID(), pRecipe->GetItemID() );
// DB M/W 요청
m_pSession->GetDBConnection()->QueryExtractSecondarySkillRecipe( m_pSession, pRecipe->GetItemSerial(), bIsCash ? DBDNWorldDef::ItemLocation::CashInventory : DBDNWorldDef::ItemLocation::Inventory );
return true;
}
bool CSecondarySkillEventHandlerServer::OnChangeExp( CSecondarySkill* pSkill, int iAddExp )
{
TSecondarySkillLevelTableData* pLevelData = g_pDataManager->GetSecondarySkillLevelTableData( pSkill->GetSkillID(), pSkill->GetExp() );
if( pLevelData == NULL )
return false;
pSkill->SetGrade( pLevelData->Grade );
pSkill->SetLevel( pLevelData->iLevel );
if( pSkill->GetExp() > pLevelData->iExp )
{
if( pSkill->GetExp()-iAddExp >= pLevelData->iExp )
iAddExp = 0;
else
iAddExp -= pSkill->GetExp()-pLevelData->iExp;
pSkill->SetExp( pLevelData->iExp, NULL );
}
// 가감값
if( iAddExp > 0 )
{
// 클라이언트에 패킷 전송
m_pSession->SendUpdateSecondarySkillExp( ERROR_NONE, pSkill->GetSkillID(), pSkill->GetGrade(), pSkill->GetExp(), pSkill->GetLevel() );
// DB M/W 요청
if( m_pSession->CheckDBConnection() )
{
m_pSession->GetDBConnection()->QueryModSecondarySkillExp( m_pSession, pSkill->GetSkillID(), iAddExp, pSkill->GetExp() );
}
}
return true;
}
bool CSecondarySkillEventHandlerServer::OnChangeRecipeExp( CSecondarySkillRecipe* pRecipe, int iAddExp )
{
_ASSERT( m_pSession->CheckDBConnection() );
if( m_pSession->CheckDBConnection() == false )
return false;
// 클라이언트에 패킷 전송
m_pSession->SendUpdateSecondarySkillRecipeExp( ERROR_NONE, pRecipe->GetSkillID(), pRecipe->GetItemID(), pRecipe->GetExp() );
// DB M/W 요청
m_pSession->GetDBConnection()->QueryModSecondarySkillRecipeExp( m_pSession, pRecipe->GetItemSerial(), iAddExp, pRecipe->GetExp() );
return true;
}
bool CSecondarySkillEventHandlerServer::OnManufacture( CSecondarySkill* pSkill, CSecondarySkillRecipe* pRecipe, bool bIsStart )
{
int iRet = ERROR_NONE;
_ASSERT( dynamic_cast<CManufactureSkill*>(pSkill) );
if( bIsStart == false )
{
TSecondarySkillRecipeTableData* pRecipeData = g_pDataManager->GetSecondarySkillRecipeTableData( pRecipe->GetItemID() );
int iRandVal = 0;
#if defined( _GAMESERVER )
_srand( m_pSession->GetGameRoom(), timeGetTime() );
iRandVal = _rand( m_pSession->GetGameRoom() ) % 100;
#else
_srand( timeGetTime() );
iRandVal = _rand() % 100;
#endif // #if defined( _GAMESERVER )
if( iRandVal >= pRecipeData->iSuccessProbability )
iRet = ERROR_SECONDARYSKILL_MANUFACTURE_PROBABILITY_FAILED;
// 재료템 제거
for( int i=0 ; i<_countof(pRecipeData->iMaterialItemID) ; ++i )
{
if( pRecipeData->iMaterialItemID[i] > 0 )
{
_ASSERT( pRecipeData->iMaterialItemCount > 0 );
bool bRet = m_pSession->GetItem()->DeleteInventoryByItemID( pRecipeData->iMaterialItemID[i], pRecipeData->iMaterialItemCount[i], DBDNWorldDef::UseItem::Use );
_ASSERT( bRet );
if( bRet == false )
return false;
}
}
// 아이템 생성
if( iRet == ERROR_NONE )
{
int iCreateItemID = pRecipeData->GetManufactureItemID( pRecipe->GetExp(), pRecipe->GetMaxExp() );
int iCreateItemCount = pRecipeData->iSuccessCount;
TItemData* pItemData = g_pDataManager->GetItemData( iCreateItemID );
if( pItemData && pItemData->nType == ITEMTYPE_INSTANT )
{
#if defined( _GAMESERVER )
CDNGameRoom* pRoom = m_pSession->GetGameRoom();
DnDropItemHandle hDrop = pRoom->GetItemTask()->RequestDropItem( STATIC_INSTANCE_(CDnDropItem::s_dwUniqueCount)++, *(m_pSession->GetActorHandle()->GetPosition()), iCreateItemID, 0, 1, 0 );
_ASSERT( hDrop );
if( !hDrop )
return false;
#else
_ASSERT(0);
return false;
#endif // #if defined( _GAMESERVER )
}
else
{
int iCreateItemRet = m_pSession->GetItem()->CreateInvenItem1( iCreateItemID, iCreateItemCount, 0, 0, DBDNWorldDef::AddMaterializedItem::ItemCompound, 0 );
_ASSERT( iCreateItemRet == ERROR_NONE );
if( iCreateItemRet != ERROR_NONE )
return false;
TItemData *pItemData = g_pDataManager->GetItemData(iCreateItemID);
if (pItemData)
m_pSession->GetEventSystem()->OnEvent( EventSystem::OnItemGain, 2, EventSystem::ItemType, pItemData->nType, EventSystem::ItemCount, m_pSession->GetItem()->GetInventoryItemCountByType(pItemData->nType) );
}
}
int iPlusExp = pRecipeData->iSuccessUpExp;
int iAddExp = iPlusExp;
if (pSkill->GetSubType() == SecondarySkill::SubType::CookingSkill)
CNpcReputationProcessor::CheckAndCalcUnionBenefit( m_pSession, TStoreBenefitData::CookProficiencyUp, iAddExp );
#if defined(PRE_ADD_TOTAL_LEVEL_SKILL)
#if defined(_GAMESERVER)
DnActorHandle hActor = m_pSession->GetActorHandle();
if (hActor &&
hActor->IsAppliedThisStateBlow(STATE_BLOW::BLOW_265) &&
pSkill->GetSubType() == SecondarySkill::SubType::CookingSkill)
{
float fIncRate = 0.0f;
DNVector(DnBlowHandle) vlhBlows;
hActor->GatherAppliedStateBlowByBlowIndex( STATE_BLOW::BLOW_265, vlhBlows );
int iNumBlow = (int)vlhBlows.size();
for( int i = 0; i < iNumBlow; ++i )
{
fIncRate += vlhBlows[i]->GetFloatValue();
}
iAddExp += (int)((float)iAddExp * fIncRate);
}
#elif defined( _VILLAGESERVER )
float fTotalLevel = m_pSession->GetTotalLevelSkillEffect(TotalLevelSkill::Common::CookExpIncrease);
iAddExp += (int)(iAddExp * fTotalLevel);
#endif // _GAMESERVER
#endif // PRE_ADD_TOTAL_LEVEL_SKILL
// 보조 스킬 경험치 적용
pSkill->AddExp( iAddExp, this );
// 클라이언트에 패킷 전송
m_pSession->SendManufactureSecondarySkill( iRet, bIsStart, pRecipe->GetSkillID(), pRecipe->GetItemID() );
// 레시피 경험치 적용
pRecipe->AddExp( pRecipeData->iRecipeUpExp, this );
// Tick 초기화
static_cast<CManufactureSkill*>(pSkill)->ClearManufactureTick();
// Flag 설정
static_cast<CSecondarySkillRepositoryServer*>(m_pSession->GetSecondarySkillRepository())->SetManufacturingFlag( false );
// HeadEffect
m_pSession->BroadcastingEffect( EffectType_Cooking_Finish, EffectState_Success );
return true;
}
else
{
// Tick 저장
static_cast<CManufactureSkill*>(pSkill)->SetManufactureTick( timeGetTime() );
// Flag 해제
static_cast<CSecondarySkillRepositoryServer*>(m_pSession->GetSecondarySkillRepository())->SetManufacturingFlag( true );
// HeadEffect
m_pSession->BroadcastingEffect( EffectType_Cooking_Making, EffectState_Start );
}
// 클라이언트에 패킷 전송
m_pSession->SendManufactureSecondarySkill( iRet, bIsStart, pRecipe->GetSkillID(), pRecipe->GetItemID() );
return true;
}
bool CSecondarySkillEventHandlerServer::OnCancelManufacture( CManufactureSkill* pManufactureSkill, bool bSend )
{
// Flag 해제
static_cast<CSecondarySkillRepositoryServer*>(m_pSession->GetSecondarySkillRepository())->SetManufacturingFlag( false );
// Tick 초기화
pManufactureSkill->ClearManufactureTick();
// HeadEffect
m_pSession->BroadcastingEffect( EffectType_Cooking_Making, EffectState_Cancel );
// 클라이언트에 패킷 전송
if( bSend )
m_pSession->SendCancleManufactureSecondarySkill( ERROR_NONE, pManufactureSkill->GetSkillID() );
return true;
}
#endif // #if defined( PRE_ADD_SECONDARY_SKILL )