Implemented the official effect of Vellum Vanish (fixes #900 and fixes #1021)

* The Vellum Vanish bonus only refers to bHPVanishRaceRate and bSPVanishRaceRate.
* Requires client 2013-03-20 and newer to display blue damage.
* Properly displays blue damage being done for SP Vellum Vanish.
* Vellum Vanish items no longer deal physical damage except on skill usage.
* Skill usage with Vellum Vanish does not cause vanish.
* HP and SP Vellum Vanish items do not stack (SP will override HP).
This commit is contained in:
aleos89 2016-03-23 14:25:58 -04:00
parent 1c055f923c
commit 6dc437fd08
8 changed files with 128 additions and 76 deletions

View File

@ -1166,7 +1166,7 @@ ACMD_FUNC(heal)
if ( hp < 0 && sp <= 0 ) { if ( hp < 0 && sp <= 0 ) {
status_damage(NULL, &sd->bl, -hp, -sp, 0, 0); status_damage(NULL, &sd->bl, -hp, -sp, 0, 0);
clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, DMG_ENDURE, 0); clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, DMG_ENDURE, 0, false);
clif_displaymessage(fd, msg_txt(sd,156)); // HP or/and SP modified. clif_displaymessage(fd, msg_txt(sd,156)); // HP or/and SP modified.
return 0; return 0;
} }
@ -1177,7 +1177,7 @@ ACMD_FUNC(heal)
status_heal(&sd->bl, hp, 0, 0); status_heal(&sd->bl, hp, 0, 0);
else { else {
status_damage(NULL, &sd->bl, -hp, 0, 0, 0); status_damage(NULL, &sd->bl, -hp, 0, 0, 0);
clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, DMG_ENDURE, 0); clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, DMG_ENDURE, 0, false);
} }
} }

View File

@ -254,11 +254,15 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int
* @param dmg_lv: State of the attack (miss, etc.) * @param dmg_lv: State of the attack (miss, etc.)
* @param attack_type: Type of the attack (BF_NORMAL|BF_SKILL|BF_SHORT|BF_LONG|BF_WEAPON|BF_MAGIC|BF_MISC) * @param attack_type: Type of the attack (BF_NORMAL|BF_SKILL|BF_SHORT|BF_LONG|BF_WEAPON|BF_MAGIC|BF_MISC)
* @param additional_effects: Whether additional effect should be applied * @param additional_effects: Whether additional effect should be applied
* @param isspdamage: If the damage is done to SP
* @param tick: Current tick * @param tick: Current tick
*------------------------------------------*/ *------------------------------------------*/
void battle_damage(struct block_list *src, struct block_list *target, int64 damage, int delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, unsigned int tick) { void battle_damage(struct block_list *src, struct block_list *target, int64 damage, int delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, unsigned int tick, bool isspdamage) {
map_freeblock_lock(); map_freeblock_lock();
status_fix_damage(src, target, damage, delay); // We have to separate here between reflect damage and others [icescope] if (isspdamage)
status_fix_spdamage(src, target, damage, delay);
else
status_fix_damage(src, target, damage, delay); // We have to separate here between reflect damage and others [icescope]
if (attack_type && !status_isdead(target) && additional_effects) if (attack_type && !status_isdead(target) && additional_effects)
skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, tick); skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, tick);
if (dmg_lv > ATK_BLOCK && attack_type) if (dmg_lv > ATK_BLOCK && attack_type)
@ -285,6 +289,7 @@ struct delay_damage {
unsigned short attack_type; unsigned short attack_type;
bool additional_effects; bool additional_effects;
enum bl_type src_type; enum bl_type src_type;
bool isspdamage;
}; };
int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data)
@ -312,7 +317,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data)
check_distance_bl(src, target, dat->distance) ) //Check to see if you haven't teleported. [Skotlex] check_distance_bl(src, target, dat->distance) ) //Check to see if you haven't teleported. [Skotlex]
{ {
//Deal damage //Deal damage
battle_damage(src, target, dat->damage, dat->delay, dat->skill_lv, dat->skill_id, dat->dmg_lv, dat->attack_type, dat->additional_effects, tick); battle_damage(src, target, dat->damage, dat->delay, dat->skill_lv, dat->skill_id, dat->dmg_lv, dat->attack_type, dat->additional_effects, tick, dat->isspdamage);
} else if( !src && dat->skill_id == CR_REFLECTSHIELD ) { // it was monster reflected damage, and the monster died, we pass the damage to the character as expected } else if( !src && dat->skill_id == CR_REFLECTSHIELD ) { // it was monster reflected damage, and the monster died, we pass the damage to the character as expected
map_freeblock_lock(); map_freeblock_lock();
status_fix_damage(target, target, dat->damage, dat->delay); status_fix_damage(target, target, dat->damage, dat->delay);
@ -328,7 +333,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data)
return 0; return 0;
} }
int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects, bool isspdamage)
{ {
struct delay_damage *dat; struct delay_damage *dat;
struct status_change *sc; struct status_change *sc;
@ -353,7 +358,7 @@ int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src,
if ( !battle_config.delay_battle_damage || amotion <= 1 ) { if ( !battle_config.delay_battle_damage || amotion <= 1 ) {
//Deal damage //Deal damage
battle_damage(src, target, damage, ddelay, skill_lv, skill_id, dmg_lv, attack_type, additional_effects, gettick()); battle_damage(src, target, damage, ddelay, skill_lv, skill_id, dmg_lv, attack_type, additional_effects, gettick(), isspdamage);
return 0; return 0;
} }
dat = ers_alloc(delay_damage_ers, struct delay_damage); dat = ers_alloc(delay_damage_ers, struct delay_damage);
@ -368,6 +373,7 @@ int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src,
dat->distance = distance_bl(src, target) + (battle_config.snap_dodge ? 10 : AREA_SIZE); dat->distance = distance_bl(src, target) + (battle_config.snap_dodge ? 10 : AREA_SIZE);
dat->additional_effects = additional_effects; dat->additional_effects = additional_effects;
dat->src_type = src->type; dat->src_type = src->type;
dat->isspdamage = isspdamage;
if (src->type != BL_PC && amotion > 1000) if (src->type != BL_PC && amotion > 1000)
amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex] amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
@ -4893,11 +4899,11 @@ struct Damage battle_calc_attack_gvg_bg(struct Damage wd, struct block_list *src
if( rdamage > 0 ) { //Item reflect gets calculated before any mapflag reducing is applicated if( rdamage > 0 ) { //Item reflect gets calculated before any mapflag reducing is applicated
struct block_list *d_bl = battle_check_devotion(src); struct block_list *d_bl = battle_check_devotion(src);
rdelay = clif_damage(src, (!d_bl) ? src : d_bl, tick, wd.amotion, sstatus->dmotion, rdamage, 1, DMG_ENDURE, 0); rdelay = clif_damage(src, (!d_bl) ? src : d_bl, tick, wd.amotion, sstatus->dmotion, rdamage, 1, DMG_ENDURE, 0, false);
if( tsd ) if( tsd )
battle_drain(tsd, src, rdamage, rdamage, sstatus->race, sstatus->class_, is_infinite_defense(src,wd.flag)); battle_drain(tsd, src, rdamage, rdamage, sstatus->race, sstatus->class_);
//Use Reflect Shield to signal this kind of skill trigger [Skotlex] //Use Reflect Shield to signal this kind of skill trigger [Skotlex]
battle_delay_damage(tick, wd.amotion, target, (!d_bl) ? src : d_bl, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay, true); battle_delay_damage(tick, wd.amotion, target, (!d_bl) ? src : d_bl, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay, true, false);
skill_additional_effect(target, (!d_bl) ? src : d_bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL, ATK_DEF, tick); skill_additional_effect(target, (!d_bl) ? src : d_bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL, ATK_DEF, tick);
} }
} }
@ -4961,7 +4967,7 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
) )
{ {
ATK_RATER(wd.damage, 50) ATK_RATER(wd.damage, 50)
status_fix_damage(target,src,wd.damage,clif_damage(target,src,gettick(),0,0,wd.damage,0,DMG_NORMAL,0)); status_fix_damage(target,src,wd.damage,clif_damage(target,src,gettick(),0,0,wd.damage,0,DMG_NORMAL,0,false));
clif_skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1); clif_skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1);
if( --(tsc->data[SC_REJECTSWORD]->val3) <= 0 ) if( --(tsc->data[SC_REJECTSWORD]->val3) <= 0 )
status_change_end(target, SC_REJECTSWORD, INVALID_TIMER); status_change_end(target, SC_REJECTSWORD, INVALID_TIMER);
@ -4977,7 +4983,7 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
skill_blown(target, src, skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), 0); skill_blown(target, src, skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1), unit_getdir(src), 0);
clif_skill_damage(target, src, gettick(), status_get_amotion(src), 0, rdamage, clif_skill_damage(target, src, gettick(), status_get_amotion(src), 0, rdamage,
1, SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does 1, SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
clif_damage(src, target, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, DMG_NORMAL, 0); clif_damage(src, target, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, DMG_NORMAL, 0, false);
status_damage(target, src, rdamage, 0, 0, 0); status_damage(target, src, rdamage, 0, 0, 0);
status_damage(src, target, rdamage/10, 0, 0, 1); status_damage(src, target, rdamage/10, 0, 0, 1);
status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER); status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER);
@ -5160,11 +5166,11 @@ void battle_do_reflect(int attack_type, struct Damage *wd, struct block_list* sr
if( attack_type == BF_WEAPON && tsc->data[SC_REFLECTDAMAGE] ) // Don't reflect your own damage (Grand Cross) if( attack_type == BF_WEAPON && tsc->data[SC_REFLECTDAMAGE] ) // Don't reflect your own damage (Grand Cross)
map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd->amotion,sstatus->dmotion,rdamage,wd->flag); map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd->amotion,sstatus->dmotion,rdamage,wd->flag);
else if( attack_type == BF_WEAPON || attack_type == BF_MISC) { else if( attack_type == BF_WEAPON || attack_type == BF_MISC) {
rdelay = clif_damage(src, (!d_bl) ? src : d_bl, tick, wd->amotion, sstatus->dmotion, rdamage, 1, DMG_ENDURE, 0); rdelay = clif_damage(src, (!d_bl) ? src : d_bl, tick, wd->amotion, sstatus->dmotion, rdamage, 1, DMG_ENDURE, 0, false);
if( tsd ) if( tsd )
battle_drain(tsd, src, rdamage, rdamage, sstatus->race, sstatus->class_, is_infinite_defense(src,wd->flag)); battle_drain(tsd, src, rdamage, rdamage, sstatus->race, sstatus->class_);
// It appears that official servers give skill reflect damage a longer delay // It appears that official servers give skill reflect damage a longer delay
battle_delay_damage(tick, wd->amotion, target, (!d_bl) ? src : d_bl, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay ,true); battle_delay_damage(tick, wd->amotion, target, (!d_bl) ? src : d_bl, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay ,true, false);
skill_additional_effect(target, (!d_bl) ? src : d_bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL, ATK_DEF, tick); skill_additional_effect(target, (!d_bl) ? src : d_bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL, ATK_DEF, tick);
} }
} }
@ -6786,12 +6792,69 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
return cap_value(min(rdamage,max_damage),INT_MIN,INT_MAX); return cap_value(min(rdamage,max_damage),INT_MIN,INT_MAX);
} }
/**
* Calculate vanish from target
* @param sd: Player with vanish item
* @param target: Target to vanish HP/SP
* @param wd: Reference to Damage struct
*/
void battle_vanish(struct map_session_data *sd, struct block_list *target, struct Damage *wd)
{
struct status_data *tstatus;
int hp = 0, sp = 0, race = status_get_race(target);
short vrate_hp = 0, vrate_sp = 0, v_hp = 0, v_sp = 0;
uint8 i = 0;
nullpo_retv(sd);
nullpo_retv(target);
tstatus = status_get_status_data(target);
wd->isspdamage = false;
hp = (sd->bonus.hp_vanish_rate * 10) + sd->hp_vanish_race[race].rate + sd->hp_vanish_race[RC_ALL].rate;
vrate_hp = cap_value(hp, 0, SHRT_MAX);
hp = sd->bonus.hp_vanish_per + sd->hp_vanish_race[race].per + sd->hp_vanish_race[RC_ALL].per;
v_hp = cap_value(hp, SHRT_MIN, SHRT_MAX);
sp = (sd->bonus.sp_vanish_rate * 10) + sd->sp_vanish_race[race].rate + sd->sp_vanish_race[RC_ALL].rate;
vrate_sp = cap_value(sp, 0, SHRT_MAX);
sp = sd->bonus.sp_vanish_per + sd->sp_vanish_race[race].per + sd->sp_vanish_race[RC_ALL].per;
v_sp = cap_value(sp, SHRT_MIN, SHRT_MAX);
if (wd->flag) {
// The HP and SP vanish bonus from these items can't stack because of the special damage display.
if (v_hp && vrate_hp && (vrate_hp >= 10000 || rnd()%10000 < vrate_hp))
i = 1;
if (v_sp && vrate_sp && (vrate_sp >= 10000 || rnd()%10000 < vrate_sp))
i = 2;
if (i == 1) {
wd->damage = apply_rate(tstatus->max_hp, v_hp);
wd->damage2 = 0;
}
if (i == 2) {
wd->damage = apply_rate(tstatus->max_sp, v_sp);
wd->damage2 = 0;
wd->isspdamage = true;
}
} else {
if (v_hp && vrate_hp && (vrate_hp >= 10000 || rnd()%10000 < vrate_hp))
i |= 1;
if (v_sp && vrate_sp && (vrate_sp >= 10000 || rnd()%10000 < vrate_sp))
i |= 2;
if (i)
status_percent_damage(&sd->bl, target, (i&1) ? (int8)(-v_hp) : 0, (i&2) ? (int8)(-v_sp) : 0, false);
}
}
/*=========================================== /*===========================================
* Perform battle drain effects (HP/SP loss) * Perform battle drain effects (HP/SP loss)
*-------------------------------------------*/ *-------------------------------------------*/
void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int class_, bool infdef) void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int class_)
{ {
struct weapon_data *wd; struct weapon_data *wd;
struct Damage d;
int64 *damage; int64 *damage;
int thp = 0, // HP gained int thp = 0, // HP gained
tsp = 0, // SP gained tsp = 0, // SP gained
@ -6799,32 +6862,14 @@ void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rda
//rsp = 0, // SP reduced from target //rsp = 0, // SP reduced from target
hp = 0, sp = 0; hp = 0, sp = 0;
uint8 i = 0; uint8 i = 0;
short vrate_hp = 0, vrate_sp = 0, v_hp = 0, v_sp = 0;
if (!CHK_RACE(race) && !CHK_CLASS(class_)) if (!CHK_RACE(race) && !CHK_CLASS(class_))
return; return;
memset(&d, 0, sizeof(d));
// Check for vanish HP/SP. !CHECKME: Which first, drain or vanish? // Check for vanish HP/SP. !CHECKME: Which first, drain or vanish?
hp = (sd->bonus.hp_vanish_rate*10) + sd->hp_vanish_race[race].rate + sd->hp_vanish_race[RC_ALL].rate; battle_vanish(sd, tbl, &d);
vrate_hp = cap_value(hp, 0, SHRT_MAX);
hp = sd->bonus.hp_vanish_per + sd->hp_vanish_race[race].per + sd->hp_vanish_race[RC_ALL].per;
v_hp = cap_value(hp, SHRT_MIN, SHRT_MAX);
sp = (sd->bonus.sp_vanish_rate*10) + sd->sp_vanish_race[race].rate + sd->sp_vanish_race[RC_ALL].rate;
vrate_sp = cap_value(sp, 0, SHRT_MAX);
sp = sd->bonus.sp_vanish_per + sd->sp_vanish_race[race].per + sd->sp_vanish_race[RC_ALL].per;
v_sp = cap_value(sp, INT8_MIN, INT8_MAX);
if (v_hp > 0 && vrate_hp > 0 && (vrate_hp >= 10000 || rnd()%10000 < vrate_hp))
i |= 1;
if (v_sp > 0 && vrate_sp > 0 && (vrate_sp >= 10000 || rnd()%10000 < vrate_sp))
i |= 2;
if (i) {
if (infdef)
status_zap(tbl, v_hp ? v_hp/100 : 0, v_sp ? v_sp/100 : 0);
else
status_percent_damage(&sd->bl, tbl, (i&1 ? (int8)(-v_hp): 0), (i&2 ? (int8)(-v_sp) : 0), false);
}
// Check for drain HP/SP // Check for drain HP/SP
hp = sp = i = 0; hp = sp = i = 0;
@ -6908,12 +6953,12 @@ int battle_damage_area(struct block_list *bl, va_list ap) {
if( bl != src && battle_check_target(src,bl,BCT_ENEMY) > 0 ) { if( bl != src && battle_check_target(src,bl,BCT_ENEMY) > 0 ) {
map_freeblock_lock(); map_freeblock_lock();
if( src->type == BL_PC ) if( src->type == BL_PC )
battle_drain((TBL_PC*)src, bl, damage, damage, status_get_race(bl), status_get_class_(bl), is_infinite_defense(bl,flag)); battle_drain((TBL_PC*)src, bl, damage, damage, status_get_race(bl), status_get_class_(bl));
if( amotion ) if( amotion )
battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true); battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true,false);
else else
status_fix_damage(src,bl,damage,0); status_fix_damage(src,bl,damage,0);
clif_damage(bl,bl,tick,amotion,dmotion,damage,1,DMG_ENDURE,0); clif_damage(bl,bl,tick,amotion,dmotion,damage,1,DMG_ENDURE,0,false);
skill_additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); skill_additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
map_freeblock_unlock(); map_freeblock_unlock();
} }
@ -7007,7 +7052,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
uint16 skill_lv = tsc->data[SC_AUTOCOUNTER]->val1; uint16 skill_lv = tsc->data[SC_AUTOCOUNTER]->val1;
clif_skillcastcancel(target); //Remove the casting bar. [Skotlex] clif_skillcastcancel(target); //Remove the casting bar. [Skotlex]
clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, DMG_NORMAL, 0); //Display MISS. clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, DMG_NORMAL, 0, false); //Display MISS.
status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER); status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0); skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0);
return ATK_BLOCK; return ATK_BLOCK;
@ -7021,7 +7066,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER); status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
if(sc_start4(src,src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) if(sc_start4(src,src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration))
{ //Target locked. { //Target locked.
clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, DMG_NORMAL, 0); //Display MISS. clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, DMG_NORMAL, 0, false); //Display MISS.
clif_bladestop(target, src->id, 1); clif_bladestop(target, src->id, 1);
sc_start4(src,target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration); sc_start4(src,target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
return ATK_BLOCK; return ATK_BLOCK;
@ -7101,6 +7146,9 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag); wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag);
if (sd && wd.damage + wd.damage2 > 0)
battle_vanish(sd, target, &wd);
if( sc && sc->count ) { if( sc && sc->count ) {
if (sc->data[SC_EXEEDBREAK]) { if (sc->data[SC_EXEEDBREAK]) {
wd.damage *= sc->data[SC_EXEEDBREAK]->val2 / 100; wd.damage *= sc->data[SC_EXEEDBREAK]->val2 / 100;
@ -7143,7 +7191,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
} }
} }
wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , (enum e_damage_type)wd.type, wd.damage2); wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , (enum e_damage_type)wd.type, wd.damage2, wd.isspdamage);
if (sd && sd->bonus.splash_range > 0 && damage > 0) if (sd && sd->bonus.splash_range > 0 && damage > 0)
skill_castend_damage_id(src, target, 0, 1, tick, 0); skill_castend_damage_id(src, target, 0, 1, tick, 0);
@ -7168,7 +7216,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if( wd.dmg_lv > ATK_BLOCK ) if( wd.dmg_lv > ATK_BLOCK )
skill_counter_additional_effect(src, target, 0, 0, wd.flag, tick); skill_counter_additional_effect(src, target, 0, 0, wd.flag, tick);
} else } else
battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true); battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true, wd.isspdamage);
if( tsc ) { if( tsc ) {
if( tsc->data[SC_DEVOTION] ) { if( tsc->data[SC_DEVOTION] ) {
struct status_change_entry *sce = tsc->data[SC_DEVOTION]; struct status_change_entry *sce = tsc->data[SC_DEVOTION];
@ -7179,7 +7227,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
(d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id) (d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id)
) && check_distance_bl(target, d_bl, sce->val3) ) ) && check_distance_bl(target, d_bl, sce->val3) )
{ {
clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, DMG_NORMAL, 0); clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, DMG_NORMAL, 0, false);
status_fix_damage(NULL, d_bl, damage, 0); status_fix_damage(NULL, d_bl, damage, 0);
} }
else else
@ -7197,7 +7245,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1); struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1);
if (e_bl && !status_isdead(e_bl)) { if (e_bl && !status_isdead(e_bl)) {
clif_damage(e_bl, e_bl, tick, 0, 0, damage, wd.div_, DMG_NORMAL, 0); clif_damage(e_bl, e_bl, tick, 0, 0, damage, wd.div_, DMG_NORMAL, 0, false);
status_fix_damage(NULL, e_bl, damage, 0); status_fix_damage(NULL, e_bl, damage, 0);
} }
} }
@ -7305,9 +7353,9 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if (wd.flag & BF_WEAPON && src != target && damage > 0) { if (wd.flag & BF_WEAPON && src != target && damage > 0) {
if (battle_config.left_cardfix_to_right) if (battle_config.left_cardfix_to_right)
battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, tstatus->class_, is_infinite_defense(target,wd.flag)); battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, tstatus->class_);
else else
battle_drain(sd, target, wd.damage, wd.damage2, tstatus->race, tstatus->class_, is_infinite_defense(target,wd.flag)); battle_drain(sd, target, wd.damage, wd.damage2, tstatus->race, tstatus->class_);
} }
} }

View File

@ -69,6 +69,7 @@ struct Damage {
int flag; /// chk e_battle_flag int flag; /// chk e_battle_flag
int miscflag; int miscflag;
enum damage_lv dmg_lv; /// ATK_LUCKY,ATK_FLEE,ATK_DEF enum damage_lv dmg_lv; /// ATK_LUCKY,ATK_FLEE,ATK_DEF
bool isspdamage; /// Display blue damage numbers in clif_damage
}; };
//(Used in read pc.c,) attribute table (battle_attr_fix) //(Used in read pc.c,) attribute table (battle_attr_fix)
@ -85,7 +86,8 @@ struct Damage battle_calc_attack_plant(struct Damage wd, struct block_list *src,
int64 battle_calc_return_damage(struct block_list *bl, struct block_list *src, int64 *, int flag, uint16 skill_id, bool status_reflect); int64 battle_calc_return_damage(struct block_list *bl, struct block_list *src, int64 *, int flag, uint16 skill_id, bool status_reflect);
void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int class_, bool infdef); void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int class_);
void battle_vanish(struct map_session_data *sd, struct block_list *target, struct Damage *wd);
int battle_attr_ratio(int atk_elem,int def_type, int def_lv); int battle_attr_ratio(int atk_elem,int def_type, int def_lv);
int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv); int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv);
@ -96,8 +98,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag); int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag);
int64 battle_calc_bg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag); int64 battle_calc_bg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag);
void battle_damage(struct block_list *src, struct block_list *target, int64 damage, int delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, unsigned int tick); void battle_damage(struct block_list *src, struct block_list *target, int64 damage, int delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, unsigned int tick, bool spdamage);
int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects); int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects, bool spdamage);
// Summary normal attack treatment (basic attack) // Summary normal attack treatment (basic attack)
enum damage_lv battle_weapon_attack( struct block_list *bl,struct block_list *target,unsigned int tick,int flag); enum damage_lv battle_weapon_attack( struct block_list *bl,struct block_list *target,unsigned int tick,int flag);

View File

@ -4663,7 +4663,7 @@ static int clif_calc_walkdelay(struct block_list *bl,int delay, char type, int64
/// 10 = critical hit /// 10 = critical hit
/// 11 = lucky dodge /// 11 = lucky dodge
/// 12 = (touch skill?) /// 12 = (touch skill?)
int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 sdamage, int div, enum e_damage_type type, int64 sdamage2) int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 sdamage, int div, enum e_damage_type type, int64 sdamage2, bool spdamage)
{ {
unsigned char buf[34]; unsigned char buf[34];
struct status_change *sc; struct status_change *sc;
@ -4711,7 +4711,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
#endif #endif
} }
#if PACKETVER >= 20131223 #if PACKETVER >= 20131223
WBUFB(buf,26) = 0; // IsSPDamage - Displays blue digits. Need a way to handle this. [Rytech] WBUFB(buf,26) = (spdamage) ? 1 : 0; // IsSPDamage - Displays blue digits.
#endif #endif
WBUFW(buf,24+offset) = div; WBUFW(buf,24+offset) = div;
WBUFB(buf,26+offset) = type; WBUFB(buf,26+offset) = type;
@ -4749,7 +4749,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
*------------------------------------------*/ *------------------------------------------*/
void clif_takeitem(struct block_list* src, struct block_list* dst) void clif_takeitem(struct block_list* src, struct block_list* dst)
{ {
//clif_damage(src,dst,0,0,0,0,0,DMG_PICKUP_ITEM,0); //clif_damage(src,dst,0,0,0,0,0,DMG_PICKUP_ITEM,0,false);
unsigned char buf[32]; unsigned char buf[32];
nullpo_retv(src); nullpo_retv(src);

View File

@ -538,7 +538,7 @@ void clif_dropitem(struct map_session_data *sd,int n,int amount); //self
void clif_delitem(struct map_session_data *sd,int n,int amount, short reason); //self void clif_delitem(struct map_session_data *sd,int n,int amount, short reason); //self
void clif_updatestatus(struct map_session_data *sd,int type); //self void clif_updatestatus(struct map_session_data *sd,int type); //self
void clif_changestatus(struct map_session_data* sd,int type,int val); //area void clif_changestatus(struct map_session_data* sd,int type,int val); //area
int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 sdamage, int div, enum e_damage_type type, int64 sdamage2); // area int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 sdamage, int div, enum e_damage_type type, int64 sdamage2, bool spdamage); // area
void clif_takeitem(struct block_list* src, struct block_list* dst); void clif_takeitem(struct block_list* src, struct block_list* dst);
void clif_sitting(struct block_list* bl); void clif_sitting(struct block_list* bl);
void clif_standing(struct block_list* bl); void clif_standing(struct block_list* bl);

View File

@ -3243,7 +3243,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
case NPC_CRITICALSLASH: case NPC_CRITICALSLASH:
case TF_DOUBLE: case TF_DOUBLE:
case GS_CHAINACTION: case GS_CHAINACTION:
dmg.dmotion = clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,(enum e_damage_type)dmg.type,dmg.damage2); dmg.dmotion = clif_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,(enum e_damage_type)dmg.type,dmg.damage2,false);
break; break;
case AS_SPLASHER: case AS_SPLASHER:
@ -3393,7 +3393,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
if( dmg.flag > ATK_BLOCK ) if( dmg.flag > ATK_BLOCK )
skill_counter_additional_effect(src, bl, skill_id, skill_lv, dmg.flag, tick); skill_counter_additional_effect(src, bl, skill_id, skill_lv, dmg.flag, tick);
} else } else
battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects); battle_delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects, false);
} }
if (tsc && skill_id != PA_PRESSURE && skill_id != HW_GRAVITATION && skill_id != NPC_EVILLAND) { if (tsc && skill_id != PA_PRESSURE && skill_id != HW_GRAVITATION && skill_id != NPC_EVILLAND) {
@ -3407,7 +3407,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
) && check_distance_bl(bl, d_bl, sce->val3) ) ) && check_distance_bl(bl, d_bl, sce->val3) )
{ {
if (!rmdamage) { if (!rmdamage) {
clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, DMG_NORMAL, 0); clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, DMG_NORMAL, 0, false);
status_fix_damage(NULL, d_bl, damage, 0); status_fix_damage(NULL, d_bl, damage, 0);
} else { } else {
bool isDevotRdamage = false; bool isDevotRdamage = false;
@ -3417,7 +3417,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
// If !isDevotRdamage, reflected magics are done directly on the target not on paladin // If !isDevotRdamage, reflected magics are done directly on the target not on paladin
// This check is only for magical skill. // This check is only for magical skill.
// For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage // For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage
clif_damage(bl, (!isDevotRdamage) ? bl : d_bl, gettick(), 0, 0, damage, 0, DMG_NORMAL, 0); clif_damage(bl, (!isDevotRdamage) ? bl : d_bl, gettick(), 0, 0, damage, 0, DMG_NORMAL, 0, false);
status_fix_damage(bl, (!isDevotRdamage) ? bl : d_bl, damage, 0); status_fix_damage(bl, (!isDevotRdamage) ? bl : d_bl, damage, 0);
} }
} else { } else {
@ -3459,9 +3459,9 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
(dmg.flag&BF_MISC && (skill_id == RA_CLUSTERBOMB || skill_id == RA_FIRINGTRAP || skill_id == RA_ICEBOUNDTRAP)) ) ) (dmg.flag&BF_MISC && (skill_id == RA_CLUSTERBOMB || skill_id == RA_FIRINGTRAP || skill_id == RA_ICEBOUNDTRAP)) ) )
{ {
if (battle_config.left_cardfix_to_right) if (battle_config.left_cardfix_to_right)
battle_drain(sd, bl, dmg.damage, dmg.damage, tstatus->race, tstatus->class_, is_infinite_defense(bl,dmg.flag)); battle_drain(sd, bl, dmg.damage, dmg.damage, tstatus->race, tstatus->class_);
else else
battle_drain(sd, bl, dmg.damage, dmg.damage2, tstatus->race, tstatus->class_, is_infinite_defense(bl,dmg.flag)); battle_drain(sd, bl, dmg.damage, dmg.damage2, tstatus->race, tstatus->class_);
} }
if( damage > 0 ) { // Post-damage effects if( damage > 0 ) { // Post-damage effects
@ -4937,7 +4937,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break; break;
case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex] case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex]
// clif_skill_nodamage(src,bl,skill_id,skill_lv,0); //Can't make this one display the correct attack animation delay :/ // clif_skill_nodamage(src,bl,skill_id,skill_lv,0); //Can't make this one display the correct attack animation delay :/
clif_damage(src,bl,tick,status_get_amotion(src),0,-1,1,DMG_ENDURE,0); //Display an absorbed damage attack. clif_damage(src,bl,tick,status_get_amotion(src),0,-1,1,DMG_ENDURE,0,false); //Display an absorbed damage attack.
skill_addtimerskill(src, tick + (1000+status_get_amotion(src)), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag); skill_addtimerskill(src, tick + (1000+status_get_amotion(src)), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
break; break;
@ -8411,7 +8411,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case 3: // 1000 damage, random armor destroyed case 3: // 1000 damage, random armor destroyed
{ {
status_fix_damage(src, bl, 1000, 0); status_fix_damage(src, bl, 1000, 0);
clif_damage(src,bl,tick,0,0,1000,0,DMG_NORMAL,0); clif_damage(src,bl,tick,0,0,1000,0,DMG_NORMAL,0,false);
if( !status_isdead(bl) ) { if( !status_isdead(bl) ) {
int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT }; int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
skill_break_equip(src,bl, where[rnd()%5], 10000, BCT_ENEMY); skill_break_equip(src,bl, where[rnd()%5], 10000, BCT_ENEMY);
@ -8450,14 +8450,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case 10: // 6666 damage, atk matk halved, cursed case 10: // 6666 damage, atk matk halved, cursed
status_fix_damage(src, bl, 6666, 0); status_fix_damage(src, bl, 6666, 0);
clif_damage(src,bl,tick,0,0,6666,0,DMG_NORMAL,0); clif_damage(src,bl,tick,0,0,6666,0,DMG_NORMAL,0,false);
sc_start(src,bl,SC_INCATKRATE,100,-50,skill_get_time2(skill_id,skill_lv)); sc_start(src,bl,SC_INCATKRATE,100,-50,skill_get_time2(skill_id,skill_lv));
sc_start(src,bl,SC_INCMATKRATE,100,-50,skill_get_time2(skill_id,skill_lv)); sc_start(src,bl,SC_INCMATKRATE,100,-50,skill_get_time2(skill_id,skill_lv));
sc_start(src,bl,SC_CURSE,skill_lv,100,skill_get_time2(skill_id,skill_lv)); sc_start(src,bl,SC_CURSE,skill_lv,100,skill_get_time2(skill_id,skill_lv));
break; break;
case 11: // 4444 damage case 11: // 4444 damage
status_fix_damage(src, bl, 4444, 0); status_fix_damage(src, bl, 4444, 0);
clif_damage(src,bl,tick,0,0,4444,0,DMG_NORMAL,0); clif_damage(src,bl,tick,0,0,4444,0,DMG_NORMAL,0,false);
break; break;
case 12: // stun case 12: // stun
sc_start(src,bl,SC_STUN,100,skill_lv,5000); sc_start(src,bl,SC_STUN,100,skill_lv,5000);
@ -9938,7 +9938,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
sc_start(src,bl, type, 100, skill_lv,skill_get_time(skill_id, skill_lv)); sc_start(src,bl, type, 100, skill_lv,skill_get_time(skill_id, skill_lv));
} else if( flag&2 ) { } else if( flag&2 ) {
if( src->id != bl->id && battle_check_target(src,bl,BCT_ENEMY) > 0 ) if( src->id != bl->id && battle_check_target(src,bl,BCT_ENEMY) > 0 )
status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,DMG_NORMAL,0)); status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,DMG_NORMAL,0,false));
} else if( sd ) { } else if( sd ) {
short chance = sstatus->int_/6 + sd->status.job_level/5 + skill_lv*4; short chance = sstatus->int_/6 + sd->status.job_level/5 + skill_lv*4;
if( !sd->status.party_id || (rnd()%100 > chance)) { if( !sd->status.party_id || (rnd()%100 > chance)) {
@ -9954,7 +9954,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif_skill_nodamage(src, bl, skill_id, skill_lv, clif_skill_nodamage(src, bl, skill_id, skill_lv,
sc_start(src,src,SC_STOP,100,skill_lv,skill_get_time2(skill_id,skill_lv))); sc_start(src,src,SC_STOP,100,skill_lv,skill_get_time2(skill_id,skill_lv)));
if( flag&2 ) // Dealed here to prevent conflicts if( flag&2 ) // Dealed here to prevent conflicts
status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,DMG_NORMAL,0)); status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,DMG_NORMAL,0,false));
} }
break; break;
case WM_SONG_OF_MANA: case WM_SONG_OF_MANA:
@ -17413,7 +17413,7 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit)
return false; return false;
} }
status_damage(bl, src, damage, 0, clif_damage(src, src, gettick(), 500, 500, damage, hit, (hit > 1 ? DMG_MULTI_HIT : DMG_NORMAL), 0), 0); status_damage(bl, src, damage, 0, clif_damage(src, src, gettick(), 500, 500, damage, hit, (hit > 1 ? DMG_MULTI_HIT : DMG_NORMAL), 0, false), 0);
if( sc && sc->data[SC__SHADOWFORM] && (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) { if( sc && sc->data[SC__SHADOWFORM] && (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) {
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
if( src->type == BL_PC ) if( src->type == BL_PC )

View File

@ -11465,7 +11465,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
struct block_list* src = map_id2bl(sce->val2); struct block_list* src = map_id2bl(sce->val2);
if( tid == -1 || !src) if( tid == -1 || !src)
break; // Terminated by Damage break; // Terminated by Damage
status_fix_damage(src,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,DMG_NORMAL,0)); status_fix_damage(src,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,DMG_NORMAL,0,false));
} }
break; break;
case SC_WUGDASH: case SC_WUGDASH:
@ -12023,7 +12023,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
int64 damage = 1000 + (3 * status->max_hp) / 100; // Deals fixed (1000 + 3%*MaxHP) int64 damage = 1000 + (3 * status->max_hp) / 100; // Deals fixed (1000 + 3%*MaxHP)
map_freeblock_lock(); map_freeblock_lock();
dounlock = true; dounlock = true;
status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, 0, 1, damage, 1, DMG_NORMAL, 0)); status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, 0, 1, damage, 1, DMG_NORMAL, 0, false));
} }
break; break;
@ -12031,7 +12031,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
if (sce->val4 >= 0) { // Damage is every 10 seconds including 3%sp drain. if (sce->val4 >= 0) { // Damage is every 10 seconds including 3%sp drain.
map_freeblock_lock(); map_freeblock_lock();
dounlock = true; dounlock = true;
status_damage(bl, bl, 1, status->max_sp * 3 / 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 1, 1, DMG_NORMAL, 0), 0); status_damage(bl, bl, 1, status->max_sp * 3 / 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 1, 1, DMG_NORMAL, 0, false), 0);
} }
break; break;
@ -12083,7 +12083,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
if (sce->val4 >= 0) { if (sce->val4 >= 0) {
map_freeblock_lock(); map_freeblock_lock();
dounlock = true; dounlock = true;
status_fix_damage(bl, bl, 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 100, 1, DMG_NORMAL, 0)); status_fix_damage(bl, bl, 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 100, 1, DMG_NORMAL, 0, false));
} }
break; break;
@ -12092,7 +12092,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
int64 damage = status->vit * (sce->val1 - 3) + status->max_hp / 100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100) int64 damage = status->vit * (sce->val1 - 3) + status->max_hp / 100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
map_freeblock_lock(); map_freeblock_lock();
dounlock = true; dounlock = true;
status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, damage, 1, DMG_NORMAL, 0)); status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, damage, 1, DMG_NORMAL, 0, false));
unit_skillcastcancel(bl, 2); unit_skillcastcancel(bl, 2);
} }
break; break;
@ -12394,7 +12394,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
damage = 1; damage = 1;
else else
damage = 200 + 100 * sce->val1 + status_get_int(src); damage = 200 + 100 * sce->val1 + status_get_int(src);
status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,DMG_NORMAL,0), 0); status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,DMG_NORMAL,0,false), 0);
unit_skillcastcancel(bl,1); unit_skillcastcancel(bl,1);
if ( sc->data[type] ) { if ( sc->data[type] ) {
sc_timer_next(1000 + tick, status_change_timer, bl->id, data); sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
@ -12501,7 +12501,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
int damage = status->max_hp / 100; // Suggestion 1% each second int damage = status->max_hp / 100; // Suggestion 1% each second
if( damage >= status->hp ) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum if( damage >= status->hp ) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
map_freeblock_lock(); map_freeblock_lock();
status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,DMG_NORMAL,0)); status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,DMG_NORMAL,0,false));
if( sc->data[type] ) { if( sc->data[type] ) {
sc_timer_next(1000 + tick, status_change_timer, bl->id, data); sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
} }
@ -12586,7 +12586,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
int damage = sce->val2; int damage = sce->val2;
map_freeblock_lock(); map_freeblock_lock();
clif_damage(bl, bl, tick, 0, 0, damage, 1, DMG_MULTI_HIT_ENDURE, 0); clif_damage(bl, bl, tick, 0, 0, damage, 1, DMG_MULTI_HIT_ENDURE, 0, false);
status_damage(src, bl, damage,0, 0, 1); status_damage(src, bl, damage,0, 0, 1);
if( sc->data[type] ) { if( sc->data[type] ) {
sc_timer_next(2000 + tick, status_change_timer, bl->id, data); sc_timer_next(2000 + tick, status_change_timer, bl->id, data);

View File

@ -2095,6 +2095,8 @@ int StatusIconChangeTable[SC_MAX]; /// status -> "icon" (icon is a bit
int status_damage(struct block_list *src,struct block_list *target,int64 dhp,int64 dsp, int walkdelay, int flag); int status_damage(struct block_list *src,struct block_list *target,int64 dhp,int64 dsp, int walkdelay, int flag);
//Define for standard HP damage attacks. //Define for standard HP damage attacks.
#define status_fix_damage(src, target, hp, walkdelay) status_damage(src, target, hp, 0, walkdelay, 0) #define status_fix_damage(src, target, hp, walkdelay) status_damage(src, target, hp, 0, walkdelay, 0)
//Define for standard SP damage attacks.
#define status_fix_spdamage(src, target, sp, walkdelay) status_damage(src, target, 0, sp, walkdelay, 0)
//Define for standard HP/SP damage triggers. //Define for standard HP/SP damage triggers.
#define status_zap(bl, hp, sp) status_damage(NULL, bl, hp, sp, 0, 1) #define status_zap(bl, hp, sp) status_damage(NULL, bl, hp, sp, 0, 1)
//Define for standard HP/SP skill-related cost triggers (mobs require no HP/SP to use skills) //Define for standard HP/SP skill-related cost triggers (mobs require no HP/SP to use skills)