From 81a2b776cebb41d52a90994b605d9b0c5925acb5 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 18:20:59 +0100 Subject: Add enumeration for auto-cast types --- src/map/skill.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/map/skill.h b/src/map/skill.h index c65547181..b241e0498 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1724,6 +1724,15 @@ enum { UNT_MAX = 0x190 }; +/** Constants to identify the auto-cast type. **/ +enum autocast_type { + AUTOCAST_NONE = 0, + AUTOCAST_TEMP, // Used when type is only required during the execution of the calling instance. (For example bAutoSpell* skills.) + AUTOCAST_ABRA, // Used for Abracadabra (Hocus pocus). + AUTOCAST_IMPROVISE, // Used for Improvised Song. + AUTOCAST_ITEM, // Used for itemskill() script command. +}; + /** * Structures **/ -- cgit v1.2.3-70-g09d2 From e0ce59dbbed70b40b06f7e75e7c76c23feec0fc5 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 19:01:30 +0100 Subject: Add structure for auto-cast related data --- src/map/pc.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/map/pc.h b/src/map/pc.h index 8d1ae3607..1fbc6c579 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -173,6 +173,17 @@ struct pc_combos { int id; /* this combo id */ }; +/** Auto-cast related data. **/ +struct autocast_data { + enum autocast_type type; // The auto-cast type. + int skill_id; // The auto-cast skill ID. + int skill_lv; // The auto-cast skill level. + bool itemskill_conditions_checked; // Used by itemskill() script command, to prevent second check of conditions after target was selected. + bool itemskill_check_conditions; // Used by itemskill() script command, to check skill conditions and consume them. + bool itemskill_instant_cast; // Used by itemskill() script command, to cast skill instantaneously. + bool itemskill_cast_on_self; // Used by itemskill() script command, to forcefully cast skill on invoking character. +}; + struct map_session_data { struct block_list bl; struct unit_data ud; -- cgit v1.2.3-70-g09d2 From bfbb4fcbc6bed6266c91d13461c93f2fe4128182 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 19:02:17 +0100 Subject: Add struct autocast_data to struct map_session_data --- src/map/pc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/map/pc.h b/src/map/pc.h index 1fbc6c579..f069c0d66 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -192,6 +192,7 @@ struct map_session_data { struct status_change sc; struct regen_data regen; struct regen_data_sub sregen, ssregen; + struct autocast_data autocast; //NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in //status_calc_pc, while special_state is recalculated in each call. [Skotlex] struct { -- cgit v1.2.3-70-g09d2 From 3e847676d726c0e38782ce3708be430289972405 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 20:46:44 +0100 Subject: Add map_session_data->autocast.type assignments --- src/map/battle.c | 12 ++++++++++++ src/map/pc.c | 1 + src/map/script.c | 1 + src/map/skill.c | 24 ++++++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/src/map/battle.c b/src/map/battle.c index 985d2bca4..e73c93bab 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -5939,8 +5939,18 @@ static void battle_reflect_damage(struct block_list *target, struct block_list * sd->state.autocast = 1; } + enum autocast_type ac_type; + + if (sd != NULL) { + ac_type = sd->autocast.type; + sd->autocast.type = AUTOCAST_TEMP; + } + map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,delay,wd->dmotion,rdamage,status_get_race(target)); + if (sd != NULL) + sd->autocast.type = ac_type; + if( change ) sd->state.autocast = 0; @@ -6457,8 +6467,10 @@ static enum damage_lv battle_weapon_attack(struct block_list *src, struct block_ } sd->state.autocast = 1; + sd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(sd,r_skill,r_lv,3); skill->castend_type(type, src, target, r_skill, r_lv, tick, flag); + sd->autocast.type = AUTOCAST_NONE; sd->state.autocast = 0; sd->ud.canact_tick = tick + skill->delay_fix(src, r_skill, r_lv); clif->status_change(src, status->get_sc_icon(SC_POSTDELAY), status->get_sc_relevant_bl_types(SC_POSTDELAY), 1, skill->delay_fix(src, r_skill, r_lv), 0, 0, 1); diff --git a/src/map/pc.c b/src/map/pc.c index c604e16dc..73bae2b5b 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5346,6 +5346,7 @@ static int pc_itemskill_clear(struct map_session_data *sd) { nullpo_ret(sd); + sd->autocast.type = AUTOCAST_NONE; sd->itemskill_id = 0; sd->itemskill_lv = 0; sd->state.itemskill_conditions_checked = 0; diff --git a/src/map/script.c b/src/map/script.c index b8a7979a7..18855e3b0 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11002,6 +11002,7 @@ static BUILDIN(itemskill) return true; pc->itemskill_clear(sd); + sd->autocast.type = AUTOCAST_ITEM; sd->skillitem = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); sd->skillitemlv = script_getnum(st, 3); sd->state.itemskill_conditions_checked = 0; // Skill casting items will check the conditions prior to the target selection in AEGIS. Thus we need a flag to prevent checking them twice. diff --git a/src/map/skill.c b/src/map/skill.c index a1a22f74f..a83f3bfe5 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2066,7 +2066,9 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl temp = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id; sd->state.autocast = 1; + sd->autocast.type = AUTOCAST_TEMP; notok = skill->not_ok(temp, sd); + sd->autocast.type = AUTOCAST_NONE; sd->state.autocast = 0; if ( notok ) @@ -2119,9 +2121,11 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl type = CAST_GROUND; sd->state.autocast = 1; + sd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(sd,temp,auto_skill_lv,1); skill->toggle_magicpower(src, temp); skill->castend_type(type, src, tbl, temp, auto_skill_lv, tick, 0); + sd->autocast.type = AUTOCAST_NONE; sd->state.autocast = 0; //Set canact delay. [Skotlex] ud = unit->bl2ud(src); @@ -2191,6 +2195,9 @@ static int skill_onskillusage(struct map_session_data *sd, struct block_list *bl if( sd == NULL || !skill_id ) return 0; + // Preserve auto-cast type if bAutoSpellOnSkill was triggered by a skill which was cast by Abracadabra, Improvised Song or an item. + enum autocast_type ac_type = sd->autocast.type; + for( i = 0; i < ARRAYLENGTH(sd->autospell3) && sd->autospell3[i].flag; i++ ) { if( sd->autospell3[i].flag != skill_id ) continue; @@ -2201,7 +2208,9 @@ static int skill_onskillusage(struct map_session_data *sd, struct block_list *bl temp = (sd->autospell3[i].id > 0) ? sd->autospell3[i].id : -sd->autospell3[i].id; sd->state.autocast = 1; + sd->autocast.type = AUTOCAST_TEMP; notok = skill->not_ok(temp, sd); + sd->autocast.type = AUTOCAST_NONE; sd->state.autocast = 0; if ( notok ) @@ -2250,12 +2259,16 @@ static int skill_onskillusage(struct map_session_data *sd, struct block_list *bl sd->state.autocast = 1; sd->autospell3[i].lock = true; + sd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(sd,temp,skill_lv,1); skill->castend_type(type, &sd->bl, tbl, temp, skill_lv, tick, 0); + sd->autocast.type = AUTOCAST_NONE; sd->autospell3[i].lock = false; sd->state.autocast = 0; } + sd->autocast.type = ac_type; + if (sd->autobonus3[0].rate) { for( i = 0; i < ARRAYLENGTH(sd->autobonus3); i++ ) { if( rnd()%1000 >= sd->autobonus3[i].rate ) @@ -2402,6 +2415,9 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_ struct unit_data *ud; int i, auto_skill_id, auto_skill_lv, type, notok; + // Preserve auto-cast type if bAutoSpellWhenHit was triggered during cast of a skill which was cast by Abracadabra, Improvised Song or an item. + enum autocast_type ac_type = dstsd->autocast.type; + for (i = 0; i < ARRAYLENGTH(dstsd->autospell2) && dstsd->autospell2[i].id; i++) { if(!(dstsd->autospell2[i].flag&attack_type&BF_WEAPONMASK && @@ -2418,7 +2434,9 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_ rate>>=1; dstsd->state.autocast = 1; + dstsd->autocast.type = AUTOCAST_TEMP; notok = skill->not_ok(auto_skill_id, dstsd); + dstsd->autocast.type = AUTOCAST_NONE; dstsd->state.autocast = 0; if ( notok ) @@ -2461,8 +2479,10 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_ continue; dstsd->state.autocast = 1; + dstsd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(dstsd,auto_skill_id,auto_skill_lv,1); skill->castend_type(type, bl, tbl, auto_skill_id, auto_skill_lv, tick, 0); + dstsd->autocast.type = AUTOCAST_NONE; dstsd->state.autocast = 0; // Set canact delay. [Skotlex] ud = unit->bl2ud(bl); @@ -2475,6 +2495,8 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_ } } } + + dstsd->autocast.type = ac_type; } //Autobonus when attacked @@ -6299,6 +6321,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * if (sd) { // player-casted + sd->autocast.type = AUTOCAST_ABRA; sd->state.abra_flag = 1; sd->skillitem = abra_skill_id; sd->skillitemlv = abra_skill_lv; @@ -10041,6 +10064,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); if (sd != NULL) { + sd->autocast.type = AUTOCAST_IMPROVISE; sd->state.abra_flag = 2; sd->skillitem = improv_skill_id; sd->skillitemlv = improv_skill_lv; -- cgit v1.2.3-70-g09d2 From 80e505df06aab94b74210cc2f0e0651d6b6feb5f Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 20:53:34 +0100 Subject: Add map_session_data->autocast.skill_id/_lv assignments --- src/map/pc.c | 2 ++ src/map/script.c | 2 ++ src/map/skill.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/src/map/pc.c b/src/map/pc.c index 73bae2b5b..0981cdee9 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5347,6 +5347,8 @@ static int pc_itemskill_clear(struct map_session_data *sd) nullpo_ret(sd); sd->autocast.type = AUTOCAST_NONE; + sd->autocast.skill_id = 0; + sd->autocast.skill_lv = 0; sd->itemskill_id = 0; sd->itemskill_lv = 0; sd->state.itemskill_conditions_checked = 0; diff --git a/src/map/script.c b/src/map/script.c index 18855e3b0..44cab8429 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11003,6 +11003,8 @@ static BUILDIN(itemskill) pc->itemskill_clear(sd); sd->autocast.type = AUTOCAST_ITEM; + sd->autocast.skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); + sd->autocast.skill_lv = script_getnum(st, 3); sd->skillitem = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); sd->skillitemlv = script_getnum(st, 3); sd->state.itemskill_conditions_checked = 0; // Skill casting items will check the conditions prior to the target selection in AEGIS. Thus we need a flag to prevent checking them twice. diff --git a/src/map/skill.c b/src/map/skill.c index a83f3bfe5..5ceff376f 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6322,6 +6322,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * if (sd) { // player-casted sd->autocast.type = AUTOCAST_ABRA; + sd->autocast.skill_id = abra_skill_id; + sd->autocast.skill_lv = abra_skill_lv; sd->state.abra_flag = 1; sd->skillitem = abra_skill_id; sd->skillitemlv = abra_skill_lv; @@ -10065,6 +10067,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * if (sd != NULL) { sd->autocast.type = AUTOCAST_IMPROVISE; + sd->autocast.skill_id = improv_skill_id; + sd->autocast.skill_lv = improv_skill_lv; sd->state.abra_flag = 2; sd->skillitem = improv_skill_id; sd->skillitemlv = improv_skill_lv; -- cgit v1.2.3-70-g09d2 From 735b763ed55c8cf9aca3ddeb6b469ce43896bf7d Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 21:04:42 +0100 Subject: Add map_session_data->autocast.itemskill_* assignments --- src/map/pc.c | 4 ++++ src/map/script.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/map/pc.c b/src/map/pc.c index 0981cdee9..ebba015a2 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5349,6 +5349,10 @@ static int pc_itemskill_clear(struct map_session_data *sd) sd->autocast.type = AUTOCAST_NONE; sd->autocast.skill_id = 0; sd->autocast.skill_lv = 0; + sd->autocast.itemskill_conditions_checked = false; + sd->autocast.itemskill_check_conditions = false; + sd->autocast.itemskill_instant_cast = false; + sd->autocast.itemskill_cast_on_self = false; sd->itemskill_id = 0; sd->itemskill_lv = 0; sd->state.itemskill_conditions_checked = 0; diff --git a/src/map/script.c b/src/map/script.c index 44cab8429..83c221e78 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11012,6 +11012,7 @@ static BUILDIN(itemskill) int flag = script_hasdata(st, 4) ? script_getnum(st, 4) : ISF_NONE; sd->state.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS) ? 1 : 0; // Unset in pc_itemskill_clear(). + sd->autocast.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS); if (sd->state.itemskill_check_conditions == 1) { if (skill->check_condition_castbegin(sd, sd->skillitem, sd->skillitemlv) == 0 @@ -11021,10 +11022,13 @@ static BUILDIN(itemskill) } sd->state.itemskill_conditions_checked = 1; // Unset in pc_itemskill_clear(). + sd->autocast.itemskill_conditions_checked = true; } sd->state.itemskill_no_casttime = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST) ? 1 : 0; // Unset in pc_itemskill_clear(). sd->state.itemskill_castonself = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF) ? 1 : 0; // Unset in pc_itemskill_clear(). + sd->autocast.itemskill_instant_cast = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST); + sd->autocast.itemskill_cast_on_self = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF); // itemskill_conditions_checked/itemskill_no_conditions/itemskill_no_casttime/itemskill_castonself abuse prevention. Unset in pc_itemskill_clear(). sd->itemskill_id = sd->skillitem; -- cgit v1.2.3-70-g09d2 From 0a1982baa30e29431622c1a4f52668756d563214 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 21:24:28 +0100 Subject: Rename function pc_itemskill_clear() to pc_autocast_clear() --- src/map/clif.c | 2 +- src/map/pc.c | 6 +++--- src/map/pc.h | 2 +- src/map/script.c | 14 +++++++------- src/map/skill.c | 2 +- src/map/unit.c | 4 ++-- src/plugins/HPMHooking/HPMHooking.Defs.inc | 4 ++-- src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc | 8 ++++---- src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc | 2 +- src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 16 ++++++++-------- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index c9e018f73..d7dffb293 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -12987,7 +12987,7 @@ static void clif_parse_UseSkillMap(int fd, struct map_session_data *sd) pc->delinvincibletimer(sd); skill->castend_map(sd,skill_id,map_name); - pc->itemskill_clear(sd); + pc->autocast_clear(sd); } static void clif_parse_RequestMemo(int fd, struct map_session_data *sd) __attribute__((nonnull (2))); diff --git a/src/map/pc.c b/src/map/pc.c index ebba015a2..073c16029 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5337,12 +5337,12 @@ static int pc_useitem(struct map_session_data *sd, int n) } /** - * Sets state flags and helper variables, used by itemskill() script command, to 0. + * Unsets a character's auto-cast related data. * * @param sd The character's session data. * @return 0 if parameter sd is NULL, otherwise 1. */ -static int pc_itemskill_clear(struct map_session_data *sd) +static int pc_autocast_clear(struct map_session_data *sd) { nullpo_ret(sd); @@ -12733,7 +12733,7 @@ void pc_defaults(void) pc->unequipitem_pos = pc_unequipitem_pos; pc->checkitem = pc_checkitem; pc->useitem = pc_useitem; - pc->itemskill_clear = pc_itemskill_clear; + pc->autocast_clear = pc_autocast_clear; pc->skillatk_bonus = pc_skillatk_bonus; pc->skillheal_bonus = pc_skillheal_bonus; diff --git a/src/map/pc.h b/src/map/pc.h index f069c0d66..92444aa2a 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -1046,7 +1046,7 @@ END_ZEROED_BLOCK; /* End */ void (*unequipitem_pos) (struct map_session_data *sd, int n, int pos); int (*checkitem) (struct map_session_data *sd); int (*useitem) (struct map_session_data *sd,int n); - int (*itemskill_clear) (struct map_session_data *sd); + int (*autocast_clear) (struct map_session_data *sd); int (*skillatk_bonus) (struct map_session_data *sd, uint16 skill_id); int (*skillheal_bonus) (struct map_session_data *sd, uint16 skill_id); diff --git a/src/map/script.c b/src/map/script.c index 83c221e78..b08613ec3 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11001,7 +11001,7 @@ static BUILDIN(itemskill) if (sd == NULL || sd->ud.skilltimer != INVALID_TIMER) return true; - pc->itemskill_clear(sd); + pc->autocast_clear(sd); sd->autocast.type = AUTOCAST_ITEM; sd->autocast.skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); sd->autocast.skill_lv = script_getnum(st, 3); @@ -11011,26 +11011,26 @@ static BUILDIN(itemskill) int flag = script_hasdata(st, 4) ? script_getnum(st, 4) : ISF_NONE; - sd->state.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS) ? 1 : 0; // Unset in pc_itemskill_clear(). + sd->state.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS) ? 1 : 0; // Unset in pc_autocast_clear(). sd->autocast.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS); if (sd->state.itemskill_check_conditions == 1) { if (skill->check_condition_castbegin(sd, sd->skillitem, sd->skillitemlv) == 0 || skill->check_condition_castend(sd, sd->skillitem, sd->skillitemlv) == 0) { - pc->itemskill_clear(sd); + pc->autocast_clear(sd); return true; } - sd->state.itemskill_conditions_checked = 1; // Unset in pc_itemskill_clear(). + sd->state.itemskill_conditions_checked = 1; // Unset in pc_autocast_clear(). sd->autocast.itemskill_conditions_checked = true; } - sd->state.itemskill_no_casttime = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST) ? 1 : 0; // Unset in pc_itemskill_clear(). - sd->state.itemskill_castonself = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF) ? 1 : 0; // Unset in pc_itemskill_clear(). + sd->state.itemskill_no_casttime = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST) ? 1 : 0; // Unset in pc_autocast_clear(). + sd->state.itemskill_castonself = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF) ? 1 : 0; // Unset in pc_autocast_clear(). sd->autocast.itemskill_instant_cast = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST); sd->autocast.itemskill_cast_on_self = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF); - // itemskill_conditions_checked/itemskill_no_conditions/itemskill_no_casttime/itemskill_castonself abuse prevention. Unset in pc_itemskill_clear(). + // itemskill_conditions_checked/itemskill_no_conditions/itemskill_no_casttime/itemskill_castonself abuse prevention. Unset in pc_autocast_clear(). sd->itemskill_id = sd->skillitem; sd->itemskill_lv = sd->skillitemlv; diff --git a/src/map/skill.c b/src/map/skill.c index 5ceff376f..f28d50c6e 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4223,7 +4223,7 @@ static void skill_castend_type(int type, struct block_list *src, struct block_li struct map_session_data *sd = BL_CAST(BL_PC, src); if (sd != NULL) - pc->itemskill_clear(sd); + pc->autocast_clear(sd); } /*========================================== diff --git a/src/map/unit.c b/src/map/unit.c index d2cfcb03d..984cc6802 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1146,7 +1146,7 @@ static int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_ struct map_session_data *sd = BL_CAST(BL_PC, src); if (sd != NULL && (ret == 0 || !skill->is_item_skill(sd, skill_id, skill_lv))) - pc->itemskill_clear(sd); + pc->autocast_clear(sd); return ret; } @@ -1783,7 +1783,7 @@ static int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_ struct map_session_data *sd = BL_CAST(BL_PC, src); if (sd != NULL && (ret == 0 || !skill->is_item_skill(sd, skill_id, skill_lv))) - pc->itemskill_clear(sd); + pc->autocast_clear(sd); return ret; } diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 28f81b97f..edfd60fbc 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -6184,8 +6184,8 @@ typedef int (*HPMHOOK_pre_pc_checkitem) (struct map_session_data **sd); typedef int (*HPMHOOK_post_pc_checkitem) (int retVal___, struct map_session_data *sd); typedef int (*HPMHOOK_pre_pc_useitem) (struct map_session_data **sd, int *n); typedef int (*HPMHOOK_post_pc_useitem) (int retVal___, struct map_session_data *sd, int n); -typedef int (*HPMHOOK_pre_pc_itemskill_clear) (struct map_session_data **sd); -typedef int (*HPMHOOK_post_pc_itemskill_clear) (int retVal___, struct map_session_data *sd); +typedef int (*HPMHOOK_pre_pc_autocast_clear) (struct map_session_data **sd); +typedef int (*HPMHOOK_post_pc_autocast_clear) (int retVal___, struct map_session_data *sd); typedef int (*HPMHOOK_pre_pc_skillatk_bonus) (struct map_session_data **sd, uint16 *skill_id); typedef int (*HPMHOOK_post_pc_skillatk_bonus) (int retVal___, struct map_session_data *sd, uint16 skill_id); typedef int (*HPMHOOK_pre_pc_skillheal_bonus) (struct map_session_data **sd, uint16 *skill_id); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index f94606bab..fed7e7a5e 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -4764,8 +4764,8 @@ struct { struct HPMHookPoint *HP_pc_checkitem_post; struct HPMHookPoint *HP_pc_useitem_pre; struct HPMHookPoint *HP_pc_useitem_post; - struct HPMHookPoint *HP_pc_itemskill_clear_pre; - struct HPMHookPoint *HP_pc_itemskill_clear_post; + struct HPMHookPoint *HP_pc_autocast_clear_pre; + struct HPMHookPoint *HP_pc_autocast_clear_post; struct HPMHookPoint *HP_pc_skillatk_bonus_pre; struct HPMHookPoint *HP_pc_skillatk_bonus_post; struct HPMHookPoint *HP_pc_skillheal_bonus_pre; @@ -11639,8 +11639,8 @@ struct { int HP_pc_checkitem_post; int HP_pc_useitem_pre; int HP_pc_useitem_post; - int HP_pc_itemskill_clear_pre; - int HP_pc_itemskill_clear_post; + int HP_pc_autocast_clear_pre; + int HP_pc_autocast_clear_post; int HP_pc_skillatk_bonus_pre; int HP_pc_skillatk_bonus_post; int HP_pc_skillheal_bonus_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index a360b3f53..8b38177ae 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -2440,7 +2440,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(pc->unequipitem_pos, HP_pc_unequipitem_pos) }, { HP_POP(pc->checkitem, HP_pc_checkitem) }, { HP_POP(pc->useitem, HP_pc_useitem) }, - { HP_POP(pc->itemskill_clear, HP_pc_itemskill_clear) }, + { HP_POP(pc->autocast_clear, HP_pc_autocast_clear) }, { HP_POP(pc->skillatk_bonus, HP_pc_skillatk_bonus) }, { HP_POP(pc->skillheal_bonus, HP_pc_skillheal_bonus) }, { HP_POP(pc->skillheal2_bonus, HP_pc_skillheal2_bonus) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 592279cc4..4b139b322 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -63359,14 +63359,14 @@ int HP_pc_useitem(struct map_session_data *sd, int n) { } return retVal___; } -int HP_pc_itemskill_clear(struct map_session_data *sd) { +int HP_pc_autocast_clear(struct map_session_data *sd) { int hIndex = 0; int retVal___ = 0; - if (HPMHooks.count.HP_pc_itemskill_clear_pre > 0) { + if (HPMHooks.count.HP_pc_autocast_clear_pre > 0) { int (*preHookFunc) (struct map_session_data **sd); *HPMforce_return = false; - for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_itemskill_clear_pre; hIndex++) { - preHookFunc = HPMHooks.list.HP_pc_itemskill_clear_pre[hIndex].func; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_autocast_clear_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_pc_autocast_clear_pre[hIndex].func; retVal___ = preHookFunc(&sd); } if (*HPMforce_return) { @@ -63375,12 +63375,12 @@ int HP_pc_itemskill_clear(struct map_session_data *sd) { } } { - retVal___ = HPMHooks.source.pc.itemskill_clear(sd); + retVal___ = HPMHooks.source.pc.autocast_clear(sd); } - if (HPMHooks.count.HP_pc_itemskill_clear_post > 0) { + if (HPMHooks.count.HP_pc_autocast_clear_post > 0) { int (*postHookFunc) (int retVal___, struct map_session_data *sd); - for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_itemskill_clear_post; hIndex++) { - postHookFunc = HPMHooks.list.HP_pc_itemskill_clear_post[hIndex].func; + for (hIndex = 0; hIndex < HPMHooks.count.HP_pc_autocast_clear_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_pc_autocast_clear_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); } } -- cgit v1.2.3-70-g09d2 From b6ecc4bf45b87261f4269e7d61683126c40780f1 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 21:35:47 +0100 Subject: Add pc_autocast_clear() function calls --- src/map/atcommand.c | 2 ++ src/map/clif.c | 4 ++-- src/map/pc.c | 6 +++--- src/map/script.c | 6 ++++++ src/map/skill.c | 10 +++++----- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 410cd7af7..d3368c3b0 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5671,6 +5671,8 @@ ACMD(useskill) return false; } + pc->autocast_clear(sd); + if (skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd && homun_alive(sd->hd)) // (If used with @useskill, put the homunc as dest) bl = &sd->hd->bl; diff --git a/src/map/clif.c b/src/map/clif.c index d7dffb293..6c693297d 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -12786,7 +12786,7 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill return; } - sd->skillitem = sd->skillitemlv = 0; + pc->autocast_clear(sd); if (skill_id >= GD_SKILLBASE && skill_id < GD_MAX) { if (sd->state.gmaster_flag) @@ -12914,7 +12914,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin unit->skilluse_pos(&sd->bl, x, y, skill_id, skill_lv); } else { int lv; - sd->skillitem = sd->skillitemlv = 0; + pc->autocast_clear(sd); if( (lv = pc->checkskill(sd, skill_id)) > 0 ) { if( skill_lv > lv ) skill_lv = lv; diff --git a/src/map/pc.c b/src/map/pc.c index 073c16029..b37afab86 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -8129,9 +8129,9 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src) clif->party_dead_notification(sd); - //Reset menu skills/item skills - if (sd->skillitem) - sd->skillitem = sd->skillitemlv = 0; + pc->autocast_clear(sd); // Unset auto-cast data. + + // Reset menu skills. if (sd->menuskill_id) sd->menuskill_id = sd->menuskill_val = 0; //Reset ticks. diff --git a/src/map/script.c b/src/map/script.c index b08613ec3..5e285020f 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -21436,7 +21436,10 @@ static BUILDIN(unitskilluseid) } else { status_calc_npc(nd, SCO_NONE); } + } else if (bl->type == BL_PC) { + pc->autocast_clear(BL_UCAST(BL_PC, bl)); } + unit->skilluse_id(bl, target_id, skill_id, skill_lv); } @@ -21472,7 +21475,10 @@ static BUILDIN(unitskillusepos) } else { status_calc_npc(nd, SCO_NONE); } + } else if (bl->type == BL_PC) { + pc->autocast_clear(BL_UCAST(BL_PC, bl)); } + unit->skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv); } diff --git a/src/map/skill.c b/src/map/skill.c index f28d50c6e..f679c3f6a 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5883,7 +5883,7 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) } if( sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL ) // they just set the data so leave it as it is.[Inkfish] - sd->skillitem = sd->skillitemlv = 0; + pc->autocast_clear(sd); if (ud->skilltimer == INVALID_TIMER) { if(md) md->skill_idx = -1; @@ -5939,7 +5939,7 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) //sent in ALL cases, even cases where skill_check_condition fails //which would lead to double 'skill failed' messages u.u [Skotlex] if(sd) - sd->skillitem = sd->skillitemlv = 0; + pc->autocast_clear(sd); else if(md) md->skill_idx = -1; return 0; @@ -10870,7 +10870,7 @@ static int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) skill->castend_pos2(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv,tick,0); if( sd && sd->skillitem != AL_WARP ) // Warp-Portal thru items will clear data in skill_castend_map. [Inkfish] - sd->skillitem = sd->skillitemlv = 0; + pc->autocast_clear(sd); unit->set_dir(src, map->calc_dir(src, ud->skillx, ud->skilly)); @@ -10888,7 +10888,7 @@ static int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) ud->canact_tick = tick; ud->skill_id = ud->skill_lv = 0; if(sd) - sd->skillitem = sd->skillitemlv = 0; + pc->autocast_clear(sd); else if(md) md->skill_idx = -1; return 0; @@ -11041,7 +11041,7 @@ static int skill_castend_map(struct map_session_data *sd, uint16 skill_id, const } skill->consume_requirement(sd,sd->menuskill_id,lv,2); - sd->skillitem = sd->skillitemlv = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish] + pc->autocast_clear(sd); // Clear data which was skipped in skill_castend_pos(). if((group=skill->unitsetting(&sd->bl,skill_id,lv,wx,wy,0))==NULL) { skill_failed(sd); -- cgit v1.2.3-70-g09d2 From 017b07dab50b4cbd84d20bd3003a3bd9939e20c7 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 21:39:58 +0100 Subject: Remove misplaced pc_autocast_clear() function call --- src/map/skill.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/map/skill.c b/src/map/skill.c index f679c3f6a..bff9c0e5c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4219,11 +4219,6 @@ static void skill_castend_type(int type, struct block_list *src, struct block_li skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, flag); break; } - - struct map_session_data *sd = BL_CAST(BL_PC, src); - - if (sd != NULL) - pc->autocast_clear(sd); } /*========================================== -- cgit v1.2.3-70-g09d2 From 4470161450c46a8cb52cb095577b43f2b6e29e5a Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 21:53:59 +0100 Subject: Add skill_validate_autocast_data() function --- src/map/skill.c | 26 ++++++++++++++++++++++++++ src/map/skill.h | 1 + 2 files changed, 27 insertions(+) diff --git a/src/map/skill.c b/src/map/skill.c index bff9c0e5c..abc5e60c4 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1177,6 +1177,31 @@ static int skillnotok_mercenary(uint16 skill_id, struct mercenary_data *md) return skill->not_ok(skill_id, md->master); } +/** + * Validates the plausibility of auto-cast related data and calls pc_autocast_clear() if necessary. + * + * @param sd The character who cast the skill. + * @param skill_id The cast skill's ID. + * @param skill_lv The cast skill's level. (clif_parse_UseSkillMap() passes 0.) + * + **/ +static void skill_validate_autocast_data(struct map_session_data *sd, int skill_id, int skill_lv) +{ + nullpo_retv(sd); + + // Determine if called by clif_parse_UseSkillMap(). + bool use_skill_map = (skill_lv == 0 && (skill_id == AL_WARP || skill_id == AL_TELEPORT)); + + if (sd->autocast.type == AUTOCAST_NONE) + pc->autocast_clear(sd); // No auto-cast type set. Preventively unset all auto-cast related data. + else if (sd->autocast.type == AUTOCAST_TEMP) + pc->autocast_clear(sd); // AUTOCAST_TEMP should have been unset straight after usage. + else if (sd->autocast.skill_id == 0 || skill_id == 0 || sd->autocast.skill_id != skill_id) + pc->autocast_clear(sd); // Implausible skill ID. + else if (sd->autocast.skill_lv == 0 || (!use_skill_map && (skill_lv == 0 || sd->autocast.skill_lv != skill_lv))) + pc->autocast_clear(sd); // Implausible skill level. +} + static struct s_skill_unit_layout *skill_get_unit_layout(uint16 skill_id, uint16 skill_lv, struct block_list *src, int x, int y) { int pos = skill->get_unit_layout_type(skill_id,skill_lv); @@ -21685,6 +21710,7 @@ void skill_defaults(void) skill->not_ok_hom = skillnotok_hom; skill->not_ok_hom_unknown = skillnotok_hom_unknown; skill->not_ok_mercenary = skillnotok_mercenary; + skill->validate_autocast_data = skill_validate_autocast_data; skill->chastle_mob_changetarget = skill_chastle_mob_changetarget; skill->can_produce_mix = skill_can_produce_mix; skill->produce_mix = skill_produce_mix; diff --git a/src/map/skill.h b/src/map/skill.h index b241e0498..731044876 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2055,6 +2055,7 @@ struct skill_interface { int (*not_ok_hom) (uint16 skill_id, struct homun_data *hd); int (*not_ok_hom_unknown) (uint16 skill_id, struct homun_data *hd); int (*not_ok_mercenary) (uint16 skill_id, struct mercenary_data *md); + void (*validate_autocast_data) (struct map_session_data *sd, int skill_id, int skill_lv); int (*chastle_mob_changetarget) (struct block_list *bl,va_list ap); int (*can_produce_mix) ( struct map_session_data *sd, int nameid, int trigger, int qty); int (*produce_mix) ( struct map_session_data *sd, uint16 skill_id, int nameid, int slot1, int slot2, int slot3, int qty ); -- cgit v1.2.3-70-g09d2 From b151b29cf072ed336214c2d0ca43e6db34a773ad Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 22:07:36 +0100 Subject: Add skill_validate_autocast_data() function calls --- src/map/clif.c | 24 ++++++++++++++++++++++++ src/map/unit.c | 12 ++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 6c693297d..66533a6fc 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -12706,6 +12706,14 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill { int64 tick = timer->gettick(); + /** + * According to Skotlex' comment below, the client sometimes passes 0 for the skill level. + * Even though this seems to only affect guild skills, sd->autocast.skill_lv is used + * for the auto-cast data validation if skill_lv is 0. + * + **/ + skill->validate_autocast_data(sd, skill_id, (skill_lv == 0) ? sd->autocast.skill_lv : skill_lv); + if (skill_lv < 1) skill_lv = 1; //No clue, I have seen the client do this with guild skills :/ [Skotlex] @@ -12847,6 +12855,16 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin int64 tick = timer->gettick(); nullpo_retv(sd); + + /** + * When using clif_item_skill() to initiate the execution of ground skills, + * the client sometimes passes 0 for the skill level in packet 0x0af4. + * In that case sd->autocast.skill_lv is used for the auto-cast data validation, + * since clif_item_skill() is only used for auto-cast skills. + * + **/ + skill->validate_autocast_data(sd, skill_id, (skill_lv == 0) ? sd->autocast.skill_lv : skill_lv); + if( !(skill->get_inf(skill_id)&INF_GROUND_SKILL) ) return; //Using a target skill on the ground? WRONG. @@ -12985,6 +13003,12 @@ static void clif_parse_UseSkillMap(int fd, struct map_session_data *sd) return; } + /** + * Since no skill level was passed use 0 to notify skill_validate_autocast_data() of this special case. + * + **/ + skill->validate_autocast_data(sd, skill_id, 0); + pc->delinvincibletimer(sd); skill->castend_map(sd,skill_id,map_name); pc->autocast_clear(sd); diff --git a/src/map/unit.c b/src/map/unit.c index 984cc6802..c1da2c72b 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1145,8 +1145,10 @@ static int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_ int ret = unit->skilluse_id2(src, target_id, skill_id, skill_lv, casttime, castcancel); struct map_session_data *sd = BL_CAST(BL_PC, src); - if (sd != NULL && (ret == 0 || !skill->is_item_skill(sd, skill_id, skill_lv))) - pc->autocast_clear(sd); + if (sd != NULL && ret == 0) + pc->autocast_clear(sd); // Error in unit_skilluse_id2(). + else if (sd != NULL && ret != 0 && skill_id != SA_ABRACADABRA && skill_id != WM_RANDOMIZESPELL) + skill->validate_autocast_data(sd, skill_id, skill_lv); return ret; } @@ -1782,8 +1784,10 @@ static int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_ int ret = unit->skilluse_pos2(src, skill_x, skill_y, skill_id, skill_lv, casttime, castcancel); struct map_session_data *sd = BL_CAST(BL_PC, src); - if (sd != NULL && (ret == 0 || !skill->is_item_skill(sd, skill_id, skill_lv))) - pc->autocast_clear(sd); + if (sd != NULL && ret == 0) + pc->autocast_clear(sd); // Error in unit_skilluse_pos2(). + else if (sd != NULL && ret != 0 && skill_id != SA_ABRACADABRA && skill_id != WM_RANDOMIZESPELL) + skill->validate_autocast_data(sd, skill_id, skill_lv); return ret; } -- cgit v1.2.3-70-g09d2 From 7d70f7ec35b0b4476686b73fc221527a6d1ed0fa Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 22:22:59 +0100 Subject: Remove map_session_data->state.autocast and use map_session_data->autocast.type instead --- src/map/battle.c | 14 +------------- src/map/pc.h | 1 - src/map/skill.c | 20 +++++--------------- 3 files changed, 6 insertions(+), 29 deletions(-) diff --git a/src/map/battle.c b/src/map/battle.c index e73c93bab..6519b1f37 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -5928,17 +5928,10 @@ static void battle_reflect_damage(struct block_list *target, struct block_list * delay += 100;/* gradual increase so the numbers don't clip in the client */ } if( sc->data[SC_LG_REFLECTDAMAGE] && rnd()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) { - bool change = false; - NORMALIZE_RDAMAGE(damage * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100); trdamage -= rdamage;/* wont count towards total */ - if( sd && !sd->state.autocast ) { - change = true; - sd->state.autocast = 1; - } - enum autocast_type ac_type; if (sd != NULL) { @@ -5951,9 +5944,6 @@ static void battle_reflect_damage(struct block_list *target, struct block_list * if (sd != NULL) sd->autocast.type = ac_type; - if( change ) - sd->state.autocast = 0; - delay += 150;/* gradual increase so the numbers don't clip in the client */ if( (--sc->data[SC_LG_REFLECTDAMAGE]->val3) <= 0 ) @@ -6142,7 +6132,7 @@ static int battle_damage_area(struct block_list *bl, va_list ap) else status_fix_damage(src,bl,damage,0); clif->damage(bl,bl,amotion,dmotion,damage,1,BDT_ENDURE,0); - if (src->type != BL_PC || !BL_UCCAST(BL_PC, src)->state.autocast) + if (src->type != BL_PC || BL_UCCAST(BL_PC, src)->autocast.type != AUTOCAST_TEMP) skill->additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); map->freeblock_unlock(); } @@ -6466,12 +6456,10 @@ static enum damage_lv battle_weapon_attack(struct block_list *src, struct block_ } } - sd->state.autocast = 1; sd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(sd,r_skill,r_lv,3); skill->castend_type(type, src, target, r_skill, r_lv, tick, flag); sd->autocast.type = AUTOCAST_NONE; - sd->state.autocast = 0; sd->ud.canact_tick = tick + skill->delay_fix(src, r_skill, r_lv); clif->status_change(src, status->get_sc_icon(SC_POSTDELAY), status->get_sc_relevant_bl_types(SC_POSTDELAY), 1, skill->delay_fix(src, r_skill, r_lv), 0, 0, 1); } diff --git a/src/map/pc.h b/src/map/pc.h index 92444aa2a..7e69169f0 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -207,7 +207,6 @@ struct map_session_data { unsigned int storage_flag : 2; // @see enum storage_flag unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used. unsigned int abra_flag : 2; // Abracadabra bugfix by Aru - unsigned int autocast : 1; // Autospell flag [Inkfish] unsigned int autotrade : 2; //By Fantik unsigned int showdelay :1; unsigned int showexp :1; diff --git a/src/map/skill.c b/src/map/skill.c index abc5e60c4..dfc939c6f 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1017,7 +1017,7 @@ static int skillnotok(uint16 skill_id, struct map_session_data *sd) // This code will compare the player's attack motion value which is influenced by ASPD before // allowing a skill to be cast. This is to prevent no-delay ACT files from spamming skills such as // AC_DOUBLE which do not have a skill delay and are not regarded in terms of attack motion. - if( !sd->state.autocast && sd->skillitem != skill_id && sd->canskill_tick && + if (sd->autocast.type == AUTOCAST_NONE && sd->canskill_tick != 0 && DIFF_TICK(timer->gettick(), sd->canskill_tick) < (sd->battle_status.amotion * (battle_config.skill_amotion_leniency) / 100) ) {// attempted to cast a skill before the attack motion has finished return 1; @@ -2090,11 +2090,9 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl temp = (sd->autospell[i].id > 0) ? sd->autospell[i].id : -sd->autospell[i].id; - sd->state.autocast = 1; sd->autocast.type = AUTOCAST_TEMP; notok = skill->not_ok(temp, sd); sd->autocast.type = AUTOCAST_NONE; - sd->state.autocast = 0; if ( notok ) continue; @@ -2145,13 +2143,12 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl else if (temp == PF_SPIDERWEB) //Special case, due to its nature of coding. type = CAST_GROUND; - sd->state.autocast = 1; sd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(sd,temp,auto_skill_lv,1); skill->toggle_magicpower(src, temp); skill->castend_type(type, src, tbl, temp, auto_skill_lv, tick, 0); sd->autocast.type = AUTOCAST_NONE; - sd->state.autocast = 0; + //Set canact delay. [Skotlex] ud = unit->bl2ud(src); if (ud) { @@ -2232,11 +2229,9 @@ static int skill_onskillusage(struct map_session_data *sd, struct block_list *bl temp = (sd->autospell3[i].id > 0) ? sd->autospell3[i].id : -sd->autospell3[i].id; - sd->state.autocast = 1; sd->autocast.type = AUTOCAST_TEMP; notok = skill->not_ok(temp, sd); sd->autocast.type = AUTOCAST_NONE; - sd->state.autocast = 0; if ( notok ) continue; @@ -2282,14 +2277,12 @@ static int skill_onskillusage(struct map_session_data *sd, struct block_list *bl !battle->check_range(&sd->bl, tbl, skill->get_range2(&sd->bl, temp,skill_lv) + (temp == RG_CLOSECONFINE?0:1)) ) continue; - sd->state.autocast = 1; sd->autospell3[i].lock = true; sd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(sd,temp,skill_lv,1); skill->castend_type(type, &sd->bl, tbl, temp, skill_lv, tick, 0); sd->autocast.type = AUTOCAST_NONE; sd->autospell3[i].lock = false; - sd->state.autocast = 0; } sd->autocast.type = ac_type; @@ -2458,11 +2451,9 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_ if (attack_type&BF_LONG) rate>>=1; - dstsd->state.autocast = 1; dstsd->autocast.type = AUTOCAST_TEMP; notok = skill->not_ok(auto_skill_id, dstsd); dstsd->autocast.type = AUTOCAST_NONE; - dstsd->state.autocast = 0; if ( notok ) continue; @@ -2503,12 +2494,11 @@ static int skill_counter_additional_effect(struct block_list *src, struct block_ if( !battle->check_range(src, tbl, skill->get_range2(src, auto_skill_id,auto_skill_lv) + (auto_skill_id == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range ) continue; - dstsd->state.autocast = 1; dstsd->autocast.type = AUTOCAST_TEMP; skill->consume_requirement(dstsd,auto_skill_id,auto_skill_lv,1); skill->castend_type(type, bl, tbl, auto_skill_id, auto_skill_lv, tick, 0); dstsd->autocast.type = AUTOCAST_NONE; - dstsd->state.autocast = 0; + // Set canact delay. [Skotlex] ud = unit->bl2ud(bl); if (ud) { @@ -7512,7 +7502,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * break; } - if( sd->state.autocast || ( (sd->skillitem == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skill_lv == 1 ) || skill_lv == 3 ) + if (sd->autocast.type == AUTOCAST_TEMP || ((sd->skillitem == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skill_lv == 1) || skill_lv == 3) { if( skill_lv == 1 ) pc->randomwarp(sd,CLR_TELEPORT); @@ -15302,7 +15292,7 @@ static int skill_consume_requirement(struct map_session_data *sd, uint16 skill_i break; default: - if (sd->state.autocast == 1 || sd->skillitem == skill_id) /// Skill casting items and Hocus-Pocus skills don't consume SP. [Kenpachi] + if (sd->autocast.type != AUTOCAST_NONE) // Auto-cast skills don't consume SP. req.sp = 0; break; -- cgit v1.2.3-70-g09d2 From 492c7bc03c5a40957677f2d98c7d61961dfa6113 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 22:53:36 +0100 Subject: Remove map_session_data->state.abra_flag and use map_session_data->autocast.type instead --- src/map/pc.c | 7 ++++--- src/map/pc.h | 1 - src/map/skill.c | 8 +++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/map/pc.c b/src/map/pc.c index b37afab86..3cfe28a11 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5295,9 +5295,10 @@ static int pc_useitem(struct map_session_data *sd, int n) if(sd->catch_target_class != -1) //Abort pet catching. sd->catch_target_class = -1; - // Removes abracadabra/randomize spell flag for delayed consume items or item doesn't get consumed - if (sd->inventory_data[n]->flag.delay_consume) - sd->state.abra_flag = 0; + // Unset auto-cast related data for items of type IT_DELAYCONSUME or the item won't be consumed. + // TODO: Check if this is still required. [Kenpachi] + if (sd->inventory_data[n]->flag.delay_consume != 0) + sd->autocast.type = AUTOCAST_NONE; amount = sd->status.inventory[n].amount; //Check if the item is to be consumed immediately [Skotlex] diff --git a/src/map/pc.h b/src/map/pc.h index 7e69169f0..a0566fadc 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -206,7 +206,6 @@ struct map_session_data { unsigned int rest : 1; unsigned int storage_flag : 2; // @see enum storage_flag unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used. - unsigned int abra_flag : 2; // Abracadabra bugfix by Aru unsigned int autotrade : 2; //By Fantik unsigned int showdelay :1; unsigned int showexp :1; diff --git a/src/map/skill.c b/src/map/skill.c index dfc939c6f..d21a19742 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6334,7 +6334,6 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * sd->autocast.type = AUTOCAST_ABRA; sd->autocast.skill_id = abra_skill_id; sd->autocast.skill_lv = abra_skill_lv; - sd->state.abra_flag = 1; sd->skillitem = abra_skill_id; sd->skillitemlv = abra_skill_lv; clif->item_skill(sd, abra_skill_id, abra_skill_lv); @@ -10079,7 +10078,6 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * sd->autocast.type = AUTOCAST_IMPROVISE; sd->autocast.skill_id = improv_skill_id; sd->autocast.skill_lv = improv_skill_lv; - sd->state.abra_flag = 2; sd->skillitem = improv_skill_id; sd->skillitemlv = improv_skill_lv; clif->item_skill(sd, improv_skill_id, improv_skill_lv); @@ -14118,9 +14116,9 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s sc = NULL; if( sd->skillitem == skill_id ) { - if( sd->state.abra_flag ) // Hocus-Pocus was used. [Inkfish] - sd->state.abra_flag = 0; - else { + if (sd->autocast.type == AUTOCAST_ABRA || sd->autocast.type == AUTOCAST_IMPROVISE) { // Abracadabra or Improvised Song was used. + sd->autocast.type = AUTOCAST_NONE; + } else { int i; // When a target was selected, consume items that were skipped in pc_use_item [Skotlex] if( (i = sd->itemindex) == -1 || -- cgit v1.2.3-70-g09d2 From 49d0ce1c60455e4971c7bf9c80f4b92ce49f377f Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 23:02:24 +0100 Subject: Remove skill_is_item_skill() function and use map_session_data->autocast.type instead --- src/map/clif.c | 2 +- src/map/skill.c | 23 +++--------------- src/map/skill.h | 1 - src/map/unit.c | 4 ++-- src/plugins/HPMHooking/HPMHooking.Defs.inc | 2 -- .../HPMHooking/HPMHooking_map.HPMHooksCore.inc | 4 ---- .../HPMHooking/HPMHooking_map.HookingPoints.inc | 1 - src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 27 ---------------------- 8 files changed, 6 insertions(+), 58 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 66533a6fc..1a99a07f3 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -6766,7 +6766,7 @@ static void clif_item_skill(struct map_session_data *sd, uint16 skill_id, uint16 struct PACKET_ZC_AUTORUN_SKILL *p = WFIFOP(fd, 0); int type = skill->get_inf(skill_id); - if (sd->state.itemskill_castonself == 1 && skill->is_item_skill(sd, skill_id, skill_lv)) + if (sd->state.itemskill_castonself == 1 && sd->autocast.type == AUTOCAST_ITEM) type = INF_SELF_SKILL; p->packetType = HEADER_ZC_AUTORUN_SKILL; diff --git a/src/map/skill.c b/src/map/skill.c index d21a19742..14bc9460e 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -14048,22 +14048,6 @@ static bool skill_is_combo(int skill_id) return false; } -/** - * Checks if a skill is casted by an item (itemskill() script command). - * - * @param sd The charcater's session data. - * @param skill_id The skill's ID. - * @param skill_lv The skill's level. - * @return true if skill is casted by an item, otherwise false. - */ -static bool skill_is_item_skill(struct map_session_data *sd, int skill_id, int skill_lv) -{ - nullpo_retr(false, sd); - - return (sd->skillitem == skill_id && sd->skillitemlv == skill_lv - && sd->itemskill_id == skill_id && sd->itemskill_lv == skill_lv); -} - static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv) { struct status_data *st; @@ -14079,7 +14063,7 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s return 0; if ((sd->state.itemskill_conditions_checked == 1 || sd->state.itemskill_check_conditions == 0) - && skill->is_item_skill(sd, skill_id, skill_lv)) { + && sd->autocast.type == AUTOCAST_ITEM) { return 1; } @@ -15068,7 +15052,7 @@ static int skill_check_condition_castend(struct map_session_data *sd, uint16 ski return 0; if ((sd->state.itemskill_conditions_checked == 1 || sd->state.itemskill_check_conditions == 0) - && skill->is_item_skill(sd, skill_id, skill_lv)) { + && sd->autocast.type == AUTOCAST_ITEM) { return 1; } @@ -15273,7 +15257,7 @@ static int skill_consume_requirement(struct map_session_data *sd, uint16 skill_i nullpo_ret(sd); - if (sd->state.itemskill_check_conditions == 0 && skill->is_item_skill(sd, skill_id, skill_lv)) + if (sd->state.itemskill_check_conditions == 0 && sd->autocast.type == AUTOCAST_ITEM) return 1; req = skill->get_requirement(sd,skill_id,skill_lv); @@ -21672,7 +21656,6 @@ void skill_defaults(void) skill->cast_fix_sc = skill_castfix_sc; skill->vf_cast_fix = skill_vfcastfix; skill->delay_fix = skill_delay_fix; - skill->is_item_skill = skill_is_item_skill; skill->check_condition_castbegin = skill_check_condition_castbegin; skill->check_condition_castend = skill_check_condition_castend; skill->consume_requirement = skill_consume_requirement; diff --git a/src/map/skill.h b/src/map/skill.h index 731044876..65195dc75 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2029,7 +2029,6 @@ struct skill_interface { int (*cast_fix_sc) ( struct block_list *bl, int time); int (*vf_cast_fix) ( struct block_list *bl, double time, uint16 skill_id, uint16 skill_lv); int (*delay_fix) ( struct block_list *bl, uint16 skill_id, uint16 skill_lv); - bool (*is_item_skill) (struct map_session_data *sd, int skill_id, int skill_lv); int (*check_condition_castbegin) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv); int (*check_condition_castend) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv); int (*consume_requirement) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type); diff --git a/src/map/unit.c b/src/map/unit.c index c1da2c72b..ab6f345ed 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1707,7 +1707,7 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill if (!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026 unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);// even though this is not how official works but this will do the trick. bugreport:6829 - if (sd != NULL && sd->state.itemskill_no_casttime == 1 && skill->is_item_skill(sd, skill_id, skill_lv)) + if (sd != NULL && sd->state.itemskill_no_casttime == 1 && sd->autocast.type == AUTOCAST_ITEM) casttime = 0; // in official this is triggered even if no cast time. @@ -1915,7 +1915,7 @@ static int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); - if (sd != NULL && sd->state.itemskill_no_casttime == 1 && skill->is_item_skill(sd, skill_id, skill_lv)) + if (sd != NULL && sd->state.itemskill_no_casttime == 1 && sd->autocast.type == AUTOCAST_ITEM) casttime = 0; // in official this is triggered even if no cast time. diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index edfd60fbc..018170812 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -7332,8 +7332,6 @@ typedef int (*HPMHOOK_pre_skill_vf_cast_fix) (struct block_list **bl, double *ti typedef int (*HPMHOOK_post_skill_vf_cast_fix) (int retVal___, struct block_list *bl, double time, uint16 skill_id, uint16 skill_lv); typedef int (*HPMHOOK_pre_skill_delay_fix) (struct block_list **bl, uint16 *skill_id, uint16 *skill_lv); typedef int (*HPMHOOK_post_skill_delay_fix) (int retVal___, struct block_list *bl, uint16 skill_id, uint16 skill_lv); -typedef bool (*HPMHOOK_pre_skill_is_item_skill) (struct map_session_data **sd, int *skill_id, int *skill_lv); -typedef bool (*HPMHOOK_post_skill_is_item_skill) (bool retVal___, struct map_session_data *sd, int skill_id, int skill_lv); typedef int (*HPMHOOK_pre_skill_check_condition_castbegin) (struct map_session_data **sd, uint16 *skill_id, uint16 *skill_lv); typedef int (*HPMHOOK_post_skill_check_condition_castbegin) (int retVal___, struct map_session_data *sd, uint16 skill_id, uint16 skill_lv); typedef int (*HPMHOOK_pre_skill_check_condition_castend) (struct map_session_data **sd, uint16 *skill_id, uint16 *skill_lv); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index fed7e7a5e..8912ad8ef 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -5856,8 +5856,6 @@ struct { struct HPMHookPoint *HP_skill_vf_cast_fix_post; struct HPMHookPoint *HP_skill_delay_fix_pre; struct HPMHookPoint *HP_skill_delay_fix_post; - struct HPMHookPoint *HP_skill_is_item_skill_pre; - struct HPMHookPoint *HP_skill_is_item_skill_post; struct HPMHookPoint *HP_skill_check_condition_castbegin_pre; struct HPMHookPoint *HP_skill_check_condition_castbegin_post; struct HPMHookPoint *HP_skill_check_condition_castend_pre; @@ -12731,8 +12729,6 @@ struct { int HP_skill_vf_cast_fix_post; int HP_skill_delay_fix_pre; int HP_skill_delay_fix_post; - int HP_skill_is_item_skill_pre; - int HP_skill_is_item_skill_post; int HP_skill_check_condition_castbegin_pre; int HP_skill_check_condition_castbegin_post; int HP_skill_check_condition_castend_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index 8b38177ae..9458fc2f6 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -2997,7 +2997,6 @@ struct HookingPointData HookingPoints[] = { { HP_POP(skill->cast_fix_sc, HP_skill_cast_fix_sc) }, { HP_POP(skill->vf_cast_fix, HP_skill_vf_cast_fix) }, { HP_POP(skill->delay_fix, HP_skill_delay_fix) }, - { HP_POP(skill->is_item_skill, HP_skill_is_item_skill) }, { HP_POP(skill->check_condition_castbegin, HP_skill_check_condition_castbegin) }, { HP_POP(skill->check_condition_castend, HP_skill_check_condition_castend) }, { HP_POP(skill->consume_requirement, HP_skill_consume_requirement) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 4b139b322..04706b751 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -78163,33 +78163,6 @@ int HP_skill_delay_fix(struct block_list *bl, uint16 skill_id, uint16 skill_lv) } return retVal___; } -bool HP_skill_is_item_skill(struct map_session_data *sd, int skill_id, int skill_lv) { - int hIndex = 0; - bool retVal___ = false; - if (HPMHooks.count.HP_skill_is_item_skill_pre > 0) { - bool (*preHookFunc) (struct map_session_data **sd, int *skill_id, int *skill_lv); - *HPMforce_return = false; - for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_is_item_skill_pre; hIndex++) { - preHookFunc = HPMHooks.list.HP_skill_is_item_skill_pre[hIndex].func; - retVal___ = preHookFunc(&sd, &skill_id, &skill_lv); - } - if (*HPMforce_return) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.skill.is_item_skill(sd, skill_id, skill_lv); - } - if (HPMHooks.count.HP_skill_is_item_skill_post > 0) { - bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int skill_id, int skill_lv); - for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_is_item_skill_post; hIndex++) { - postHookFunc = HPMHooks.list.HP_skill_is_item_skill_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, skill_id, skill_lv); - } - } - return retVal___; -} int HP_skill_check_condition_castbegin(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv) { int hIndex = 0; int retVal___ = 0; -- cgit v1.2.3-70-g09d2 From d92d1772e8dd2fc65fd009247b7009f26ae73b66 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 23:05:28 +0100 Subject: Remove itemskill_id and itemskill_lv helper variables, since they are not used anymore --- src/map/pc.c | 2 -- src/map/pc.h | 9 --------- src/map/script.c | 4 ---- 3 files changed, 15 deletions(-) diff --git a/src/map/pc.c b/src/map/pc.c index 3cfe28a11..8586270b8 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5354,8 +5354,6 @@ static int pc_autocast_clear(struct map_session_data *sd) sd->autocast.itemskill_check_conditions = false; sd->autocast.itemskill_instant_cast = false; sd->autocast.itemskill_cast_on_self = false; - sd->itemskill_id = 0; - sd->itemskill_lv = 0; sd->state.itemskill_conditions_checked = 0; sd->state.itemskill_check_conditions = 0; sd->state.itemskill_no_casttime = 0; diff --git a/src/map/pc.h b/src/map/pc.h index a0566fadc..83b86b68b 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -657,15 +657,6 @@ END_ZEROED_BLOCK; bool achievements_received; // Title VECTOR_DECL(int) title_ids; - - /* - * itemskill_conditions_checked/itemskill_no_conditions/itemskill_no_casttime/itemskill_castonself abuse prevention. - * If a skill, casted by itemskill() script command, is aborted while target selection, - * the map server gets no notification where these states could be unset. - * Thus we need this helper variables to prevent abusing these states for next skill cast. - */ - int itemskill_id; - int itemskill_lv; }; #define EQP_WEAPON EQP_HAND_R diff --git a/src/map/script.c b/src/map/script.c index 5e285020f..b8f8d7638 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11030,10 +11030,6 @@ static BUILDIN(itemskill) sd->autocast.itemskill_instant_cast = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST); sd->autocast.itemskill_cast_on_self = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF); - // itemskill_conditions_checked/itemskill_no_conditions/itemskill_no_casttime/itemskill_castonself abuse prevention. Unset in pc_autocast_clear(). - sd->itemskill_id = sd->skillitem; - sd->itemskill_lv = sd->skillitemlv; - clif->item_skill(sd, sd->skillitem, sd->skillitemlv); return true; -- cgit v1.2.3-70-g09d2 From 12de22e7008081c94631c8730d05d487e7b0cfcc Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Wed, 11 Mar 2020 23:16:29 +0100 Subject: Remove map_session_data->state.itemskill_* and use map_session_data->autocast.itemskill_* instead --- src/map/clif.c | 2 +- src/map/pc.c | 4 ---- src/map/pc.h | 4 ---- src/map/script.c | 7 +------ src/map/skill.c | 6 +++--- src/map/unit.c | 4 ++-- 6 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 1a99a07f3..6b5c57d46 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -6766,7 +6766,7 @@ static void clif_item_skill(struct map_session_data *sd, uint16 skill_id, uint16 struct PACKET_ZC_AUTORUN_SKILL *p = WFIFOP(fd, 0); int type = skill->get_inf(skill_id); - if (sd->state.itemskill_castonself == 1 && sd->autocast.type == AUTOCAST_ITEM) + if (sd->autocast.itemskill_cast_on_self && sd->autocast.type == AUTOCAST_ITEM) type = INF_SELF_SKILL; p->packetType = HEADER_ZC_AUTORUN_SKILL; diff --git a/src/map/pc.c b/src/map/pc.c index 8586270b8..e181b5f89 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5354,10 +5354,6 @@ static int pc_autocast_clear(struct map_session_data *sd) sd->autocast.itemskill_check_conditions = false; sd->autocast.itemskill_instant_cast = false; sd->autocast.itemskill_cast_on_self = false; - sd->state.itemskill_conditions_checked = 0; - sd->state.itemskill_check_conditions = 0; - sd->state.itemskill_no_casttime = 0; - sd->state.itemskill_castonself = 0; return 1; } diff --git a/src/map/pc.h b/src/map/pc.h index 83b86b68b..2991bfc68 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -250,10 +250,6 @@ struct map_session_data { unsigned int refine_ui : 1; unsigned int npc_unloaded : 1; ///< The player is talking with an unloaded NPCs (respawned tombstones) unsigned int lapine_ui : 1; - unsigned int itemskill_conditions_checked : 1; // Used by itemskill() script command, to prevent second check of conditions after target was selected. - unsigned int itemskill_check_conditions : 1; // Used by itemskill() script command, to check skill conditions and consume them. - unsigned int itemskill_no_casttime : 1; // Used by itemskill() script command, to cast skill instantaneously. - unsigned int itemskill_castonself : 1; // Used by itemskill() script command, to forcefully cast skill on invoking character. } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; diff --git a/src/map/script.c b/src/map/script.c index b8f8d7638..6ed94bc92 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11007,26 +11007,21 @@ static BUILDIN(itemskill) sd->autocast.skill_lv = script_getnum(st, 3); sd->skillitem = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); sd->skillitemlv = script_getnum(st, 3); - sd->state.itemskill_conditions_checked = 0; // Skill casting items will check the conditions prior to the target selection in AEGIS. Thus we need a flag to prevent checking them twice. int flag = script_hasdata(st, 4) ? script_getnum(st, 4) : ISF_NONE; - sd->state.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS) ? 1 : 0; // Unset in pc_autocast_clear(). sd->autocast.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS); - if (sd->state.itemskill_check_conditions == 1) { + if (sd->autocast.itemskill_check_conditions) { if (skill->check_condition_castbegin(sd, sd->skillitem, sd->skillitemlv) == 0 || skill->check_condition_castend(sd, sd->skillitem, sd->skillitemlv) == 0) { pc->autocast_clear(sd); return true; } - sd->state.itemskill_conditions_checked = 1; // Unset in pc_autocast_clear(). sd->autocast.itemskill_conditions_checked = true; } - sd->state.itemskill_no_casttime = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST) ? 1 : 0; // Unset in pc_autocast_clear(). - sd->state.itemskill_castonself = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF) ? 1 : 0; // Unset in pc_autocast_clear(). sd->autocast.itemskill_instant_cast = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST); sd->autocast.itemskill_cast_on_self = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF); diff --git a/src/map/skill.c b/src/map/skill.c index 14bc9460e..001c11c36 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -14062,7 +14062,7 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s if (sd->chat_id != 0) return 0; - if ((sd->state.itemskill_conditions_checked == 1 || sd->state.itemskill_check_conditions == 0) + if ((sd->autocast.itemskill_conditions_checked || !sd->autocast.itemskill_check_conditions) && sd->autocast.type == AUTOCAST_ITEM) { return 1; } @@ -15051,7 +15051,7 @@ static int skill_check_condition_castend(struct map_session_data *sd, uint16 ski if (sd->chat_id != 0) return 0; - if ((sd->state.itemskill_conditions_checked == 1 || sd->state.itemskill_check_conditions == 0) + if ((sd->autocast.itemskill_conditions_checked || !sd->autocast.itemskill_check_conditions) && sd->autocast.type == AUTOCAST_ITEM) { return 1; } @@ -15257,7 +15257,7 @@ static int skill_consume_requirement(struct map_session_data *sd, uint16 skill_i nullpo_ret(sd); - if (sd->state.itemskill_check_conditions == 0 && sd->autocast.type == AUTOCAST_ITEM) + if (!sd->autocast.itemskill_check_conditions && sd->autocast.type == AUTOCAST_ITEM) return 1; req = skill->get_requirement(sd,skill_id,skill_lv); diff --git a/src/map/unit.c b/src/map/unit.c index ab6f345ed..ad4dc88b5 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1707,7 +1707,7 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill if (!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026 unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);// even though this is not how official works but this will do the trick. bugreport:6829 - if (sd != NULL && sd->state.itemskill_no_casttime == 1 && sd->autocast.type == AUTOCAST_ITEM) + if (sd != NULL && sd->autocast.itemskill_instant_cast && sd->autocast.type == AUTOCAST_ITEM) casttime = 0; // in official this is triggered even if no cast time. @@ -1915,7 +1915,7 @@ static int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); - if (sd != NULL && sd->state.itemskill_no_casttime == 1 && sd->autocast.type == AUTOCAST_ITEM) + if (sd != NULL && sd->autocast.itemskill_instant_cast && sd->autocast.type == AUTOCAST_ITEM) casttime = 0; // in official this is triggered even if no cast time. -- cgit v1.2.3-70-g09d2 From 6f49858747acc7ee3767dd431bec32b919b81536 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Thu, 12 Mar 2020 00:03:54 +0100 Subject: Use map_session_data->autocast.type instead of skillitem variable to check for auto-cast skills --- src/map/clif.c | 8 ++++---- src/map/skill.c | 26 +++++++++++++------------- src/map/status.c | 6 +++--- src/map/unit.c | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 6b5c57d46..074ca570b 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -12767,7 +12767,7 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill if (skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST) return; } else if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) { - if (sd->skillitem != skill_id) { + if (sd->autocast.type == AUTOCAST_NONE) { clif->skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0, 0); return; } @@ -12785,7 +12785,7 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill } else if (sd->menuskill_id != SA_AUTOSPELL) return; //Can't use skills while a menu is open. } - if (sd->skillitem == skill_id) { + if (sd->autocast.type != AUTOCAST_NONE) { if (skill_lv != sd->skillitemlv) skill_lv = sd->skillitemlv; if (!(tmp&INF_SELF_SKILL)) @@ -12905,7 +12905,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin return; if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 ) { - if( sd->skillitem != skill_id ) { + if (sd->autocast.type == AUTOCAST_NONE) { clif->skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0, 0); return; } @@ -12926,7 +12926,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin pc->delinvincibletimer(sd); - if( sd->skillitem == skill_id ) { + if (sd->autocast.type != AUTOCAST_NONE) { if( skill_lv != sd->skillitemlv ) skill_lv = sd->skillitemlv; unit->skilluse_pos(&sd->bl, x, y, skill_id, skill_lv); diff --git a/src/map/skill.c b/src/map/skill.c index 001c11c36..8515cc3c9 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1010,8 +1010,8 @@ static int skillnotok(uint16 skill_id, struct map_session_data *sd) if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL)) return 0; // can do any damn thing they want - if( skill_id == AL_TELEPORT && sd->skillitem == skill_id && sd->skillitemlv > 2 ) - return 0; // Teleport lv 3 bypasses this check.[Inkfish] + if (skill_id == AL_TELEPORT && sd->autocast.type == AUTOCAST_ITEM && sd->skillitemlv > 2) + return 0; // Teleport level 3 and higher bypasses this check if cast by itemskill() script commands. // Epoque: // This code will compare the player's attack motion value which is influenced by ASPD before @@ -1032,7 +1032,7 @@ static int skillnotok(uint16 skill_id, struct map_session_data *sd) * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions below * Also, without this check, an exploit where an item casting + healing (or any other kind buff) isn't deleted after used on a restricted map **/ - if( sd->skillitem == skill_id ) + if (sd->autocast.type == AUTOCAST_ITEM) return 0; if( sd->sc.data[SC_ALL_RIDING] ) @@ -7464,7 +7464,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * map->freeblock_unlock(); return 1; } - if( sd->skillitem != skill_id ) + if (sd->autocast.type == AUTOCAST_NONE) status_zap(src, 0, skill->get_sp(skill_id, skill_lv)); // consume sp only if succeeded } break; @@ -11026,7 +11026,7 @@ static int skill_castend_map(struct map_session_data *sd, uint16 skill_id, const } } - lv = sd->skillitem==skill_id?sd->skillitemlv:pc->checkskill(sd,skill_id); + lv = (sd->autocast.type > AUTOCAST_TEMP) ? sd->skillitemlv : pc->checkskill(sd, skill_id); wx = sd->menuskill_val>>16; wy = sd->menuskill_val&0xffff; @@ -14067,8 +14067,8 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s return 1; } - 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] + if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->autocast.type != AUTOCAST_ITEM) { + // GMs don't override the AUTOCAST_ITEM check, otherwise they can use items without them being consumed! 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; @@ -14099,7 +14099,7 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s if( !sc->count ) sc = NULL; - if( sd->skillitem == skill_id ) { + if (sd->autocast.type == AUTOCAST_ITEM) { if (sd->autocast.type == AUTOCAST_ABRA || sd->autocast.type == AUTOCAST_IMPROVISE) { // Abracadabra or Improvised Song was used. sd->autocast.type = AUTOCAST_NONE; } else { @@ -14122,7 +14122,7 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s } } - if (pc_is90overweight(sd) && sd->skillitem != skill_id) { /// Skill casting items ignore the overweight restriction. [Kenpachi] + if (pc_is90overweight(sd) && sd->autocast.type != AUTOCAST_ITEM) { // Skill casting items ignore the overweight restriction. clif->skill_fail(sd, skill_id, USESKILL_FAIL_WEIGHTOVER, 0, 0); return 0; } @@ -14993,7 +14993,7 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s return 0; } - if (require.sp > 0 && st->sp < (unsigned int)require.sp && sd->skillitem != skill_id) { /// Skill casting items and Hocus-Pocus skills don't consume SP. [Kenpachi] + if (require.sp > 0 && st->sp < (unsigned int)require.sp && sd->autocast.type == AUTOCAST_NONE) { // Auto-cast skills don't consume SP. clif->skill_fail(sd, skill_id, USESKILL_FAIL_SP_INSUFFICIENT, 0, 0); return 0; } @@ -15056,8 +15056,8 @@ static int skill_check_condition_castend(struct map_session_data *sd, uint16 ski return 1; } - 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] + if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->autocast.type != AUTOCAST_ITEM) { + // GMs don't override the AUTOCAST_ITEM check, otherwise they can use items without them being consumed! 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; @@ -15084,7 +15084,7 @@ static int skill_check_condition_castend(struct map_session_data *sd, uint16 ski break; } - if (pc_is90overweight(sd) && sd->skillitem != skill_id) { /// Skill casting items ignore the overweight restriction. [Kenpachi] + if (pc_is90overweight(sd) && sd->autocast.type != AUTOCAST_ITEM) { // Skill casting items ignore the overweight restriction. clif->skill_fail(sd, skill_id, USESKILL_FAIL_WEIGHTOVER, 0, 0); return 0; } diff --git a/src/map/status.c b/src/map/status.c index 4d798b606..a1aac8649 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1584,7 +1584,7 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ } if( skill_id ) { - if (src != NULL && (sd == NULL || sd->skillitem == 0)) { + if (src != NULL && (sd == NULL || sd->autocast.type != AUTOCAST_ITEM)) { // Items that cast skills using 'itemskill' will not be handled by map_zone_db. int i; @@ -1628,7 +1628,7 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ if (src != NULL && map->getcell(src->m, src, src->x, src->y, CELL_CHKLANDPROTECTOR) && !(st->mode&MD_BOSS) - && (src->type != BL_PC || sd->skillitem != skill_id)) + && (src->type != BL_PC || sd->autocast.type != AUTOCAST_ITEM)) return 0; break; default: @@ -1707,7 +1707,7 @@ static int status_check_skilluse(struct block_list *src, struct block_list *targ return 0; //Can't amp out of Wand of Hermode :/ [Skotlex] } - if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->skillitem != skill_id)) { + if (skill_id != 0 /* Do not block item-casted skills.*/ && (src->type != BL_PC || sd->autocast.type != AUTOCAST_ITEM)) { //Skills blocked through status changes... if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through sc->data[SC_SILENCE] || diff --git a/src/map/unit.c b/src/map/unit.c index ad4dc88b5..f9ea9adb6 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1745,7 +1745,7 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill if( casttime <= 0 ) ud->state.skillcastcancel = 0; - if( !sd || sd->skillitem != skill_id || skill->get_cast(skill_id,skill_lv) ) + if (sd == NULL || sd->autocast.type < AUTOCAST_ABRA || skill->get_cast(skill_id, skill_lv) != 0) ud->canact_tick = tick + casttime + 100; if( sd ) { @@ -1884,7 +1884,7 @@ static int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill } ud->state.skillcastcancel = castcancel&&casttime>0?1:0; - if( !sd || sd->skillitem != skill_id || skill->get_cast(skill_id,skill_lv) ) + if (sd == NULL || sd->autocast.type < AUTOCAST_ABRA || skill->get_cast(skill_id, skill_lv) != 0) ud->canact_tick = tick + casttime + 100; #if 0 if (sd) { -- cgit v1.2.3-70-g09d2 From 10312bc4329e16a4b4420131cb976ef9fa6a13f5 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Thu, 12 Mar 2020 00:14:52 +0100 Subject: Remove obsolete auto-cast type validation from skill_check_condition_castbegin() function --- src/map/skill.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/map/skill.c b/src/map/skill.c index 8515cc3c9..89729c572 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -14099,27 +14099,23 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s if( !sc->count ) sc = NULL; + // TODO: Check if the validation of delayed consume is still required. (See the delayed consume related TODO in pc_useitem().) if (sd->autocast.type == AUTOCAST_ITEM) { - if (sd->autocast.type == AUTOCAST_ABRA || sd->autocast.type == AUTOCAST_IMPROVISE) { // Abracadabra or Improvised Song was used. - sd->autocast.type = AUTOCAST_NONE; - } else { - int i; - // When a target was selected, consume items that were skipped in pc_use_item [Skotlex] - if( (i = sd->itemindex) == -1 || - sd->status.inventory[i].nameid != sd->itemid || - sd->inventory_data[i] == NULL || - sd->status.inventory[i].amount < 1 - ) { - //Something went wrong, item exploit? - sd->itemid = sd->itemindex = -1; - return 0; - } + int i = sd->itemindex; - //Consume - sd->itemid = sd->itemindex = -1; - if (sd->status.inventory[i].expire_time == 0 && sd->inventory_data[i]->flag.delay_consume == 1) // Rental usable items are not consumed until expiration - pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); + if (i == INDEX_NOT_FOUND || sd->status.inventory[i].nameid != sd->itemid || sd->inventory_data[i] == NULL + || sd->status.inventory[i].amount < 1) { // Something went wrong. Item exploit? + sd->itemid = INDEX_NOT_FOUND; + sd->itemindex = INDEX_NOT_FOUND; + return 0; } + + // Consume the item. Rental usable items are not consumed until expiration. + if (sd->status.inventory[i].expire_time == 0 && sd->inventory_data[i]->flag.delay_consume == 1) + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); + + sd->itemid = INDEX_NOT_FOUND; + sd->itemindex = INDEX_NOT_FOUND; } if (pc_is90overweight(sd) && sd->autocast.type != AUTOCAST_ITEM) { // Skill casting items ignore the overweight restriction. -- cgit v1.2.3-70-g09d2 From 44581f9de0df3ab18b719e55f793dc22bd2fcb72 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Thu, 12 Mar 2020 00:24:35 +0100 Subject: Remove skillitem and skillitemlv variables and use map_session_data->autocast.skill_id/_lv instead --- src/map/clif.c | 8 ++++---- src/map/pc.h | 1 - src/map/script.c | 8 +++----- src/map/skill.c | 20 ++++++++------------ 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 074ca570b..66a3d84c9 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -12786,8 +12786,8 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill return; //Can't use skills while a menu is open. } if (sd->autocast.type != AUTOCAST_NONE) { - if (skill_lv != sd->skillitemlv) - skill_lv = sd->skillitemlv; + if (skill_lv != sd->autocast.skill_lv) + skill_lv = sd->autocast.skill_lv; if (!(tmp&INF_SELF_SKILL)) pc->delinvincibletimer(sd); // Target skills through items cancel invincibility. [Inkfish] unit->skilluse_id(&sd->bl, target_id, skill_id, skill_lv); @@ -12927,8 +12927,8 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin pc->delinvincibletimer(sd); if (sd->autocast.type != AUTOCAST_NONE) { - if( skill_lv != sd->skillitemlv ) - skill_lv = sd->skillitemlv; + if (skill_lv != sd->autocast.skill_lv) + skill_lv = sd->autocast.skill_lv; unit->skilluse_pos(&sd->bl, x, y, skill_id, skill_lv); } else { int lv; diff --git a/src/map/pc.h b/src/map/pc.h index 2991bfc68..6f932c447 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -304,7 +304,6 @@ struct map_session_data { int followtimer; // [MouseJstr] int followtarget; time_t emotionlasttime; // to limit flood with emotion packets - int skillitem,skillitemlv; uint16 skill_id_old,skill_lv_old; uint16 skill_id_dance,skill_lv_dance; short cook_mastery; // range: [0,1999] [Inkfish] diff --git a/src/map/script.c b/src/map/script.c index 6ed94bc92..2c8ce683e 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11005,16 +11005,14 @@ static BUILDIN(itemskill) sd->autocast.type = AUTOCAST_ITEM; sd->autocast.skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); sd->autocast.skill_lv = script_getnum(st, 3); - sd->skillitem = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); - sd->skillitemlv = script_getnum(st, 3); int flag = script_hasdata(st, 4) ? script_getnum(st, 4) : ISF_NONE; sd->autocast.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS); if (sd->autocast.itemskill_check_conditions) { - if (skill->check_condition_castbegin(sd, sd->skillitem, sd->skillitemlv) == 0 - || skill->check_condition_castend(sd, sd->skillitem, sd->skillitemlv) == 0) { + if (skill->check_condition_castbegin(sd, sd->autocast.skill_id, sd->autocast.skill_lv) == 0 + || skill->check_condition_castend(sd, sd->autocast.skill_id, sd->autocast.skill_lv) == 0) { pc->autocast_clear(sd); return true; } @@ -11025,7 +11023,7 @@ static BUILDIN(itemskill) sd->autocast.itemskill_instant_cast = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST); sd->autocast.itemskill_cast_on_self = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF); - clif->item_skill(sd, sd->skillitem, sd->skillitemlv); + clif->item_skill(sd, sd->autocast.skill_id, sd->autocast.skill_lv); return true; } diff --git a/src/map/skill.c b/src/map/skill.c index 89729c572..6fc1b80a2 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1010,7 +1010,7 @@ static int skillnotok(uint16 skill_id, struct map_session_data *sd) if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL)) return 0; // can do any damn thing they want - if (skill_id == AL_TELEPORT && sd->autocast.type == AUTOCAST_ITEM && sd->skillitemlv > 2) + if (skill_id == AL_TELEPORT && sd->autocast.type == AUTOCAST_ITEM && sd->autocast.skill_lv > 2) return 0; // Teleport level 3 and higher bypasses this check if cast by itemskill() script commands. // Epoque: @@ -5824,7 +5824,7 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH) unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); - if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) + if (sd == NULL || sd->autocast.skill_id != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) != 0) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); // Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish] if (sd) { // Cooldown application int i, cooldown = skill->get_cooldown(ud->skill_id, ud->skill_lv); @@ -5942,7 +5942,7 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data) } } - if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) + if (sd == NULL || sd->autocast.skill_id != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) != 0) ud->canact_tick = tick; ud->skill_id = ud->skill_lv = ud->skilltarget = 0; //You can't place a skill failed packet here because it would be @@ -6334,8 +6334,6 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * sd->autocast.type = AUTOCAST_ABRA; sd->autocast.skill_id = abra_skill_id; sd->autocast.skill_lv = abra_skill_lv; - sd->skillitem = abra_skill_id; - sd->skillitemlv = abra_skill_lv; clif->item_skill(sd, abra_skill_id, abra_skill_lv); } else { // mob-casted @@ -7501,7 +7499,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * break; } - if (sd->autocast.type == AUTOCAST_TEMP || ((sd->skillitem == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skill_lv == 1) || skill_lv == 3) + if (sd->autocast.type == AUTOCAST_TEMP || ((sd->autocast.skill_id == AL_TELEPORT || battle_config.skip_teleport_lv1_menu) && skill_lv == 1) || skill_lv == 3) { if( skill_lv == 1 ) pc->randomwarp(sd,CLR_TELEPORT); @@ -10078,8 +10076,6 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * sd->autocast.type = AUTOCAST_IMPROVISE; sd->autocast.skill_id = improv_skill_id; sd->autocast.skill_lv = improv_skill_lv; - sd->skillitem = improv_skill_id; - sd->skillitemlv = improv_skill_lv; clif->item_skill(sd, improv_skill_id, improv_skill_lv); } else { struct unit_data *ud = unit->bl2ud(src); @@ -10848,7 +10844,7 @@ static int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) if (ud->walktimer != INVALID_TIMER) unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); - if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) + if (sd == NULL || sd->autocast.skill_id != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) != 0) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); if (sd) { //Cooldown application int i, cooldown = skill->get_cooldown(ud->skill_id, ud->skill_lv); @@ -10877,7 +10873,7 @@ static int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) map->freeblock_lock(); skill->castend_pos2(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv,tick,0); - if( sd && sd->skillitem != AL_WARP ) // Warp-Portal thru items will clear data in skill_castend_map. [Inkfish] + if (sd != NULL && sd->autocast.skill_id != AL_WARP) // Warp-Portal thru items will clear data in skill_castend_map. [Inkfish] pc->autocast_clear(sd); unit->set_dir(src, map->calc_dir(src, ud->skillx, ud->skilly)); @@ -10892,7 +10888,7 @@ static int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) return 1; } while(0); - if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) + if (sd == NULL || sd->autocast.skill_id != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) != 0) ud->canact_tick = tick; ud->skill_id = ud->skill_lv = 0; if(sd) @@ -11026,7 +11022,7 @@ static int skill_castend_map(struct map_session_data *sd, uint16 skill_id, const } } - lv = (sd->autocast.type > AUTOCAST_TEMP) ? sd->skillitemlv : pc->checkskill(sd, skill_id); + lv = (sd->autocast.type > AUTOCAST_TEMP) ? sd->autocast.skill_lv : pc->checkskill(sd, skill_id); wx = sd->menuskill_val>>16; wy = sd->menuskill_val&0xffff; -- cgit v1.2.3-70-g09d2 From 7c6e21a9057b07929b55de23ae67299434edb6db Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Thu, 12 Mar 2020 17:22:36 +0100 Subject: Remove IT_DELAYCONSUME related auto-cast code First of all: In official servers, skill casting item are consumed immediately and thus IT_DELAYCONSUME should not be used for those items And additionally these code blocks are obsolete, because of the way how skill casting items work. * If the item won't check the skill's requirements, the code block to delete the item of type IT_DELAYCONSUME isn't even executed. * If the item does check the skill's requirements, the check is done prior to the skill casting which would be the same as using IT_USABLE. --- src/map/pc.c | 5 ----- src/map/skill.c | 19 ------------------- 2 files changed, 24 deletions(-) diff --git a/src/map/pc.c b/src/map/pc.c index e181b5f89..5d87d017d 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5295,11 +5295,6 @@ static int pc_useitem(struct map_session_data *sd, int n) if(sd->catch_target_class != -1) //Abort pet catching. sd->catch_target_class = -1; - // Unset auto-cast related data for items of type IT_DELAYCONSUME or the item won't be consumed. - // TODO: Check if this is still required. [Kenpachi] - if (sd->inventory_data[n]->flag.delay_consume != 0) - sd->autocast.type = AUTOCAST_NONE; - amount = sd->status.inventory[n].amount; //Check if the item is to be consumed immediately [Skotlex] if (sd->inventory_data[n]->flag.delay_consume || sd->inventory_data[n]->flag.keepafteruse) diff --git a/src/map/skill.c b/src/map/skill.c index 6fc1b80a2..e779e9859 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -14095,25 +14095,6 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s if( !sc->count ) sc = NULL; - // TODO: Check if the validation of delayed consume is still required. (See the delayed consume related TODO in pc_useitem().) - if (sd->autocast.type == AUTOCAST_ITEM) { - int i = sd->itemindex; - - if (i == INDEX_NOT_FOUND || sd->status.inventory[i].nameid != sd->itemid || sd->inventory_data[i] == NULL - || sd->status.inventory[i].amount < 1) { // Something went wrong. Item exploit? - sd->itemid = INDEX_NOT_FOUND; - sd->itemindex = INDEX_NOT_FOUND; - return 0; - } - - // Consume the item. Rental usable items are not consumed until expiration. - if (sd->status.inventory[i].expire_time == 0 && sd->inventory_data[i]->flag.delay_consume == 1) - pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); - - sd->itemid = INDEX_NOT_FOUND; - sd->itemindex = INDEX_NOT_FOUND; - } - if (pc_is90overweight(sd) && sd->autocast.type != AUTOCAST_ITEM) { // Skill casting items ignore the overweight restriction. clif->skill_fail(sd, skill_id, USESKILL_FAIL_WEIGHTOVER, 0, 0); return 0; -- cgit v1.2.3-70-g09d2 From 876cfa678d5e9a43d1ce419bd9d8300d9c8c6b36 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Fri, 13 Mar 2020 04:47:07 +0100 Subject: Make skills cast by Improvised Song ignore all requirements --- src/map/skill.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/map/skill.c b/src/map/skill.c index e779e9859..1022700fe 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -14058,8 +14058,8 @@ static int skill_check_condition_castbegin(struct map_session_data *sd, uint16 s if (sd->chat_id != 0) return 0; - if ((sd->autocast.itemskill_conditions_checked || !sd->autocast.itemskill_check_conditions) - && sd->autocast.type == AUTOCAST_ITEM) { + if (((sd->autocast.itemskill_conditions_checked || !sd->autocast.itemskill_check_conditions) + && sd->autocast.type == AUTOCAST_ITEM) || sd->autocast.type == AUTOCAST_IMPROVISE) { return 1; } @@ -15024,8 +15024,8 @@ static int skill_check_condition_castend(struct map_session_data *sd, uint16 ski if (sd->chat_id != 0) return 0; - if ((sd->autocast.itemskill_conditions_checked || !sd->autocast.itemskill_check_conditions) - && sd->autocast.type == AUTOCAST_ITEM) { + if (((sd->autocast.itemskill_conditions_checked || !sd->autocast.itemskill_check_conditions) + && sd->autocast.type == AUTOCAST_ITEM) || sd->autocast.type == AUTOCAST_IMPROVISE) { return 1; } @@ -15230,8 +15230,10 @@ static int skill_consume_requirement(struct map_session_data *sd, uint16 skill_i nullpo_ret(sd); - if (!sd->autocast.itemskill_check_conditions && sd->autocast.type == AUTOCAST_ITEM) + if ((!sd->autocast.itemskill_check_conditions && sd->autocast.type == AUTOCAST_ITEM) + || sd->autocast.type == AUTOCAST_IMPROVISE) { return 1; + } req = skill->get_requirement(sd,skill_id,skill_lv); -- cgit v1.2.3-70-g09d2