Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions src/map/battle.c
Original file line number Diff line number Diff line change
Expand Up @@ -7317,13 +7317,25 @@ static int battle_check_target(struct block_list *src, struct block_list *target
const struct status_change *sc = status->get_sc(src);
const struct map_session_data *t_sd = BL_UCCAST(BL_PC, target);
if (t_sd->invincible_timer != INVALID_TIMER) {
switch( battle->get_current_skill(src) ) {
/* TODO a proper distinction should be established bugreport:8397 */
case PR_SANCTUARY:
case PR_MAGNIFICAT:
break;
default:
/* unit_data::skill_id only reflects the last skill *cast* by src
* and is never cleared afterwards, so it must not be trusted for
* a plain attack (flagged explicitly by unit->attack()). */
int skill_id = (flag & BCT_NORMAL_ATTACK) != 0 ? 0 : battle->get_current_skill(src);
switch (skill_id) {
/* Equip-strip skills deal no damage but are still an offensive
* debuff on official servers, so they stay blocked. (bugreport:8397) */
case RG_STRIPWEAPON:
case RG_STRIPSHIELD:
case RG_STRIPARMOR:
case RG_STRIPHELM:
case ST_FULLSTRIP:
case SC_STRIPACCESSARY:
case GC_WEAPONCRUSH:
return -1;
default:
if ((skill->get_nk(skill_id) & NK_NO_DAMAGE) == 0)
return -1;
break;
}
}
if (pc_isinvisible(t_sd))
Expand Down
6 changes: 6 additions & 0 deletions src/map/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ enum e_battle_check_target { //New definitions [Skotlex]
BCT_NOENEMY = 0x3d0000, ///< This must be (~BCT_ENEMY&BCT_ALL)

BCT_ALL = 0x3f0000, ///< Sum of BCT_NOONE to BCT_SAMEGUILD

/// Set by unit->attack() to tell battle->check_target() this is a normal
/// attack, not a skill, so the caller's stale unit_data::skill_id (which
/// only reflects the last skill *cast*, not the current action) must not
/// be used to decide whether to bypass a target's invincible_timer.
BCT_NORMAL_ATTACK = 0x1000000,
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/map/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -2169,7 +2169,7 @@ static int unit_attack(struct block_list *src, int target_id, int continuous)
return 0;
}
}
if( battle->check_target(src,target,BCT_ENEMY) <= 0 || !status->check_skilluse(src, target, 0, 0) ) {
if (battle->check_target(src, target, BCT_ENEMY | BCT_NORMAL_ATTACK) <= 0 || !status->check_skilluse(src, target, 0, 0)) {
unit->unattackable(src);
return 1;
}
Expand Down
Loading