Browse Source

- Improved the format of battle_calc_cardfix so that it's actually readable and added various comments so others can actually understand what's going on there
- Reverted the change from r17216 and replaced it with another fix that will now work for all skills (still related to bugreport:6991)
- Implemented the official stun chance of Bash based on an Aegis leak; basically the base chance (5% per level above 5) will get multiplied by BaseLevel/50.0, so on level 50, it will be 1x, on level 75 it will be 1.5x and on level 99 it will be almost 2x (prior reductions), e.g. a level 99 knight using bash 10 will have a 49.5% base success chance to stun with it (if he has learned the quest skill)

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

playtester 12 years ago
parent
commit
aace543611
2 changed files with 54 additions and 52 deletions
  1. 51 49
      src/map/battle.c
  2. 3 3
      src/map/skill.c

+ 51 - 49
src/map/battle.c

@@ -499,7 +499,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
 			break;
 		case BF_WEAPON:
 			t_race2 = status_get_race2(target);
-			if( sd && !(nk&NK_NO_CARDFIX_ATK) && (left&2) )
+			if( sd && !(nk&NK_NO_CARDFIX_ATK) && (left&2) ) //Attacker cards should be checked
 			{
 				short cardfix_ = 1000;
 				if(sd->state.arrow_atk)
@@ -572,7 +572,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
 					else
 					{
 						int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
-					for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+						for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
 							if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
 							if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
 								 sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
@@ -632,60 +632,60 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
 				else if( cardfix != 1000 )
 					bccDAMAGE_RATE(cardfix)
 
-		}else if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
-			if( !(nk&NK_NO_ELEFIX) )
-			{
-				int ele_fix = tsd->subele[s_ele];
-				for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+			} else if( tsd && !(nk&NK_NO_CARDFIX_DEF) && !(left&2) ){ //Target cards should be checked
+				if( !(nk&NK_NO_ELEFIX) )
 				{
-					if(tsd->subele2[i].ele != s_ele) continue;
-					if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
-						 tsd->subele2[i].flag&flag&BF_RANGEMASK &&
-						 tsd->subele2[i].flag&flag&BF_SKILLMASK))
-						continue;
-					ele_fix += tsd->subele2[i].rate;
-				}
-				cardfix=cardfix*(100-ele_fix)/100;
-				if( left&1 && s_ele_ != s_ele )
-				{
-					int ele_fix_lh = tsd->subele[s_ele_];
+					int ele_fix = tsd->subele[s_ele];
 					for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
 					{
-						if(tsd->subele2[i].ele != s_ele_) continue;
+						if(tsd->subele2[i].ele != s_ele) continue;
 						if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
 							 tsd->subele2[i].flag&flag&BF_RANGEMASK &&
 							 tsd->subele2[i].flag&flag&BF_SKILLMASK))
 							continue;
-						ele_fix_lh += tsd->subele2[i].rate;
+						ele_fix += tsd->subele2[i].rate;
+					}
+					cardfix=cardfix*(100-ele_fix)/100;
+					if( left&1 && s_ele_ != s_ele )
+					{
+						int ele_fix_lh = tsd->subele[s_ele_];
+						for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+						{
+							if(tsd->subele2[i].ele != s_ele_) continue;
+							if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
+								 tsd->subele2[i].flag&flag&BF_RANGEMASK &&
+								 tsd->subele2[i].flag&flag&BF_SKILLMASK))
+								continue;
+							ele_fix_lh += tsd->subele2[i].rate;
+						}
+						cardfix=cardfix*(100-ele_fix_lh)/100;
 					}
-					cardfix=cardfix*(100-ele_fix_lh)/100;
 				}
-			}
-			cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- 			cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
-			cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
-			cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
-			if( sstatus->race != RC_DEMIHUMAN )
-				cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
+				cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
+	 			cardfix=cardfix*(100-tsd->subrace2[s_race2])/100;
+				cardfix=cardfix*(100-tsd->subrace[sstatus->race])/100;
+				cardfix=cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS])/100;
+				if( sstatus->race != RC_DEMIHUMAN )
+					cardfix=cardfix*(100-tsd->subrace[RC_NONDEMIHUMAN])/100;
 
-			for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ) {
-				if( tsd->add_def[i].class_ == s_class ) {
-					cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
-					break;
+				for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ) {
+					if( tsd->add_def[i].class_ == s_class ) {
+						cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
+						break;
+					}
 				}
-			}
 
-			if( flag&BF_SHORT )
-				cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
-			else	// BF_LONG (there's no other choice)
-				cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+				if( flag&BF_SHORT )
+					cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
+				else	// BF_LONG (there's no other choice)
+					cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
 
-			if( tsd->sc.data[SC_DEF_RATE] )
-				cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
+				if( tsd->sc.data[SC_DEF_RATE] )
+					cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
 
-			if( cardfix != 1000 )
-				bccDAMAGE_RATE(cardfix)
-		}
+				if( cardfix != 1000 )
+					bccDAMAGE_RATE(cardfix)
+			}
 			break;
 		case BF_MISC:
 			if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
@@ -3437,7 +3437,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 	if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
 		return wd; //Enough, rest is not needed.
 
-	if (sd)
+	if(sd)
 	{
 		if (skill_id != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
 			ATK_ADD2(wd.div_*sd->right_weapon.star, wd.div_*sd->left_weapon.star);
@@ -3447,10 +3447,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 			ATK_ADD(wd.div_*sd->spiritball*3);
 		}
 
-		//Card Fix for player and target
-        wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
-        if( flag.lh )
-            wd.damage2 = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag);
+		//Card Fix for attacker (sd), 2 is added to the "left" flag meaning "attacker cards only"
+		wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
+		if( flag.lh )
+			wd.damage2 = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag);
 
 		if( skill_id == CR_SHIELDBOOMERANG || skill_id == PA_SHIELDCHAIN )
 		{ //Refine bonus applies after cards and elements.
@@ -3458,8 +3458,10 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 			if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
 				ATK_ADD(10*sd->status.inventory[index].refine);
 		}
-	}else if(tsd) // Card Fix for target
-        wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, flag.lh, wd.flag);
+	}
+
+	if(tsd) // Card Fix for target (tsd), 2 is not added to the "left" flag meaning "target cards only"
+		wd.damage = battle_calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, flag.lh, wd.flag);
 
 	if( flag.infdef )
 	{ //Plants receive 1 damage when hit

+ 3 - 3
src/map/skill.c

@@ -954,9 +954,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
 
 	case SM_BASH:
 		if( sd && skill_lv > 5 && pc_checkskill(sd,SM_FATALBLOW)>0 ){
-			//TODO: How much % per base level it actually is?
-			sc_start(src,bl,SC_STUN,(5*(skill_lv-5)+(int)sd->status.base_level/10),
-				skill_lv,skill_get_time2(SM_FATALBLOW,skill_lv));
+			//BaseChance gets multiplied with BaseLevel/50.0; 500/50 simplifies to 10 [Playtester]
+			status_change_start(src,bl,SC_STUN,(skill_lv-5)*sd->status.base_level*10,
+				skill_lv,0,0,0,skill_get_time2(SM_FATALBLOW,skill_lv),0);
 		}
 		break;