From 00c02479dbf4fe5ec16c1c8adbe48f7544b3f4fc Mon Sep 17 00:00:00 2001 From: Aleos Date: Wed, 7 Oct 2020 09:45:58 -0400 Subject: [PATCH] Fixes Magnetic field behavior (#5423) * Fixes #5401. * Minor optimizations to core skill behavior. * Adjusts the status timer to be stored in val4. * Impose a unit lock before doing status damage. * Check for status state before attempting to reapply the status timer. Thanks to @LotusRO! --- src/map/skill.cpp | 16 ++++++++-------- src/map/status.cpp | 9 ++++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 29c263d885..7ab9ade4b7 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -5913,10 +5913,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint map_foreachinallrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id); } break; - - case NC_MAGNETICFIELD: - sc_start2(src,bl,SC_MAGNETICFIELD,100,skill_lv,src->id,skill_get_time(skill_id,skill_lv)); - break; case SC_FATALMENACE: if( flag&1 ) skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); @@ -10227,10 +10223,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case NC_MAGNETICFIELD: - clif_skill_damage(src,bl,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,DMG_SINGLE); - if (map_flag_vs(src->m)) // Doesn't affect the caster in non-PVP maps [exneval] - sc_start2(src,bl,type,100,skill_lv,src->id,skill_get_time(skill_id,skill_lv)); - map_foreachinallrange(skill_area_sub,bl,skill_get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill_castend_damage_id); + if (flag & 1) { + sc_start2(src, bl, SC_MAGNETICFIELD, 100, skill_lv, src->id, skill_get_time(skill_id, skill_lv)); + } else { + if (map_flag_vs(src->m)) // Doesn't affect the caster in non-PVP maps [exneval] + sc_start2(src, bl, type, 100, skill_lv, src->id, skill_get_time(skill_id, skill_lv)); + map_foreachinallrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_nodamage_id); + clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SINGLE); + } break; case NC_REPAIR: diff --git a/src/map/status.cpp b/src/map/status.cpp index 39081687fe..2fab6c7592 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -11564,8 +11564,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty tick_time = 5000; // [GodLesZ] tick time break; case SC_MAGNETICFIELD: - val3 = tick / 1000; tick_time = 1000; // [GodLesZ] tick time + val4 = tick / tick_time; break; case SC_INSPIRATION: val2 = (sd?sd->status.job_level:50); @@ -14510,14 +14510,17 @@ TIMER_FUNC(status_change_timer){ break; case SC_MAGNETICFIELD: - if (--(sce->val3) >= 0) { + if (--(sce->val4) >= 0) { struct block_list *src = map_id2bl(sce->val2); if (!src || (src && (status_isdead(src) || src->m != bl->m))) break; + map_freeblock_lock(); if (!status_charge(bl, 0, 50)) status_zap(bl, 0, status->sp); - sc_timer_next(1000 + tick); + if (sc->data[type]) + sc_timer_next(1000 + tick); + map_freeblock_unlock(); return 0; } break;