Pārlūkot izejas kodu

* Fixed some behaviors of additional effects (bugreport:3100,bugreport:2661)
- 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.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13800 54d463be-8e91-2dee-dedb-b68131a5f0ec

Inkfish 16 gadi atpakaļ
vecāks
revīzija
d8a02e92eb
3 mainītis faili ar 91 papildinājumiem un 75 dzēšanām
  1. 6 0
      Changelog-Trunk.txt
  2. 0 34
      src/map/battle.c
  3. 85 41
      src/map/skill.c

+ 6 - 0
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)

+ 0 - 34
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])
 	{

+ 85 - 41
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);