summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLed Mitz <smoothshifter@tuta.io>2023-11-27 13:47:33 +0000
committerLed Mitz <smoothshifter@tuta.io>2023-11-27 13:47:33 +0000
commit70c2692d38e6fac1c230a51c283438de11a61ce1 (patch)
treef1b3713ad5ce48f48e688bb627edc51af067eb0d
parent4d23200c606b5c96877384f5ab2820a6cfcadda8 (diff)
parent78ad8bcab7a0d29200e8cd47c1d759d0eeb15a72 (diff)
downloadtmwa-70c2692d38e6fac1c230a51c283438de11a61ce1.tar.gz
tmwa-70c2692d38e6fac1c230a51c283438de11a61ce1.tar.bz2
tmwa-70c2692d38e6fac1c230a51c283438de11a61ce1.tar.xz
tmwa-70c2692d38e6fac1c230a51c283438de11a61ce1.zip
Merge branch 'activity_checks' into 'master'
activity checks and status cleanup See merge request legacy/tmwa!252
-rw-r--r--src/map/atcommand.cpp28
-rw-r--r--src/map/chrif.cpp2
-rw-r--r--src/map/map.cpp2
-rw-r--r--src/map/map.hpp9
-rw-r--r--src/map/map.t.hpp2
-rw-r--r--src/map/mob.cpp253
-rw-r--r--src/map/pc.cpp103
-rw-r--r--src/map/pc.t.hpp10
-rw-r--r--src/map/script-fun.cpp21
-rw-r--r--src/map/skill-pools.cpp4
-rw-r--r--src/map/skill.cpp4
-rw-r--r--src/mmo/clif.t.hpp6
12 files changed, 318 insertions, 126 deletions
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 8c0eb90..eaefd4f 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -1270,7 +1270,7 @@ ATCE atcommand_option(Session *s, dumb_ptr<map_session_data> sd,
sd->status.option = param3;
clif_changeoption(sd);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_displaymessage(s, "Options changed."_s);
return ATCE::OKAY;
@@ -1532,7 +1532,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, SP::BASELEVEL);
clif_updatestatus(sd, SP::NEXTBASEEXP);
clif_updatestatus(sd, SP::STATUSPOINT);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
pc_heal(sd, sd->status.max_hp, sd->status.max_sp);
clif_misceffect(sd, 0);
clif_displaymessage(s, "Base level raised."_s);
@@ -1560,7 +1560,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd,
sd->status.base_level += level;
clif_updatestatus(sd, SP::BASELEVEL);
clif_updatestatus(sd, SP::NEXTBASEEXP);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_displaymessage(s, "Base level lowered."_s);
}
@@ -1595,7 +1595,7 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, SP::NEXTJOBEXP);
sd->status.skill_point += level;
clif_updatestatus(sd, SP::SKILLPOINT);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_misceffect(sd, 1);
clif_displaymessage(s, "Job level raised."_s);
}
@@ -1620,7 +1620,7 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, SP::SKILLPOINT);
}
// to add: remove status points from skills
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_displaymessage(s, "Job level lowered."_s);
}
@@ -1853,7 +1853,7 @@ ATCE atcommand_mobinfo(Session *s, dumb_ptr<map_session_data> sd,
clif_displaymessage(s, STRPRINTF("Monster ID: %i, English Name: %s, Japanese Name: %s"_fmt, mob_id, get_mob_db(mob_id).name, get_mob_db(mob_id).jname));
clif_displaymessage(s, STRPRINTF("Level: %i, HP: %i, SP: %i, Base EXP: %i, JEXP: %i"_fmt, get_mob_db(mob_id).lv, get_mob_db(mob_id).max_hp, get_mob_db(mob_id).max_sp, get_mob_db(mob_id).base_exp, get_mob_db(mob_id).job_exp));
clif_displaymessage(s, STRPRINTF("Range1: %i, ATK1: %i, ATK2: %i, DEF: %i, MDEF: %i, CRITICAL_DEF: %i"_fmt, get_mob_db(mob_id).range, get_mob_db(mob_id).atk1, get_mob_db(mob_id).atk2, get_mob_db(mob_id).def, get_mob_db(mob_id).mdef, get_mob_db(mob_id).critical_def));
- clif_displaymessage(s, STRPRINTF("Stats: STR: %i, AGI: %i, VIT: %i, INT: %i, DEX:, %i LUK:, %i"_fmt, get_mob_db(mob_id).attrs[ATTR::STR], get_mob_db(mob_id).attrs[ATTR::AGI], get_mob_db(mob_id).attrs[ATTR::VIT], get_mob_db(mob_id).attrs[ATTR::INT], get_mob_db(mob_id).attrs[ATTR::DEX], get_mob_db(mob_id).attrs[ATTR::LUK]));
+ clif_displaymessage(s, STRPRINTF("Stats: STR: %i, AGI: %i, VIT: %i, INT: %i, DEX: %i, LUK: %i"_fmt, get_mob_db(mob_id).attrs[ATTR::STR], get_mob_db(mob_id).attrs[ATTR::AGI], get_mob_db(mob_id).attrs[ATTR::VIT], get_mob_db(mob_id).attrs[ATTR::INT], get_mob_db(mob_id).attrs[ATTR::DEX], get_mob_db(mob_id).attrs[ATTR::LUK]));
clif_displaymessage(s, STRPRINTF("Range2: %i, Range3: %i, Scale: %i, Race: %i, Element: %i, Element Level: %i, Mode: %i"_fmt, get_mob_db(mob_id).range2, get_mob_db(mob_id).range3, get_mob_db(mob_id).size, get_mob_db(mob_id).race, get_mob_db(mob_id).element.element, get_mob_db(mob_id).element.level, get_mob_db(mob_id).mode));
clif_displaymessage(s, STRPRINTF("Speed: %i, Adelay: %i, Amotion: %i, Dmotion: %i"_fmt, get_mob_db(mob_id).speed.count(), get_mob_db(mob_id).adelay.count(), get_mob_db(mob_id).amotion.count(), get_mob_db(mob_id).dmotion.count()));
if (get_mob_db(mob_id).mutations_nr)
@@ -2283,7 +2283,7 @@ ATCE atcommand_param(Session *s, dumb_ptr<map_session_data> sd,
sd->status.attrs[attr] = new_value;
clif_updatestatus(sd, attr_to_sp(attr));
clif_updatestatus(sd, attr_to_usp(attr));
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_displaymessage(s, "Stat changed."_s);
}
else
@@ -2318,7 +2318,7 @@ ATCE atcommand_all_stats(Session *s, dumb_ptr<map_session_data> sd,
sd->status.attrs[attr] = new_value;
clif_updatestatus(sd, attr_to_sp(attr));
clif_updatestatus(sd, attr_to_usp(attr));
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
count++;
}
}
@@ -2682,7 +2682,7 @@ ATCE atcommand_character_option(Session *s, dumb_ptr<map_session_data> sd,
pl_sd->status.option = opt3;
clif_changeoption(pl_sd);
- pc_calcstatus(pl_sd, 0);
+ pc_calcstatus(pl_sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_displaymessage(s, "Character's options changed."_s);
}
else
@@ -3004,7 +3004,7 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::BASELEVEL);
clif_updatestatus(pl_sd, SP::NEXTBASEEXP);
clif_updatestatus(pl_sd, SP::STATUSPOINT);
- pc_calcstatus(pl_sd, 0);
+ pc_calcstatus(pl_sd, (int)CalcStatusKind::NORMAL_RECALC);
pc_heal(pl_sd, pl_sd->status.max_hp, pl_sd->status.max_sp);
clif_misceffect(pl_sd, 0);
clif_displaymessage(s, "Character's base level raised."_s);
@@ -3034,7 +3034,7 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::BASELEVEL);
clif_updatestatus(pl_sd, SP::NEXTBASEEXP);
clif_updatestatus(pl_sd, SP::BASEEXP);
- pc_calcstatus(pl_sd, 0);
+ pc_calcstatus(pl_sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_displaymessage(s, "Character's base level lowered."_s);
}
// Reset their stat points to prevent extra points from stacking
@@ -3088,7 +3088,7 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::NEXTJOBEXP);
pl_sd->status.skill_point += level;
clif_updatestatus(pl_sd, SP::SKILLPOINT);
- pc_calcstatus(pl_sd, 0);
+ pc_calcstatus(pl_sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_misceffect(pl_sd, 1);
clif_displaymessage(s, "character's job level raised."_s);
}
@@ -3112,7 +3112,7 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::SKILLPOINT);
}
// to add: remove status points from skills
- pc_calcstatus(pl_sd, 0);
+ pc_calcstatus(pl_sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_displaymessage(s, "Character's job level lowered."_s);
}
}
@@ -3595,7 +3595,7 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
pc_additem(pl_sd, &item, 1);
// Reset stats and skills
- pc_calcstatus(pl_sd, 0);
+ pc_calcstatus(pl_sd, (int)CalcStatusKind::NORMAL_RECALC);
pc_resetstate(pl_sd);
pc_resetskill(pl_sd);
pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"_s), 0);
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index 972bfd0..52c311b 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -587,7 +587,7 @@ void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed)
&& bool(sd->status.inventory[i].equip))
pc_unequipitem(sd, i, CalcStatus::LATER);
}
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
// save character
chrif_save(sd);
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
diff --git a/src/map/map.cpp b/src/map/map.cpp
index e7b0da8..ff69a56 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -816,7 +816,7 @@ void map_quit(dumb_ptr<map_session_data> sd)
pc_stopattack(sd);
pc_delinvincibletimer(sd);
- pc_calcstatus(sd, 4);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC_NO_CLIENT_UPDATE);
clif_clearchar(sd, BeingRemoveWhy::QUIT);
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 659ed2d..7cf43d5 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -307,6 +307,15 @@ struct map_session_data : block_list, SessionData
unsigned guild:1;
} mute;
+ struct
+ {
+ int kills;
+ int casts;
+ int items_used;
+ int tiles_walked;
+ int attacks;
+ } activity;
+
AutoMod automod;
tick_t flood_rates[0x220];
diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp
index 4336411..0f3e608 100644
--- a/src/map/map.t.hpp
+++ b/src/map/map.t.hpp
@@ -182,7 +182,7 @@ namespace e
enum class MapCell : uint8_t
{
// the usual thing
- UNWALKABLE = 0x01,
+ UNWALKABLE = 0x01,
// not in tmwa data
_range = 0x04,
};
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 715a9cb..4fd9d6d 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -227,9 +227,9 @@ earray<int, mob_stat, mob_stat::XP_BONUS> mutation_base //=
/*========================================
* Mutates a MOB. For large `direction' values, calling this multiple times will give bigger XP boni.
+ * intensity: positive: strengthen, negative: weaken. 256 = 100%.
*----------------------------------------
*/
-// intensity: positive: strengthen, negative: weaken. 256 = 100%.
static
void mob_mutate(dumb_ptr<mob_data> md, mob_stat stat, int intensity)
{
@@ -309,7 +309,10 @@ void mob_mutate(dumb_ptr<mob_data> md, mob_stat stat, int intensity)
}
}
-// This calculates the exp of a given mob
+/*==========================================
+ * This calculates the exp of a given mob
+ *------------------------------------------
+ */
static
int mob_gen_exp(mob_db_ *mob)
{
@@ -343,6 +346,10 @@ int mob_gen_exp(mob_db_ *mob)
return xp;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
void mob_init(dumb_ptr<mob_data> md)
{
@@ -517,46 +524,82 @@ BlockId mob_once_spawn_area(dumb_ptr<map_session_data> sd,
}
// TODO: deprecate these
+/*==========================================
+ *
+ *------------------------------------------
+ */
short mob_get_hair(Species mob_class)
{
return get_mob_db(mob_class).hair;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
short mob_get_hair_color(Species mob_class)
{
return get_mob_db(mob_class).hair_color;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
short mob_get_weapon(Species mob_class)
{
return get_mob_db(mob_class).weapon;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
ItemNameId mob_get_shield(Species mob_class)
{
return get_mob_db(mob_class).shield;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
ItemNameId mob_get_head_top(Species mob_class)
{
return get_mob_db(mob_class).head_top;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
ItemNameId mob_get_head_mid(Species mob_class)
{
return get_mob_db(mob_class).head_mid;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
ItemNameId mob_get_head_buttom(Species mob_class)
{
return get_mob_db(mob_class).head_buttom;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
short mob_get_clothes_color(Species mob_class) // Add for player monster dye - Valaris
{
return get_mob_db(mob_class).clothes_color; // End
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
int mob_get_equip(Species mob_class) // mob equip [Valaris]
{
return get_mob_db(mob_class).equip;
@@ -789,6 +832,10 @@ int mob_check_attack(dumb_ptr<mob_data> md)
return 1;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
void mob_ancillary_attack(dumb_ptr<block_list> bl,
dumb_ptr<block_list> mdbl, dumb_ptr<block_list> tbl, tick_t tick)
@@ -815,7 +862,7 @@ int mob_attack(dumb_ptr<mob_data> md, tick_t tick)
return 0;
if (battle_config.monster_attack_direction_change)
- md->dir = map_calc_dir(md, tbl->bl_x, tbl->bl_y); // 向き設定
+ md->dir = map_calc_dir(md, tbl->bl_x, tbl->bl_y); // 向き設定 | Orientation setting
//clif_fixmobpos(md);
@@ -941,7 +988,7 @@ void mob_timer(TimerData *, tick_t tick, BlockId id, unsigned char data)
dumb_ptr<block_list> bl;
bl = map_id2bl(id);
if (bl == nullptr)
- { //攻撃してきた敵がもういないのは正常のようだ
+ { // 攻撃してきた敵がもういないのは正常のようだ | It seems normal that the enemy that attacked us is no longer there.
return;
}
@@ -1301,13 +1348,13 @@ int mob_can_reach(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int range)
return 0;
}
- if (md->bl_m != bl->bl_m) // 違うャbプ
+ if (md->bl_m != bl->bl_m) // 違うャbプ | Different type
return 0;
- if (range > 0 && range < arange) // 遠すぎる
+ if (range > 0 && range < arange) // 遠すぎる | too far
return 0;
- if (md->bl_x == bl->bl_x && md->bl_y == bl->bl_y) // 同じャX
+ if (md->bl_x == bl->bl_x && md->bl_y == bl->bl_y) // 同じャX | Same guy
return 1;
// Obstacle judging
@@ -1400,6 +1447,10 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist)
return 0;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
int mob_aggravate(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl)
{
if (md->bl_type != BL::MOB)
@@ -1434,7 +1485,7 @@ void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl,
else
return;
- //敵味方判定
+ // 敵味方判定 | Enemy/ally determination
if (battle_check_target(smd, bl, BCT_ENEMY) == 0)
return;
@@ -1443,11 +1494,11 @@ void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl,
else
mode = smd->mode;
- // アクティブでターゲット射程内にいるなら、ロックする
+ // アクティブでターゲット射程内にいるなら、ロックする | Lock if active and within target range
if (bool(mode & MobMode::AGGRESSIVE))
{
Race race = get_mob_db(smd->mob_class).race;
- //対象がPCの場合
+ // 対象がPCの場合 | If the target is a PC
if (tsd &&
!pc_isdead(tsd) &&
tsd->bl_m == smd->bl_m &&
@@ -1461,29 +1512,29 @@ void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl,
|| race == Race::_insect
|| race == Race::_demon))
{
- // 妨害がないか判定
- // 到達可能性判定
+ // 妨害がないか判定 | Determine if there is any interference
+ // 到達可能性判定 | Arrival possibility determination
if (mob_can_reach(smd, bl, 12)
&& random_::chance({1, ++*pcc}))
{
- // 範囲内PCで等確率にする
+ // 範囲内PCで等確率にする | Make the probability equal for PCs within the range
smd->target_id = tsd->bl_id;
smd->state.attackable = true;
smd->min_chase = 13;
}
}
}
- //対象がMobの場合
+ // 対象がMobの場合 | If the target is a mob
else if (tmd &&
tmd->bl_m == smd->bl_m &&
(dist =
distance(smd->bl_x, smd->bl_y, tmd->bl_x, tmd->bl_y)) < 9)
{
- // 到達可能性判定
+ // 到達可能性判定 | Arrival possibility determination
if (mob_can_reach(smd, bl, 12)
&& random_::chance({1, ++*pcc}))
{
- // 範囲内で等確率にする
+ // 範囲内で等確率にする | Make the probability equal within the range
smd->target_id = bl->bl_id;
smd->state.attackable = true;
smd->min_chase = 13;
@@ -1681,7 +1732,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
|| (!sd->state.gangsterparadise
|| race == Race::_insect
|| race == Race::_demon))
- { // 妨害がないか判定
+ { // 妨害がないか判定 | Determine if there is any interference
md->target_id = sd->bl_id;
md->state.attackable = true;
@@ -1875,7 +1926,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
if (md->master_id && md->state.special_mob_ai == 0)
mob_ai_sub_hard_slavemob(md, tick);
- // アクティヴモンスターの策敵 (?? of a bitter taste TIVU monster)
+ // アクティヴモンスターの策敵 | Active monster's enemy (?? of a bitter taste TIVU monster)
if ((!md->target_id || !md->state.attackable)
&& bool(mode & MobMode::AGGRESSIVE) && !md->state.master_check
&& battle_config.monster_active_enable == 1)
@@ -1927,40 +1978,40 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
|| (dist =
distance(md->bl_x, md->bl_y, tbl->bl_x,
tbl->bl_y)) >= md->min_chase)
- mob_unlocktarget(md, tick); // 別マップか、視界外
+ mob_unlocktarget(md, tick); // 別マップか、視界外 | Another map or out of sight?
else if (tsd && !bool(mode & MobMode::BOSS)
&& (tsd->state.gangsterparadise
&& race != Race::_insect
&& race != Race::_demon))
- mob_unlocktarget(md, tick); // スキルなどによる策敵妨害
+ mob_unlocktarget(md, tick); // スキルなどによる策敵妨害 | Interfering with enemy tactics using skills etc.
else if (!battle_check_range(md, tbl, get_mob_db(md->mob_class).range))
{
- // 攻撃範囲外なので移動
+ // 攻撃範囲外なので移動 | Move because you are out of attack range
if (!bool(mode & MobMode::CAN_MOVE))
- { // 移動しないモード
+ { // 移動しないモード | No-move mode
mob_unlocktarget(md, tick);
return;
}
- if (!mob_can_move(md)) // 動けない状態にある
+ if (!mob_can_move(md)) // 動けない状態にある | unable to move
return;
- md->state.skillstate = MobSkillState::MSS_CHASE; // 突撃時スキル
+ md->state.skillstate = MobSkillState::MSS_CHASE; // 突撃時スキル | Assault skills
mobskill_use(md, tick, MobSkillCondition::ANY);
if (md->timer && md->state.state != MS::ATTACK
&& (md->next_walktime < tick
|| distance(md->to_x, md->to_y, tbl->bl_x, tbl->bl_y) < 2))
- return; // 既に移動中
+ return; // 既に移動中 | Already on the move
if (!mob_can_reach(md, tbl, (md->min_chase > 13) ? md->min_chase : 13))
- mob_unlocktarget(md, tick); // 移動できないのでタゲ解除(IWとか?)
+ mob_unlocktarget(md, tick); // 移動できないのでタゲ解除(IWとか?) | I can't move so I can't target it (IW or something?)
else
{
- // 追跡
+ // 追跡 | tracking
md->next_walktime = tick + 500_ms;
i = 0;
do
{
if (i == 0)
{
- // 最初はAEGISと同じ方法で検索
+ // 最初はAEGISと同じ方法で検索 | First search in the same way as AEGIS
dx = tbl->bl_x - md->bl_x;
dy = tbl->bl_y - md->bl_y;
if (dx < 0)
@@ -1974,7 +2025,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
}
else
{
- // だめならAthena式(ランダム)
+ // だめならAthena式(ランダム) | If not, use Athena style (random)
// {0 1 2}
dx = tbl->bl_x - md->bl_x + random_::in(-1, 1);
dy = tbl->bl_y - md->bl_y + random_::in(-1, 1);
@@ -1985,7 +2036,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
while (ret && i < 5);
if (ret)
- { // 移動不可能な所からの攻撃なら2歩下る
+ { // 移動不可能な所からの攻撃なら2歩下る | If attacking from a place where you can't move, take 2 steps back.
if (dx < 0)
dx = 2;
else if (dx > 0)
@@ -2000,57 +2051,57 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
}
}
else
- { // 攻撃射程範囲内
+ { // 攻撃射程範囲内 | Within attack range
md->state.skillstate = MobSkillState::MSS_ATTACK;
if (md->state.state == MS::WALK)
- mob_stop_walking(md, 1); // 歩行中なら停止
+ mob_stop_walking(md, 1); // 歩行中なら停止 | Stop if you are walking
if (md->state.state == MS::ATTACK)
- return; // 既に攻撃中
+ return; // 既に攻撃中 | already under attack
mob_changestate(md, MS::ATTACK, attack_type);
}
return;
}
else
- { // ルートモンスター処理
+ { // ルートモンスター処理 | Root monster processing
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(get_mob_db(md->mob_class).mode & MobMode::LOOTER))
{
- // 遠すぎるかアイテムがなくなった
+ // 遠すぎるかアイテムがなくなった | Too far or missing item
mob_unlocktarget(md, tick);
if (md->state.state == MS::WALK)
- mob_stop_walking(md, 1); // 歩行中なら停止
+ mob_stop_walking(md, 1); // 歩行中なら停止 | Stop if you are walking
}
else if (dist)
{
if (!bool(mode & MobMode::CAN_MOVE))
- { // 移動しないモード
+ { // 移動しないモード | no-move mode
mob_unlocktarget(md, tick);
return;
}
- if (!mob_can_move(md)) // 動けない状態にある
+ if (!mob_can_move(md)) // 動けない状態にある | unable to move
return;
- md->state.skillstate = MobSkillState::MSS_LOOT; // ルート時スキル使用
+ md->state.skillstate = MobSkillState::MSS_LOOT; // ルート時スキル使用 | Skill use during root
mobskill_use(md, tick, MobSkillCondition::ANY);
if (md->timer && md->state.state != MS::ATTACK
&& (md->next_walktime < tick
|| distance(md->to_x, md->to_y, tbl->bl_x, tbl->bl_y) <= 0))
- return; // 既に移動中
+ return; // 既に移動中 | Already on the move
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);
if (ret)
- mob_unlocktarget(md, tick); // 移動できないのでタゲ解除(IWとか?)
+ mob_unlocktarget(md, tick); // 移動できないのでタゲ解除(IWとか?) | I can't move so I can't target it (IW or something?)
}
else
- { // アイテムまでたどり着いた
+ { // アイテムまでたどり着いた | I got to the item
if (md->state.state == MS::ATTACK)
- return; // 攻撃中
+ return; // 攻撃中 | Under attack
if (md->state.state == MS::WALK)
- mob_stop_walking(md, 1); // 歩行中なら停止
+ mob_stop_walking(md, 1); // 歩行中なら停止 | Stop if you are walking
fitem = tbl->is_item();
md->lootitemv.push_back(fitem->item_data);
map_clearflooritem(tbl->bl_id);
@@ -2063,7 +2114,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
{
mob_unlocktarget(md, tick);
if (md->state.state == MS::WALK)
- mob_stop_walking(md, 4); // 歩行中なら停止
+ mob_stop_walking(md, 4); // 歩行中なら停止 | Stop if you are walking
return;
}
}
@@ -2302,6 +2353,10 @@ int mob_delete(dumb_ptr<mob_data> md)
return 0;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type)
{
nullpo_retr(1, md);
@@ -2315,6 +2370,10 @@ int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type)
return 0;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
void mob_timer_delete(TimerData *, tick_t, BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
@@ -2378,7 +2437,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
tick_t tick = gettick();
dumb_ptr<map_session_data> mvp_sd = nullptr, second_sd = nullptr, third_sd = nullptr;
- nullpo_retz(md); //srcはNULLで呼ばれる場合もあるので、他でチェック
+ nullpo_retz(md); // srcはNULLで呼ばれる場合もあるので、他でチェック | src may be called as NULL, so check it elsewhere.
if (src && src->bl_id == md->master_id
&& bool(md->mode & MobMode::TURNS_AGAINST_BAD_MASTER))
@@ -2495,6 +2554,13 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
md->hp -= damage;
+ // activity
+ if (sd)
+ if (sd->activity.attacks == 2147483647)
+ sd->activity.attacks = 1;
+ else
+ sd->activity.attacks++;
+
if (md->hp > 0)
{
return 0;
@@ -2502,7 +2568,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
MAP_LOG("MOB%d DEAD"_fmt, md->bl_id);
- // ----- ここから死亡処理 -----
+ // ----- ここから死亡処理 | Death processing begins here -----
MapBlockLock lock;
// cancels timers
@@ -2514,8 +2580,8 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
if (src && src->bl_type == BL::MOB)
mob_unlocktarget(src->is_mob(), tick);
- // map外に消えた人は計算から除くので
- // overkill分は無いけどsumはmax_hpとは違う
+ // map外に消えた人は計算から除くので | People who disappear outside the map will be excluded from the calculation.
+ // overkill分は無いけどsumはmax_hpとは違う | There is no overkill portion, but sum is different from max_hp
// snip a prelude loop, now merged
@@ -2545,6 +2611,12 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
if (tmpsdi->bl_m != md->bl_m || pc_isdead(tmpsdi))
continue;
+ // activity
+ if (tmpsdi->activity.kills == 2147483647)
+ tmpsdi->activity.kills = 1;
+ else
+ tmpsdi->activity.kills++;
+
// this way is actually fair, unlike the old way
// that refers to the subsequents ... was buggy though
if (tmpdmg > mvp_dmg)
@@ -2704,7 +2776,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
}
} // [MouseJstr]
- // SCRIPT実行
+ // SCRIPT実行 | SCRIPT execution
{
if (sd == nullptr)
{
@@ -2737,6 +2809,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
/*==========================================
* mob回復
+ * mob recovery
*------------------------------------------
*/
int mob_heal(dumb_ptr<mob_data> md, int heal)
@@ -2784,6 +2857,7 @@ int mob_warpslave(dumb_ptr<mob_data> md, int x, int y)
/*==========================================
* mobワープ
+ * mob warp
*------------------------------------------
*/
int mob_warp(dumb_ptr<mob_data> md, Option<Borrowed<map_local>> m_, int x, int y, BeingRemoveWhy type)
@@ -2806,7 +2880,7 @@ int mob_warp(dumb_ptr<mob_data> md, Option<Borrowed<map_local>> m_, int x, int y
map_delblock(md);
if (bx > 0 && by > 0)
- { // 位置指定の場合周囲9セルを探索
+ { // 位置指定の場合周囲9セルを探索 | When specifying a location, search the surrounding 9 cells
xs = ys = 9;
}
@@ -2817,13 +2891,13 @@ int mob_warp(dumb_ptr<mob_data> md, Option<Borrowed<map_local>> m_, int x, int y
{
if (xs > 0 && ys > 0 && i < 250)
{
- // 指定位置付近の探索
+ // 指定位置付近の探索 | Search near specified location
x = bx + random_::to(xs) - xs / 2;
y = by + random_::to(ys) - ys / 2;
}
else
{
- // 完全ランダム探索
+ // 完全ランダム探索 | Completely random search
x = random_::in(1, m->xs - 2);
y = random_::in(1, m->ys - 2);
}
@@ -2841,7 +2915,7 @@ int mob_warp(dumb_ptr<mob_data> md, Option<Borrowed<map_local>> m_, int x, int y
PRINTF("MOB %d warp failed, mob_class = %d\n"_fmt, md->bl_id, md->mob_class);
}
- md->target_id = BlockId(); // タゲを解除する
+ md->target_id = BlockId(); // タゲを解除する | remove target
md->state.attackable = false;
md->attacked_id = BlockId();
md->state.skillstate = MobSkillState::MSS_IDLE;
@@ -2867,6 +2941,7 @@ int mob_warp(dumb_ptr<mob_data> md, Option<Borrowed<map_local>> m_, int x, int y
/*==========================================
* 画面内の取り巻きの数計算用(foreachinarea)
+ * For calculating the number of entourage in the screen (foreachinarea)
*------------------------------------------
*/
static
@@ -2883,6 +2958,7 @@ void mob_countslave_sub(dumb_ptr<block_list> bl, BlockId id, int *c)
/*==========================================
* 画面内の取り巻きの数計算
+ * Calculating the number of entourage in the screen
*------------------------------------------
*/
static
@@ -2902,6 +2978,7 @@ int mob_countslave(dumb_ptr<mob_data> md)
/*==========================================
* 手下MOB召喚
+ * MOB summoning
*------------------------------------------
*/
int mob_summonslave(dumb_ptr<mob_data> md2, int *value_, int amount, int flag)
@@ -2965,8 +3042,8 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value_, int amount, int flag)
md->spawn.xs = 0;
md->spawn.ys = 0;
md->stats[mob_stat::SPEED] = md2->stats[mob_stat::SPEED];
- md->spawn.delay1 = static_cast<interval_t>(-1); // 一度のみフラグ
- md->spawn.delay2 = static_cast<interval_t>(-1); // 一度のみフラグ
+ md->spawn.delay1 = static_cast<interval_t>(-1); // 一度のみフラグ | once flag
+ md->spawn.delay2 = static_cast<interval_t>(-1); // 一度のみフラグ | once flag
md->npc_event = NpcEvent();
md->bl_type = BL::MOB;
@@ -2982,6 +3059,7 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value_, int amount, int flag)
/*==========================================
* 自分をロックしているPCの数を数える(foreachclient)
+ * Count the number of PCs that have locked you (foreachclient)
*------------------------------------------
*/
static
@@ -3011,6 +3089,7 @@ void mob_counttargeted_sub(dumb_ptr<block_list> bl,
/*==========================================
* 自分をロックしているPCの数を数える
+ * Count the number of PCs that have locked you
*------------------------------------------
*/
int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src,
@@ -3029,11 +3108,12 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src,
}
//
-// MOBスキル
+// MOBスキル | MOB skills
//
/*==========================================
* スキル使用(詠唱完了、ID指定)
+ * Skill use (casting completed, ID designation)
*------------------------------------------
*/
void mobskill_castend_id(TimerData *, tick_t tick, BlockId id)
@@ -3043,7 +3123,7 @@ void mobskill_castend_id(TimerData *, tick_t tick, BlockId id)
dumb_ptr<block_list> mbl;
int range;
- if ((mbl = map_id2bl(id)) == nullptr) //詠唱したMobがもういないというのは良くある正常処理
+ if ((mbl = map_id2bl(id)) == nullptr) // 詠唱したMobがもういないというのは良くある正常処理 | It's common and normal that the mob that cast is no longer there.
return;
if ((md = mbl->is_mob()) == nullptr)
{
@@ -3060,13 +3140,13 @@ void mobskill_castend_id(TimerData *, tick_t tick, BlockId id)
md->last_thinktime = tick + battle_get_adelay(md);
if ((bl = map_id2bl(md->skilltarget)) == nullptr || bl->bl_prev == nullptr)
- { //スキルターゲットが存在しない
+ { // スキルターゲットが存在しない | Skill target does not exist
return;
}
if (md->bl_m != bl->bl_m)
return;
- if (((skill_get_inf(md->skillid) & 1) || (skill_get_inf2(md->skillid) & 4)) && // 彼我敵対関係チェック
+ if (((skill_get_inf(md->skillid) & 1) || (skill_get_inf2(md->skillid) & 4)) && // 彼我敵対関係チェック | Self-enemy relationship check
battle_check_target(md, bl, BCT_ENEMY) <= 0)
return;
range = skill_get_range(md->skillid, md->skilllv);
@@ -3084,14 +3164,14 @@ void mobskill_castend_id(TimerData *, tick_t tick, BlockId id)
switch (skill_get_nk(md->skillid))
{
- // 攻撃系/吹き飛ばし系
+ // 攻撃系/吹き飛ばし系 | Attack type/Blow type
case 0:
case 2:
skill_castend_damage_id(md, bl,
md->skillid, md->skilllv,
tick, BCT_ZERO);
break;
- case 1: // 支援系
+ case 1: // 支援系 | Support system
skill_castend_nodamage_id(md, bl,
md->skillid, md->skilllv);
break;
@@ -3100,6 +3180,7 @@ void mobskill_castend_id(TimerData *, tick_t tick, BlockId id)
/*==========================================
* スキル使用(詠唱完了、場所指定)
+ * Skill use (casting completed, location specified)
*------------------------------------------
*/
void mobskill_castend_pos(TimerData *, tick_t tick, BlockId id)
@@ -3108,7 +3189,8 @@ void mobskill_castend_pos(TimerData *, tick_t tick, BlockId id)
dumb_ptr<block_list> bl;
int range;
- //mobskill_castend_id同様詠唱したMobが詠唱完了時にもういないというのはありそうなのでnullpoから除外
+ // mobskill_castend_id同様詠唱したMobが詠唱完了時にもういないというのはありそうなのでnullpoから除外
+ // mobskill_castend_id It is likely that the mob that cast the same as the one is no longer there when the cast is completed, so it is excluded from nullpo.
if ((bl = map_id2bl(id)) == nullptr)
return;
@@ -3164,7 +3246,7 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target,
if (skill_get_inf2(skill_id) & 0x200 && md->bl_id == target->bl_id)
return 0;
- // 射程と障害物チェック
+ // 射程と障害物チェック | Range and obstacle check
range = skill_get_range(skill_id, skill_lv);
if (range < 0)
range = battle_get_range(md) - (range + 1);
@@ -3183,7 +3265,7 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target,
target->bl_id, skill_id, skill_lv,
static_cast<uint32_t>(casttime.count()), md->mob_class);
- if (casttime <= interval_t::zero()) // 詠唱の無いものはキャンセルされない
+ if (casttime <= interval_t::zero()) // 詠唱の無いものはキャンセルされない | Anything without a chant will not be canceled
md->state.skillcastcancel = 0;
md->skilltarget = target->bl_id;
@@ -3210,6 +3292,7 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target,
/*==========================================
* スキル使用(場所指定)
+ * Skill usage (Location)
*------------------------------------------
*/
static
@@ -3233,7 +3316,7 @@ int mobskill_use_pos(dumb_ptr<mob_data> md,
if (bool(md->opt1))
return 0;
- // 射程と障害物チェック
+ // 射程と障害物チェック | Range and obstacle check
bl.bl_type = BL::NUL;
bl.bl_m = md->bl_m;
bl.bl_x = skill_x;
@@ -3304,11 +3387,11 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick,
tick_t& sdii = md->skilldelayup[&msii - &ms.front()];
int flag = 0;
- // ディレイ中
+ // ディレイ中 | During delay
if (tick < sdii + msii.delay)
continue;
- // 状態判定
+ // 状態判定 | Status determination
if (msii.state != MobSkillState::ANY && msii.state != md->state.skillstate)
continue;
@@ -3336,13 +3419,13 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick,
}
}
- // 確率判定
+ // 確率判定 | Probability judgment
if (flag && random_::chance({msii.permillage, 10000}))
{
if (skill_get_inf(msii.skill_id) & 2)
{
- // 場所指定
+ // 場所指定 | Specify location
dumb_ptr<block_list> bl = nullptr;
int x = 0, y = 0;
{
@@ -3404,7 +3487,7 @@ int mobskill_event(dumb_ptr<mob_data> md, BF flag)
}
//
-// 初期化
+// 初期化 | Initialization
//
/*==========================================
* Since un-setting [ mob ] up was used, it is an initial provisional value setup.
@@ -3451,6 +3534,10 @@ int mob_makedummymobdb(Species mob_class)
return 0;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
bool impl_extract(XString str, LevelElement *le)
{
@@ -3463,6 +3550,10 @@ bool impl_extract(XString str, LevelElement *le)
return false;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
bool mob_readdb(ZString filename)
{
bool rv = true;
@@ -3614,6 +3705,10 @@ bool mob_readdb(ZString filename)
return rv;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
bool impl_extract(XString str, MobSkillCondition *msc)
{
@@ -3638,6 +3733,10 @@ bool impl_extract(XString str, MobSkillCondition *msc)
return false;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
bool impl_extract(XString str, MobSkillState *mss)
{
@@ -3661,6 +3760,10 @@ bool impl_extract(XString str, MobSkillState *mss)
return false;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
bool impl_extract(XString str, MobSkillTarget *mst)
{
@@ -3682,6 +3785,10 @@ bool impl_extract(XString str, MobSkillTarget *mst)
return false;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
bool mob_readskilldb(ZString filename)
{
bool rv = true;
@@ -3764,6 +3871,10 @@ bool mob_readskilldb(ZString filename)
return rv;
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
void do_init_mob2(void)
{
Timer(gettick() + MIN_MOBTHINKTIME,
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index ea15910..c7c6acf 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -805,13 +805,13 @@ void pc_set_attack_info(dumb_ptr<map_session_data> sd, interval_t speed, int ran
if (speed == interval_t::zero())
{
- pc_calcstatus(sd, 1);
+ pc_calcstatus(sd, (int)CalcStatusKind::INITIAL_CALC);
clif_updatestatus(sd, SP::ASPD);
clif_updatestatus(sd, SP::ATTACKRANGE);
}
else
{
- pc_calcstatus(sd, 9);
+ pc_calcstatus(sd, ((int)CalcStatusKind::INITIAL_CALC + (int)CalcStatusKind::MAGIC_OVERRIDE));
clif_updatestatus(sd, SP::ASPD);
clif_updatestatus(sd, SP::ATTACKRANGE);
}
@@ -948,7 +948,7 @@ int pc_authok(AccountId id, int login_id2, ClientVersion client_version,
sd->die_counter = pc_readglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"_s));
// ステータス初期計算など | Status initial calculation, etc.
- pc_calcstatus(sd, 1);
+ pc_calcstatus(sd, (int)CalcStatusKind::INITIAL_CALC);
if (pc_isGM(sd))
{
@@ -981,7 +981,7 @@ int pc_authok(AccountId id, int login_id2, ClientVersion client_version,
sd->packet_flood_reset_due = tick_t();
sd->packet_flood_in = 0;
- pc_calcstatus(sd, 1);
+ pc_calcstatus(sd, (int)CalcStatusKind::INITIAL_CALC);
if(sd->bl_m->mask > 0)
clif_send_mask(sd, sd->bl_m->mask);
@@ -1157,7 +1157,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->max_weight = max_weight_base_0 + sd->status.attrs[ATTR::STR] * 300;
- if (first & 1)
+ if (first & (int)CalcStatusKind::INITIAL_CALC)
{
sd->weight = 0;
for (IOff0 i : IOff0::iter())
@@ -1563,7 +1563,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->aspd = sd->aspd * aspd_rate / 100;
/* Magic speed */
- if (sd->attack_spell_override || first & 8)
+ if (sd->attack_spell_override || first & (int)CalcStatusKind::MAGIC_OVERRIDE)
sd->aspd = sd->attack_spell_delay;
/* Red Threshold Calculation (TODO) */
@@ -1581,14 +1581,14 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->status.sp > sd->status.max_sp)
sd->status.sp = sd->status.max_sp;
- if (first & 4)
+ if (first & (int)CalcStatusKind::NORMAL_RECALC_NO_CLIENT_UPDATE)
return 0;
- if (first & 3) // never executed atm
+ if (first & ((int)CalcStatusKind::INITIAL_CALC + (int)CalcStatusKind::ITEM_BONUS_RECALC)) // never executed atm
{
clif_updatestatus(sd, SP::SPEED);
clif_updatestatus(sd, SP::MAXHP);
clif_updatestatus(sd, SP::MAXSP);
- if (first & 1) // its always 1 here if first is 3 so this if is not needed normally
+ if (first & (int)CalcStatusKind::INITIAL_CALC) // its always 1 here if first is 3 so this if is not needed normally
{
clif_updatestatus(sd, SP::HP);
clif_updatestatus(sd, SP::SP);
@@ -1955,7 +1955,7 @@ int pc_skill(dumb_ptr<map_session_data> sd, SkillID id, int level, int flag)
if (!flag && (sd->status.skill[id].lv || level == 0))
{
sd->status.skill[id].lv = level;
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_skillinfoblock(sd);
}
else if (sd->status.skill[id].lv < level)
@@ -2407,6 +2407,13 @@ int pc_useitem(dumb_ptr<map_session_data> sd, IOff0 n)
clif_useitemack(sd, n, amount - 1, 1);
pc_delitem(sd, n, 1, 1);
+ // activity
+ if (sd)
+ if (sd->activity.items_used == 2147483647)
+ sd->activity.items_used = 1;
+ else
+ sd->activity.items_used++;
+
run_script(ScriptPointer(script, 0), sd->bl_id, BlockId());
}
OMATCH_END ();
@@ -2730,6 +2737,13 @@ int pc_walktoxy_sub(dumb_ptr<map_session_data> sd)
}
clif_movechar(sd);
+ // activity
+ if (sd)
+ if (sd->activity.tiles_walked == 2147483647)
+ sd->activity.tiles_walked = 1;
+ else
+ sd->activity.tiles_walked++;
+
return 0;
}
@@ -2907,7 +2921,7 @@ void pc_attack_timer(TimerData *, tick_t tick, BlockId id)
sd->attack_spell_override = BlockId();
pc_set_weapon_icon(sd, 0, StatusChange::ZERO, ItemNameId());
pc_set_attack_info(sd, interval_t::zero(), 0);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
}
else
@@ -3043,7 +3057,7 @@ int pc_checkbaselevelup(dumb_ptr<map_session_data> sd)
clif_updatestatus(sd, SP::STATUSPOINT);
clif_updatestatus(sd, SP::BASELEVEL);
clif_updatestatus(sd, SP::NEXTBASEEXP);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
pc_heal(sd, sd->status.max_hp, sd->status.max_sp, true);
clif_misceffect(sd, 0);
@@ -3102,7 +3116,7 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd)
{ // [Fate] Bah, this is is painful.
// But the alternative is quite error-prone, and eAthena has far worse performance issues...
sd->status.job_exp = next - 1;
- pc_calcstatus(sd,0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
return 0;
}
@@ -3111,7 +3125,7 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd)
clif_updatestatus(sd, SP::NEXTJOBEXP);
sd->status.skill_point++;
clif_updatestatus(sd, SP::SKILLPOINT);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
MAP_LOG_PC(sd, "SKILLPOINTS-UP %d"_fmt, sd->status.skill_point);
@@ -3348,7 +3362,7 @@ int pc_statusup(dumb_ptr<map_session_data> sd, SP type)
}
clif_updatestatus(sd, SP::STATUSPOINT);
clif_updatestatus(sd, type);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_statusupack(sd, type, 1, val);
MAP_LOG_STATS(sd, "STATUP"_fmt);
@@ -3377,7 +3391,7 @@ int pc_statusup2(dumb_ptr<map_session_data> sd, SP type, int val)
sd->status.attrs[attr] = val;
clif_updatestatus(sd, sp_to_usp(type));
clif_updatestatus(sd, type);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_statusupack(sd, type, 1, val);
MAP_LOG_STATS(sd, "STATUP2"_fmt);
@@ -3400,7 +3414,7 @@ int pc_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num)
sd->status.skill_point -= sd->status.skill[skill_num].lv;
sd->status.skill[skill_num].lv++;
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
clif_skillup(sd, skill_num);
clif_updatestatus(sd, SP::SKILLPOINT);
clif_skillinfoblock(sd);
@@ -3432,7 +3446,7 @@ int pc_resetstate(dumb_ptr<map_session_data> sd)
for (ATTR attr : ATTRs)
clif_updatestatus(sd, attr_to_usp(attr));
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
return 0;
}
@@ -3458,7 +3472,7 @@ int pc_resetskill(dumb_ptr<map_session_data> sd)
clif_updatestatus(sd, SP::SKILLPOINT);
clif_skillinfoblock(sd);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
return 0;
}
@@ -3551,7 +3565,7 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
pc_set_weapon_icon(sd, 0, StatusChange::ZERO, ItemNameId());
pc_set_attack_info(sd, interval_t::zero(), 0);
}
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
if (battle_config.death_penalty_type > 0 && sd->status.base_level >= 20)
{
@@ -3851,6 +3865,21 @@ int pc_readparam(dumb_ptr<block_list> bl, SP type)
case SP::MUTE_GUILD:
val = sd ? sd->mute.guild : 0;
break;
+ case SP::KILLS:
+ val = sd->activity.kills;
+ break;
+ case SP::CASTS:
+ val = sd->activity.casts;
+ break;
+ case SP::ITEMS_USED:
+ val = sd->activity.items_used;
+ break;
+ case SP::TILES_WALKED:
+ val = sd->activity.tiles_walked;
+ break;
+ case SP::ATTACKS:
+ val = sd->activity.attacks;
+ break;
case SP::AUTOMOD:
val = sd ? static_cast<int>(sd->automod) : 0;
break;
@@ -3901,7 +3930,7 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val)
clif_updatestatus(sd, SP::NEXTBASEEXP);
clif_updatestatus(sd, SP::STATUSPOINT);
clif_updatestatus(sd, SP::BASEEXP);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
pc_heal(sd, sd->status.max_hp, sd->status.max_sp, true);
break;
case SP::JOBLEVEL:
@@ -3919,7 +3948,7 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val)
clif_updatestatus(sd, SP::JOBLEVEL);
clif_updatestatus(sd, SP::NEXTJOBEXP);
clif_updatestatus(sd, SP::JOBEXP);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
break;
case SP::CLASS:
// TODO: mob class change
@@ -3999,7 +4028,7 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val)
&& !pc_isequip(sd, j))
pc_unequipitem(sd, j, CalcStatus::LATER);
}
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
chrif_save(sd);
clif_fixpcpos(sd);
}
@@ -4100,6 +4129,22 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val)
nullpo_retz(sd);
sd->mute.guild = (val == 1);
break;
+ // atm only setting of casts is needed since magic is handled in serverdata but I let the others here as well for whatever reason
+ case SP::KILLS:
+ sd->activity.kills = val;
+ break;
+ case SP::CASTS:
+ sd->activity.casts = val;
+ break;
+ case SP::ITEMS_USED:
+ sd->activity.items_used = val;
+ break;
+ case SP::TILES_WALKED:
+ sd->activity.tiles_walked = val;
+ break;
+ case SP::ATTACKS:
+ sd->activity.attacks = val;
+ break;
case SP::AUTOMOD:
nullpo_retz(sd);
sd->automod = static_cast<AutoMod>(val);
@@ -4479,7 +4524,7 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
if (reg == stringish<VarName>("PC_DIE_COUNTER"_s) && sd->die_counter != val)
{
sd->die_counter = val;
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
Option<P<struct quest_data>> quest_data_ = questdb_searchname(var);
OMATCH_BEGIN_SOME(quest_data, quest_data_)
@@ -4910,7 +4955,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS)
}
pc_signal_advanced_equipment_change(sd, n);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
return 0;
}
@@ -4977,7 +5022,7 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type)
}
if (type == CalcStatus::NOW)
{
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
return 0;
@@ -5050,7 +5095,7 @@ int pc_checkitem(dumb_ptr<map_session_data> sd)
pc_setequipindex(sd);
if (calc_flag)
- pc_calcstatus(sd, 2);
+ pc_calcstatus(sd, (int)CalcStatusKind::ITEM_BONUS_RECALC);
return 0;
}
@@ -5435,7 +5480,7 @@ void pc_natural_heal_sub(dumb_ptr<map_session_data> sd)
if (sd->spellpower_bonus_target < sd->spellpower_bonus_current)
{
sd->spellpower_bonus_current = sd->spellpower_bonus_target;
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
else if (sd->spellpower_bonus_target > sd->spellpower_bonus_current)
{
@@ -5443,7 +5488,7 @@ void pc_natural_heal_sub(dumb_ptr<map_session_data> sd)
1 +
((sd->spellpower_bonus_target -
sd->spellpower_bonus_current) >> 5);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
if (sd->sc_data[StatusChange::SC_HALT_REGENERATE].timer)
diff --git a/src/map/pc.t.hpp b/src/map/pc.t.hpp
index c9235fa..870b25a 100644
--- a/src/map/pc.t.hpp
+++ b/src/map/pc.t.hpp
@@ -56,5 +56,15 @@ enum class CalcStatus
NOW,
LATER,
};
+
+enum class CalcStatusKind
+{
+ NORMAL_RECALC = 0,
+ INITIAL_CALC = 1,
+ ITEM_BONUS_RECALC = 2,
+ NORMAL_RECALC_NO_CLIENT_UPDATE = 4,
+ MAGIC_OVERRIDE = 8,
+};
+
} // namespace map
} // namespace tmwa
diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp
index fd3f798..8dc1989 100644
--- a/src/map/script-fun.cpp
+++ b/src/map/script-fun.cpp
@@ -117,6 +117,10 @@ void builtin_mes(ScriptState *st)
clif_scriptmes(sd, st->oid, mes);
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
void builtin_mesq(ScriptState *st)
{
@@ -131,6 +135,10 @@ void builtin_mesq(ScriptState *st)
clif_scriptmes(sd, st->oid, RString(mesq));
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
void builtin_mesn(ScriptState *st)
{
@@ -148,6 +156,10 @@ void builtin_mesn(ScriptState *st)
clif_scriptmes(sd, st->oid, RString(mesq));
}
+/*==========================================
+ *
+ *------------------------------------------
+ */
static
void builtin_clear(ScriptState *st)
{
@@ -2440,7 +2452,7 @@ void builtin_overrideattack(ScriptState *st)
sd->attack_spell_override = BlockId();
pc_set_weapon_icon(sd, 0, StatusChange::ZERO, ItemNameId());
pc_set_attack_info(sd, interval_t::zero(), 0);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
}
@@ -2508,7 +2520,7 @@ void builtin_setopt2(ScriptState *st)
return;
sd->opt2 = new_opt2;
clif_changeoption(sd);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
@@ -4827,7 +4839,7 @@ void builtin_nude(ScriptState *st)
if (idx.ok())
pc_unequipitem(sd, idx, CalcStatus::LATER);
}
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
@@ -4850,7 +4862,7 @@ void builtin_unequipbyid(ScriptState *st)
pc_unequipitem(sd, idx, CalcStatus::LATER);
}
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
}
@@ -5563,7 +5575,6 @@ void builtin_mapexit(ScriptState *)
runflag = 0;
}
-
#define BUILTIN(func, args, ret) \
{builtin_##func, #func ## _s, args, ret}
diff --git a/src/map/skill-pools.cpp b/src/map/skill-pools.cpp
index dfc70b0..ddec824 100644
--- a/src/map/skill-pools.cpp
+++ b/src/map/skill-pools.cpp
@@ -77,7 +77,7 @@ int skill_pool_activate(dumb_ptr<map_session_data> sd, SkillID skill_id)
&& (skill_pool_size(sd) < skill_pool_max(sd)))
{
sd->status.skill[skill_id].flags |= SkillFlags::POOL_ACTIVATED;
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
MAP_LOG_PC(sd, "SKILL-ACTIVATE %d %d %d"_fmt,
skill_id, sd->status.skill[skill_id].lv,
skill_power(sd, skill_id));
@@ -98,7 +98,7 @@ int skill_pool_deactivate(dumb_ptr<map_session_data> sd, SkillID skill_id)
{
sd->status.skill[skill_id].flags &= ~SkillFlags::POOL_ACTIVATED;
MAP_LOG_PC(sd, "SKILL-DEACTIVATE %d"_fmt, skill_id);
- pc_calcstatus(sd, 0);
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC);
return 0;
}
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index 0fcf505..87bbbda 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -805,7 +805,7 @@ void skill_status_change_end(dumb_ptr<block_list> bl, StatusChange type, TimerDa
clif_changeoption(bl);
if (bl->bl_type == BL::PC && calc_flag)
- pc_calcstatus(bl->is_player(), 0); /* ステータス再計算 | Status Recalculation */
+ pc_calcstatus(bl->is_player(), (int)CalcStatusKind::NORMAL_RECALC); /* ステータス再計算 | Status Recalculation */
}
int skill_update_heal_animation(dumb_ptr<map_session_data> sd)
@@ -1085,7 +1085,7 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
bl->bl_id, type));
if (bl->bl_type == BL::PC && calc_flag)
- pc_calcstatus(sd, 0); /* ステータス再計算 | Status recalculation */
+ pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC); /* ステータス再計算 | Status recalculation */
if (bl->bl_type == BL::PC && updateflag != SP::ZERO)
clif_updatestatus(sd, updateflag); /* ステータスをクライアントに送る | Send status to client */
diff --git a/src/mmo/clif.t.hpp b/src/mmo/clif.t.hpp
index 1d61070..f8350a7 100644
--- a/src/mmo/clif.t.hpp
+++ b/src/mmo/clif.t.hpp
@@ -333,6 +333,12 @@ enum class SP : uint16_t
DEAF = 70,
+ KILLS = 490,
+ CASTS = 491,
+ ITEMS_USED = 492,
+ TILES_WALKED = 493,
+ ATTACKS = 494,
+
// sent to client
GM = 500,