Updated Firewall cast check (#3556)
* Firewall should check at cast begin if unit max count has been reached. * Removed redundancy with the unit max count checks by merging into a single function. Thanks to @mrjnumber1!
This commit is contained in:
@@ -434,6 +434,50 @@ unsigned short skill_dummy2skill_id(unsigned short skill_id) {
|
||||
return skill_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check skill unit maxcount
|
||||
* @param src: Caster to check against
|
||||
* @param x: X location of skill
|
||||
* @param y: Y location of skill
|
||||
* @param skill_id: Skill used
|
||||
* @param skill_lv: Skill level used
|
||||
* @param type: Type of unit to check against for battle_config checks
|
||||
* @param display_failure: Display skill failure message
|
||||
* @return True on skill cast success or false on failure
|
||||
*/
|
||||
bool skill_pos_maxcount_check(struct block_list *src, int16 x, int16 y, uint16 skill_id, uint16 skill_lv, enum bl_type type, bool display_failure) {
|
||||
if (!src)
|
||||
return false;
|
||||
|
||||
struct unit_data *ud = unit_bl2ud(src);
|
||||
struct map_session_data *sd = map_id2sd(src->id);
|
||||
int maxcount = 0;
|
||||
|
||||
if (!(type&battle_config.skill_reiteration) && skill_get_unit_flag(skill_id)&UF_NOREITERATION && skill_check_unit_range(src, x, y, skill_id, skill_lv)) {
|
||||
if (sd && display_failure)
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
||||
return false;
|
||||
}
|
||||
if (type&battle_config.skill_nofootset && skill_get_unit_flag(skill_id)&UF_NOFOOTSET && skill_check_unit_range2(src, x, y, skill_id, skill_lv, false)) {
|
||||
if (sd && display_failure)
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
||||
return false;
|
||||
}
|
||||
if (type&battle_config.land_skill_limit && (maxcount = skill_get_maxcount(skill_id, skill_lv)) > 0) {
|
||||
for (int i = 0; i < MAX_SKILLUNITGROUP && ud->skillunit[i] && maxcount; i++) {
|
||||
if (ud->skillunit[i]->skill_id == skill_id)
|
||||
maxcount--;
|
||||
}
|
||||
if (maxcount == 0) {
|
||||
if (sd && display_failure)
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates heal value of skill's effect
|
||||
* @param src: Unit casting heal
|
||||
@@ -649,7 +693,7 @@ static int8 skill_isCopyable(struct map_session_data *sd, uint16 skill_idx) {
|
||||
|
||||
/**
|
||||
* Check if the skill is ok to cast and when.
|
||||
* Done before check_condition_begin, requirement
|
||||
* Done before skill_check_condition_castbegin, requirement
|
||||
* @param skill_id: Skill ID that casted
|
||||
* @param sd: Player who casted
|
||||
* @return true: Skill cannot be used, false: otherwise
|
||||
@@ -2106,29 +2150,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
|
||||
tbl = (it.id < 0) ? src : bl;
|
||||
|
||||
if( (type = skill_get_casttype(skill)) == CAST_GROUND ) {
|
||||
int maxcount = 0;
|
||||
if( !(BL_PC&battle_config.skill_reiteration) &&
|
||||
skill_get_unit_flag(skill)&UF_NOREITERATION &&
|
||||
skill_check_unit_range(src,tbl->x,tbl->y,skill,autospl_skill_lv)
|
||||
)
|
||||
if ((type = skill_get_casttype(skill)) == CAST_GROUND) {
|
||||
if (!skill_pos_maxcount_check(src, tbl->x, tbl->y, skill, autospl_skill_lv, BL_PC, false))
|
||||
continue;
|
||||
if( BL_PC&battle_config.skill_nofootset &&
|
||||
skill_get_unit_flag(skill)&UF_NOFOOTSET &&
|
||||
skill_check_unit_range2(src,tbl->x,tbl->y,skill,autospl_skill_lv,false)
|
||||
)
|
||||
continue;
|
||||
if( BL_PC&battle_config.land_skill_limit &&
|
||||
(maxcount = skill_get_maxcount(skill, autospl_skill_lv)) > 0
|
||||
) {
|
||||
int v;
|
||||
for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
|
||||
if(sd->ud.skillunit[v]->skill_id == skill)
|
||||
maxcount--;
|
||||
}
|
||||
if( maxcount == 0 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (battle_config.autospell_check_range &&
|
||||
!battle_check_range(bl, tbl, skill_get_range2(src, skill, autospl_skill_lv, true)))
|
||||
@@ -2233,27 +2257,9 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1
|
||||
else
|
||||
tbl = bl;
|
||||
|
||||
if( (type = skill_get_casttype(skill)) == CAST_GROUND ) {
|
||||
int maxcount = 0;
|
||||
if( !(BL_PC&battle_config.skill_reiteration) &&
|
||||
skill_get_unit_flag(skill)&UF_NOREITERATION &&
|
||||
skill_check_unit_range(&sd->bl,tbl->x,tbl->y,skill,skill_lv) )
|
||||
if ((type = skill_get_casttype(skill)) == CAST_GROUND) {
|
||||
if (!skill_pos_maxcount_check(&sd->bl, tbl->x, tbl->y, skill_id, skill_lv, BL_PC, false))
|
||||
continue;
|
||||
if( BL_PC&battle_config.skill_nofootset &&
|
||||
skill_get_unit_flag(skill)&UF_NOFOOTSET &&
|
||||
skill_check_unit_range2(&sd->bl,tbl->x,tbl->y,skill,skill_lv,false) )
|
||||
continue;
|
||||
if( BL_PC&battle_config.land_skill_limit &&
|
||||
(maxcount = skill_get_maxcount(skill, skill_lv)) > 0 )
|
||||
{
|
||||
int v;
|
||||
for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
|
||||
if(sd->ud.skillunit[v]->skill_id == skill)
|
||||
maxcount--;
|
||||
}
|
||||
if( maxcount == 0 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (battle_config.autospell_check_range &&
|
||||
!battle_check_range(bl, tbl, skill_get_range2(&sd->bl, skill, skill_lv, true)))
|
||||
@@ -2443,30 +2449,9 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
|
||||
continue;
|
||||
|
||||
tbl = (it.id < 0) ? bl : src;
|
||||
if( (type = skill_get_casttype(autospl_skill_id)) == CAST_GROUND ) {
|
||||
int maxcount = 0;
|
||||
if( !(BL_PC&battle_config.skill_reiteration) &&
|
||||
skill_get_unit_flag(autospl_skill_id)&UF_NOREITERATION &&
|
||||
skill_check_unit_range(bl,tbl->x,tbl->y,autospl_skill_id,autospl_skill_lv)
|
||||
)
|
||||
if ((type = skill_get_casttype(autospl_skill_id)) == CAST_GROUND) {
|
||||
if (!skill_pos_maxcount_check(bl, tbl->x, tbl->y, autospl_skill_id, autospl_skill_lv, BL_PC, false))
|
||||
continue;
|
||||
if( BL_PC&battle_config.skill_nofootset &&
|
||||
skill_get_unit_flag(autospl_skill_id)&UF_NOFOOTSET &&
|
||||
skill_check_unit_range2(bl,tbl->x,tbl->y,autospl_skill_id,autospl_skill_lv,false)
|
||||
)
|
||||
continue;
|
||||
if( BL_PC&battle_config.land_skill_limit &&
|
||||
(maxcount = skill_get_maxcount(autospl_skill_id, autospl_skill_lv)) > 0
|
||||
) {
|
||||
int v;
|
||||
for(v=0;v<MAX_SKILLUNITGROUP && dstsd->ud.skillunit[v] && maxcount;v++) {
|
||||
if(dstsd->ud.skillunit[v]->skill_id == autospl_skill_id)
|
||||
maxcount--;
|
||||
}
|
||||
if( maxcount == 0 ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!battle_check_range(bl, tbl, skill_get_range2(src, autospl_skill_id, autospl_skill_lv, true)) && battle_config.autospell_check_range)
|
||||
@@ -11576,39 +11561,11 @@ TIMER_FUNC(skill_castend_pos){
|
||||
ud->skilltimer = INVALID_TIMER;
|
||||
|
||||
do {
|
||||
int maxcount=0;
|
||||
if( status_isdead(src) )
|
||||
break;
|
||||
|
||||
if( !(src->type&battle_config.skill_reiteration) &&
|
||||
skill_get_unit_flag(ud->skill_id)&UF_NOREITERATION &&
|
||||
skill_check_unit_range(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv)
|
||||
)
|
||||
{
|
||||
if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
if (!skill_pos_maxcount_check(src, ud->skillx, ud->skilly, ud->skill_id, ud->skill_lv, src->type, true))
|
||||
break;
|
||||
}
|
||||
if( skill_get_unit_flag(ud->skill_id)&UF_NOFOOTSET &&
|
||||
skill_check_unit_range2(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv,false)
|
||||
)
|
||||
{
|
||||
if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
break;
|
||||
}
|
||||
if( src->type&battle_config.land_skill_limit &&
|
||||
(maxcount = skill_get_maxcount(ud->skill_id, ud->skill_lv)) > 0
|
||||
) {
|
||||
int i;
|
||||
for(i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i] && maxcount;i++) {
|
||||
if(ud->skillunit[i]->skill_id == ud->skill_id)
|
||||
maxcount--;
|
||||
}
|
||||
if( maxcount == 0 )
|
||||
{
|
||||
if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(tid != INVALID_TIMER)
|
||||
{ //Avoid double checks on instant cast skills. [Skotlex]
|
||||
|
||||
@@ -487,6 +487,7 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap);
|
||||
void skill_consume_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type);
|
||||
struct skill_condition skill_get_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
int skill_disable_check(struct status_change *sc, uint16 skill_id);
|
||||
bool skill_pos_maxcount_check(struct block_list *src, int16 x, int16 y, uint16 skill_id, uint16 skill_lv, enum bl_type type, bool display_failure);
|
||||
|
||||
int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16 *skill_lv, int range, int cast_flag);
|
||||
int skill_unit_move(struct block_list *bl,t_tick tick,int flag);
|
||||
|
||||
@@ -1998,6 +1998,8 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
if( sd ) {
|
||||
if( skill_isNotOk(skill_id, sd) || !skill_check_condition_castbegin(sd, skill_id, skill_lv) )
|
||||
return 0;
|
||||
if (skill_id == MG_FIREWALL && !skill_pos_maxcount_check(src, skill_x, skill_y, skill_id, skill_lv, BL_PC, true))
|
||||
return 0; // Special check for Firewall only
|
||||
}
|
||||
|
||||
if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && map_getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) {
|
||||
|
||||
Reference in New Issue
Block a user