소스 검색

Updated unitskilluseid and unitskillusepos script commands (#7684)

* Added the parameter 'ignore_range' to ignore the skill range defined in skill_db.yml
Atemo 2 년 전
부모
커밋
db5874d677
4개의 변경된 파일32개의 추가작업 그리고 26개의 파일을 삭제
  1. 7 4
      doc/script_commands.txt
  2. 8 6
      src/map/script.cpp
  3. 15 14
      src/map/unit.cpp
  4. 2 2
      src/map/unit.hpp

+ 7 - 4
doc/script_commands.txt

@@ -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
 This is the replacement of the older commands, these use the same values for
 GID as the other unit* commands (See 'GID').
 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'
 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.
 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>;
 *unitexists <GID>;

+ 8 - 6
src/map/script.cpp

@@ -19920,6 +19920,7 @@ BUILDIN_FUNC(unitskilluseid)
 	casttime = ( script_hasdata(st,6) ? script_getnum(st,6) : 0 );
 	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) );
 	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);
 	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(script_rid2bl(2,bl)){
 		if (msg_id > 0) {
 		if (msg_id > 0) {
@@ -19937,7 +19938,7 @@ BUILDIN_FUNC(unitskilluseid)
 			else
 			else
 				status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
 				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;
 	return SCRIPT_CMD_SUCCESS;
@@ -19974,6 +19975,7 @@ BUILDIN_FUNC(unitskillusepos)
 	casttime = ( script_hasdata(st,7) ? script_getnum(st,7) : 0 );
 	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) );
 	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);
 	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(script_rid2bl(2,bl)){
 		if (msg_id > 0) {
 		if (msg_id > 0) {
@@ -19991,7 +19993,7 @@ BUILDIN_FUNC(unitskillusepos)
 			else
 			else
 				status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
 				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;
 	return SCRIPT_CMD_SUCCESS;
@@ -22890,9 +22892,9 @@ BUILDIN_FUNC(npcskill)
 		status_calc_npc(nd, SCO_NONE);
 		status_calc_npc(nd, SCO_NONE);
 
 
 	if (skill_get_inf(skill_id)&INF_GROUND_SKILL)
 	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
 	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;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
@@ -27385,8 +27387,8 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(unitstopattack,"i"),
 	BUILDIN_DEF(unitstopattack,"i"),
 	BUILDIN_DEF(unitstopwalk,"i?"),
 	BUILDIN_DEF(unitstopwalk,"i?"),
 	BUILDIN_DEF(unittalk,"is?"),
 	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
 // <--- [zBuffer] List of unit control commands
 	BUILDIN_DEF(sleep,"i"),
 	BUILDIN_DEF(sleep,"i"),
 	BUILDIN_DEF(sleep2,"i"),
 	BUILDIN_DEF(sleep2,"i"),

+ 15 - 14
src/map/unit.cpp

@@ -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)
  * @param castcancel: Whether or not the skill can be cancelled by interruption (hit)
  * @return Success(1); Fail(0);
  * @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 unit_data *ud;
 	struct status_data *tstatus;
 	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;
 		return 0;
 
 
 	// Fail if the targetted skill is near NPC [Cydh]
 	// 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)
 		if (sd)
 			clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 			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)
 	if(ud->stepaction || ud->steptimer != INVALID_TIMER)
 		unit_stop_stepaction(src);
 		unit_stop_stepaction(src);
 	// Remember the skill request from the client while walking to the next cell
 	// 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->stepaction = true;
 		ud->target_to = target_id;
 		ud->target_to = target_id;
 		ud->stepskill_id = skill_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
 	// 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)
 	// (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( skill_get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
 			if( !unit_can_reach_bl(src, target, range + 1, 1, NULL, NULL) )
 			if( !unit_can_reach_bl(src, target, range + 1, 1, NULL, NULL) )
 				return 0; // Walk-path check failed.
 				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.
 		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) {
 			switch (md->state.skillstate) {
 				case MSS_RUSH:
 				case MSS_RUSH:
 				case MSS_FOLLOW:
 				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)
  * @param castcancel: Whether or not the skill can be cancelled by interuption (hit)
  * @return Success(1); Fail(0);
  * @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;
 	map_session_data *sd = NULL;
 	struct unit_data        *ud = 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;
 		return 0;
 
 
 	// Fail if the targetted skill is near NPC [Cydh]
 	// 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)
 		if (sd)
 			clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 			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)
 	if(ud->stepaction || ud->steptimer != INVALID_TIMER)
 		unit_stop_stepaction(src);
 		unit_stop_stepaction(src);
 	// Remember the skill request from the client while walking to the next cell
 	// 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];
 		struct map_data *md = &map[src->m];
 		// Convert coordinates to target_to so we can use it as target later
 		// Convert coordinates to target_to so we can use it as target later
 		ud->stepaction = true;
 		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
 		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);
 	unit_stop_attack(src);
 
 
 	// Moved here to prevent Suffragium from ending if skill fails
 	// Moved here to prevent Suffragium from ending if skill fails

+ 2 - 2
src/map/unit.hpp

@@ -146,8 +146,8 @@ bool unit_can_attack(struct block_list *bl, int target_id);
 // Cast on a unit
 // Cast on a unit
 int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv);
 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_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
 // Step timer used for delayed attack and skill use
 TIMER_FUNC(unit_step_timer);
 TIMER_FUNC(unit_step_timer);