Updated unitskilluseid and unitskillusepos script commands (#7684)

* Added the parameter 'ignore_range' to ignore the skill range defined in skill_db.yml
This commit is contained in:
Atemo 2023-04-07 01:09:44 +02:00 committed by GitHub
parent fff69b0cfd
commit db5874d677
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 26 deletions

View File

@ -8490,10 +8490,10 @@ flag: Specify target
---------------------------------------
*unitskilluseid <GID>,<skill id>,<skill lvl>{,<target id>,<casttime>,<cancel>,<Line_ID>};
*unitskilluseid <GID>,"<skill name>",<skill lvl>{,<target id>,<casttime>,<cancel>,<Line_ID>};
*unitskillusepos <GID>,<skill id>,<skill lvl>,<x>,<y>{,<casttime>,<cancel>,<Line_ID>};
*unitskillusepos <GID>,"<skill name>",<skill lvl>,<x>,<y>{,<casttime>,<cancel>,<Line_ID>};
*unitskilluseid <GID>,<skill id>,<skill lvl>{,<target id>,<casttime>,<cancel>,<Line_ID>,<ignore_range>};
*unitskilluseid <GID>,"<skill name>",<skill lvl>{,<target id>,<casttime>,<cancel>,<Line_ID>,<ignore_range>};
*unitskillusepos <GID>,<skill id>,<skill lvl>,<x>,<y>{,<casttime>,<cancel>,<Line_ID>,<ignore_range>};
*unitskillusepos <GID>,"<skill name>",<skill lvl>,<x>,<y>{,<casttime>,<cancel>,<Line_ID>,<ignore_range>};
This is the replacement of the older commands, these use the same values for
GID as the other unit* commands (See 'GID').
@ -8509,6 +8509,9 @@ CastCancel from skill_db.yml is the default value of <cancel>.
If <Line_ID> is defined (positive number, default 0) the monster will say the message from 'Line_ID'
in mob_chat_db.yml when casting the skill.
If <ignore_range> is true, the unit will ignore the skill range defined by the database. The default value is false.
Attention! this setting does not work for all skills.
---------------------------------------
*unitexists <GID>;

View File

@ -19920,6 +19920,7 @@ BUILDIN_FUNC(unitskilluseid)
casttime = ( script_hasdata(st,6) ? script_getnum(st,6) : 0 );
bool cancel = ( script_hasdata(st,7) ? script_getnum(st,7) > 0 : skill_get_castcancel(skill_id) );
int msg_id = (script_hasdata(st, 8) ? script_getnum(st, 8) : 0);
bool ignore_range = (script_hasdata(st, 9) ? script_getnum(st, 9) > 0 : false);
if(script_rid2bl(2,bl)){
if (msg_id > 0) {
@ -19937,7 +19938,7 @@ BUILDIN_FUNC(unitskilluseid)
else
status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
}
unit_skilluse_id2(bl, target_id, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), cancel);
unit_skilluse_id2(bl, target_id, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), cancel, ignore_range);
}
return SCRIPT_CMD_SUCCESS;
@ -19974,6 +19975,7 @@ BUILDIN_FUNC(unitskillusepos)
casttime = ( script_hasdata(st,7) ? script_getnum(st,7) : 0 );
bool cancel = ( script_hasdata(st,8) ? script_getnum(st,8) > 0 : skill_get_castcancel(skill_id) );
int msg_id = (script_hasdata(st, 9) ? script_getnum(st, 9) : 0);
bool ignore_range = (script_hasdata(st, 10) ? script_getnum(st, 10) > 0 : false);
if(script_rid2bl(2,bl)){
if (msg_id > 0) {
@ -19991,7 +19993,7 @@ BUILDIN_FUNC(unitskillusepos)
else
status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
}
unit_skilluse_pos2(bl, skill_x, skill_y, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), cancel);
unit_skilluse_pos2(bl, skill_x, skill_y, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), cancel, ignore_range);
}
return SCRIPT_CMD_SUCCESS;
@ -22890,9 +22892,9 @@ BUILDIN_FUNC(npcskill)
status_calc_npc(nd, SCO_NONE);
if (skill_get_inf(skill_id)&INF_GROUND_SKILL)
unit_skilluse_pos2(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level,0,0);
unit_skilluse_pos2(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level,0,0,true);
else
unit_skilluse_id2(&nd->bl, sd->bl.id, skill_id, skill_level,0,0);
unit_skilluse_id2(&nd->bl, sd->bl.id, skill_id, skill_level,0,0,true);
return SCRIPT_CMD_SUCCESS;
}
@ -27385,8 +27387,8 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(unitstopattack,"i"),
BUILDIN_DEF(unitstopwalk,"i?"),
BUILDIN_DEF(unittalk,"is?"),
BUILDIN_DEF(unitskilluseid,"ivi????"), // originally by Qamera [Celest]
BUILDIN_DEF(unitskillusepos,"iviii???"), // [Celest]
BUILDIN_DEF(unitskilluseid,"ivi?????"), // originally by Qamera [Celest]
BUILDIN_DEF(unitskillusepos,"iviii????"), // [Celest]
// <--- [zBuffer] List of unit control commands
BUILDIN_DEF(sleep,"i"),
BUILDIN_DEF(sleep2,"i"),

View File

@ -1602,7 +1602,7 @@ int unit_set_walkdelay(struct block_list *bl, t_tick tick, t_tick delay, int typ
* @param castcancel: Whether or not the skill can be cancelled by interruption (hit)
* @return Success(1); Fail(0);
*/
int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel)
int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel, bool ignore_range)
{
struct unit_data *ud;
struct status_data *tstatus;
@ -1747,7 +1747,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
return 0;
// Fail if the targetted skill is near NPC [Cydh]
if(skill->inf2[INF2_DISABLENEARNPC] && skill_isNotOk_npcRange(src,skill_id,skill_lv,target->x,target->y)) {
if(skill->inf2[INF2_DISABLENEARNPC] && !ignore_range && skill_isNotOk_npcRange(src,skill_id,skill_lv,target->x,target->y)) {
if (sd)
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@ -1864,7 +1864,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
if(ud->stepaction || ud->steptimer != INVALID_TIMER)
unit_stop_stepaction(src);
// Remember the skill request from the client while walking to the next cell
if(src->type == BL_PC && ud->walktimer != INVALID_TIMER && !battle_check_range(src, target, range-1)) {
if(src->type == BL_PC && ud->walktimer != INVALID_TIMER && (!battle_check_range(src, target, range-1) || ignore_range)) {
ud->stepaction = true;
ud->target_to = target_id;
ud->stepskill_id = skill_id;
@ -1874,7 +1874,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
// Check range when not using skill on yourself or is a combo-skill during attack
// (these are supposed to always have the same range as your attack)
if( src->type != BL_NPC && src->id != target_id && (!combo || ud->attacktimer == INVALID_TIMER) ) {
if( src->type != BL_NPC && !ignore_range && src->id != target_id && (!combo || ud->attacktimer == INVALID_TIMER) ) {
if( skill_get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
if( !unit_can_reach_bl(src, target, range + 1, 1, NULL, NULL) )
return 0; // Walk-path check failed.
@ -2010,7 +2010,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
mobskill_event(md, src, tick, -1); // Cast targetted skill event.
if ((status_has_mode(tstatus,MD_CASTSENSORIDLE) || status_has_mode(tstatus,MD_CASTSENSORCHASE)) && battle_check_target(target, src, BCT_ENEMY) > 0) {
if ((status_has_mode(tstatus,MD_CASTSENSORIDLE) || status_has_mode(tstatus,MD_CASTSENSORCHASE)) && battle_check_target(target, src, BCT_ENEMY) > 0 && !ignore_range) {
switch (md->state.skillstate) {
case MSS_RUSH:
case MSS_FOLLOW:
@ -2117,7 +2117,7 @@ int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_y, uint
* @param castcancel: Whether or not the skill can be cancelled by interuption (hit)
* @return Success(1); Fail(0);
*/
int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel)
int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel, bool ignore_range)
{
map_session_data *sd = NULL;
struct unit_data *ud = NULL;
@ -2170,7 +2170,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
return 0;
// Fail if the targetted skill is near NPC [Cydh]
if(skill_get_inf2(skill_id, INF2_DISABLENEARNPC) && skill_isNotOk_npcRange(src,skill_id,skill_lv,skill_x,skill_y)) {
if(skill_get_inf2(skill_id, INF2_DISABLENEARNPC) && !ignore_range && skill_isNotOk_npcRange(src,skill_id,skill_lv,skill_x,skill_y)) {
if (sd)
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@ -2192,7 +2192,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
if(ud->stepaction || ud->steptimer != INVALID_TIMER)
unit_stop_stepaction(src);
// Remember the skill request from the client while walking to the next cell
if(src->type == BL_PC && ud->walktimer != INVALID_TIMER && !battle_check_range(src, &bl, range-1)) {
if(src->type == BL_PC && ud->walktimer != INVALID_TIMER && (!battle_check_range(src, &bl, range-1) || ignore_range)) {
struct map_data *md = &map[src->m];
// Convert coordinates to target_to so we can use it as target later
ud->stepaction = true;
@ -2202,12 +2202,13 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
return 0; // Attacking will be handled by unit_walktoxy_timer in this case
}
if( skill_get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
if( !unit_can_reach_bl(src, &bl, range + 1, 1, NULL, NULL) )
return 0; // Walk-path check failed.
}else if( !battle_check_range(src, &bl, range) )
return 0; // Arrow-path check failed.
if (!ignore_range) {
if( skill_get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
if( !unit_can_reach_bl(src, &bl, range + 1, 1, NULL, NULL) )
return 0; // Walk-path check failed.
}else if( !battle_check_range(src, &bl, range) )
return 0; // Arrow-path check failed.
}
unit_stop_attack(src);
// Moved here to prevent Suffragium from ending if skill fails

View File

@ -146,8 +146,8 @@ bool unit_can_attack(struct block_list *bl, int target_id);
// Cast on a unit
int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv);
int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv);
int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel);
int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel);
int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel, bool ignore_range = false);
int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel, bool ignore_range = false);
// Step timer used for delayed attack and skill use
TIMER_FUNC(unit_step_timer);