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

385 lines
11 KiB
C++

#include "StdAfx.h"
#include ".\AchievementInfo.h"
#include "Achievement.h"
AchievementInfo::AchievementInfo() : notify_(NULL) , status_(EMPTY), is_reward_(false)
{
}
AchievementInfo::~AchievementInfo(void)
{
}
bool AchievementInfo::IsAccomplishment() const
{
for(int i = 0 ; i < MAX_ACHIEVEMENT_OBJECT ; ++i)
{
//_NA_001990_ACSYSTEM_ADD
//미션 클리어 타임 ac는 설정된 값보다 작으면 성공이다
if (object_type_ == ACHIEVEMENT_OBJECT_MISSION_CLEAR_TIME)
{
if (obejct_value_[i].Achievement_ != 0)
{
if ((obejct_value_[i].Achievement_ < obejct_value_[i].value_) ||
(obejct_value_[i].value_ == 0))
{
return false;
}
}
}
else if (obejct_value_[i].Achievement_ > obejct_value_[i].value_)
{
return false;
}
}
return true;
}
bool AchievementInfo::IsAccomplishment(BYTE object_index)
{
//_NA_001990_ACSYSTEM_ADD
//미션 클리어 타임은 설정된 값보다 작으면 성공이다
if (object_type_ == ACHIEVEMENT_OBJECT_MISSION_CLEAR_TIME)
{
if (obejct_value_[object_index].Achievement_ != 0)
{
if ((obejct_value_[object_index].Achievement_ < obejct_value_[object_index].value_) ||
(obejct_value_[object_index].value_ == 0))
{
return false;
}
}
}
else if (obejct_value_[object_index].Achievement_ > obejct_value_[object_index].value_)
{
return false;
}
return true;
}
WORD AchievementInfo::GetAccomplishmentRatio()
{
WORD accomplishment_ratio = 0;
for(int i = 0 ; i < MAX_ACHIEVEMENT_REWARD ; ++i)
{
if(rewards_[i].reward_type_ == ACHIEVEMENT_REWARD_ACCOMPLISHMENT)
{
if(IsAccomplishment(0))
{
accomplishment_ratio += rewards_[i].reward_code_;
}
}
}
return accomplishment_ratio;
}
bool AchievementInfo::IsAccomplishmentReward()
{
for(int i = 0 ; i < MAX_ACHIEVEMENT_REWARD ; ++i)
{
if(rewards_[i].reward_type_ == ACHIEVEMENT_REWARD_ACCOMPLISHMENT)
return true;
}
return false;
}
void AchievementInfo::InitValue()
{
for(int i = 0 ; i < MAX_ACHIEVEMENT_OBJECT ; ++i)
{
SetValue(i,0,ACHIEVEMENT_VALUE_SET);
}
SetReward(false, ACHIEVEMENT_VALUE_SET);
}
void AchievementInfo::Init(Achievement_ParserInfo* achievement_parser_info, AchievementNotify* notify)
{
status_ = EMPTY; // CHANGES: f110613.3L
notify_ = notify;
index_number_ = achievement_parser_info->index_;
is_reward_ = false;
location_code_ = achievement_parser_info->location_code_;
object_type_ = achievement_parser_info->object_type_;
//_NA_001990_ACSYSTEM_ADD
class_type_ = achievement_parser_info->class_type_;
for(int i = 0 ; i < MAX_ACHIEVEMENT_PARENT_CODE ; ++i)
{
parent_ac_code_[i] = achievement_parser_info->parent_ac_code_[i];
}
#if !defined(_SERVER)
object_string_code_ = achievement_parser_info->object_string_code_;
tooltip_string_code_ = achievement_parser_info->tooltip_string_code_;
icon_code_ = achievement_parser_info->icon_code_;
parent_ac_map_.clear();
child_ac_map_.clear();
#endif
for(int i = 0 ; i < MAX_ACHIEVEMENT_REWARD ; ++i)
{
rewards_[i].reward_type_ = achievement_parser_info->rewards_[i].reward_type_;
rewards_[i].reward_code_ = achievement_parser_info->rewards_[i].reward_code_;
}
for(int i = 0 ; i < MAX_ACHIEVEMENT_OBJECT ; ++i)
{
obejct_value_[i].Achievement_ = achievement_parser_info->obejcts_[i].object_number_;
obejct_value_[i].value_ = 0;
}
}
bool AchievementInfo::SetValue(BYTE object_index, WORD object_value, ACHIEVEMENT_VALUE_CHANGE_TYPE type)
{
if(type == ACHIEVEMENT_VALUE_APPEND)
{
object_value += obejct_value_[object_index].value_;
}
//값이 달성수치보다 큰가 ?
//_NA_001990_ACSYSTEM_ADD
if (( object_type_ != ACHIEVEMENT_OBJECT_MISSION_CLEAR_TIME ) &&
object_value > obejct_value_[object_index].Achievement_ )
{
object_value = obejct_value_[object_index].Achievement_;
}
if(obejct_value_[object_index].value_ != object_value)
{
if(type != ACHIEVEMENT_VALUE_INIT)
{
NotifyChangedValue(object_index, obejct_value_[object_index].value_, object_value);
}
else
{
if(status_ == EMPTY)
{
status_ = NORMAL;
}
}
obejct_value_[object_index].value_ = object_value;
//값 변경이 있으면 true 를 리턴한다.
return true;
}
return false;
}
void AchievementInfo::SetValue(WORD object_value[MAX_ACHIEVEMENT_OBJECT], ACHIEVEMENT_VALUE_CHANGE_TYPE type)
{
for(BYTE i = 0 ; i < MAX_ACHIEVEMENT_OBJECT ; ++i)
{
SetValue(i, object_value[i], type);
}
}
void AchievementInfo::GetValue(WORD object_value[MAX_ACHIEVEMENT_OBJECT])
{
for(BYTE i = 0 ; i < MAX_ACHIEVEMENT_OBJECT ; ++i)
{
object_value[i] = obejct_value_[i].value_;
}
}
void AchievementInfo::SetReward(bool reward_value, ACHIEVEMENT_VALUE_CHANGE_TYPE type)
{
if(is_reward_ != reward_value)
{
is_reward_ = reward_value;
if(type != ACHIEVEMENT_VALUE_INIT)
{
Notifyreward(reward_value, RC::RC_AC_SUCCESS);
}
else
{
if(status_ == EMPTY)
{
status_ = NORMAL;
}
}
}
}
void AchievementInfo::NotifyChangedValue(BYTE object_index, WORD previous_value, WORD current_value)
{
status_ = MODIFICATION;
if(notify_ != NULL)
{
notify_->OnValueChanged(index_number_, location_code_, object_index, previous_value, current_value);
}
}
void AchievementInfo::Notifyreward(bool is_reward, RC::eAC_RESULT rc)
{
status_ = MODIFICATION;
if(notify_ != NULL)
{
notify_->Onreward(index_number_, location_code_, rewards_, is_reward, rc);
}
}
#if !defined(_SERVER)
//_SCJ_ACSYSTEM_OVERLAP_PARENT
void AchievementInfo::SetAchievementInfoParentMap(Achievement* achievement)
{
// 디테일 정보에 출력할 선행과제들의 제목스트일 리스트를 만든다.
SetParentMap(achievement);
// 자신을 선행으로 가진 과제의 목록을 만든다.
SetChildMap(achievement);
}
void AchievementInfo::SetParentMap(Achievement* achievement)
{
// 선행과제의 선행과제를 타고 들어가면서 가져와 쌓는다.
parent_ac_map_.clear();
int depth = 0;
MakeParentMap(achievement, &parent_ac_map_, depth);
ACHIEVEMENT_INFO_MAP_ITER map_iter = parent_ac_map_.find(GetIndex());
if (map_iter != parent_ac_map_.end())
{
assert(!"선행과제 리스트 설정중에 자신이 리스트에 포함되었습니다.\nACScript.txt를 확인해 주세요");
parent_ac_map_.erase(map_iter);
}
}
void AchievementInfo::MakeParentMap(Achievement* achievement, ACHIEVEMENT_INFO_MAP* map_pointer, int depth)
{
// recursive call
if (map_pointer == NULL)
{
return;
}
if (depth >= PARENT_LIMIT_DEPTH)
{
#ifdef _NA_008226_AC_PARENTMAP_LIST_SKIP
assert(!"ac과제 Parent 맵을 만들던 중 깊이가 100이상 증가하였습니다. 의도인지 확인해주세요");
#else
assert(!"ac과제 Parent 맵을 만들던 중 깊이가 30이상 증가하였습니다. 의도인지 확인해주세요");
#endif //#ifdef _NA_008226_AC_PARENTMAP_LIST_SKIP
return;
}
for (int index = 0; index < MAX_ACHIEVEMENT_PARENT_CODE; ++index)
{
DWORD parent_code = parent_ac_code_[index];
if (parent_code == 0)
{
return;
}
// 인덱스로 Info 탐색
AchievementInfo* achievement_info = achievement->FindAchievementToIndex(parent_code);
if (achievement_info)
{
ACHIEVEMENT_INFO_MAP_ITER map_iter = map_pointer->find(parent_code);
if (map_iter == map_pointer->end())
{
map_pointer->insert(
ACHIEVEMENT_INFO_MAP::value_type(parent_code, achievement_info));
//해당 Info 에 다시 선행코드가 있는지보고 재귀호출시킴 recursive call
achievement_info->MakeParentMap(achievement, map_pointer, depth + 1);
}
}
}
}
void AchievementInfo::SetChildMap(Achievement* achievement)
{
// 선행코드가 있으면 선행코드의 AchievementInfo로 찾아가 해당 AchievementInfo의 피선행과제를 나로 지정한다.
for (int i = 0; i < MAX_ACHIEVEMENT_PARENT_CODE; ++i)
{
if (parent_ac_code_[i] == 0)
{
return;
}
// 인덱스로 AchievementInfo탐색
AchievementInfo* achievement_info = achievement->FindAchievementToIndex(parent_ac_code_[i]);
if (achievement_info)
{
// 해당 AchievementInfo 에 내 인덱스 설정
achievement_info->AddChildMap(this);
}
}
}
void AchievementInfo::AddChildMap(AchievementInfo* achievement_info)
{
child_ac_map_.insert(
ACHIEVEMENT_INFO_MAP::value_type(achievement_info->GetIndex(), achievement_info));
}
bool AchievementInfo::IsShowRewardToParentMap()
{
//2011.12.2 보상버튼이 보일땐 목록을 숨기지 않도록 수정되면서 해당 함수는 사용하지 않게됨.
// 선행과제 포함해서 보상버튼 보일지
if ((IsAccomplishment() == true) &&
(IsReward() == false))
{
return true;
}
ACHIEVEMENT_INFO_MAP_ITER parent_map_iter = parent_ac_map_.begin();
ACHIEVEMENT_INFO_MAP_ITER parent_map_iter_end = parent_ac_map_.end();
for(; parent_map_iter != parent_map_iter_end; ++parent_map_iter)
{
// 여기에 왔다는건 선행과제들이 완료가 되있다는 것이므로 완료체크는 생략
if ((*parent_map_iter).second->IsReward() == false)
{
return true;
}
}
return false;
}
AchievementInfo* AchievementInfo::GetRewardToParentMap()
{
//2011.12.2 보상버튼이 보일땐 목록을 숨기지 않도록 수정되면서 해당 함수는 사용하지 않게됨.
// 선행과제 포함해서 보상받을 과제
AchievementInfo* reward_ac_info = NULL;
if ((IsAccomplishment() == true) &&
(IsReward() == false))
{
reward_ac_info = this;
}
ACHIEVEMENT_INFO_MAP_ITER parent_map_iter = parent_ac_map_.begin();
ACHIEVEMENT_INFO_MAP_ITER parent_map_iter_end = parent_ac_map_.end();
for(; parent_map_iter != parent_map_iter_end; ++parent_map_iter)
{
// 여기에 왔다는건 선행과제들이 완료가 되있다는 것이므로 완료체크는 생략
if ((*parent_map_iter).second->IsReward() == false)
{
// 인덱스가 낮은게 우선순위 높다.
if ((reward_ac_info == NULL) ||
((*parent_map_iter).first < reward_ac_info->GetIndex()))
{
reward_ac_info = (*parent_map_iter).second;
}
}
}
assert((reward_ac_info != NULL) && "보상이 없다");
return reward_ac_info;
}
#endif //!defined(_SERVER)
bool AchievementInfo::_Sort_Index(AchievementInfo*& info_left, AchievementInfo*& info_right)
{
return (info_left->GetIndex() < info_right->GetIndex());
}
const AchievementObjectInfo* const AchievementInfo::GetAchievementObjectFormIndex( BYTE object_index )
{
return &obejct_value_[object_index];
}