diff options
Diffstat (limited to 'src/map/mob.cpp')
-rw-r--r-- | src/map/mob.cpp | 151 |
1 files changed, 77 insertions, 74 deletions
diff --git a/src/map/mob.cpp b/src/map/mob.cpp index dd061d0..539b547 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -36,18 +36,20 @@ #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" -#include "../io/cxxstdio_enums.hpp" +#include "../io/extract.hpp" #include "../io/read.hpp" #include "../net/socket.hpp" #include "../net/timer.hpp" #include "../mmo/config_parse.hpp" -#include "../mmo/extract.hpp" +#include "../mmo/cxxstdio_enums.hpp" #include "../mmo/extract_enums.hpp" #include "battle.hpp" +#include "battle_conf.hpp" #include "clif.hpp" +#include "globals.hpp" #include "itemdb.hpp" #include "map.hpp" #include "npc.hpp" @@ -61,6 +63,8 @@ namespace tmwa { +namespace map +{ constexpr interval_t MIN_MOBTHINKTIME = 100_ms; // Move probability in the negligent mode MOB (rate of 1000 minute) @@ -68,8 +72,6 @@ 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)]; @@ -318,12 +320,12 @@ int mob_gen_exp(mob_db_ *mob) (2 * mob->attrs[ATTR::LUK] * mob->max_hp / mod_def); double attack_factor = (mob->atk1 + mob->atk2 + mob->attrs[ATTR::STR] / 3.0 + mob->attrs[ATTR::DEX] / 2.0 + - mob->attrs[ATTR::LUK]) * (1872.0 / mob->adelay) / 4; + mob->attrs[ATTR::LUK]) * (1872.0 / mob->adelay.count()) / 4; double dodge_factor = pow(mob->lv + mob->attrs[ATTR::AGI] + mob->attrs[ATTR::LUK] / 2.0, 4.0 / 3.0); // TODO s/persuit/pursuit/g sometime when I'm not worried about diffs double persuit_factor = - (3 + mob->range) * bool(mob->mode & MobMode::CAN_MOVE) * 1000 / mob->speed; + (3 + mob->range) * bool(mob->mode & MobMode::CAN_MOVE) * 1000 / mob->speed.count(); double aggression_factor = bool(mob->mode & MobMode::AGGRESSIVE) ? 10.0 / 9.0 @@ -331,8 +333,7 @@ int mob_gen_exp(mob_db_ *mob) int xp = floor(effective_hp * pow(sqrt(attack_factor) + sqrt(dodge_factor) + sqrt(persuit_factor) + 55, 3) - * aggression_factor / 2000000.0 - * static_cast<double>(battle_config.base_exp_rate) / 100.); + * aggression_factor / 2000000.0); if (xp < 1) xp = 1; PRINTF("Exp for mob '%s' generated: %d\n"_fmt, mob->name, xp); @@ -357,10 +358,10 @@ void mob_init(dumb_ptr<mob_data> md) 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::ADELAY] = get_mob_db(mob_class).adelay.count(); 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::SPEED] = get_mob_db(mob_class).speed.count(); md->stats[mob_stat::XP_BONUS] = MOB_XP_BONUS_BASE; for (i = 0; i < mutations_nr; i++) @@ -410,15 +411,15 @@ BlockId mob_once_spawn(dumb_ptr<map_session_data> sd, NpcEvent event) { dumb_ptr<mob_data> md = nullptr; - map_local *m; int count; - if (sd && mapname == MOB_THIS_MAP) - m = sd->bl_m; - else - m = map_mapname2mapid(mapname); + P<map_local> m = ( + (sd && mapname == MOB_THIS_MAP) + ? sd->bl_m + : TRY_UNWRAP(map_mapname2mapid(mapname), return BlockId()) + ); - if (m == nullptr || amount <= 0 || mobdb_checkid(mob_class) == Species()) + if (amount <= 0 || mobdb_checkid(mob_class) == Species()) return BlockId(); if (sd) @@ -470,18 +471,18 @@ BlockId mob_once_spawn_area(dumb_ptr<map_session_data> sd, { int x, y, i, max, lx = -1, ly = -1; BlockId id; - map_local *m; - if (mapname == MOB_THIS_MAP) - m = sd->bl_m; - else - m = map_mapname2mapid(mapname); + P<map_local> m = ( + (mapname == MOB_THIS_MAP) + ? sd->bl_m + : TRY_UNWRAP(map_mapname2mapid(mapname), return BlockId()) + ); max = (y1 - y0 + 1) * (x1 - x0 + 1) * 3; if (max > 1000) max = 1000; - if (m == nullptr || amount <= 0 || (mobdb_checkid(mob_class) == Species())) // A summon is stopped if a value is unusual + if (amount <= 0 || (mobdb_checkid(mob_class) == Species())) // A summon is stopped if a value is unusual return BlockId(); for (i = 0; i < amount; i++) @@ -1148,7 +1149,7 @@ int mob_spawn(BlockId id) mob_init(md); if (!md->stats[mob_stat::SPEED]) - md->stats[mob_stat::SPEED] = get_mob_db(md->mob_class).speed; + md->stats[mob_stat::SPEED] = get_mob_db(md->mob_class).speed.count(); md->def_ele = get_mob_db(md->mob_class).element; md->master_id = BlockId(); md->master_dist = 0; @@ -1178,11 +1179,10 @@ int mob_spawn(BlockId id) assert (!md->sc_data[i].timer); md->sc_data[i].val1 = 0; } - md->sc_count = 0; md->opt1 = Opt1::ZERO; md->opt2 = Opt2::ZERO; md->opt3 = Opt3::ZERO; - md->option = Option::ZERO; + md->option = Opt0::ZERO; md->hp = battle_get_max_hp(md); if (md->hp <= 0) @@ -1342,7 +1342,7 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist) nullpo_retz(bl); sc_data = battle_get_sc_data(bl); - Option *option = battle_get_option(bl); + Opt0 *option = battle_get_option(bl); Race race = get_mob_db(md->mob_class).race; if (md->mode == MobMode::ZERO) @@ -1572,7 +1572,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) // Since it is in the map on which the master is not, teleport is carried out and it pursues. if (mmd->bl_m != md->bl_m) { - mob_warp(md, mmd->bl_m, mmd->bl_x, mmd->bl_y, BeingRemoveWhy::WARPED); + mob_warp(md, Some(mmd->bl_m), mmd->bl_x, mmd->bl_y, BeingRemoveWhy::WARPED); md->state.master_check = 1; return 0; } @@ -1584,7 +1584,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) // Since the master was in near immediately before, teleport is carried out and it pursues. if (old_dist < 10 && md->master_dist > 18) { - mob_warp(md, nullptr, mmd->bl_x, mmd->bl_y, BeingRemoveWhy::WARPED); + mob_warp(md, None, mmd->bl_x, mmd->bl_y, BeingRemoveWhy::WARPED); md->state.master_check = 1; return 0; } @@ -2177,7 +2177,7 @@ void mob_ai_lazy(TimerData *, tick_t tick) */ struct delay_item_drop { - map_local *m; + Borrowed<map_local> m = borrow(undefined_gat); int x, y; ItemNameId nameid; int amount; @@ -2186,7 +2186,7 @@ struct delay_item_drop struct delay_item_drop2 { - map_local *m; + Borrowed<map_local> m = borrow(undefined_gat); int x, y; Item item_data; dumb_ptr<map_session_data> first_sd, second_sd, third_sd; @@ -2541,7 +2541,6 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, int base_exp, job_exp, flag = 1; double per; - 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! @@ -2592,16 +2591,17 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, ); if (it == ptv.end()) { - p = party_search(pid); - if (p && p->exp != 0) + Option<PartyPair> p_ = party_search(pid); + OMATCH_BEGIN_SOME (p, p_) { - DmgLogParty pn {}; - pn.p = p; - pn.base_exp = base_exp; - pn.job_exp = job_exp; - ptv.push_back(pn); - flag = 0; + if (p->exp != 0) + { + DmgLogParty pn{p, base_exp, job_exp}; + ptv.push_back(pn); + flag = 0; + } } + OMATCH_END (); } else { @@ -2763,7 +2763,7 @@ int mob_warpslave(dumb_ptr<mob_data> md, int x, int y) * mobワープ *------------------------------------------ */ -int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy type) +int mob_warp(dumb_ptr<mob_data> md, Option<Borrowed<map_local>> m_, int x, int y, BeingRemoveWhy type) { int i = 0, xs = 0, ys = 0, bx = x, by = y; @@ -2772,8 +2772,7 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t if (md->bl_prev == nullptr) return 0; - if (m == nullptr) - m = md->bl_m; + P<map_local> m = m_.copy_or(md->bl_m); if (type != BeingRemoveWhy::NEGATIVE1) { @@ -2892,10 +2891,10 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value_, int amount, int flag) bx = md2->bl_x; by = md2->bl_y; - map_local *m = md2->bl_m; + P<map_local> m = md2->bl_m; Species values[5]; - for (count = 0; count < 5 && values[count] != Species(); ++count) + for (count = 0; count < 5 && value_[count]; ++count) values[count] = wrap<Species>(value_[count]); if (count < 1) return 0; @@ -3417,10 +3416,10 @@ int mob_makedummymobdb(Species mob_class) 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; + get_mob_db(mob_class).speed = 300_ms; + get_mob_db(mob_class).adelay = 1000_ms; + get_mob_db(mob_class).amotion = 500_ms; + get_mob_db(mob_class).dmotion = 500_ms; for (i = 0; i < 8; i++) { get_mob_db(mob_class).dropitem[i].nameid = ItemNameId(); @@ -3430,7 +3429,7 @@ int mob_makedummymobdb(Species mob_class) } static -bool extract(XString str, LevelElement *le) +bool impl_extract(XString str, LevelElement *le) { int tmp; if (extract(str, &tmp)) @@ -3531,30 +3530,33 @@ bool mob_readdb(ZString filename) continue; } - // TODO move this lower - get_mob_db(mob_class) = std::move(mdbv); - 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 - || get_mob_db(mob_class).base_exp * - battle_config.base_exp_rate / 100 < 0)) - get_mob_db(mob_class).base_exp = 1000000000; - else - get_mob_db(mob_class).base_exp = get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100; - + { + PRINTF("bad mob line: Xp needs to be greater than 0. %s\n"_fmt, line); + rv = false; + continue; + } + if (get_mob_db(mob_class).base_exp > 1000000000) + { + PRINTF("bad mob line: Xp needs to be less than 1000000000. %s\n"_fmt, line); + rv = false; + continue; + } 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 - || get_mob_db(mob_class).job_exp * - battle_config.job_exp_rate / 100 < 0)) - get_mob_db(mob_class).job_exp = 1000000000; - else - get_mob_db(mob_class).job_exp = get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100; + { + PRINTF("bad mob line: Job Xp needs to be greater than 0. %s\n"_fmt, line); + rv = false; + continue; + } + if (get_mob_db(mob_class).job_exp > 1000000000) + { + PRINTF("bad mob line: Job Xp needs to be less than 1000000000. %s\n"_fmt, line); + rv = false; + continue; + } + + // TODO move this lower + get_mob_db(mob_class) = std::move(mdbv); for (int i = 0; i < 8; i++) { @@ -3585,7 +3587,7 @@ bool mob_readdb(ZString filename) } static -bool extract(XString str, MobSkillCondition *msc) +bool impl_extract(XString str, MobSkillCondition *msc) { const struct { @@ -3609,7 +3611,7 @@ bool extract(XString str, MobSkillCondition *msc) } static -bool extract(XString str, MobSkillState *mss) +bool impl_extract(XString str, MobSkillState *mss) { const struct { @@ -3632,7 +3634,7 @@ bool extract(XString str, MobSkillState *mss) } static -bool extract(XString str, MobSkillTarget *mst) +bool impl_extract(XString str, MobSkillTarget *mst) { const struct { @@ -3745,4 +3747,5 @@ void do_init_mob2(void) MIN_MOBTHINKTIME * 10 ).detach(); } +} // namespace map } // namespace tmwa |