From 1098b588625774ca2cf4e05527b00fd4d0187919 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 20 Jan 2020 09:49:23 +0100 Subject: Fixed skill conditions check and parameter in itemskill() script command. * itemskill() script command should check for the skill's conditions and also consumes them. SP are not consumed. * The same applies to Hocus-pocus skill. Conditions should be checked and consumed, SP are not consumed. * This was bugged for more than 6 years now. See linked bug report and commits. Related bug: * https://herc.ws/oldboard/tracker/issue-7210-itemskill-command-does-not-check-for-required-items/ Related commits: * https://github.com/HerculesWS/Hercules/commit/b864056b8d088660fca9129bddad477732ed8df9 * https://github.com/HerculesWS/Hercules/commit/07272f7a16db87970583286db03167ca79604a69 --- src/map/script.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src/map/script.c') diff --git a/src/map/script.c b/src/map/script.c index b77e6a376..470ad9408 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -11000,15 +11000,26 @@ static BUILDIN(itemskill) id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); lv = script_getnum(st,3); -/* temporarily disabled, awaiting for kenpachi to detail this so we can make it work properly */ -#if 0 - if( !script_hasdata(st, 4) ) { - if( !skill->check_condition_castbegin(sd,id,lv) || !skill->check_condition_castend(sd,id,lv) ) - return true; - } -#endif sd->skillitem=id; sd->skillitemlv=lv; + + /// itemskill_conditions_checked/itemskill_no_conditions abuse prevention. + /// Unset in unit_skilluse_id()/unit_skilluse_pos() if skill was not aborted while target selection. + sd->itemskill_id = id; + sd->itemskill_lv = lv; + + int flag = script_hasdata(st, 4) ? script_getnum(st, 4) : ISF_NONE; + + 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. + sd->state.itemskill_no_conditions = ((flag & ISF_IGNORECONDITIONS) == ISF_IGNORECONDITIONS) ? 1 : 0; /// Unset in unit_skilluse_id()/unit_skilluse_pos() if skill was not aborted while target selection. + + if (sd->state.itemskill_no_conditions == 0) { + if (skill->check_condition_castbegin(sd, id, lv) == 0 || skill->check_condition_castend(sd, id, lv) == 0) + return true; + + sd->state.itemskill_conditions_checked = 1; /// Unset in unit_skilluse_id()/unit_skilluse_pos() if skill was not aborted while target selection. + } + clif->item_skill(sd,id,lv); return true; } -- cgit v1.2.3-70-g09d2