From 947897b52f14d58d5fe816cc38487ba288f6765c Mon Sep 17 00:00:00 2001
From: HoraK-FDF <horak-fdf@web.de>
Date: Sat, 12 Nov 2022 03:58:22 +0100
Subject: mobinfo add4

---
 src/map/pc.cpp | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 6c2f673..d427ab9 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -130,7 +130,7 @@ 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
-600_ms,  // 3 SETZER_AND_SCYTHE
+610_ms,  // 3 SETZER_AND_SCYTHE
 2000_ms, // 4
 2000_ms, // 5
 800_ms,  // 6 Falchion
@@ -792,7 +792,7 @@ void pc_set_attack_info(dumb_ptr<map_session_data> sd, interval_t speed, int ran
     }
     else
     {
-        sd->aspd = speed;
+        pc_calcstatus(sd, 9);
         clif_updatestatus(sd, SP::ASPD);
         clif_updatestatus(sd, SP::ATTACKRANGE);
     }
@@ -1085,6 +1085,12 @@ void pc_set_weapon_look(dumb_ptr<map_session_data> sd)
  * When first==0, the parameter to be calculated is from before the call
  * If it changes, it will automatically send it,
  * Actively changed parameters should be send on their own
+ *
+ * First is a bitmask
+ * &1 = ?
+ * &2 = ?
+ * &4 = ?
+ * &8 = magic override
  *------------------------------------------
  */
 int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
@@ -1517,11 +1523,18 @@ 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);
+
+    /* Magic speed */
+    if (sd->attack_spell_override || first & 8)
+        sd->aspd = sd->attack_spell_delay;
+
     if (aspd_rate != 100)
         sd->aspd = sd->aspd * aspd_rate / 100;
 
-    if (sd->attack_spell_override)
-        sd->aspd = sd->attack_spell_delay;
+    /* Red Threshold Calculation */
+    if (sd->aspd < 300_ms) {
+        sd->aspd = 300_ms + ((sd->aspd - 300_ms) * 15 / 20);
+    }
 
     sd->aspd = std::max(sd->aspd, battle_config.max_aspd);
     sd->amotion = sd->aspd;
@@ -2864,7 +2877,7 @@ void pc_attack_timer(TimerData *, tick_t tick, BlockId id)
             {"@target_id"_s, static_cast<int32_t>(unwrap<BlockId>(bl->bl_id))},
         };
         npc_event_do_l(sd->magic_attack, sd->bl_id, arg);
-        sd->attackabletime = tick + sd->attack_spell_delay;
+        sd->attackabletime = tick + sd->aspd; // sd->attack_spell_delay
         sd->attack_spell_charges--;
         if (!sd->attack_spell_charges)
         {
@@ -3124,7 +3137,10 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
     }
 
     // Double Xp Weekends
-    base_exp = (base_exp * static_cast<double>(battle_config.base_exp_rate) / 100.);
+    if (reason != PC_GAINEXP_REASON::SCRIPT)
+        base_exp = (base_exp * static_cast<double>(battle_config.base_exp_rate) / 100.);
+
+    // Sanitization
     if (base_exp <= 0)
         base_exp = 0;
     else if (base_exp > 1000000000)
@@ -5615,6 +5631,8 @@ int pc_logout(dumb_ptr<map_session_data> sd) // [fate] Player logs out
 #endif
         pc_setglobalreg(sd, stringish<VarName>("MAGIC_CAST_TICK"_s), 0);
 
+    npc_event_doall_l(stringish<ScriptLabel>("OnPCLogoutEvent"_s), sd->bl_id, nullptr);
+
     MAP_LOG_STATS(sd, "LOGOUT"_fmt);
     return 0;
 }
-- 
cgit v1.2.3-70-g09d2