From d3942a51238f34ae7807e5747f6569b55924e0d1 Mon Sep 17 00:00:00 2001 From: HoraK-FDF Date: Mon, 24 Oct 2022 23:33:34 +0000 Subject: Sc cooldown added frillyar and kaflosh status symbols and <1s fix --- src/map/clif.cpp | 4 ++++ src/map/script-fun.cpp | 31 ++++++++++++++++++++------- src/map/skill.cpp | 57 ++++++++++++++++++++++++++++++-------------------- src/mmo/skill.t.hpp | 2 ++ 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 1c78cd0..f71feb6 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -1691,6 +1691,8 @@ int clif_storageequiplist(dumb_ptr sd, Borrowed stor) /*========================================== * ステータスを送りつける * 表示専用数字はこの中で計算して送る + * send status + * Display-only numbers are calculated and sent here *------------------------------------------ */ int clif_updatestatus(dumb_ptr sd, SP type) @@ -2189,6 +2191,7 @@ void clif_pvpstatus(dumb_ptr sd) /*========================================== * 表示オプション変更 + * Change display options *------------------------------------------ */ int clif_changeoption(dumb_ptr bl) @@ -2992,6 +2995,7 @@ int clif_skill_damage(dumb_ptr src, dumb_ptr dst, /*========================================== * 状態異常アイコン/メッセージ表示 + * Abnormal status icon/message display *------------------------------------------ */ int clif_status_change(dumb_ptr bl, StatusChange type, int flag) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 135aef9..90ae671 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -3393,14 +3393,29 @@ void builtin_sc_start(ScriptState *st) StatusChange type = static_cast(conv_num(st, &AARG(0))); interval_t tick = static_cast(conv_num(st, &AARG(1))); if (tick < 1_s) - // work around old behaviour of: - // speed potion - // atk potion - // matk potion - // - // which used to use seconds - // all others used milliseconds - tick *= 1000; + switch (type) + { + // all those use ms so this checks for < 1s are not needed on those + // and it would break the cooldown symbol since many spells have cooldowns less than 1s + case StatusChange::SC_PHYS_SHIELD: + case StatusChange::SC_MBARRIER: + case StatusChange::SC_COOLDOWN: + case StatusChange::SC_COOLDOWN_MG: + case StatusChange::SC_COOLDOWN_MT: + case StatusChange::SC_COOLDOWN_R: + case StatusChange::SC_COOLDOWN_AR: + break; + + default: + // work around old behaviour of: + // speed potion + // atk potion + // matk potion + // + // which used to use seconds + // all others used milliseconds + tick *= 1000; + } val1 = conv_num(st, &AARG(2)); if (HARG(3)) //指定したキャラを状態異常にする | Make the specified character abnormal bl = map_id2bl(wrap(conv_num(st, &AARG(3)))); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 4207b93..b90207f 100644 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -662,11 +662,13 @@ int skill_castcancel(dumb_ptr bl, int) /*---------------------------------------------------------------------------- * ステータス異常 + * Status anomalies *---------------------------------------------------------------------------- */ /*========================================== * ステータス異常終了 + * Abnormal end of status *------------------------------------------ */ int skill_status_change_active(dumb_ptr bl, StatusChange type) @@ -732,26 +734,30 @@ void skill_status_change_end(dumb_ptr bl, StatusChange type, TimerDa assert (!sc_data[type].timer); switch (type) - { /* 異常の種類ごとの処理 */ - case StatusChange::SC_SPEEDPOTION0: /* 増速ポーション */ + { /* 異常の種類ごとの処理 | Processing by type of anomaly */ + case StatusChange::SC_SPEEDPOTION0: /* 増速ポーション | Speed Increasing Potion */ case StatusChange::SC_ATKPOT: /* attack potion [Valaris] */ case StatusChange::SC_MATKPOT: /* magic attack potion [Valaris] */ case StatusChange::SC_PHYS_SHIELD: case StatusChange::SC_HASTE: + calc_flag = 1; + break; + case StatusChange::SC_COOLDOWN: case StatusChange::SC_COOLDOWN_MG: case StatusChange::SC_COOLDOWN_MT: - calc_flag = 1; + case StatusChange::SC_COOLDOWN_R: + case StatusChange::SC_COOLDOWN_AR: break; /* option2 */ - case StatusChange::SC_POISON: /* 毒 */ + case StatusChange::SC_POISON: /* 毒 | poison */ calc_flag = 1; break; } if (bl->bl_type == BL::PC && type < StatusChange::SC_SENDMAX) - clif_status_change(bl, type, 0); /* アイコン消去 */ + clif_status_change(bl, type, 0); /* アイコン消去 | Icon Clearing */ switch (type) { @@ -778,11 +784,11 @@ void skill_status_change_end(dumb_ptr bl, StatusChange type, TimerDa break; } - if (opt_flag) /* optionの変更を伝える */ + if (opt_flag) /* optionの変更を伝える | Communicate option changes */ clif_changeoption(bl); if (bl->bl_type == BL::PC && calc_flag) - pc_calcstatus(bl->is_player(), 0); /* ステータス再計算 */ + pc_calcstatus(bl->is_player(), 0); /* ステータス再計算 | Status Recalculation */ } int skill_update_heal_animation(dumb_ptr sd) @@ -806,6 +812,7 @@ int skill_update_heal_animation(dumb_ptr sd) /*========================================== * ステータス異常終了タイマー + * Status abnormal end timer *------------------------------------------ */ void skill_status_change_timer(TimerData *tid, tick_t tick, BlockId id, StatusChange type) @@ -816,7 +823,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, BlockId id, StatusCh if ((bl = map_id2bl(id)) == nullptr) return; - //該当IDがすでに消滅しているというのはいかにもありそうなのでスルーしてみる + // 該当IDがすでに消滅しているというのはいかにもありそうなのでスルーしてみる | It seems that the corresponding ID has already disappeared, so let's go through it sc_data = battle_get_sc_data(bl); if (not sc_data) return; @@ -870,7 +877,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, BlockId id, StatusCh // If you manually reschedule the timer, you MUST skip the // call to skill_status_change_end below. - /* 時間切れ無し?? */ + /* 時間切れ無し?? | No time out? ? */ case StatusChange::SC_WEIGHT50: case StatusChange::SC_WEIGHT90: sc_data[type].timer = Timer(tick + 10_min, @@ -889,6 +896,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, BlockId id, StatusCh /*========================================== * ステータス異常開始 + * Abnormal status start *------------------------------------------ */ int skill_status_change_start(dumb_ptr bl, StatusChange type, @@ -948,7 +956,7 @@ int skill_status_effect(dumb_ptr bl, StatusChange type, } if (sc_data[type].timer) - { /* すでに同じ異常になっている場合タイマ解除 */ + { /* すでに同じ異常になっている場合タイマ解除 | Cancel the timer if the same error has already occurred */ if (sc_data[type].val1 > val1 && type != StatusChange::SC_SPEEDPOTION0 && type != StatusChange::SC_ATKPOT @@ -957,7 +965,7 @@ int skill_status_effect(dumb_ptr bl, StatusChange type, if (type == StatusChange::SC_POISON) return 0; - /* 継ぎ足しができない状態異常である時は状態異常を行わない */ + /* 継ぎ足しができない状態異常である時は状態異常を行わない | If the status ailment cannot be replenished, the status ailment will not be applied. */ { sc_data[type].timer.cancel(); } @@ -965,13 +973,13 @@ int skill_status_effect(dumb_ptr bl, StatusChange type, switch (type) { - /* 異常の種類ごとの処理 */ + /* 異常の種類ごとの処理 | Actions by type of anomaly */ case StatusChange::SC_SLOWPOISON: if (!sc_data[StatusChange::SC_POISON].timer) return 0; break; - case StatusChange::SC_SPEEDPOTION0: /* 増速ポーション */ + case StatusChange::SC_SPEEDPOTION0: /* 増速ポーション | speed boost potion */ *opt2 |= Opt2::_speedpotion0; calc_flag = 1; // val2 = 5*(2+type-StatusChange::SC_SPEEDPOTION0); @@ -986,7 +994,7 @@ int skill_status_effect(dumb_ptr bl, StatusChange type, break; /* option2 */ - case StatusChange::SC_POISON: /* 毒 */ + case StatusChange::SC_POISON: /* 毒 | poison */ calc_flag = 1; { int sc_def = @@ -1006,13 +1014,15 @@ int skill_status_effect(dumb_ptr bl, StatusChange type, case StatusChange::SC_HASTE: case StatusChange::SC_PHYS_SHIELD: case StatusChange::SC_MBARRIER: - case StatusChange::SC_COOLDOWN: - case StatusChange::SC_COOLDOWN_MG: - case StatusChange::SC_COOLDOWN_MT: calc_flag = 1; break; case StatusChange::SC_HALT_REGENERATE: case StatusChange::SC_HIDE: + case StatusChange::SC_COOLDOWN: + case StatusChange::SC_COOLDOWN_MG: + case StatusChange::SC_COOLDOWN_MT: + case StatusChange::SC_COOLDOWN_R: + case StatusChange::SC_COOLDOWN_AR: break; case StatusChange::SC_FLYING_BACKPACK: updateflag = SP::WEIGHT; @@ -1024,9 +1034,9 @@ int skill_status_effect(dumb_ptr bl, StatusChange type, } if (bl->bl_type == BL::PC && type < StatusChange::SC_SENDMAX) - clif_status_change(bl, type, 1); /* アイコン表示 */ + clif_status_change(bl, type, 1); /* アイコン表示 | Icon display */ - /* optionの変更 */ + /* optionの変更 | Changing an Option */ switch (type) { case StatusChange::SC_POISON: @@ -1044,27 +1054,28 @@ int skill_status_effect(dumb_ptr bl, StatusChange type, break; } - if (opt_flag) /* optionの変更 */ + if (opt_flag) /* optionの変更 | Changing an Option */ clif_changeoption(bl); sc_data[type].val1 = val1; - /* タイマー設定 */ + /* タイマー設定 | timer setting */ sc_data[type].timer = Timer(gettick() + tick, std::bind(skill_status_change_timer, ph::_1, ph::_2, bl->bl_id, type)); if (bl->bl_type == BL::PC && calc_flag) - pc_calcstatus(sd, 0); /* ステータス再計算 */ + pc_calcstatus(sd, 0); /* ステータス再計算 | Status recalculation */ if (bl->bl_type == BL::PC && updateflag != SP::ZERO) - clif_updatestatus(sd, updateflag); /* ステータスをクライアントに送る */ + clif_updatestatus(sd, updateflag); /* ステータスをクライアントに送る | Send status to client */ return 0; } /*========================================== * ステータス異常全解除 + * Remove all status abnormalities *------------------------------------------ */ int skill_status_change_clear(dumb_ptr bl, int type) diff --git a/src/mmo/skill.t.hpp b/src/mmo/skill.t.hpp index 4d9a766..166543c 100644 --- a/src/mmo/skill.t.hpp +++ b/src/mmo/skill.t.hpp @@ -55,6 +55,8 @@ enum class StatusChange : uint16_t SC_COOLDOWN = 71, // Spell cooldown SC_COOLDOWN_MG = 72, // Mana Guardian cooldown SC_COOLDOWN_MT = 73, // Mana Tyrant cooldown + SC_COOLDOWN_R = 74, // Kaflosh cooldown + SC_COOLDOWN_AR = 75, // Frillyar cooldown SC_POISON = 132, // bad; actually used -- cgit v1.2.3-60-g2f50 From 439ab328350c730c9f45d66e6a77b3fdd02dc786 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Wed, 26 Oct 2022 01:29:29 -0300 Subject: Reintroduce OnPCLogoutEvent label --- src/map/pc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 6c2f673..dc34c96 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -5615,6 +5615,8 @@ int pc_logout(dumb_ptr sd) // [fate] Player logs out #endif pc_setglobalreg(sd, stringish("MAGIC_CAST_TICK"_s), 0); + npc_event_doall_l(stringish("OnPCLogoutEvent"_s), sd->bl_id, nullptr); + MAP_LOG_STATS(sd, "LOGOUT"_fmt); return 0; } -- cgit v1.2.3-60-g2f50 From 4f8f0258127ed44f4600949314740c4f04857f31 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Sat, 5 Nov 2022 17:09:56 -0300 Subject: Reduce scope of a variable to prevent possible exploits. --- src/map/pc.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index dc34c96..a414857 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -3124,7 +3124,10 @@ int pc_gainexp_reason(dumb_ptr sd, int base_exp, int job_exp, } // Double Xp Weekends - base_exp = (base_exp * static_cast(battle_config.base_exp_rate) / 100.); + if (reason != PC_GAINEXP_REASON::SCRIPT) + base_exp = (base_exp * static_cast(battle_config.base_exp_rate) / 100.); + + // Sanitization if (base_exp <= 0) base_exp = 0; else if (base_exp > 1000000000) -- cgit v1.2.3-60-g2f50 From eb9056d8787181095af379c0861ef45d790b7385 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Tue, 8 Nov 2022 19:43:08 -0300 Subject: Remove getusers(0) because it is broken in TMWA (causes a SEGV) --- src/map/script-fun.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 90ae671..500d892 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -3157,9 +3157,9 @@ void builtin_getusers(ScriptState *st) int val = 0; switch (flag & 0x07) { - case 0: + /*case 0: val = bl->bl_m->users; - break; + break;*/ case 1: val = map_getusers(); break; -- cgit v1.2.3-60-g2f50 From c20ee2295832e1f9cc7e29a54df754d6ce3f0d0c Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Tue, 8 Nov 2022 23:02:03 -0300 Subject: Break balance: Potions and Betsanc now affect mages speed (incl. upmarmu). --- src/map/pc.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index a414857..dd2c604 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -1517,12 +1517,13 @@ int pc_calcstatus(dumb_ptr 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 (aspd_rate != 100) - sd->aspd = sd->aspd * aspd_rate / 100; if (sd->attack_spell_override) sd->aspd = sd->attack_spell_delay; + if (aspd_rate != 100) + sd->aspd = sd->aspd * aspd_rate / 100; + sd->aspd = std::max(sd->aspd, battle_config.max_aspd); sd->amotion = sd->aspd; sd->dmotion = std::chrono::milliseconds(800 - sd->paramc[ATTR::AGI] * 4); -- cgit v1.2.3-60-g2f50 From be26c64fcdec14be4ac02a470ac7ed007113c7a1 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Tue, 8 Nov 2022 23:04:11 -0300 Subject: Slow down Setzer in 10ms - unnoticeable except in DPS calculations. --- src/map/pc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index dd2c604..7ceb8f1 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -130,7 +130,7 @@ earray 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 -- cgit v1.2.3-60-g2f50 From 2fd2caa7c54e3dd6898bb60d33e0e47153b10eb5 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Tue, 8 Nov 2022 23:20:42 -0300 Subject: Nerf the "Red Threshold" attack speed. --- src/map/pc.cpp | 5 +++++ src/map/script-fun.cpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 7ceb8f1..49ef5a4 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -1524,6 +1524,11 @@ int pc_calcstatus(dumb_ptr sd, int first) if (aspd_rate != 100) sd->aspd = sd->aspd * aspd_rate / 100; + /* Red Threshold Calculation */ + if (sd->aspd < 300_ms) { + sd->aspd = 300_ms + ((sd->aspd - 300_ms) / 2); + } + sd->aspd = std::max(sd->aspd, battle_config.max_aspd); sd->amotion = sd->aspd; sd->dmotion = std::chrono::milliseconds(800 - sd->paramc[ATTR::AGI] * 4); diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 500d892..bcb5a45 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -3146,7 +3146,7 @@ void builtin_mapannounce(ScriptState *st) /*========================================== * ユーザー数所得 - * User Revenue + * User Count *------------------------------------------ */ static @@ -3169,7 +3169,7 @@ void builtin_getusers(ScriptState *st) /*========================================== * マップ指定ユーザー数所得 - * maps Designated User Income + * maps Designated User Count *------------------------------------------ */ static -- cgit v1.2.3-60-g2f50 From 84bc4cd7fbfbacf74915de7d5541c82b65d64ee3 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Wed, 9 Nov 2022 08:44:19 -0300 Subject: Fix the promised machine gun --- src/map/pc.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 49ef5a4..c7b8e3b 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -792,7 +792,7 @@ void pc_set_attack_info(dumb_ptr sd, interval_t speed, int ran } else { - sd->aspd = speed; + pc_calcstatus(sd, 1); clif_updatestatus(sd, SP::ASPD); clif_updatestatus(sd, SP::ATTACKRANGE); } @@ -1518,6 +1518,7 @@ int pc_calcstatus(dumb_ptr sd, int first) sd->speed = sd->speed * sd->speed_rate / 100; sd->speed = std::max(sd->speed, 1_ms); + /* Magic speed */ if (sd->attack_spell_override) sd->aspd = sd->attack_spell_delay; @@ -2870,7 +2871,7 @@ void pc_attack_timer(TimerData *, tick_t tick, BlockId id) {"@target_id"_s, static_cast(unwrap(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 * 2); //sd->attack_spell_delay; sd->attack_spell_charges--; if (!sd->attack_spell_charges) { -- cgit v1.2.3-60-g2f50 From e886d580bbfecb281f97c867b8fe0532985449f7 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Wed, 9 Nov 2022 09:50:02 -0300 Subject: Revert previous commit, but upmarmu is strange and TMWA is not honoring its own limits. No wonder upmarmu is so powerful, it is easy to be if you ignore max_aspeed parameter. Also, smooth the aspd nerf. --- src/map/pc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index c7b8e3b..32d6769 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -792,7 +792,7 @@ void pc_set_attack_info(dumb_ptr sd, interval_t speed, int ran } else { - pc_calcstatus(sd, 1); + sd->aspd = speed; //pc_calcstatus(sd, 1); clif_updatestatus(sd, SP::ASPD); clif_updatestatus(sd, SP::ATTACKRANGE); } @@ -1527,7 +1527,7 @@ int pc_calcstatus(dumb_ptr sd, int first) /* Red Threshold Calculation */ if (sd->aspd < 300_ms) { - sd->aspd = 300_ms + ((sd->aspd - 300_ms) / 2); + sd->aspd = 300_ms + ((sd->aspd - 300_ms) * 11 / 20); } sd->aspd = std::max(sd->aspd, battle_config.max_aspd); @@ -2871,7 +2871,7 @@ void pc_attack_timer(TimerData *, tick_t tick, BlockId id) {"@target_id"_s, static_cast(unwrap(bl->bl_id))}, }; npc_event_do_l(sd->magic_attack, sd->bl_id, arg); - sd->attackabletime = tick + (sd->aspd * 2); //sd->attack_spell_delay; + sd->attackabletime = tick + sd->attack_spell_delay; sd->attack_spell_charges--; if (!sd->attack_spell_charges) { -- cgit v1.2.3-60-g2f50 From 1b097707c019a1c9a121998be942a7237a7f3592 Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Wed, 9 Nov 2022 22:06:14 -0300 Subject: This is the patch for tomorrow. Have fun :3 - Fix the lighting machine gun bug - Fix upmarmu workings - Reduce nerf factor from 11 to 15 --- src/map/pc.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 32d6769..d427ab9 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -792,7 +792,7 @@ void pc_set_attack_info(dumb_ptr sd, interval_t speed, int ran } else { - sd->aspd = speed; //pc_calcstatus(sd, 1); + 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 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 sd, int first) @@ -1519,7 +1525,7 @@ int pc_calcstatus(dumb_ptr sd, int first) sd->speed = std::max(sd->speed, 1_ms); /* Magic speed */ - if (sd->attack_spell_override) + if (sd->attack_spell_override || first & 8) sd->aspd = sd->attack_spell_delay; if (aspd_rate != 100) @@ -1527,7 +1533,7 @@ int pc_calcstatus(dumb_ptr sd, int first) /* Red Threshold Calculation */ if (sd->aspd < 300_ms) { - sd->aspd = 300_ms + ((sd->aspd - 300_ms) * 11 / 20); + sd->aspd = 300_ms + ((sd->aspd - 300_ms) * 15 / 20); } sd->aspd = std::max(sd->aspd, battle_config.max_aspd); @@ -2871,7 +2877,7 @@ void pc_attack_timer(TimerData *, tick_t tick, BlockId id) {"@target_id"_s, static_cast(unwrap(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) { -- cgit v1.2.3-60-g2f50