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

998 lines
28 KiB
C++

#include "Stdafx.h"
#include "GrowingArea.h"
#include "DNFarmGameRoom.h"
#include "DnFarmGameTask.h"
#include "DNUserSession.h"
#include "GrowingAreaStateNone.h"
#include "GrowingAreaStatePlanting.h"
#include "GrowingAreaStateGrowing.h"
#include "GrowingAreaStateCompleted.h"
#include "GrowingAreaStateHarvesting.h"
#include "GrowingAreaStateHarvested.h"
#include "DNDBConnection.h"
#include "DNGameDataManager.h"
#include "DnDropItem.h"
#include "SecondarySkillRepository.h"
#include "SecondarySkill.h"
#include "DNWorldUserState.h"
#include "DNMasterConnectionManager.h"
#include "DNFarmUserSession.h"
#include "DNGameDataManager.h"
#include "DNMissionSystem.h"
#include "TimeSet.h"
#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
#include "DnPlayerActor.h"
#include "DnStateBlow.h"
#endif
CGrowingArea::CGrowingArea( CDNFarmGameRoom* pGameRoom, const int iIndex, SOBB* pOBB, bool bPrivate/*=false*/, INT64 biCharacterDBID/*=0*/ )
:m_pFarmGameRoom(pGameRoom),m_iIndex(iIndex),m_OBB(pOBB?*pOBB:SOBB())
,m_pState(new CFarmAreaStateNone(this)),m_dwStateElapsedTick(0),m_pSeed(NULL)
{
_ASSERT( dynamic_cast<CDnFarmGameTask*>(m_pFarmGameRoom->GetGameTask()) );
m_pFarmGameTask = reinterpret_cast<CDnFarmGameTask*>(m_pFarmGameRoom->GetGameTask());
m_lChangeStateLock = 0;
m_uiRandSeed = 0;
m_bPrivateArea = bPrivate;
m_biPrivateCharacterDBID = biCharacterDBID;
}
CGrowingArea::~CGrowingArea()
{
SAFE_DELETE( m_pState );
SAFE_DELETE( m_pSeed );
}
void CGrowingArea::Process( float fDelta )
{
m_dwStateElapsedTick += static_cast<DWORD>(fDelta*1000);
_DeleteProcess();
m_pState->Process( fDelta );
}
void CGrowingArea::_DeleteProcess()
{
if( m_vDeleteState.empty() )
return;
for( UINT i=0 ; i<m_vDeleteState.size() ; ++i )
delete m_vDeleteState[i];
m_vDeleteState.clear();
}
bool CGrowingArea::CheckPlantItem( CDNUserSession* pSession, CSFarmPlant* pPacket, const TItem*& pItem, const TItem*& pAttachItem )
{
pItem = pAttachItem = NULL;
// žĆŔĚĹŰ °Ëťç
pItem = pSession->GetItem()->GetInventory( pPacket->cSeedInvenIndex );
if( pItem == NULL )
return false;
const TItemData* pItemData = g_pDataManager->GetItemData( pItem->nItemID );
if( pItemData == NULL )
return false;
if( pItemData->nType != ITEMTYPE_SEED )
return false;
TFarmCultivateTableData* pCultivateTable = g_pDataManager->GetFarmCultivateTableData( pItem->nItemID );
if( pCultivateTable == NULL )
return false;
if( pPacket->cCount > 0 )
{
int iItemCount = 0;
for( int i=0 ; i<pPacket->cCount ; ++i )
{
iItemCount += pPacket->AttachItems[i].cCount;
}
// ÇĘżä°łźö ßŊ
if( iItemCount != pCultivateTable->iCatalystCount )
return false;
// ¸đľç žĆŔĚĹŰŔÇ ˝Ă¸ŽžóŔĚ Ć˛ˇÁžßÇŃ´Ů.
std::map<INT64,int> mDuplicate;
for( int i=0 ; i<pPacket->cCount ; ++i )
{
mDuplicate.insert( std::make_pair(pPacket->AttachItems[i].biSerial,0) );
}
if( mDuplicate.size() != pPacket->cCount )
return false;
}
// AttachItem
int iOrgItemID = 0;
for( int i=0 ; i<pPacket->cCount ; ++i )
{
pAttachItem = pSession->GetItem()->GetCashInventory( pPacket->AttachItems[i].biSerial );
if( pAttachItem == NULL )
return false;
if( i == 0 )
{
iOrgItemID = pAttachItem->nItemID;
const TItemData* pAttachItemData = g_pDataManager->GetItemData( pAttachItem->nItemID );
if( pAttachItemData == NULL )
return false;
switch( pAttachItemData->nType )
{
case ITEMTYPE_GROWING_BOOST: // źşŔĺĂËÁřÁŚ
{
break;
}
default:
{
return false;
}
}
}
else
{
// ¸đľç žĆŔĚĹŰŔş °°Ŕş žĆŔĚĹŰID żŠžßÇŃ´Ů.
if( iOrgItemID != pAttachItem->nItemID )
return false;
}
}
// żĎˇáŔĎś§´Â START ŔĎś§ šĚ¸Ž źłÁ¤ÇŘ ľĐ Á¤ş¸żÍ °°ŔşÁö şńąłÇŘşť´Ů.
if( pPacket->ActionType == Farm::ActionType::COMPLETE )
{
if( m_pSeed->GetSeedItemID() != pItem->nItemID )
return false;
#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
int nTotalLevel = pSession->GetintTotalLevelSkillEffect(TotalLevelSkill::Common::GrowingBoost);
if( g_pDataManager->GetItemMainType(nTotalLevel) != ITEMTYPE_GROWING_BOOST )
{
nTotalLevel = 0;
}
if( m_pSeed->GetFirstAttachItemID() != nTotalLevel )
{
if( m_pSeed->GetFirstAttachItemID() != (pAttachItem ? pAttachItem->nItemID : 0) )
return false;
}
#else
if( m_pSeed->GetFirstAttachItemID() != (pAttachItem ? pAttachItem->nItemID : 0) )
return false;
#endif
}
// ş¸Áś˝şĹł °Ëťç
CSecondarySkill* pSecondarySkill = pSession->GetSecondarySkillRepository()->Get( SecondarySkill::SubType::CultivationSkill );
if( pSecondarySkill == NULL )
return false;
if( pCultivateTable->RequiredSkillGrade > pSecondarySkill->GetGrade() )
return false;
if( pCultivateTable->RequiredSkillGrade == pSecondarySkill->GetGrade() )
{
if( pCultivateTable->iRequiredSkillLevel > pSecondarySkill->GetLevel() )
return false;
}
return true;
}
bool CGrowingArea::CheckHarvestItem( CDNUserSession* pSession, CSFarmHarvest* pPacket )
{
// žĆŔĚĹŰ °Ëťç
const TItem* pItem = pSession->GetItem()->GetInventory( pPacket->cNeedItemInvenIndex );
if( pItem == NULL )
return false;
TFarmCultivateTableData* pCultivateTable = g_pDataManager->GetFarmCultivateTableData( m_pSeed->GetSeedItemID() );
if( pCultivateTable == NULL )
return false;
if( pItem->nItemID != pCultivateTable->iHarvestNeedItemID )
return false;
return true;
}
bool CGrowingArea::CheckAddWaterItem( CDNUserSession* pSession, const CSFarmAddWater* pPacket, const TItem*& pItem )
{
pItem = NULL;
// žĆŔĚĹŰ °Ëťç
switch( pPacket->cInvenType )
{
case ITEMPOSITION_INVEN:
{
pItem = pSession->GetItem()->GetInventory( pPacket->cWaterItemInvenIndex );
break;
}
case ITEMPOSITION_CASHINVEN:
{
pItem = pSession->GetItem()->GetCashInventory( pPacket->biWaterItemItemSerial );
break;
}
default:
{
g_Log.Log(LogType::_FARM, pSession, L"CGrowingArea::CheckAddWaterItem Invalid pPacket->cInvenType\n");
return false;
}
}
if( pItem == NULL )
{
g_Log.Log(LogType::_FARM, pSession, L"CGrowingArea::CheckAddWaterItem Invalid pItem\n");
return false;
}
const TItemData* pItemData = g_pDataManager->GetItemData( pItem->nItemID );
if( pItemData == NULL )
{
g_Log.Log(LogType::_FARM, pSession, L"CGrowingArea::CheckAddWaterItem Invalid pItemData\n");
return false;
}
switch( pItemData->nType )
{
case ITEMTYPE_WATER:
case ITEMTYPE_WATERBOTTLE:
{
break;
}
default:
{
g_Log.Log(LogType::_FARM, pSession, L"CGrowingArea::CheckAddWaterItem Invalid pItemData->nType\n");
return false;
}
}
return true;
}
void CGrowingArea::ProcessStartPlant( CDNUserSession* pSession, CSFarmPlant* pPacket )
{
do
{
#if defined( PRE_ADD_VIP_FARM )
#if defined( PRE_ADD_FARM_DOWNSCALE )
if( GetFarmGameRoom()->GetAttr()&Farm::Attr::Vip )
#else
if( GetFarmGameRoom()->GetAttr() == Farm::Attr::Vip )
#endif // #if defined( PRE_ADD_FARM_DOWNSCALE )
{
if( pSession->bIsFarmVip() == false )
{
pSession->SendFarmPlantSeed( ERROR_FARM_INVALID_VIP, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
}
#endif // #if defined( PRE_ADD_VIP_FARM )
#if defined( PRE_ADD_FARM_DOWNSCALE )
if( GetFarmGameRoom()->GetAttr()&Farm::Attr::DownScale && bIsPrivateArea() == false )
{
pSession->SendFarmPlantSeed( ERROR_FARM_CANT_START_PLANTSTATE_DOWNSCALEFARM, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
#endif // #if defined( PRE_ADD_FARM_DOWNSCALE )
if( GetFarmGameRoom()->GetAttr()&Farm::Attr::GuildChampion && bIsPrivateArea() == false )
{
TGuildUID GuildUID = g_pMasterConnectionManager->GetPreWinGuildUID( pSession->GetWorldSetID() );
if( GuildUID.IsSet() == false )
{
pSession->SendFarmPlantSeed( ERROR_GENERIC_MASTERCON_NOT_FOUND, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
if( GuildUID != pSession->GetGuildUID() )
{
pSession->SendFarmPlantSeed( ERROR_FARM_INVALUD_CHAMPIONGUILD, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
}
if( CanStartPlantSeed( pSession ) == false )
break;
if( static_cast<CDNFarmUserSession*>(pSession)->CheckActiveFieldCount() == false )
{
pSession->SendFarmPlantSeed( ERROR_FARM_CANT_START_PLANTSTATE_MAXFIELDCOUNT, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
if( bIsPrivateArea() == true )
{
if( GetFarmGameTask()->CheckActivePrivateFieldCount( pSession ) == false )
{
pSession->SendFarmPlantSeed( ERROR_FARM_CANT_START_PLANTSTATE_MAXPRIVATEFIELDCOUNT, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
}
// žĆŔĚĹŰ °Ëťç
const TItem* pItem;
const TItem* pAttachItem;
if( CheckPlantItem( pSession, pPacket, pItem, pAttachItem ) == false )
break;
m_pSeed = new CPlantSeed( pItem->nItemID, 0, pSession->GetCharacterDBID(), pSession->GetCharacterName() );
if( m_pSeed == NULL || m_pSeed->bIsValid() == false )
break;
if( pAttachItem )
{
if( m_pSeed->CanAttach( pAttachItem, true ) == false )
{
SAFE_DELETE( m_pSeed );
break;
}
m_pSeed->AttachItem( pAttachItem->nItemID );
}
#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
int nTotalLevel = pSession->GetintTotalLevelSkillEffect(TotalLevelSkill::Common::GrowingBoost);
if( g_pDataManager->GetItemMainType(nTotalLevel) == ITEMTYPE_GROWING_BOOST )
{
m_pSeed->AttachItem( nTotalLevel );
}
#endif
if( GetFarmGameRoom()->GetAttr()&Farm::Attr::GuildChampion && bIsPrivateArea() == false )
{
// łŞÁßżĄ źşŔĺĂËÁřÁڰĄ ľéžî
TFarmCultivateTableData* pCultivateData = g_pDataManager->GetFarmCultivateTableData( pItem->nItemID );
if( pCultivateData )
{
__time64_t FinalStartTime = g_pMasterConnectionManager->GetGuildWarFinalStatTime( pSession->GetWorldSetID() );
if( FinalStartTime > 0 )
{
CTimeSet CurTime;
__time64_t tCurTime = CurTime.GetTimeT64_LC();
if( tCurTime+m_pSeed->GetRequiredTimeSec() > FinalStartTime )
{
SAFE_DELETE( m_pSeed );
pSession->SendFarmPlantSeed( ERROR_FARM_CANT_START_PLANTSTATE_GUILDCHAMPION_TIMELIMIT, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
}
}
}
ChangeState( Farm::AreaState::PLANTING );
return;
}while( false );
// żĄˇŻ
pSession->SendFarmPlantSeed( ERROR_FARM_CANT_START_PLANTSTATE, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
}
void CGrowingArea::ProcessCancelPlant( CDNUserSession* pSession, CSFarmPlant* pPacket )
{
if( CanCancelPlantSeed( pSession ) == false )
{
pSession->SendFarmPlantSeed( ERROR_FARM_CANT_CANCEL_PLANTSTATE, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
return;
}
ChangeState( Farm::AreaState::NONE );
}
void CGrowingArea::QueryCompletePlant( CDNUserSession* pSession, CSFarmPlant* pPacket )
{
do
{
if( CanCompletePlantSeed( pSession->GetCharacterDBID() ) == false )
break;
// žĆŔĚĹŰ °Ëťç
const TItem* pItem = NULL;
const TItem* pAttachItem = NULL;
if( CheckPlantItem( pSession, pPacket, pItem, pAttachItem ) == false )
break;
CDNDBConnection* pDBCon = NULL;
BYTE cThreadID;
GetFarmGameRoom()->CopyDBConnectionInfo( pDBCon, cThreadID );
CSecondarySkill* pSecondarySkill = pSession->GetSecondarySkillRepository()->Get( SecondarySkill::SubType::CultivationSkill );
if( pSecondarySkill == NULL )
break;
TSecondarySkillLevelTableData* pTableData = g_pDataManager->GetSecondarySkillLevelTableData( pSecondarySkill->GetSkillID(), pSecondarySkill->GetGrade(), pSecondarySkill->GetLevel() );
if( pTableData == NULL )
break;
#if defined( PRE_ADD_TOTAL_LEVEL_SKILL )
for(int i=0;i<pPacket->cCount;i++)
{
pPacket->AttachItems[i].bRemoveItem = true;
}
int nTotalLevel = pSession->GetintTotalLevelSkillEffect(TotalLevelSkill::Common::GrowingBoost);
if( g_pDataManager->GetItemMainType(nTotalLevel) == ITEMTYPE_GROWING_BOOST )
{
pPacket->AttachItems[pPacket->cCount].biSerial = nTotalLevel;
pPacket->AttachItems[pPacket->cCount].cCount = 1;
pPacket->AttachItems[pPacket->cCount].bRemoveItem = false;
pPacket->cCount++;
}
#endif
static_cast<CFarmAreaStatePlanting*>(m_pState)->SetQueryFlag( true );
if( bIsPrivateArea() == true )
{
pDBCon->QueryAddFieldForCharacter( cThreadID, GetFarmGameRoom()->GetWorldSetID(), pSession->GetAccountDBID(), pSession->GetCharacterDBID(), GetFarmGameRoom()->GetRoomID(), this, pTableData->iParam,
pPacket->cSeedInvenIndex, pItem->nSerial, pPacket, pSession->GetMapIndex(), pSession->GetIpW() );
}
else
{
pDBCon->QueryAddField( cThreadID, pSession, this, pTableData->iParam, pPacket->cSeedInvenIndex, pItem->nSerial, pPacket );
}
return;
}while( false );
pSession->SendFarmPlantSeed( ERROR_FARM_CANT_COMPLETE_PLANTSTATE, pPacket->ActionType, pPacket->iAreaIndex, 0, 0 );
}
void CGrowingArea::ProcessStartHarvest( CDNUserSession* pSession, CSFarmHarvest* pPacket )
{
do
{
if( CanStartHarvest( pSession ) == false )
break;
// žĆŔĚĹŰ °Ëťç
if( CheckHarvestItem( pSession, pPacket ) == false )
break;
ChangeState( Farm::AreaState::HARVESTING, pSession );
return;
}while( false );
// żĄˇŻ
pSession->SendFarmHarvest( ERROR_FARM_CANT_START_HARVESTSTATE, pPacket->ActionType, pPacket->iAreaIndex );
}
void CGrowingArea::ProcessCancelHarvest( CDNUserSession* pSession, CSFarmHarvest* pPacket )
{
if( CanCancelHarvest( pSession ) == false )
{
pSession->SendFarmHarvest( ERROR_FARM_CANT_CANCEL_HARVESTSTATE, pPacket->ActionType, pPacket->iAreaIndex );
return;
}
ChangeState( Farm::AreaState::COMPLETED );
}
#if defined( PRE_ADD_FARM_DOWNSCALE )
void CGrowingArea::QueryCompleteHarvest( CDNUserSession* pSession, CSFarmHarvest* pPacket, bool bAuthHarvest/*=false*/ )
#else
void CGrowingArea::QueryCompleteHarvest( CDNUserSession* pSession, CSFarmHarvest* pPacket )
#endif // #if defined( PRE_ADD_FARM_DOWNSCALE )
{
do
{
#if defined( PRE_ADD_FARM_DOWNSCALE )
if( bAuthHarvest == true )
{
_ASSERT( pSession );
pSession = NULL; // ŔÚľż źöČŽŔĎ ś§ pSession ŔĚ ŔÖŔť źö°Ą žř´Ů. ¸¸žŕŔÇ ťçĹÂ(?)¸Ś ´ëşńÇŘ °­ÁŚ NULL Ăł¸Ž
}
else
{
if( pSession == NULL )
break;
}
if( pSession )
{
if( CanCompleteHarvest( pSession->GetCharacterDBID() ) == false )
break;
// žĆŔĚĹŰ °Ëťç
if( CheckHarvestItem( pSession, pPacket ) == false )
break;
}
#else
if( CanCompleteHarvest( pSession->GetCharacterDBID() ) == false )
break;
// žĆŔĚĹŰ °Ëťç
if( CheckHarvestItem( pSession, pPacket ) == false )
break;
#endif // #if defined( PRE_ADD_FARM_DOWNSCALE )
CDNDBConnection* pDBCon = NULL;
BYTE cThreadID;
GetFarmGameRoom()->CopyDBConnectionInfo( pDBCon, cThreadID );
// žĆŔĚĹŰ ťýźş
TFarmCultivateTableData* pCultivateTable = g_pDataManager->GetFarmCultivateTableData( m_pSeed->GetSeedItemID() );
if( pCultivateTable == NULL )
break;
int iHarvestCount = 1;
int iRandVal = 0;
if( pSession )
iRandVal = (_roomrand(pSession->GetGameRoom())%100)+1;
else
{
CMtRandom Random;
Random.srand( timeGetTime() );
iRandVal = ((Random.rand())%100)+1;
}
int iVal = pCultivateTable->iHarvestDropRate[0];
for( int i=1 ; i<_countof(pCultivateTable->iHarvestDropRate) ; ++i )
{
if( iVal < iRandVal )
++iHarvestCount;
else
break;
iVal += pCultivateTable->iHarvestDropRate[i];
}
std::vector<TItem> vItem;
// żŠąâź­ žĆŔĚĹŰ °čťęÇŘź­ ťőˇç Ăß°ĄÇŘÁŘ´Ů.
for( int i=0 ; i<iHarvestCount ; ++i )
{
int iResultItemID = 0;
int iReulstItemCount = 0;
int iLevel = 1;
int iDepth = ITEMDROP_DEPTH;
#if defined( PRE_ADD_FARM_DOWNSCALE )
CDNUserItem::CalcDropItems( pSession, pCultivateTable->iHarvestDropTableID, iResultItemID, iReulstItemCount, iLevel, iDepth );
#else
pSession->GetItem()->CalcDropItems( pCultivateTable->iHarvestDropTableID, iResultItemID, iReulstItemCount, iLevel, iDepth );
#endif // #if defined( PRE_ADD_FARM_DOWNSCALE )
TItem ResultItem;
if( CDNUserItem::MakeItemStruct( iResultItemID, ResultItem ) == false )
continue;
GetPlantSeed()->PushResultItem( ResultItem.nItemID );
vItem.push_back( ResultItem );
TItemData *pItemData = g_pDataManager->GetItemData(ResultItem.nItemID);
if( pSession && pItemData )
pSession->GetEventSystem()->OnEvent( EventSystem::OnItemGain, 2, EventSystem::ItemType, pItemData->nType, EventSystem::ItemCount, pSession->GetItem()->GetInventoryItemCountByType(pItemData->nType));
}
// żŔŔ×?? ťýźşÇŇ žĆŔĚĹŰŔĚ žřťď?
if( vItem.empty() )
break;
if( m_pState->GetState() == Farm::AreaState::HARVESTING )
static_cast<CFarmAreaStateHarvesting*>(m_pState)->SetQueryFlag( true );
UINT uiAccountDBID = pSession ? pSession->GetAccountDBID() : 0;
INT64 biCharacterDBID = pSession ? pSession->GetCharacterDBID() : 0;
int iMapIndex = pSession ? pSession->GetMapIndex() : 0;
const char* pszIP = pSession ? pSession->GetIp() : "";
if( bIsPrivateArea() == true )
{
pDBCon->QueryHarvestForCharacter( cThreadID, GetFarmGameRoom()->GetWorldSetID(), uiAccountDBID, GetFarmGameRoom()->GetRoomID(), GetIndex(),
GetPlantSeed()->GetOwnerCharacterDBID(), biCharacterDBID, vItem, iMapIndex, pszIP );
}
else
{
pDBCon->QueryHarvest( cThreadID, GetFarmGameRoom()->GetWorldSetID(), uiAccountDBID, GetFarmGameRoom()->GetFarmIndex(), GetFarmGameRoom()->GetRoomID(), GetIndex(),
GetPlantSeed()->GetOwnerCharacterDBID(), biCharacterDBID, vItem, iMapIndex, pszIP );
}
return;
}while( false );
if( pSession )
pSession->SendFarmHarvest( ERROR_FARM_CANT_COMPLETE_HARVESTSTATE, pPacket->ActionType, pPacket->iAreaIndex );
}
void CGrowingArea::ProcessStartAddWater( CDNUserSession* pSession, const CSFarmAddWater* pPacket )
{
do
{
#if defined( PRE_ADD_VIP_FARM )
#if defined( PRE_ADD_FARM_DOWNSCALE )
if( GetFarmGameRoom()->GetAttr()&Farm::Attr::Vip )
#else
if( GetFarmGameRoom()->GetAttr() == Farm::Attr::Vip )
#endif // #if defined( PRE_ADD_FARM_DOWNSCALE )
{
if( pSession->bIsFarmVip() == false )
{
pSession->SendFarmAddWater( ERROR_FARM_INVALID_VIP, pPacket->ActionType, pPacket->iAreaIndex );
return;
}
}
#endif // #if defined( PRE_ADD_VIP_FARM )
// žĆŔĚĹŰ °Ëťç
const TItem* pItem = NULL;
if( CheckAddWaterItem( pSession, pPacket, pItem ) == false )
break;
if( CanStartAddWater( pSession, pItem ) == false )
break;
CFarmAreaStateGrowing* pGrowingState = static_cast<CFarmAreaStateGrowing*>(GetStatePtr());
pGrowingState->StartAddWater( pSession, pPacket );
return;
}while( false );
// żĄˇŻ
pSession->SendFarmAddWater( ERROR_FARM_CANT_START_ADDWATERSTATE, pPacket->ActionType, pPacket->iAreaIndex );
}
void CGrowingArea::ProcessCancelAddWater( CDNUserSession* pSession, const CSFarmAddWater* pPacket )
{
if( CanCancelAddWater( pSession ) == false )
{
pSession->SendFarmAddWater( ERROR_FARM_CANT_CANCEL_ADDWATERSTATE, pPacket->ActionType, pPacket->iAreaIndex );
return;
}
CFarmAreaStateGrowing* pGrowingState = static_cast<CFarmAreaStateGrowing*>(GetStatePtr());
pGrowingState->CancelAddWater( pSession, pPacket );
}
void CGrowingArea::QueryCompleteAddWater( CDNUserSession* pSession, const CSFarmAddWater* pPacket )
{
do
{
if( CanCompleteAddWater( pSession ) == false )
break;
// žĆŔĚĹŰ °Ëťç
const TItem* pItem = NULL;
if( CheckAddWaterItem( pSession, pPacket, pItem ) == false )
break;
CDNDBConnection* pDBCon = NULL;
BYTE cThreadID;
GetFarmGameRoom()->CopyDBConnectionInfo( pDBCon, cThreadID );
static_cast<CFarmAreaStateGrowing*>(m_pState)->QueryAddWater();
if( bIsPrivateArea() == true )
{
pDBCon->QueryAddFieldForCharacterAttachment( cThreadID, pSession->GetWorldSetID(), pSession->GetAccountDBID(), pSession->GetCharacterDBID(), GetFarmGameRoom()->GetRoomID(),
GetIndex(), pItem->nItemID, pPacket->cInvenType, pPacket->cWaterItemInvenIndex, pItem->nSerial, pSession->GetMapIndex(), pSession->GetIpW() );
}
else
{
pDBCon->QueryAddFieldAttachment( cThreadID, pSession, GetFarmGameRoom()->GetFarmIndex(), GetFarmGameRoom()->GetRoomID(), GetIndex(), pItem->nItemID, pPacket->cInvenType, pPacket->cWaterItemInvenIndex, pItem->nSerial );
}
return;
}while( false );
pSession->SendFarmAddWater( ERROR_FARM_CANT_COMPLETE_ADDWATERSTATE, pPacket->ActionType, pPacket->iAreaIndex );
}
void CGrowingArea::ChangeState( Farm::AreaState::eState State, CDNUserSession* pSession/*=NULL*/ )
{
// ŔĚšĚ °°Ŕş State ŔĚ¸é ˝şĹľÇŃ´Ů.
if( m_pState->GetState() == State )
return;
IFarmAreaState* pChangeState = NULL;
switch( State )
{
case Farm::AreaState::NONE:
{
pChangeState = new CFarmAreaStateNone( this );
break;
}
case Farm::AreaState::PLANTING:
{
pChangeState = new CFarmAreaStatePlanting( this );
break;
}
case Farm::AreaState::GROWING:
{
pChangeState = new CFarmAreaStateGrowing( this );
break;
}
case Farm::AreaState::COMPLETED:
{
pChangeState = new CFarmAreaStateCompleted( this );
break;
}
case Farm::AreaState::HARVESTING:
{
pChangeState = new CFarmAreaStateHarvesting( this );
_ASSERT( pSession );
static_cast<CFarmAreaStateHarvesting*>(pChangeState)->SetHarvestInfo( pSession );
break;
}
case Farm::AreaState::HARVESTED:
{
pChangeState = new CFarmAreaStateHarvested( this );
static_cast<CFarmAreaStateHarvested*>(pChangeState)->SetHarvestedInfo( pSession );
break;
}
default:
{
_ASSERT(0);
return;
}
}
IFarmAreaState* pDeleteState = m_pState;
// ChangeState ľżąâČ­
if( InterlockedIncrement( &m_lChangeStateLock ) >= 2 )
{
_ASSERT(0);
SAFE_DELETE( pChangeState );
return;
}
m_pState = pChangeState;
pDeleteState->EndProcess();
m_pState->BeginProcess();
InterlockedDecrement( &m_lChangeStateLock );
// ťčÁŚÇŇ State °´Ăź
m_vDeleteState.push_back( pDeleteState );
// Delta ĂĘąâČ­
m_dwStateElapsedTick = 0;
}
// bResetUpdateTick : °łŔÎłóŔ幸żŞ DB ťóżĄź­ ElapsedTick ŔĚ Áöł­°ćżě Setting
void CGrowingArea::InitializeSeed( const TFarmField* pPacket, bool bResetUpdateTick/*=false*/ )
{
_ASSERT( m_pSeed == NULL );
m_pSeed = new CPlantSeed( pPacket->iItemID, pPacket->iElapsedTimeSec*1000, pPacket->biCharacterDBID, const_cast<WCHAR*>(pPacket->wszCharName) );
for( int i=0 ;i<_countof(pPacket->AttachItems) ; ++i )
{
if( pPacket->AttachItems[i].iItemID > 0 )
{
m_pSeed->ForceAttachItem(pPacket->AttachItems[i].iItemID,pPacket->AttachItems[i].iCount);
}
}
m_pSeed->CalcAttachItem();
m_pSeed->SetDBCreateFlag( true );
if( bResetUpdateTick == true )
m_pSeed->ResetUpdateTick();
IFarmAreaState* pChangeState = NULL;
if( m_pSeed->bIsValid() == false )
{
_ASSERT(0);
SAFE_DELETE( m_pSeed );
pChangeState = new CFarmAreaStateNone( this );
}
else if( m_pSeed->bIsComplete() && bResetUpdateTick == false )
{
pChangeState = new CFarmAreaStateCompleted( this );
}
else
{
pChangeState = new CFarmAreaStateGrowing( this );
}
delete m_pState;
m_pState = pChangeState;
}
void CGrowingArea::DestroySeed()
{
// žžžŃ ĆÄąŤ DB
if( m_pSeed )
{
if( m_pSeed->bIsDBCreate() == true )
{
if( bIsPrivateArea() == true )
GetFarmGameRoom()->GetDBConnection()->QueryDelFieldForCharacter( GetFarmGameRoom()->GetDBThreadID(), GetFarmGameRoom()->GetWorldSetID(), GetOwnerCharacterDBID(), GetFarmGameRoom()->GetRoomID(), GetIndex() );
else
GetFarmGameRoom()->GetDBConnection()->QueryDelField( GetFarmGameRoom()->GetDBThreadID(), GetFarmGameRoom()->GetWorldSetID(), GetFarmGameRoom()->GetFarmIndex(), GetFarmGameRoom()->GetRoomID(), GetIndex() );
}
// FieldCount ľżąâČ­
CDNUserSession* pSession = GetUserSession( m_pSeed->GetOwnerCharacterDBID() );
if( pSession )
pSession->GetDBConnection()->QueryGetFieldCountByCharacter( GetFarmGameRoom()->GetDBThreadID(), GetFarmGameRoom()->GetWorldSetID(), pSession->GetAccountDBID(), pSession->GetCharacterDBID(), true );
else
{
TCommunityLocation Location;
if( g_pWorldUserState->GetUserState( m_pSeed->GetOwnerCharacterDBID(), Location ) == true )
{
if( Location.cServerLocation == _LOCATION_GAME )
{
switch( g_pDataManager->GetMapSubType( Location.nMapIdx ) )
{
case GlobalEnum::eMapSubTypeEnum::MAPSUB_FARM:
{
g_pMasterConnectionManager->SendFarmSync( GetFarmGameRoom()->GetWorldSetID(), m_pSeed->GetOwnerCharacterDBID(), Farm::ServerSyncType::FIELDCOUNT );
break;
}
}
}
}
}
}
SAFE_DELETE( m_pSeed );
SendAreaInfo();
}
void CGrowingArea::MakeAreaInfo( TFarmAreaInfo& Info )
{
memset( &Info, 0, sizeof(Info) );
Info.iAreaIndex = GetIndex();
Info.iRandSeed = GetRandSeed();
Info.State = GetState();
Info.iElapsedTick = GetElapsedStateTick();
if( m_pSeed )
{
Info.iElapsedTick = m_pSeed->GetElapsedTimeSec()*1000;
Info.iItemID = m_pSeed->GetSeedItemID();
m_pSeed->MakeAttachItemInfo( Info );
_wcscpy( Info.wszCharName, _countof(Info.wszCharName), m_pSeed->GetOwnerCharacterName(), (int)wcslen(m_pSeed->GetOwnerCharacterName()) );
}
}
void CGrowingArea::SendAreaInfo()
{
SCAreaInfo TxPacket;
memset( &TxPacket, 0, sizeof(TxPacket) );
MakeAreaInfo( TxPacket.AreaInfo );
int iSize = sizeof(TxPacket)-sizeof(TxPacket.AreaInfo.AttachItems)+TxPacket.AreaInfo.cAttachCount*sizeof(TxPacket.AreaInfo.AttachItems[0]);
if( bIsPrivateArea() == true )
{
CDNUserSession* pSession = GetUserSession( GetOwnerCharacterDBID() );
if( pSession )
{
_wcscpy( TxPacket.AreaInfo.wszCharName, NAMELENMAX, pSession->GetCharacterName(), static_cast<int>(wcslen(pSession->GetCharacterName())) );
pSession->AddSendData( SC_FARM, eFarm::SC_AREAINFO, reinterpret_cast<char*>(&TxPacket), iSize );
}
}
else
GetFarmGameRoom()->BroadCast( SC_FARM, eFarm::SC_AREAINFO, reinterpret_cast<char*>(&TxPacket), iSize );
}
bool CGrowingArea::CanStartPlantSeed( CDNUserSession* pSession )
{
if( m_pState->CanStartPlantSeed() == false )
{
g_Log.Log(LogType::_FARM, pSession, L"CGrowingArea::CanStartPlantSeed() State=%d", m_pState->GetState() );
return false;
}
// ˝Äš°Ŕçšč ˝şĹł °Ëťç
if( pSession->GetSecondarySkillRepository()->Get( SecondarySkill::SubType::CultivationSkill ) == NULL )
return false;
return true;
}
bool CGrowingArea::CanCompletePlantSeed( INT64 biCharacterDBID )
{
// Owner ČŽŔÎ
if( biCharacterDBID != GetOwnerCharacterDBID() )
return false;
return m_pState->CanCompletePlantSeed();
}
bool CGrowingArea::CanCancelPlantSeed( CDNUserSession* pSession )
{
// Owner ČŽŔÎ
if( pSession->GetCharacterDBID() != GetOwnerCharacterDBID() )
return false;
return m_pState->CanCancelPlantSeed();
}
bool CGrowingArea::CanStartHarvest( CDNUserSession* pSession )
{
if( m_pState->CanStartHarvest() == false )
return false;
// ˝Äš°Ŕçšč ˝şĹł °Ëťç
if( pSession->GetSecondarySkillRepository()->Get( SecondarySkill::SubType::CultivationSkill ) == NULL )
return false;
// šüŔ§ °Ëťç
float fDistSq = EtVec3LengthSq( &( *pSession->GetActorHandle()->GetPosition() - m_OBB.Center ) );
if( fDistSq > 40000.0f)
return false;
return true;
}
bool CGrowingArea::CanCancelHarvest( CDNUserSession* pSession )
{
if( m_pState->CanCancelHarvest() == false )
return false;
_ASSERT( dynamic_cast<CFarmAreaStateHarvesting*>(m_pState) );
// HarvestringUser ValidCheck
if( static_cast<CFarmAreaStateHarvesting*>(m_pState)->GetHarvestingCharacterDBID() != pSession->GetCharacterDBID() )
return false;
return true;
}
bool CGrowingArea::CanStartAddWater( CDNUserSession* pSession, const TItem* pItem )
{
if( m_pState->CanStartAddWater() == false )
{
m_pState->RejectReasonLog(L"CanStartAddWater", pSession);
return false;
}
// AttachItem °łźö °Ëťç
if( m_pSeed->CanAttach( pItem, false ) == false )
{
m_pState->RejectReasonLog(L"CanAttach", pSession);
return false;
}
// ˝Äš°Ŕçšč ˝şĹł °Ëťç
if( pSession->GetSecondarySkillRepository()->Get( SecondarySkill::SubType::CultivationSkill ) == NULL )
{
m_pState->RejectReasonLog(L"CultivationSkill is NULL", pSession);
return false;
}
return true;
}
bool CGrowingArea::CanCancelAddWater( CDNUserSession* pSession )
{
if( m_pState->CanCancelAddWater( pSession ) == false )
return false;
return true;
}
bool CGrowingArea::CanCompleteAddWater( CDNUserSession* pSession )
{
return m_pState->CanCompleteAddWater( pSession );
}
bool CGrowingArea::CanCompleteHarvest( INT64 biCharacterDBID )
{
if( m_pState->CanCompleteHarvest() == false )
return false;
_ASSERT( dynamic_cast<CFarmAreaStateHarvesting*>(m_pState) );
// HarvestringUser ValidCheck
if( static_cast<CFarmAreaStateHarvesting*>(m_pState)->GetHarvestingCharacterDBID() != biCharacterDBID )
return false;
return true;
}
CDNUserSession* CGrowingArea::GetUserSession( INT64 biCharacterDBID )
{
return m_pFarmGameRoom->GetUserSessionByCharDBID( biCharacterDBID );
}
UINT CGrowingArea::GetRandSeed()
{
if( GetPlantSeed() == NULL )
{
m_uiRandSeed = 0;
return m_uiRandSeed;
}
if( m_uiRandSeed == 0 )
{
m_uiRandSeed = _roomrand( GetFarmGameRoom() );
}
return m_uiRandSeed;
}