Browse Source

Follow up 32fd3ee:
- Added config 'discount_item_point_shop' to decide item/point shop is discountable or not. (see conf/misc.conf), thx http://rathena.org/board/tracker/issue-8298-itemshop-and-pointshop/
- (for advanced use) Added optional discount flag for item/point shop. (see doc/script_commands.txt)
--> -%TAB%itemshop%TAB%<NPC Name>%TAB%<sprite id>,<costitemid>{:<discount>},<itemid>:<price>{,<itemid>:<price>...}
--> -%TAB%pointshop%TAB%<NPC Name>%TAB%<sprite id>,<costvariable>{:<discount>},<itemid>:<price>{,<itemid>:<price>...}

Signed-off-by: Cahyadi Ramadhan Togihon <house.bad@gmail.com>

Cahyadi Ramadhan Togihon 11 years ago
parent
commit
1ce4dbf107
7 changed files with 50 additions and 12 deletions
  1. 7 0
      conf/battle/misc.conf
  2. 6 5
      doc/script_commands.txt
  3. 1 0
      src/map/battle.c
  4. 1 0
      src/map/battle.h
  5. 3 1
      src/map/clif.c
  6. 30 6
      src/map/npc.c
  7. 2 0
      src/map/npc.h

+ 7 - 0
conf/battle/misc.conf

@@ -128,3 +128,10 @@ mail_show_status: 0
 // Is monster transformation disabled during Guild Wars?
 // Is monster transformation disabled during Guild Wars?
 // If set to yes, monster transforming is automatically removed/disabled when enterting castles during WoE times
 // If set to yes, monster transforming is automatically removed/disabled when enterting castles during WoE times
 mon_trans_disable_in_gvg: no
 mon_trans_disable_in_gvg: no
+
+// Is item's price at item/point shop discountable?
+// 0 = No (Default)
+// 1 = Item shops
+// 2 = Point shops
+// 3 = Item & point shops
+discount_item_point_shop: 0

+ 6 - 5
doc/script_commands.txt

@@ -273,11 +273,11 @@ these floating NPC objects are for. More on that below.
 -%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}
 -%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}
 <map name>,<x>,<y>,<facing>%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}
 <map name>,<x>,<y>,<facing>%TAB%shop%TAB%<NPC Name>%TAB%<sprite id>,<itemid>:<price>{,<itemid>:<price>...}
 
 
--%TAB%itemshop%TAB%<NPC Name>%TAB%<sprite id>,<costitemid>,<itemid>:<price>{,<itemid>:<price>...}
-<map name>,<x>,<y>,<facing>%TAB%itemshop%TAB%<NPC Name>%TAB%<sprite id>,<costitemid>,<itemid>:<price>{,<itemid>:<price>...}
+-%TAB%itemshop%TAB%<NPC Name>%TAB%<sprite id>,<costitemid>{:<discount>},<itemid>:<price>{,<itemid>:<price>...}
+<map name>,<x>,<y>,<facing>%TAB%itemshop%TAB%<NPC Name>%TAB%<sprite id>,<costitemid>{:<discount>},<itemid>:<price>{,<itemid>:<price>...}
 
 
--%TAB%pointshop%TAB%<NPC Name>%TAB%<sprite id>,<costvariable>,<itemid>:<price>{,<itemid>:<price>...}
-<map name>,<x>,<y>,<facing>%TAB%pointshop%TAB%<NPC Name>%TAB%<sprite id>,<costvariable>,<itemid>:<price>{,<itemid>:<price>...}
+-%TAB%pointshop%TAB%<NPC Name>%TAB%<sprite id>,<costvariable>{:<discount>},<itemid>:<price>{,<itemid>:<price>...}
+<map name>,<x>,<y>,<facing>%TAB%pointshop%TAB%<NPC Name>%TAB%<sprite id>,<costvariable>{:<discount>},<itemid>:<price>{,<itemid>:<price>...}
 
 
 This will define a shop NPC, which, when triggered (which can only be done by 
 This will define a shop NPC, which, when triggered (which can only be done by 
 clicking) will cause a shop window to come up. No code whatsoever runs in shop 
 clicking) will cause a shop window to come up. No code whatsoever runs in shop 
@@ -302,7 +302,8 @@ of "shop" to use the Shop interface, allowing you to buy items with a specific
 item or special points from a variable. 'pointshop' only supported variable types
 item or special points from a variable. 'pointshop' only supported variable types
 are permanent character variables, temporary character variables, permanent
 are permanent character variables, temporary character variables, permanent
 local account variables, or permanent global account variables. These variables
 local account variables, or permanent global account variables. These variables
-must be of integer type, not string.
+must be of integer type, not string. 'discount' flag is an option, makes the price
+at that shop is affected by discount skill.
 
 
 ** Define an warp/shop/cashshop/itemshop/pointshop/NPC duplicate.
 ** Define an warp/shop/cashshop/itemshop/pointshop/NPC duplicate.
 
 

+ 1 - 0
src/map/battle.c

@@ -7261,6 +7261,7 @@ static const struct _battle_data {
 	{ "homunculus_S_growth_level",          &battle_config.hom_S_growth_level,             99,      0,      MAX_LEVEL,      },
 	{ "homunculus_S_growth_level",          &battle_config.hom_S_growth_level,             99,      0,      MAX_LEVEL,      },
 	{ "emblem_woe_change",                  &battle_config.emblem_woe_change,               0,      0,      1,              },
 	{ "emblem_woe_change",                  &battle_config.emblem_woe_change,               0,      0,      1,              },
 	{ "emblem_transparency_limit",          &battle_config.emblem_transparency_limit,      80,      0,      100,            },
 	{ "emblem_transparency_limit",          &battle_config.emblem_transparency_limit,      80,      0,      100,            },
+	{ "discount_item_point_shop",			&battle_config.discount_item_point_shop,		0,		0,		3,				},
 };
 };
 #ifndef STATS_OPT_OUT
 #ifndef STATS_OPT_OUT
 /**
 /**

+ 1 - 0
src/map/battle.h

@@ -512,6 +512,7 @@ extern struct Battle_Config
 	int mon_trans_disable_in_gvg;
 	int mon_trans_disable_in_gvg;
 	int emblem_woe_change;
 	int emblem_woe_change;
 	int emblem_transparency_limit;
 	int emblem_transparency_limit;
+	int discount_item_point_shop;
 } battle_config;
 } battle_config;
 
 
 void do_init_battle(void);
 void do_init_battle(void);

+ 3 - 1
src/map/clif.c

@@ -1777,6 +1777,7 @@ void clif_npcbuysell(struct map_session_data* sd, int id)
 void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
 void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
 {
 {
 	int fd,i,c;
 	int fd,i,c;
+	bool discount;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 	nullpo_retv(nd);
 	nullpo_retv(nd);
@@ -1786,6 +1787,7 @@ void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
 	WFIFOW(fd,0) = 0xc6;
 	WFIFOW(fd,0) = 0xc6;
 
 
 	c = 0;
 	c = 0;
+	discount = npc_shop_discount(nd->subtype,nd->u.shop.discount);
 	for( i = 0; i < nd->u.shop.count; i++ )
 	for( i = 0; i < nd->u.shop.count; i++ )
 	{
 	{
 		struct item_data* id = itemdb_exists(nd->u.shop.shop_item[i].nameid);
 		struct item_data* id = itemdb_exists(nd->u.shop.shop_item[i].nameid);
@@ -1793,7 +1795,7 @@ void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
 		if( id == NULL )
 		if( id == NULL )
 			continue;
 			continue;
 		WFIFOL(fd, 4+c*11) = val;
 		WFIFOL(fd, 4+c*11) = val;
-		WFIFOL(fd, 8+c*11) = pc_modifybuyvalue(sd,val);
+		WFIFOL(fd, 8+c*11) = (discount) ? pc_modifybuyvalue(sd,val) : val;
 		WFIFOB(fd,12+c*11) = itemtype(id->type);
 		WFIFOB(fd,12+c*11) = itemtype(id->type);
 		WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
 		WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid;
 		c++;
 		c++;

+ 30 - 6
src/map/npc.c

@@ -1583,7 +1583,8 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
 				return 2;
 				return 2;
 		}
 		}
 
 
-		value = pc_modifybuyvalue(sd,value);
+		if (npc_shop_discount(nd->subtype,nd->u.shop.discount))
+			value = pc_modifybuyvalue(sd,value);
 
 
 		z += (double)value * amount;
 		z += (double)value * amount;
 		w += itemdb_weight(nameid) * amount;
 		w += itemdb_weight(nameid) * amount;
@@ -1656,8 +1657,6 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
 					pc_setglobalreg(sd, nd->u.shop.pointshop_str, count - (int)z);
 					pc_setglobalreg(sd, nd->u.shop.pointshop_str, count - (int)z);
 					break;
 					break;
 			}
 			}
-			sprintf(output,msg_txt(sd,716),nd->u.shop.pointshop_str,count - (int)z); // Your '%s' now: %d
-			clif_disp_onlyself(sd,output,strlen(output)+1);
 			break;
 			break;
 	}
 	}
 
 
@@ -1694,6 +1693,11 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
 		}
 		}
 	}
 	}
 
 
+	if (nd->subtype == POINTSHOP) {
+		sprintf(output,msg_txt(sd,716),nd->u.shop.pointshop_str,count - (int)z); // Your '%s' now: %d
+		clif_disp_onlyself(sd,output,strlen(output)+1);
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -2275,7 +2279,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 	#define MAX_SHOPITEM 100
 	#define MAX_SHOPITEM 100
 	struct npc_item_list items[MAX_SHOPITEM];
 	struct npc_item_list items[MAX_SHOPITEM];
 	char *p, point_str[32];
 	char *p, point_str[32];
-	int x, y, dir, m, i, nameid = 0;
+	int x, y, dir, m, i, nameid = 0, is_discount = 0;
 	struct npc_data *nd;
 	struct npc_data *nd;
 	enum npc_subtype type;
 	enum npc_subtype type;
 
 
@@ -2316,7 +2320,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 	switch(type) {
 	switch(type) {
 		case ITEMSHOP: {
 		case ITEMSHOP: {
 			struct item_data* tmp;
 			struct item_data* tmp;
-			if (sscanf(p,",%d,",&nameid) < 1) {
+			if (sscanf(p,",%d:%d,",&nameid,&is_discount) < 1) {
 				ShowError("npc_parse_shop: Invalid item cost definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
 				ShowError("npc_parse_shop: Invalid item cost definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
 				return strchr(start,'\n'); // skip and continue
 				return strchr(start,'\n'); // skip and continue
 			}
 			}
@@ -2328,7 +2332,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 			break;
 			break;
 		}
 		}
 		case POINTSHOP: {
 		case POINTSHOP: {
-			if (sscanf(p, ",%32[^,],",point_str) < 1) {
+			if (sscanf(p, ",%32[^,:]:%d,",point_str,&is_discount) < 1) {
 				ShowError("npc_parse_shop: Invalid item cost definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
 				ShowError("npc_parse_shop: Invalid item cost definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
 				return strchr(start,'\n'); // skip and continue
 				return strchr(start,'\n'); // skip and continue
 			}
 			}
@@ -2347,6 +2351,9 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 			p = strchr(p+1,',');
 			p = strchr(p+1,',');
 			break;
 			break;
 		}
 		}
+		default:
+			is_discount = 1;
+			break;
 	}
 	}
 
 
 	for( i = 0; i < ARRAYLENGTH(items) && p; ++i ) {
 	for( i = 0; i < ARRAYLENGTH(items) && p; ++i ) {
@@ -2395,6 +2402,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 	nd->u.shop.count = i;
 	nd->u.shop.count = i;
 	nd->u.shop.itemshop_nameid = nameid; // Item shop currency
 	nd->u.shop.itemshop_nameid = nameid; // Item shop currency
 	safestrncpy(nd->u.shop.pointshop_str,point_str,strlen(point_str)+1); // Point shop currency
 	safestrncpy(nd->u.shop.pointshop_str,point_str,strlen(point_str)+1); // Point shop currency
+	nd->u.shop.discount = is_discount;
 	nd->bl.prev = nd->bl.next = NULL;
 	nd->bl.prev = nd->bl.next = NULL;
 	nd->bl.m = m;
 	nd->bl.m = m;
 	nd->bl.x = x;
 	nd->bl.x = x;
@@ -2425,6 +2433,22 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 	return strchr(start,'\n');// continue
 	return strchr(start,'\n');// continue
 }
 }
 
 
+/** [Cydh]
+* Check if the shop is affected by discount or not
+* @param type Type of NPC shop (enum npc_subtype)
+* @param discount Discount flag of NPC shop
+* @return bool 'true' is discountable, 'false' otherwise
+*/
+bool npc_shop_discount(enum npc_subtype type, bool discount) {
+	if (type == SHOP || (type != SHOP && discount))
+		return true;
+
+	if( (type == ITEMSHOP && battle_config.discount_item_point_shop&1) ||
+		(type == POINTSHOP && battle_config.discount_item_point_shop&2) )
+		return true;
+	return false;
+}
+
 /**
 /**
  * NPC other label
  * NPC other label
  * Not sure, seem to add label in a chainlink
  * Not sure, seem to add label in a chainlink

+ 2 - 0
src/map/npc.h

@@ -60,6 +60,7 @@ struct npc_data {
 			int count;
 			int count;
 			int itemshop_nameid; // Item Shop cost item ID
 			int itemshop_nameid; // Item Shop cost item ID
 			char pointshop_str[32]; // Point Shop cost variable name
 			char pointshop_str[32]; // Point Shop cost variable name
+			bool discount;
 		} shop;
 		} shop;
 		struct {
 		struct {
 			short xs,ys; // OnTouch area radius
 			short xs,ys; // OnTouch area radius
@@ -175,6 +176,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
 extern struct npc_data* fake_nd;
 extern struct npc_data* fake_nd;
 
 
 int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list);
 int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list);
+bool npc_shop_discount(enum npc_subtype type, bool discount);
 
 
 #ifdef SECURE_NPCTIMEOUT
 #ifdef SECURE_NPCTIMEOUT
 	int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);
 	int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);