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

954 lines
34 KiB
C++

#include "stdafx.h"
#define PROGRAMCOMMON_ITEM_ATTR_CALCULATOR_INTER_UTIL
#include "./ItemAttrCalculator_Util.hxx"
#undef PROGRAMCOMMON_ITEM_ATTR_CALCULATOR_INTER_UTIL
#if defined(_NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT)
namespace ns_formula {
;
}; //end of namespace
//==================================================================================================
Attributes::OperationRecord* ns_formula::ItemAttrContext::BeginRecord()
{
assert(working_record == NULL);
if (static_cast<size_t>(workable_it - begin_it) >=
static_cast<size_t>(end_it - begin_it))
{
assert(!"index out of ranges");
return NULL;
};
Attributes::OperationRecord* empty_record = workable_it;
ZeroMemory(empty_record, sizeof(*empty_record));
working_record = empty_record;
return empty_record;
}
bool ns_formula::ItemAttrContext::CommitRecord()
{
if (working_record == NULL) {
assert(!"this record must be same working record");
return false;
};
const size_t index = static_cast<size_t>(working_record - begin_it);
if (index >= static_cast<size_t>(end_it - begin_it)) {
assert(!"index out of ranges");
return false;
};
;{
++workable_it;
working_record = NULL;
};
return true;
}
bool ns_formula::ItemAttrContext::RollbackRecord()
{
if (working_record == NULL) {
assert(!"this record must be same working record");
return false;
};
const size_t index = static_cast<size_t>(working_record - begin_it);
if (index >= static_cast<size_t>(end_it - begin_it)) {
assert(!"index out of ranges");
return false;
};
;{
//++number_of_records;
working_record = NULL;
};
return true;
}
//==================================================================================================
ns_formula::ItemAttrContextList::ItemAttrContextList()
{
ZeroMemory(this, static_cast<size_t>(reinterpret_cast<char*>(contexts) -
reinterpret_cast<char*>(this)));
}
ns_formula::ItemAttrContext* ns_formula::ItemAttrContextList::BeginContext(POSTYPE equip_position)
{
assert(working_context == NULL);
if (number_of_contexts >= _countof(contexts)) {
assert(number_of_contexts < _countof(contexts));
return NULL;
};
if (ItemAttrContext* const context = &contexts[number_of_contexts])
{
ZeroMemory(context, sizeof(*context));
context->equip_position = equip_position;
context->begin_it = &total_records[number_of_total_records];
context->workable_it = context->begin_it;
context->end_it = &total_records[number_of_total_records + kMaxNumberOfContextRecords];
context->parent = this;
working_context = context;
};
return working_context;
}
bool ns_formula::ItemAttrContextList::CommitContext()
{
if (working_context == NULL) {
assert(!"can't find working context");
return false;
};
const size_t context_index = static_cast<size_t>(working_context - contexts);
if (context_index >= _countof(contexts) || context_index != number_of_contexts) {
assert(!"index out of ranges");
return false;
};
;{
size_t number_of_used_nodes =
static_cast<size_t>(working_context->workable_it - working_context->begin_it);
number_of_total_records += number_of_used_nodes;
assert(number_of_total_records < _countof(total_records));
};
;{
++number_of_contexts;
working_context = NULL;
};
return true;
}
bool ns_formula::ItemAttrContextList::RollbackContext()
{
if (working_context == NULL) {
assert(!"can't find working context");
return false;
};
const size_t index = static_cast<size_t>(working_context - contexts);
if (index >= _countof(contexts) || index != number_of_contexts) {
assert(!"index out of ranges");
return false;
};
;{
//++number_of_contexts;
working_context = NULL;
};
return true;
}
// [1, 2] operations per item
bool ns_formula::ItemAttrContextList::RecycleContexts()
{
assert(working_context == NULL);
number_of_contexts = 0;
number_of_total_records = 0;
return true;
}
//==================================================================================================
ns_formula::ItemAttrCalculatorInterControlAutoVariable::ItemAttrCalculatorInterControlAutoVariable(
int* ref, eItemAttrCalculatorInterControl mode)
: ref_field(ref)
, backup_field(*ref_field)
{
*ref_field = mode;
}
ns_formula::ItemAttrCalculatorInterControlAutoVariable::~ItemAttrCalculatorInterControlAutoVariable()
{
*ref_field = backup_field;
}
//==================================================================================================
void ns_formula::SocketSearchBoard::Clear()
{
ZeroMemory(this, static_cast<size_t>(reinterpret_cast<char*>(nodes) -
reinterpret_cast<char*>(this)));
for (node_type* it = nodes; it != &nodes[_countof(nodes)]; ++it)
{
*it = node_type::kDefault;
}
}
bool ns_formula::SocketSearchBoard::SearchSocketOptionPoint(
const SCItemSlot& item_slot, ns_formula::SocketSearchBoard* search_board)
{
WAVERIX_WRAPPER((WAVERIX_LC_CALL1("waverix_log_trace", __FUNCTION__)));
typedef SocketSearchBoard::node_type result_node_t;
//
search_board->Clear(); // nodes not cleared;
//
const int number_of_sockets = item_slot.GetSocketNum();
for (eSOCKET socket = SOCKET_1;
socket < number_of_sockets;
socket = static_cast<eSOCKET>(socket+1))
{
// 소켓 옵션 정보가 유효한지 검사한다.
const sSOCKET_OPTION* const socket_option = item_slot.GetSocketOption(socket);
if (socket_option == NULL) {
continue;
}
const sSOCKET_OPTION::OptionPointInfo* point_it = NULL;
const int number_of_points = socket_option->GetPointArrayInfo(&point_it);
if (number_of_points == 0) {
assert(!"exist invalid option");
continue;
};
// 소켓 옵션의 각 옵션 포인트에 대해
for (int point_index = 0; point_index < number_of_points; ++point_index, ++point_it)
{
if (point_it->option_point == 0) {
assert(!"exist invalid option");
continue;
};
// 옵션 정보가 유효한지 검사한다.
const ZardOptionInfo* const zard_option = point_it->zard_option;
if (zard_option == NULL ||
zard_option->attr_option_code == eATTR_TYPE_INVALID ||
zard_option->item_option_code == 0)
{
assert(!"exist invalid option");
continue;
}
const eATTR_TYPE attr_type = zard_option->attr_option_code;
if (attr_type >= eATTR_MAX) {
assert(!"exist invalid option");
continue;
};
eVALUE_TYPE value_type = point_it->zard_option->GetOptionType();
if (value_type == 0 ||
value_type >= _countof(ItemAttrCalculator::kAttrKindByValueTypes))
{
assert(!"exist invalid option");
continue;
};
// 중복 옵션인지 검사해서 중복이면 포인트 수치를 합친다.
result_node_t& result_node = search_board->nodes[attr_type];
if (result_node.attr_option_code == eATTR_TYPE_INVALID)
{
result_node.attr_option_code = attr_type;
result_node.item_option_code = zard_option->item_option_code;
result_node.option_point = point_it->option_point;
result_node.option_type = value_type;
//result_node.option_value = 0;
if (SocketSearchBoard::RegistNode* regist_node = \
&search_board->registered_nodes[search_board->number_of_registered])
{
regist_node->link_node = &result_node;
regist_node->option_info = zard_option;
++search_board->number_of_registered;
}
}
else
{
result_node.option_point += point_it->option_point;
}
//
};
};
//
return (search_board->number_of_registered != 0);
}
//==================================================================================================
// NOTE: f110111.2L, magical defense values are used to increase it of all elements
// in the Episode II.
void ns_formula::InterAttackPowerCalculator::AddRatioWeight_Limited(float ratio)
{
const float apply_rates = (ratio / 100.0f);
float min_power = static_cast<float>(sum_of_min_power);
float max_power = static_cast<float>(sum_of_max_power);
const float correction_value = (ratio >= 0.0f) ? +0.5f : -0.5f;
min_power += (apply_rates * min_power + correction_value);
max_power += (apply_rates * max_power + correction_value);
sum_of_min_power = static_cast<DWORD>(min_power);
sum_of_max_power = static_cast<DWORD>(max_power);
}
// __NA_001062_20080623_STRENGTH_PENALTY
void ns_formula::InterAttackPowerCalculator::AddRatioWeight_Strength(float ratio)
{
float min_power = static_cast<float>(sum_of_min_power);
float max_power = static_cast<float>(sum_of_max_power);
const float correction_value = (ratio >= 0.0f) ? +0.5f : -0.5f;
min_power = (ratio * min_power + correction_value);
max_power = (ratio * max_power + correction_value);
sum_of_min_power = static_cast<DWORD>(min_power);
sum_of_max_power = static_cast<DWORD>(max_power);
}
void ns_formula::InterAttackPowerCalculator::AddRatioWeight_Fate(float ratio)
{
const float apply_rates = (ratio / 100.0f);
float min_power = static_cast<float>(sum_of_min_power);
float max_power = static_cast<float>(sum_of_max_power);
const float correction_value = (ratio >= 0.0f) ? +0.5f : -0.5f;
min_power += (apply_rates * min_power + correction_value);
max_power += (apply_rates * max_power + correction_value);
sum_of_min_power = static_cast<DWORD>(min_power);
sum_of_max_power = static_cast<DWORD>(max_power);
}
//==================================================================================================
// NOTE: f110111.2L, magical defense values are used to increase it of all elements
// in the Episode II.
void ns_formula::InterDefensePowerCalculator::AddRatioWeight_Limited(float ratio)
{
const float apply_rates = (ratio / 100.0f);
float defense_power = static_cast<float>(sum_of_defense_power);
const float correction_value = (ratio >= 0.0f) ? +0.5f : -0.5f;
defense_power += (apply_rates * defense_power + correction_value);
sum_of_defense_power = static_cast<DWORD>(defense_power);
}
// __NA_001062_20080623_STRENGTH_PENALTY
void ns_formula::InterDefensePowerCalculator::AddRatioWeight_Strength(float ratio)
{
float defense_power = static_cast<float>(sum_of_defense_power);
const float correction_value = (ratio >= 0.0f) ? +0.5f : -0.5f;
defense_power = (ratio * defense_power + correction_value);
sum_of_defense_power = static_cast<DWORD>(defense_power);
}
void ns_formula::InterDefensePowerCalculator::AddRatioWeight_Fate(float ratio)
{
const float apply_rates = (ratio / 100.0f);
float defense_power = static_cast<float>(sum_of_defense_power);
const float correction_value = (ratio >= 0.0f) ? +0.5f : -0.5f;
defense_power += (apply_rates * defense_power + correction_value);
sum_of_defense_power = static_cast<DWORD>(defense_power);
}
//==================================================================================================
//==================================================================================================
//==================================================================================================
ns_formula::EquipSlotsManageInfo::EquipSlotsManageInfo()
{
ZeroMemory(slots, sizeof(slots));
#ifdef _NA_002935_20110704_ITEM_SCORE
item_score_info.slot_nodes = slots;
#endif
}
ns_formula::EquipSlotsManageInfo::~EquipSlotsManageInfo()
{
}
void ns_formula::EquipSlotsManageInfo::ClearAll()
{
ZeroMemory(slots, sizeof(slots));
ClearEquipCounterInfo();
#if USE_CLIENT_SOCKET_OPTION_TABLE
// CHANGES: f110530.3L
item_socket_option_lines_sorted.resize(0);
item_socket_option_lines.resize(0);
for (ItemSocketOptionList* it = item_socket_option_list;
it != &item_socket_option_list[_countof(item_socket_option_list)];
++it)
{
it->resize(0);
};
#endif
#ifdef _NA_002935_20110704_ITEM_SCORE
item_score_info.Clear();
#endif
}
void ns_formula::EquipSlotsManageInfo::ClearCacheInfo()
{
ZeroMemory(slots, sizeof(slots));
}
void ns_formula::EquipSlotsManageInfo::ClearEquipCounterInfo()
{
FOREACH_CONTAINER(ItemEquipCounterTable::value_type& node, restrict_table_,
ItemEquipCounterTable)
{
EquipSlotsManageInfo::CounterNode* counter_node = &node.second;
ZeroMemory(counter_node, sizeof(*counter_node));
};
}
bool ns_formula::EquipSlotsManageInfo::IsEquipEventItem(BYTE event_code) const
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.event_info.event_code = event_code;
key_node.key_value.event_info.tag = key_node.eEquipEvent;
ItemEquipCounterTable::const_iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
const EquipSlotsManageInfo::CounterNode& counter_node = it->second;
return (counter_node.number_of_contains + counter_node.post_apply_working_value) != 0;
};
return false;
}
int ns_formula::EquipSlotsManageInfo::GetEquipCount(SLOTCODE item_code) const
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.code_info.item_code = item_code;
key_node.key_value.code_info.tag = key_node.eItemCode;
ItemEquipCounterTable::const_iterator it = restrict_table_.find(key_node.key_value.composed);
if (it == restrict_table_.end()) {
return 0;
};
const EquipSlotsManageInfo::CounterNode& counter_node = it->second;
int number_of_same_items =
(counter_node.number_of_contains + counter_node.post_apply_working_value);
return number_of_same_items;
}
int ns_formula::EquipSlotsManageInfo::GetEquipTypeCount(eITEMTYPE item_type) const
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.type_info.item_type = static_cast<uint16_t>(item_type);
key_node.key_value.type_info.tag = key_node.eItemType;
ItemEquipCounterTable::const_iterator it = restrict_table_.find(key_node.key_value.composed);
if (it == restrict_table_.end()) {
return 0;
};
const EquipSlotsManageInfo::CounterNode& counter_node = it->second;
int number_of_same_type_items =
(counter_node.number_of_contains + counter_node.post_apply_working_value);
return number_of_same_type_items;
}
//그룹별 장착 개수 제한 관리
// (NOTE) it has not the usage case at this point in time (100505)
int ns_formula::EquipSlotsManageInfo::GetEquipGroupCount(DURATYPE equip_group) const
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.group_info.group = equip_group;
key_node.key_value.group_info.tag = key_node.eEquipGroup;
ItemEquipCounterTable::const_iterator it = restrict_table_.find(key_node.key_value.composed);
if (it == restrict_table_.end()) {
return 0;
};
const EquipSlotsManageInfo::CounterNode& counter_node = it->second;
int number_of_same_group_items =
(counter_node.number_of_contains + counter_node.post_apply_working_value);
return number_of_same_group_items;
}
//_NA_001990_ACSYSTEM_ADD
int ns_formula::EquipSlotsManageInfo::GetEquipACGroupCount(WORD item_acgroup) const
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.ac_group_info.ac_group = item_acgroup;
key_node.key_value.ac_group_info.tag = key_node.eACGroup;
ItemEquipCounterTable::const_iterator it = restrict_table_.find(key_node.key_value.composed);
if (it == restrict_table_.end()) {
return 0;
};
const EquipSlotsManageInfo::CounterNode& counter_node = it->second;
int number_of_same_group_items =
(counter_node.number_of_contains + counter_node.post_apply_working_value);
return number_of_same_group_items;
}
//==================================================================================================
// CHANGES: f110422.5L, added filter to check the item relational dependency rules
bool ns_formula::EquipSlotsManageInfo::CanEquipmentsDependency(const SCItemSlot& item_slot) const
{
const BASE_ITEMINFO* const item_info = item_slot.GetItemInfo();
// 중복장착 개수 체크(0이면 무제한)
if (item_info->m_byDupEquipNum)
{
const int number_of_same_items = GetEquipCount(item_info->m_Code);
if (number_of_same_items >= item_info->m_byDupEquipNum) {
return false;
}
};
// 중복타입 장착 개수 체크
if (item_info->m_byDupEquipTypeNum)
{
const int number_of_same_items =
GetEquipTypeCount(static_cast<eITEMTYPE>(item_info->m_wType));
if (number_of_same_items >= 1)
return false;
};
// 아이템 그룹별 개수 제한 체크
if (item_info->m_byDupEquipGroup)
{
const int number_of_same_items = GetEquipGroupCount(item_info->m_byDupEquipGroup);
if (number_of_same_items >= item_info->m_byDupEquipGroupNum) {
return false;
}
};
return true;
}
//==================================================================================================
void ns_formula::EquipSlotsManageInfo::IncreaseEquipInfo(const SCItemSlot& item_slot)
{
const BASE_ITEMINFO* item_info = item_slot.GetItemInfo();
if (item_info->m_Code == 0) {
return;
};
;{
ItemEquipCounter key_node = { 0, };
key_node.key_value.code_info.item_code = item_info->m_Code;
key_node.key_value.code_info.tag = key_node.eItemCode;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->number_of_contains;
};
if (item_info->m_wType)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.type_info.item_type = item_info->m_wType;
key_node.key_value.type_info.tag = key_node.eItemType;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->number_of_contains;
};
if (item_info->m_byDupEquipGroup)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.group_info.group = item_info->m_byDupEquipGroup;
key_node.key_value.group_info.tag = key_node.eEquipGroup;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->number_of_contains;
}
if (item_info->m_byEventCode)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.event_info.event_code = item_info->m_byEventCode;
key_node.key_value.event_info.tag = key_node.eEquipEvent;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->number_of_contains;
}
//_NA_001990_ACSYSTEM_ADD
if (item_info->m_byACReferenceID)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.ac_group_info.ac_group = item_info->m_byACReferenceID;
key_node.key_value.ac_group_info.tag = key_node.eEquipGroup;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->number_of_contains;
}
}
void ns_formula::EquipSlotsManageInfo::DecreaseEquipInfo(const SCItemSlot& item_slot)
{
const BASE_ITEMINFO* item_info = item_slot.GetItemInfo();
if (item_info->m_Code == 0) {
return;
};
;{
ItemEquipCounter key_node = { 0, };
key_node.key_value.code_info.item_code = item_info->m_Code;
key_node.key_value.code_info.tag = key_node.eItemCode;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
if (counter_node->number_of_contains) {
--counter_node->number_of_contains;
};
if (counter_node->number_of_contains == 0) {
restrict_table_.erase(it);
};
};
};
if (item_info->m_wType)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.type_info.item_type = item_info->m_wType;
key_node.key_value.type_info.tag = key_node.eItemType;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
if (counter_node->number_of_contains) {
--counter_node->number_of_contains;
};
if (counter_node->number_of_contains == 0) {
restrict_table_.erase(it);
};
};
};
if (item_info->m_byDupEquipGroup)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.group_info.group = item_info->m_byDupEquipGroup;
key_node.key_value.group_info.tag = key_node.eEquipGroup;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
if (counter_node->number_of_contains) {
--counter_node->number_of_contains;
};
if (counter_node->number_of_contains == 0) {
restrict_table_.erase(it);
};
};
}
if (item_info->m_byEventCode)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.event_info.event_code = item_info->m_byEventCode;
key_node.key_value.event_info.tag = key_node.eEquipEvent;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
if (counter_node->number_of_contains) {
--counter_node->number_of_contains;
};
if (counter_node->number_of_contains == 0) {
restrict_table_.erase(it);
};
};
}
//_NA_001990_ACSYSTEM_ADD
if (item_info->m_byACReferenceID)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.ac_group_info.ac_group = item_info->m_byACReferenceID;
key_node.key_value.ac_group_info.tag = key_node.eACGroup;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
if (counter_node->number_of_contains) {
--counter_node->number_of_contains;
};
if (counter_node->number_of_contains == 0) {
restrict_table_.erase(it);
};
};
}
}
//==================================================================================================
// NOTE: f110530.3L
namespace ns_formula {
;
EquipSlotsManageInfo::ItemScoreInfo::ItemScoreInfo() :
slot_nodes(NULL), socket_score(0), set_option_score(0), total_score(0)
{
::ZeroMemory(each_item_score, sizeof(each_item_score));
}
void EquipSlotsManageInfo::ItemScoreInfo::Clear()
{
socket_score = 0;
set_option_score = 0;
total_score = 0;
::ZeroMemory(each_item_score, sizeof(each_item_score));
}
int EquipSlotsManageInfo::ItemScoreInfo::GetScore(const POSTYPE equip_position) const
{
enum { kMaxWeight = 999999 };
if (equip_position >= _countof(each_item_score))
{
return 0;
}
assert(slot_nodes != NULL);
const Node& slot_node = *(slot_nodes + equip_position);
if (slot_node.activated == false)
{
return 0;
}
const Weight item_score = each_item_score[equip_position];
if (item_score < 0)
{
return 0;
}
if (item_score > kMaxWeight)
{
return kMaxWeight;
}
return static_cast<int>(item_score + 0.5f);
}
int EquipSlotsManageInfo::ItemScoreInfo::GetTotalScore() const
{
enum { kMaxWeight = 999999 };
if (total_score < 0)
{
return 0;
}
if (total_score > kMaxWeight)
{
return kMaxWeight;
}
return static_cast<int>(total_score + 0.5f);
}
void EquipSlotsManageInfo::ItemScoreInfo::UpdateTotalScore()
{
total_score = 0;
assert(slot_nodes != NULL);
for (int i = 0; i < _countof(each_item_score); ++i)
{
const Node& slot_node = *(slot_nodes + i);
if (slot_node.activated == false)
{
continue;
}
total_score += each_item_score[i];
}
total_score += socket_score;
total_score += set_option_score;
}
struct SocketOptionMappingTableUtil
{
typedef ns_formula::EquipSlotsManageInfo::ItemSocketOption ItemSocketOption;
typedef ns_formula::EquipSlotsManageInfo::ItemSocketOptionList ItemSocketOptionList;
typedef ns_formula::EquipSlotsManageInfo::ItemSocketOptionLine ItemSocketOptionLine;
typedef ns_formula::EquipSlotsManageInfo::ItemSocketOptionLineList ItemSocketOptionLineList;
typedef ns_formula::EquipSlotsManageInfo::ItemSocketOptionLineListSorted
ItemSocketOptionLineListSorted;
//
SocketOptionMappingTableUtil(ItemSocketOptionLineList* const line_list,
ItemSocketOptionLineListSorted* const sorted_line_list);
ItemSocketOptionLine* FindOptionLine(eATTR_TYPE attr_type);
bool AddItemSocketOptionList(POSTYPE equip_pos, const ItemSocketOptionList& item_socket_options);
bool SortBySumOfPoints();
static bool DescendingOrderComparator(
const ItemSocketOptionLine* lhs, const ItemSocketOptionLine* rhs);
//
ItemSocketOptionLineList* const line_list_;
ItemSocketOptionLineListSorted* const sorted_line_list_;
//
__DISABLE_COPY(SocketOptionMappingTableUtil);
};
}; //end of namespace
ns_formula::SocketOptionMappingTableUtil::SocketOptionMappingTableUtil(
ItemSocketOptionLineList* const line_list,
ItemSocketOptionLineListSorted* const sorted_line_list)
: line_list_(line_list)
, sorted_line_list_(sorted_line_list)
{
line_list_->resize(0);
sorted_line_list_->resize(0);
};
ns_formula::SocketOptionMappingTableUtil::ItemSocketOptionLine*
ns_formula::SocketOptionMappingTableUtil::FindOptionLine(eATTR_TYPE attr_type)
{
FOREACH_CONTAINER(ItemSocketOptionLineList::value_type& node, (*line_list_),
ItemSocketOptionLineList)
{
if (node.attr_type == attr_type) {
return &node;
};
};
return NULL;
}
bool ns_formula::SocketOptionMappingTableUtil::AddItemSocketOptionList(
POSTYPE equip_pos, const ItemSocketOptionList& item_socket_options)
{
FOREACH_CONTAINER(const ItemSocketOptionList::value_type& node, item_socket_options,
ItemSocketOptionList)
{
const ItemSocketOption& option_type = node;
ItemSocketOptionLine* working_line = FindOptionLine(option_type.attr_option_code);
if (working_line == NULL)
{
line_list_->resize(line_list_->size() + 1);
working_line = &line_list_->back();
};
working_line->attr_type = option_type.attr_option_code;
working_line->options[equip_pos] = &option_type;
working_line->sum_of_points += option_type.option_point;
};
return true;
}
bool ns_formula::SocketOptionMappingTableUtil::DescendingOrderComparator(
const ItemSocketOptionLine* lhs, const ItemSocketOptionLine* rhs)
{
return (lhs->sum_of_points > rhs->sum_of_points);
}
bool ns_formula::SocketOptionMappingTableUtil::SortBySumOfPoints()
{
if (line_list_->empty()) {
return true;
};
FOREACH_CONTAINER(const ItemSocketOptionLineList::value_type& node, (*line_list_),
ItemSocketOptionLineList)
{
sorted_line_list_->push_back(&node);
};
std::sort(sorted_line_list_->begin(), sorted_line_list_->end(), &DescendingOrderComparator);
return true;
}
#if USE_CLIENT_SOCKET_OPTION_TABLE
bool ns_formula::EquipSlotsManageInfo::CalculateSocketOptionMappingTable()
{
SocketOptionMappingTableUtil inter_util(
&item_socket_option_lines, &item_socket_option_lines_sorted);
//
for (const ItemSocketOptionList* it = item_socket_option_list;
it != &item_socket_option_list[_countof(item_socket_option_list)];
++it)
{
inter_util.AddItemSocketOptionList(static_cast<POSTYPE>(it - item_socket_option_list), *it);
};
return inter_util.SortBySumOfPoints();
}
#endif //USE_CLIENT_SOCKET_OPTION_TABLE
//==================================================================================================
BOOST_STATIC_ASSERT(sizeof(EquipSlotsManageInfoInterController) ==
sizeof(EquipSlotsManageInfo));
void ns_formula::EquipSlotsManageInfoInterController::IncreaseEquipInfoSimulation(
const SCItemSlot& item_slot)
{
const BASE_ITEMINFO* item_info = item_slot.GetItemInfo();
if (item_info->m_Code == 0) {
return;
};
;{
ItemEquipCounter key_node = { 0, };
key_node.key_value.code_info.item_code = item_info->m_Code;
key_node.key_value.code_info.tag = key_node.eItemCode;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->post_apply_working_value;
};
if (item_info->m_wType)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.type_info.item_type = item_info->m_wType;
key_node.key_value.type_info.tag = key_node.eItemType;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->post_apply_working_value;
};
if (item_info->m_byDupEquipGroup)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.group_info.group = item_info->m_byDupEquipGroup;
key_node.key_value.group_info.tag = key_node.eEquipGroup;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->post_apply_working_value;
}
if (item_info->m_byEventCode)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.event_info.event_code = item_info->m_byEventCode;
key_node.key_value.event_info.tag = key_node.eEquipEvent;
EquipSlotsManageInfo::CounterNode* counter_node =
&restrict_table_[key_node.key_value.composed];
++counter_node->post_apply_working_value;
}
}
void ns_formula::EquipSlotsManageInfoInterController::DecreaseEquipInfoSimulation(
const SCItemSlot& item_slot)
{
const BASE_ITEMINFO* item_info = item_slot.GetItemInfo();
if (item_info->m_Code == 0) {
return;
};
;{
ItemEquipCounter key_node = { 0, };
key_node.key_value.code_info.item_code = item_info->m_Code;
key_node.key_value.code_info.tag = key_node.eItemCode;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
--counter_node->post_apply_working_value;
};
};
if (item_info->m_wType)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.type_info.item_type = item_info->m_wType;
key_node.key_value.type_info.tag = key_node.eItemType;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
--counter_node->post_apply_working_value;
};
};
if (item_info->m_byDupEquipGroup)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.group_info.group = item_info->m_byDupEquipGroup;
key_node.key_value.group_info.tag = key_node.eEquipGroup;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
--counter_node->post_apply_working_value;
};
}
if (item_info->m_byEventCode)
{
ItemEquipCounter key_node = { 0, };
key_node.key_value.event_info.event_code = item_info->m_byEventCode;
key_node.key_value.event_info.tag = key_node.eEquipEvent;
ItemEquipCounterTable::iterator it = restrict_table_.find(key_node.key_value.composed);
if (it != restrict_table_.end())
{
EquipSlotsManageInfo::CounterNode* counter_node = &it->second;
--counter_node->post_apply_working_value;
};
}
}
// CHANGES: f110429.2L, removed. using external equipment limitation conditions can check
// whether this item enable equips.
#if SUN_CODE_BACKUP
// NOTE: f110424.2L, this mediator that additionally support the IEquipmentRestriction object
// process item duplication dependency rule conditions
// with CheckEquipDefaultValidationWithoutStats calling in the object
bool ns_formula::EquipSlotsManageInfoInterController::CheckEquipDefaultValidationWithoutStats(
IEquipmentRestriction* restriction,
POSTYPE at_pos, const SCItemSlot& IN check_slot)
{
if (restriction->CheckEquipDefaultValidationWithoutStats(at_pos, check_slot) == false) {
return false;
};
if (this->CanEquipmentsDependency(check_slot) == false) {
return false;
};
return true;
}
#endif //
//==================================================================================================
//==================================================================================================
#endif //_NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT