|
@@ -434,6 +434,50 @@ unsigned short skill_dummy2skill_id(unsigned short skill_id) {
|
|
return 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
|
|
* Calculates heal value of skill's effect
|
|
* @param src: Unit casting heal
|
|
* @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.
|
|
* 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 skill_id: Skill ID that casted
|
|
* @param sd: Player who casted
|
|
* @param sd: Player who casted
|
|
* @return true: Skill cannot be used, false: otherwise
|
|
* @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;
|
|
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)
|
|
|
|
- )
|
|
|
|
- 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)
|
|
|
|
- )
|
|
|
|
|
|
+ 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;
|
|
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 &&
|
|
if (battle_config.autospell_check_range &&
|
|
!battle_check_range(bl, tbl, skill_get_range2(src, skill, autospl_skill_lv, true)))
|
|
!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
|
|
else
|
|
tbl = bl;
|
|
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) )
|
|
|
|
- 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) )
|
|
|
|
|
|
+ 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;
|
|
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 &&
|
|
if (battle_config.autospell_check_range &&
|
|
!battle_check_range(bl, tbl, skill_get_range2(&sd->bl, skill, skill_lv, true)))
|
|
!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;
|
|
continue;
|
|
|
|
|
|
tbl = (it.id < 0) ? bl : src;
|
|
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)
|
|
|
|
- )
|
|
|
|
- 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)
|
|
|
|
- )
|
|
|
|
|
|
+ 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;
|
|
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)
|
|
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;
|
|
ud->skilltimer = INVALID_TIMER;
|
|
|
|
|
|
do {
|
|
do {
|
|
- int maxcount=0;
|
|
|
|
if( status_isdead(src) )
|
|
if( status_isdead(src) )
|
|
break;
|
|
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);
|
|
|
|
- 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);
|
|
|
|
|
|
+ if (!skill_pos_maxcount_check(src, ud->skillx, ud->skilly, ud->skill_id, ud->skill_lv, src->type, true))
|
|
break;
|
|
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)
|
|
if(tid != INVALID_TIMER)
|
|
{ //Avoid double checks on instant cast skills. [Skotlex]
|
|
{ //Avoid double checks on instant cast skills. [Skotlex]
|