#include "stdafx.h" #include "GMCmdManager.h" // // @history // CHANGES: f110103.4L, added file. this file is used to modify various formula constant values. #include "CharacterFormula.h" // Internal utilities #include "./GMHandler_InterUtils.hxx" namespace nsGM { ; static bool ProcessFormulaList(DWORD player_key, const GmCmdTokens& cmd_tokens) { GMCmdManager* const gm_manager = GMCmdManager::Instance(); Player* player = gm_manager->GetGMPlayer(player_key); if (player == NULL) { return false; } #if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_) ;{ MSG_CG_GM_STRING_CMD_NAK msg_nak; msg_nak.m_byErrorCode = RC::RC_GM_CMD_FAILED; player->SendPacket(&msg_nak, sizeof(msg_nak)); }; return false; #endif #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ MSG_CG_ETC_DEBUGINFO_CMD msg_cmd; int written = _snprintf(msg_cmd.m_pszChatMsg, _countof(msg_cmd.m_pszChatMsg), "List = { damage_formula, critical_formula }"); msg_cmd.m_pszChatMsg[_countof(msg_cmd.m_pszChatMsg) - 1] = '\0'; msg_cmd.m_byMsgLength = static_cast(min(written, _countof(msg_cmd.m_pszChatMsg))); player->SendPacket(&msg_cmd, msg_cmd.GetSize()); return true; #endif }; // query command // '//damage_formula' // '//µ¥¹ÌÁö°ø½Ä' // change command // '//damage_formula [C1] [C2] [C3.1] [C3.2]' // '//µ¥¹ÌÁö°ø½Ä [C1] [C2] [C3.1] [C3.2]' // C1 = °ø°ÝÀÚ ·¹º§ °¡ÁßÄ¡ // C2 = °ø°Ý/¹æ¾îÀÚ °£ÀÇ ·¹º§ Â÷ÀÌ // C3.1 = PvP µ¥¹ÌÁö Â÷°¨·ü // C3.2 = PvE µ¥¹ÌÁö Â÷°¨·ü static bool ProcessDamageFormula(DWORD player_key, const GmCmdTokens& cmd_tokens) { GMCmdManager* const gm_manager = GMCmdManager::Instance(); Player* player = gm_manager->GetGMPlayer(player_key); if (player == NULL) { return false; } #if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_) ;{ MSG_CG_GM_STRING_CMD_NAK msg_nak; msg_nak.m_byErrorCode = RC::RC_GM_CMD_FAILED; player->SendPacket(&msg_nak, sizeof(msg_nak)); }; return false; #endif #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ bool processed = false; const int number_of_arguments = cmd_tokens.size(); if (number_of_arguments == 5) { processed = true; ep2::DamageBalanceConstant constants = { 0, }; constants.attacker_level_weight = atof(cmd_tokens[1].c_str()); constants.diff_level_weight = atof(cmd_tokens[2].c_str()); constants.damage_deduction_pvp_weight = atof(cmd_tokens[3].c_str()); constants.damage_deduction_pve_weight = atof(cmd_tokens[4].c_str()); ep2::ModifyDamageBalanceConstant(constants); } // query command if (number_of_arguments == 1 || number_of_arguments == 5) { processed = true; ep2::DamageBalanceConstant constants; ep2::GetCurrentDamageBalanceConstant(&constants); MSG_CG_ETC_DEBUGINFO_CMD msg_cmd; int written = _snprintf(msg_cmd.m_pszChatMsg, _countof(msg_cmd.m_pszChatMsg), "AttackerWeight = %.4f, DiffLevelWeight = %.4f, " "PvPdeduction = %.4f, PvEdeduction = %.4f", constants.attacker_level_weight, constants.diff_level_weight, constants.damage_deduction_pvp_weight, constants.damage_deduction_pve_weight); msg_cmd.m_pszChatMsg[_countof(msg_cmd.m_pszChatMsg) - 1] = '\0'; msg_cmd.m_byMsgLength = static_cast(min(written, _countof(msg_cmd.m_pszChatMsg))); player->SendPacket(&msg_cmd, msg_cmd.GetSize()); return true; } // ;{ MSG_CG_GM_STRING_CMD_NAK msg_nak; msg_nak.m_byErrorCode = RC::RC_GM_CMD_FAILED; player->SendPacket(&msg_nak, sizeof(msg_nak)); }; if (processed == false) { MSG_CG_ETC_DEBUGINFO_CMD msg_cmd; int written = _snprintf(msg_cmd.m_pszChatMsg, _countof(msg_cmd.m_pszChatMsg), "Usage = " "\"//damage_formula [AttackerWeight] [DiffLevelWeight] " "[PvPdeduction] [PvEdeduction]\""); msg_cmd.m_pszChatMsg[_countof(msg_cmd.m_pszChatMsg) - 1] = '\0'; msg_cmd.m_byMsgLength = static_cast(min(written, _countof(msg_cmd.m_pszChatMsg))); player->SendPacket(&msg_cmd, msg_cmd.GetSize()); } return false; #endif }; // query command // '//critical_formula' // '//Å©¸®Æ¼Äðø½Ä' // change command // '//critical_formula [C1] [C2] [C3] [C4] [C5]' // '//Å©¸®Æ¼Äðø½Ä [C1] [C2] [C3] [C4] [C5]' // C1 = ¹ö¼­Ä¿ // C2 = µå·¡°ï³ªÀÌÆ® // C3 = ¼Îµµ¿ì // C4 = ¹ß۸® // C5 = ¿¤¸®¸àÅ»¸®½ºÆ® static bool ProcessCriticalFormula(DWORD player_key, const GmCmdTokens& cmd_tokens) { GMCmdManager* const gm_manager = GMCmdManager::Instance(); Player* player = gm_manager->GetGMPlayer(player_key); if (player == NULL) { return false; } #if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_) ;{ MSG_CG_GM_STRING_CMD_NAK msg_nak; msg_nak.m_byErrorCode = RC::RC_GM_CMD_FAILED; player->SendPacket(&msg_nak, sizeof(msg_nak)); }; return false; #endif #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ bool processed = false; const int number_of_arguments = cmd_tokens.size(); if (number_of_arguments == eCHAR_TYPE_MAX) { processed = true; ns_formula::CriticalBalanceConstants constants = { 0, }; constants.kNumberatorWeight = -1.0f; constants.kDenominatorWeight = -1.0f; constants.base_probabilies[eCHAR_BERSERKER] = atof(cmd_tokens[1].c_str()); constants.base_probabilies[eCHAR_DRAGON] = atof(cmd_tokens[2].c_str()); constants.base_probabilies[eCHAR_SHADOW] = atof(cmd_tokens[3].c_str()); constants.base_probabilies[eCHAR_VALKYRIE] = atof(cmd_tokens[4].c_str()); constants.base_probabilies[eCHAR_ELEMENTALIST] = atof(cmd_tokens[5].c_str()); // _NA_004965_20120613_NEW_CHARACTER_MYSTIC constants.base_probabilies[eCHAR_MYSTIC] = atof(cmd_tokens[6].c_str()); //_NA_000000_20130812_NEW_CHARACTER_HELLROID constants.base_probabilies[eCHAR_HELLROID] = atof(cmd_tokens[7].c_str()); #ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE constants.base_probabilies[eCHAR_WITCHBLADE] = atof(cmd_tokens[8].c_str()); #endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE ns_formula::BalanceConstantsChangerInProgramCommon::ModifyCriticalChance(constants); } // query command if (number_of_arguments == 1 || number_of_arguments == eCHAR_TYPE_MAX) { processed = true; ns_formula::CriticalBalanceConstants constants; ns_formula::BalanceConstantsChangerInProgramCommon::GetCriticalChance(&constants); // MSG_CG_ETC_DEBUGINFO_CMD msg_cmd; int written = _snprintf(msg_cmd.m_pszChatMsg, _countof(msg_cmd.m_pszChatMsg), "Berserker=(%.2f/100), DragonKnight=(%.2f/100), Shadow=(%.2f/100)," "Valkyrie=(%.2f/100), Elementalist=(%.2f/100), Mystic=(%.2f/100)", constants.base_probabilies[eCHAR_BERSERKER], constants.base_probabilies[eCHAR_DRAGON], constants.base_probabilies[eCHAR_SHADOW], constants.base_probabilies[eCHAR_VALKYRIE], constants.base_probabilies[eCHAR_ELEMENTALIST], constants.base_probabilies[eCHAR_MYSTIC]); msg_cmd.m_pszChatMsg[_countof(msg_cmd.m_pszChatMsg) - 1] = '\0'; msg_cmd.m_byMsgLength = static_cast(min(written, _countof(msg_cmd.m_pszChatMsg))); player->SendPacket(&msg_cmd, msg_cmd.GetSize()); return true; } // ;{ MSG_CG_GM_STRING_CMD_NAK msg_nak; msg_nak.m_byErrorCode = RC::RC_GM_CMD_FAILED; player->SendPacket(&msg_nak, sizeof(msg_nak)); }; if (processed == false) { MSG_CG_ETC_DEBUGINFO_CMD msg_cmd; int written = _snprintf(msg_cmd.m_pszChatMsg, _countof(msg_cmd.m_pszChatMsg), "Usage = " "\"//critical_formula [Berserker:C1] [DragonKnight:C2] " " [Shadow:C3] [Valkyrie:C4] [Elementalist:C5] [Mystic:C6]\""); msg_cmd.m_pszChatMsg[_countof(msg_cmd.m_pszChatMsg) - 1] = '\0'; msg_cmd.m_byMsgLength = static_cast(min(written, _countof(msg_cmd.m_pszChatMsg))); player->SendPacket(&msg_cmd, msg_cmd.GetSize()); } return false; #endif }; // query command // '//element' // '//¿ø¼Ò' // change command // '//element [C1] [C2]' // '//¿ø¼Ò [C1] [C2]' // [C1] : '(ºÒ/¹°/¹Ù¶÷/´ëÁö/¾ÏÈæ)°ø°Ý' or '(ºÒ/¹°/¹Ù¶÷/´ëÁö/¾ÏÈæ)ÀúÇ×' // [C2] : Çö ±âÁØ º¯°æÇÒ ¼öÄ¡ struct ElementMatchNode { uint8_t is_defense; ulong key; eATTR_TYPE attr_type; }; static bool ProcessChangeElements(DWORD player_key, const GmCmdTokens& cmd_tokens) { GMCmdManager* const gm_manager = GMCmdManager::Instance(); Player* player = gm_manager->GetGMPlayer(player_key); if (player == NULL) { return false; } #if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_) ;{ MSG_CG_GM_STRING_CMD_NAK msg_nak; msg_nak.m_byErrorCode = RC::RC_GM_CMD_FAILED; player->SendPacket(&msg_nak, sizeof(msg_nak)); }; return false; #endif #ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_ static const ElementMatchNode elements_matches[10 * 2] = { { 0, util::StreamHashKey::GetStringHashKey("ºÒ°ø°Ý"), eATTR_MAGICAL_FIRE_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("ºÒÀúÇ×"), eATTR_DEL_FIRE_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("¹°°ø°Ý"), eATTR_MAGICAL_WATER_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("¹°ÀúÇ×"), eATTR_DEL_WATER_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("¹Ù¶÷°ø°Ý"), eATTR_MAGICAL_WIND_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("¹Ù¶÷ÀúÇ×"), eATTR_DEL_WIND_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("´ëÁö°ø°Ý"), eATTR_MAGICAL_EARTH_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("´ëÁöÀúÇ×"), eATTR_DEL_EARTH_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("¾ÏÈæ°ø°Ý"), eATTR_MAGICAL_DARKNESS_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("¾ÏÈæÀúÇ×"), eATTR_DEL_DARKNESS_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("fireattack"), eATTR_MAGICAL_FIRE_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("fireresist"), eATTR_DEL_FIRE_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("waterattack"), eATTR_MAGICAL_WATER_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("waterresist"), eATTR_DEL_WATER_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("windattack"), eATTR_MAGICAL_WIND_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("windresist"), eATTR_DEL_WIND_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("earthattack"), eATTR_MAGICAL_EARTH_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("earthresist"), eATTR_DEL_EARTH_DAMAGE }, { 0, util::StreamHashKey::GetStringHashKey("darkattack"), eATTR_MAGICAL_DARKNESS_ATTACK_POWER }, { 1, util::StreamHashKey::GetStringHashKey("darkresist"), eATTR_DEL_DARKNESS_DAMAGE }, }; bool processed = false; const int number_of_arguments = cmd_tokens.size(); const ElementMatchNode* match_node = NULL; if (number_of_arguments > 1) { char token[20]; strncpy(token, cmd_tokens[1].c_str(), _countof(token)); token[_countof(token) - 1] = '\0'; _strlwr(token); const ulong hash_key = util::StreamHashKey::GetStringHashKey(token); match_node = elements_matches; for ( ; match_node != &elements_matches[_countof(elements_matches)]; ++match_node) { if (match_node->key == hash_key) { break; } } if (match_node == &elements_matches[_countof(elements_matches)]) { match_node = NULL; // not found } }; const Attributes& attributes = player->GetAttr(); if (match_node != NULL && number_of_arguments == 3) { processed = true; const Attributes::Operation oper = { 0, }; Attributes::OperationRecord record = { 0, }; record.operate = oper.eOper_Add; record.attr_kind = eATTR_KIND_BASE; record.attr_type = static_cast(match_node->attr_type); record.attr_value = atoi(cmd_tokens[2].c_str()); const_cast(attributes).GroupBatchOperate(&record, 1); const_cast(attributes).UpdateEx(); ;{ int value = attributes[match_node->attr_type][eATTR_KIND_BASE]; MSG_CG_STATUS_STAT_SELECT_ACK msg_ack; msg_ack.m_dwObjKey = player->GetObjectKey(); msg_ack.m_AttrType = match_node->attr_type; msg_ack.m_dwValue = value; player->SendPacket(&msg_ack, sizeof(msg_ack)); }; return true; } // query command if (number_of_arguments == 1 || number_of_arguments == 3) { processed = true; MSG_CG_ETC_DEBUGINFO_CMD msg_cmd; int written = _snprintf(msg_cmd.m_pszChatMsg, _countof(msg_cmd.m_pszChatMsg), "Element:(Attack/Resist) " "Fire(%d,%d), Water(%d,%d), Wind(%d,%d), Earth(%d,%d), Dark(%d,%d)", attributes[elements_matches[0].attr_type][eATTR_KIND_CALC], attributes[elements_matches[1].attr_type][eATTR_KIND_CALC], attributes[elements_matches[2].attr_type][eATTR_KIND_CALC], attributes[elements_matches[3].attr_type][eATTR_KIND_CALC], attributes[elements_matches[4].attr_type][eATTR_KIND_CALC], attributes[elements_matches[5].attr_type][eATTR_KIND_CALC], attributes[elements_matches[6].attr_type][eATTR_KIND_CALC], attributes[elements_matches[7].attr_type][eATTR_KIND_CALC], attributes[elements_matches[8].attr_type][eATTR_KIND_CALC], attributes[elements_matches[9].attr_type][eATTR_KIND_CALC]); msg_cmd.m_pszChatMsg[_countof(msg_cmd.m_pszChatMsg) - 1] = '\0'; msg_cmd.m_byMsgLength = static_cast(min(written, _countof(msg_cmd.m_pszChatMsg))); player->SendPacket(&msg_cmd, msg_cmd.GetSize()); return true; } // ;{ MSG_CG_GM_STRING_CMD_NAK msg_nak; msg_nak.m_byErrorCode = RC::RC_GM_CMD_FAILED; player->SendPacket(&msg_nak, sizeof(msg_nak)); }; if (processed == false) { MSG_CG_ETC_DEBUGINFO_CMD msg_cmd; int written = _snprintf(msg_cmd.m_pszChatMsg, _countof(msg_cmd.m_pszChatMsg), "Usage = \"//element [" "fireattack|fireresist|" "waterattack|waterresist|" "windattack|windresist|" "earthattack|earthresist|" "darkattack|darkresist] " "[(+/-)value]\""); msg_cmd.m_pszChatMsg[_countof(msg_cmd.m_pszChatMsg) - 1] = '\0'; msg_cmd.m_byMsgLength = static_cast(min(written, _countof(msg_cmd.m_pszChatMsg))); player->SendPacket(&msg_cmd, msg_cmd.GetSize()); } return false; #endif } }; //end of namespace 'nsGM' bool GMCmdManager::RegisterFomulas(const HandlerNode** node_array, size_t* result_array_count) { using namespace nsGM; bool success = false; #define GMHANDLER_MAPPING(activated, korean, english, handler) \ { activated, eGM_GRADE_MAX, 0xFFFFFFFF, 0xFFFFFFFF, handler, korean, english } static HandlerNode const_node_array[] = { GMHANDLER_MAPPING(true, "°ø½Ä¸ñ·Ï", "formula_list", &ProcessFormulaList), GMHANDLER_MAPPING(true, "µ¥¹ÌÁö°ø½Ä", "damage_formula", &ProcessDamageFormula), GMHANDLER_MAPPING(true, "Å©¸®Æ¼Äðø½Ä", "critical_formula", &ProcessCriticalFormula), GMHANDLER_MAPPING(true, "¿ø¼Ò", "element", &ProcessChangeElements), }; // ModifyGmHandlerNode(const_node_array, _countof(const_node_array)); *node_array = const_node_array; *result_array_count = _countof(const_node_array); success = true; // return success; }