diff options
-rw-r--r-- | Changelog-Trunk.txt | 6 | ||||
-rw-r--r-- | src/map/battle.c | 34 | ||||
-rw-r--r-- | src/map/skill.c | 126 |
3 files changed, 91 insertions, 75 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index cdd285754..e7a2ea99f 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,12 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +09/05/22 + * Fixed some behaviors of additional effects (bugreport:3100,bugreport:2661) [Inkfish] + - Coma can now be blocked by such skills as SafetyWall, Pneuma and Basilica. + - Equipment breaking behaves exactly like coma. + - Skill's self damage may now causes coma, equipment breaking and autospell/autoscript. + - GrandCross now allows you to drain hp/sp. 09/05/20 * Now fiberlocking a fiberlocked target doesn't renew the timer but instead increases its fireweakness [Inkfish] - This makes doublecasting firebolts on a double fiberlocked target having double damage from both 2 bolts possible = =(bugreport:3061) diff --git a/src/map/battle.c b/src/map/battle.c index 3eced353a..f26a56b89 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2176,40 +2176,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo wd.damage += md.damage; } - if (wd.damage || wd.damage2) { - if (sd && battle_config.equip_self_break_rate) - { // Self weapon breaking - int breakrate = battle_config.equip_natural_break_rate; - if (sc) { - if(sc->data[SC_OVERTHRUST]) - breakrate += 10; - if(sc->data[SC_MAXOVERTHRUST]) - breakrate += 10; - } - if (breakrate) - skill_break_equip(src, EQP_WEAPON, breakrate, BCT_SELF); - } - //Cart Termination/Tomahawk won't trigger breaking data. Why? No idea, go ask Gravity. - if (battle_config.equip_skill_break_rate && skill_num != WS_CARTTERMINATION && skill_num != ITM_TOMAHAWK) - { // Target equipment breaking - int breakrate[2] = {0,0}; // weapon = 0, armor = 1 - if (sd) { // Break rate from equipment - breakrate[0] += sd->break_weapon_rate; - breakrate[1] += sd->break_armor_rate; - } - if (sc) { - if (sc->data[SC_MELTDOWN]) { - breakrate[0] += sc->data[SC_MELTDOWN]->val2; - breakrate[1] += sc->data[SC_MELTDOWN]->val3; - } - } - if (breakrate[0]) - skill_break_equip(target, EQP_WEAPON, breakrate[0], BCT_ENEMY); - if (breakrate[1]) - skill_break_equip(target, EQP_ARMOR, breakrate[1], BCT_ENEMY); - } - } - //SG_FUSION hp penalty [Komurka] if (sc && sc->data[SC_FUSION]) { diff --git a/src/map/skill.c b/src/map/skill.c index 77f27f643..bb18f0e12 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -489,15 +489,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int if( sd ) { // These statuses would be applied anyway even if the damage was blocked by some skills. [Inkfish] - if( sd->special_state.bonus_coma && !skillid) - { - rate = sd->weapon_coma_ele[tstatus->def_ele]; - rate += sd->weapon_coma_race[tstatus->race]; - rate += sd->weapon_coma_race[tstatus->mode&MD_BOSS?RC_BOSS:RC_NONBOSS]; - if (rate) - status_change_start(bl, SC_COMA, rate, 0, 0, 0, 0, 0, 0); - } - if( skillid != WS_CARTTERMINATION && skillid != AM_DEMONSTRATION && skillid != CR_REFLECTSHIELD && skillid != MS_REFLECTSHIELD && skillid != ASC_BREAKER ) { // Trigger status effects enum sc_type type; @@ -709,6 +700,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int //Chance to cause blind status vs demon and undead element, but not against players if(!dstsd && (battle_check_undead(tstatus->race,tstatus->def_ele) || tstatus->race == RC_DEMON)) sc_start(bl,SC_BLIND,100,skilllv,skill_get_time2(skillid,skilllv)); + attack_type |= BF_WEAPON; break; case AM_ACIDTERROR: @@ -914,8 +906,53 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int src = sd?&sd->bl:src; } + if( attack_type&BF_WEAPON ) + { // Coma, Breaking Equipment + if( sd && sd->special_state.bonus_coma ) + { + rate = sd->weapon_coma_ele[tstatus->def_ele]; + rate += sd->weapon_coma_race[tstatus->race]; + rate += sd->weapon_coma_race[tstatus->mode&MD_BOSS?RC_BOSS:RC_NONBOSS]; + if (rate) + status_change_start(bl, SC_COMA, rate, 0, 0, 0, 0, 0, 0); + } + if( sd && battle_config.equip_self_break_rate ) + { // Self weapon breaking + rate = battle_config.equip_natural_break_rate; + if( sc ) + { + if(sc->data[SC_OVERTHRUST]) + rate += 10; + if(sc->data[SC_MAXOVERTHRUST]) + rate += 10; + } + if( rate ) + skill_break_equip(src, EQP_WEAPON, rate, BCT_SELF); + } + if( battle_config.equip_skill_break_rate && skillid != WS_CARTTERMINATION && skillid != ITM_TOMAHAWK ) + { // Cart Termination/Tomahawk won't trigger breaking data. Why? No idea, go ask Gravity. + // Target weapon breaking + rate = 0; + if( sd ) + rate += sd->break_weapon_rate; + if( sc && sc->data[SC_MELTDOWN] ) + rate += sc->data[SC_MELTDOWN]->val2; + if( rate ) + skill_break_equip(bl, EQP_WEAPON, rate, BCT_ENEMY); + + // Target armor breaking + rate = 0; + if( sd ) + rate += sd->break_armor_rate; + if( rate ) + rate += sc->data[SC_MELTDOWN]->val3; + if( rate ) + skill_break_equip(bl, EQP_ARMOR, rate, BCT_ENEMY); + } + } + // Autospell when attacking - if( sd && !status_isdead(bl) && src != bl && sd->autospell[0].id ) + if( sd && !status_isdead(bl) && sd->autospell[0].id ) { struct block_list *tbl; struct unit_data *ud; @@ -971,7 +1008,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int } //Auto-script when attacking - if( sd && src != bl && sd->autoscript[0].script ) + if( sd && sd->autoscript[0].script ) { int i; for( i = 0; i < ARRAYLENGTH(sd->autoscript) && sd->autoscript[i].script; i++ ) @@ -1098,6 +1135,34 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * sd = BL_CAST(BL_PC, src); dstsd = BL_CAST(BL_PC, bl); + if(dstsd && attack_type&BF_WEAPON) + { //Counter effects. + enum sc_type type; + int i, time; + for(i=0; i < ARRAYLENGTH(dstsd->addeff2) && dstsd->addeff2[i].flag; i++) + { + rate = dstsd->addeff2[i].rate; + if (attack_type&BF_LONG) + rate+=dstsd->addeff2[i].arrow_rate; + if (!rate) continue; + + if ((dstsd->addeff2[i].flag&(ATF_LONG|ATF_SHORT)) != (ATF_LONG|ATF_SHORT)) + { //Trigger has range consideration. + if((dstsd->addeff2[i].flag&ATF_LONG && !(attack_type&BF_LONG)) || + (dstsd->addeff2[i].flag&ATF_SHORT && !(attack_type&BF_SHORT))) + continue; //Range Failed. + } + type = dstsd->addeff2[i].id; + time = skill_get_time2(status_sc2skill(type),7); + + if (dstsd->addeff2[i].flag&ATF_TARGET) + status_change_start(src,type,rate,7,0,0,0,time,0); + + if (dstsd->addeff2[i].flag&ATF_SELF && !status_isdead(bl)) + status_change_start(bl,type,rate,7,0,0,0,time,0); + } + } + switch(skillid){ case 0: //Normal Attack if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == -1) @@ -1120,6 +1185,10 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * clif_send_homdata(hd->master,0x100,hd->homunculus.intimacy/100); } break; + case CR_GRANDCROSS: + case NPC_GRANDDARKNESS: + attack_type |= BF_WEAPON; + break; } if(sd && (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR && @@ -1135,36 +1204,8 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * status_heal(src, 0, status_get_lv(bl)*(95+15*rate)/100, 2); } - if(dstsd && attack_type&BF_WEAPON) - { //Counter effects. - enum sc_type type; - int i, time; - for(i=0; i < ARRAYLENGTH(dstsd->addeff2) && dstsd->addeff2[i].flag; i++) - { - rate = dstsd->addeff2[i].rate; - if (attack_type&BF_LONG) - rate+=dstsd->addeff2[i].arrow_rate; - if (!rate) continue; - - if ((dstsd->addeff2[i].flag&(ATF_LONG|ATF_SHORT)) != (ATF_LONG|ATF_SHORT)) - { //Trigger has range consideration. - if((dstsd->addeff2[i].flag&ATF_LONG && !(attack_type&BF_LONG)) || - (dstsd->addeff2[i].flag&ATF_SHORT && !(attack_type&BF_SHORT))) - continue; //Range Failed. - } - type = dstsd->addeff2[i].id; - time = skill_get_time2(status_sc2skill(type),7); - - if (dstsd->addeff2[i].flag&ATF_TARGET) - status_change_start(src,type,rate,7,0,0,0,time,0); - - if (dstsd->addeff2[i].flag&ATF_SELF && !status_isdead(bl)) - status_change_start(bl,type,rate,7,0,0,0,time,0); - } - } - // Trigger counter-spells to retaliate against damage causing skills. - if(dstsd && !status_isdead(bl) && src != bl && dstsd->autospell2[0].id && + if(dstsd && !status_isdead(bl) && dstsd->autospell2[0].id && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE)) { struct block_list *tbl; @@ -1220,7 +1261,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * } } //Auto-script when attacked - if( dstsd && !status_isdead(bl) && src != bl && dstsd->autoscript2[0].script && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE) ) + if( dstsd && !status_isdead(bl) && dstsd->autoscript2[0].script && !(skillid && skill_get_nk(skillid)&NK_NO_DAMAGE) ) { int i; for( i = 0; i < ARRAYLENGTH(dstsd->autoscript2) && dstsd->autoscript2[i].script; i++ ) @@ -1822,6 +1863,9 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds skill_addtimerskill(src,tick + 800,bl->id,0,0,skillid,skilllv,0,flag); } + if(skillid == CR_GRANDCROSS || skillid == NPC_GRANDDARKNESS) + dmg.flag |= BF_WEAPON; + if(sd && dmg.flag&BF_WEAPON && src != bl && src == dsrc && damage > 0) { if (battle_config.left_cardfix_to_right) battle_drain(sd, bl, dmg.damage, dmg.damage, tstatus->race, tstatus->mode&MD_BOSS); |