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.cpp156
1 files changed, 83 insertions, 73 deletions
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 4b68cd9..46bb71e 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -103,7 +103,7 @@ int mob_spawn_dataset(struct mob_data *md, const char *mobname, int mob_class)
md->bl.prev = NULL;
md->bl.next = NULL;
md->n = 0;
- md->base_class = md->mob_class = mob_class;
+ md->mob_class = mob_class;
md->bl.id = npc_get_new_npc_id();
memset(&md->state, 0, sizeof(md->state));
@@ -282,9 +282,13 @@ int mob_gen_exp(struct mob_db *mob)
mob->attrs[ATTR::LUK]) * (1872.0 / mob->adelay) / 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) * (mob->mode % 2) * 1000 / mob->speed;
- double aggression_factor = (mob->mode & 4) == 4 ? 10.0 / 9.0 : 1.0;
+ (3 + mob->range) * bool(mob->mode & MobMode::CAN_MOVE) * 1000 / mob->speed;
+ double aggression_factor =
+ bool(mob->mode & MobMode::AGGRESSIVE)
+ ? 10.0 / 9.0
+ : 1.0;
int xp =
(int) floor(effective_hp *
pow(sqrt(attack_factor) + sqrt(dodge_factor) +
@@ -410,7 +414,7 @@ int mob_once_spawn(struct map_session_data *sd, const char *mapname,
for (count = 0; count < amount; count++)
{
md = (struct mob_data *) calloc(1, sizeof(struct mob_data));
- if (mob_db[mob_class].mode & 0x02)
+ if (bool(mob_db[mob_class].mode & MobMode::LOOTER))
md->lootitem =
(struct item *) calloc(LOOTITEM_SIZE, sizeof(struct item));
else
@@ -421,7 +425,8 @@ int mob_once_spawn(struct map_session_data *sd, const char *mapname,
md->bl.x = x;
md->bl.y = y;
if (r < 0 && battle_config.dead_branch_active == 1)
- md->mode = 0x1 + 0x4 + 0x80; //移動してアクティブで反撃する
+ //移動してアクティブで反撃する
+ md->mode = MobMode::war;
md->m = m;
md->x0 = x;
md->y0 = y;
@@ -548,6 +553,7 @@ int mob_spawn_guardian(struct map_session_data *sd, const char *mapname,
return (amount > 0) ? md->bl.id : 0;
}
+// TODO: deprecate these
int mob_get_sex(int mob_class)
{
return mob_db[mob_class].sex;
@@ -751,7 +757,8 @@ int mob_check_attack(struct mob_data *md)
struct map_session_data *tsd = NULL;
struct mob_data *tmd = NULL;
- int mode, race, range;
+ MobMode mode;
+ int race, range;
nullpo_ret(md);
@@ -802,22 +809,23 @@ int mob_check_attack(struct mob_data *md)
}
}
- if (!md->mode)
+ if (md->mode == MobMode::ZERO)
mode = mob_db[md->mob_class].mode;
else
mode = md->mode;
race = mob_db[md->mob_class].race;
- if (!(mode & 0x80))
+ if (!bool(mode & MobMode::CAN_ATTACK))
{
md->target_id = 0;
md->state.attackable = false;
return 0;
}
- if (tsd && !(mode & 0x20) && (tsd->sc_data[SC_TRICKDEAD].timer != -1 ||
- ((pc_ishiding(tsd)
- || tsd->state.gangsterparadise)
- && race != 4 && race != 6)))
+ if (tsd
+ && !bool(mode & MobMode::BOSS)
+ && (tsd->sc_data[SC_TRICKDEAD].timer != -1
+ || ((pc_ishiding(tsd) || tsd->state.gangsterparadise)
+ && race != 4 && race != 6)))
{
md->target_id = 0;
md->state.attackable = false;
@@ -825,7 +833,7 @@ int mob_check_attack(struct mob_data *md)
}
range = mob_db[md->mob_class].range;
- if (mode & 1)
+ if (bool(mode & MobMode::CAN_MOVE))
range++;
if (distance(md->bl.x, md->bl.y, tbl->x, tbl->y) > range)
return 0;
@@ -1179,8 +1187,6 @@ int mob_spawn(int id)
skill_unit_out_all(&md->bl, gettick(), 1);
map_delblock(&md->bl);
}
- else
- md->mob_class = md->base_class;
md->bl.m = md->m;
{
@@ -1420,7 +1426,8 @@ int mob_target(struct mob_data *md, struct block_list *bl, int dist)
{
struct map_session_data *sd;
eptr<struct status_change, StatusChange> sc_data;
- int mode, race;
+ MobMode mode;
+ int race;
nullpo_ret(md);
nullpo_ret(bl);
@@ -1429,7 +1436,7 @@ int mob_target(struct mob_data *md, struct block_list *bl, int dist)
Option *option = battle_get_option(bl);
race = mob_db[md->mob_class].race;
- if (!md->mode)
+ if (md->mode == MobMode::ZERO)
{
mode = mob_db[md->mob_class].mode;
}
@@ -1437,18 +1444,18 @@ int mob_target(struct mob_data *md, struct block_list *bl, int dist)
{
mode = md->mode;
}
- if (!(mode & 0x80))
+ if (!bool(mode & MobMode::CAN_ATTACK))
{
md->target_id = 0;
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)
- && (!(mode & 0x04) || MRAND(100) > 25))
+ && (!bool(mode & MobMode::AGGRESSIVE) || MRAND(100) > 25))
return 0;
// Coercion is exerted if it is MVPMOB.
- if (mode & 0x20
+ if (bool(mode & MobMode::BOSS)
|| (sc_data && sc_data[SC_TRICKDEAD].timer == -1
&& ((option != NULL && !bool(*option & (Option::CLOAK | Option::HIDE2)))
|| race == 4
@@ -1459,7 +1466,7 @@ int mob_target(struct mob_data *md, struct block_list *bl, int dist)
nullpo_ret(sd = (struct map_session_data *) bl);
if (sd->invincible_timer != -1 || pc_isinvisible(sd))
return 0;
- if (!(mode & 0x20) && race != 4 && race != 6
+ if (!bool(mode & MobMode::BOSS) && race != 4 && race != 6
&& sd->state.gangsterparadise)
return 0;
}
@@ -1486,7 +1493,8 @@ void mob_ai_sub_hard_activesearch(struct block_list *bl,
{
struct map_session_data *tsd = NULL;
struct mob_data *tmd = NULL;
- int mode, race, dist;
+ MobMode mode;
+ int race, dist;
nullpo_retv(bl);
nullpo_retv(smd);
@@ -1503,13 +1511,13 @@ void mob_ai_sub_hard_activesearch(struct block_list *bl,
if (battle_check_target(&smd->bl, bl, BCT_ENEMY) == 0)
return;
- if (!smd->mode)
+ if (smd->mode == MobMode::ZERO)
mode = mob_db[smd->mob_class].mode;
else
mode = smd->mode;
// アクティブでターゲット射程内にいるなら、ロックする
- if (mode & 0x04)
+ if (bool(mode & MobMode::AGGRESSIVE))
{
race = mob_db[smd->mob_class].race;
//対象がPCの場合
@@ -1521,10 +1529,11 @@ void mob_ai_sub_hard_activesearch(struct block_list *bl,
(dist =
distance(smd->bl.x, smd->bl.y, tsd->bl.x, tsd->bl.y)) < 9)
{
- if (mode & 0x20 ||
- (tsd->sc_data[SC_TRICKDEAD].timer == -1 &&
- ((!pc_ishiding(tsd) && !tsd->state.gangsterparadise)
- || race == 4 || race == 6)))
+ if (bool(mode & MobMode::BOSS)
+ || (tsd->sc_data[SC_TRICKDEAD].timer == -1
+ && ((!pc_ishiding(tsd)
+ && !tsd->state.gangsterparadise)
+ || race == 4 || race == 6)))
{ // 妨害がないか判定
if (mob_can_reach(smd, bl, 12) && // 到達可能性判定
MRAND(1000) < 1000 / (++(*pcc)))
@@ -1559,11 +1568,12 @@ void mob_ai_sub_hard_activesearch(struct block_list *bl,
static
void mob_ai_sub_hard_lootsearch(struct block_list *bl, struct mob_data *md, int *itc)
{
- int mode, dist;
+ MobMode mode;
+ int dist;
nullpo_retv(bl);
- if (!md->mode)
+ if (md->mode == MobMode::ZERO)
{
mode = mob_db[md->mob_class].mode;
}
@@ -1572,7 +1582,7 @@ void mob_ai_sub_hard_lootsearch(struct block_list *bl, struct mob_data *md, int
mode = md->mode;
}
- if (!md->target_id && mode & 0x02)
+ if (!md->target_id && bool(mode & MobMode::LOOTER))
{
if (!md->lootitem
|| (battle_config.monster_loot_type == 1
@@ -1606,23 +1616,16 @@ void mob_ai_sub_hard_linksearch(struct block_list *bl, struct mob_data *md, stru
nullpo_retv(md);
nullpo_retv(target);
- // same family free in a range at a link monster -- it will be made to lock if MOB is
-/* if ((md->target_id > 0 && md->state.attackable) && mob_db[md->mob_class].mode&0x08){
- if ( tmd->mob_class==md->mob_class && (!tmd->target_id || !md->state.attackable) && tmd->bl.m == md->bl.m){
- if ( mob_can_reach(tmd,target,12) ){ // Reachability judging
- tmd->target_id=md->target_id;
- tmd->state.attackable = true;
- tmd->min_chase=13;
- }
- }
- }*/
- if (md->attacked_id > 0 && mob_db[md->mob_class].mode & 0x08)
+ if (md->attacked_id > 0
+ && bool(mob_db[md->mob_class].mode & MobMode::ASSIST))
{
- if (tmd->mob_class == md->mob_class && tmd->bl.m == md->bl.m
+ if (tmd->mob_class == md->mob_class
+ && tmd->bl.m == md->bl.m
&& (!tmd->target_id || !md->state.attackable))
{
if (mob_can_reach(tmd, target, 12))
- { // Reachability judging
+ {
+ // Reachability judging
tmd->target_id = md->attacked_id;
tmd->state.attackable = true;
tmd->min_chase = 13;
@@ -1640,7 +1643,8 @@ int mob_ai_sub_hard_slavemob(struct mob_data *md, unsigned int tick)
{
struct mob_data *mmd = NULL;
struct block_list *bl;
- int mode, race, old_dist;
+ MobMode mode;
+ int race, old_dist;
nullpo_ret(md);
@@ -1742,7 +1746,7 @@ int mob_ai_sub_hard_slavemob(struct mob_data *md, unsigned int tick)
{
race = mob_db[md->mob_class].race;
- if (mode & 0x20 ||
+ if (bool(mode & MobMode::BOSS) ||
(sd->sc_data[SC_TRICKDEAD].timer == -1 &&
((!pc_ishiding(sd) && !sd->state.gangsterparadise)
|| race == 4 || race == 6)))
@@ -1863,7 +1867,8 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
struct flooritem_data *fitem;
int i, dx, dy, ret, dist;
int attack_type = 0;
- int mode, race;
+ MobMode mode;
+ int race;
nullpo_retv(bl);
md = (struct mob_data *) bl;
@@ -1879,7 +1884,7 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
return;
}
- if (!md->mode)
+ if (md->mode == MobMode::ZERO)
mode = mob_db[md->mob_class].mode;
else
mode = md->mode;
@@ -1891,10 +1896,10 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
|| md->state.state == MS_DELAY)
return;
- if (!(mode & 0x80) && md->target_id > 0)
+ if (!bool(mode & MobMode::CAN_ATTACK) && md->target_id > 0)
md->target_id = 0;
- if (md->attacked_id > 0 && mode & 0x08)
+ if (md->attacked_id > 0 && bool(mode & MobMode::ASSIST))
{ // Link monster
struct map_session_data *asd = map_id2sd(md->attacked_id);
if (asd)
@@ -1909,9 +1914,9 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
}
// It checks to see it was attacked first (if active, it is target change at 25% of probability).
- if (mode > 0 && md->attacked_id > 0
+ if (mode != MobMode::ZERO && md->attacked_id > 0
&& (!md->target_id || !md->state.attackable
- || (mode & 0x04 && MRAND(100) < 25)))
+ || (bool(mode & MobMode::AGGRESSIVE) && MRAND(100) < 25)))
{
struct block_list *abl = map_id2bl(md->attacked_id);
struct map_session_data *asd = NULL;
@@ -1945,7 +1950,7 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
// アクティヴモンスターの策敵 (?? of a bitter taste TIVU monster)
if ((!md->target_id || !md->state.attackable)
- && mode & 0x04 && !md->state.master_check
+ && bool(mode & MobMode::AGGRESSIVE) && !md->state.master_check
&& battle_config.monster_active_enable == 1)
{
i = 0;
@@ -1965,7 +1970,9 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
}
// The item search of a route monster
- if (!md->target_id && mode & 0x02 && !md->state.master_check)
+ if (!md->target_id
+ && bool(mode & MobMode::LOOTER)
+ && !md->state.master_check)
{
i = 0;
map_foreachinarea(std::bind(mob_ai_sub_hard_lootsearch, ph::_1, md, &i),
@@ -1989,7 +1996,7 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
distance(md->bl.x, md->bl.y, tbl->x,
tbl->y)) >= md->min_chase)
mob_unlocktarget(md, tick); // 別マップか、視界外
- else if (tsd && !(mode & 0x20)
+ else if (tsd && !bool(mode & MobMode::BOSS)
&& (tsd->sc_data[SC_TRICKDEAD].timer != -1
||
((pc_ishiding(tsd)
@@ -1999,7 +2006,7 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
else if (!battle_check_range(&md->bl, tbl, mob_db[md->mob_class].range))
{
// 攻撃範囲外なので移動
- if (!(mode & 1))
+ if (!bool(mode & MobMode::CAN_MOVE))
{ // 移動しないモード
mob_unlocktarget(md, tick);
return;
@@ -2103,7 +2110,7 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
}
else if (dist)
{
- if (!(mode & 1))
+ if (!bool(mode & MobMode::CAN_MOVE))
{ // 移動しないモード
mob_unlocktarget(md, tick);
return;
@@ -2173,9 +2180,10 @@ void mob_ai_sub_hard(struct block_list *bl, unsigned int tick)
return;
// 歩行処理
- if (mode & 1 && mob_can_move(md) && // 移動可能MOB&動ける状態にある
- (md->master_id == 0 || md->state.special_mob_ai
- || md->master_dist > 10))
+ if (bool(mode & MobMode::CAN_MOVE)
+ && mob_can_move(md)
+ && (md->master_id == 0 || md->state.special_mob_ai
+ || md->master_dist > 10))
{ //取り巻きMOBじゃない
if (DIFF_TICK(md->next_walktime, tick) > +7000 &&
@@ -2248,8 +2256,9 @@ void mob_ai_sub_lazy(db_key_t, db_val_t data, unsigned int tick)
return;
}
- if (DIFF_TICK(md->next_walktime, tick) < 0 &&
- (mob_db[md->mob_class].mode & 1) && mob_can_move(md))
+ if (DIFF_TICK(md->next_walktime, tick) < 0
+ && bool(mob_db[md->mob_class].mode & MobMode::CAN_MOVE)
+ && mob_can_move(md))
{
if (map[md->bl.m].users > 0)
@@ -2263,7 +2272,7 @@ void mob_ai_sub_lazy(db_key_t, db_val_t data, unsigned int tick)
// MOB which is not not the summons MOB but BOSS, either sometimes reboils.
else if (MRAND(1000) < MOB_LAZYWARPPERC && md->x0 <= 0
&& md->master_id != 0 && mob_db[md->mob_class].mexp <= 0
- && !(mob_db[md->mob_class].mode & 0x20))
+ && !bool(mob_db[md->mob_class].mode & MobMode::BOSS))
mob_spawn(md->bl.id);
}
@@ -2274,7 +2283,7 @@ void mob_ai_sub_lazy(db_key_t, db_val_t data, unsigned int tick)
// MOB which is not BOSS which is not Summons MOB, either -- a case -- sometimes -- leaping
if (MRAND(1000) < MOB_LAZYWARPPERC && md->x0 <= 0
&& md->master_id != 0 && mob_db[md->mob_class].mexp <= 0
- && !(mob_db[md->mob_class].mode & 0x20))
+ && !bool(mob_db[md->mob_class].mode & MobMode::BOSS))
mob_warp(md, -1, -1, -1, -1);
}
@@ -2491,11 +2500,11 @@ int mob_damage(struct block_list *src, struct mob_data *md, int damage,
nullpo_ret(md); //srcはNULLで呼ばれる場合もあるので、他でチェック
if (src && src->id == md->master_id
- && md->mode & MOB_MODE_TURNS_AGAINST_BAD_MASTER)
+ && bool(md->mode & MOB_MODE_TURNS_AGAINST_BAD_MASTER))
{
/* If the master hits a monster, have the monster turn against him */
md->master_id = 0;
- md->mode = 0x85; /* Regular war mode */
+ md->mode = MobMode::war; /* Regular war mode */
md->target_id = src->id;
md->attacked_id = src->id;
}
@@ -2635,7 +2644,7 @@ int mob_damage(struct block_list *src, struct mob_data *md, int damage,
if ((skillidx =
mob_skillid2skillidx(md->mob_class, NPC_SELFDESTRUCTION2)) >= 0)
{
- md->mode |= 0x1;
+ md->mode |= MobMode::CAN_MOVE;
md->next_walktime = tick;
mobskill_use_id(md, &md->bl, skillidx); //自爆詠唱開始
md->state.special_mob_ai++;
@@ -2826,9 +2835,9 @@ int mob_damage(struct block_list *src, struct mob_data *md, int damage,
if (sd->monster_drop_itemid[i] <= 0)
continue;
if (sd->monster_drop_race[i] & (1 << race) ||
- (mob_db[md->mob_class].mode & 0x20
+ (bool(mob_db[md->mob_class].mode & MobMode::BOSS)
&& sd->monster_drop_race[i] & 1 << 10)
- || (!(mob_db[md->mob_class].mode & 0x20)
+ || (!bool(mob_db[md->mob_class].mode & MobMode::BOSS)
&& sd->monster_drop_race[i] & 1 << 11))
{
if (sd->monster_drop_itemrate[i] <= MRAND(10000))
@@ -3026,7 +3035,8 @@ int mob_class_change(struct mob_data *md, int *value)
md->skillid = SkillID();
md->skilllv = 0;
- if (md->lootitem == NULL && mob_db[mob_class].mode & 0x02)
+ if (md->lootitem == NULL
+ && bool(mob_db[mob_class].mode & MobMode::LOOTER))
md->lootitem = (struct item *)
calloc(LOOTITEM_SIZE, sizeof(struct item));
@@ -3231,7 +3241,7 @@ int mob_summonslave(struct mob_data *md2, int *value, int amount, int flag)
{
int x = 0, y = 0, c = 0, i = 0;
md = (struct mob_data *) calloc(1, sizeof(struct mob_data));
- if (mob_db[mob_class].mode & 0x02)
+ if (bool(mob_db[mob_class].mode & MobMode::LOOTER))
md->lootitem = (struct item *)
calloc(LOOTITEM_SIZE, sizeof(struct item));
else
@@ -4012,7 +4022,7 @@ int mob_makedummymobdb(int mob_class)
mob_db[mob_class].size = 0;
mob_db[mob_class].race = 0;
mob_db[mob_class].element = 0;
- mob_db[mob_class].mode = 0;
+ 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;
@@ -4133,7 +4143,7 @@ int mob_readdb(void)
mob_db[mob_class].size = atoi(str[21]);
mob_db[mob_class].race = atoi(str[22]);
mob_db[mob_class].element = atoi(str[23]);
- mob_db[mob_class].mode = atoi(str[24]);
+ mob_db[mob_class].mode = static_cast<MobMode>(atoi(str[24]));
mob_db[mob_class].speed = atoi(str[25]);
mob_db[mob_class].adelay = atoi(str[26]);
mob_db[mob_class].amotion = atoi(str[27]);