Merge pull request #1530 from rathena/itemskill

Itemskill script command expansion
This commit is contained in:
Jittapan Pluemsumran 2016-09-03 15:04:28 +07:00 committed by GitHub
commit b29f7fcd93
5 changed files with 31 additions and 14 deletions

View File

@ -11037,7 +11037,7 @@
23191,Varetyr_Spear_Scroll_1_5,Level 5 Varetyr Spear,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "SO_VARETYR_SPEAR",5; },{},{}
23192,Diamond_Dust_Scroll_1_5,Level 5 Diamond Dust,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "SO_DIAMONDDUST",5; },{},{}
23193,Crimson_Rock_Scroll_1_5,Level 5 Crimson Rock,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "WL_CRIMSONROCK",5; },{},{}
23194,Sienna_Execrate_Scroll_1_5,Level 5 Sienna Execrate,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "WL_SIENNAEXECRATE",5; },{},{}
23194,Sienna_Execrate_Scroll_1_5,Level 5 Sienna Execrate,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "WL_SIENNAEXECRATE",5,true; },{},{}
//===================================================================
// Shadow Equipments
//===================================================================

View File

@ -4754,18 +4754,24 @@ The default setting, 'item_enabled_npc', is defined in 'conf/battle/items.conf'.
---------------------------------------
*itemskill <skill id>,<skill level>;
*itemskill "<skill name>",<skill level>;
*itemskill <skill id>,<skill level>{,<keep requirement>};
*itemskill "<skill name>",<skill level>{,<keep requirement>};
This command is meant for item scripts to replicate single-use skills in usable
items. It will not work properly if there is a visible dialog window or menu.
If the skill is self or auto-targeting, it will be used immediately; otherwise a
target cursor is shown.
If <keep requirement> parameter is set to true, the skill's requirements will be checked.
By default, the requirements for item skills are not checked, and therefore the default value is false.
// When Anodyne is used, it will cast Endure (8), Level 1, as if the actual
// skill has been used from skill tree.
605,Anodyne,Anodyne,11,2000,0,100,,,,,10477567,2,,,,,{ itemskill 8,1; },{}
// When Sienna_Execrate_Scroll_1_5 is used, it will cast Sienna Execrate Level 5 and consume 2 Red_Gemstones.
23194,Sienna_Execrate_Scroll_1_5,Level 5 Sienna Execrate,11,10,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "WL_SIENNAEXECRATE",5,true; },{},{}
---------------------------------------
*consumeitem <item id>{,<char_id>};

View File

@ -307,6 +307,7 @@ struct map_session_data {
time_t emotionlasttime; // to limit flood with emotion packets
short skillitem,skillitemlv;
bool skillitem_keep_requirement;
uint16 skill_id_old,skill_lv_old;
uint16 skill_id_dance,skill_lv_dance;
short cook_mastery; // range: [0,1999] [Inkfish]

View File

@ -9563,6 +9563,7 @@ BUILDIN_FUNC(itemskill)
{
int id;
int lv;
bool keep_requirement;
TBL_PC* sd;
struct script_data *data;
@ -9574,9 +9575,15 @@ BUILDIN_FUNC(itemskill)
get_val(st, data); // Convert into value in case of a variable
id = ( data_isstring(data) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
lv = script_getnum(st,3);
if (script_hasdata(st, 4)) {
keep_requirement = (script_getnum(st, 4) != 0);
} else {
keep_requirement = false;
}
sd->skillitem=id;
sd->skillitemlv=lv;
sd->skillitem_keep_requirement = keep_requirement;
clif_item_skill(sd,id,lv);
return SCRIPT_CMD_SUCCESS;
}
@ -21916,7 +21923,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(gettimestr,"si"),
BUILDIN_DEF(openstorage,""),
BUILDIN_DEF(guildopenstorage,""),
BUILDIN_DEF(itemskill,"vi"),
BUILDIN_DEF(itemskill,"vi?"),
BUILDIN_DEF(produce,"i"),
BUILDIN_DEF(cooking,"i"),
BUILDIN_DEF(monster,"siisii???"),

View File

@ -645,7 +645,7 @@ bool skill_isNotOk(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 above
* 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->skillitem == skill_id && !sd->skillitem_keep_requirement )
return false;
// Check skill restrictions [Celest]
if( (!map_flag_vs(m) && skill_get_nocast (skill_id) & 1) ||
@ -6109,6 +6109,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
sd->state.abra_flag = 1;
sd->skillitem = abra_skill_id;
sd->skillitemlv = abra_skill_lv;
sd->skillitem_keep_requirement = false;
clif_item_skill(sd, abra_skill_id, abra_skill_lv);
}
else
@ -9993,6 +9994,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
sd->state.abra_flag = 2;
sd->skillitem = improv_skill_id;
sd->skillitemlv = improv_skill_lv;
sd->skillitem_keep_requirement = false;
clif_item_skill(sd, improv_skill_id, improv_skill_lv);
} else {
struct unit_data *ud = unit_bl2ud(src);
@ -11210,8 +11212,8 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
skill_blockpc_start(sd,BD_ADAPTATION,3000);
}
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;
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 = sd->skillitem_keep_requirement = 0;
if (ud->skilltimer == INVALID_TIMER) {
if(md) md->skill_idx = -1;
@ -11269,7 +11271,7 @@ int skill_castend_id(int tid, unsigned int 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;
sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = 0;
else if(md)
md->skill_idx = -1;
return 0;
@ -11406,7 +11408,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data)
status_change_end(src, SC_CAMOUFLAGE, INVALID_TIMER); // Applies to the first skill if active
if( sd && sd->skillitem != AL_WARP ) // Warp-Portal thru items will clear data in skill_castend_map. [Inkfish]
sd->skillitem = sd->skillitemlv = 0;
sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = 0;
if (ud->skilltimer == INVALID_TIMER) {
if (md) md->skill_idx = -1;
@ -11422,7 +11424,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data)
ud->canact_tick = tick;
ud->skill_id = ud->skill_lv = 0;
if(sd)
sd->skillitem = sd->skillitemlv = 0;
sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = 0;
else if(md)
md->skill_idx = -1;
return 0;
@ -12358,7 +12360,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
}
skill_consume_requirement(sd,sd->menuskill_id,lv,2);
sd->skillitem = sd->skillitemlv = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish]
sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish]
if((group=skill_unitsetting(&sd->bl,skill_id,lv,wx,wy,0))==NULL) {
skill_failed(sd);
@ -14739,7 +14741,8 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
else if( sd->status.inventory[i].expire_time == 0 )
pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration
}
return true;
if(!sd->skillitem_keep_requirement)
return true;
}
if( pc_is90overweight(sd) ) {
@ -15587,7 +15590,7 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
break;
}
if( sd->skillitem == skill_id ) // Casting finished (Item skill or Hocus-Pocus)
if( sd->skillitem == skill_id && !sd->skillitem_keep_requirement ) // Casting finished (Item skill or Hocus-Pocus)
return true;
if( pc_is90overweight(sd) ) {
@ -15850,7 +15853,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
if( !sd )
return req;
if( sd->skillitem == skill_id )
if( sd->skillitem == skill_id && !sd->skillitem_keep_requirement )
return req; // Item skills and Hocus-Pocus don't have requirements.[Inkfish]
sc = &sd->sc;