- 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
This commit is contained in:
parent
8c9b7356eb
commit
3b5c9e1f78
@ -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]
|
||||
|
102
src/map/battle.c
102
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で呼ばれることがあるので他でチェック
|
||||
|
||||
if (damage == 0 || status_isdead(target))
|
||||
return 0;
|
||||
|
||||
sc = status_get_sc(target);
|
||||
|
||||
if (damage == 0 ||
|
||||
target->prev == NULL ||
|
||||
target->type == BL_PET)
|
||||
return 0;
|
||||
|
||||
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->data[SC_DEVOTION].val1 && src && battle_getcurrentskill(src) != PA_PRESSURE)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user