* Fixed Fallen Angel behavior that consumes wrong ammo number

* Updated @iteminfo message, for ammo now show the ammo type instead "Arrow/Ammunition"
* Changed some clif_skill_fail messages
* Updated src documentaion for skill_check_castbegin and skill_check_castend

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>
This commit is contained in:
Cydh Ramdh 2014-01-28 13:06:47 +07:00
parent 5adccc4d34
commit 8fff37eadc
7 changed files with 210 additions and 153 deletions

View File

@ -903,7 +903,7 @@
2561,0,0,10:15:20:25:30,0,0,0,17,3,5,none,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_FIREDANCE#Fire Dance#
2562,0,0,45:50:55:60:65,0,0,0,21,0,0,none,0,0,7664,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_H_MINE#Howling Mine#
2563,0,0,20:24:28:32:36,0,0,0,99,0,0,none,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13201 //RL_P_ALTER#Platinum Alter#
2564,0,0,90,0,0,0,17,3,10,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_FALLEN_ANGEL#Fallen Angel#
2564,0,0,90,0,0,0,17,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_FALLEN_ANGEL#Fallen Angel#
2565,0,0,40:45:50:55:60,0,0,0,19,3,5,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_R_TRIP#Round Trip#
2566,0,0,60:70:80:90:100,0,0,0,21,5,1,none,0,0,7665,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_D_TAIL#Dragon Tail#
2567,0,0,70,0,0,0,19,3,10,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RL_FIRE_RAIN#Fire Rain#

View File

@ -7371,7 +7371,7 @@ ACMD_FUNC(iteminfo)
item_data = item_array[i];
sprintf(atcmd_output, msg_txt(sd,1277), // Item: '%s'/'%s'[%d] (%d) Type: %s | Extra Effect: %s
item_data->name,item_data->jname,item_data->slot,item_data->nameid,
itemdb_typename(item_data->type),
(item_data->type != IT_AMMO) ? itemdb_typename(item_data->type) : itemdb_typename_ammo(item_data->look),
(item_data->script==NULL)? msg_txt(sd,1278) : msg_txt(sd,1279) // None / With script
);
clif_displaymessage(fd, atcmd_output);

View File

@ -340,7 +340,7 @@ enum useskill_fail_cause
USESKILL_FAIL_STYLE_CHANGE_FIGHTER = 81,
USESKILL_FAIL_STYLE_CHANGE_GRAPPLER = 82,
USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83,
//USESKILL_FAIL_NEED_MORE_BULLET = 84,
USESKILL_FAIL_NEED_MORE_BULLET = 84,
};
enum clif_messages {

View File

@ -305,6 +305,22 @@ struct item_data* itemdb_exists(int nameid)
return item;
}
/// Returns name type of ammunition [Cydh]
const char *itemdb_typename_ammo (enum e_item_ammo ammo) {
switch (ammo) {
case AMMO_ARROW: return "Arrow";
case AMMO_THROWABLE_DAGGER: return "Throwable Dagger";
case AMMO_BULLET: return "Bullet";
case AMMO_SHELL: return "Shell";
case AMMO_GRENADE: return "Grenade";
case AMMO_SHURIKEN: return "Shuriken";
case AMMO_KUNAI: return "Kunai";
case AMMO_CANNONBALL: return "Cannonball";
case AMMO_THROWABLE_ITEM: return "Throwable Item/Sling Item";
}
return "Ammunition";
}
/// Returns human readable name for given item type.
/// @param type Type id to retrieve name for ( IT_* ).
const char* itemdb_typename(enum item_types type)

View File

@ -297,6 +297,18 @@ enum e_item_job {
ITEMJ_THIRD_BABY = 0x20,
};
enum e_item_ammo {
AMMO_ARROW = 1,
AMMO_THROWABLE_DAGGER,
AMMO_BULLET,
AMMO_SHELL,
AMMO_GRENADE,
AMMO_SHURIKEN,
AMMO_KUNAI,
AMMO_CANNONBALL,
AMMO_THROWABLE_ITEM, ///Sling items
};
///Item combo struct
struct item_combo {
struct script_code *script;
@ -424,6 +436,7 @@ struct item_data* itemdb_exists(int nameid);
#define itemdb_is_GNbomb(n) (n >= ITEMID_APPLE_BOMB && n <= ITEMID_VERY_HARD_LUMP)
#define itemdb_is_GNthrowable(n) (n >= ITEMID_MYSTERIOUS_POWDER && n <= ITEMID_BLACK_THING_TO_THROW)
const char* itemdb_typename(enum item_types type);
const char *itemdb_typename_ammo (enum e_item_ammo ammo);
int itemdb_group_bonus(struct map_session_data* sd, int itemid);
unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group);

View File

@ -11184,10 +11184,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
enum e_skill skill_use = GS_DESPERADO;
uint8 skill_use_lv = pc_checkskill(sd,skill_use);
clif_slide(src,x,y);
if (skill_check_condition_castbegin(sd,skill_use,skill_use_lv)) {
if (skill_check_condition_castend(sd,skill_use,skill_use_lv)) {
sd->skill_id_old = RL_FALLEN_ANGEL;
skill_castend_pos2(src,src->x,src->y,skill_use,skill_use_lv,tick,SD_LEVEL|SD_ANIMATION|SD_SPLASH);
skill_consume_requirement(sd,skill_use,skill_use_lv,1); //Consume Desperado ammunitions
battle_consume_ammo(sd,skill_use,skill_use_lv);
}
sd->skill_id_old = 0;
}
@ -13390,22 +13390,29 @@ int skill_isammotype (struct map_session_data *sd, int skill)
);
}
int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv) {
/** Check skill condition when cast begin
* NOTE: For ammo, only check if the skill need ammo, for checking ammo requirement (type and amount) will be skill_check_condition_castend
* @param sd Player who uses skill
* @param skill_id ID of used skill
* @param skill_lv Level of used skill
* @return true: All condition passed, false: Failed
*/
bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv) {
struct status_data *status;
struct status_change *sc;
struct skill_condition require;
int i;
uint32 inf2, inf3;
nullpo_ret(sd);
nullpo_retr(false,sd);
if (sd->chatID) return 0;
if (sd->chatID) return false;
if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id )
{ //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
sd->state.arrow_atk = skill_get_ammotype(skill_id)?1:0; //Need to do arrow state check.
sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
return 1;
return true;
}
switch( sd->menuskill_id ) {
@ -13417,7 +13424,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case AM_TWILIGHT1:
case AM_TWILIGHT2:
case AM_TWILIGHT3:
return 0;
return false;
}
break;
case GN_MIX_COOKING:
@ -13425,7 +13432,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case GN_S_PHARMACY:
case GN_CHANGEMATERIAL:
if( sd->menuskill_id != skill_id )
return 0;
return false;
break;
}
status = &sd->battle_status;
@ -13447,7 +13454,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
)
{ //Something went wrong, item exploit?
sd->itemid = sd->itemindex = -1;
return 0;
return false;
}
//Consume
sd->itemid = sd->itemindex = -1;
@ -13456,39 +13463,38 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
else if( sd->status.inventory[i].expire_time == 0 )
pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration
}
return 1;
return true;
}
if( pc_is90overweight(sd) )
{
if( pc_is90overweight(sd) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_WEIGHTOVER,0);
return 0;
return false;
}
if( sc && ( sc->data[SC__SHADOWFORM] || sc->data[SC__IGNORANCE] ) )
return 0;
return false;
//Checks if disabling skill - in which case no SP requirements are necessary
if( sc && skill_disable_check(sc,skill_id))
return 1;
return true;
inf3 = skill_get_inf3(skill_id);
// Check the skills that can be used while mounted on a warg
if( pc_isridingwug(sd) ) {
if(!(inf3&INF3_USABLE_WARG))
return 0; // in official there is no message.
return false; // in official there is no message.
}
if( pc_ismadogear(sd) ) {
//None Mado skills are unusable when Mado is equipped. [Jobbie]
//Only Mechanic exlcusive skill can be used.
if(inf3&INF3_DIS_MADO){
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
if( skill_lv < 1 || skill_lv > MAX_SKILL_LEVEL )
return 0;
return false;
require = skill_get_requirement(sd,skill_id,skill_lv);
@ -13500,13 +13506,13 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if(inf2&INF2_CHORUS_SKILL) {
if ( skill_check_pc_partner(sd,skill_id,&skill_lv,skill_get_splash(skill_id,skill_lv),0) < 1 ){
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
else if(inf2&INF2_ENSEMBLE_SKILL) {
if (skill_check_pc_partner(sd, skill_id, &skill_lv, 1, 0) < 1) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
// perform skill-specific checks (and actions)
@ -13514,12 +13520,12 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case SO_SPELLFIST:
if(sd->skill_id_old != MG_FIREBOLT && sd->skill_id_old != MG_COLDBOLT && sd->skill_id_old != MG_LIGHTNINGBOLT) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
case SA_CASTCANCEL:
if(sd->ud.skilltimer == INVALID_TIMER) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case AS_CLOAKING:
@ -13532,7 +13538,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
ARR_FIND( 0, 8, i, map_getcell(sd->bl.m, sd->bl.x+dx[i], sd->bl.y+dy[i], CELL_CHKNOPASS) != 0 );
if( i == 8 ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
break;
@ -13541,7 +13547,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if(!battle_config.duel_allow_teleport && sd->duel_group) { // duel restriction [LuzZza]
char output[128]; sprintf(output, msg_txt(sd,365), skill_get_name(AL_WARP));
clif_displaymessage(sd->fd, output); //"Duel: Can't use %s in duel."
return 0;
return false;
}
break;
case MO_CALLSPIRITS:
@ -13549,7 +13555,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
skill_lv += sc->data[SC_RAISINGDRAGON]->val1;
if(sd->spiritball >= skill_lv) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case MO_FINGEROFFENSIVE:
@ -13563,29 +13569,29 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case MO_CHAINCOMBO:
if(!sc)
return 0;
return false;
if(sc->data[SC_BLADESTOP])
break;
if(sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_TRIPLEATTACK)
break;
return 0;
return false;
case MO_COMBOFINISH:
if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_CHAINCOMBO))
return 0;
return false;
break;
case CH_TIGERFIST:
if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_COMBOFINISH))
return 0;
return false;
break;
case CH_CHAINCRUSH:
if(!(sc && sc->data[SC_COMBO]))
return 0;
return false;
if(sc->data[SC_COMBO]->val1 != MO_COMBOFINISH && sc->data[SC_COMBO]->val1 != CH_TIGERFIST)
return 0;
return false;
break;
case MO_EXTREMITYFIST:
// if(sc && sc->data[SC_EXTREMITYFIST]) //To disable Asura during the 5 min skill block uncomment this...
// return 0;
// return false;
if( sc && (sc->data[SC_BLADESTOP] || sc->data[SC_CURSEDCIRCLE_ATKER]) )
break;
if( sc && sc->data[SC_COMBO] ) {
@ -13595,18 +13601,18 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case CH_CHAINCRUSH:
break;
default:
return 0;
return false;
}
}
else if( !unit_can_move(&sd->bl) ) { //Placed here as ST_MOVE_ENABLE should not apply if rooted or on a combo. [Skotlex]
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case TK_MISSION:
if( (sd->class_&MAPID_UPPERMASK) != MAPID_TAEKWON ) { // Cannot be used by Non-Taekwon classes
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case TK_READYCOUNTER:
@ -13616,7 +13622,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case TK_JUMPKICK:
if( (sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER ) { // Soul Linkers cannot use this skill
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case TK_TURNKICK:
@ -13624,20 +13630,20 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case TK_DOWNKICK:
case TK_COUNTER:
if ((sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
return false; //Anti-Soul Linker check in case you job-changed with Stances active.
if(!(sc && sc->data[SC_COMBO]) || sc->data[SC_COMBO]->val1 == TK_JUMPKICK)
return 0; //Combo needs to be ready
return false; //Combo needs to be ready
if (sc->data[SC_COMBO]->val3) { //Kick chain
//Do not repeat a kick.
if (sc->data[SC_COMBO]->val3 != skill_id)
break;
status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
return 0;
return false;
}
if(sc->data[SC_COMBO]->val1 != skill_id && !( sd && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) )) { //Cancel combo wait.
unit_cancel_combo(&sd->bl);
return 0;
return false;
}
break; //Combo ready.
case BD_ADAPTATION:
@ -13645,7 +13651,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
int time;
if(!(sc && sc->data[SC_DANCING])) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
time = 1000*(sc->data[SC_DANCING]->val3>>16);
if (skill_get_time(
@ -13654,28 +13660,28 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
- time < skill_get_time2(skill_id,skill_lv))
{
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
break;
case PR_BENEDICTIO:
if (skill_check_pc_partner(sd, skill_id, &skill_lv, 1, 0) < 2) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case SL_SMA:
if(!(sc && sc->data[SC_SMA]))
return 0;
return false;
break;
case HT_POWER:
if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == AC_DOUBLE))
return 0;
return false;
break;
case CG_HERMODE:
if(!npc_check_areanpc(1,sd->bl.m,sd->bl.x,sd->bl.y,skill_get_splash(skill_id, skill_lv))) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case CG_MOONLIT: //Check there's no wall in the range+1 area around the caster. [Skotlex]
@ -13687,7 +13693,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
int y = sd->bl.y+(i/size-range);
if (map_getcell(sd->bl.m,x,y,CELL_CHKWALL)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
}
@ -13698,7 +13704,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if( ((exp = pc_nextbaseexp(sd)) > 0 && get_percentage(sd->status.base_exp, exp) < 1) ||
((exp = pc_nextjobexp(sd)) > 0 && get_percentage(sd->status.job_exp, exp) < 1)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); //Not enough exp.
return 0;
return false;
}
break;
}
@ -13712,12 +13718,12 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
int y = sd->bl.y+(i/size-range);
if( map_getcell(sd->bl.m,x,y,CELL_CHKWALL) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL,0);
return 0;
return false;
}
}
if( map_foreachinrange(skill_count_wos, &sd->bl, range, BL_ALL, &sd->bl) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL,0);
return 0;
return false;
}
}
}
@ -13726,7 +13732,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case AM_TWILIGHT3:
if (!party_skill_check(sd, sd->status.party_id, skill_id, skill_lv)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case SG_SUN_WARM:
@ -13738,7 +13744,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if (sd->bl.m == sd->feel_map[i].m)
break;
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
break;
case SG_SUN_COMFORT:
case SG_MOON_COMFORT:
@ -13750,7 +13756,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
(battle_config.allow_skill_without_day || sg_info[i].day_func()))
break;
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
case SG_FUSION:
if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_STAR)
break;
@ -13762,25 +13768,25 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
else
status_zap(&sd->bl, 0, require.sp);
}
return 0;
return false;
case GD_BATTLEORDER:
case GD_REGENERATION:
case GD_RESTORE:
if (!map_flag_gvg2(sd->bl.m)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
case GD_EMERGENCYCALL:
case GD_ITEMEMERGENCYCALL:
// other checks were already done in skill_isNotOk()
if (!sd->status.guild_id || !sd->state.gmaster_flag)
return 0;
return false;
break;
case GS_GLITTERING:
if(sd->spiritball >= 10) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case NJ_ISSEN:
@ -13790,35 +13796,35 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if (status->hp < 2) {
#endif
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
case NJ_BUNSINJYUTSU:
if (!(sc && sc->data[SC_NEN])) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case NJ_ZENYNAGE:
case KO_MUCHANAGE:
if(sd->status.zeny < require.zeny) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_MONEY,0);
return 0;
return false;
}
break;
case PF_HPCONVERSION:
if (status->sp == status->max_sp)
return 0; //Unusable when at full SP.
return false; //Unusable when at full SP.
break;
case AM_CALLHOMUN: //Can't summon if a hom is already out
if (sd->status.hom_id && sd->hd && !sd->hd->homunculus.vaporize) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case AM_REST: //Can't vapo homun if you don't have an active homunc or it's hp is < 80%
if (!merc_is_hom_active(sd->hd) || sd->hd->battle_status.hp < (sd->hd->battle_status.max_hp*80/100)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
/**
@ -13832,7 +13838,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
count += sd->status.inventory[i].amount;
if( count >= 3 ) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_ANCILLA_NUMOVER, 0);
return 0;
return false;
}
}
break;
@ -13844,7 +13850,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
//case AB_LAUDARAMUS:
// if( !sd->status.party_id ) {
// clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
// return 0;
// return false;
// }
// break;
@ -13859,7 +13865,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
&& ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) ) {
//clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]);
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case WL_SUMMONFB:
@ -13870,7 +13876,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
ARR_FIND(SC_SPHERE_1,SC_SPHERE_5+1,i,!sc->data[i]);
if( i == SC_SPHERE_5+1 ) { // No more free slots
clif_skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0);
return 0;
return false;
}
}
break;
@ -13885,12 +13891,12 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if( j < 4 ) { // Need 4 spheres minimum
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
else { // no status at all? no spheres present
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
/**
@ -13899,14 +13905,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case GC_HALLUCINATIONWALK:
if( sc && (sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY]) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case GC_COUNTERSLASH:
case GC_WEAPONCRUSH:
if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == GC_WEAPONBLOCKING) ) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_GC_WEAPONBLOCKING, 0);
return 0;
return false;
}
break;
/**
@ -13915,25 +13921,25 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case RA_WUGMASTERY:
if( (pc_isfalcon(sd) && !battle_config.warg_can_falcon) || pc_isridingwug(sd) || sd->sc.data[SC__GROOMY]) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case RA_WUGSTRIKE:
if( !pc_iswug(sd) && !pc_isridingwug(sd) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case RA_WUGRIDER:
if( (pc_isfalcon(sd) && !battle_config.warg_can_falcon) || ( !pc_isridingwug(sd) && !pc_iswug(sd) ) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case RA_WUGDASH:
if(!pc_isridingwug(sd)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
/**
@ -13942,46 +13948,46 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case LG_BANDING:
if( sc && sc->data[SC_INSPIRATION] ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case LG_PRESTIGE:
if( sc && (sc->data[SC_BANDING] || sc->data[SC_INSPIRATION]) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case LG_RAGEBURST:
if( sd->spiritball == 0 ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_SKILLINTERVAL,0);
return 0;
return false;
}
sd->spiritball_old = require.spiritball = sd->spiritball;
break;
case LG_RAYOFGENESIS:
if( sc && sc->data[SC_INSPIRATION] )
return 1; // Don't check for partner.
return true; // Don't check for partner.
if( !(sc && sc->data[SC_BANDING]) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL,0);
return 0;
return false;
} else if( skill_check_pc_partner(sd,skill_id,&skill_lv,skill_get_range(skill_id,skill_lv),0) < 1 )
return 0; // Just fails, no msg here.
return false; // Just fails, no msg here.
break;
case LG_HESPERUSLIT:
if( !sc || !sc->data[SC_BANDING] ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case SR_FALLENEMPIRE:
if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO) )
return 0;
return false;
break;
case SR_CRESCENTELBOW:
if( sc && sc->data[SC_CRESCENTELBOW] ) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_DUPLICATE, 0);
return 0;
return false;
}
break;
case SR_CURSEDCIRCLE:
@ -13991,14 +13997,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
char output[128];
sprintf(output,"%s",msg_txt(sd,382)); // You're too close to a stone or emperium to use this skill.
clif_colormes(sd,color_table[COLOR_RED], output);
return 0;
return false;
}
}
if( sd->spiritball > 0 )
sd->spiritball_old = require.spiritball = sd->spiritball;
else {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case SR_GATEOFHELL:
@ -14009,7 +14015,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case SC_DIMENSIONDOOR:
if( sc && sc->data[SC_MAGNETICFIELD] ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case WM_GREAT_ECHO: {
@ -14017,7 +14023,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
count = skill_check_pc_partner(sd, skill_id, &skill_lv, skill_get_splash(skill_id,skill_lv), 0);
if( count < 1 ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_HELPER,0);
return 0;
return false;
} else
require.sp -= require.sp * 20 * count / 100; // -20% each W/M in the party.
}
@ -14027,26 +14033,26 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if( sc && sc->data[SC_PROPERTYWALK] &&
sc->data[SC_PROPERTYWALK]->val3 < skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case SO_EL_CONTROL:
if( !sd->status.ele_id || !sd->ed ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case RETURN_TO_ELDICASTES:
if( pc_ismadogear(sd) ) { //Cannot be used if Mado is equipped.
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case LG_REFLECTDAMAGE:
case CR_REFLECTSHIELD:
if( sc && sc->data[SC_KYOMU] && rand()%100 < 30){
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case KO_KAHU_ENTEN:
@ -14058,7 +14064,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
ARR_FIND(1, 5, i, sd->talisman[i] > 0 && i != ttype);
if( (i < 5 && i != ttype) || sd->talisman[ttype] >= 10 ) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
return 0;
return false;
}
}
break;
@ -14067,7 +14073,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
ARR_FIND(1, 6, i, sd->talisman[i] > 0);
if( i > 4 ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
}
@ -14077,37 +14083,37 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case ST_HIDDEN:
if(!pc_ishiding(sd)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_RIDING:
if(!pc_isriding(sd) && !pc_isridingdragon(sd)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_FALCON:
if(!pc_isfalcon(sd)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_CART:
if(!pc_iscarton(sd)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
clif_skill_fail(sd,skill_id,USESKILL_FAIL_CART,0);
return false;
}
break;
case ST_SHIELD:
if(sd->status.shield <= 0) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_RECOV_WEIGHT_RATE:
if(battle_config.natural_heal_weight_rate <= 100 && sd->weight*100/sd->max_weight >= (unsigned int)battle_config.natural_heal_weight_rate) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_MOVE_ENABLE:
@ -14116,7 +14122,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if (!unit_can_move(&sd->bl)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_WATER:
@ -14125,41 +14131,41 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))
break;
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
case ST_RIDINGDRAGON:
if( !pc_isridingdragon(sd) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
clif_skill_fail(sd,skill_id,USESKILL_FAIL_DRAGON,0);
return false;
}
break;
case ST_WUG:
if( !pc_iswug(sd) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_RIDINGWUG:
if( !pc_isridingwug(sd) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_MADO:
if( !pc_ismadogear(sd) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
case ST_ELEMENTALSPIRIT:
if(!sd->ed) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_EL_SUMMON,0);
return 0;
return false;
}
break;
case ST_PECO:
if(!pc_isriding(sd)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
break;
}
@ -14170,12 +14176,16 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
/* May has multiple requirements */
if (!sc) {
clif_skill_fail(sd, skill_id, USESKILL_FAIL_CONDITION, 0);
return 0;
return false;
}
for (i = 0; i < require.status_count; i++) {
if (require.status[i] >= 0 && !sc->data[require.status[i]]) {
if (require.status[i] == SC_PUSH_CART) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_CART,0);
return false;
}
clif_skill_fail(sd, skill_id, USESKILL_FAIL_CONDITION, 0);
return 0;
return false;
}
}
}
@ -14190,7 +14200,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
//clif_skill_fail(sd, skill_id, USESKILL_FAIL_NEED_EQUIPMENT, reqeqit);
sprintf(output,"need to put on [%d] in order to use.",reqeqit);
clif_colormes(sd,color_table[COLOR_RED],output);
return 0;
return false;
}
}
}
@ -14199,50 +14209,56 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
//mhp is the max-hp-requirement, that is,
//you must have this % or less of HP to cast it.
clif_skill_fail(sd,skill_id,USESKILL_FAIL_HP_INSUFFICIENT,0);
return 0;
return false;
}
if( require.weapon && !pc_check_weapontype(sd,require.weapon) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0);
return 0;
return false;
}
if( require.sp > 0 && status->sp < (unsigned int)require.sp) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_SP_INSUFFICIENT,0);
return 0;
return false;
}
if( require.zeny > 0 && sd->status.zeny < require.zeny ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_MONEY,0);
return 0;
return false;
}
if( (require.spiritball > 0 && sd->spiritball < require.spiritball) ||
(require.spiritball == -1 && sd->spiritball < 1) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_SPIRITS,(require.spiritball == -1)? 1: require.spiritball);
return 0;
return false;
}
return 1;
return true;
}
int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv)
{
/** Check skill condition when cast end.
* NOTE: Checking ammo requirement (type and amount) will be here, not at skill_check_condition_castbegin
* @param sd Player who uses skill
* @param skill_id ID of used skill
* @param skill_lv Level of used skill
* @return true: All condition passed, false: Failed
*/
bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv) {
struct skill_condition require;
struct status_data *status;
int i;
int index[MAX_SKILL_ITEM_REQUIRE];
nullpo_ret(sd);
nullpo_retr(false,sd);
if( sd->chatID )
return 0;
return false;
if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id ) {
//GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
sd->state.arrow_atk = skill_get_ammotype(skill_id)?1:0; //Need to do arrow state check.
sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
return 1;
return true;
}
switch( sd->menuskill_id ) { // Cast start or cast end??
@ -14254,7 +14270,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
case AM_TWILIGHT1:
case AM_TWILIGHT2:
case AM_TWILIGHT3:
return 0;
return false;
}
break;
case GN_MIX_COOKING:
@ -14262,16 +14278,16 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
case GN_S_PHARMACY:
case GN_CHANGEMATERIAL:
if( sd->menuskill_id != skill_id )
return 0;
return false;
break;
}
if( sd->skillitem == skill_id ) // Casting finished (Item skill or Hocus-Pocus)
return 1;
return true;
if( pc_is90overweight(sd) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_WEIGHTOVER,0);
return 0;
return false;
}
// perform skill-specific checks (and actions)
@ -14291,7 +14307,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
(skill_id==AM_CANNIBALIZE && c != i && battle_config.summon_flora&2))
{ //Fails when: exceed max limit. There are other plant types already out.
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
return false;
}
}
break;
@ -14313,7 +14329,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill_id, &c);
if( c >= maxcount ) {
clif_skill_fail(sd , skill_id, USESKILL_FAIL_LEVEL, 0);
return 0;
return false;
}
}
}
@ -14324,7 +14340,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
if( c >= skill_get_maxcount(skill_id,skill_lv) || c != i)
{
clif_skill_fail(sd , skill_id, USESKILL_FAIL_LEVEL, 0);
return 0;
return false;
}
break;
}
@ -14335,32 +14351,40 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
if( require.hp > 0 && status->hp <= (unsigned int)require.hp) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_HP_INSUFFICIENT,0);
return 0;
return false;
}
if( require.weapon && !pc_check_weapontype(sd,require.weapon) ) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0);
return 0;
return false;
}
if( require.ammo ) { //Skill requires stuff equipped in the arrow slot.
if( require.ammo ) { //Skill requires stuff equipped in the ammo slot.
if((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i] ) {
clif_arrow_fail(sd,0);
return 0;
return false;
} else if( sd->status.inventory[i].amount < require.ammo_qty ) {
char e_msg[100];
if (require.ammo&(1<<AMMO_BULLET|1<<AMMO_GRENADE|1<<AMMO_SHELL)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_MORE_BULLET,0);
return false;
}
else if (require.ammo&(1<<AMMO_KUNAI)) {
clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_EQUIPMENT_KUNAI,0);
return false;
}
sprintf(e_msg,msg_txt(sd,381), //Skill Failed. [%s] requires %dx %s.
skill_get_desc(skill_id),
require.ammo_qty,
itemdb_jname(sd->status.inventory[i].nameid));
clif_colormes(sd,color_table[COLOR_RED],e_msg);
return 0;
return false;
}
if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message
//which is the closest we have to wrong ammo type. [Skotlex]
clif_arrow_fail(sd,0); //Haplo suggested we just send the equip-arrows message instead. [Skotlex]
//clif_skill_fail(sd,skill_id,USESKILL_FAIL_THIS_WEAPON,0);
return 0;
return false;
}
}
@ -14379,20 +14403,26 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
// sprintf(output, "You need itemid=%d, amount=%d", require.itemid[i], require.amount[i]);
// clif_colormes(sd,color_table[COLOR_RED],output);
}
return 0;
return false;
}
}
return 1;
return true;
}
// type&2: consume items (after skill was used)
// type&1: consume the others (before skill was used)
int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type)
/** Consume skill requirement
* @param sd Player who uses the skill
* @param skill_id ID of used skill
* @param skill_lv Level of used skill
* @param type Consume type
* type&1: consume the others (before skill was used);
* type&2: consume items (after skill was used)
*/
void skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type)
{
struct skill_condition req;
nullpo_ret(sd);
nullpo_retv(sd);
req = skill_get_requirement(sd,skill_id,skill_lv);
@ -14404,7 +14434,7 @@ int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uin
req.sp = 0;
break;
case GS_DESPERADO:
if (sd->skill_id_old == RL_FALLEN_ANGEL)
if (sd->skill_id_old == RL_FALLEN_ANGEL) //Don't consume SP if triggered by Fallen Angel
req.sp = 0;
break;
default:
@ -14476,8 +14506,6 @@ int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uin
pc_delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME);
}
}
return 1;
}
/**

View File

@ -377,10 +377,10 @@ int skill_vfcastfix( struct block_list *bl, double time, uint16 skill_id, uint16
int skill_delayfix( struct block_list *bl, uint16 skill_id, uint16 skill_lv);
// Skill conditions check and remove [Inkfish]
int skill_check_condition_castbegin(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
int skill_check_condition_castend(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
bool skill_check_condition_castbegin(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
bool skill_check_condition_castend(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
int skill_check_condition_char_sub (struct block_list *bl, va_list ap);
int skill_consume_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type);
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);