summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenpachi Developer <Kenpachi.Developer@gmx.de>2020-05-10 03:05:29 +0200
committerKenpachi Developer <Kenpachi.Developer@gmx.de>2020-05-13 05:18:02 +0200
commit9a64eca5235da46655ca64ba5916c6fd4d90208a (patch)
treea11a4aa10060e7b32553000dcbaf5c9fc52dd59b
parentcfe2d8527ecc8eb8e6dfacc7e661c5ed1f08ddd9 (diff)
downloadhercules-9a64eca5235da46655ca64ba5916c6fd4d90208a.tar.gz
hercules-9a64eca5235da46655ca64ba5916c6fd4d90208a.tar.bz2
hercules-9a64eca5235da46655ca64ba5916c6fd4d90208a.tar.xz
hercules-9a64eca5235da46655ca64ba5916c6fd4d90208a.zip
Add skill_enabled_npc battle flag and implement usage
-rw-r--r--conf/map/battle/skill.conf8
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/clif.c18
-rw-r--r--src/map/pc.h1
-rw-r--r--src/map/script.c5
-rw-r--r--src/map/skill.h7
7 files changed, 36 insertions, 6 deletions
diff --git a/conf/map/battle/skill.conf b/conf/map/battle/skill.conf
index a40b52124..fe9ca638a 100644
--- a/conf/map/battle/skill.conf
+++ b/conf/map/battle/skill.conf
@@ -347,3 +347,11 @@ stormgust_knockback: true
// 0 : (official) Magic Rod's animation occurs every time it is used.
// 1 : Magic Rod's animation would not occur unless a spell was absorbed. (old behavior)
magicrod_type: 0
+
+// Which skills are allowed to use while interacting with NPC?
+// 0 (SKILLENABLEDNPC_NONE) - Don't allow using skills.
+// 1 (SKILLENABLEDNPC_SELF) - Allow using non-damaging self skills.
+// 2 (SKILLENABLEDNPC_ALL) - Allow using all skills.
+// Official RE: 0 (Default value.)
+// Official Pre-RE: 1
+skill_enabled_npc: 0
diff --git a/src/map/battle.c b/src/map/battle.c
index cf51f4fc5..d99daca14 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7425,6 +7425,7 @@ static const struct battle_data {
{ "min_item_sell_price", &battle_config.min_item_sell_price, 0, 0, INT_MAX, },
{ "display_fake_hp_when_dead", &battle_config.display_fake_hp_when_dead, 1, 0, 1, },
{ "magicrod_type", &battle_config.magicrod_type, 0, 0, 1, },
+ { "skill_enabled_npc", &battle_config.skill_enabled_npc, 0, 0, INT_MAX, },
{ "features/enable_achievement_system", &battle_config.feature_enable_achievement, 1, 0, 1, },
{ "ping_timer_inverval", &battle_config.ping_timer_interval, 30, 0, 99999999, },
{ "ping_time", &battle_config.ping_time, 20, 0, 99999999, },
diff --git a/src/map/battle.h b/src/map/battle.h
index bb907d5b9..55ee32445 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -580,6 +580,8 @@ struct Battle_Config {
int magicrod_type;
+ int skill_enabled_npc;
+
int feature_enable_achievement;
int ping_timer_interval;
diff --git a/src/map/clif.c b/src/map/clif.c
index 5a090301d..4f0859a4c 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -12832,7 +12832,11 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill
// Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
pc->update_idle_time(sd, BCIDLE_USESKILLTOID);
- if (sd->npc_id || sd->state.workinprogress & 1) {
+ bool allow_self_skill = ((tmp & INF_SELF_SKILL) != 0 && (skill->get_nk(skill_id) & NK_NO_DAMAGE) != 0);
+ allow_self_skill = (allow_self_skill && battle_config.skill_enabled_npc == SKILLENABLEDNPC_SELF);
+
+ if ((sd->npc_id != 0 && !allow_self_skill && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
+ || (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
#else
@@ -12841,7 +12845,7 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill
return;
}
- if (pc_cant_act(sd)
+ if (pc_cant_act_except_npc(sd)
&& skill_id != RK_REFRESH
&& !(skill_id == SR_GENTLETOUCH_CURE && (sd->sc.opt1 == OPT1_STONE || sd->sc.opt1 == OPT1_FREEZE || sd->sc.opt1 == OPT1_STUN))
&& (sd->state.storage_flag != STORAGE_FLAG_CLOSED && !(tmp&INF_SELF_SKILL)) // SELF skills can be used with the storage open, issue: 8027
@@ -12976,7 +12980,8 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
return;
}
- if (sd->state.workinprogress & 1) {
+ if ((sd->npc_id != 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
+ || (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
#else
@@ -13046,7 +13051,7 @@ static void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd) __attr
/// There are various variants of this packet, some of them have padding between fields.
static void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd)
{
- if (pc_cant_act(sd))
+ if (pc_cant_act_except_npc(sd))
return;
if (pc_issit(sd))
return;
@@ -13067,7 +13072,7 @@ static void clif_parse_UseSkillToPosMoreInfo(int fd, struct map_session_data *sd
/// There are various variants of this packet, some of them have padding between fields.
static void clif_parse_UseSkillToPosMoreInfo(int fd, struct map_session_data *sd)
{
- if (pc_cant_act(sd))
+ if (pc_cant_act_except_npc(sd))
return;
if (pc_issit(sd))
return;
@@ -13096,7 +13101,8 @@ static void clif_parse_UseSkillMap(int fd, struct map_session_data *sd)
return;
// It is possible to use teleport with the storage window open issue:8027
- if (pc_cant_act(sd) && (sd->state.storage_flag == STORAGE_FLAG_CLOSED && skill_id != AL_TELEPORT)) {
+ if ((pc_cant_act_except_npc(sd) && sd->state.storage_flag == STORAGE_FLAG_CLOSED && skill_id != AL_TELEPORT)
+ || (sd->npc_id != 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)) {
clif_menuskill_clear(sd);
return;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index 01fd855b7..f9526c248 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -686,6 +686,7 @@ END_ZEROED_BLOCK;
#define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading )
#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
#define pc_cant_act_except_lapine(sd) ((sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1)
+#define pc_cant_act_except_npc(sd) ( (sd)->state.vending != 0 || (sd)->state.buyingstore != 0 || (sd)->chat_id != 0 || ((sd)->sc.opt1 != 0 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading != 0 || (sd)->state.storage_flag != 0 || (sd)->state.prevend != 0 || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
/* equals pc_cant_act except it doesn't check for chat rooms */
#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
diff --git a/src/map/script.c b/src/map/script.c
index bda461d5d..7ba9fd276 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -27918,6 +27918,11 @@ static void script_hardcoded_constants(void)
script->set_constant("ITEMENABLEDNPC_EQUIP", ITEMENABLEDNPC_EQUIP, false, false);
script->set_constant("ITEMENABLEDNPC_CONSUME", ITEMENABLEDNPC_CONSUME, false, false);
+ script->constdb_comment("NPC allowed skill use constants");
+ script->set_constant("SKILLENABLEDNPC_NONE", SKILLENABLEDNPC_NONE, false, false);
+ script->set_constant("SKILLENABLEDNPC_SELF", SKILLENABLEDNPC_SELF, false, false);
+ script->set_constant("SKILLENABLEDNPC_ALL", SKILLENABLEDNPC_ALL, false, false);
+
script->constdb_comment("private airship responds");
script->set_constant("P_AIRSHIP_NONE", P_AIRSHIP_NONE, false, false);
script->set_constant("P_AIRSHIP_RETRY", P_AIRSHIP_RETRY, false, false);
diff --git a/src/map/skill.h b/src/map/skill.h
index 4dbbaf147..e8360c91f 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1733,6 +1733,13 @@ enum autocast_type {
AUTOCAST_ITEM, // Used for itemskill() script command.
};
+/** Constants for allowed skill use while interacting with NPC. **/
+enum skill_enabled_npc_flags {
+ SKILLENABLEDNPC_NONE = 0, //!< Don't allow using any skills while interacting with NPC.
+ SKILLENABLEDNPC_SELF = 1, //!< Allow using non-damaging self skills while interacting with NPC.
+ SKILLENABLEDNPC_ALL = 2, //!< Allow using all skills while interacting with NPC.
+};
+
/**
* Structures
**/