|
@@ -1,6 +1,13 @@
|
|
|
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
|
|
// For more information, see LICENCE in the main folder
|
|
|
|
|
|
+#include "status.hpp"
|
|
|
+
|
|
|
+#include <stdlib.h>
|
|
|
+#include <math.h>
|
|
|
+#include <string>
|
|
|
+#include <yaml-cpp/yaml.h>
|
|
|
+
|
|
|
#include "../common/cbasetypes.h"
|
|
|
#include "../common/timer.h"
|
|
|
#include "../common/nullpo.h"
|
|
@@ -10,22 +17,23 @@
|
|
|
#include "../common/utils.h"
|
|
|
#include "../common/ers.h"
|
|
|
#include "../common/strlib.h"
|
|
|
-#include "../common/yamlwrapper.h"
|
|
|
-
|
|
|
-#include "battle.h"
|
|
|
-#include "itemdb.h"
|
|
|
-#include "map.h"
|
|
|
-#include "path.h"
|
|
|
-#include "pc.h"
|
|
|
-#include "pet.h"
|
|
|
-#include "battleground.h"
|
|
|
-#include "homunculus.h"
|
|
|
-#include "mercenary.h"
|
|
|
-#include "elemental.h"
|
|
|
-#include "script.h"
|
|
|
|
|
|
-#include <stdlib.h>
|
|
|
-#include <math.h>
|
|
|
+#include "battle.hpp"
|
|
|
+#include "itemdb.hpp"
|
|
|
+#include "map.hpp"
|
|
|
+#include "path.hpp"
|
|
|
+#include "pc.hpp"
|
|
|
+#include "pet.hpp"
|
|
|
+#include "battleground.hpp"
|
|
|
+#include "homunculus.hpp"
|
|
|
+#include "mercenary.hpp"
|
|
|
+#include "elemental.hpp"
|
|
|
+#include "script.hpp"
|
|
|
+#include "npc.hpp"
|
|
|
+#include "guild.hpp"
|
|
|
+#include "clif.hpp"
|
|
|
+#include "mob.hpp"
|
|
|
+#include "pc_groups.hpp"
|
|
|
|
|
|
// Regen related flags.
|
|
|
enum e_regen {
|
|
@@ -104,7 +112,7 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned
|
|
|
static int status_get_sc_interval(enum sc_type type);
|
|
|
|
|
|
static bool status_change_isDisabledOnMap_(sc_type type, bool mapIsVS, bool mapIsPVP, bool mapIsGVG, bool mapIsBG, unsigned int mapZone, bool mapIsTE);
|
|
|
-#define status_change_isDisabledOnMap(type, m) ( status_change_isDisabledOnMap_((type), map_flag_vs2((m)), map[(m)].flag.pvp, map_flag_gvg2_no_te((m)), map[(m)].flag.battleground, map[(m)].zone << 3, map_flag_gvg2_te((m))) )
|
|
|
+#define status_change_isDisabledOnMap(type, m) ( status_change_isDisabledOnMap_((type), map_flag_vs2((m)), map[(m)].flag.pvp != 0, map_flag_gvg2_no_te((m)), map[(m)].flag.battleground != 0, (map[(m)].zone << 3) != 0, map_flag_gvg2_te((m))) )
|
|
|
|
|
|
/**
|
|
|
* Returns the status change associated with a skill.
|
|
@@ -2801,7 +2809,7 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt)
|
|
|
break;
|
|
|
case AM_CANNIBALIZE:
|
|
|
status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
|
|
|
- status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
|
|
|
+ status->mode = static_cast<e_mode>(status->mode|MD_CANATTACK|MD_AGGRESSIVE);
|
|
|
break;
|
|
|
case MH_SUMMON_LEGION:
|
|
|
{
|
|
@@ -2863,7 +2871,7 @@ void status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
|
|
|
|
|
|
if(battle_config.pet_attack_support || battle_config.pet_damage_support) {
|
|
|
// Attack support requires the pet to be able to attack
|
|
|
- pd->status.mode |= MD_CANATTACK;
|
|
|
+ pd->status.mode = static_cast<e_mode>(pd->status.mode|MD_CANATTACK);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3322,8 +3330,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
|
|
|
sd->regen.state.block = 0;
|
|
|
sd->add_max_weight = 0;
|
|
|
|
|
|
- // Zeroed arrays, order follows the order in pc.h.
|
|
|
- // Add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
|
|
|
+ // Zeroed arrays, order follows the order in pc.hpp.
|
|
|
+ // Add new arrays to the end of zeroed area in pc.hpp (see comments) and size here. [zzo]
|
|
|
memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
|
|
|
+ sizeof(sd->param_equip)
|
|
|
+ sizeof(sd->subele)
|
|
@@ -3388,7 +3396,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
|
|
|
|
|
|
// !FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
|
|
|
// Give them all modes except these (useful for clones)
|
|
|
- base_status->mode = MD_MASK&~(MD_STATUS_IMMUNE|MD_IGNOREMELEE|MD_IGNOREMAGIC|MD_IGNORERANGED|MD_IGNOREMISC|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
|
|
|
+ base_status->mode = static_cast<e_mode>(MD_MASK&~(MD_STATUS_IMMUNE|MD_IGNOREMELEE|MD_IGNOREMAGIC|MD_IGNORERANGED|MD_IGNOREMISC|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK));
|
|
|
|
|
|
base_status->size = (sd->class_&JOBL_BABY || (sd->class_&MAPID_BASEMASK) == MAPID_SUMMONER) ? SZ_SMALL : SZ_MEDIUM;
|
|
|
if (battle_config.character_size && pc_isriding(sd)) { // [Lupus]
|
|
@@ -4200,7 +4208,7 @@ int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt
|
|
|
if (opt&SCO_FIRST) {
|
|
|
memcpy(status, &md->db->status, sizeof(struct status_data));
|
|
|
status->class_ = CLASS_NORMAL;
|
|
|
- status->mode = MD_CANMOVE|MD_CANATTACK;
|
|
|
+ status->mode = static_cast<e_mode>(MD_CANMOVE|MD_CANATTACK);
|
|
|
status->hp = status->max_hp;
|
|
|
status->sp = status->max_sp;
|
|
|
md->battle_status.hp = merc->hp;
|
|
@@ -4245,7 +4253,7 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
|
|
|
status->class_ = CLASS_NORMAL;
|
|
|
status->size = (hom->class_ == db->evo_class) ? db->evo_size : db->base_size;
|
|
|
status->rhw.range = 1 + status->size;
|
|
|
- status->mode = MD_CANMOVE|MD_CANATTACK;
|
|
|
+ status->mode = static_cast<e_mode>(MD_CANMOVE|MD_CANATTACK);
|
|
|
status->speed = DEFAULT_WALK_SPEED;
|
|
|
if (battle_config.hom_setting&HOMSET_COPY_SPEED && hd->master)
|
|
|
status->speed = status_get_speed(&hd->master->bl);
|
|
@@ -4385,7 +4393,7 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
|
|
|
status->class_ = CLASS_NORMAL;
|
|
|
status->size = nd->size;
|
|
|
status->rhw.range = 1 + status->size;
|
|
|
- status->mode = (MD_CANMOVE|MD_CANATTACK);
|
|
|
+ status->mode = static_cast<e_mode>(MD_CANMOVE|MD_CANATTACK);
|
|
|
status->speed = nd->speed;
|
|
|
}
|
|
|
|
|
@@ -7215,16 +7223,16 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
|
|
|
static enum e_mode status_calc_mode(struct block_list *bl, struct status_change *sc, enum e_mode mode)
|
|
|
{
|
|
|
if(!sc || !sc->count)
|
|
|
- return cap_value(mode, 0, INT_MAX);
|
|
|
+ return cap_value(mode, MD_NONE, static_cast<e_mode>(INT_MAX));
|
|
|
if(sc->data[SC_MODECHANGE]) {
|
|
|
if (sc->data[SC_MODECHANGE]->val2)
|
|
|
- mode = (mode&~MD_MASK)|sc->data[SC_MODECHANGE]->val2; // Set mode
|
|
|
+ mode = static_cast<e_mode>((mode&~MD_MASK)|sc->data[SC_MODECHANGE]->val2); // Set mode
|
|
|
if (sc->data[SC_MODECHANGE]->val3)
|
|
|
- mode|= sc->data[SC_MODECHANGE]->val3; // Add mode
|
|
|
+ mode = static_cast<e_mode>(mode|sc->data[SC_MODECHANGE]->val3); // Add mode
|
|
|
if (sc->data[SC_MODECHANGE]->val4)
|
|
|
- mode&=~sc->data[SC_MODECHANGE]->val4; // Del mode
|
|
|
+ mode = static_cast<e_mode>(mode&~sc->data[SC_MODECHANGE]->val4); // Del mode
|
|
|
}
|
|
|
- return cap_value(mode, 0, INT_MAX);
|
|
|
+ return cap_value(mode, MD_NONE, static_cast<e_mode>(INT_MAX));
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -8572,9 +8580,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
|
|
val3 |= sc->data[type]->val3;
|
|
|
val4 |= sc->data[type]->val4;
|
|
|
}
|
|
|
- mode = val2 ? ((val2&~MD_MASK)|val2) : bstatus->mode; // Base mode
|
|
|
- if (val4) mode&=~val4; // Del mode
|
|
|
- if (val3) mode|= val3; // Add mode
|
|
|
+ mode = val2 ? static_cast<e_mode>((val2&~MD_MASK)|val2) : bstatus->mode; // Base mode
|
|
|
+ if (val4) mode = static_cast<e_mode>(mode&~val4); // Del mode
|
|
|
+ if (val3) mode = static_cast<e_mode>(mode|val3); // Add mode
|
|
|
if (mode == bstatus->mode) { // No change.
|
|
|
if (sc->data[type]) // Abort previous status
|
|
|
return status_change_end(bl, type, INVALID_TIMER);
|
|
@@ -11810,7 +11818,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
|
|
struct status_change_entry *sce;
|
|
|
struct status_data *status;
|
|
|
struct view_data *vd;
|
|
|
- int opt_flag = 0, calc_flag;
|
|
|
+ int opt_flag = 0;
|
|
|
+ enum scb_flag calc_flag = SCB_NONE;
|
|
|
|
|
|
nullpo_ret(bl);
|
|
|
|
|
@@ -11898,7 +11907,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
|
|
status_display_remove(bl,type);
|
|
|
|
|
|
vd = status_get_viewdata(bl);
|
|
|
- calc_flag = StatusChangeFlagTable[type];
|
|
|
+ calc_flag = static_cast<scb_flag>(StatusChangeFlagTable[type]);
|
|
|
switch(type) {
|
|
|
case SC_GRANITIC_ARMOR:
|
|
|
{
|
|
@@ -12530,14 +12539,14 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
|
|
if (calc_flag&SCB_DYE) { // Restore DYE color
|
|
|
if (vd && !vd->cloth_color && sce->val4)
|
|
|
clif_changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
|
|
|
- calc_flag&=~SCB_DYE;
|
|
|
+ calc_flag = static_cast<scb_flag>(calc_flag&~SCB_DYE);
|
|
|
}
|
|
|
|
|
|
/*if (calc_flag&SCB_BODY)// Might be needed in the future. [Rytech]
|
|
|
{ //Restore body style
|
|
|
if (vd && !vd->body_style && sce->val4)
|
|
|
clif_changelook(bl,LOOK_BODY2,sce->val4);
|
|
|
- calc_flag&=~SCB_BODY;
|
|
|
+ calc_flag = static_cast<scb_flag>(calc_flag&~SCB_BODY);
|
|
|
}*/
|
|
|
|
|
|
// On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
|
|
@@ -12708,12 +12717,12 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
case SC_POISON:
|
|
|
case SC_DPOISON:
|
|
|
if (sce->val4 >= 0 && !sc->data[SC_SLOWPOISON]) {
|
|
|
- int64 damage = 0;
|
|
|
+ unsigned int damage = 0;
|
|
|
if (sd)
|
|
|
damage = (type == SC_DPOISON) ? 2 + status->max_hp / 50 : 2 + status->max_hp * 3 / 200;
|
|
|
else
|
|
|
damage = (type == SC_DPOISON) ? 2 + status->max_hp / 100 : 2 + status->max_hp / 200;
|
|
|
- if (status->hp > max(status->max_hp / 4, damage)) // Stop damaging after 25% HP left.
|
|
|
+ if (status->hp > umax(status->max_hp / 4, damage)) // Stop damaging after 25% HP left.
|
|
|
status_zap(bl, damage, 0);
|
|
|
}
|
|
|
break;
|
|
@@ -13306,9 +13315,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
|
|
if( !status_charge(bl,0,sce->val2) ) {
|
|
|
struct block_list *s_bl = battle_get_master(bl);
|
|
|
if (bl->type == BL_ELEM)
|
|
|
- elemental_change_mode(BL_CAST(BL_ELEM, bl), MAX_ELESKILLTREE);
|
|
|
+ elemental_change_mode(BL_CAST(BL_ELEM, bl), static_cast<e_mode>(MAX_ELESKILLTREE));
|
|
|
if( s_bl )
|
|
|
- status_change_end(s_bl,type+1,INVALID_TIMER);
|
|
|
+ status_change_end(s_bl,static_cast<sc_type>(type+1),INVALID_TIMER);
|
|
|
status_change_end(bl,type,INVALID_TIMER);
|
|
|
break;
|
|
|
}
|
|
@@ -13564,7 +13573,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
|
|
|
break;
|
|
|
case SC_TINDER_BREAKER:
|
|
|
case SC_CLOSECONFINE:{
|
|
|
- int type2 = ((type==SC_CLOSECONFINE)?SC_CLOSECONFINE2:SC_TINDER_BREAKER2);
|
|
|
+ enum sc_type type2 = ((type==SC_CLOSECONFINE)?SC_CLOSECONFINE2:SC_TINDER_BREAKER2);
|
|
|
// Lock char has released the hold on everyone...
|
|
|
if (tsc && tsc->data[type2] && tsc->data[type2]->val2 == src->id) {
|
|
|
tsc->data[type2]->val2 = 0;
|
|
@@ -14172,9 +14181,9 @@ void status_change_clear_onChangeMap(struct block_list *bl, struct status_change
|
|
|
if (sc && sc->count) {
|
|
|
unsigned short i;
|
|
|
bool mapIsVS = map_flag_vs2(bl->m);
|
|
|
- bool mapIsPVP = map[bl->m].flag.pvp;
|
|
|
+ bool mapIsPVP = map[bl->m].flag.pvp != 0;
|
|
|
bool mapIsGVG = map_flag_gvg2_no_te(bl->m);
|
|
|
- bool mapIsBG = map[bl->m].flag.battleground;
|
|
|
+ bool mapIsBG = map[bl->m].flag.battleground != 0;
|
|
|
bool mapIsTE = map_flag_gvg2_te(bl->m);
|
|
|
unsigned int mapZone = map[bl->m].zone << 3;
|
|
|
|
|
@@ -14234,85 +14243,68 @@ static bool status_readdb_sizefix(char* fields[], int columns, int current)
|
|
|
|
|
|
/**
|
|
|
* Reads and parses an entry from the refine_db
|
|
|
- * @param wrapper: The YAML wrapper containing the entry
|
|
|
+ * @param node: The YAML node containing the entry
|
|
|
* @param refine_info_index: The sequential index of the current entry
|
|
|
* @param file_name: File name for displaying only
|
|
|
* @return True on success or false on failure
|
|
|
*/
|
|
|
-static bool status_yaml_readdb_refine_sub(yamlwrapper* wrapper, int refine_info_index, char* file_name) {
|
|
|
+static bool status_yaml_readdb_refine_sub(const YAML::Node &node, int refine_info_index, const std::string &file_name) {
|
|
|
if (refine_info_index < 0 || refine_info_index >= REFINE_TYPE_MAX)
|
|
|
return false;
|
|
|
|
|
|
- int bonus_per_level = yaml_get_int(wrapper, "StatsPerLevel");
|
|
|
- int random_bonus_start_level = yaml_get_int(wrapper, "RandomBonusStartLevel");
|
|
|
- int random_bonus = yaml_get_int(wrapper, "RandomBonusValue");
|
|
|
-
|
|
|
- yamlwrapper* costs = yaml_get_subnode(wrapper, "Costs");
|
|
|
- yamliterator* it = yaml_get_iterator(costs);
|
|
|
- if (yaml_iterator_is_valid(it)) {
|
|
|
- for (yamlwrapper* type = yaml_iterator_first(it); yaml_iterator_has_next(it); type = yaml_iterator_next(it)) {
|
|
|
- int idx = 0, price;
|
|
|
- unsigned short material;
|
|
|
- static char* keys[] = {"Type", "Price", "Material" };
|
|
|
- char* result;
|
|
|
-
|
|
|
- if ((result = yaml_verify_nodes(type, ARRAYLENGTH(keys), keys)) != NULL) {
|
|
|
- ShowWarning("status_yaml_readdb_refine_sub: Invalid refine cost with undefined " CL_WHITE "%s" CL_RESET "in file" CL_WHITE "%s" CL_RESET ".\n", result, file_name);
|
|
|
- yaml_destroy_wrapper(type);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- char* refine_cost_const = yaml_get_c_string(type, "Type");
|
|
|
- if (ISDIGIT(refine_cost_const[0]))
|
|
|
- idx = atoi(refine_cost_const);
|
|
|
- else
|
|
|
- script_get_constant(refine_cost_const, &idx);
|
|
|
- price = yaml_get_int(type, "Price");
|
|
|
- material = yaml_get_uint16(type, "Material");
|
|
|
+ int bonus_per_level = node["StatsPerLevel"].as<int>();
|
|
|
+ int random_bonus_start_level = node["RandomBonusStartLevel"].as<int>();
|
|
|
+ int random_bonus = node["RandomBonusValue"].as<int>();
|
|
|
+ const YAML::Node &costs = node["Costs"];
|
|
|
|
|
|
- refine_info[refine_info_index].cost[idx].nameid = material;
|
|
|
- refine_info[refine_info_index].cost[idx].zeny = price;
|
|
|
+ for (const auto costit : costs) {
|
|
|
+ const YAML::Node &type = costit;
|
|
|
+ int idx = 0, price;
|
|
|
+ unsigned short material;
|
|
|
+ const std::string keys[] = { "Type", "Price", "Material" };
|
|
|
|
|
|
- aFree(refine_cost_const);
|
|
|
- yaml_destroy_wrapper(type);
|
|
|
+ for (int i = 0; i < ARRAYLENGTH(keys); i++) {
|
|
|
+ if (!type[keys[i]].IsDefined())
|
|
|
+ ShowWarning("status_yaml_readdb_refine_sub: Invalid refine cost with undefined " CL_WHITE "%s" CL_RESET "in file" CL_WHITE "%s" CL_RESET ".\n", keys[i].c_str(), file_name.c_str());
|
|
|
}
|
|
|
+
|
|
|
+ std::string refine_cost_const = type["Type"].as<std::string>();
|
|
|
+ if (ISDIGIT(refine_cost_const[0]))
|
|
|
+ idx = atoi(refine_cost_const.c_str());
|
|
|
+ else
|
|
|
+ script_get_constant(refine_cost_const.c_str(), &idx);
|
|
|
+ price = type["Price"].as<int>();
|
|
|
+ material = type["Material"].as<uint16>();
|
|
|
+
|
|
|
+ refine_info[refine_info_index].cost[idx].nameid = material;
|
|
|
+ refine_info[refine_info_index].cost[idx].zeny = price;
|
|
|
}
|
|
|
- yaml_destroy_wrapper(costs);
|
|
|
- yaml_iterator_destroy(it);
|
|
|
|
|
|
- yamlwrapper* rates = yaml_get_subnode(wrapper, "Rates");
|
|
|
- it = yaml_get_iterator(rates);
|
|
|
+ const YAML::Node &rates = node["Rates"];
|
|
|
|
|
|
- if (yaml_iterator_is_valid(it)) {
|
|
|
- for (yamlwrapper* level = yaml_iterator_first(it); yaml_iterator_has_next(it); level = yaml_iterator_next(it)) {
|
|
|
- int refine_level = yaml_get_int(level, "Level") - 1;
|
|
|
+ for (const auto rateit : rates) {
|
|
|
+ const YAML::Node &level = rateit;
|
|
|
+ int refine_level = level["Level"].as<int>() - 1;
|
|
|
|
|
|
- if (refine_level >= MAX_REFINE) {
|
|
|
- yaml_destroy_wrapper(level);
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (refine_level >= MAX_REFINE)
|
|
|
+ continue;
|
|
|
|
|
|
- if (yaml_node_is_defined(level, "NormalChance"))
|
|
|
- refine_info[refine_info_index].chance[REFINE_CHANCE_NORMAL][refine_level] = yaml_get_int(level, "NormalChance");
|
|
|
- if (yaml_node_is_defined(level, "EnrichedChance"))
|
|
|
- refine_info[refine_info_index].chance[REFINE_CHANCE_ENRICHED][refine_level] = yaml_get_int(level, "EnrichedChance");
|
|
|
- if (yaml_node_is_defined(level, "EventNormalChance"))
|
|
|
- refine_info[refine_info_index].chance[REFINE_CHANCE_EVENT_NORMAL][refine_level] = yaml_get_int(level, "EventNormalChance");
|
|
|
- if (yaml_node_is_defined(level, "EventEnrichedChance"))
|
|
|
- refine_info[refine_info_index].chance[REFINE_CHANCE_EVENT_ENRICHED][refine_level] = yaml_get_int(level, "EventEnrichedChance");
|
|
|
- if (yaml_node_is_defined(level, "Bonus"))
|
|
|
- refine_info[refine_info_index].bonus[refine_level] = yaml_get_int(level, "Bonus");
|
|
|
+ if (level["NormalChance"].IsDefined())
|
|
|
+ refine_info[refine_info_index].chance[REFINE_CHANCE_NORMAL][refine_level] = level["NormalChance"].as<int>();
|
|
|
+ if (level["EnrichedChance"].IsDefined())
|
|
|
+ refine_info[refine_info_index].chance[REFINE_CHANCE_ENRICHED][refine_level] = level["EnrichedChance"].as<int>();
|
|
|
+ if (level["EventNormalChance"].IsDefined())
|
|
|
+ refine_info[refine_info_index].chance[REFINE_CHANCE_EVENT_NORMAL][refine_level] = level["EventNormalChance"].as<int>();
|
|
|
+ if (level["EventEnrichedChance"].IsDefined())
|
|
|
+ refine_info[refine_info_index].chance[REFINE_CHANCE_EVENT_ENRICHED][refine_level] = level["EventEnrichedChance"].as<int>();
|
|
|
+ if (level["Bonus"].IsDefined())
|
|
|
+ refine_info[refine_info_index].bonus[refine_level] = level["Bonus"].as<int>();
|
|
|
|
|
|
- if (refine_level >= random_bonus_start_level - 1)
|
|
|
- refine_info[refine_info_index].randombonus_max[refine_level] = random_bonus * (refine_level - random_bonus_start_level + 2);
|
|
|
- yaml_destroy_wrapper(level);
|
|
|
- }
|
|
|
- for (int refine_level = 0; refine_level < MAX_REFINE; ++refine_level) {
|
|
|
- refine_info[refine_info_index].bonus[refine_level] += bonus_per_level + (refine_level > 0 ? refine_info[refine_info_index].bonus[refine_level - 1] : 0);
|
|
|
- }
|
|
|
+ if (refine_level >= random_bonus_start_level - 1)
|
|
|
+ refine_info[refine_info_index].randombonus_max[refine_level] = random_bonus * (refine_level - random_bonus_start_level + 2);
|
|
|
}
|
|
|
- yaml_destroy_wrapper(rates);
|
|
|
- yaml_iterator_destroy(it);
|
|
|
+ for (int refine_level = 0; refine_level < MAX_REFINE; ++refine_level)
|
|
|
+ refine_info[refine_info_index].bonus[refine_level] += bonus_per_level + (refine_level > 0 ? refine_info[refine_info_index].bonus[refine_level - 1] : 0);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -14322,32 +14314,27 @@ static bool status_yaml_readdb_refine_sub(yamlwrapper* wrapper, int refine_info_
|
|
|
* @param directory: Location of refine_db file
|
|
|
* @param file: File name
|
|
|
*/
|
|
|
-static void status_yaml_readdb_refine(const char* directory, const char* file) {
|
|
|
+static void status_yaml_readdb_refine(const std::string &directory, const std::string &file) {
|
|
|
int count = 0;
|
|
|
- const char* labels[6] = { "Armor", "WeaponLv1", "WeaponLv2", "WeaponLv3", "WeaponLv4", "Shadow" };
|
|
|
- size_t str_size = strlen(directory) + strlen(file) + 2;
|
|
|
- char* buf = (char*)aCalloc(1, str_size);
|
|
|
- sprintf(buf, "%s/%s", directory, file);
|
|
|
- yamlwrapper* root_node, *sub_node;
|
|
|
-
|
|
|
- if ((root_node = yaml_load_file(buf)) == NULL) {
|
|
|
- ShowError("Failed to read '%s'.\n", buf);
|
|
|
- aFree(buf);
|
|
|
+ const std::string labels[] = { "Armor", "WeaponLv1", "WeaponLv2", "WeaponLv3", "WeaponLv4", "Shadow" };
|
|
|
+ const std::string current_file = directory + "/" + file;
|
|
|
+ YAML::Node config;
|
|
|
+
|
|
|
+ try {
|
|
|
+ config = YAML::LoadFile(current_file);
|
|
|
+ }
|
|
|
+ catch (...) {
|
|
|
+ ShowError("Failed to read '" CL_WHITE "%s" CL_RESET "'.\n", current_file.c_str());
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < ARRAYLENGTH(labels); i++) {
|
|
|
- if (yaml_node_is_defined(root_node, labels[i])) {
|
|
|
- sub_node = yaml_get_subnode(root_node, labels[i]);
|
|
|
- if (status_yaml_readdb_refine_sub(sub_node, i, buf))
|
|
|
- count++;
|
|
|
- yaml_destroy_wrapper(sub_node);
|
|
|
- }
|
|
|
- }
|
|
|
- ShowStatus("Done reading '" CL_WHITE "%d" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, buf);
|
|
|
+ const YAML::Node &node = config[labels[i]];
|
|
|
|
|
|
- yaml_destroy_wrapper(root_node);
|
|
|
- aFree(buf);
|
|
|
+ if (node.IsDefined() && status_yaml_readdb_refine_sub(node, i, file))
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ ShowStatus("Done reading '" CL_WHITE "%d" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, current_file.c_str());
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -14411,7 +14398,7 @@ static bool status_readdb_attrfix(const char *basedir,bool silent)
|
|
|
entries++;
|
|
|
}
|
|
|
fclose(fp);
|
|
|
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entries, path);
|
|
|
+ ShowStatus("Done reading '" CL_WHITE "%d" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", entries, path);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -14430,7 +14417,7 @@ int status_readdb(void)
|
|
|
int i, j, k;
|
|
|
const char* dbsubpath[] = {
|
|
|
"",
|
|
|
- "/"DBIMPORT,
|
|
|
+ "/" DBIMPORT,
|
|
|
//add other path here
|
|
|
};
|
|
|
// Initialize databases to default
|
|
@@ -14475,9 +14462,9 @@ int status_readdb(void)
|
|
|
safesnprintf(dbsubpath2,n1,"%s%s",db_path,dbsubpath[i]);
|
|
|
}
|
|
|
|
|
|
- status_readdb_attrfix(dbsubpath2,i); // !TODO use sv_readdb ?
|
|
|
- sv_readdb(dbsubpath1, "status_disabled.txt", ',', 2, 2, -1, &status_readdb_status_disabled, i);
|
|
|
- sv_readdb(dbsubpath1, "size_fix.txt",',',MAX_WEAPON_TYPE,MAX_WEAPON_TYPE,ARRAYLENGTH(atkmods),&status_readdb_sizefix, i);
|
|
|
+ status_readdb_attrfix(dbsubpath2,i > 0); // !TODO use sv_readdb ?
|
|
|
+ sv_readdb(dbsubpath1, "status_disabled.txt", ',', 2, 2, -1, &status_readdb_status_disabled, i > 0);
|
|
|
+ sv_readdb(dbsubpath1, "size_fix.txt",',',MAX_WEAPON_TYPE,MAX_WEAPON_TYPE,ARRAYLENGTH(atkmods),&status_readdb_sizefix, i > 0);
|
|
|
status_yaml_readdb_refine(dbsubpath2, "refine_db.yml");
|
|
|
aFree(dbsubpath1);
|
|
|
aFree(dbsubpath2);
|
|
@@ -14496,7 +14483,7 @@ int do_init_status(void)
|
|
|
initDummyData();
|
|
|
status_readdb();
|
|
|
natural_heal_prev_tick = gettick();
|
|
|
- sc_data_ers = ers_new(sizeof(struct status_change_entry),"status.c::sc_data_ers",ERS_OPT_NONE);
|
|
|
+ sc_data_ers = ers_new(sizeof(struct status_change_entry),"status.cpp::sc_data_ers",ERS_OPT_NONE);
|
|
|
add_timer_interval(natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status_natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
|
|
|
return 0;
|
|
|
}
|