CN1602 is the local client. KR is the official tree with unpacked Data, System, and Sound. Packed .wpk files stay off git.
811 lines
30 KiB
C++
811 lines
30 KiB
C++
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///
|
|
/// @file ItemScoreParser.cpp
|
|
/// @author hukim
|
|
/// @email silped@gmail.com
|
|
/// @brief [2011/07/04 by hukim] This is created.\n
|
|
///
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include ".\ItemScoreParser.h" // header
|
|
#include <SCItemSlot.h>
|
|
#include <SCItemSlotContainer.h>
|
|
#include <PlayerAttributes.h>
|
|
#include <ItemAttrCalculatorEP2.h>
|
|
#include <boost/foreach.hpp>
|
|
#ifdef _NA_008124_20150313_AWAKENING_SYSTEM
|
|
#include "AwakeningInfoParser.h"
|
|
#endif // _NA_008124_20150313_AWAKENING_SYSTEM
|
|
|
|
// _NA_002935_20110704_ITEM_SCORE
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// REGION : WeightManager
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace LocalUtil {
|
|
// 初始化存储指针的地图.
|
|
template < typename MAP_T >
|
|
inline void ClearPointerMap(MAP_T& map)
|
|
{
|
|
for (MAP_T::iterator it = map.begin(); it != map.end(); ++it)
|
|
{
|
|
typename MAP_T::mapped_type pointer = it->second;
|
|
delete pointer;
|
|
}
|
|
map.clear();
|
|
}
|
|
|
|
// 在指针映射中插入指针.
|
|
template < typename MAP_T >
|
|
inline void InsertPointerMap(
|
|
MAP_T& map, const typename MAP_T::key_type key, typename MAP_T::mapped_type pointer)
|
|
{
|
|
if (pointer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
MAP_T::iterator it = map.find(key);
|
|
if (it != map.end())
|
|
{
|
|
typename MAP_T::mapped_type old_pointer = it->second;
|
|
delete old_pointer;
|
|
}
|
|
map[key] = pointer;
|
|
}
|
|
|
|
// 在指针映射中查找指针.
|
|
template < typename MAP_T >
|
|
inline typename MAP_T::mapped_type FindPointerMap(MAP_T& map, const typename MAP_T::key_type key)
|
|
{
|
|
const MAP_T::const_iterator it = map.find(key);
|
|
if (it == map.end())
|
|
{
|
|
return NULL;
|
|
}
|
|
return it->second;
|
|
}
|
|
} // LocalUtil
|
|
|
|
ItemScoreParser::WeightManager::WeightManager()
|
|
{
|
|
}
|
|
|
|
ItemScoreParser::WeightManager::~WeightManager()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void ItemScoreParser::WeightManager::Clear()
|
|
{
|
|
LocalUtil::ClearPointerMap(item_level_weight_map_);
|
|
LocalUtil::ClearPointerMap(divine_item_level_weight_map_);
|
|
LocalUtil::ClearPointerMap(enchant_weight_map_);
|
|
LocalUtil::ClearPointerMap(extra_stone_weight_map_);
|
|
zard_option_point_weight_map_.clear();
|
|
LocalUtil::ClearPointerMap(option_weight_map_);
|
|
}
|
|
|
|
void ItemScoreParser::WeightManager::InsertItemLevelWeight(
|
|
const ItemLevelWeight* weight, const bool is_divine)
|
|
{
|
|
ItemLevelWeightMap& item_level_weight_map =
|
|
is_divine ? divine_item_level_weight_map_ : item_level_weight_map_;
|
|
LocalUtil::InsertPointerMap(item_level_weight_map, weight->item_level, weight);
|
|
}
|
|
|
|
ItemScoreParser::Weight ItemScoreParser::WeightManager::FindItemLevelWeight(
|
|
const LEVELTYPE item_level,
|
|
const ItemLevelWeight::EquipPosition equip_position,
|
|
const bool is_divine) const
|
|
{
|
|
const ItemLevelWeightMap& item_level_weight_map =
|
|
is_divine ? divine_item_level_weight_map_ : item_level_weight_map_;
|
|
const ItemLevelWeight* const weight =
|
|
LocalUtil::FindPointerMap(item_level_weight_map, item_level);
|
|
if (weight == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
typedef ItemLevelWeight::EquipPositionMap EquipPositionMap;
|
|
const EquipPositionMap& equip_position_map = weight->equip_position_map;
|
|
const EquipPositionMap::const_iterator eq_pos_it = equip_position_map.find(equip_position);
|
|
if (eq_pos_it == equip_position_map.end())
|
|
{
|
|
return 0;
|
|
}
|
|
return eq_pos_it->second;
|
|
}
|
|
|
|
void ItemScoreParser::WeightManager::InsertEnchantWeight(const EnchantWeight* weight)
|
|
{
|
|
LocalUtil::InsertPointerMap(enchant_weight_map_, weight->enchant_grade, weight);
|
|
}
|
|
|
|
ItemScoreParser::Weight ItemScoreParser::WeightManager::FindEnchantWeight(
|
|
const EnchantWeight::EnchantGrade enchant_grade, const EnchantWeight::ItemType item_type) const
|
|
{
|
|
const EnchantWeight* const weight =
|
|
LocalUtil::FindPointerMap(enchant_weight_map_, enchant_grade);
|
|
if (weight == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
if (item_type < 0 || item_type >= _countof(weight->item_type_list))
|
|
{
|
|
return 0;
|
|
}
|
|
return (weight->item_type_list)[item_type];
|
|
}
|
|
|
|
void ItemScoreParser::WeightManager::InsertExtraStoneWeight(const ExtraStoneWeight* weight)
|
|
{
|
|
LocalUtil::InsertPointerMap(extra_stone_weight_map_, weight->extra_stone_size, weight);
|
|
}
|
|
|
|
ItemScoreParser::Weight ItemScoreParser::WeightManager::FindExtraStoneWeight(
|
|
const ExtraStoneWeight::ExtraStoneSize extra_stone_size,
|
|
const ExtraStoneWeight::ItemType item_type) const
|
|
{
|
|
const ExtraStoneWeight* const weight =
|
|
LocalUtil::FindPointerMap(extra_stone_weight_map_, extra_stone_size);
|
|
if (weight == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
if (item_type < 0 || item_type >= _countof(weight->item_type_list))
|
|
{
|
|
return 0;
|
|
}
|
|
return (weight->item_type_list)[item_type];
|
|
}
|
|
|
|
void ItemScoreParser::WeightManager::InsertZardOptionPointWeight(
|
|
const ZardOptionPoint zard_option_point, const Weight weight)
|
|
{
|
|
zard_option_point_weight_map_[zard_option_point] = weight;
|
|
}
|
|
|
|
ItemScoreParser::Weight ItemScoreParser::WeightManager::FindZardOptionPointWeight(
|
|
const ZardOptionPoint zard_option_point) const
|
|
{
|
|
if (zard_option_point <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
ZardOptionPointWeightMap::const_reverse_iterator it = zard_option_point_weight_map_.rbegin();
|
|
for (; it != zard_option_point_weight_map_.rend(); ++it)
|
|
{
|
|
const ZardOptionPoint option_point = it->first;
|
|
if (option_point <= zard_option_point)
|
|
{
|
|
return it->second;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ItemScoreParser::WeightManager::InsertOptionWeight(const OptionWeight* weight)
|
|
{
|
|
LocalUtil::InsertPointerMap(option_weight_map_, weight->attr_option_code, weight);
|
|
}
|
|
|
|
ItemScoreParser::Weight ItemScoreParser::WeightManager::FindOptionWeight(
|
|
const eATTR_TYPE attr_option_code, const OptionWeight::ValueType value_type) const
|
|
{
|
|
const OptionWeight* const weight =
|
|
LocalUtil::FindPointerMap(option_weight_map_, attr_option_code);
|
|
if (weight == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
if (value_type < 0 || value_type >= _countof(weight->value_type_list))
|
|
{
|
|
return 0;
|
|
}
|
|
if (weight->is_reverse_benefit)
|
|
{
|
|
return (-1 * (weight->value_type_list)[value_type]);
|
|
}
|
|
return (weight->value_type_list)[value_type];
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// REGION : Constructor & Destructor
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ItemScoreParser::ItemScoreParser()
|
|
{
|
|
}
|
|
|
|
ItemScoreParser::~ItemScoreParser()
|
|
{
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// REGION : Public
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL ItemScoreParser::LoadScript(eSCRIPT_CODE script_code, BOOL is_reload)
|
|
{
|
|
if (script_code != SCRIPT_ITEM_SCORE_COMMON)
|
|
{
|
|
FASSERT(false && _T("脚本data error."));
|
|
return FALSE;
|
|
}
|
|
return (LoadWeight(is_reload == TRUE) ? TRUE : FALSE);
|
|
}
|
|
|
|
ItemScoreParser::Weight ItemScoreParser::CalculateSingleScore(
|
|
const SCItemSlot& item_slot, const bool is_pc_room) const
|
|
{
|
|
const SLOTCODE item_code = item_slot.GetItemCode();
|
|
if (item_code == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
const BASE_ITEMINFO* const item_info = item_slot.GetItemInfo();
|
|
if ((item_info->IsWeapon() == false) &&
|
|
(item_info->IsArmor() == false) &&
|
|
(item_info->IsAccessory() == false) &&
|
|
(item_info->IsSpecialAccessory() == false) &&
|
|
(item_slot.IsWingItem() == false))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// 选择分数
|
|
Weight option_weight = CalculateOptionWeight(
|
|
item_info->m_wOptionIndex, item_info->m_byOptionType, item_info->m_iOptionValue);
|
|
if (is_pc_room)
|
|
{
|
|
option_weight += CalculateOptionWeight(
|
|
item_info->m_wPCOptionIndex, item_info->m_byPCOptionType, item_info->m_iPCOptionValue);
|
|
}
|
|
|
|
// 计算饰品分数.
|
|
if (item_info->IsAccessory())
|
|
{
|
|
return option_weight;
|
|
}
|
|
|
|
// 附魔分数
|
|
const EnchantWeight::ItemType enchant_item_type =
|
|
item_info->IsWeapon() ? EnchantWeight::kWeapon : EnchantWeight::kArmor;
|
|
const Weight enchant_score =
|
|
weight_manager_.FindEnchantWeight(item_slot.GetEnchant(), enchant_item_type);
|
|
|
|
#ifdef _NA_008124_20150313_AWAKENING_SYSTEM
|
|
// 觉醒分数
|
|
const AwakeningWeight::ItemType awakening_item_type =
|
|
item_info->IsWeapon() ? AwakeningWeight::kWeapon : AwakeningWeight::kArmor;
|
|
Weight awakening_score = 0;
|
|
if (item_slot.GetAwakening() > 0)
|
|
{
|
|
awakening_score = weight_manager_.GetAwakeningWeight(awakening_item_type)
|
|
* AwakeningInfoParser::Instance()->GetOptionValue(item_slot.GetCode(), item_slot.GetAwakening());
|
|
}
|
|
#endif // _NA_008124_20150313_AWAKENING_SYSTEM
|
|
|
|
// 计算武器或装分数.
|
|
if (item_info->IsWeapon() == true || item_info->IsArmor() == true)
|
|
{
|
|
// 基础分数
|
|
const Weight base_score = weight_manager_.FindItemLevelWeight(
|
|
item_info->m_LV, item_info->m_wEqPos, (item_slot.IsDivine() == TRUE));
|
|
|
|
// 额外的石头分数
|
|
const ExtraStoneWeight::ExtraStoneSize extra_stone_size = item_slot.GetNOptionValueIndex();
|
|
const ExtraStoneWeight::ItemType extra_stone_item_type =
|
|
item_info->IsWeapon() ? ExtraStoneWeight::kWeapon : ExtraStoneWeight::kArmor;
|
|
const Weight extra_stone_score =
|
|
weight_manager_.FindExtraStoneWeight(extra_stone_size, extra_stone_item_type);
|
|
|
|
#ifdef _NA_008124_20150313_AWAKENING_SYSTEM
|
|
// 基础分数+附魔分数+额外石头分数+选项分数+觉醒分数
|
|
return (base_score + enchant_score + extra_stone_score + option_weight + awakening_score);
|
|
#else
|
|
// 基础点+附魔点+额外石点+选项点
|
|
return (base_score + enchant_score + extra_stone_score + option_weight);
|
|
#endif // _NA_008124_20150313_AWAKENING_SYSTEM
|
|
}
|
|
|
|
// 计算特殊配件分数.
|
|
if (item_info->IsSpecialAccessory())
|
|
{
|
|
const WORD item_phy_def = item_slot.IsDivine() ? item_info->m_wDivPhyDef : item_info->m_wPhyDef;
|
|
if (item_phy_def == 0)
|
|
{
|
|
// 只有选项点适用于脚本中没有防御的特殊配件。
|
|
return option_weight;
|
|
}
|
|
else
|
|
{
|
|
const Weight defense_option_weight =
|
|
weight_manager_.FindOptionWeight(eATTR_OPTION_PHYSICAL_DEFENSE_POWER, OptionWeight::kFix);
|
|
const Weight defense_score = defense_option_weight * (Weight)item_phy_def;
|
|
|
|
// 防御点+附魔点+选项点
|
|
return (defense_score + enchant_score + option_weight);
|
|
}
|
|
}
|
|
|
|
#ifdef _DEV_VER
|
|
FASSERT(false && _T("不支持的物品类型."));
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ItemScoreParser::CalculateTotalEquipScore(
|
|
const PlayerAttributes& player_attrs, Weight& socket_score, Weight& set_option_score) const
|
|
{
|
|
socket_score = 0;
|
|
set_option_score = 0;
|
|
|
|
const SocketOptionAttributes& socket_attrs = player_attrs.GetSocketOptionAttributes();
|
|
const SetOptionAttributes& set_attrs = player_attrs.GetSetOptionAttributes();
|
|
|
|
for (int i = eATTR_TYPE_INVALID+1; i < eATTR_MAX; ++i)
|
|
{
|
|
const eATTR_TYPE attr_type = static_cast<eATTR_TYPE>(i);
|
|
|
|
// 计算打孔评估分数.
|
|
const SocketOptionAttributes::AttrValue& socket_attr_value =
|
|
socket_attrs.GetAttrValue(attr_type);
|
|
if (socket_attr_value.point != 0)
|
|
{
|
|
socket_score += weight_manager_.FindZardOptionPointWeight(socket_attr_value.point);
|
|
}
|
|
|
|
// 计算设置选项评估分数.
|
|
const SetOptionAttributes::AttrValue& set_attr_value = set_attrs.GetAttrValue(attr_type);
|
|
if (set_attr_value.fix_value != 0)
|
|
{
|
|
// 计算固定值.
|
|
const Weight option_weight =
|
|
weight_manager_.FindOptionWeight(attr_type, OptionWeight::kFix);
|
|
if (option_weight != 0)
|
|
{
|
|
set_option_score += (option_weight * set_attr_value.fix_value);
|
|
}
|
|
}
|
|
if (set_attr_value.ratio_value != 0)
|
|
{
|
|
// 计算比例值.
|
|
const Weight option_weight =
|
|
weight_manager_.FindOptionWeight(attr_type, OptionWeight::kRatio);
|
|
if (option_weight != 0)
|
|
{
|
|
set_option_score += (option_weight * set_attr_value.ratio_value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// REGION : Private
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool ItemScoreParser::LoadWeight(const bool is_reload)
|
|
{
|
|
if (is_reload)
|
|
{
|
|
weight_manager_.Clear();
|
|
}
|
|
|
|
const int row_size = GetRowSize();
|
|
for (int row = 0; row < row_size; ++row)
|
|
{
|
|
const int large_group = GetDataInt(_T("LGroup"), row);
|
|
enum LargeGroup
|
|
{
|
|
kItemLevel = 1,
|
|
kDivineItemLevel = 2,
|
|
kEnchant = 3,
|
|
kExtraStone = 4,
|
|
kZardOptionPoint = 5,
|
|
kOption = 6,
|
|
#ifdef _NA_008124_20150313_AWAKENING_SYSTEM
|
|
kAwakening = 7,
|
|
#endif // _NA_008124_20150313_AWAKENING_SYSTEM
|
|
};
|
|
switch (large_group)
|
|
{
|
|
case kItemLevel:
|
|
case kDivineItemLevel:
|
|
{
|
|
enum { kItemLevelMaxWeight = 9999 };
|
|
|
|
const LEVELTYPE item_level = GetDataWORD(_T("SGroup"), row);
|
|
if (item_level < ItemCustomLevel::kMinLV || item_level > ItemCustomLevel::kMaxLV)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品级别无效。|行号 = %d,级别 = %d|"),
|
|
__FUNCTION__,
|
|
row,
|
|
item_level);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight weapon_weight = GetDataFloat(_T("Value1"), row);
|
|
if (weapon_weight < 0 || weapon_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品级武器重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
weapon_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight armor_weight = GetDataFloat(_T("Value2"), row);
|
|
if (armor_weight < 0 || armor_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品等级装甲重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
armor_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight protector_weight = GetDataFloat(_T("Value3"), row);
|
|
if (protector_weight < 0 || protector_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品级别保护器重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
protector_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight helmet_weight = GetDataFloat(_T("Value4"), row);
|
|
if (helmet_weight < 0 || helmet_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s |物品级别头盔的重量不正确。|行号=%d,重量=%f |"),
|
|
__FUNCTION__,
|
|
row,
|
|
helmet_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight pants_weight = GetDataFloat(_T("Value5"), row);
|
|
if (pants_weight < 0 || pants_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品级别裤子重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
pants_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight boots_weight = GetDataFloat(_T("Value6"), row);
|
|
if (boots_weight < 0 || boots_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品级引导权重不正确。|行号 = %d,权重 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
boots_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight glove_weight = GetDataFloat(_T("Value7"), row);
|
|
if (glove_weight < 0 || glove_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品等级手套重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
glove_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight belt_weight = GetDataFloat(_T("Value8"), row);
|
|
if (belt_weight < 0 || belt_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品等级皮带重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
belt_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight shirts_weight = GetDataFloat(_T("Value9"), row);
|
|
if (shirts_weight < 0 || shirts_weight > kItemLevelMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|物品级别衬衫重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
shirts_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
|
|
ItemLevelWeight* weight(new ItemLevelWeight(item_level));
|
|
ItemLevelWeight::EquipPositionMap& equip_position_map = weight->equip_position_map;
|
|
equip_position_map[eEQUIPCONTAINER_WEAPON] = weapon_weight;
|
|
equip_position_map[eEQUIPCONTAINER_ARMOR] = armor_weight;
|
|
equip_position_map[eEQUIPCONTAINER_PROTECTOR] = protector_weight;
|
|
equip_position_map[eEQUIPCONTAINER_HELMET] = helmet_weight;
|
|
equip_position_map[eEQUIPCONTAINER_PANTS] = pants_weight;
|
|
equip_position_map[eEQUIPCONTAINER_BOOTS] = boots_weight;
|
|
equip_position_map[eEQUIPCONTAINER_GLOVE] = glove_weight;
|
|
equip_position_map[eEQUIPCONTAINER_BELT] = belt_weight;
|
|
equip_position_map[eEQUIPCONTAINER_SHIRTS] = shirts_weight;
|
|
|
|
weight_manager_.InsertItemLevelWeight(weight, (large_group == kDivineItemLevel));
|
|
}
|
|
break;
|
|
case kEnchant:
|
|
{
|
|
#ifdef _NA_003966_20111227_ADD_ENCHANT
|
|
enum { kMaxEnchantGrade = 15 };
|
|
#else
|
|
enum { kMaxEnchantGrade = 12 };
|
|
#endif
|
|
enum { kEnchantMaxWeight = 9999 };
|
|
|
|
const EnchantWeight::EnchantGrade enchant_grade = GetDataBYTE(_T("SGroup"), row);
|
|
if (enchant_grade > kMaxEnchantGrade)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|无效的附魔等级。|行号 = %d,等级 = %d|"),
|
|
__FUNCTION__,
|
|
row,
|
|
enchant_grade);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight weapon_weight = GetDataFloat(_T("Value1"), row);
|
|
if (weapon_weight < 0 || weapon_weight > kEnchantMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|无效的附魔武器重量。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
weapon_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight armor_weight = GetDataFloat(_T("Value2"), row);
|
|
if (armor_weight < 0 || armor_weight > kEnchantMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s |附魔装甲重量无效。|线号=%d,重量=%f |"),
|
|
__FUNCTION__,
|
|
row,
|
|
armor_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
|
|
Weight item_type_list[EnchantWeight::kMaxSize];
|
|
::ZeroMemory(item_type_list, sizeof(item_type_list));
|
|
item_type_list[EnchantWeight::kWeapon] = weapon_weight;
|
|
item_type_list[EnchantWeight::kArmor] = armor_weight;
|
|
|
|
const EnchantWeight* weight(new EnchantWeight(enchant_grade, item_type_list));
|
|
weight_manager_.InsertEnchantWeight(weight);
|
|
}
|
|
break;
|
|
case kExtraStone:
|
|
{
|
|
enum { kExtraStoneMaxWeight = 9999 };
|
|
const ExtraStoneWeight::ExtraStoneSize extra_stone_size =
|
|
GetDataInt(_T("SGroup"), row);
|
|
if (extra_stone_size < 0 || extra_stone_size > sEXTRASTONE_OPT_INFO::MAX_VALUE_NUM)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|使用的额外宝石数无效。|行号 = %d,行号 = %d|"),
|
|
__FUNCTION__,
|
|
row,
|
|
extra_stone_size);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight weapon_weight = GetDataFloat(_T("Value1"), row);
|
|
if (weapon_weight < 0 || weapon_weight > kExtraStoneMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|额外的石头武器重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
weapon_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight armor_weight = GetDataFloat(_T("Value2"), row);
|
|
if (armor_weight < 0 || armor_weight > kExtraStoneMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|额外的石甲重量不正确。|行号 = %d,重量 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
armor_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
|
|
Weight item_type_list[ExtraStoneWeight::kMaxSize];
|
|
::ZeroMemory(item_type_list, sizeof(item_type_list));
|
|
item_type_list[ExtraStoneWeight::kWeapon] = weapon_weight;
|
|
item_type_list[ExtraStoneWeight::kArmor] = armor_weight;
|
|
|
|
const ExtraStoneWeight* weight(new ExtraStoneWeight(extra_stone_size, item_type_list));
|
|
weight_manager_.InsertExtraStoneWeight(weight);
|
|
}
|
|
break;
|
|
case kZardOptionPoint:
|
|
{
|
|
enum { kZardOptionPointMaxWeight = 9999 };
|
|
const ZardOptionPoint zard_option_point = GetDataInt(_T("SGroup"), row);
|
|
const Weight weight = GetDataFloat(_T("Value1"), row);
|
|
if (weight < 0 || weight > kZardOptionPointMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|Jard 选项点权重不正确。|行号 = %d,权重 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
weight_manager_.InsertZardOptionPointWeight(zard_option_point, weight);
|
|
}
|
|
break;
|
|
case kOption:
|
|
{
|
|
enum { kOptionMaxWeight = 9999 };
|
|
const WORD item_option_code = GetDataWORD(_T("SGroup"), row);
|
|
if (item_option_code == 0 || item_option_code >= _countof(g_ITEM_OPTION))
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|未知的选项代码。|行号 = %d,选项代码 = %u|"),
|
|
__FUNCTION__,
|
|
row,
|
|
item_option_code);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight fix_weight = GetDataFloat(_T("Value1"), row);
|
|
if (fix_weight < 0 || fix_weight > kOptionMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|选项固定值权重不正确。|行号 = %d,权重 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
fix_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const Weight ratio_weight = GetDataFloat(_T("Value2"), row);
|
|
if (ratio_weight < 0 || ratio_weight > kOptionMaxWeight)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|选项百分比值权重不正确。|行号 = %d,权重 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
ratio_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const int readed_reverse_benefit = GetDataInt(_T("Value3"), row);
|
|
if (readed_reverse_benefit != 0 && readed_reverse_benefit != 1)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|选项是否反向盈利。|行号 = %d,反向盈利与否 = %d|"),
|
|
__FUNCTION__,
|
|
row,
|
|
readed_reverse_benefit);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
const bool is_reverse_benefit = (readed_reverse_benefit == 1);
|
|
|
|
const eATTR_TYPE attr_option_code = g_ITEM_OPTION[item_option_code];
|
|
Weight value_type_list[OptionWeight::kMaxSize];
|
|
::ZeroMemory(value_type_list, sizeof(value_type_list));
|
|
value_type_list[OptionWeight::kFix] = fix_weight;
|
|
value_type_list[OptionWeight::kRatio] = ratio_weight;
|
|
|
|
const OptionWeight* weight(
|
|
new OptionWeight(attr_option_code, is_reverse_benefit, value_type_list));
|
|
weight_manager_.InsertOptionWeight(weight);
|
|
}
|
|
break;
|
|
#ifdef _NA_008124_20150313_AWAKENING_SYSTEM
|
|
case kAwakening:
|
|
{
|
|
const int unused = GetDataInt(_T("SGroup"), row);
|
|
Weight weapon_weight = GetDataFloat(_T("Value1"), row);
|
|
if (!weight_manager_.SetAwakeningWeight(weapon_weight, AwakeningWeight::kWeapon))
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|唤醒权重不正确。|行号 = %d,权重 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
weapon_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
|
|
Weight armor_weight = GetDataFloat(_T("Value2"), row);
|
|
if (!weight_manager_.SetAwakeningWeight(armor_weight, AwakeningWeight::kArmor))
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|唤醒权重不正确。|行号 = %d,权重 = %f|"),
|
|
__FUNCTION__,
|
|
row,
|
|
armor_weight);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
}
|
|
break;
|
|
#endif // _NA_008124_20150313_AWAKENING_SYSTEM
|
|
default:
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s|未知的主要类别。|行号 = %d,主要类别 = %d|"),
|
|
__FUNCTION__,
|
|
row,
|
|
large_group);
|
|
assert(false);
|
|
continue;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
ItemScoreParser::Weight ItemScoreParser::CalculateOptionWeight(
|
|
const BASE_ITEMINFO::OptionIndexes& option_indexes,
|
|
const BASE_ITEMINFO::OptionTypes& option_types,
|
|
const BASE_ITEMINFO::OptionValues& option_values) const
|
|
{
|
|
Weight weight = 0;
|
|
for (int i = 0; i < _countof(option_indexes); ++i)
|
|
{
|
|
const WORD item_option_code = option_indexes[i];
|
|
if (item_option_code == 0 || item_option_code >= _countof(g_ITEM_OPTION))
|
|
{
|
|
continue;
|
|
}
|
|
if (option_values[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
OptionWeight::ValueType option_value_type = OptionWeight::kMaxSize;
|
|
if (option_types[i] == VALUE_TYPE_VALUE ||
|
|
option_types[i] == VALUE_TYPE_RATIO_VALUE)
|
|
{
|
|
option_value_type = OptionWeight::kFix;
|
|
}
|
|
else if (option_types[i] == VALUE_TYPE_PERCENT_PER_CUR)
|
|
{
|
|
option_value_type = OptionWeight::kRatio;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
const eATTR_TYPE attr_option_code = g_ITEM_OPTION[item_option_code];
|
|
const Weight option_weight =
|
|
weight_manager_.FindOptionWeight(attr_option_code, option_value_type);
|
|
if (option_weight != 0)
|
|
{
|
|
// 期权得分=期权权重*期权价值
|
|
weight += (option_weight * option_values[i]);
|
|
}
|
|
}
|
|
return weight;
|
|
} |