From d20cbae7763546555c4c9c8aa53266c40b31a2b1 Mon Sep 17 00:00:00 2001
From: Emistry Haoyan <equinox1991@gmail.com>
Date: Tue, 9 Apr 2019 23:23:33 +0800
Subject: Add *setfavoriteitemidx & *autofavoriteitem script command.

- set an item as favorite item or not based inventory
index.
- if an item is set to favorite item, it will be moved into favorite
tab, else move out from favorite tab.
- only non-equipped item can adjust the favorite item state.
---
 doc/script_commands.txt | 24 ++++++++++++++++++++++++
 src/map/itemdb.h        |  3 ++-
 src/map/pc.c            |  7 +++++++
 src/map/script.c        | 45 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 516454365..03a45017a 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -3192,6 +3192,30 @@ runs of getcartinventorylist().
 
 ---------------------------------------
 
+*setfavoriteitemidx(<idx>, <flag>)
+
+This function will set an item in inventory as favorite or not.
+If its favorite item, it will be moved to favorite tab, else move out from favorite tab.
+Note: Cant change favorite flag of an equipped item.
+
+Valid Parameters: 
+	<idx>    - inventory index, refer *getinventorylist()
+	<flag>   - true/false (true = favorite item, false = otherwise)
+
+---------------------------------------
+
+*autofavoriteitem(<item_id>, <flag>)
+
+This function will auto set an item as favorite when <item_id> is obtained. 
+If its favorite item, it will be auto moved to favorite tab, else move out from favorite tab.
+This setting affect not only attached player, but also everyone player globally.
+
+Valid Parameters: 
+	<item_id> - item ID
+	<flag>    - true/false (true = favorite item, false = otherwise)
+
+---------------------------------------
+
 *cardscnt()
 
 This function will return the number of cards inserted into the weapon
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index e032def0c..f66abe066 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -521,7 +521,8 @@ struct item_data {
 		unsigned no_refine : 1; // [celest]
 		unsigned delay_consume : 1;     ///< Signifies items that are not consumed immediately upon double-click [Skotlex]
 		unsigned trade_restriction : 9; ///< Item trade restrictions mask (@see enum ItemTradeRestrictions)
-		unsigned autoequip: 1;
+		unsigned autoequip : 1;
+		unsigned auto_favorite : 1;
 		unsigned buyingstore : 1;
 		unsigned bindonequip : 1;
 		unsigned keepafteruse : 1;
diff --git a/src/map/pc.c b/src/map/pc.c
index 5416fbec2..fb023b2a4 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4778,6 +4778,13 @@ static int pc_additem(struct map_session_data *sd, const struct item *item_data,
 
 	sd->weight += w;
 	clif->updatestatus(sd,SP_WEIGHT);
+
+	// auto-favorite
+	if (data->flag.auto_favorite > 0) {
+		sd->status.inventory[i].favorite = 1;
+		clif->favorite_item(sd, i);
+	}
+
 	//Auto-equip
 	if(data->flag.autoequip)
 		pc->equipitem(sd, i, data->equip);
diff --git a/src/map/script.c b/src/map/script.c
index 5843ac292..0f99d9199 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -24681,6 +24681,49 @@ static BUILDIN(consolemes)
 	return true;
 }
 
+static BUILDIN(setfavoriteitemidx)
+{
+	struct map_session_data *sd = script_rid2sd(st);
+	int idx = script_getnum(st, 2);
+	int value = script_getnum(st, 3);
+
+	if (sd == NULL) {
+		ShowError("buildin_setfavoriteitemidx: No player attached.\n");
+		return false;
+	}
+
+	if (idx < 0 || idx >= sd->status.inventorySize) {
+		ShowError("buildin_setfavoriteitemidx: Invalid inventory index %d (min: %d, max: %d).\n", idx, 0, (sd->status.inventorySize - 1));
+		return false;
+	} else if (sd->inventory_data[idx] == NULL || sd->inventory_data[idx]->nameid <= 0) {
+		ShowWarning("buildin_setfavoriteitemidx: Current inventory index %d has no data.\n", idx);
+		return false;
+	} else if (sd->status.inventory[idx].equip > 0) {
+		ShowWarning("buildin_setfavoriteitemidx: Cant change favorite flag of an equipped item.\n");
+		return false;
+	} else {
+		sd->status.inventory[idx].favorite = cap_value(value, 0, 1);
+		clif->favorite_item(sd, idx);
+	}
+
+	return true;
+}
+
+static BUILDIN(autofavoriteitem)
+{
+	int nameid = script_getnum(st, 2);
+	int flag = script_getnum(st, 3);
+	struct item_data *item_data;
+
+	if ((item_data = itemdb->exists(nameid)) == NULL) {
+		ShowError("buildin_autofavoriteitem: Invalid item '%d'.\n", nameid);
+		return false;
+	}
+
+	item_data->flag.auto_favorite = cap_value(flag, 0, 1);
+	return true;
+}
+
 /** place holder for the translation macro **/
 static BUILDIN(_)
 {
@@ -26059,6 +26102,8 @@ static void script_parse_builtin(void)
 
 		BUILDIN_DEF(closeroulette, ""),
 		BUILDIN_DEF(openrefineryui, ""),
+		BUILDIN_DEF(setfavoriteitemidx, "ii"),
+		BUILDIN_DEF(autofavoriteitem, "ii"),
 	};
 	int i, len = ARRAYLENGTH(BUILDIN);
 	RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
-- 
cgit v1.2.3-70-g09d2