From eccf5ab20c3ae02cf46c9827f485b8d88a62b531 Mon Sep 17 00:00:00 2001 From: Aleos Date: Mon, 3 Aug 2020 20:57:09 -0400 Subject: [PATCH] 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! --- doc/script_commands.txt | 6 ++--- src/map/script.cpp | 59 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index b7408cb8e1..dab507ca3b 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -5808,9 +5808,9 @@ Increase AGI Lv 5, and display appropriate effects. *npcskilleffect ,,,; *npcskilleffect "",,,; -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. --------------------------------------- diff --git a/src/map/script.cpp b/src/map/script.cpp index 7c182a3260..bab8c8bd03 100644 --- a/src/map/script.cpp +++ b/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; }