diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf index 6e6507b93b..736314f947 100644 --- a/conf/battle/misc.conf +++ b/conf/battle/misc.conf @@ -128,3 +128,10 @@ mail_show_status: 0 // Is monster transformation disabled during Guild Wars? // If set to yes, monster transforming is automatically removed/disabled when enterting castles during WoE times 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 diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 30d69c9749..8dda02d2ba 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -273,11 +273,11 @@ these floating NPC objects are for. More on that below. -%TAB%shop%TAB%%TAB%,:{,:...} ,,,%TAB%shop%TAB%%TAB%,:{,:...} --%TAB%itemshop%TAB%%TAB%,,:{,:...} -,,,%TAB%itemshop%TAB%%TAB%,,:{,:...} +-%TAB%itemshop%TAB%%TAB%,{:},:{,:...} +,,,%TAB%itemshop%TAB%%TAB%,{:},:{,:...} --%TAB%pointshop%TAB%%TAB%,,:{,:...} -,,,%TAB%pointshop%TAB%%TAB%,,:{,:...} +-%TAB%pointshop%TAB%%TAB%,{:},:{,:...} +,,,%TAB%pointshop%TAB%%TAB%,{:},:{,:...} 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 @@ -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 are permanent character variables, temporary character variables, permanent 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. diff --git a/src/map/battle.c b/src/map/battle.c index 6b7cf4b744..22d1191614 100644 --- a/src/map/battle.c +++ b/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, }, { "emblem_woe_change", &battle_config.emblem_woe_change, 0, 0, 1, }, { "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 /** diff --git a/src/map/battle.h b/src/map/battle.h index 8b40b34a7a..b4cde53f4a 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -512,6 +512,7 @@ extern struct Battle_Config int mon_trans_disable_in_gvg; int emblem_woe_change; int emblem_transparency_limit; + int discount_item_point_shop; } battle_config; void do_init_battle(void); diff --git a/src/map/clif.c b/src/map/clif.c index 2731018613..48d4e8cf98 100644 --- a/src/map/clif.c +++ b/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) { int fd,i,c; + bool discount; nullpo_retv(sd); nullpo_retv(nd); @@ -1786,6 +1787,7 @@ void clif_buylist(struct map_session_data *sd, struct npc_data *nd) WFIFOW(fd,0) = 0xc6; c = 0; + discount = npc_shop_discount(nd->subtype,nd->u.shop.discount); for( i = 0; i < nd->u.shop.count; i++ ) { 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 ) continue; 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); WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid; c++; diff --git a/src/map/npc.c b/src/map/npc.c index dbed20e713..f2f75d0d2e 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1583,7 +1583,8 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) 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; 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); 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; } @@ -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; } @@ -2275,7 +2279,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const #define MAX_SHOPITEM 100 struct npc_item_list items[MAX_SHOPITEM]; 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; 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) { case ITEMSHOP: { 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); 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; } 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); 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,','); break; } + default: + is_discount = 1; + break; } 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.itemshop_nameid = nameid; // Item 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.m = m; 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 } +/** [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 * Not sure, seem to add label in a chainlink diff --git a/src/map/npc.h b/src/map/npc.h index 80770e96aa..a137dbb2c9 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -60,6 +60,7 @@ struct npc_data { int count; int itemshop_nameid; // Item Shop cost item ID char pointshop_str[32]; // Point Shop cost variable name + bool discount; } shop; struct { 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; 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 int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);