Bladeren bron

* More logical modifications on skill_additional_effect thing. Thanks to ultramage.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13771 54d463be-8e91-2dee-dedb-b68131a5f0ec
Inkfish 16 jaren geleden
bovenliggende
commit
1a70b702c8
5 gewijzigde bestanden met toevoegingen van 57 en 84 verwijderingen
  1. 8 4
      conf/battle/battle.conf
  2. 26 59
      src/map/battle.c
  3. 3 1
      src/map/battle.h
  4. 19 19
      src/map/skill.c
  5. 1 1
      src/map/skill.h

+ 8 - 4
conf/battle/battle.conf

@@ -116,15 +116,19 @@ magic_defense_type: 0
 // How to count the number of attackers when applying agi penalty ? (choose one)
 // 1-: Count every attack attempt (even those that were dodged/lucky-dodged)
 // 2 : Count every non-lucky-dodged attack attempt
-// 3 : Count only attacks that actually connect
-// 4+: None of the above, count will always be 0
+// 3 : Count attacks that miss due to element/race modifier
+// 4 : Count attacks whose damages are blocked by skills
+// 5 : Count only attacks that actually connect
+// 6+: None of the above, count will always be 0
 agi_penalty_count_lv: 2
 
 // How to count the number of attackers when applying vit penalty ? (choose one)
 // 1-: Count every attack attempt (even those that were dodged/lucky-dodged)
 // 2 : Count every non-lucky-dodged attack attempt
-// 3 : Count only attacks that actually connect
-// 4+: None of the above, count will always be 0
+// 3 : Count attacks that miss due to element/race modifier
+// 4 : Count attacks whose damages are blocked by skills
+// 5 : Count only attacks that actually connect
+// 6+: None of the above, count will always be 0
 vit_penalty_count_lv: 3
 
 // Change attacker's direction to face opponent on every attack? (Note 3)

+ 26 - 59
src/map/battle.c

@@ -165,11 +165,8 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr data)
 	{
 		map_freeblock_lock();
 		status_fix_damage(dat->src, target, dat->damage, dat->delay);
-		if( dat->attack_type && (dat->damage > 0 || dat->attack_type&0xf000) && !status_isdead(target) )
-		{
-			if( dat->damage > 0 ) dat->attack_type &= ~0xf000;
-			skill_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
-		}
+		if( dat->attack_type && !status_isdead(target) )
+			skill_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,dat->dmg_lv,tick);
 		if( dat->damage > 0 && dat->attack_type )
 			skill_counter_additional_effect(dat->src,target,dat->skill_id,dat->skill_lv,dat->attack_type,tick);
 		map_freeblock_unlock();
@@ -187,11 +184,8 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src,
 	if (!battle_config.delay_battle_damage) {
 		map_freeblock_lock();
 		status_fix_damage(src, target, damage, ddelay);
-		if( attack_type && (damage > 0 || attack_type&0xf000) && !status_isdead(target) )
-		{
-			if( damage > 0 ) attack_type &= ~0xf000;
-			skill_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
-		}
+		if( attack_type && !status_isdead(target) )
+			skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, gettick());
 		if( damage > 0 && attack_type )
 			skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, gettick());
 		map_freeblock_unlock();
@@ -272,11 +266,12 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
 /*==========================================
  * ƒ_??[ƒW??IŒvŽZ
  *------------------------------------------*/
-int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag)
+int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int damage,int skill_num,int skill_lv)
 {
 	struct map_session_data *sd = NULL;
 	struct status_change *sc;
 	struct status_change_entry *sce;
+	int div_ = d->div_, flag = d->flag;
 
 	nullpo_retr(0, bl);
 
@@ -309,7 +304,10 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
 	{
 		//First, sc_*'s that reduce damage to 0.
 		if( sc->data[SC_BASILICA] && !(status_get_mode(src)&MD_BOSS) && skill_num != PA_PRESSURE )
-			return (damage > 0 ? -1 : 0); // Trigger status effects.
+		{
+			d->dmg_lv = ATK_BLOCK;
+			return 0;
+		}
 
 		if( sc->data[SC_SAFETYWALL] && (flag&(BF_SHORT|BF_MAGIC))==BF_SHORT )
 		{
@@ -317,13 +315,17 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
 			if (group) {
 				if (--group->val2<=0)
 					skill_delunitgroup(NULL,group);
-				return (damage > 0 ? -1 : 0); // Trigger status effects.
+				d->dmg_lv = ATK_BLOCK;
+				return 0;
 			}
 			status_change_end(bl,SC_SAFETYWALL,-1);
 		}
 
 		if( sc->data[SC_PNEUMA] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG )
-			return (damage > 0 ? -1 : 0); // Trigger status effects.
+		{
+			d->dmg_lv = ATK_BLOCK;
+			return 0;
+		}
 
 		if( (sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK) && rand()%100 < sce->val2 )
 		{
@@ -2140,13 +2142,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 	{	//There is a total damage value
 		if(!wd.damage2)
 		{
-			bool flag = (wd.damage > 0);
-			wd.damage = battle_calc_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
-			if( flag && wd.damage == -1 )
-			{
-				wd.flag |= 0xf000;
-				wd.damage = 0;
-			}
+			wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_num,skill_lv);
 			if( map_flag_gvg2(target->m) )
 				wd.damage=battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
 			else if( map[target->m].flag.battleground )
@@ -2154,13 +2150,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 		}
 		else if(!wd.damage)
 		{
-			bool flag = (wd.damage2 > 0);
-			wd.damage2 = battle_calc_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
-			if( flag && wd.damage2 == -1 )
-			{
-				wd.flag |= 0xf000;
-				wd.damage2 = 0;
-			}
+			wd.damage2 = battle_calc_damage(src,target,&wd,wd.damage2,skill_num,skill_lv);
 			if( map_flag_gvg2(target->m) )
 				wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,wd.div_,skill_num,skill_lv,wd.flag);
 			else if( map[target->m].flag.battleground )
@@ -2169,14 +2159,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 		else
 		{
 			int d1 = wd.damage + wd.damage2,d2 = wd.damage2;
-			bool flag;
-			flag = (d1 > 0);
-			wd.damage = battle_calc_damage(src,target,d1,wd.div_,skill_num,skill_lv,wd.flag);
-			if( flag && wd.damage == -1 )
-			{
-				wd.flag |= 0xf000;
-				wd.damage = 0;
-			}
+			wd.damage = battle_calc_damage(src,target,&wd,d1,skill_num,skill_lv);
 			if( map_flag_gvg2(target->m) )
 				wd.damage = battle_calc_gvg_damage(src,target,wd.damage,wd.div_,skill_num,skill_lv,wd.flag);
 			else if( map[target->m].flag.battleground )
@@ -2578,15 +2561,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 	if (flag.infdef && ad.damage)
 		ad.damage = ad.damage>0?1:-1;
 
-	{
-		bool flag = (ad.damage > 0);
-		ad.damage=battle_calc_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
-		if( flag && ad.damage == -1 )
-		{
-			ad.flag |= 0xf000;
-			ad.damage = 0;
-		}
-	}
+	ad.damage=battle_calc_damage(src,target,&ad,ad.damage,skill_num,skill_lv);
 	if( map_flag_gvg2(target->m) )
 		ad.damage=battle_calc_gvg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
 	else if( map[target->m].flag.battleground )
@@ -2815,15 +2790,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 	if(!(nk&NK_NO_ELEFIX))
 		md.damage=battle_attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
 
-	{
-		bool flag = (md.damage > 0);
-		md.damage=battle_calc_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
-		if( flag && md.damage == -1 )
-		{
-			md.flag |= 0xf000;
-			md.damage = 0;
-		}
-	}
+	md.damage=battle_calc_damage(src,target,&md,md.damage,skill_num,skill_lv);
 	if( map_flag_gvg2(target->m) )
 		md.damage=battle_calc_gvg_damage(src,target,md.damage,md.div_,skill_num,skill_lv,md.flag);
 	else if( map[target->m].flag.battleground )
@@ -2853,11 +2820,11 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl
 		memset(&d,0,sizeof(d));
 		break;
 	}
-	if (d.damage + d.damage2 < 1)
+	if( d.damage + d.damage2 < 1 )
 	{	//Miss/Absorbed
 		//Weapon attacks should go through to cause additional effects.
-		if (d.dmg_lv != ATK_LUCKY && attack_type&(BF_MAGIC|BF_MISC))
-			d.dmg_lv = ATK_FLEE;
+		if (d.dmg_lv == ATK_DEF /*&& attack_type&(BF_MAGIC|BF_MISC)*/) // Isn't it that additional effects don't apply if miss?
+			d.dmg_lv = ATK_MISS;
 		d.dmotion = 0;
 	}
 	return d;
@@ -3079,7 +3046,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 		{
 			rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0);
 			//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
-			skill_additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,tick);
+			skill_additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
 		}
 	}
 
@@ -3673,7 +3640,7 @@ static const struct _battle_data {
 	{ "vit_penalty_type",                   &battle_config.vit_penalty_type,                1,      0,      2,              },
 	{ "vit_penalty_count",                  &battle_config.vit_penalty_count,               3,      2,      INT_MAX,        },
 	{ "vit_penalty_num",                    &battle_config.vit_penalty_num,                 5,      0,      INT_MAX,        },
-	{ "vit_penalty_count_lv",               &battle_config.vit_penalty_count_lv,            ATK_DEF, 0,     INT_MAX,        },
+	{ "vit_penalty_count_lv",               &battle_config.vit_penalty_count_lv,            ATK_MISS, 0,    INT_MAX,        },
 	{ "weapon_defense_type",                &battle_config.weapon_defense_type,             0,      0,      INT_MAX,        },
 	{ "magic_defense_type",                 &battle_config.magic_defense_type,              0,      0,      INT_MAX,        },
 	{ "skill_reiteration",                  &battle_config.skill_reiteration,               BL_NUL, BL_NUL, BL_ALL,         },

+ 3 - 1
src/map/battle.h

@@ -9,6 +9,8 @@ typedef enum damage_lv {
 	ATK_NONE,    // not an attack
 	ATK_LUCKY,   // attack was lucky-dodged
 	ATK_FLEE,    // attack was dodged
+	ATK_MISS,    // attack missed because of element/race modifier.
+	ATK_BLOCK,   // attack was blocked by some skills.
 	ATK_DEF      // attack connected
 } damage_lv;
 
@@ -41,7 +43,7 @@ int battle_attr_ratio(int atk_elem,int def_type, int def_lv);
 int battle_attr_fix(struct block_list *src, struct block_list *target, int damage,int atk_elem,int def_type, int def_lv);
 
 // ƒ_ƒ��[ƒW�Å�IŒvŽZ
-int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag);
+int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int damage,int skill_num,int skill_lv);
 int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag);
 int battle_calc_bg_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag);
 

+ 19 - 19
src/map/skill.c

@@ -454,7 +454,7 @@ struct s_skill_unit_layout* skill_get_unit_layout (int skillid, int skilllv, str
 /*==========================================
  *
  *------------------------------------------*/
-int skill_additional_effect (struct block_list* src, struct block_list *bl, int skillid, int skilllv, int attack_type, unsigned int tick)
+int skill_additional_effect (struct block_list* src, struct block_list *bl, int skillid, int skilllv, int attack_type, int dmg_lv, unsigned int tick)
 {
 	struct map_session_data *sd, *dstsd;
 	struct mob_data *md, *dstmd;
@@ -471,6 +471,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 	if(skillid < 0) return 0;
 	if(skillid > 0 && skilllv <= 0) return 0;	// don't forget auto attacks! - celest
 
+	if( dmg_lv < ATK_BLOCK ) // Don't apply effect if miss.
+		return 0;
+
 	sd = BL_CAST(BL_PC, src);
 	md = BL_CAST(BL_MOB, src);
 	dstsd = BL_CAST(BL_PC, bl);
@@ -485,7 +488,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		return 0;
 
 	if( sd )
-	{ // These status will be applied anyway even if there is no actual damage. [Inkfish]
+	{ // 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];
@@ -549,7 +552,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		}
 	}
 
-	if( attack_type&0xf000 ) // no damage, return;
+	if( dmg_lv < ATK_DEF ) // no damage, return;
 		return 0;
 
 	switch(skillid)
@@ -1575,7 +1578,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 					type = 0;
 				if (type >= 0) {
 					dmg.damage = dmg.damage2 = 0;
-					dmg.dmg_lv = ATK_FLEE;
+					dmg.dmg_lv = ATK_MISS;
 					sc->data[SC_SPIRIT]->val3 = skillid;
 					sc->data[SC_SPIRIT]->val4 = dsrc->id;
 				}
@@ -1585,7 +1588,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 		if(sc && sc->data[SC_MAGICROD] && src == dsrc) {
 			int sp = skill_get_sp(skillid,skilllv);
 			dmg.damage = dmg.damage2 = 0;
-			dmg.dmg_lv = ATK_FLEE; //This will prevent skill additional effect from taking effect. [Skotlex]
+			dmg.dmg_lv = ATK_MISS; //This will prevent skill additional effect from taking effect. [Skotlex]
 			sp = sp * sc->data[SC_MAGICROD]->val2 / 100;
 			if(skillid == WZ_WATERBALL && skilllv > 1)
 				sp = sp/((skilllv|1)*(skilllv|1)); //Estimate SP cost of a single water-ball
@@ -1777,7 +1780,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 			damage = 0; //Sight rasher, blaster, and arrow shower may dmg traps. [Kevin]
 	}
 
-	if (dmg.dmg_lv == ATK_DEF && (type = skill_get_walkdelay(skillid, skilllv)) > 0)
+	if (dmg.dmg_lv >= ATK_MISS && (type = skill_get_walkdelay(skillid, skilllv)) > 0)
 	{	//Skills with can't walk delay also stop normal attacking for that
 		//duration when the attack connects. [Skotlex]
 		struct unit_data *ud = unit_bl2ud(src);
@@ -1788,11 +1791,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 	if( !dmg.amotion )
 	{ //Instant damage
 		status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
-		if( (damage > 0 || attack_type&0xf000) && !status_isdead(bl) )
-		{
-			if( damage > 0 ) attack_type &= ~0xf000;
-			skill_additional_effect(src,bl,skillid,skilllv,attack_type,tick);
-		}
+		if( !status_isdead(bl) )
+			skill_additional_effect(src,bl,skillid,skilllv,attack_type,dmg.dmg_lv,tick);
 		if( damage > 0 ) //Counter status effects [Skotlex]
 			skill_counter_additional_effect(dsrc,bl,skillid,skilllv,attack_type,tick);
 	}
@@ -1839,7 +1839,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 		//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
 		if( tsd && src != bl )
 			battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
-		skill_additional_effect(bl, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,tick);
+		skill_additional_effect(bl, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
 	}
 
 	if (!(flag&2) &&
@@ -3773,7 +3773,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case MO_BALKYOUNG: //Passive part of the attack. Splash knock-back+stun. [Skotlex]
 		if (skill_area_temp[1] != bl->id) {
 			skill_blown(src,bl,skill_get_blewcount(skillid,skilllv),-1,0);
-			skill_additional_effect(src,bl,skillid,skilllv,BF_MISC,tick); //Use Misc rather than weapon to signal passive pushback
+			skill_additional_effect(src,bl,skillid,skilllv,BF_MISC,ATK_DEF,tick); //Use Misc rather than weapon to signal passive pushback
 		}
 		break;
 
@@ -7077,7 +7077,7 @@ static int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, un
 		{
 			sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit);
 			if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
-				skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, tick);
+				skill_additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, ATK_DEF, tick);
 		}
 		break;
 
@@ -7374,12 +7374,12 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 		case UNT_LULLABY:
 			if (ss->id == bl->id)
 				break;
-			skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, tick);
+			skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, ATK_DEF, tick);
 			break;
 
 		case UNT_UGLYDANCE:	//Ugly Dance [Skotlex]
 			if (ss->id != bl->id)
-				skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, tick);
+				skill_additional_effect(ss, bl, sg->skill_id, sg->skill_lv, BF_LONG|BF_SKILL|BF_MISC, ATK_DEF, tick);
 			break;
 
 		case UNT_DISSONANCE:
@@ -9266,9 +9266,9 @@ int skill_frostjoke_scream (struct block_list *bl, va_list ap)
 	}
 	//It has been reported that Scream/Joke works the same regardless of woe-setting. [Skotlex]
 	if(battle_check_target(src,bl,BCT_ENEMY) > 0)
-		skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick);
+		skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,ATK_DEF,tick);
 	else if(battle_check_target(src,bl,BCT_PARTY) > 0 && rand()%100 < 10)
-		skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick);
+		skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,ATK_DEF,tick);
 
 	return 0;
 }
@@ -9561,7 +9561,7 @@ static int skill_trap_splash (struct block_list *bl, va_list ap)
 		case UNT_SHOCKWAVE:
 		case UNT_SANDMAN:
 		case UNT_FLASHER:
-			skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,tick);
+			skill_additional_effect(ss,bl,sg->skill_id,sg->skill_lv,BF_MISC,ATK_DEF,tick);
 			break;
 		case UNT_GROUNDDRIFT_WIND:
 			if(skill_attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))

+ 1 - 1
src/map/skill.h

@@ -261,7 +261,7 @@ int skill_cleartimerskill(struct block_list *src);
 int skill_addtimerskill(struct block_list *src,unsigned int tick,int target,int x,int y,int skill_id,int skill_lv,int type,int flag);
 
 // ’ljÁ?‰Ê
-int skill_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick);
+int skill_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,int dmg_lv,unsigned int tick);
 int skill_counter_additional_effect( struct block_list* src, struct block_list *bl,int skillid,int skilllv,int attack_type,unsigned int tick);
 int skill_blown(struct block_list* src, struct block_list* target, int count, int direction, int flag);
 int skill_break_equip(struct block_list *bl, unsigned short where, int rate, int flag);