Files
Sun1602/Server/GameServer/MissionRewardManager.cpp
T
2022-10-26 12:25:11 +08:00

401 lines
12 KiB
C++

#include "stdafx.h"
#include "MissionManager.h"
#include "MissionRewardManager.h"
#include "ItemInfoParser.h"
#include "ItemManager.h"
#include <SCItemSlotContainer.h>
#include "Player.h"
#include "TriggerManagerEx.h"
#include <../ProgramCommon/BattleGroundInfoParser.h>
SLOTCODE MissionRewardManager::rewardItemCode[MAX_INVENTORY_SLOT_NUM];
POSTYPE MissionRewardManager::rewardItemNum[MAX_INVENTORY_SLOT_NUM];
BYTE MissionRewardManager::GetTypeOfMissionPoint( )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo::sCLASS::sREWARD *pREWARD, *pCurr;
if( rMRA.GetMissionRewardInfoClassCode() == NULL )
GetMissionRewardInfoNClassCode();
pREWARD = pCurr = rMRA.GetMissionRewardInfoClassCode()->REWARDs;
if( rMRA.GetMissionPoint() > 0 )
{
DWORD nextIDX = 1;
for( DWORD i=0 ; i<MissionRewardInfo::MISSION_REWARD_MAX_SIZE ; ++i )
{
if( rMRA.GetMissionPoint() >= (WORD)pCurr[i].m_bMissionNum )
{
bool bOK = (MissionRewardInfo::MISSION_REWARD_MAX_SIZE != nextIDX) ?
(rMRA.GetMissionPoint() < pCurr[nextIDX].m_bMissionNum) : true;
if( bOK )
return (BYTE)i;
pREWARD = &pCurr[nextIDX++];
continue;
}
}
}
return MissionRewardInfo::MISSION_REWARD_MAX_SIZE;
}
WORD MissionRewardManager::GetRewardCode( BOOL bPreUpdate )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo::sCLASS::sREWARD *pREWARD, *pCurr;
if( rMRA.GetMissionRewardInfoClassCode() == NULL )
{
if( GetMissionRewardInfoNClassCode() == NULL )
return (WORD)0xFFFF;
}
pREWARD = pCurr = rMRA.GetMissionRewardInfoClassCode()->REWARDs;
WORD wMissionPoint = rMRA.GetMissionPoint() + (bPreUpdate ? 1 : 0);
if( wMissionPoint > 0 )
{
DWORD nextIDX = 1;
for(int i = 0; i < MissionRewardInfo::MISSION_REWARD_MAX_SIZE; ++i)
{
WORD wMPoint = (WORD)pCurr[i].m_bMissionNum;
if( wMPoint && (wMissionPoint >= wMPoint) )
{
bool bOK = (MissionRewardInfo::MISSION_REWARD_MAX_SIZE != nextIDX) ?
(wMissionPoint < pCurr[nextIDX].m_bMissionNum) : true;
if( bOK )
return pREWARD->m_wRewardCode;
pREWARD = &pCurr[nextIDX++];
continue;
}
else
{ // wMPoint가 0인 경우에는 무한대로 설정하자.
if( !wMPoint )
{
if(i > 0)
return pCurr[i - 1].m_wRewardCode;
FlowControl::FCAssert(!"i <= 0");
}
}
}
}
return (WORD)0xFFFF;
}
// m_MissionRewardInfo 정보에 의거 계산된다.
MissionRewardInfo* MissionRewardManager::GetMissionRewardInfoNClassCode()
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
eCHAR_TYPE type = rMRA.GetPlayer()->GetCharType();
MissionRewardParser* pParser = MissionRewardParser::Instance();
MissionRewardInfo* pMRI = pParser->GetMissionReward( rMRA.GetNum() );
if( pMRI )
{
rMRA.SetMissionPoint( rMRA.GetMissionManager()->GetMissionPoint(rMRA.GetNum()) );
MissionRewardInfo::sCLASS* pCLASS = &(pMRI->CLASSs[type]);
ASSERT( pCLASS->m_bClassCode == type );
rMRA.SetMissionRewardInfoClassCode( pCLASS );
}
return pMRI;
}
// m_MissionRewardInfo 정보에 의거 계산된다.
RC::eREWARD_RESULT MissionRewardManager::RewardItem( INVENTORY_TOTAL_INFO& OUT rInvenInfo )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo* pMRI = GetMissionRewardInfoNClassCode();
return RewardItem( rMRA.GetMissionRewardInfoClassCode(), rInvenInfo );
}
// m_MissionRewardInfo 정보에 의거 계산된다.
RC::eREWARD_RESULT MissionRewardManager::RewardExp( EXPTYPE* OUT pExp )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo* pMRI = GetMissionRewardInfoNClassCode();
return RewardExp( rMRA.GetMissionRewardInfoClassCode(), pExp );
}
// m_MissionRewardInfo 정보에 의거 계산된다.
RC::eREWARD_RESULT MissionRewardManager::RewardHime( MONEY* OUT pMoney )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo* pMRI = GetMissionRewardInfoNClassCode();
return RewardHime( rMRA.GetMissionRewardInfoClassCode(), pMoney );
}
// m_MissionRewardInfo 정보에 의거 계산된다.
RC::eREWARD_RESULT MissionRewardManager::RewardExp( const MissionRewardInfo::sCLASS* IN pMRIclass, EXPTYPE* OUT pExp )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo::sCLASS::sREWARD *pREWARD, *pCurr;
if( rMRA.GetMissionRewardInfoClassCode() == NULL )
{
if( GetMissionRewardInfoNClassCode() == NULL )
return RC::RC_REWARD_FAILED;
}
pREWARD = pCurr = rMRA.GetMissionRewardInfoClassCode()->REWARDs;
if( ((DWORD)(__int64)pREWARD)<4000 )
{
ASSERT( 0 && "뚫렸다!" );
return RC::RC_REWARD_FAILED;
}
if( rMRA.GetMissionPoint() > 0 )
{
DWORD nextIDX = 1;
for(int i = 0; i < MissionRewardInfo::MISSION_REWARD_MAX_SIZE; ++i)
{
WORD wMPoint = (WORD)pCurr[i].m_bMissionNum;
if( wMPoint && (rMRA.GetMissionPoint() >= wMPoint) )
{
bool bOK = (MissionRewardInfo::MISSION_REWARD_MAX_SIZE != nextIDX) ?
(rMRA.GetMissionPoint() < pCurr[nextIDX].m_bMissionNum) : true;
if( bOK )
{
WORD wExpRatio = rMRA.GetPlayer()->GetFatigueManager()->GetExpRewardRatio();
#ifdef _NA_20081121_ABUMAN_NIJOT_EVENT
// 현재 이벤트 중이면
SunEventInfoParser* const pSunEventInfoParser = SunEventInfoParser::Instance();
EVENT_INFO* const pEventInfo = pSunEventInfoParser->FindEventInfoFromMode( eEVENT_GUILD_MISSION_EVENT );
//현재 이벤트 중이고, 길드 클리어 했으면.
if( pEventInfo && pEventInfo->CheckEvent() && rMRA.GetPlayer()->GetMissionManager()->IsGuildEvent() )
{
#ifndef _DEBUG
BOOST_STATIC_WARNING(false); // TODO: is valid calculation?
#endif
wExpRatio += pEventInfo->m_fRewardExpRate*100;
}
#endif
//_KR_0_20091021_FIRENDINVITATION_EXTEND //미션 보상에 경험치 증가시키기
GameField* const field = rMRA.GetPlayer()->GetField();
if(field)
{
wExpRatio += rMRA.GetPlayer()->GetInvitateFriend().GetAddMissionExpRate(field->GetFieldCode());
}
return g_RewardManager.RewardExp( pREWARD->m_wRewardCode, rMRA.GetPlayer(), *pExp, wExpRatio );
}
pREWARD = &pCurr[nextIDX++];
continue;
}
else
{ // wMPoint가 0인 경우에는 무한대로 설정하자.
if( !wMPoint )
{
if(i > 0) {
WORD wExpRatio = rMRA.GetPlayer()->GetFatigueManager()->GetExpRewardRatio();
return g_RewardManager.RewardExp( pCurr[i-1].m_wRewardCode, rMRA.GetPlayer(), *pExp, wExpRatio );
}
FlowControl::FCAssert(!"i <= 0");
}
}
}
}
return RC::RC_REWARD_FAILED;
}
// m_MissionRewardInfo 정보에 의거 계산된다.
RC::eREWARD_RESULT MissionRewardManager::RewardHime( const MissionRewardInfo::sCLASS* IN pMRIclass, MONEY* OUT pMoney )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo::sCLASS::sREWARD *pREWARD, *pCurr;
if( rMRA.GetMissionRewardInfoClassCode() == NULL )
{
if( GetMissionRewardInfoNClassCode() == NULL )
return RC::RC_REWARD_FAILED;
}
pREWARD = pCurr = rMRA.GetMissionRewardInfoClassCode()->REWARDs;
if( ((DWORD)(__int64)pREWARD)<4000 )
{
ASSERT( 0 && "뚫렸다!" );
return RC::RC_REWARD_FAILED;
}
if( rMRA.GetMissionPoint() > 0 )
{
DWORD nextIDX = 1;
for(int i = 0; i < MissionRewardInfo::MISSION_REWARD_MAX_SIZE; ++i)
{
WORD wMPoint = (WORD)pCurr[i].m_bMissionNum;
if( wMPoint && (rMRA.GetMissionPoint() >= wMPoint) )
{
bool bOK = (MissionRewardInfo::MISSION_REWARD_MAX_SIZE != nextIDX) ?
(rMRA.GetMissionPoint() < pCurr[nextIDX].m_bMissionNum) : true;
if( bOK )
{
BYTE byHeimRatio = rMRA.GetPlayer()->GetFatigueManager()->GetHeimRewardRatio();
return g_RewardManager.RewardHime( pREWARD->m_wRewardCode, rMRA.GetPlayer(), *pMoney, byHeimRatio );
}
pREWARD = &pCurr[nextIDX++];
continue;
}
else
{ // wMPoint가 0인 경우에는 무한대로 설정하자.
if( !wMPoint )
{
if(i > 0) {
BYTE byHeimRatio = rMRA.GetPlayer()->GetFatigueManager()->GetHeimRewardRatio();
return g_RewardManager.RewardHime( pCurr[i-1].m_wRewardCode, rMRA.GetPlayer(), *pMoney, byHeimRatio );
}
FlowControl::FCAssert(!"i <= 0");
}
}
}
}
return RC::RC_REWARD_FAILED;
}
// m_MissionRewardInfo 정보에 의거 계산된다.
RC::eREWARD_RESULT MissionRewardManager::RewardItem( const MissionRewardInfo::sCLASS* IN pMRIclass, INVENTORY_TOTAL_INFO& OUT rInvenInfo )
{
MissionRewardArgs& rMRA = GetMissionRewardArgs();
MissionRewardInfo::sCLASS::sREWARD *pREWARD, *pCurr;
if( rMRA.GetMissionRewardInfoClassCode() == NULL )
{
if( GetMissionRewardInfoNClassCode() == NULL )
return RC::RC_REWARD_FAILED;
}
if( rMRA.GetPlayer()->GetFatigueManager()->GetItemReward() == FALSE )
{
rInvenInfo.m_InvenCount = 0;
rInvenInfo.m_TmpInvenCount = 0;
return RC::RC_REWARD_SUCCESS; // 보상받지 못하는 피로시간이면, 성공으로 리턴해서 하임과 경험치를 얻게 한다.
}
pREWARD = pCurr = rMRA.GetMissionRewardInfoClassCode()->REWARDs;
if( ((DWORD)(__int64)pREWARD)<4000 )
{
ASSERT( 0 && "뚫렸다!" );
return RC::RC_REWARD_FAILED;
}
if( rMRA.GetMissionPoint() > 0 )
{
DWORD nextIDX = 1;
for(int i = 0; i < MissionRewardInfo::MISSION_REWARD_MAX_SIZE; ++i)
{
WORD wMPoint = (WORD)pCurr[i].m_bMissionNum;
if( wMPoint && (rMRA.GetMissionPoint() >= wMPoint) )
{
bool bOK = (MissionRewardInfo::MISSION_REWARD_MAX_SIZE != nextIDX) ?
(rMRA.GetMissionPoint() < pCurr[nextIDX].m_bMissionNum) : true;
if( bOK )
return g_RewardManager.RewardItem( RewardManager::eREWARD_MISSION, pREWARD->m_wRewardCode, rMRA.GetSelectedItem(), rMRA.GetPlayer(), rInvenInfo );
pREWARD = &pCurr[nextIDX++];
continue;
}
else
{ // wMPoint가 0인 경우에는 무한대로 설정하자.
if( !wMPoint )
{
if(i > 0)
return g_RewardManager.RewardItem( RewardManager::eREWARD_MISSION, pCurr[i-1].m_wRewardCode, rMRA.GetSelectedItem(), rMRA.GetPlayer(), rInvenInfo );
FlowControl::FCAssert(!"i <= 0");
}
}
}
}
return RC::RC_REWARD_FAILED;
}
//_NA_008679_20160202_REWORK_BATTLEGROUND
BOOL MissionRewardManager::RewardBattlegroundMember( Player* const player, const ZONEKEY& zone_key,
const MAPCODE& battleground_mapcode,
const eBATTLEGROUND_RESULT& result_type )
{
MissionManager* const mission_manager = player->GetMissionManager();
mission_manager->CheckEnableWindowOpen(); // 그럴리 없다고 단정지어진 것이지만, 중복된 보상이 존재할 경우를 대비
if (mission_manager->EnableWindowOpen())
{
TriggerManagerEx::Check_RewardWindow(player, true);
return FALSE;
}
const BattleGroundInfo* battle_ground_info =
BattleGroundInfoParser::Instance()->FindData(battleground_mapcode);
DWORD reward_index = 0;
switch(result_type)
{
case eBG_RESULT_WIN:
reward_index = battle_ground_info->win_reward_code;
break;
case eBG_RESULT_DRAW:
case eBG_RESULT_LOSE:
reward_index = battle_ground_info->base_reward_code;
break;
case eBG_RESULT_ABUSE:
reward_index = battle_ground_info->penalty_reward_code;
break;
#ifdef _NA_008679_20160202_REWORK_BATTLEGROUND
case eBG_RESULT_MISMATCHING:
reward_index = battle_ground_info->mismatch_reward_code;
break;
#endif //_NA_008679_20160202_REWORK_BATTLEGROUND
}
if (!reward_index || !(reward_index < (DWORD)MAX_MISSION_NUM))
{
return FALSE;
}
const DWORD mission_point = mission_manager->GetMissionPoint(reward_index);
printf("BattleGroundTeam::_OnReward :User [%u] MissonNumber[%u], MissionPoint[%u]\n",
player->GetUserKey(), reward_index, mission_point);
MissionRewardManager* reward_manager = MissionRewardManager::Instance();
reward_manager->Init();
MissionRewardArgs& mission_reward_args = reward_manager->GetMissionRewardArgs();
mission_reward_args.SetPlayer(player);
mission_reward_args.SetMissionManager(mission_manager);
mission_reward_args.SetNum(reward_index);
const WORD reward_code = reward_manager->GetRewardCode(true);
ASSERT(0xFFFF != reward_code);
if (0xFFFF != reward_code)
{
MSG_CG_TRIGGER_REWARD_WINDOW_CMD cmsg;
cmsg.m_RewardCode = reward_code;
player->SendPacket(&cmsg, sizeof(cmsg));
}
mission_manager->SetMissionState(reward_index, MISSION_REWARD);
mission_manager->SetMissionPoint(reward_index, mission_point + 1);
return TRUE;
}