Selaa lähdekoodia

- Moved the devotion damage reduction to the block that only executes if flag is zero in battle_damage.
- skill_castcancel won't trigger on battle_damage when the passed flag is 1
- The flag in battle_heal is now used to determine whether Berserk blocks the healing or not.
- Moved the Fusion HP penalty to battle_calc_weapon_attack
- Some cleaning to use battle_heal/damage rather than pc_heal/damage where appropiate.
- cleaned up the deadly-poison hp reduction code.


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

skotlex 19 vuotta sitten
vanhempi
commit
3b5c9e1f78
7 muutettua tiedostoa jossa 94 lisäystä ja 94 poistoa
  1. 4 0
      Changelog-Trunk.txt
  2. 55 47
      src/map/battle.c
  3. 4 0
      src/map/mob.c
  4. 1 4
      src/map/pc.c
  5. 1 1
      src/map/pet.c
  6. 17 15
      src/map/skill.c
  7. 12 27
      src/map/status.c

+ 4 - 0
Changelog-Trunk.txt

@@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2006/04/07
+	* Moved the Fusion HP penalty to battle_calc_weapon_attack  [Skotlex]
+	* Some cleaning to use battle_heal/damage rather than pc_heal/damage where
+	  appropiate. [Skotlex]
+	* Cleaned up the deadly-poison hp reduction code. [Skotlex]
 	* IRC User access levels now refresh on a mode set and join/part. [Zido]
 	* Added missing creation/destruction of the expcache_ers in guild.c
 	  [Skotlex]

+ 55 - 47
src/map/battle.c

@@ -178,22 +178,20 @@ int battle_damage(struct block_list *src,struct block_list *target,int damage, i
 
 	nullpo_retr(0, target); //srcはNULLで呼ばれることがあるので他でチェック
 	
-	sc = status_get_sc(target);
-
-	if (damage == 0 ||
-		target->prev == NULL ||
-		target->type == BL_PET)
+	if (damage == 0 || status_isdead(target))
 		return 0;
+	
+	sc = status_get_sc(target);
 
+	if (damage < 0)
+		return battle_heal(src,target,-damage,0,flag);
+	
 	if (src) {
 		if (src->prev == NULL)
 			return 0;
 		BL_CAST(BL_PC, src, sd);
 	}
 
-	if (damage < 0)
-		return battle_heal(src,target,-damage,0,flag);
-
 	if (!flag && sc && sc->count) {
 		// 凍結?A?ホ化?A?⊥ーを?チ去
 		if (sc->data[SC_FREEZE].timer != -1)
@@ -230,20 +228,22 @@ int battle_damage(struct block_list *src,struct block_list *target,int damage, i
 				status_change_end(target, SC_GRAVITATION, -1);
 			}
 		}
-	}
-
-	if (sc && sc->count && sc->data[SC_DEVOTION].val1 && src && battle_getcurrentskill(src) != PA_PRESSURE)
-	{	//Devotion only works on attacks from a source (to prevent it from absorbing coma) [Skotlex]
-		struct map_session_data *sd2 = map_id2sd(sc->data[SC_DEVOTION].val1);
-		if (sd2 && sd2->devotion[sc->data[SC_DEVOTION].val2] == target->id)
+		if (sc->data[SC_DEVOTION].val1 && src && battle_getcurrentskill(src) != PA_PRESSURE)
 		{
-			clif_damage(src, &sd2->bl, gettick(), 0, 0, damage, 0, 0, 0);
-			pc_damage(&sd2->bl, sd2, damage);
-			return 0;
-		} else
-			status_change_end(target, SC_DEVOTION, -1);
+			struct map_session_data *sd2 = map_id2sd(sc->data[SC_DEVOTION].val1);
+			if (sd2 && sd2->devotion[sc->data[SC_DEVOTION].val2] == target->id)
+			{
+				clif_damage(src, &sd2->bl, gettick(), 0, 0, damage, 0, 0, 0);
+				pc_damage(&sd2->bl, sd2, damage);
+				return 0;
+			} else
+				status_change_end(target, SC_DEVOTION, -1);
+		}
 	}
-	unit_skillcastcancel(target, 2);
+
+	if (!flag)
+		unit_skillcastcancel(target, 2);
+	
 	if (target->type == BL_MOB) {
 		return mob_damage(src,(TBL_MOB*)target, damage,0);
 	} else if (target->type == BL_PC) {
@@ -253,14 +253,29 @@ int battle_damage(struct block_list *src,struct block_list *target,int damage, i
 	return 0;
 }
 
-int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp,int flag)
+int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp, int flag)
 {
-	nullpo_retr(0, target); //blはNULLで呼ばれることがあるので他でチェック
-
+	struct status_change *sc;
+	nullpo_retr(0, target); 
 
 	if (status_isdead(target))
 		return 0;
 
+	if (!flag) {
+		sc = status_get_sc(target);
+		if (sc && sc->count) {
+			if (sc->data[SC_BERSERK].timer!=-1)
+				hp = 0;
+		}
+	}
+	
+	if (sp == 0) {
+		if (hp < 0) //Use flag 1 because heal-damage shouldn't make you flinch. 
+			return battle_damage(bl, target, -hp, 1);
+		if (hp == 0)
+			return 0;
+	}
+
 	if (target->type == BL_MOB)
 		return mob_heal((struct mob_data *)target,hp);
 	else if (target->type == BL_PC)
@@ -1383,7 +1398,7 @@ static struct Damage battle_calc_weapon_attack(
 			case PA_SACRIFICE:
 			{
 				int hp_dmg = status_get_max_hp(src)* 9/100;
-				battle_damage(src, src, hp_dmg, 0); //Damage to self is always 9%
+				battle_damage(src, src, hp_dmg, 1); //Damage to self is always 9%
 				clif_damage(src,src, gettick(), 0, 0, hp_dmg, 0 , 0, 0);
 				
 				wd.damage = hp_dmg;
@@ -2261,6 +2276,19 @@ static struct Damage battle_calc_weapon_attack(
 		}
 	}
 
+	//SG_FUSION hp penalty [Komurka]
+	if (sc && sc->data[SC_FUSION].timer!=-1)
+	{
+		int hp= status_get_max_hp(src);
+		if (sd && tsd) {
+			hp = 8*hp/100;
+			if (100*sd->status.hp <= 20*sd->status.max_hp)
+				hp = sd->status.hp;
+		} else
+			hp = 5*hp/1000;
+		battle_damage(NULL, src, hp, 1);
+	}
+
 	return wd;
 }
 
@@ -3135,7 +3163,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
 					f = skill_castend_damage_id(src, target, skillid, skilllv, tick, flag);
 					break;
 			}
-			if (sd && !f) { pc_heal(sd, 0, -sp); }
+			if (sd && !f) { pc_damage_sp(sd, sp, 0); }
 		}
 	}
 	if (sd) {
@@ -3173,15 +3201,10 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
 			}
 
 			if (tsd && sd->sp_drain_type)
-				pc_heal(tsd, 0, -sp);
+				pc_damage_sp(tsd, sp, 0);
 
 			if (tsd && rand()%1000 < sd->sp_vanish_rate)
-			{
-				sp = tsd->status.sp * sd->sp_vanish_per/100;
-				if (sp > 0)
-					pc_heal(tsd, 0, -sp);
-
-			}
+				pc_damage_sp(tsd, 0, sd->sp_vanish_per);
 		}
 	}
 	if (rdamage > 0) //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
@@ -3203,21 +3226,6 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
 				status_change_end(target, SC_POISONREACT, -1);
 		}
 	}
-
-	//SG_FUSION hp penalty [Komurka]
-	if (sd && sc && sc->data[SC_FUSION].timer!=-1)
-	{
-		int hp=0;
-		if(target->type == BL_PC)
-		{
-			hp = sd->status.max_hp * 8 / 100;
-			if((sd->status.hp * 100/sd->status.max_hp) <= 20)
-				hp = sd->status.hp;
-		}else
-			hp = sd->status.max_hp * 5 / 1000;
-		pc_heal(sd,-hp,0);
-	}
-
 	map_freeblock_unlock();
 	return wd.dmg_lv;
 }

+ 4 - 0
src/map/mob.c

@@ -2412,6 +2412,10 @@ int mob_heal(struct mob_data *md,int heal)
 	md->hp += heal;
 	if( max_hp < md->hp )
 		md->hp = max_hp;
+	else if (md->hp <= 0) {
+		md->hp = 1;
+		return mob_damage(NULL, md, 1, 0);
+	}
 
 	if(md->guardian_data && md->guardian_data->number < MAX_GUARDIANS) { // guardian hp update [Valaris] (updated by [Skotlex])
 		if ((md->guardian_data->castle->guardian[md->guardian_data->number].hp = md->hp) <= 0)

+ 1 - 4
src/map/pc.c

@@ -5248,9 +5248,6 @@ int pc_heal(struct map_session_data *sd,int hp,int sp)
 //	if(sp > 0 && pc_checkoversp(sd))
 //		sp = 0;
 
-	if(sd->sc.count && sd->sc.data[SC_BERSERK].timer!=-1 && hp+sp>0)
-		return 0;
-
 	if(hp > sd->status.max_hp - sd->status.hp)
 		hp = sd->status.max_hp - sd->status.hp;
 	sd->status.hp+=hp;
@@ -6407,7 +6404,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
 			hp = sd->status.hp;
 		if (sp > sd->status.sp)
 			sp = sd->status.sp;
-		pc_heal(sd,-hp,-sp);
+		pc_heal(sd, -hp, -sp);
 	}
 
 	return 0;

+ 1 - 1
src/map/pet.c

@@ -1269,7 +1269,7 @@ int pet_heal_timer(int tid,unsigned int tick,int id,int data)
 	pet_stop_attack(pd);
 	pet_stop_walking(pd,1);
 	clif_skill_nodamage(&pd->bl,&sd->bl,AL_HEAL,pd->s_skill->lv,1);
-	pc_heal(sd,pd->s_skill->lv,0);
+	battle_heal(&pd->bl, &sd->bl, pd->s_skill->lv,0, 0);
 	pd->s_skill->timer=add_timer(tick+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0);
 	return 0;
 }

+ 17 - 15
src/map/skill.c

@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <limits.h>
 
 #include "../common/timer.h"
 #include "../common/nullpo.h"
@@ -1165,7 +1166,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		if(dstsd) {
 			int sp = dstsd->status.max_sp*(10+skilllv)/100;
 			if(sp < 1) sp = 1;
-			pc_heal(dstsd,0,-sp);
+			pc_damage_sp(dstsd,sp,0);
 		}
 		break;
 	// Equipment breaking monster skills [Celest]
@@ -2031,8 +2032,8 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
 		}
 		if(hp || sp)
 			pc_heal(sd,hp,sp);
-		if (sd->sp_drain_type && bl->type == BL_PC)
-			battle_heal(NULL,bl,0,-sp,0);
+		if (sd->sp_drain_type && tsd)
+			pc_damage_sp(tsd,sp,0);
 	}
 
 	if (rdamage>0) {
@@ -3448,8 +3449,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
 		if (status_isimmune(bl))
 			break;
-		if (dstsd) pc_heal (dstsd, dstsd->status.max_hp, dstsd->status.max_sp);
-		else if (dstmd) dstmd->hp = status_get_max_hp(bl);
+		battle_heal(src, bl, status_get_max_hp(bl), dstsd?dstsd->status.max_sp:0,0);
 		break;
 	case SA_SUMMONMONSTER:
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -3461,7 +3461,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 		break;
 	case SA_INSTANTDEATH:
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		battle_damage(NULL,src,status_get_hp(src)-1,0);
+		battle_damage(NULL,src,status_get_hp(src)-1,1);
 		break;
 	case SA_QUESTION:
 	case SA_GRAVITY:
@@ -4036,7 +4036,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			skill_get_splash(skillid, skilllv), BL_CHAR,
 			src, skillid, skilllv, tick, flag|BCT_ENEMY,
 			skill_castend_damage_id);
-		battle_damage(src, src, status_get_max_hp(src), 0);
+		battle_damage(src, src, status_get_max_hp(src), 1);
 		break;
 
 	/* パ?ティスキル */
@@ -4703,7 +4703,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				if(dstsd) {
 					sp = skill_get_sp(skillid,skilllv);
 					sp = sp * tsc->data[SC_MAGICROD].val2 / 100;
-					if(sp > 0x7fff) sp = 0x7fff;
+					if(sp > SHRT_MAX) sp = SHRT_MAX;
 					else if(sp < 1) sp = 1;
 					clif_heal(dstsd->fd,SP_SP,pc_heal(dstsd, 0, sp));
 				}
@@ -4711,7 +4711,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				if(sd) {
 					sp = sd->status.max_sp/5;
 					if(sp < 1) sp = 1;
-					pc_heal(sd,0,-sp);
+					pc_damage_sp(sd,sp,0);
 				}
 			} else {
 				struct unit_data *ud = unit_bl2ud(bl);
@@ -4732,11 +4732,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				clif_skill_nodamage(src,bl,skillid,skilllv,1);
 				unit_skillcastcancel(bl,0);
 				sp = skill_get_sp(bl_skillid,bl_skilllv);
-				battle_heal(NULL, bl, -hp, -sp, 0);
+				if (dstsd)
+					pc_damage_sp(dstsd, sp, 0);
+				battle_damage(NULL, bl, hp, 1);
 				if(sd && sp) {
 					sp = sp*(25*(skilllv-1))/100;
 					if(skilllv > 1 && sp < 1) sp = 1;
-					else if(sp > 0x7fff) sp = 0x7fff;
+					else if(sp > SHRT_MAX) sp = SHRT_MAX;
 					clif_heal(sd->fd,SP_SP,pc_heal(sd, 0, sp));
 				}
 				if (hp && skilllv >= 5)
@@ -4865,7 +4867,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				clif_skill_nodamage(src,bl,skillid,skilllv,0);
 				break;
 			}
-			pc_heal(dstsd,0,-100);
+			pc_damage_sp(dstsd,100,0);
 		}
 		clif_skill_nodamage(src,bl,skillid,skilllv,
 			sc_start(bl,type,(skilllv*5),skilllv,skill_get_time2(skillid,skilllv)));
@@ -4873,7 +4875,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 
 	case NPC_SUICIDE:			/* 自決 */
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
-		battle_damage(NULL,src,status_get_hp(bl),3); //Suicidal Mobs should give neither exp (flag&1) not items (flag&2) [Skotlex]
+		battle_damage(NULL, src,status_get_hp(src),3); //Suicidal Mobs should give neither exp (flag&1) not items (flag&2) [Skotlex]
 		break;
 
 	case NPC_SUMMONSLAVE:		/* 手下?「喚 */
@@ -5271,7 +5273,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 				switch (eff)
 				{
 				case 0:	// heals SP to 0
-					if (dstsd) pc_heal(dstsd,0,-dstsd->status.sp);
+					if (dstsd) pc_damage_sp(dstsd,0,100);
 					break;
 				case 1:	// matk halved
 					sc_start(bl,SC_INCMATKRATE,100,-50,skill_get_time2(skillid,skilllv));
@@ -10242,7 +10244,7 @@ int skill_produce_mix( struct map_session_data *sd, int skill_id,
 	} else {
 		switch (skill_id) {
 			case ASC_CDP: //Damage yourself, and display same effect as failed potion.
-				pc_heal(sd,-(sd->status.max_hp>>2),0);
+				battle_damage(NULL, &sd->bl, sd->status.max_hp>>2, 1);
 			case AM_PHARMACY:
 			case AM_TWILIGHT1:
 			case AM_TWILIGHT2:

+ 12 - 27
src/map/status.c

@@ -4113,21 +4113,12 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 			int hp = status_get_hp(bl);
 			int mhp = status_get_max_hp(bl);
 
-			// MHP?1/4????????
+			//Lose 10/15% of your life as long as it doesn't brings life below 25%
 			if (hp > mhp>>2) {
-				if(bl->type == BL_PC) {
-					int diff = mhp*10/100;
-					if (hp - diff < mhp>>2)
-						diff = hp - (mhp>>2);
-					pc_heal((struct map_session_data *)bl, -diff, 0);
-				} else if(bl->type == BL_MOB) {
-					struct mob_data *md = (struct mob_data *)bl;
-					hp -= mhp*15/100;
-					if (hp > mhp>>2)
-						md->hp = hp;
-					else
-						md->hp = mhp>>2;
-				}
+				int diff = mhp*(bl->type==BL_PC?10:15)/100;
+				if (hp - diff < mhp>>2)
+					diff = hp - (mhp>>2);
+				battle_damage(NULL, bl, diff, 1);
 			}
 		}	// fall through
 		case SC_POISON:				/* “Å */
@@ -4355,7 +4346,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 		}
 
 		case SC_COMA: //Coma. Sends a char to 1HP
-			battle_damage(NULL, bl, status_get_hp(bl)-1, 0);
+			battle_damage(NULL, bl, status_get_hp(bl)-1, 1);
 			return 1;
 
 		case SC_CLOSECONFINE2:
@@ -5441,7 +5432,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 			if((++sc->data[type].val4)%5 == 0 && status_get_hp(bl) > hp>>2) {
 				hp = hp/100;
 				if(hp < 1) hp = 1;
-				battle_heal(NULL, bl, -hp, 0, 0);
+				battle_damage(NULL, bl, hp, 1);
 			}
 			sc->data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
 			return 0;
@@ -5453,7 +5444,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 			break;
 	case SC_DPOISON:
 		if ((--sc->data[type].val3) > 0 && sc->data[SC_SLOWPOISON].timer == -1)
-			battle_heal(NULL, bl, -sc->data[type].val4, 0, 1);
+			battle_damage(NULL, bl, sc->data[type].val4, 1);
 		if (sc->data[type].val3 > 0 && !status_isdead(bl))
 		{
 			sc->data[type].timer = add_timer (1000 + tick, status_change_timer, bl->id, data );
@@ -5484,13 +5475,9 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 		// To-do: bleeding effect increases damage taken?
 		if ((sc->data[type].val4 -= 10000) >= 0) {
 			int hp = rand()%600 + 200;
-			battle_heal(NULL,bl,-hp,0,1);
-			if (!status_isdead(bl)) {
-				// walking and casting effect is lost
-				unit_stop_walking (bl, 1);
-				unit_skillcastcancel (bl, 2);
+			battle_damage(NULL,bl,hp,0);
+			if (!status_isdead(bl))
 				sc->data[type].timer = add_timer(10000 + tick, status_change_timer, bl->id, data );
-			}
 			return 0;
 		}
 		break;
@@ -5655,10 +5642,8 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 				(sd == NULL || sd->status.sp - sp> 0))
 			{
 				if (sd)
-					pc_heal(sd,-hp,-sp);
-				else if (bl->type == BL_MOB)
-					mob_heal((struct mob_data *)bl,-hp);
-					
+					pc_damage_sp(sd, sp, 0);
+				battle_damage(NULL, bl, hp, 1);
 				if ((sc->data[type].val2 -= 10000) > 0) {
 					sc->data[type].timer = add_timer(
 					10000+tick, status_change_timer,