瀏覽代碼

Adjusts npcskilleffect and skilleffect (#5270)

* Fixes #2156.
* Adjusts the two script commands to take into account the type of skill being used.
* Adjusts documentation to reflect.
* Verify skill and skill level.
Thanks to @Yuchinin and @Lemongrass3110!
Aleos 4 年之前
父節點
當前提交
eccf5ab20c
共有 2 個文件被更改,包括 57 次插入8 次删除
  1. 3 3
      doc/script_commands.txt
  2. 54 5
      src/map/script.cpp

+ 3 - 3
doc/script_commands.txt

@@ -5808,9 +5808,9 @@ Increase AGI Lv 5, and display appropriate effects.
 *npcskilleffect <skill id>,<number>,<x>,<y>;
 *npcskilleffect "<skill name>",<number>,<x>,<y>;
 
-This command behaves identically to 'skilleffect', however, the effect will not
-be centered on the invoking character's sprite, nor on the NPC sprite, if any,
-but will be centered at map coordinates given on the same map as the invoking
+This command behaves identically to 'skilleffect', however, ground type skill
+effects will be centered at the map coordinates given on the same map as the
+attached character and all other skill types will be centered on the attached
 character.
 
 ---------------------------------------

+ 54 - 5
src/map/script.cpp

@@ -14547,6 +14547,22 @@ BUILDIN_FUNC(petskillsupport)
 	return SCRIPT_CMD_SUCCESS;
 }
 
+static inline void script_skill_effect(block_list *bl, uint16 skill_id, uint16 skill_lv, int16 x, int16 y) {
+	nullpo_retv(bl);
+
+	switch (skill_get_casttype(skill_id)) {
+		case CAST_GROUND:
+			clif_skill_poseffect(bl, skill_id, skill_lv, x, y, gettick());
+			break;
+		case CAST_NODAMAGE:
+			clif_skill_nodamage(bl, bl, skill_id, skill_lv, 1);
+			break;
+		case CAST_DAMAGE:
+			clif_skill_damage(bl, bl, gettick(), status_get_amotion(bl), status_get_dmotion(bl), 0, 1, skill_id, skill_lv, skill_get_hit(skill_id));
+			break;
+	}
+}
+
 /*==========================================
  * Scripted skill effects [Celest]
  *------------------------------------------*/
@@ -14558,11 +14574,24 @@ BUILDIN_FUNC(skilleffect)
 	uint16 skill_id, skill_lv;
 	
 	if( !script_rid2sd(sd) )
-		return SCRIPT_CMD_SUCCESS;
+		return SCRIPT_CMD_FAILURE;
 	
 	skill_id = ( script_isstring(st, 2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
 	skill_lv = script_getnum(st,3);
 
+	if (skill_db.find(skill_id) == nullptr) {
+		ShowError("buildin_skilleffect: Invalid skill defined (%s)!\n", script_getstr(st, 2));
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	uint16 skill_lv_cap = cap_value(skill_lv, 1, skill_get_max(skill_id));
+
+	if (skill_lv != skill_lv_cap) {
+		ShowWarning("buildin_skilleffect: Invalid skill level %d, capping to %d.\n", skill_lv, skill_lv_cap);
+		skill_lv = skill_lv_cap;
+		script_reportsrc(st);
+	}
+
 	/* Ensure we're standing because the following packet causes the client to virtually set the char to stand,
 	 * which leaves the server thinking it still is sitting. */
 	if( pc_issit(sd) && pc_setstand(sd, false) ) {
@@ -14570,7 +14599,8 @@ BUILDIN_FUNC(skilleffect)
 		clif_standing(&sd->bl);
 	}
 
-	clif_skill_nodamage(&sd->bl,&sd->bl,skill_id,skill_lv,1);
+	script_skill_effect(&sd->bl, skill_id, skill_lv, sd->bl.x, sd->bl.y);
+
 	return SCRIPT_CMD_SUCCESS;
 }
 
@@ -14582,16 +14612,35 @@ BUILDIN_FUNC(skilleffect)
 BUILDIN_FUNC(npcskilleffect)
 {
 	struct block_list *bl= map_id2bl(st->oid);
+
+	if (bl == nullptr) {
+		ShowError("buildin_npcskilleffect: Invalid object attached to NPC.");
+		return SCRIPT_CMD_FAILURE;
+	}
+
 	uint16 skill_id, skill_lv;
-	int x, y;
+	int16 x, y;
 
 	skill_id=( script_isstring(st, 2) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) );
 	skill_lv=script_getnum(st,3);
 	x=script_getnum(st,4);
 	y=script_getnum(st,5);
 
-	if (bl)
-		clif_skill_poseffect(bl,skill_id,skill_lv,x,y,gettick());
+	if (skill_db.find(skill_id) == nullptr) {
+		ShowError("buildin_npcskilleffect: Invalid skill defined (%s)!\n", script_getstr(st, 2));
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	uint16 skill_lv_cap = cap_value(skill_lv, 1, skill_get_max(skill_id));
+
+	if (skill_lv != skill_lv_cap) {
+		ShowWarning("buildin_npcskilleffect: Invalid skill level %d, capping to %d.\n", skill_lv, skill_lv_cap);
+		skill_lv = skill_lv_cap;
+		script_reportsrc(st);
+	}
+
+	script_skill_effect(bl, skill_id, skill_lv, bl->x, bl->y);
+
 	return SCRIPT_CMD_SUCCESS;
 }