From 0224ba74aa451f4103974ea860815683f70c4ef7 Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 7 Apr 2006 20:23:52 +0000 Subject: - 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5949 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 102 ++++++++++++++++++++++++++++++------------------------- src/map/mob.c | 4 +++ src/map/pc.c | 5 +-- src/map/pet.c | 2 +- src/map/skill.c | 32 +++++++++-------- src/map/status.c | 39 +++++++-------------- 6 files changed, 90 insertions(+), 94 deletions(-) (limited to 'src/map') 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 #include #include +#include #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, -- cgit v1.2.3-70-g09d2