Files
Sun1602/Achievement/AchievementPart.cpp
T
2022-10-26 12:25:11 +08:00

399 lines
11 KiB
C++

#include "stdafx.h"
#include "./AchievementPart.h"
//==================================================================================================
// CHANGES: f110526.5L, changes to shared pool each AchievementInfo
namespace util {
;
struct AchievementInfoPool
{
public:
static AchievementInfoPool* Instance();
util::CMemoryPoolFactory<AchievementInfo> info_pool_;
//
private:
AchievementInfoPool()
{
info_pool_.Initialize(20, 20);
};
~AchievementInfoPool()
{
info_pool_.Release();
}
static AchievementInfoPool* CreateInstance();
//
static AchievementInfoPool* instance_static_;
__DISABLE_COPY(AchievementInfoPool);
};
};
util::AchievementInfoPool* util::AchievementInfoPool::instance_static_ = NULL;
util::AchievementInfoPool* util::AchievementInfoPool::CreateInstance()
{
// if the old util::Singleton support interface don't exist, the below code need implements
static struct AutoClosure {
AutoClosure(AchievementInfoPool** static_table) : static_table_(static_table) {
}
~AutoClosure() {
SAFE_DELETE(*static_table_);
}
AchievementInfoPool** static_table_;
} auto_closure(&instance_static_);
//
if (instance_static_ != NULL) {
return instance_static_;
}
//
AchievementInfoPool* provider = new AchievementInfoPool;
// initialization...
instance_static_ = provider;
//
return instance_static_;
}
inline util::AchievementInfoPool* util::AchievementInfoPool::Instance()
{
if (instance_static_ != NULL) {
return instance_static_;
}
return CreateInstance();
}
AchievementInfo* AchievementPart::AllocInfo()
{
return reinterpret_cast<AchievementInfo*>(
util::AchievementInfoPool::Instance()->info_pool_.Alloc());
}
BOOL AchievementPart::FreeInfo(AchievementInfo* delete_pointer)
{
return util::AchievementInfoPool::Instance()->info_pool_.Free(delete_pointer);
};
//==================================================================================================
AchievementPart::AchievementPart(void) : notify_(NULL)
{
parser_ = AchievementParser::Instance();
}
AchievementPart::~AchievementPart(void)
{
ratios_.clear();
infos_.clear();
}
void AchievementPart::Init(AchievementNotify* notify)
{
notify_ = notify;
ratio_sum_ = 0;
show_ratio_ = false;
ACHIEVEMENT_ITER iter = Begin();
for(; iter != End() ; ++iter)
{
iter->second->SetNotifyObject(NULL);
FreeInfo(iter->second);
}
infos_.clear();
ratios_.clear();
#ifdef _SERVER
collect_condition_info_.can_collect_treasurebox_ = false;
BOOST_STATIC_ASSERT(_countof(collect_condition_info_.is_accomplishment_) ==
_countof(collect_condition_info_.condition_) &&
_countof(collect_condition_info_.condition_) ==
Collect_Condition_Accomplishment_Info::MAX_COLLECT_CONDITION);
for(int i = 0 ; i < Collect_Condition_Accomplishment_Info::MAX_COLLECT_CONDITION ; ++i)
{
collect_condition_info_.is_accomplishment_[i] = false;
collect_condition_info_.condition_[i] = 0;
}
#endif
}
AchievementInfo* AchievementPart::AddAchievement(WORD index_number)
{
Achievement_ParserInfo* achievement_parser =
parser_->GetAchievement_ParserInfo(index_number);
if(achievement_parser == NULL)
{
return NULL;
//SUNLOG(eCRITICAL_LOG, "Not Find AchievementParser %u\n", index_number);
}
return AddAchievement(achievement_parser);
}
void AchievementPart::InitAchievement()
{
ACHIEVEMENT_ITER iter = Begin();
for(; iter != End() ; ++iter)
{
iter->second->InitValue();
}
}
AchievementInfo* AchievementPart::AddAchievement(Achievement_ParserInfo* achievement_parser_info)
{
AchievementInfo* achievement_info = AllocInfo();
achievement_info->Init(achievement_parser_info, notify_);
ACHIEVEMENT_RESULT result;
result = infos_.insert(ACHIEVEMENT_MAP::value_type(
achievement_info->GetIndex(), achievement_info));
if(!result.second) return NULL;
if(achievement_parser_info->object_type_ == ACHIEVEMENT_OBJECT_ACCOMPLISHMENT) //달성률 업적
{
ACHIEVEMENT_RESULT result_ptr = ratios_.insert(ACHIEVEMENT_MAP::value_type(
achievement_info->GetIndex(), achievement_info));
}
if(achievement_parser_info->object_type_ == ACHIEVEMENT_OBJECT_ACCOMPLISHMENT || //달성률 모으는 업적이거나
achievement_parser_info->rewards_[0].reward_type_ == ACHIEVEMENT_REWARD_ACCOMPLISHMENT) //달성률 보상이면
{
show_ratio_ = true;
}
return achievement_info;
}
AchievementInfo* AchievementPart::GetAchievement(WORD index_number)
{
ACHIEVEMENT_ITER iter = infos_.find(index_number);
if(iter == infos_.end())
{
return AddAchievement(index_number);
}
return iter->second;
}
bool AchievementPart::SetAchievementValue(WORD index, BYTE object_index,
WORD value , ACHIEVEMENT_VALUE_CHANGE_TYPE type)
{
AchievementInfo* achievement_info = GetAchievement(index);
if(!achievement_info) return false;
if(achievement_info->SetValue(object_index, value, type))
{
#ifdef _SERVER
CheckTreasureBoxCondition(achievement_info, type);
#endif
}
return true;
}
bool AchievementPart::SetAchievementValue(Character_Achievement& char_achievement_info,
ACHIEVEMENT_VALUE_CHANGE_TYPE type)
{
AchievementInfo* achievement_info = GetAchievement(char_achievement_info.index_number_);
if(!achievement_info) return false;
achievement_info->SetValue(char_achievement_info.object_value_, type);
achievement_info->SetReward(char_achievement_info.is_reward_, type);
#ifdef _SERVER
CheckTreasureBoxCondition(achievement_info, type);
#endif
return true;
}
void AchievementPart::InitAccomplishmentRatio()
{
ACHIEVEMENT_ITER iter = Begin();
for(; iter != End() ; ++iter)
{
if(iter->second->IsAccomplishment() && iter->second->IsReward())
{
ratio_sum_ += iter->second->GetAccomplishmentRatio();
}
}
InitAccomplishmentAchievement(ACHIEVEMENT_VALUE_INIT);
}
void AchievementPart::LoadAchievement(WORD& index, Character_Achievements& achievement_info, ACHIEVEMENT_SERIALIZE eType)
{
ACHIEVEMENT_ITER iter = Begin();
for(; iter != End() ; ++iter)
{
//_NA_001990_ACSYSTEM_ADD_INCREASE_INDEX
if(index == MAX_ACHIEVEMENT_COUNT)
return;
if(eType == ACSERIALIZE_CLIENT_LOAD)
{
if(iter->second->IsEmpty())
{
continue;
}
}
else if(eType == ACSERIALIZE_DBPROXY_LOAD)
{
if(!iter->second->IsModification())
{
continue;
}
}
else
{
continue;
}
achievement_info.achievement_info_[index].is_reward_ = iter->second->IsReward();
achievement_info.achievement_info_[index].index_number_ = iter->second->GetIndex();
iter->second->GetValue(achievement_info.achievement_info_[index].object_value_);
index++;
}
}
bool AchievementPart::IsAccomplishment(WORD index)
{
AchievementInfo* achievement_info = GetAchievement(index);
if(!achievement_info) return false;
return achievement_info->IsAccomplishment();
}
bool AchievementPart::RewardAchievement(WORD index_number, bool is_reward)
{
AchievementInfo* achievement_info = GetAchievement(index_number);
if(!achievement_info) return false;
//보상 해도 되는지 확인한다.
if(achievement_info->GetObjectType() == ACHIEVEMENT_OBJECT_ACCOMPLISHMENT)
{
#ifdef _NA_007770_20141103_BUG_AREACONQUEST_REWARD_CHECK
AchievementObjectInfo ac_info = achievement_info->GetObjectInfo(0);
if(ac_info.Achievement_ > ratio_sum_)
return false;
#else
if(achievement_info->GetObjectInfo(0).value_ > ratio_sum_)
return false;
#endif //_NA_007770_20141103_BUG_AREACONQUEST_REWARD_CHECK
}
else
{
if(!achievement_info->IsAccomplishment())
return false;
}
achievement_info->SetReward(is_reward, ACHIEVEMENT_VALUE_SET);
return true;
}
bool AchievementPart::Force_RewardAchievement(WORD index_number, bool is_reward)
{
AchievementInfo* achievement_info = GetAchievement(index_number);
if(!achievement_info) return false;
achievement_info->SetReward(is_reward, ACHIEVEMENT_VALUE_SET);
return true;
}
WORD AchievementPart::AddAccomplishmentRation(WORD accomplishment_ration)
{
ratio_sum_ += accomplishment_ration;
InitAccomplishmentAchievement(ACHIEVEMENT_VALUE_SET);
return ratio_sum_;
}
void AchievementPart::InitAccomplishmentAchievement(ACHIEVEMENT_VALUE_CHANGE_TYPE type)
{
ACHIEVEMENT_ITER iter = ratios_.begin();
for(; iter != ratios_.end() ; ++iter)
{
if(iter->second->GetObjectInfo(0).Achievement_ <= ratio_sum_)
{
iter->second->SetValue(0,
iter->second->GetObjectInfo(0).Achievement_,
type);
//달성률 업적 달성
}
}
}
void AchievementPart::AccomplishAchievement()
{
ACHIEVEMENT_ITER iter = Begin();
for(; iter != End() ; ++iter)
{
if(iter->second->IsAccomplishmentReward() && iter->second->IsAccomplishment())
{
iter->second->SetReward(true, ACHIEVEMENT_VALUE_SET);
}
}
}
#ifdef _SERVER
void AchievementPart::CheckTreasureBoxCondition(AchievementInfo* achievement_info, ACHIEVEMENT_VALUE_CHANGE_TYPE type)
{
if(collect_condition_info_.can_collect_treasurebox_) //이미 보물상자 채취가 가능한 상태이면 비교할 필요 없다.
return;
for(int i = 0 ; i < Collect_Condition_Accomplishment_Info::MAX_COLLECT_CONDITION ; ++ i)
{
if(collect_condition_info_.is_accomplishment_[i])
continue;
if(collect_condition_info_.condition_[i] == achievement_info->GetIndex())
{
if(achievement_info->IsAccomplishment()) //해당 업적이 달성 되었나 ?
{
collect_condition_info_.is_accomplishment_[i] = true;
collect_condition_info_.CalcConditionAccomplish();
if(type != ACHIEVEMENT_VALUE_INIT && collect_condition_info_.can_collect_treasurebox_)
{
//보물상자 채취 상태로 변경되어 통보 한다.
notify_->OnCanCollectTreasureBox();
}
break;
}
}
}
}
void AchievementPart::SetTreasureBoxConditionInfo(Collect_Condition_Info* collect_condition_info)
{
for(int i = 0 ; i < Collect_Condition_Info::MAX_COLLECT_CONDITION ; ++i)
{
collect_condition_info_.condition_[i] = collect_condition_info->condition_[i];
}
}
#endif
#if !defined(_SERVER)
//_SCJ_ACSYSTEM_OVERLAP_PARENT
void AchievementPart::SetAchievementPartParentMap(Achievement* achievement)
{
ACHIEVEMENT_ITER iter = Begin();
for(; iter != End() ; ++iter)
{
iter->second->SetAchievementInfoParentMap(achievement);
}
}
AchievementInfo* AchievementPart::FindAchievementInfoToIndex(WORD index_number)
{
ACHIEVEMENT_ITER iter = infos_.find(index_number);
if(iter == infos_.end())
{
return 0;
}
return iter->second;
}
#endif //!defined(_SERVER)