summaryrefslogtreecommitdiff
path: root/src/map/pc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/pc.cpp')
-rw-r--r--src/map/pc.cpp299
1 files changed, 205 insertions, 94 deletions
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 9e76ecf..12af48f 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -127,71 +127,90 @@ int sp_coefficient_0 = 100;
static //const
earray<interval_t, ItemLook, ItemLook::COUNT> aspd_base_0 //=
{{
-650_ms, // 0 NONE
-700_ms, // 1 BLADE or some other common weapons
-750_ms, // 2
-610_ms, // 3 SETZER_AND_SCYTHE
-2000_ms, // 4
-2000_ms, // 5
-800_ms, // 6 Falchion
-2000_ms, // 7
-700_ms, // 8
-700_ms, // 9
-650_ms, //10 STAFF / Sandcutter
-900_ms, //11 BOW
-2000_ms, //12
-2000_ms, //13
-2000_ms, //14
-2000_ms, //15
-2000_ms, //16
+ 550_ms, // 0 { "Fist", W_FIST },
+ 600_ms, // 1 { "Dagger", W_DAGGER },
+ 650_ms, // 2 { "Sword", W_1HSWORD },
+ 700_ms, // 3 { "TwoHandSword", W_2HSWORD },
+ 650_ms, // 4 { "Spear", W_1HSPEAR },
+ 700_ms, // 5 { "TwoHandSpear", W_2HSPEAR },
+ 700_ms, // 6 { "Axe", W_1HAXE },
+ 750_ms, // 7 { "TwoHandAxe", W_2HAXE },
+ 700_ms, // 8 { "Mace", W_MACE },
+ 750_ms, // 9 { "TwoHandMace", W_2HMACE },
+ 700_ms, // 10 { "Rod", W_STAFF },
+ 800_ms, // 11 { "Bow", W_BOW },
+ 575_ms, // 12 { "Knuckle", W_KNUCKLE },
+ 800_ms, // 13 { "Instrument", W_MUSICAL },
+ 675_ms, // 14 { "Whip", W_WHIP },
+ 700_ms, // 15 { "Book", W_BOOK },
+ 600_ms, // 16 { "Katar", W_KATAR },
+ 600_ms, // 17 { "Revolver", W_REVOLVER },
+ 800_ms, // 18 { "Rifle", W_RIFLE },
+ 500_ms, // 19 { "GatlingGun", W_GATLING },
+ 1000_ms, // 20 { "Shotgun", W_SHOTGUN },
+ 2000_ms, // 21 { "GrenadeLauncher", W_GRENADE },
+ 650_ms, // 22 { "FuumaShuriken", W_HUUMA },
+ 750_ms, // 23 { "TwoHandRod", W_2HSTAFF },
}};
static const
int exp_table_0[MAX_LEVEL] =
{
- // 1 .. 9
+ // 1 .. 10
9, 16, 25, 36,
77, 112, 153, 200, 253,
- // 10 .. 19
+ // 11 .. 20
320, 385, 490, 585, 700,
830, 970, 1120, 1260, 1420,
- // 20 .. 29
+ // 21 .. 30
1620, 1860, 1990, 2240, 2504,
2950, 3426, 3934, 4474, 6889,
- // 30 .. 39
+ // 31 .. 40
7995, 9174, 10425, 11748, 13967,
15775, 17678, 19677, 21773, 30543,
- // 40 .. 49
+ // 41 .. 50
34212, 38065, 42102, 46323, 53026,
58419, 64041, 69892, 75973, 102468,
- // 50 .. 59
+ // 51 .. 60
115254, 128692, 142784, 157528, 178184,
196300, 215198, 234879, 255341, 330188,
- // 60 .. 69
+ // 61 .. 70
365914, 403224, 442116, 482590, 536948,
585191, 635278, 687211, 740988, 925400,
- // 70 .. 79
+ // 71 .. 80
1473746, 1594058, 1718928, 1848355, 1982340,
2230113, 2386162, 2547417, 2713878, 3206160,
- // 80 .. 89
+ // 81 .. 90
3681024, 4022472, 4377024, 4744680, 5125440,
5767272, 6204000, 6655464, 7121664, 7602600,
- // 90 .. 99
+ // 91 .. 100
9738720, 11649960, 13643520, 18339300, 23836800,
35658000, 48687000, 58135000, 99999999, 103000000,
- // 100 .. 109
+ // 101 .. 110
107000000, 112000000, 116000000, 121000000, 125000000,
130000000, 134000000, 139000000, 145000000, 152200000,
- // 110 .. 119
+ // 111 .. 120
160840000, 171200000, 191930000, 202290000, 214720000,
229640000, 247550000, 283370000, 301280000, 322770000,
- // 120 .. 129
+ // 121 .. 130
348560000, 379500000, 417450000, 459195000, 505114500,
555625950, 622301064, 696977191, 780614454, 880533104,
- // 130 .. 135
- 993241342, 1120376234, 1263784392, 1425548794, 1608019039,
- 2147483647, 0
+ // 131 .. 140
+ 993241342, 1120376234, 1263784392, 1425548794, 1588019039,
+ 1680000000, 1780000000, 1890000000, 2010000000, 2140000000,
+ // 141
+ 0
};
+// The old table contained a bug, actually max level was 136 and not 135 but to reach level 136 you must hit exactly the value 2147483647
+// else and overflow occurs and you lose all the progress of that level and start with level 135 at 0% again.
+// I made a buffer that is great enough now I guess its 7483647 while looking through all gm logs I saw the highest values ever where 300%.
+// A Xakelbael killed on 300% exp one time tabbed gives around 6 mil so I have a little buffer on top of that as well, it won't make it for
+// 400% exp but since this will most likely never happen and the chance that one will make his lvl up with Xakelbael one time tabbed
+// is extremely rare as well.
+ // 130 .. 135
+ //993241342, 1120376234, 1263784392, 1425548794, 1608019039,
+ //2147483647, 0
+
// is this *actually* used anywhere?
static const
@@ -694,7 +713,7 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd)
}
OMATCH_CASE_NONE ()
{
- sd->weapontype1 = ItemLook::NONE;
+ sd->weapontype1 = ItemLook::W_FIST;
}
}
OMATCH_END ();
@@ -786,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);
}
@@ -831,7 +850,7 @@ int pc_authok(AccountId id, int login_id2, ClientVersion client_version,
sd->state.connect_new = 1;
sd->bl_prev = sd->bl_next = nullptr;
- sd->weapontype1 = ItemLook::NONE;
+ sd->weapontype1 = ItemLook::W_FIST;
sd->speed = DEFAULT_WALK_SPEED;
sd->state.dead_sit = 0;
sd->dir = DIR::S;
@@ -929,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))
{
@@ -962,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);
@@ -1087,10 +1106,11 @@ void pc_set_weapon_look(dumb_ptr<map_session_data> sd)
* Actively changed parameters should be send on their own
*
* First is a bitmask
- * &1 = ?
- * &2 = ?
- * &4 = ?
- * &8 = magic override
+ * &0 = Status Recalculation | ステータス再計算
+ * &1 = Status initial calculation, etc.| ステータス初期計算など
+ * &2 = Recalculate item bonus (used in pc_checkitem but not handled in this function atm, so if function is called with first = 2 its basically first = 0 only)
+ * &4 = Status Recalculation but don't use any clif_updatestatus to send status to client (used by map_quit)
+ * &8 = magic override (used in pc_set_attack_info)
*------------------------------------------
*/
int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
@@ -1115,11 +1135,11 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
b_weight = sd->weight;
b_max_weight = sd->max_weight;
earray<int, ATTR, ATTR::COUNT> b_paramb = sd->paramb;
- earray<int, ATTR, ATTR::COUNT> b_parame = sd->paramc;
+ earray<int, ATTR, ATTR::COUNT> b_parame = sd->parame;
earray<SkillValue, SkillID, MAX_SKILL> b_skill = sd->status.skill;
b_hit = sd->hit;
b_flee = sd->flee;
- interval_t b_aspd = sd->aspd;
+ interval_t b_aspd = sd->aspd, b_base_weapon_delay_adjust = interval_t::zero();
b_watk = sd->watk;
b_def = sd->def;
b_watk2 = sd->watk2;
@@ -1137,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())
@@ -1161,7 +1181,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->flee = 0;
sd->flee2 = 0;
sd->critical = 0;
- sd->aspd = interval_t::zero();
+ sd->aspd = sd->base_weapon_delay_adjust = interval_t::zero();
sd->watk = 0;
sd->def = 0;
sd->mdef = 0;
@@ -1174,6 +1194,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->matk1 = 0;
sd->matk2 = 0;
sd->speed = DEFAULT_WALK_SPEED;
+ sd->speed_cap = interval_t::zero();
sd->hprate = 100;
sd->sprate = 100;
sd->dsprate = 100;
@@ -1192,11 +1213,11 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->double_rate = 0;
sd->atk_rate = sd->matk_rate = 100;
sd->arrow_cri = 0;
- sd->perfect_hit = 0;
+ sd->perfect_hit = sd->deadly_strike = 0;
sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
sd->speed_add_rate = sd->aspd_add_rate = 100;
- sd->double_add_rate = sd->perfect_hit_add = 0;
+ sd->double_add_rate = sd->perfect_hit_add_rate = sd->deadly_strike_add_rate = 0;
sd->hp_drain_rate = sd->hp_drain_per = sd->sp_drain_rate =
sd->sp_drain_per = 0;
@@ -1324,10 +1345,11 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->attackrange < 1)
sd->attackrange = 1;
- if (sd->status.weapon == ItemLook::BOW)
+ if (sd->status.weapon == ItemLook::W_BOW)
sd->attackrange += sd->arrow_range;
sd->double_rate += sd->double_add_rate;
- sd->perfect_hit += sd->perfect_hit_add;
+ sd->perfect_hit += sd->perfect_hit_add_rate;
+ sd->deadly_strike += sd->deadly_strike_add_rate;
if (sd->speed_add_rate != 100)
sd->speed_rate += sd->speed_add_rate - 100;
if (sd->aspd_add_rate != 100)
@@ -1341,7 +1363,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
for (ATTR attr : ATTRs)
sd->paramc[attr] = std::max(0, sd->status.attrs[attr] + sd->paramb[attr] + sd->parame[attr]);
- if (sd->status.weapon == ItemLook::BOW)
+ if (sd->status.weapon == ItemLook::W_BOW)
{
str = sd->paramc[ATTR::DEX];
dex = sd->paramc[ATTR::STR];
@@ -1356,6 +1378,13 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->base_atk += str + dstr * dstr + dex / 5 + sd->paramc[ATTR::LUK] / 5;
sd->matk1 += sd->paramc[ATTR::INT] + (sd->paramc[ATTR::INT] / 5) * (sd->paramc[ATTR::INT] / 5);
sd->matk2 += sd->paramc[ATTR::INT] + (sd->paramc[ATTR::INT] / 7) * (sd->paramc[ATTR::INT] / 7);
+
+ if (sd->sc_data[StatusChange::SC_MATKPOT].timer)
+ {
+ sd->matk1 += sd->sc_data[StatusChange::SC_MATKPOT].val1;
+ sd->matk2 += sd->sc_data[StatusChange::SC_MATKPOT].val1;
+ }
+
if (sd->matk1 < sd->matk2)
{
int temp = sd->matk2;
@@ -1435,9 +1464,12 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
//二刀流 ASPD 修正 | Two-cut ASPD correction
{
- sd->aspd += aspd_base_0[sd->status.weapon]
+ b_base_weapon_delay_adjust = aspd_base_0[sd->status.weapon] + sd->base_weapon_delay_adjust;
+ if (b_base_weapon_delay_adjust.count() < 0)
+ b_base_weapon_delay_adjust = interval_t::zero();
+ sd->aspd += b_base_weapon_delay_adjust
- (sd->paramc[ATTR::AGI] * 4 + sd->paramc[ATTR::DEX])
- * aspd_base_0[sd->status.weapon] / 1000;
+ * b_base_weapon_delay_adjust / 1000;
}
aspd_rate = sd->aspd_rate;
@@ -1507,11 +1539,6 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->sc_data[StatusChange::SC_ATKPOT].timer)
sd->watk += sd->sc_data[StatusChange::SC_ATKPOT].val1;
- if (sd->sc_data[StatusChange::SC_MATKPOT].timer)
- {
- sd->matk1 += sd->sc_data[StatusChange::SC_MATKPOT].val1;
- sd->matk2 += sd->sc_data[StatusChange::SC_MATKPOT].val1;
- }
if (sd->sc_data[StatusChange::SC_SPEEDPOTION0].timer)
aspd_rate -= sd->sc_data[StatusChange::SC_SPEEDPOTION0].val1;
@@ -1528,17 +1555,20 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->speed_rate != 100)
sd->speed = sd->speed * sd->speed_rate / 100;
sd->speed = std::max(sd->speed, 1_ms);
+ if (sd->speed_cap < interval_t::zero())
+ sd->speed_cap = interval_t::zero();
+ if (sd->speed < sd->speed_cap)
+ sd->speed = sd->speed_cap;
+ if (aspd_rate != 100)
+ 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;
- if (aspd_rate != 100)
- sd->aspd = sd->aspd * aspd_rate / 100;
-
- /* Red Threshold Calculation (TODO) */
+ /* Red Threshold Calculation */
if (sd->aspd < 300_ms) {
- sd->aspd = 300_ms + ((sd->aspd - 300_ms) * 20 / 20);
+ sd->aspd = 300_ms + ((sd->aspd - 300_ms) * 19 / 20);
}
sd->aspd = std::max(sd->aspd, battle_config.max_aspd);
@@ -1551,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)
+ 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)
+ 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);
@@ -1792,7 +1822,7 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val)
break;
case SP::PERFECT_HIT_ADD_RATE:
if (!sd->state.lr_flag_is_arrow_2)
- sd->perfect_hit_add += val;
+ sd->perfect_hit_add_rate += val;
break;
case SP::CRITICAL_RATE:
if (!sd->state.lr_flag_is_arrow_2)
@@ -1829,6 +1859,41 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val)
case SP::DEAF:
sd->special_state.deaf = 1;
break;
+ case SP::SPEED_CAP:
+ if (!sd->state.lr_flag_is_arrow_2)
+ // highest value (slowest speed) is taken others are ignored
+ if (sd->speed_cap < interval_t(val))
+ sd->speed_cap = interval_t(val);
+ break;
+ case SP::ALL_STATS:
+ sd->parame[ATTR::STR] += val;
+ sd->parame[ATTR::AGI] += val;
+ sd->parame[ATTR::VIT] += val;
+ sd->parame[ATTR::INT] += val;
+ sd->parame[ATTR::DEX] += val;
+ sd->parame[ATTR::LUK] += val;
+ break;
+ case SP::AGI_VIT:
+ sd->parame[ATTR::AGI] += val;
+ sd->parame[ATTR::VIT] += val;
+ break;
+ case SP::AGI_DEX_STR:
+ sd->parame[ATTR::AGI] += val;
+ sd->parame[ATTR::DEX] += val;
+ sd->parame[ATTR::STR] += val;
+ break;
+ case SP::DEADLY_STRIKE_RATE:
+ if (!sd->state.lr_flag_is_arrow_2 && sd->deadly_strike < val)
+ sd->deadly_strike = val;
+ break;
+ case SP::DEADLY_STRIKE_ADD_RATE:
+ if (!sd->state.lr_flag_is_arrow_2)
+ sd->deadly_strike_add_rate += val;
+ break;
+ case SP::BASE_WEAPON_DELAY_ADJUST:
+ if (!sd->state.lr_flag_is_arrow_2)
+ sd->base_weapon_delay_adjust += interval_t(val);
+ break;
default:
if (battle_config.error_log)
PRINTF("pc_bonus: unknown type %d %d !\n"_fmt,
@@ -1840,6 +1905,7 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val)
/*==========================================
* ソスソス ソスソスソスiソスノゑソスソスソスソス\ソスヘ難ソスソスフボソス[ソスiソスXソスン抵ソス
+ * sos sos sos sos sos i sos no sos sos sos sos\
*------------------------------------------
*/
int pc_bonus2(dumb_ptr<map_session_data> sd, SP type, int type2, int val)
@@ -1889,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)
@@ -2341,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 ();
@@ -2664,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;
}
@@ -2841,14 +2921,14 @@ 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
{
dist = distance(sd->bl_x, sd->bl_y, bl->bl_x, bl->bl_y);
range = sd->attackrange;
- if (sd->status.weapon != ItemLook::BOW)
+ if (sd->status.weapon != ItemLook::W_BOW)
range++;
if (dist > range)
{ //届 かないので移動 | Move because it does not arrive
@@ -2977,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);
@@ -3036,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;
}
@@ -3045,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);
@@ -3282,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);
@@ -3311,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);
@@ -3334,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);
@@ -3366,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;
}
@@ -3392,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;
}
@@ -3485,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)
{
@@ -3785,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;
@@ -3835,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:
@@ -3853,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
@@ -3933,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);
}
@@ -4034,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);
@@ -4413,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_)
@@ -4780,11 +4891,11 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS)
sd->status.inventory[n].equip = pos;
ItemNameId view_i;
- ItemLook view_l = ItemLook::NONE;
+ ItemLook view_l = ItemLook::W_FIST;
// TODO: This is ugly.
OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[n])
{
- bool look_not_weapon = sdidn->look == ItemLook::NONE;
+ bool look_not_weapon = sdidn->look == ItemLook::W_FIST;
bool equip_is_weapon = bool(sd->status.inventory[n].equip & EPOS::WEAPON);
assert (look_not_weapon != equip_is_weapon);
@@ -4844,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;
}
@@ -4873,9 +4984,9 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type)
}
if (bool(sd->status.inventory[n].equip & EPOS::WEAPON))
{
- sd->weapontype1 = ItemLook::NONE;
+ sd->weapontype1 = ItemLook::W_FIST;
// when reading the diff, think twice about this
- sd->status.weapon = ItemLook::NONE;
+ sd->status.weapon = ItemLook::W_FIST;
pc_calcweapontype(sd);
pc_set_weapon_look(sd);
}
@@ -4911,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;
@@ -4984,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;
}
@@ -5369,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)
{
@@ -5377,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)