diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 102 | ||||
-rw-r--r-- | src/map/mob.c | 4 | ||||
-rw-r--r-- | src/map/pc.c | 5 | ||||
-rw-r--r-- | src/map/pet.c | 2 | ||||
-rw-r--r-- | src/map/skill.c | 32 | ||||
-rw-r--r-- | src/map/status.c | 39 |
6 files changed, 90 insertions, 94 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index ff8a55c7f..a60c0b577 100644 --- a/src/map/battle.c +++ b/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‚ŌĂ΂ê‚邱‚Æ‚ª‚ ‚é‚Ì‚Å‘¼‚Ń`ƒFƒbƒN
- 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‚ŌĂ΂ê‚邱‚Æ‚ª‚ ‚é‚Ì‚Å‘¼‚Ń`ƒFƒbƒN
-
+ 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;
}
diff --git a/src/map/mob.c b/src/map/mob.c index 52765b47b..e917b4fd6 100644 --- a/src/map/mob.c +++ b/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)
diff --git a/src/map/pc.c b/src/map/pc.c index baf7c7dcc..a5cacfea8 100644 --- a/src/map/pc.c +++ b/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;
diff --git a/src/map/pet.c b/src/map/pet.c index 25f8274c9..c2c00e106 100644 --- a/src/map/pet.c +++ b/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;
}
diff --git a/src/map/skill.c b/src/map/skill.c index 67ca9f2f1..b94916433 100644 --- a/src/map/skill.c +++ b/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;
/* ƒp?ƒeƒBƒXƒLƒ‹ */
@@ -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:
diff --git a/src/map/status.c b/src/map/status.c index 86fc8fb29..336b9165d 100644 --- a/src/map/status.c +++ b/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,
|