From 8fff37eadc1bfdb8a42825f9f84ecdbaae16c3f4 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Tue, 28 Jan 2014 13:06:47 +0700 Subject: [PATCH] * 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 --- db/re/skill_require_db.txt | 2 +- src/map/atcommand.c | 2 +- src/map/clif.h | 2 +- src/map/itemdb.c | 16 ++ src/map/itemdb.h | 13 ++ src/map/skill.c | 322 ++++++++++++++++++++----------------- src/map/skill.h | 6 +- 7 files changed, 210 insertions(+), 153 deletions(-) diff --git a/db/re/skill_require_db.txt b/db/re/skill_require_db.txt index 6bee91d46e..5646ee7ab4 100644 --- a/db/re/skill_require_db.txt +++ b/db/re/skill_require_db.txt @@ -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# diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 4f05f52370..8fb315efec 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -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); diff --git a/src/map/clif.h b/src/map/clif.h index 682a7b0149..6e85a69e87 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -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 { diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 9ee0d26f8f..8a4d7b1ccf 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -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) diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 596e2734bd..33d607d514 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -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); diff --git a/src/map/skill.c b/src/map/skill.c index 5ff38f661f..a88936793d 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -11180,14 +11180,14 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui break; case RL_FALLEN_ANGEL: - if( unit_movepos(src, x, y, 1, 1) ) { + if (unit_movepos(src,x,y,1,1)) { 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<status.inventory[i].nameid)); clif_colormes(sd,color_table[COLOR_RED],e_msg); - return 0; + return false; } if (!(require.ammo&1<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; } /** diff --git a/src/map/skill.h b/src/map/skill.h index a1dbd03161..b7cf234de1 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -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);