From a244b61804209ec8a836d8d3f1b7220b2bfec990 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Fri, 15 Feb 2013 01:16:28 -0200 Subject: Fixed Bug #7039 Status effects no longer propagate with magical reflection (e.g. when frost diver is reflected there is no chance that target will be frozen) http://hercules.ws/board/tracker/issue-7039-frost-diver/ Signed-off-by: shennetsind --- src/map/battle.c | 14 ++++++++------ src/map/battle.h | 2 +- src/map/skill.c | 16 ++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 5bc3df6f8..460826414 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -209,6 +209,7 @@ struct delay_damage { uint16 skill_id; enum damage_lv dmg_lv; unsigned short attack_type; + bool additional_effects; }; int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { @@ -231,7 +232,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { { map_freeblock_lock(); status_fix_damage(src, target, dat->damage, dat->delay); - if( dat->attack_type && !status_isdead(target) ) + if( dat->attack_type && !status_isdead(target) && dat->additional_effects ) skill_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick); if( dat->dmg_lv > ATK_BLOCK && dat->attack_type ) skill_counter_additional_effect(src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick); @@ -249,7 +250,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { return 0; } -int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int damage, enum damage_lv dmg_lv, int ddelay) +int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) { struct delay_damage *dat; struct status_change *sc; @@ -264,7 +265,7 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, if ( !battle_config.delay_battle_damage || amotion <= 1 ) { map_freeblock_lock(); status_fix_damage(src, target, damage, ddelay); // We have to seperate here between reflect damage and others [icescope] - if( attack_type && !status_isdead(target) ) + if( attack_type && !status_isdead(target) && additional_effects ) skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, gettick()); if( dmg_lv > ATK_BLOCK && attack_type ) skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick()); @@ -281,6 +282,7 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, dat->dmg_lv = dmg_lv; dat->delay = ddelay; dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported. + dat->additional_effects = additional_effects; if (src->type != BL_PC && amotion > 1000) amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex] @@ -4690,7 +4692,7 @@ int battle_damage_area( struct block_list *bl, va_list ap) { if( src->type == BL_PC ) battle_drain((TBL_PC*)src, bl, damage, damage, status_get_race(bl), is_boss(bl)); if( amotion ) - battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0); + battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true); else status_fix_damage(src,bl,damage,0); clif_damage(bl,bl,tick,amotion,dmotion,damage,1,ATK_BLOCK,0); @@ -4927,7 +4929,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } map_freeblock_lock(); - battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion); + battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true); if( tsc ) { if( tsc->data[SC_DEVOTION] ) { struct status_change_entry *sce = tsc->data[SC_DEVOTION]; @@ -5055,7 +5057,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if (rdamage > 0 && !(tsc && tsc->data[SC_REFLECTDAMAGE])) { //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex] if(tsd && src != target) battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); - battle_delay_damage(tick, wd.amotion, target, src, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay); + battle_delay_damage(tick, wd.amotion, target, src, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay, true); } if (tsc) { diff --git a/src/map/battle.h b/src/map/battle.h index cd626cd6b..e3a0a51ab 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -62,7 +62,7 @@ enum { // Flag of the final calculation BF_SKILLMASK= 0x0f00, }; -int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int damage, enum damage_lv dmg_lv, int ddelay); +int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects); // Summary normal attack treatment (basic attack) enum damage_lv battle_weapon_attack( struct block_list *bl,struct block_list *target,unsigned int tick,int flag); diff --git a/src/map/skill.c b/src/map/skill.c index b37d28e3c..86a03b64b 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2192,6 +2192,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds struct map_session_data *sd, *tsd; int type,damage,rdamage=0; int8 rmdamage=0;//magic reflected + bool additional_effects = true; if(skill_id > 0 && !skill_lv) return 0; @@ -2272,7 +2273,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds sc->data[SC_SPIRIT]->val3 = skill_id; sc->data[SC_SPIRIT]->val4 = dsrc->id; } - } + } else if( type != 2 ) /* Kaite bypasses */ + additional_effects = false; /** * Official Magic Reflection Behavior : damage reflected depends on gears caster wears, not target @@ -2618,7 +2620,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds { //Instant damage if( !sc || (!sc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD) ) status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo. - if( !status_isdead(bl) ) + if( !status_isdead(bl) && additional_effects ) skill_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick); if( damage > 0 ) //Counter status effects [Skotlex] skill_counter_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,tick); @@ -2692,10 +2694,9 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds //Delayed damage must be dealt after the knockback (it needs to know actual position of target) if (dmg.amotion) - battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion); + battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects); - if( sc && sc->data[SC_DEVOTION] && skill_id != PA_PRESSURE ) - { + if( sc && sc->data[SC_DEVOTION] && skill_id != PA_PRESSURE ) { struct status_change_entry *sce = sc->data[SC_DEVOTION]; struct block_list *d_bl = map_id2bl(sce->val1); @@ -2707,8 +2708,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if(!rmdamage){ clif_damage(d_bl,d_bl, gettick(), 0, 0, damage, 0, 0, 0); status_fix_damage(NULL,d_bl, damage, 0); - } - else{//Reflected magics are done directly on the target not on paladin + } else{ //Reflected magics are done directly on the target not on paladin //This check is only for magical skill. //For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage clif_damage(bl,bl, gettick(), 0, 0, damage, 0, 0, 0); @@ -2750,7 +2750,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds map_foreachinshootrange(battle_damage_area,bl,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,bl,dmg.amotion,sstatus->dmotion,rdamage,tstatus->race); } else { if( dmg.amotion ) - battle_delay_damage(tick, dmg.amotion,bl,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,0); + battle_delay_damage(tick, dmg.amotion,bl,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,0,additional_effects); else status_fix_damage(bl,src,rdamage,0); clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0); // in aegis damage reflected is shown in single hit. -- cgit v1.2.3-60-g2f50