* 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:
parent
1c055f923c
commit
6dc437fd08
@ -1166,7 +1166,7 @@ ACMD_FUNC(heal)
|
||||
|
||||
if ( hp < 0 && sp <= 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.
|
||||
return 0;
|
||||
}
|
||||
@ -1177,7 +1177,7 @@ ACMD_FUNC(heal)
|
||||
status_heal(&sd->bl, hp, 0, 0);
|
||||
else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
138
src/map/battle.c
138
src/map/battle.c
@ -254,10 +254,14 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int
|
||||
* @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 additional_effects: Whether additional effect should be applied
|
||||
* @param isspdamage: If the damage is done to SP
|
||||
* @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();
|
||||
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)
|
||||
skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, tick);
|
||||
@ -285,6 +289,7 @@ struct delay_damage {
|
||||
unsigned short attack_type;
|
||||
bool additional_effects;
|
||||
enum bl_type src_type;
|
||||
bool isspdamage;
|
||||
};
|
||||
|
||||
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]
|
||||
{
|
||||
//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
|
||||
map_freeblock_lock();
|
||||
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;
|
||||
}
|
||||
|
||||
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 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 ) {
|
||||
//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;
|
||||
}
|
||||
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->additional_effects = additional_effects;
|
||||
dat->src_type = src->type;
|
||||
dat->isspdamage = isspdamage;
|
||||
if (src->type != BL_PC && amotion > 1000)
|
||||
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
|
||||
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 )
|
||||
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]
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -4961,7 +4967,7 @@ struct Damage battle_calc_weapon_final_atk_modifiers(struct Damage wd, struct bl
|
||||
)
|
||||
{
|
||||
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);
|
||||
if( --(tsc->data[SC_REJECTSWORD]->val3) <= 0 )
|
||||
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);
|
||||
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
|
||||
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(src, target, rdamage/10, 0, 0, 1);
|
||||
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)
|
||||
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) {
|
||||
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 )
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*-------------------------------------------*/
|
||||
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 Damage d;
|
||||
int64 *damage;
|
||||
int thp = 0, // HP 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
|
||||
hp = 0, sp = 0;
|
||||
uint8 i = 0;
|
||||
short vrate_hp = 0, vrate_sp = 0, v_hp = 0, v_sp = 0;
|
||||
|
||||
if (!CHK_RACE(race) && !CHK_CLASS(class_))
|
||||
return;
|
||||
|
||||
memset(&d, 0, sizeof(d));
|
||||
|
||||
// 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;
|
||||
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);
|
||||
}
|
||||
battle_vanish(sd, tbl, &d);
|
||||
|
||||
// Check for drain HP/SP
|
||||
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 ) {
|
||||
map_freeblock_lock();
|
||||
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 )
|
||||
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
|
||||
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);
|
||||
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;
|
||||
|
||||
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);
|
||||
skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0);
|
||||
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);
|
||||
if(sc_start4(src,src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration))
|
||||
{ //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);
|
||||
sc_start4(src,target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
|
||||
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);
|
||||
|
||||
if (sd && wd.damage + wd.damage2 > 0)
|
||||
battle_vanish(sd, target, &wd);
|
||||
|
||||
if( sc && sc->count ) {
|
||||
if (sc->data[SC_EXEEDBREAK]) {
|
||||
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)
|
||||
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 )
|
||||
skill_counter_additional_effect(src, target, 0, 0, wd.flag, tick);
|
||||
} 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->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)
|
||||
) && 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);
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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 (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
|
||||
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_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@ struct Damage {
|
||||
int flag; /// chk e_battle_flag
|
||||
int miscflag;
|
||||
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)
|
||||
@ -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);
|
||||
|
||||
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);
|
||||
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_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);
|
||||
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);
|
||||
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, bool spdamage);
|
||||
|
||||
// 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);
|
||||
|
@ -4663,7 +4663,7 @@ static int clif_calc_walkdelay(struct block_list *bl,int delay, char type, int64
|
||||
/// 10 = critical hit
|
||||
/// 11 = lucky dodge
|
||||
/// 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];
|
||||
struct status_change *sc;
|
||||
@ -4711,7 +4711,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
|
||||
#endif
|
||||
}
|
||||
#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
|
||||
WBUFW(buf,24+offset) = div;
|
||||
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)
|
||||
{
|
||||
//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];
|
||||
|
||||
nullpo_retv(src);
|
||||
|
@ -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_updatestatus(struct map_session_data *sd,int type); //self
|
||||
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_sitting(struct block_list* bl);
|
||||
void clif_standing(struct block_list* bl);
|
||||
|
@ -3243,7 +3243,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
case NPC_CRITICALSLASH:
|
||||
case TF_DOUBLE:
|
||||
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;
|
||||
|
||||
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 )
|
||||
skill_counter_additional_effect(src, bl, skill_id, skill_lv, dmg.flag, tick);
|
||||
} 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) {
|
||||
@ -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) )
|
||||
{
|
||||
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);
|
||||
} else {
|
||||
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
|
||||
// This check is only for magical skill.
|
||||
// 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);
|
||||
}
|
||||
} 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)) ) )
|
||||
{
|
||||
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
|
||||
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
|
||||
@ -4937,7 +4937,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
break;
|
||||
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_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);
|
||||
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
|
||||
{
|
||||
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) ) {
|
||||
int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
|
||||
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;
|
||||
case 10: // 6666 damage, atk matk halved, cursed
|
||||
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_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));
|
||||
break;
|
||||
case 11: // 4444 damage
|
||||
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;
|
||||
case 12: // stun
|
||||
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));
|
||||
} else if( flag&2 ) {
|
||||
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 ) {
|
||||
short chance = sstatus->int_/6 + sd->status.job_level/5 + skill_lv*4;
|
||||
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,
|
||||
sc_start(src,src,SC_STOP,100,skill_lv,skill_get_time2(skill_id,skill_lv)));
|
||||
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;
|
||||
case WM_SONG_OF_MANA:
|
||||
@ -17413,7 +17413,7 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit)
|
||||
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 ) {
|
||||
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
|
||||
if( src->type == BL_PC )
|
||||
|
@ -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);
|
||||
if( tid == -1 || !src)
|
||||
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;
|
||||
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)
|
||||
map_freeblock_lock();
|
||||
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;
|
||||
|
||||
@ -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.
|
||||
map_freeblock_lock();
|
||||
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;
|
||||
|
||||
@ -12083,7 +12083,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
if (sce->val4 >= 0) {
|
||||
map_freeblock_lock();
|
||||
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;
|
||||
|
||||
@ -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)
|
||||
map_freeblock_lock();
|
||||
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);
|
||||
}
|
||||
break;
|
||||
@ -12394,7 +12394,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
damage = 1;
|
||||
else
|
||||
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);
|
||||
if ( sc->data[type] ) {
|
||||
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
|
||||
if( damage >= status->hp ) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
|
||||
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] ) {
|
||||
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;
|
||||
|
||||
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);
|
||||
if( sc->data[type] ) {
|
||||
sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
|
||||
|
@ -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);
|
||||
//Define for standard HP damage attacks.
|
||||
#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 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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user