From d7bbebdf8526667b288223c8adc2d110204814c5 Mon Sep 17 00:00:00 2001
From: Emistry Haoyan <equinox1991@gmail.com>
Date: Tue, 2 Oct 2018 22:41:53 +0800
Subject: Implement status reduction script command.

- for stat reduction support.
- return the amount of status point required to increase a status.
---
 doc/script_commands.txt          | 16 ++++++++++++++++
 npc/other/CashShop_Functions.txt | 27 +++++++++++++++++++++++++++
 src/map/script.c                 | 20 ++++++++++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 343eb02cb..953cc86f3 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -6034,6 +6034,22 @@ Amount can be negative. See statusup().
 
 ---------------------------------------
 
+*needed_status_point(<type>, <val>, {<char_id>});
+
+Returns the number of stat points needed to change the specified stat <type> by <val>.
+If <val> is negative, returns the number of stat points that would be needed to
+raise the specified stat from (current value - <val>) to current value.
+
+List of <type>:
+bStr -  Strength
+bVit -  Vitality
+bInt -  Intelligence
+bAgi -  Agility
+bDex -  Dexterity
+bLuk -  Luck
+
+---------------------------------------
+
 *bonus(<bonus type>, <val1>)
 *bonus2(<bonus type>, <val1>, <val2>)
 *bonus3(<bonus type>, <val1>, <val2>, <val3>)
diff --git a/npc/other/CashShop_Functions.txt b/npc/other/CashShop_Functions.txt
index 92fe841e1..5b957f9f2 100644
--- a/npc/other/CashShop_Functions.txt
+++ b/npc/other/CashShop_Functions.txt
@@ -310,3 +310,30 @@ function	script	F_Snowball	{
 	}
 	end;
 }
+
+// Status reduction potion
+//============================================================
+// - Permanently reduces base stat <type> by <val>.
+// - Returns status points equals to points needed to raise
+//   that stat to original value.
+// - Doesn't work if base status <type> would become lower than 1 after reduction.
+// * callfunc("F_CashReduceStat", <type>{, <val>, <itemid>});
+function	script	F_CashReduceStat	{
+	.@type = getarg(0);
+	.@amount = getarg(1, -1);
+	.@itemid = getarg(2, 0);
+	
+	if ((readparam(.@type) + .@amount) < 1) return;
+	
+	if (.@itemid) {
+		if (countitem(.@itemid))
+			delitem .@itemid, 1;
+		else
+			return;
+	}
+	
+	StatusPoint += needed_status_point(.@type, .@amount);
+	statusup2 .@type, .@amount;
+	
+	return;
+}
\ No newline at end of file
diff --git a/src/map/script.c b/src/map/script.c
index b787d0138..b2f1120f1 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -9809,6 +9809,25 @@ static BUILDIN(statusup2)
 	return true;
 }
 
+
+/*==========================================
+* Returns the number of stat points needed to change the specified stat by val.
+* needed_status_point(<type>,<val>{,<char id>}); [secretdataz]
+*------------------------------------------*/
+static BUILDIN(needed_status_point)
+{
+	int type = script_getnum(st, 2);
+	int val = script_getnum(st, 3);;
+	struct map_session_data *sd = script->rid2sd(st);
+
+	if (sd == NULL)
+		script_pushint(st, 0);
+	else
+		script_pushint(st, pc->need_status_point(sd, type, val));
+
+	return true;
+}
+
 /// See 'doc/item_bonus.txt'
 ///
 /// bonus <bonus type>,<val1>;
@@ -25048,6 +25067,7 @@ static void script_parse_builtin(void)
 		BUILDIN_DEF(downrefitem,"i?"),
 		BUILDIN_DEF(statusup,"i"),
 		BUILDIN_DEF(statusup2,"ii"),
+		BUILDIN_DEF(needed_status_point,"ii?"),
 		BUILDIN_DEF(bonus,"iv"),
 		BUILDIN_DEF2(bonus,"bonus2","ivi"),
 		BUILDIN_DEF2(bonus,"bonus3","ivii"),
-- 
cgit v1.2.3-70-g09d2