diff options
Diffstat (limited to 'src/map/mob.cpp')
-rw-r--r-- | src/map/mob.cpp | 802 |
1 files changed, 406 insertions, 396 deletions
diff --git a/src/map/mob.cpp b/src/map/mob.cpp index a96f829..dd061d0 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -23,8 +23,6 @@ #include <cassert> #include <cmath> -#include <cstdlib> -#include <cstring> #include <algorithm> @@ -32,17 +30,21 @@ #include "../compat/nullpo.hpp" #include "../strings/astring.hpp" +#include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" +#include "../io/cxxstdio_enums.hpp" #include "../io/read.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" + #include "../mmo/config_parse.hpp" #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../mmo/extract_enums.hpp" #include "battle.hpp" #include "clif.hpp" @@ -56,14 +58,22 @@ #include "../poison.hpp" -constexpr interval_t MIN_MOBTHINKTIME = std::chrono::milliseconds(100); + +namespace tmwa +{ +constexpr interval_t MIN_MOBTHINKTIME = 100_ms; // Move probability in the negligent mode MOB (rate of 1000 minute) constexpr random_::Fraction MOB_LAZYMOVEPERC {50, 1000}; // Warp probability in the negligent mode MOB (rate of 1000 minute) constexpr random_::Fraction MOB_LAZYWARPPERC {20, 1000}; +static struct mob_db_ mob_db[2001]; +struct mob_db_& get_mob_db(Species s) +{ + return mob_db[unwrap<Species>(s)]; +} /*========================================== * Local prototype declaration (only required thing) @@ -72,9 +82,9 @@ struct mob_db_ mob_db[2001]; static int distance(int, int, int, int); static -int mob_makedummymobdb(int); +int mob_makedummymobdb(Species); static -void mob_timer(TimerData *, tick_t, int, unsigned char); +void mob_timer(TimerData *, tick_t, BlockId, unsigned char); static int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, mob_skill& skill_idx); @@ -83,30 +93,29 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, * Mob is searched with a name. *------------------------------------------ */ -int mobdb_searchname(MobName str) +Species mobdb_searchname(MobName str) { int i; for (i = 0; i < sizeof(mob_db) / sizeof(mob_db[0]); i++) { if (mob_db[i].name == str || mob_db[i].jname == str) - return i; + return wrap<Species>(i); } - return 0; + return Species(); } /*========================================== * Id Mob is checked. *------------------------------------------ */ -int mobdb_checkid(const int id) +Species mobdb_checkid(Species id) { - if (id <= 0 || id >= (sizeof(mob_db) / sizeof(mob_db[0])) - || !mob_db[id].name) - return 0; - - return id; + // value range is [1001, 2000] + if (wrap<Species>(1000) < id && id < wrap<Species>(2001)) + return id; + return Species(); } static @@ -117,27 +126,27 @@ void mob_init(dumb_ptr<mob_data> md); *------------------------------------------ */ static -void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, int mob_class) +void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, Species mob_class) { nullpo_retv(md); if (mobname == ENGLISH_NAME) - md->name = mob_db[mob_class].name; + md->name = get_mob_db(mob_class).name; else if (mobname == JAPANESE_NAME) - md->name = mob_db[mob_class].jname; + md->name = get_mob_db(mob_class).jname; else md->name = mobname; - md->bl_prev = NULL; - md->bl_next = NULL; + md->bl_prev = nullptr; + md->bl_next = nullptr; md->n = 0; md->mob_class = mob_class; md->bl_id = npc_get_new_npc_id(); really_memzero_this(&md->state); // md->timer = nullptr; - md->target_id = 0; - md->attacked_id = 0; + md->target_id = BlockId(); + md->attacked_id = BlockId(); mob_init(md); } @@ -265,12 +274,16 @@ void mob_mutate(dumb_ptr<mob_data> md, mob_stat stat, int intensity) int real_intensity2 = (((new_stat - old_stat) << 8) / mut_base); if (real_intensity < 0) + { if (real_intensity2 > real_intensity) real_intensity = real_intensity2; + } if (real_intensity > 0) + { if (real_intensity2 < real_intensity) real_intensity = real_intensity2; + } } real_intensity *= sign; @@ -322,7 +335,7 @@ int mob_gen_exp(mob_db_ *mob) * static_cast<double>(battle_config.base_exp_rate) / 100.); if (xp < 1) xp = 1; - PRINTF("Exp for mob '%s' generated: %d\n", mob->name, xp); + PRINTF("Exp for mob '%s' generated: %d\n"_fmt, mob->name, xp); return xp; } @@ -330,24 +343,24 @@ static void mob_init(dumb_ptr<mob_data> md) { int i; - const int mob_class = md->mob_class; - const int mutations_nr = mob_db[mob_class].mutations_nr; - const int mutation_power = mob_db[mob_class].mutation_power; - - md->stats[mob_stat::LV] = mob_db[mob_class].lv; - md->stats[mob_stat::MAX_HP] = mob_db[mob_class].max_hp; - md->stats[mob_stat::STR] = mob_db[mob_class].attrs[ATTR::STR]; - md->stats[mob_stat::AGI] = mob_db[mob_class].attrs[ATTR::AGI]; - md->stats[mob_stat::VIT] = mob_db[mob_class].attrs[ATTR::VIT]; - md->stats[mob_stat::INT] = mob_db[mob_class].attrs[ATTR::INT]; - md->stats[mob_stat::DEX] = mob_db[mob_class].attrs[ATTR::DEX]; - md->stats[mob_stat::LUK] = mob_db[mob_class].attrs[ATTR::LUK]; - md->stats[mob_stat::ATK1] = mob_db[mob_class].atk1; - md->stats[mob_stat::ATK2] = mob_db[mob_class].atk2; - md->stats[mob_stat::ADELAY] = mob_db[mob_class].adelay; - md->stats[mob_stat::DEF] = mob_db[mob_class].def; - md->stats[mob_stat::MDEF] = mob_db[mob_class].mdef; - md->stats[mob_stat::SPEED] = mob_db[mob_class].speed; + const Species mob_class = md->mob_class; + const int mutations_nr = get_mob_db(mob_class).mutations_nr; + const int mutation_power = get_mob_db(mob_class).mutation_power; + + md->stats[mob_stat::LV] = get_mob_db(mob_class).lv; + md->stats[mob_stat::MAX_HP] = get_mob_db(mob_class).max_hp; + md->stats[mob_stat::STR] = get_mob_db(mob_class).attrs[ATTR::STR]; + md->stats[mob_stat::AGI] = get_mob_db(mob_class).attrs[ATTR::AGI]; + md->stats[mob_stat::VIT] = get_mob_db(mob_class).attrs[ATTR::VIT]; + md->stats[mob_stat::INT] = get_mob_db(mob_class).attrs[ATTR::INT]; + md->stats[mob_stat::DEX] = get_mob_db(mob_class).attrs[ATTR::DEX]; + md->stats[mob_stat::LUK] = get_mob_db(mob_class).attrs[ATTR::LUK]; + md->stats[mob_stat::ATK1] = get_mob_db(mob_class).atk1; + md->stats[mob_stat::ATK2] = get_mob_db(mob_class).atk2; + md->stats[mob_stat::ADELAY] = get_mob_db(mob_class).adelay; + md->stats[mob_stat::DEF] = get_mob_db(mob_class).def; + md->stats[mob_stat::MDEF] = get_mob_db(mob_class).mdef; + md->stats[mob_stat::SPEED] = get_mob_db(mob_class).speed; md->stats[mob_stat::XP_BONUS] = MOB_XP_BONUS_BASE; for (i = 0; i < mutations_nr; i++) @@ -391,22 +404,22 @@ void mob_init(dumb_ptr<mob_data> md) * The MOB appearance for one time (for scripts) *------------------------------------------ */ -int mob_once_spawn(dumb_ptr<map_session_data> sd, +BlockId mob_once_spawn(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y, - MobName mobname, int mob_class, int amount, + MobName mobname, Species mob_class, int amount, NpcEvent event) { - dumb_ptr<mob_data> md = NULL; + dumb_ptr<mob_data> md = nullptr; map_local *m; - int count, r = mob_class; + int count; if (sd && mapname == MOB_THIS_MAP) m = sd->bl_m; else m = map_mapname2mapid(mapname); - if (m == nullptr || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // 値が異常なら召喚を止める - return 0; + if (m == nullptr || amount <= 0 || mobdb_checkid(mob_class) == Species()) + return BlockId(); if (sd) { @@ -417,7 +430,7 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, } else if (x <= 0 || y <= 0) { - PRINTF("mob_once_spawn: ??\n"); + PRINTF("mob_once_spawn: ??\n"_fmt); } for (count = 0; count < amount; count++) @@ -429,9 +442,6 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, md->bl_m = m; md->bl_x = x; md->bl_y = y; - if (r < 0 && battle_config.dead_branch_active == 1) - //移動してアクティブで反撃する - md->mode = MobMode::war; md->spawn.m = m; md->spawn.x0 = x; md->spawn.y0 = y; @@ -446,19 +456,20 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, map_addiddb(md); mob_spawn(md->bl_id); } - return (amount > 0) ? md->bl_id : 0; + return (amount > 0) ? md->bl_id : BlockId(); } /*========================================== * The MOB appearance for one time (& area specification for scripts) *------------------------------------------ */ -int mob_once_spawn_area(dumb_ptr<map_session_data> sd, +BlockId mob_once_spawn_area(dumb_ptr<map_session_data> sd, MapName mapname, int x0, int y0, int x1, int y1, - MobName mobname, int mob_class, int amount, + MobName mobname, Species mob_class, int amount, NpcEvent event) { - int x, y, i, max, lx = -1, ly = -1, id = 0; + int x, y, i, max, lx = -1, ly = -1; + BlockId id; map_local *m; if (mapname == MOB_THIS_MAP) @@ -470,8 +481,8 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, if (max > 1000) max = 1000; - if (m == nullptr || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // A summon is stopped if a value is unusual - return 0; + if (m == nullptr || amount <= 0 || (mobdb_checkid(mob_class) == Species())) // A summon is stopped if a value is unusual + return BlockId(); for (i = 0; i < amount; i++) { @@ -491,7 +502,7 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, y = ly; } else - return 0; // Since reference of the place which boils first went wrong, it stops. + return BlockId(); // Since reference of the place which boils first went wrong, it stops. } id = mob_once_spawn(sd, mapname, x, y, mobname, mob_class, 1, event); lx = x; @@ -501,49 +512,49 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, } // TODO: deprecate these -short mob_get_hair(int mob_class) +short mob_get_hair(Species mob_class) { - return mob_db[mob_class].hair; + return get_mob_db(mob_class).hair; } -short mob_get_hair_color(int mob_class) +short mob_get_hair_color(Species mob_class) { - return mob_db[mob_class].hair_color; + return get_mob_db(mob_class).hair_color; } -short mob_get_weapon(int mob_class) +short mob_get_weapon(Species mob_class) { - return mob_db[mob_class].weapon; + return get_mob_db(mob_class).weapon; } -short mob_get_shield(int mob_class) +ItemNameId mob_get_shield(Species mob_class) { - return mob_db[mob_class].shield; + return get_mob_db(mob_class).shield; } -short mob_get_head_top(int mob_class) +ItemNameId mob_get_head_top(Species mob_class) { - return mob_db[mob_class].head_top; + return get_mob_db(mob_class).head_top; } -short mob_get_head_mid(int mob_class) +ItemNameId mob_get_head_mid(Species mob_class) { - return mob_db[mob_class].head_mid; + return get_mob_db(mob_class).head_mid; } -short mob_get_head_buttom(int mob_class) +ItemNameId mob_get_head_buttom(Species mob_class) { - return mob_db[mob_class].head_buttom; + return get_mob_db(mob_class).head_buttom; } -short mob_get_clothes_color(int mob_class) // Add for player monster dye - Valaris +short mob_get_clothes_color(Species mob_class) // Add for player monster dye - Valaris { - return mob_db[mob_class].clothes_color; // End + return get_mob_db(mob_class).clothes_color; // End } -int mob_get_equip(int mob_class) // mob equip [Valaris] +int mob_get_equip(Species mob_class) // mob equip [Valaris] { - return mob_db[mob_class].equip; + return get_mob_db(mob_class).equip; } /*========================================== @@ -553,7 +564,7 @@ int mob_get_equip(int mob_class) // mob equip [Valaris] static int mob_can_move(dumb_ptr<mob_data> md) { - nullpo_ret(md); + nullpo_retz(md); if (md->canmove_tick > gettick() || (bool(md->opt1) && md->opt1 != Opt1::_stone6)) @@ -591,7 +602,7 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data) int moveblock; int x, y, dx, dy; - nullpo_ret(md); + nullpo_retz(md); md->state.state = MS::IDLE; if (md->walkpath.path_pos >= md->walkpath.path_len @@ -667,7 +678,7 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data) { i = i / 2; if (md->walkpath.path_half == 0) - i = std::max(i, std::chrono::milliseconds(1)); + i = std::max(i, 1_ms); md->timer = Timer(tick + i, std::bind(mob_timer, ph::_1, ph::_2, md->bl_id, md->walkpath.path_pos)); @@ -686,14 +697,14 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data) static int mob_check_attack(dumb_ptr<mob_data> md) { - dumb_ptr<block_list> tbl = NULL; - dumb_ptr<map_session_data> tsd = NULL; - dumb_ptr<mob_data> tmd = NULL; + dumb_ptr<block_list> tbl = nullptr; + dumb_ptr<map_session_data> tsd = nullptr; + dumb_ptr<mob_data> tmd = nullptr; MobMode mode; int range; - nullpo_ret(md); + nullpo_retz(md); md->min_chase = 13; md->state.state = MS::IDLE; @@ -705,9 +716,9 @@ int mob_check_attack(dumb_ptr<mob_data> md) if (bool(md->opt1)) return 0; - if ((tbl = map_id2bl(md->target_id)) == NULL) + if ((tbl = map_id2bl(md->target_id)) == nullptr) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } @@ -722,34 +733,34 @@ int mob_check_attack(dumb_ptr<mob_data> md) if (tsd) { if (pc_isdead(tsd) || tsd->invincible_timer - || pc_isinvisible(tsd) || md->bl_m != tbl->bl_m || tbl->bl_prev == NULL + || pc_isinvisible(tsd) || md->bl_m != tbl->bl_m || tbl->bl_prev == nullptr || distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) >= 13) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } } if (tmd) { - if (md->bl_m != tbl->bl_m || tbl->bl_prev == NULL + if (md->bl_m != tbl->bl_m || tbl->bl_prev == nullptr || distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) >= 13) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } } if (md->mode == MobMode::ZERO) - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; else mode = md->mode; - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; if (!bool(mode & MobMode::CAN_ATTACK)) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } @@ -759,12 +770,12 @@ int mob_check_attack(dumb_ptr<mob_data> md) && race != Race::_insect && race != Race::_demon)) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } - range = mob_db[md->mob_class].range; + range = get_mob_db(md->mob_class).range; if (bool(mode & MobMode::CAN_MOVE)) range++; if (distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) > range) @@ -788,11 +799,11 @@ void mob_ancillary_attack(dumb_ptr<block_list> bl, static int mob_attack(dumb_ptr<mob_data> md, tick_t tick) { - dumb_ptr<block_list> tbl = NULL; + dumb_ptr<block_list> tbl = nullptr; - nullpo_ret(md); + nullpo_retz(md); - if ((tbl = map_id2bl(md->target_id)) == NULL) + if ((tbl = map_id2bl(md->target_id)) == nullptr) return 0; if (!mob_check_attack(md)) @@ -834,7 +845,7 @@ int mob_attack(dumb_ptr<mob_data> md, tick_t tick) *------------------------------------------ */ static -void mob_stopattacked(dumb_ptr<map_session_data> sd, int id) +void mob_stopattacked(dumb_ptr<map_session_data> sd, BlockId id) { nullpo_retv(sd); @@ -849,7 +860,7 @@ void mob_stopattacked(dumb_ptr<map_session_data> sd, int id) static int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) { - nullpo_ret(md); + nullpo_retz(md); md->timer.cancel(); md->state.state = state; @@ -874,7 +885,7 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) { tick_t tick = gettick(); interval_t i = md->attackabletime - tick; - if (i > interval_t::zero() && i < std::chrono::seconds(2)) + if (i > interval_t::zero() && i < 2_s) md->timer = Timer(md->attackabletime, std::bind(mob_timer, ph::_1, ph::_2, md->bl_id, 0)); @@ -887,7 +898,7 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) } else { - md->attackabletime = tick + std::chrono::milliseconds(1); + md->attackabletime = tick + 1_ms; md->timer = Timer(md->attackabletime, std::bind(mob_timer, ph::_1, ph::_2, md->bl_id, 0)); @@ -903,7 +914,8 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) clif_foreachclient(std::bind(mob_stopattacked, ph::_1, md->bl_id)); skill_status_change_clear(md, 2); // The abnormalities in status are canceled. md->deletetimer.cancel(); - md->hp = md->target_id = md->attacked_id = 0; + md->hp = 0; + md->target_id = md->attacked_id = BlockId(); md->state.attackable = false; } break; @@ -918,12 +930,12 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) *------------------------------------------ */ static -void mob_timer(TimerData *, tick_t tick, int id, unsigned char data) +void mob_timer(TimerData *, tick_t tick, BlockId id, unsigned char data) { dumb_ptr<mob_data> md; dumb_ptr<block_list> bl; bl = map_id2bl(id); - if (bl == NULL) + if (bl == nullptr) { //攻撃してきた敵がもういないのは正常のようだ return; } @@ -933,7 +945,7 @@ void mob_timer(TimerData *, tick_t tick, int id, unsigned char data) md = bl->is_mob(); - if (md->bl_prev == NULL || md->state.state == MS::DEAD) + if (md->bl_prev == nullptr || md->state.state == MS::DEAD) return; MapBlockLock lock; @@ -948,7 +960,7 @@ void mob_timer(TimerData *, tick_t tick, int id, unsigned char data) break; default: if (battle_config.error_log == 1) - PRINTF("mob_timer : %d ?\n", + PRINTF("mob_timer : %d ?\n"_fmt, md->state.state); break; } @@ -963,7 +975,7 @@ int mob_walktoxy_sub(dumb_ptr<mob_data> md) { struct walkpath_data wpd; - nullpo_ret(md); + nullpo_retz(md); if (path_search(&wpd, md->bl_m, md->bl_x, md->bl_y, md->to_x, md->to_y, md->state.walk_easy)) @@ -986,7 +998,7 @@ int mob_walktoxy(dumb_ptr<mob_data> md, int x, int y, int easy) { struct walkpath_data wpd; - nullpo_ret(md); + nullpo_retz(md); if (md->state.state == MS::WALK && path_search(&wpd, md->bl_m, md->bl_x, md->bl_y, x, y, easy)) @@ -1012,7 +1024,7 @@ int mob_walktoxy(dumb_ptr<mob_data> md, int x, int y, int easy) *------------------------------------------ */ static -void mob_delayspawn(TimerData *, tick_t, int m) +void mob_delayspawn(TimerData *, tick_t, BlockId m) { mob_spawn(m); } @@ -1022,12 +1034,12 @@ void mob_delayspawn(TimerData *, tick_t, int m) *------------------------------------------ */ static -int mob_setdelayspawn(int id) +int mob_setdelayspawn(BlockId id) { dumb_ptr<mob_data> md; dumb_ptr<block_list> bl; - if ((bl = map_id2bl(id)) == NULL) + if ((bl = map_id2bl(id)) == nullptr) return -1; if (!bl || bl->bl_type == BL::NUL || bl->bl_type != BL::MOB) @@ -1052,7 +1064,7 @@ int mob_setdelayspawn(int id) tick_t spawntime1 = md->last_spawntime + md->spawn.delay1; tick_t spawntime2 = md->last_deadtime + md->spawn.delay2; - tick_t spawntime3 = gettick() + std::chrono::seconds(5); + tick_t spawntime3 = gettick() + 5_s; tick_t spawntime = std::max({spawntime1, spawntime2, spawntime3}); Timer(spawntime, @@ -1066,7 +1078,7 @@ int mob_setdelayspawn(int id) * Mob spawning. Initialization is also variously here. *------------------------------------------ */ -int mob_spawn(int id) +int mob_spawn(BlockId id) { int x = 0, y = 0; tick_t tick = gettick(); @@ -1086,7 +1098,7 @@ int mob_spawn(int id) return -1; md->last_spawntime = tick; - if (md->bl_prev != NULL) + if (md->bl_prev != nullptr) { map_delblock(md); } @@ -1115,9 +1127,7 @@ int mob_spawn(int id) if (i >= 50) { - // if(battle_config.error_log==1) - // PRINTF("MOB spawn error %d @ %s\n",id,map[md->bl_m].name); - Timer(tick + std::chrono::seconds(5), + Timer(tick + 5_s, std::bind(mob_delayspawn, ph::_1, ph::_2, id) ).detach(); @@ -1132,31 +1142,31 @@ int mob_spawn(int id) map_addblock(md); really_memzero_this(&md->state); - md->attacked_id = 0; - md->target_id = 0; + md->attacked_id = BlockId(); + md->target_id = BlockId(); md->move_fail_count = 0; mob_init(md); if (!md->stats[mob_stat::SPEED]) - md->stats[mob_stat::SPEED] = mob_db[md->mob_class].speed; - md->def_ele = mob_db[md->mob_class].element; - md->master_id = 0; + md->stats[mob_stat::SPEED] = get_mob_db(md->mob_class).speed; + md->def_ele = get_mob_db(md->mob_class).element; + md->master_id = BlockId(); md->master_dist = 0; md->state.state = MS::IDLE; md->state.skillstate = MobSkillState::MSS_IDLE; assert (!md->timer); md->last_thinktime = tick; - md->next_walktime = tick + std::chrono::seconds(5) + std::chrono::milliseconds(random_::to(50)); + md->next_walktime = tick + 5_s + std::chrono::milliseconds(random_::to(50)); md->attackabletime = tick; md->canmove_tick = tick; // md->deletetimer = nullptr; // md->skilltimer = nullptr; - md->skilldelayup = make_unique<tick_t[]>(mob_db[md->mob_class].skills.size()); - for (size_t i = 0; i < mob_db[md->mob_class].skills.size(); i++) - md->skilldelayup[i] = tick - std::chrono::hours(10); + md->skilldelayup = make_unique<tick_t[]>(get_mob_db(md->mob_class).skills.size()); + for (size_t i = 0; i < get_mob_db(md->mob_class).skills.size(); i++) + md->skilldelayup[i] = tick - 10_h; md->skillid = SkillID(); md->skilllv = 0; @@ -1206,9 +1216,9 @@ int distance(int x0, int y0, int x1, int y1) */ int mob_stopattack(dumb_ptr<mob_data> md) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; - md->attacked_id = 0; + md->attacked_id = BlockId(); return 0; } @@ -1218,7 +1228,7 @@ int mob_stopattack(dumb_ptr<mob_data> md) */ int mob_stop_walking(dumb_ptr<mob_data> md, int type) { - nullpo_ret(md); + nullpo_retz(md); if (md->state.state == MS::WALK || md->state.state == MS::IDLE) { @@ -1271,8 +1281,8 @@ int mob_can_reach(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int range) struct walkpath_data wpd; int i; - nullpo_ret(md); - nullpo_ret(bl); + nullpo_retz(md); + nullpo_retz(bl); dx = abs(bl->bl_x - md->bl_x); dy = abs(bl->bl_y - md->bl_y); @@ -1328,16 +1338,16 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist) eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; MobMode mode; - nullpo_ret(md); - nullpo_ret(bl); + nullpo_retz(md); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); Option *option = battle_get_option(bl); - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; if (md->mode == MobMode::ZERO) { - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; } else { @@ -1345,25 +1355,25 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist) } if (!bool(mode & MobMode::CAN_ATTACK)) { - md->target_id = 0; + md->target_id = BlockId(); return 0; } // Nothing will be carried out if there is no mind of changing TAGE by TAGE ending. - if ((md->target_id > 0 && md->state.attackable) + if ((md->target_id && md->state.attackable) && (!bool(mode & MobMode::AGGRESSIVE) || !random_::chance({25 + 1, 100}))) return 0; // Coercion is exerted if it is MVPMOB. if (bool(mode & MobMode::BOSS) - || (option != NULL + || (option != nullptr || race == Race::_insect || race == Race::_demon)) { if (bl->bl_type == BL::PC) { sd = bl->is_player(); - nullpo_ret(sd); + nullpo_retz(sd); if (sd->invincible_timer || pc_isinvisible(sd)) return 0; if (!bool(mode & MobMode::BOSS) && race != Race::_insect && race != Race::_demon @@ -1391,8 +1401,8 @@ static void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> smd, int *pcc) { - dumb_ptr<map_session_data> tsd = NULL; - dumb_ptr<mob_data> tmd = NULL; + dumb_ptr<map_session_data> tsd = nullptr; + dumb_ptr<mob_data> tmd = nullptr; MobMode mode; int dist; @@ -1412,14 +1422,14 @@ void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl, return; if (smd->mode == MobMode::ZERO) - mode = mob_db[smd->mob_class].mode; + mode = get_mob_db(smd->mob_class).mode; else mode = smd->mode; // アクティブでターゲット射程内にいるなら、ロックする if (bool(mode & MobMode::AGGRESSIVE)) { - Race race = mob_db[smd->mob_class].race; + Race race = get_mob_db(smd->mob_class).race; //対象がPCの場合 if (tsd && !pc_isdead(tsd) && @@ -1479,7 +1489,7 @@ void mob_ai_sub_hard_lootsearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md, if (md->mode == MobMode::ZERO) { - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; } else { @@ -1518,8 +1528,8 @@ void mob_ai_sub_hard_linksearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md, nullpo_retv(md); nullpo_retv(target); - if (md->attacked_id > 0 - && bool(mob_db[md->mob_class].mode & MobMode::ASSIST)) + if (md->attacked_id + && bool(get_mob_db(md->mob_class).mode & MobMode::ASSIST)) { if (tmd->mob_class == md->mob_class && tmd->bl_m == md->bl_m @@ -1543,17 +1553,17 @@ void mob_ai_sub_hard_linksearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md, static int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) { - dumb_ptr<mob_data> mmd = NULL; + dumb_ptr<mob_data> mmd = nullptr; dumb_ptr<block_list> bl; MobMode mode; int old_dist; - nullpo_ret(md); + nullpo_retz(md); - if ((bl = map_id2bl(md->master_id)) != NULL) + if ((bl = map_id2bl(md->master_id)) != nullptr) mmd = bl->is_mob(); - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; // It is not main monster/leader. if (!mmd || mmd->bl_type != BL::MOB || mmd->bl_id != md->master_id) @@ -1636,20 +1646,20 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) while (ret && i < 10); } - md->next_walktime = tick + std::chrono::milliseconds(500); + md->next_walktime = tick + 500_ms; md->state.master_check = 1; } // There is the master, the master locks a target and he does not lock. - if ((mmd->target_id > 0 && mmd->state.attackable) + if ((mmd->target_id && mmd->state.attackable) && (!md->target_id || !md->state.attackable)) { dumb_ptr<map_session_data> sd = map_id2sd(mmd->target_id); - if (sd != NULL && !pc_isdead(sd) && !sd->invincible_timer + if (sd != nullptr && !pc_isdead(sd) && !sd->invincible_timer && !pc_isinvisible(sd)) { - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; if (bool(mode & MobMode::BOSS) || (!sd->state.gangsterparadise || race == Race::_insect @@ -1675,12 +1685,12 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) static int mob_unlocktarget(dumb_ptr<mob_data> md, tick_t tick) { - nullpo_ret(md); + nullpo_retz(md); - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; md->state.skillstate = MobSkillState::MSS_IDLE; - md->next_walktime = tick + std::chrono::seconds(3) + std::chrono::milliseconds(random_::to(3000)); + md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(3000)); return 0; } @@ -1693,7 +1703,7 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) { const int retrycount = 20; - nullpo_ret(md); + nullpo_retz(md); interval_t speed = battle_get_speed(md); if (md->next_walktime < tick) @@ -1718,8 +1728,8 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) if (md->move_fail_count > 1000) { if (battle_config.error_log == 1) - PRINTF("MOB cant move. random spawn %d, mob_class = %d\n", - md->bl_id, md->mob_class); + PRINTF("MOB cant move. random spawn %d, mob_class = %d\n"_fmt, + md->bl_id, md->mob_class); md->move_fail_count = 0; mob_spawn(md->bl_id); } @@ -1734,7 +1744,7 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) else c += speed; } - md->next_walktime = tick + std::chrono::seconds(3) + std::chrono::milliseconds(random_::to(3000)) + c; + md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(3000)) + c; md->state.skillstate = MobSkillState::MSS_WALK; return 1; } @@ -1748,9 +1758,9 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) static void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) { - dumb_ptr<mob_data> md, tmd = NULL; - dumb_ptr<map_session_data> tsd = NULL; - dumb_ptr<block_list> tbl = NULL; + dumb_ptr<mob_data> md, tmd = nullptr; + dumb_ptr<map_session_data> tsd = nullptr; + dumb_ptr<block_list> tbl = nullptr; dumb_ptr<flooritem_data> fitem; int i, dx, dy, ret, dist; int attack_type = 0; @@ -1763,7 +1773,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) return; md->last_thinktime = tick; - if (md->skilltimer || md->bl_prev == NULL) + if (md->skilltimer || md->bl_prev == nullptr) { // Under a skill aria and death if (tick > md->next_walktime + MIN_MOBTHINKTIME) @@ -1772,20 +1782,20 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } if (md->mode == MobMode::ZERO) - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; else mode = md->mode; - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; // Abnormalities if (bool(md->opt1) && md->opt1 != Opt1::_stone6) return; - if (!bool(mode & MobMode::CAN_ATTACK) && md->target_id > 0) - md->target_id = 0; + if (!bool(mode & MobMode::CAN_ATTACK) && md->target_id) + md->target_id = BlockId(); - if (md->attacked_id > 0 && bool(mode & MobMode::ASSIST)) + if (md->attacked_id && bool(mode & MobMode::ASSIST)) { // Link monster dumb_ptr<map_session_data> asd = map_id2sd(md->attacked_id); if (asd) @@ -1802,28 +1812,28 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } // It checks to see it was attacked first (if active, it is target change at 25% of probability). - if (mode != MobMode::ZERO && md->attacked_id > 0 + if (mode != MobMode::ZERO && md->attacked_id && (!md->target_id || !md->state.attackable || (bool(mode & MobMode::AGGRESSIVE) && random_::chance({25, 100})))) { dumb_ptr<block_list> abl = map_id2bl(md->attacked_id); - dumb_ptr<map_session_data> asd = NULL; + dumb_ptr<map_session_data> asd = nullptr; if (abl) { if (abl->bl_type == BL::PC) asd = abl->is_player(); - if (asd == NULL || md->bl_m != abl->bl_m || abl->bl_prev == NULL + if (asd == nullptr || md->bl_m != abl->bl_m || abl->bl_prev == nullptr || asd->invincible_timer || pc_isinvisible(asd) || (dist = distance(md->bl_x, md->bl_y, abl->bl_x, abl->bl_y)) >= 32 || battle_check_target(bl, abl, BCT_ENEMY) == 0) - md->attacked_id = 0; + md->attacked_id = BlockId(); else { md->target_id = md->attacked_id; // set target md->state.attackable = true; attack_type = 1; - md->attacked_id = 0; + md->attacked_id = BlockId(); md->min_chase = dist + 13; if (md->min_chase > 26) md->min_chase = 26; @@ -1833,7 +1843,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) md->state.master_check = 0; // Processing of slave monster - if (md->master_id > 0 && md->state.special_mob_ai == 0) + if (md->master_id && md->state.special_mob_ai == 0) mob_ai_sub_hard_slavemob(md, tick); // アクティヴモンスターの策敵 (?? of a bitter taste TIVU monster) @@ -1874,7 +1884,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } // It will attack, if the candidate for an attack is. - if (md->target_id > 0) + if (md->target_id) { if ((tbl = map_id2bl(md->target_id))) { @@ -1884,7 +1894,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) tmd = tbl->is_mob(); if (tsd || tmd) { - if (tbl->bl_m != md->bl_m || tbl->bl_prev == NULL + if (tbl->bl_m != md->bl_m || tbl->bl_prev == nullptr || (dist = distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y)) >= md->min_chase) @@ -1894,7 +1904,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) && race != Race::_insect && race != Race::_demon)) mob_unlocktarget(md, tick); // スキルなどによる策敵妨害 - else if (!battle_check_range(md, tbl, mob_db[md->mob_class].range)) + else if (!battle_check_range(md, tbl, get_mob_db(md->mob_class).range)) { // 攻撃範囲外なので移動 if (!bool(mode & MobMode::CAN_MOVE)) @@ -1915,7 +1925,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) else { // 追跡 - md->next_walktime = tick + std::chrono::milliseconds(500); + md->next_walktime = tick + 500_ms; i = 0; do { @@ -1973,11 +1983,11 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } else { // ルートモンスター処理 - if (tbl == NULL || tbl->bl_type != BL::ITEM || tbl->bl_m != md->bl_m + if (tbl == nullptr || tbl->bl_type != BL::ITEM || tbl->bl_m != md->bl_m || (dist = distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y)) >= md->min_chase - || !bool(mob_db[md->mob_class].mode & MobMode::LOOTER)) + || !bool(get_mob_db(md->mob_class).mode & MobMode::LOOTER)) { // 遠すぎるかアイテムがなくなった mob_unlocktarget(md, tick); @@ -1999,7 +2009,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) && (md->next_walktime < tick || distance(md->to_x, md->to_y, tbl->bl_x, tbl->bl_y) <= 0)) return; // 既に移動中 - md->next_walktime = tick + std::chrono::milliseconds(500); + md->next_walktime = tick + 500_ms; dx = tbl->bl_x - md->bl_x; dy = tbl->bl_y - md->bl_y; ret = mob_walktoxy(md, md->bl_x + dx, md->bl_y + dy, 0); @@ -2036,16 +2046,16 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) // mobs that are not slaves can random-walk if (bool(mode & MobMode::CAN_MOVE) && mob_can_move(md) - && (md->master_id == 0 || md->state.special_mob_ai + && (!md->master_id || md->state.special_mob_ai || md->master_dist > 10)) { // if walktime is more than 7 seconds in the future, // set it to somewhere between 3 and 5 seconds - if (md->next_walktime > tick + std::chrono::seconds(7) + if (md->next_walktime > tick + 7_s && (md->walkpath.path_len == 0 || md->walkpath.path_pos >= md->walkpath.path_len)) { - md->next_walktime = tick + std::chrono::seconds(3) + md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(2000)); } @@ -2104,7 +2114,7 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) return; md->last_thinktime = tick; - if (md->bl_prev == NULL || md->skilltimer) + if (md->bl_prev == nullptr || md->skilltimer) { if (tick > md->next_walktime + MIN_MOBTHINKTIME * 10) md->next_walktime = tick; @@ -2112,7 +2122,7 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) } if (md->next_walktime < tick - && bool(mob_db[md->mob_class].mode & MobMode::CAN_MOVE) + && bool(get_mob_db(md->mob_class).mode & MobMode::CAN_MOVE) && mob_can_move(md)) { @@ -2127,8 +2137,8 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) // MOB which is not not the summons MOB but BOSS, either sometimes reboils. else if (random_::chance(MOB_LAZYWARPPERC) && md->spawn.x0 <= 0 - && md->master_id != 0 - && !bool(mob_db[md->mob_class].mode & MobMode::BOSS)) + && md->master_id + && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS)) mob_spawn(md->bl_id); } @@ -2139,12 +2149,12 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) // MOB which is not BOSS which is not Summons MOB, either -- a case -- sometimes -- leaping if (random_::chance(MOB_LAZYWARPPERC) && md->spawn.x0 <= 0 - && md->master_id != 0 - && !bool(mob_db[md->mob_class].mode & MobMode::BOSS)) + && md->master_id + && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS)) mob_warp(md, nullptr, -1, -1, BeingRemoveWhy::NEGATIVE1); } - md->next_walktime = tick + std::chrono::seconds(5) + std::chrono::milliseconds(random_::to(10 * 1000)); + md->next_walktime = tick + 5_s + std::chrono::milliseconds(random_::to(10 * 1000)); } } @@ -2169,7 +2179,8 @@ struct delay_item_drop { map_local *m; int x, y; - int nameid, amount; + ItemNameId nameid; + int amount; dumb_ptr<map_session_data> first_sd, second_sd, third_sd; }; @@ -2177,7 +2188,7 @@ struct delay_item_drop2 { map_local *m; int x, y; - struct item item_data; + Item item_data; dumb_ptr<map_session_data> first_sd, second_sd, third_sd; }; @@ -2188,7 +2199,7 @@ struct delay_item_drop2 static void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem) { - struct item temp_item {}; + Item temp_item {}; PickupFail flag; temp_item.nameid = ditem.nameid; @@ -2201,7 +2212,7 @@ void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem) pc_additem(ditem.first_sd, &temp_item, ditem.amount)) != PickupFail::OKAY) { - clif_additem(ditem.first_sd, 0, 0, flag); + clif_additem(ditem.first_sd, IOff0::from(0), 0, flag); map_addflooritem(&temp_item, 1, ditem.m, ditem.x, ditem.y, ditem.first_sd, ditem.second_sd, ditem.third_sd); @@ -2231,7 +2242,7 @@ void mob_delay_item_drop2(TimerData *, tick_t, struct delay_item_drop2 ditem) ditem.item_data.amount)) != PickupFail::OKAY) { - clif_additem(ditem.first_sd, 0, 0, flag); + clif_additem(ditem.first_sd, IOff0::from(0), 0, flag); map_addflooritem(&ditem.item_data, ditem.item_data.amount, ditem.m, ditem.x, ditem.y, ditem.first_sd, ditem.second_sd, ditem.third_sd); @@ -2252,7 +2263,7 @@ int mob_delete(dumb_ptr<mob_data> md) { nullpo_retr(1, md); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 1; mob_changestate(md, MS::DEAD, 0); clif_clearchar(md, BeingRemoveWhy::DEAD); @@ -2266,7 +2277,7 @@ int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type) { nullpo_retr(1, md); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 1; mob_changestate(md, MS::DEAD, 0); clif_clearchar(md, type); @@ -2275,7 +2286,7 @@ int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type) return 0; } -void mob_timer_delete(TimerData *, tick_t, int id) +void mob_timer_delete(TimerData *, tick_t, BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); dumb_ptr<mob_data> md; @@ -2291,15 +2302,15 @@ void mob_timer_delete(TimerData *, tick_t, int id) *------------------------------------------ */ static -void mob_deleteslave_sub(dumb_ptr<block_list> bl, int id) +void mob_deleteslave_sub(dumb_ptr<block_list> bl, BlockId id) { dumb_ptr<mob_data> md; nullpo_retv(bl); md = bl->is_mob(); - if (md->master_id > 0 && md->master_id == id) - mob_damage(NULL, md, md->hp, 1); + if (md->master_id && md->master_id == id) + mob_damage(nullptr, md, md->hp, 1); } /*========================================== @@ -2308,7 +2319,7 @@ void mob_deleteslave_sub(dumb_ptr<block_list> bl, int id) */ int mob_deleteslave(dumb_ptr<mob_data> md) { - nullpo_ret(md); + nullpo_retz(md); map_foreachinarea(std::bind(mob_deleteslave_sub, ph::_1, md->bl_id), md->bl_m, @@ -2333,18 +2344,18 @@ double damage_bonus_factor[DAMAGE_BONUS_COUNT + 1] = int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, int type) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; int max_hp; tick_t tick = gettick(); - dumb_ptr<map_session_data> mvp_sd = NULL, second_sd = NULL, third_sd = NULL; + dumb_ptr<map_session_data> mvp_sd = nullptr, second_sd = nullptr, third_sd = nullptr; - nullpo_ret(md); //srcはNULLで呼ばれる場合もあるので、他でチェック + nullpo_retz(md); //srcはNULLで呼ばれる場合もあるので、他でチェック if (src && src->bl_id == md->master_id && bool(md->mode & MobMode::TURNS_AGAINST_BAD_MASTER)) { /* If the master hits a monster, have the monster turn against him */ - md->master_id = 0; + md->master_id = BlockId(); md->mode = MobMode::war; /* Regular war mode */ md->target_id = src->bl_id; md->attacked_id = src->bl_id; @@ -2358,18 +2369,16 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, mvp_sd = sd; } -// if(battle_config.battle_log) -// PRINTF("mob_damage %d %d %d\n",md->hp,max_hp,damage); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) { if (battle_config.error_log == 1) - PRINTF("mob_damage : BlockError!!\n"); + PRINTF("mob_damage : BlockError!!\n"_fmt); return 0; } if (md->state.state == MS::DEAD || md->hp <= 0) { - if (md->bl_prev != NULL) + if (md->bl_prev != nullptr) { mob_changestate(md, MS::DEAD, 0); // It is skill at the time of death. @@ -2395,7 +2404,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (!(type & 2)) { - if (sd != NULL) + if (sd != nullptr) { for (mob_data::DmgLogEntry& dle : md->dmglogv) { @@ -2414,7 +2423,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, } damage_logged_pc: - if (md->attacked_id <= 0 && md->state.special_mob_ai == 0) + if (!md->attacked_id && md->state.special_mob_ai == 0) md->attacked_id = sd->bl_id; } if (src && src->bl_type == BL::MOB @@ -2425,12 +2434,12 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (master_bl && master_bl->bl_type == BL::PC) { MAP_LOG_PC(master_bl->is_player(), - "MOB-TO-MOB-DMG FROM MOB%d %d TO MOB%d %d FOR %d", - md2->bl_id, md2->mob_class, md->bl_id, md->mob_class, - damage); + "MOB-TO-MOB-DMG FROM MOB%d %d TO MOB%d %d FOR %d"_fmt, + md2->bl_id, md2->mob_class, md->bl_id, md->mob_class, + damage); } - nullpo_ret(md2); + nullpo_retz(md2); for (mob_data::DmgLogEntry& dle : md->dmglogv) { if (dle.id == md2->master_id) @@ -2446,7 +2455,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, app.dmg = damage; md->dmglogv.push_back(app); - if (md->attacked_id <= 0 && md->state.special_mob_ai == 0) + if (!md->attacked_id && md->state.special_mob_ai == 0) md->attacked_id = md2->master_id; } damage_logged_slave: @@ -2461,7 +2470,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, return 0; } - MAP_LOG("MOB%d DEAD", md->bl_id); + MAP_LOG("MOB%d DEAD"_fmt, md->bl_id); // ----- ここから死亡処理 ----- @@ -2491,7 +2500,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, { struct DmgLogParty { - struct party *p; + PartyPair p; int base_exp, job_exp; }; std::vector<DmgLogParty> ptv; @@ -2501,7 +2510,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, { dumb_ptr<map_session_data> tmpsdi = map_id2sd(dle.id); int tmpdmg = dle.dmg; - if (tmpsdi == NULL) + if (tmpsdi == nullptr) continue; if (tmpsdi->bl_m != md->bl_m || pc_isdead(tmpsdi)) continue; @@ -2532,7 +2541,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, int base_exp, job_exp, flag = 1; double per; - struct party *p; + PartyPair p; // [Fate] The above is the old formula. We do a more involved computation below. // [o11c] Look in git history for old code, you idiot! @@ -2548,23 +2557,23 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, per = 1; base_exp = - ((mob_db[md->mob_class].base_exp * + ((get_mob_db(md->mob_class).base_exp * md->stats[mob_stat::XP_BONUS]) >> MOB_XP_BONUS_SHIFT) * per / 256; if (base_exp < 1) base_exp = 1; if (sd && md && battle_config.pk_mode == 1 - && (mob_db[md->mob_class].lv - sd->status.base_level >= 20)) + && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) { base_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) base_exp = 0; // Added [Valaris] - job_exp = mob_db[md->mob_class].job_exp * per / 256; + job_exp = get_mob_db(md->mob_class).job_exp * per / 256; if (job_exp < 1) job_exp = 1; if (sd && md && battle_config.pk_mode == 1 - && (mob_db[md->mob_class].lv - sd->status.base_level >= 20)) + && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) { job_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } @@ -2572,19 +2581,19 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, && battle_config.alchemist_summon_reward != 1) job_exp = 0; // Added [Valaris] - int pid = tmpsdi->status.party_id; - if (pid > 0) + PartyId pid = tmpsdi->status.party_id; + if (pid) { std::vector<DmgLogParty>::iterator it = std::find_if(ptv.begin(), ptv.end(), [pid](const DmgLogParty& dlp) { - return dlp.p->party_id == pid; + return dlp.p.party_id == pid; } ); if (it == ptv.end()) { p = party_search(pid); - if (p != NULL && p->exp != 0) + if (p && p->exp != 0) { DmgLogParty pn {}; pn.p = p; @@ -2617,19 +2626,19 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) // Added [Valaris] break; // End - if (mob_db[md->mob_class].dropitem[i].nameid <= 0) + if (!get_mob_db(md->mob_class).dropitem[i].nameid) continue; - random_::Fixed<int, 10000> drop_rate = mob_db[md->mob_class].dropitem[i].p; + random_::Fixed<int, 10000> drop_rate = get_mob_db(md->mob_class).dropitem[i].p; if (battle_config.drops_by_luk > 0 && sd && md) drop_rate.num += (sd->status.attrs[ATTR::LUK] * battle_config.drops_by_luk) / 100; // drops affected by luk [Valaris] if (sd && md && battle_config.pk_mode == 1 - && (mob_db[md->mob_class].lv - sd->status.base_level >= 20)) + && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) drop_rate.num *= 1.25; // pk_mode increase drops if 20 level difference [Valaris] if (!random_::chance(drop_rate)) continue; struct delay_item_drop ditem {}; - ditem.nameid = mob_db[md->mob_class].dropitem[i].nameid; + ditem.nameid = get_mob_db(md->mob_class).dropitem[i].nameid; ditem.amount = 1; ditem.m = md->bl_m; ditem.x = md->bl_x; @@ -2637,14 +2646,14 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, ditem.first_sd = mvp_sd; ditem.second_sd = second_sd; ditem.third_sd = third_sd; - Timer(tick + std::chrono::milliseconds(500) + static_cast<interval_t>(i), + Timer(tick + 500_ms + static_cast<interval_t>(i), std::bind(mob_delay_item_drop, ph::_1, ph::_2, ditem) ).detach(); } { int i = 0; - for (struct item lit : md->lootitemv) + for (Item lit : md->lootitemv) { struct delay_item_drop2 ditem {}; ditem.item_data = lit; @@ -2655,7 +2664,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, ditem.second_sd = second_sd; ditem.third_sd = third_sd; // ? - Timer(tick + std::chrono::milliseconds(540) + static_cast<interval_t>(i), + Timer(tick + 540_ms + static_cast<interval_t>(i), std::bind(mob_delay_item_drop2, ph::_1, ph::_2, ditem) ).detach(); @@ -2668,9 +2677,9 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, // SCRIPT実行 if (md->npc_event) { - if (sd == NULL) + if (sd == nullptr) { - if (mvp_sd != NULL) + if (mvp_sd != nullptr) sd = mvp_sd; else { @@ -2711,7 +2720,7 @@ int mob_heal(dumb_ptr<mob_data> md, int heal) { int max_hp = battle_get_max_hp(md); - nullpo_ret(md); + nullpo_retz(md); md->hp += heal; if (max_hp < md->hp) @@ -2725,7 +2734,7 @@ int mob_heal(dumb_ptr<mob_data> md, int heal) *------------------------------------------ */ static -void mob_warpslave_sub(dumb_ptr<block_list> bl, int id, int x, int y) +void mob_warpslave_sub(dumb_ptr<block_list> bl, BlockId id, int x, int y) { dumb_ptr<mob_data> md = bl->is_mob(); @@ -2742,7 +2751,6 @@ void mob_warpslave_sub(dumb_ptr<block_list> bl, int id, int x, int y) static int mob_warpslave(dumb_ptr<mob_data> md, int x, int y) { -//PRINTF("warp slave\n"); map_foreachinarea(std::bind(mob_warpslave_sub, ph::_1, md->bl_id, md->bl_x, md->bl_y), md->bl_m, x - AREA_SIZE, y - AREA_SIZE, @@ -2759,9 +2767,9 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t { int i = 0, xs = 0, ys = 0, bx = x, by = y; - nullpo_ret(md); + nullpo_retz(md); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 0; if (m == nullptr) @@ -2808,12 +2816,12 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t else { if (battle_config.error_log == 1) - PRINTF("MOB %d warp failed, mob_class = %d\n", md->bl_id, md->mob_class); + PRINTF("MOB %d warp failed, mob_class = %d\n"_fmt, md->bl_id, md->mob_class); } - md->target_id = 0; // タゲを解除する + md->target_id = BlockId(); // タゲを解除する md->state.attackable = false; - md->attacked_id = 0; + md->attacked_id = BlockId(); md->state.skillstate = MobSkillState::MSS_IDLE; mob_changestate(md, MS::IDLE, 0); @@ -2821,7 +2829,7 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t && i == 1000) { if (battle_config.battle_log == 1) - PRINTF("MOB %d warp to (%d,%d), mob_class = %d\n", md->bl_id, x, y, + PRINTF("MOB %d warp to (%d,%d), mob_class = %d\n"_fmt, md->bl_id, x, y, md->mob_class); } @@ -2840,7 +2848,7 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t *------------------------------------------ */ static -void mob_countslave_sub(dumb_ptr<block_list> bl, int id, int *c) +void mob_countslave_sub(dumb_ptr<block_list> bl, BlockId id, int *c) { dumb_ptr<mob_data> md; @@ -2860,7 +2868,7 @@ int mob_countslave(dumb_ptr<mob_data> md) { int c = 0; - nullpo_ret(md); + nullpo_retz(md); map_foreachinarea(std::bind(mob_countslave_sub, ph::_1, md->bl_id, &c), md->bl_m, @@ -2874,36 +2882,38 @@ int mob_countslave(dumb_ptr<mob_data> md) * 手下MOB召喚 *------------------------------------------ */ -int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) +int mob_summonslave(dumb_ptr<mob_data> md2, int *value_, int amount, int flag) { dumb_ptr<mob_data> md; - int bx, by, count = 0, mob_class, k, a = amount; + int bx, by, count = 0, a = amount; - nullpo_ret(md2); - nullpo_ret(value); + nullpo_retz(md2); + nullpo_retz(value_); bx = md2->bl_x; by = md2->bl_y; map_local *m = md2->bl_m; - if (value[0] <= 1000 || value[0] > 2000) // 値が異常なら召喚を止める - return 0; - while (count < 5 && value[count] > 1000 && value[count] <= 2000) - count++; + Species values[5]; + for (count = 0; count < 5 && values[count] != Species(); ++count) + values[count] = wrap<Species>(value_[count]); if (count < 1) return 0; - for (k = 0; k < count; k++) + for (int k = 0; k < count; k++) { amount = a; - mob_class = value[k]; - if (mob_class <= 1000 || mob_class > 2000) + Species mob_class = values[k]; + if (mobdb_checkid(mob_class) == Species()) + { + PRINTF("Warning: bad slave class %u\n"_fmt, mob_class); continue; + } for (; amount > 0; amount--) { int x = 0, y = 0, i = 0; md.new_(); - if (bool(mob_db[mob_class].mode & MobMode::LOOTER)) + if (bool(get_mob_db(mob_class).mode & MobMode::LOOTER)) md->lootitemv.clear(); while ((x <= 0 @@ -2921,8 +2931,8 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) } mob_spawn_dataset(md, JAPANESE_NAME, mob_class); - md->bl_prev = NULL; - md->bl_next = NULL; + md->bl_prev = nullptr; + md->bl_next = nullptr; md->bl_m = m; md->bl_x = x; md->bl_y = y; @@ -2954,7 +2964,7 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) */ static void mob_counttargeted_sub(dumb_ptr<block_list> bl, - int id, int *c, dumb_ptr<block_list> src, ATK target_lv) + BlockId id, int *c, dumb_ptr<block_list> src, ATK target_lv) { nullpo_retv(bl); nullpo_retv(c); @@ -2986,7 +2996,7 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src, { int c = 0; - nullpo_ret(md); + nullpo_retz(md); map_foreachinarea(std::bind(mob_counttargeted_sub, ph::_1, md->bl_id, &c, src, target_lv), md->bl_m, @@ -3004,21 +3014,21 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src, * スキル使用(詠唱完了、ID指定) *------------------------------------------ */ -void mobskill_castend_id(TimerData *, tick_t tick, int id) +void mobskill_castend_id(TimerData *, tick_t tick, BlockId id) { - dumb_ptr<mob_data> md = NULL; + dumb_ptr<mob_data> md = nullptr; dumb_ptr<block_list> bl; dumb_ptr<block_list> mbl; int range; - if ((mbl = map_id2bl(id)) == NULL) //詠唱したMobがもういないというのは良くある正常処理 + if ((mbl = map_id2bl(id)) == nullptr) //詠唱したMobがもういないというのは良くある正常処理 return; - if ((md = mbl->is_mob()) == NULL) + if ((md = mbl->is_mob()) == nullptr) { - PRINTF("mobskill_castend_id nullpo mbl->bl_id:%d\n", mbl->bl_id); + PRINTF("mobskill_castend_id nullpo mbl->bl_id:%d\n"_fmt, mbl->bl_id); return; } - if (md->bl_type != BL::MOB || md->bl_prev == NULL) + if (md->bl_type != BL::MOB || md->bl_prev == nullptr) return; if (bool(md->opt1)) @@ -3027,9 +3037,8 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id) if (md->skillid != SkillID::NPC_EMOTION) md->last_thinktime = tick + battle_get_adelay(md); - if ((bl = map_id2bl(md->skilltarget)) == NULL || bl->bl_prev == NULL) + if ((bl = map_id2bl(md->skilltarget)) == nullptr || bl->bl_prev == nullptr) { //スキルターゲットが存在しない - //PRINTF("mobskill_castend_id nullpo\n");//ターゲットがいないときはnullpoじゃなくて普通に終了 return; } if (md->bl_m != bl->bl_m) @@ -3044,10 +3053,10 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id) if (range + battle_config.monster_skill_add_range < distance(md->bl_x, md->bl_y, bl->bl_x, bl->bl_y)) return; - md->skilldelayup[md->skillidx - &mob_db[md->mob_class].skills.front()] = tick; + md->skilldelayup[md->skillidx - &get_mob_db(md->mob_class).skills.front()] = tick; if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill castend skill=%d, mob_class = %d\n", + PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt, md->skillid, md->mob_class); mob_stop_walking(md, 0); @@ -3071,20 +3080,20 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id) * スキル使用(詠唱完了、場所指定) *------------------------------------------ */ -void mobskill_castend_pos(TimerData *, tick_t tick, int id) +void mobskill_castend_pos(TimerData *, tick_t tick, BlockId id) { - dumb_ptr<mob_data> md = NULL; + dumb_ptr<mob_data> md = nullptr; dumb_ptr<block_list> bl; int range; //mobskill_castend_id同様詠唱したMobが詠唱完了時にもういないというのはありそうなのでnullpoから除外 - if ((bl = map_id2bl(id)) == NULL) + if ((bl = map_id2bl(id)) == nullptr) return; md = bl->is_mob(); nullpo_retv(md); - if (md->bl_type != BL::MOB || md->bl_prev == NULL) + if (md->bl_type != BL::MOB || md->bl_prev == nullptr) return; if (bool(md->opt1)) @@ -3095,10 +3104,10 @@ void mobskill_castend_pos(TimerData *, tick_t tick, int id) range = battle_get_range(md) - (range + 1); if (range + battle_config.monster_skill_add_range < distance(md->bl_x, md->bl_y, md->skillx, md->skilly)) return; - md->skilldelayup[md->skillidx - &mob_db[md->mob_class].skills.front()] = tick; + md->skilldelayup[md->skillidx - &get_mob_db(md->mob_class).skills.front()] = tick; if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill castend skill=%d, mob_class = %d\n", + PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt, md->skillid, md->mob_class); mob_stop_walking(md, 0); } @@ -3115,13 +3124,13 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, SkillID skill_id; int skill_lv; - nullpo_ret(md); + nullpo_retz(md); ms = &skill_idx; - if (target == NULL && (target = map_id2bl(md->target_id)) == NULL) + if (target == nullptr && (target = map_id2bl(md->target_id)) == nullptr) return 0; - if (target->bl_prev == NULL || md->bl_prev == NULL) + if (target->bl_prev == nullptr || md->bl_prev == nullptr) return 0; skill_id = ms->skill_id; @@ -3145,10 +3154,10 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, interval_t casttime = skill_castfix(md, ms->casttime); md->state.skillcastcancel = ms->cancel; - md->skilldelayup[ms - &mob_db[md->mob_class].skills.front()] = gettick(); + md->skilldelayup[ms - &get_mob_db(md->mob_class).skills.front()] = gettick(); if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill use target_id=%d skill=%d lv=%d cast=%d, mob_class = %d\n", + PRINTF("MOB skill use target_id=%d skill=%d lv=%d cast=%d, mob_class = %d\n"_fmt, target->bl_id, skill_id, skill_lv, static_cast<uint32_t>(casttime.count()), md->mob_class); @@ -3190,10 +3199,10 @@ int mobskill_use_pos(dumb_ptr<mob_data> md, struct block_list bl; int skill_lv; - nullpo_ret(md); + nullpo_retz(md); ms = &skill_idx; - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 0; SkillID skill_id = ms->skill_id; @@ -3215,13 +3224,13 @@ int mobskill_use_pos(dumb_ptr<mob_data> md, // delay=skill_delayfix(sd, skill_get_delay( skill_id,skill_lv) ); interval_t casttime = skill_castfix(md, ms->casttime); - md->skilldelayup[ms - &mob_db[md->mob_class].skills.front()] = gettick(); + md->skilldelayup[ms - &get_mob_db(md->mob_class).skills.front()] = gettick(); md->state.skillcastcancel = ms->cancel; if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill use target_pos= (%d,%d) skill=%d lv=%d cast=%d, mob_class = %d\n", - skill_x, skill_y, skill_id, skill_lv, - static_cast<uint32_t>(casttime.count()), md->mob_class); + PRINTF("MOB skill use target_pos= (%d,%d) skill=%d lv=%d cast=%d, mob_class = %d\n"_fmt, + skill_x, skill_y, skill_id, skill_lv, + static_cast<uint32_t>(casttime.count()), md->mob_class); if (casttime <= interval_t::zero()) // A skill without a cast time wont be cancelled. @@ -3229,7 +3238,7 @@ int mobskill_use_pos(dumb_ptr<mob_data> md, md->skillx = skill_x; md->skilly = skill_y; - md->skilltarget = 0; + md->skilltarget = BlockId(); md->skillid = skill_id; md->skilllv = skill_lv; md->skillidx = &skill_idx; @@ -3257,8 +3266,8 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, { int max_hp; - nullpo_ret(md); - std::vector<mob_skill>& ms = mob_db[md->mob_class].skills; + nullpo_retz(md); + std::vector<mob_skill>& ms = get_mob_db(md->mob_class).skills; max_hp = battle_get_max_hp(md); @@ -3312,7 +3321,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, if (skill_get_inf(msii.skill_id) & 2) { // 場所指定 - dumb_ptr<block_list> bl = NULL; + dumb_ptr<block_list> bl = nullptr; int x = 0, y = 0; { if (msii.target == MobSkillTarget::MST_TARGET) @@ -3334,7 +3343,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, else { { - dumb_ptr<block_list> bl = NULL; + dumb_ptr<block_list> bl = nullptr; if (msii.target == MobSkillTarget::MST_TARGET) bl = map_id2bl(md->target_id); else @@ -3358,7 +3367,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, */ int mobskill_event(dumb_ptr<mob_data> md, BF flag) { - nullpo_ret(md); + nullpo_retz(md); if (flag == BF::NEGATIVE_1 && mobskill_use(md, gettick(), MobSkillCondition::ANY)) @@ -3380,42 +3389,42 @@ int mobskill_event(dumb_ptr<mob_data> md, BF flag) *------------------------------------------ */ static -int mob_makedummymobdb(int mob_class) +int mob_makedummymobdb(Species mob_class) { int i; - SNPRINTF(mob_db[mob_class].name, 24, "mob%d", mob_class); - SNPRINTF(mob_db[mob_class].jname, 24, "mob%d", mob_class); - mob_db[mob_class].lv = 1; - mob_db[mob_class].max_hp = 1000; - mob_db[mob_class].max_sp = 1; - mob_db[mob_class].base_exp = 2; - mob_db[mob_class].job_exp = 1; - mob_db[mob_class].range = 1; - mob_db[mob_class].atk1 = 7; - mob_db[mob_class].atk2 = 10; - mob_db[mob_class].def = 0; - mob_db[mob_class].mdef = 0; - mob_db[mob_class].attrs[ATTR::STR] = 1; - mob_db[mob_class].attrs[ATTR::AGI] = 1; - mob_db[mob_class].attrs[ATTR::VIT] = 1; - mob_db[mob_class].attrs[ATTR::INT] = 1; - mob_db[mob_class].attrs[ATTR::DEX] = 6; - mob_db[mob_class].attrs[ATTR::LUK] = 2; - mob_db[mob_class].range2 = 10; - mob_db[mob_class].range3 = 10; - mob_db[mob_class].size = 0; // 1 - mob_db[mob_class].race = Race::formless; - mob_db[mob_class].element = LevelElement{0, Element::neutral}; - mob_db[mob_class].mode = MobMode::ZERO; - mob_db[mob_class].speed = 300; - mob_db[mob_class].adelay = 1000; - mob_db[mob_class].amotion = 500; - mob_db[mob_class].dmotion = 500; + SNPRINTF(get_mob_db(mob_class).name, 24, "mob%d"_fmt, mob_class); + SNPRINTF(get_mob_db(mob_class).jname, 24, "mob%d"_fmt, mob_class); + get_mob_db(mob_class).lv = 1; + get_mob_db(mob_class).max_hp = 1000; + get_mob_db(mob_class).max_sp = 1; + get_mob_db(mob_class).base_exp = 2; + get_mob_db(mob_class).job_exp = 1; + get_mob_db(mob_class).range = 1; + get_mob_db(mob_class).atk1 = 7; + get_mob_db(mob_class).atk2 = 10; + get_mob_db(mob_class).def = 0; + get_mob_db(mob_class).mdef = 0; + get_mob_db(mob_class).attrs[ATTR::STR] = 1; + get_mob_db(mob_class).attrs[ATTR::AGI] = 1; + get_mob_db(mob_class).attrs[ATTR::VIT] = 1; + get_mob_db(mob_class).attrs[ATTR::INT] = 1; + get_mob_db(mob_class).attrs[ATTR::DEX] = 6; + get_mob_db(mob_class).attrs[ATTR::LUK] = 2; + get_mob_db(mob_class).range2 = 10; + get_mob_db(mob_class).range3 = 10; + get_mob_db(mob_class).size = 0; // 1 + get_mob_db(mob_class).race = Race::formless; + get_mob_db(mob_class).element = LevelElement{0, Element::neutral}; + get_mob_db(mob_class).mode = MobMode::ZERO; + get_mob_db(mob_class).speed = 300; + get_mob_db(mob_class).adelay = 1000; + get_mob_db(mob_class).amotion = 500; + get_mob_db(mob_class).dmotion = 500; for (i = 0; i < 8; i++) { - mob_db[mob_class].dropitem[i].nameid = 0; - mob_db[mob_class].dropitem[i].p.num = 0; + get_mob_db(mob_class).dropitem[i].nameid = ItemNameId(); + get_mob_db(mob_class).dropitem[i].p.num = 0; } return 0; } @@ -3439,13 +3448,13 @@ bool mob_readdb(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - PRINTF("Unable to read mob db: %s\n", filename); + PRINTF("Unable to read mob db: %s\n"_fmt, filename); return false; } AString line; while (in.getline(line)) { - int mob_class; + Species mob_class; if (is_comment(line)) continue; @@ -3515,80 +3524,80 @@ bool mob_readdb(ZString filename) ) ); - if (!okay || mob_class <= 1000 || mob_class > 2000) + if (!okay || mobdb_checkid(mob_class) == Species()) { - PRINTF("bad mob line: %s\n", line); + PRINTF("bad mob line: %s\n"_fmt, line); rv = false; continue; } // TODO move this lower - mob_db[mob_class] = std::move(mdbv); + get_mob_db(mob_class) = std::move(mdbv); - if (mob_db[mob_class].base_exp < 0) - mob_db[mob_class].base_exp = 0; - else if (mob_db[mob_class].base_exp > 0 - && (mob_db[mob_class].base_exp * + if (get_mob_db(mob_class).base_exp < 0) + get_mob_db(mob_class).base_exp = 0; + else if (get_mob_db(mob_class).base_exp > 0 + && (get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100 > 1000000000 - || mob_db[mob_class].base_exp * + || get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100 < 0)) - mob_db[mob_class].base_exp = 1000000000; + get_mob_db(mob_class).base_exp = 1000000000; else - mob_db[mob_class].base_exp = mob_db[mob_class].base_exp * battle_config.base_exp_rate / 100; + get_mob_db(mob_class).base_exp = get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100; - if (mob_db[mob_class].job_exp < 0) - mob_db[mob_class].job_exp = 0; - else if (mob_db[mob_class].job_exp > 0 - && (mob_db[mob_class].job_exp * battle_config.job_exp_rate / + if (get_mob_db(mob_class).job_exp < 0) + get_mob_db(mob_class).job_exp = 0; + else if (get_mob_db(mob_class).job_exp > 0 + && (get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100 > 1000000000 - || mob_db[mob_class].job_exp * + || get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100 < 0)) - mob_db[mob_class].job_exp = 1000000000; + get_mob_db(mob_class).job_exp = 1000000000; else - mob_db[mob_class].job_exp = mob_db[mob_class].job_exp * battle_config.job_exp_rate / 100; + get_mob_db(mob_class).job_exp = get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100; for (int i = 0; i < 8; i++) { - int rate = mob_db[mob_class].dropitem[i].p.num; + int rate = get_mob_db(mob_class).dropitem[i].p.num; if (rate < 1) rate = 1; if (rate > 10000) rate = 10000; - mob_db[mob_class].dropitem[i].p.num = rate; + get_mob_db(mob_class).dropitem[i].p.num = rate; } - mob_db[mob_class].skills.clear(); + get_mob_db(mob_class).skills.clear(); - mob_db[mob_class].hair = 0; - mob_db[mob_class].hair_color = 0; - mob_db[mob_class].weapon = 0; - mob_db[mob_class].shield = 0; - mob_db[mob_class].head_top = 0; - mob_db[mob_class].head_mid = 0; - mob_db[mob_class].head_buttom = 0; - mob_db[mob_class].clothes_color = 0; //Add for player monster dye - Valaris + get_mob_db(mob_class).hair = 0; + get_mob_db(mob_class).hair_color = 0; + get_mob_db(mob_class).weapon = 0; + get_mob_db(mob_class).shield = ItemNameId(); + get_mob_db(mob_class).head_top = ItemNameId(); + get_mob_db(mob_class).head_mid = ItemNameId(); + get_mob_db(mob_class).head_buttom = ItemNameId(); + get_mob_db(mob_class).clothes_color = 0; //Add for player monster dye - Valaris - if (mob_db[mob_class].base_exp == 0) - mob_db[mob_class].base_exp = mob_gen_exp(&mob_db[mob_class]); + if (get_mob_db(mob_class).base_exp == 0) + get_mob_db(mob_class).base_exp = mob_gen_exp(&get_mob_db(mob_class)); } - PRINTF("read %s done\n", filename); + PRINTF("read %s done\n"_fmt, filename); } return rv; } -template<> -bool extract<MobSkillCondition, void, void>(XString str, MobSkillCondition *msc) +static +bool extract(XString str, MobSkillCondition *msc) { const struct { - ZString str; + LString str; MobSkillCondition id; } cond1[] = { - {ZString("always"), MobSkillCondition::MSC_ALWAYS}, - {ZString("myhpltmaxrate"), MobSkillCondition::MSC_MYHPLTMAXRATE}, - {ZString("notintown"), MobSkillCondition::MSC_NOTINTOWN}, - {ZString("slavelt"), MobSkillCondition::MSC_SLAVELT}, - {ZString("slavele"), MobSkillCondition::MSC_SLAVELE}, + {"always"_s, MobSkillCondition::MSC_ALWAYS}, + {"myhpltmaxrate"_s, MobSkillCondition::MSC_MYHPLTMAXRATE}, + {"notintown"_s, MobSkillCondition::MSC_NOTINTOWN}, + {"slavelt"_s, MobSkillCondition::MSC_SLAVELT}, + {"slavele"_s, MobSkillCondition::MSC_SLAVELE}, }; for (auto& pair : cond1) if (str == pair.str) @@ -3599,19 +3608,19 @@ bool extract<MobSkillCondition, void, void>(XString str, MobSkillCondition *msc) return false; } -template<> -bool extract<MobSkillState, void, void>(XString str, MobSkillState *mss) +static +bool extract(XString str, MobSkillState *mss) { const struct { - ZString str; + LString str; MobSkillState id; } state[] = { - {ZString("any"), MobSkillState::ANY}, - {ZString("idle"), MobSkillState::MSS_IDLE}, - {ZString("walk"), MobSkillState::MSS_WALK}, - {ZString("attack"), MobSkillState::MSS_ATTACK}, + {"any"_s, MobSkillState::ANY}, + {"idle"_s, MobSkillState::MSS_IDLE}, + {"walk"_s, MobSkillState::MSS_WALK}, + {"attack"_s, MobSkillState::MSS_ATTACK}, }; for (auto& pair : state) if (str == pair.str) @@ -3622,17 +3631,17 @@ bool extract<MobSkillState, void, void>(XString str, MobSkillState *mss) return false; } -template<> -bool extract<MobSkillTarget, void, void>(XString str, MobSkillTarget *mst) +static +bool extract(XString str, MobSkillTarget *mst) { const struct { - ZString str; + LString str; MobSkillTarget id; } target[] = { - {ZString("target"), MobSkillTarget::MST_TARGET}, - {ZString("self"), MobSkillTarget::MST_SELF}, + {"target"_s, MobSkillTarget::MST_TARGET}, + {"self"_s, MobSkillTarget::MST_SELF}, }; for (auto& pair : target) if (str == pair.str) @@ -3650,21 +3659,21 @@ bool mob_readskilldb(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - PRINTF("can't read %s\n", filename); + PRINTF("can't read %s\n"_fmt, filename); return false; } AString line; while (in.getline(line)) { - int mob_id; + Species mob_id; if (is_comment(line)) continue; XString blah; - if (extract(line, record<','>(&mob_id, &blah)) && mob_id > 0 && blah == "clear") + if (extract(line, record<','>(&mob_id, &blah)) && mobdb_checkid(mob_id) != Species() && blah == "clear"_s) { - mob_db[mob_id].skills.clear(); + get_mob_db(mob_id).skills.clear(); continue; } @@ -3699,9 +3708,9 @@ bool mob_readskilldb(ZString filename) ) ) continue; - if (cancellable == "yes") + if (cancellable == "yes"_s) msv.cancel = true; - else if (cancellable == "no") + else if (cancellable == "no"_s) msv.cancel = false; else { @@ -3712,15 +3721,15 @@ bool mob_readskilldb(ZString filename) msv.casttime = std::chrono::milliseconds(casttime); msv.delay = std::chrono::milliseconds(delay); - if (mob_id <= 0) + if (mobdb_checkid(mob_id) == Species()) { rv = false; continue; } - mob_db[mob_id].skills.push_back(std::move(msv)); + get_mob_db(mob_id).skills.push_back(std::move(msv)); } - PRINTF("read %s done\n", filename); + PRINTF("read %s done\n"_fmt, filename); } return rv; } @@ -3736,3 +3745,4 @@ void do_init_mob2(void) MIN_MOBTHINKTIME * 10 ).detach(); } +} // namespace tmwa |