summaryrefslogtreecommitdiff
path: root/src/map/mob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/mob.cpp')
-rw-r--r--src/map/mob.cpp151
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