ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.C
(Generate patch)

Comparing deliantra/server/server/shop.C (file contents):
Revision 1.81 by root, Wed Apr 28 19:20:48 2010 UTC vs.
Revision 1.95 by root, Sat Nov 17 23:40:04 2018 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team 6 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 7 * Copyright (©) 1992 Frank Tore Johansen
7 * 8 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 9 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 10 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 11 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 12 * option) any later version.
12 * 13 *
13 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 17 * GNU General Public License for more details.
17 * 18 *
18 * You should have received a copy of the Affero GNU General Public License 19 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 20 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 21 * <http://www.gnu.org/licenses/>.
21 * 22 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 23 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 24 */
24 25
25#include <global.h> 26#include <global.h>
26#include <spells.h> 27#include <spells.h>
29#include <sproto.h> 30#include <sproto.h>
30 31
31/* this is a measure of how effective store specialisation is. A general store 32/* this is a measure of how effective store specialisation is. A general store
32 * will offer this proportion of the 'maximum' price, a specialised store will 33 * will offer this proportion of the 'maximum' price, a specialised store will
33 * offer a range of prices around it such that the maximum price is always one 34 * offer a range of prices around it such that the maximum price is always one
34 * therefore making this number higher, makes specialisation less effective. 35 * therefore making this number higher, makes specialisation less effective.
35 * setting this value above 1 or to a negative value would have interesting, 36 * setting this value above 1 or to a negative value would have interesting,
36 * (though not useful) effects. 37 * (though not useful) effects.
37 */ 38 */
38#define SPECIALISATION_EFFECT .5 39#define SPECIALISATION_EFFECT .5
39 40
55 * would not be done. 56 * would not be done.
56 * 57 *
57 * Added F_APPROX flag, which means that the price returned should be wrong by 58 * Added F_APPROX flag, which means that the price returned should be wrong by
58 * an amount related to the player's bargaining skill. 59 * an amount related to the player's bargaining skill.
59 * 60 *
60 * Added F_SHOP flag to mean that the specialisation of the shop on the player's 61 * Added F_SHOP flag to mean that the specialisation of the shop on the player's
61 * current map should be taken into account when determining the price. Shops that 62 * current map should be taken into account when determining the price. Shops that
62 * specialise in what is being traded will give better prices than those that do not. 63 * specialise in what is being traded will give better prices than those that do not.
63 * 64 *
64 * CF 0.91.4 - This function got changed around a bit. Now the 65 * CF 0.91.4 - This function got changed around a bit. Now the
65 * number of object is multiplied by the value early on. This fixes problems 66 * number of object is multiplied by the value early on. This fixes problems
66 * with items worth very little. What happened before is that various 67 * with items worth very little. What happened before is that various
67 * divisions took place, the value got rounded to 0 (Being an int), and 68 * divisions took place, the value got rounded to 0 (Being an int), and
79 int no_bargain; 80 int no_bargain;
80 int identified; 81 int identified;
81 int not_cursed; 82 int not_cursed;
82 int approximate; 83 int approximate;
83 int shop; 84 int shop;
84 double diff;
85 85
86 approx_range = 0; 86 approx_range = 0;
87 87
88 no_bargain = flag & F_NO_BARGAIN; 88 no_bargain = flag & F_NO_BARGAIN;
89 identified = flag & F_IDENTIFIED; 89 identified = flag & F_IDENTIFIED;
170 /* Value of the wand is multiplied by the number of 170 /* Value of the wand is multiplied by the number of
171 * charges. the treasure code already sets up the value 171 * charges. the treasure code already sets up the value
172 * 50 charges is used as the baseline. 172 * 50 charges is used as the baseline.
173 */ 173 */
174 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified) 174 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
175 val *= tmp->stats.food / 50; 175 val *= tmp->stats.food;
176 else /* if not identified, presume one charge */ 176 /* if not identified, presume one charge */
177 val /= 50; 177 val /= 50;
178 } 178 }
179 179
180 /* Limit amount of money you can get for really great items. */ 180 /* Limit amount of money you can get for really great items. */
181 if (flag == F_SELL) 181 if (flag == F_SELL)
182 val = value_limit (val, number, who, shop); 182 val = value_limit (val, number, who, shop);
190 * AND Cha = 30 will get optimal price. 190 * AND Cha = 30 will get optimal price.
191 * Thus charisma will never get useless. 191 * Thus charisma will never get useless.
192 * -b.e. edler@heydernet.de 192 * -b.e. edler@heydernet.de
193 */ 193 */
194 194
195 if (who && who->type == PLAYER) 195 if (who && who->is_player ())
196 { 196 {
197 int lev_bargain = 0; 197 int lev_bargain = 0;
198 int lev_identify = 0; 198 int lev_identify = 0;
199 199
200 if (find_skill_by_number (who, SK_BARGAINING)) 200 if (!no_bargain)
201 lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level; 201 if (object *skill = find_skill_by_name (who, shstr_bargaining))
202 lev_bargain = skill->level;
202 203
203 if (const typedata *tmptype = get_typedata (tmp->type)) 204 if (const typedata *tmptype = get_typedata (tmp->type))
204 { 205 {
205 if (int idskill1 = tmptype->identifyskill) 206 if (int idskill1 = tmptype->identifyskill)
206 { 207 {
217 /* ratio determines how much of the price modification 218 /* ratio determines how much of the price modification
218 * will come from the basic stat charisma 219 * will come from the basic stat charisma
219 * the rest will come from the level in bargaining skill 220 * the rest will come from the level in bargaining skill
220 */ 221 */
221 const double cha_ratio = 0.40; 222 const double cha_ratio = 0.40;
222 223 double bargaining = max (0., 1. - powf (double (lev_bargain) / MAXLEVEL_TREASURE, 0.25));
223 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / MAXLEVEL_TREASURE, 0.25);
224 diff = (1. - cha_ratio) * diff + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.); 224 double charisma = (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.);
225 diff = .02 + (.80 - .02) * diff; 225
226 double factor = (1. - cha_ratio) * bargaining + cha_ratio * charisma;
227
228 // scale 0..1 to 2 .. 80%
229 factor = lerp (factor, 0., 1., 0.02, 0.80);
226 230
227 if (flag == F_BUY) 231 if (flag == F_BUY)
228 val += val * diff; 232 val += val * factor;
229 else if (flag == F_SELL) 233 else if (flag == F_SELL)
230 val -= val * diff; 234 val -= val * factor;
231 235
232 // now find a price range. the less good we can judge, the larger the range is 236 // now find a price range. the less good we can judge, the larger the range is
233 // then the range is adjusted randomly around the correct value 237 // then the range is adjusted randomly around the correct value
234 if (approximate) 238 if (approximate)
235 approx_range = val / sqrt (lev_identify * 3 + 1); 239 approx_range = val / sqrt (lev_identify * 3 + 1);
252 { 256 {
253 if (flag == F_SELL) 257 if (flag == F_SELL)
254 val *= shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map); 258 val *= shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map);
255 else if (flag == F_BUY) 259 else if (flag == F_BUY)
256 { 260 {
257 /* 261 /*
258 * when buying, if the item was sold by another player, it is ok to 262 * when buying, if the item was sold by another player, it is ok to
259 * let the item be sold cheaper, according to the specialisation of 263 * let the item be sold cheaper, according to the specialisation of
260 * the shop. If a player sold an item here, then his sale price was 264 * the shop. If a player sold an item here, then his sale price was
261 * multiplied by the specialisation ratio, to do the same to the buy 265 * multiplied by the specialisation ratio, to do the same to the buy
262 * price will not generate extra money. However, the 266 * price will not generate extra money. However, the
263 * same is not true of generated items, these have to /divide/ by the 267 * same is not true of generated items, these have to /divide/ by the
264 * specialisation, so that the price is never less than what they could 268 * specialisation, so that the price is never less than what they could
265 * be sold for (otherwise players could camp map resets to make money). 269 * be sold for (otherwise players could camp map resets to make money).
266 * In game terms, a non-specialist shop, might not recognise the true 270 * In game terms, a non-specialist shop, might not recognise the true
267 * value of the items they sell (much like how people sometimes find 271 * value of the items they sell (much like how people sometimes find
268 * antiques in a junk shop in real life). 272 * antiques in a junk shop in real life).
269 */ 273 */
270 if (tmp->flag [FLAG_PLAYER_SOLD]) 274 if (tmp->flag [FLAG_PLAYER_SOLD])
271 val *= shop_specialisation_ratio (tmp, who->map); 275 val *= shop_specialisation_ratio (tmp, who->map);
272 else 276 else
273 val /= shop_specialisation_ratio (tmp, who->map); 277 val /= shop_specialisation_ratio (tmp, who->map);
274 278
275 val *= shop_greed (who->map) / shopkeeper_approval (who->map, who); 279 val *= shop_greed (who->map) / shopkeeper_approval (who->map, who);
276 } 280 }
277 281
278 /* we will also have an extra 0-5% variation between shops of the same type 282 /* we will also have an extra 0-5% variation between shops of the same type
279 * for valuable items (below a value of 50 this effect wouldn't be very 283 * for valuable items (below a value of 50 this effect wouldn't be very
280 * pointful, and could give fun with rounding. 284 * pointful, and could give fun with rounding.
281 */ 285 */
282 //TODO: why use cosf at all, just % and scale linearly, gives more even distribution 286 //TODO: why use cosf at all, just % and scale linearly, gives more even distribution
283 if (val > 50) 287 if (val > 50)
284 val *= 1 + .05f * cosf ((tmp->uuid.seq & 0xffff) * M_PI * 2. / 0x10000); 288 val *= 1 + .05f * cosf ((tmp->uuid.seq & 0xffff) * M_PI * 2. / 0x10000);
380 { 384 {
381 if (!idskill1 || !find_skill_by_number (who, idskill1)) 385 if (!idskill1 || !find_skill_by_number (who, idskill1))
382 { 386 {
383 if (!idskill2 || !find_skill_by_number (who, idskill2)) 387 if (!idskill2 || !find_skill_by_number (who, idskill2))
384 { 388 {
385 if (!find_skill_by_number (who, SK_BARGAINING)) 389 if (!find_skill_by_name (who, shstr_bargaining))
386 { 390 {
387 int num, cointype = 0; 391 int num, cointype = 0;
388 archetype *coin = find_next_coin (real_value, &cointype); 392 archetype *coin = find_next_coin (real_value, &cointype);
389 393
390 if (!coin) 394 if (!coin)
440 } 444 }
441 445
442 for (tmp = op->inv; tmp; tmp = tmp->below) 446 for (tmp = op->inv; tmp; tmp = tmp->below)
443 if (tmp->type == MONEY) 447 if (tmp->type == MONEY)
444 total += tmp->nrof * (sint64)tmp->value; 448 total += tmp->nrof * (sint64)tmp->value;
445 else if (tmp->type == CONTAINER && tmp->flag [FLAG_APPLIED] && (!tmp->race || tmp->race.contains ("gold"))) 449 else if (tmp->type == CONTAINER && tmp->flag [FLAG_APPLIED] && (!tmp->race || tmp->race.contains (shstr_gold)))
446 total += query_money (tmp); 450 total += query_money (tmp);
447 451
448 return total; 452 return total;
449} 453}
450 454
465 return 0; 469 return 0;
466 470
467 pay_from_container (pl, pl, to_pay); 471 pay_from_container (pl, pl, to_pay);
468 472
469 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 473 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
470 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains ("gold"))) 474 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
471 pay_from_container (pl, pouch, to_pay); 475 pay_from_container (pl, pouch, to_pay);
472 476
473 pl->update_stats (); 477 pl->update_stats ();
474 return 1; 478 return 1;
475} 479}
497 * This determins the amount of exp (if any) gained for bargaining. 501 * This determins the amount of exp (if any) gained for bargaining.
498 */ 502 */
499 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay; 503 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay;
500 504
501 if (saved_money > 0) 505 if (saved_money > 0)
502 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE); 506 change_exp (pl, saved_money, shstr_bargaining, SK_EXP_NONE);
503 507
504 pay_from_container (pl, pl, to_pay); 508 pay_from_container (pl, pl, to_pay);
505 509
506 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 510 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
507 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains ("gold"))) 511 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
508 pay_from_container (pl, pouch, to_pay); 512 pay_from_container (pl, pouch, to_pay);
509 513
510 pl->update_stats (); 514 pl->update_stats ();
511 515
512 return 1; 516 return 1;
614 coin_objs[i]->destroy (); 618 coin_objs[i]->destroy ();
615} 619}
616 620
617/* Checks all unpaid items in op's inventory, adds up all the money they 621/* Checks all unpaid items in op's inventory, adds up all the money they
618 * have, and checks that they can actually afford what they want to buy. 622 * have, and checks that they can actually afford what they want to buy.
619 * Returns 1 if they can, and 0 if they can't. also prints an appropriate message 623 * Returns 1 if they can, and 0 if they can't. also prints an appropriate message
620 * to the player 624 * to the player
621 */ 625 */
622int 626int
623can_pay (object *pl) 627can_pay (object *pl)
624{ 628{
717void 721void
718pay_player (object *pl, sint64 amount) 722pay_player (object *pl, sint64 amount)
719{ 723{
720 int count = 0; 724 int count = 0;
721 archetype *at = 0; 725 archetype *at = 0;
722 object *pouch = 0, *tmp = 0; 726 object *pouch = 0;
723 727
724 for (count = 0; coins[count]; count++) 728 for (count = 0; coins[count]; count++)
725 { 729 {
726 at = archetype::find (coins[count]); 730 at = archetype::find (coins[count]);
727 731
729 LOG (llevError, "Could not find %s archetype\n", coins[count]); 733 LOG (llevError, "Could not find %s archetype\n", coins[count]);
730 else if ((amount / at->value) > 0) 734 else if ((amount / at->value) > 0)
731 { 735 {
732 for (pouch = pl->inv; pouch; pouch = pouch->below) 736 for (pouch = pl->inv; pouch; pouch = pouch->below)
733 { 737 {
734 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && pouch->race.contains ("gold")) 738 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && pouch->race.contains (shstr_gold))
735 { 739 {
736 int w = at->weight * (100 - pouch->stats.Str) / 100; 740 int w = at->weight * (100 - pouch->stats.Str) / 100;
737 int n = amount / at->value; 741 int n = amount / at->value;
738 742
739 if (w == 0) 743 if (w == 0)
819 * exp/10 -> 1 for each gold coin 823 * exp/10 -> 1 for each gold coin
820 */ 824 */
821 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP); 825 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP);
822 826
823 if (extra_gain > 0) 827 if (extra_gain > 0)
824 change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE); 828 change_exp (pl, extra_gain / 10, shstr_bargaining, SK_EXP_NONE);
825 829
826 pay_player (pl, amount); 830 pay_player (pl, amount);
827 831
828 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.", 832 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.",
829 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op)); 833 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op));
834 838
835 return true; 839 return true;
836} 840}
837 841
838/* returns a double that is the ratio of the price that a shop will offer for 842/* returns a double that is the ratio of the price that a shop will offer for
839 * item based on the shops specialisation. Does not take account of greed, 843 * item based on the shops specialisation. Does not take account of greed,
840 * returned value is between SPECIALISATION_EFFECT and 1. 844 * returned value is between SPECIALISATION_EFFECT and 1.
841 */ 845 */
842static double 846static double
843shop_specialisation_ratio (const object *item, const maptile *map) 847shop_specialisation_ratio (const object *item, const maptile *map)
844{ 848{
852 return 0; 856 return 0;
853 } 857 }
854 858
855 if (!item->type) 859 if (!item->type)
856 { 860 {
857 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n"); 861 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type: %s\n", item->debug_desc ());
858 /* 862 /*
859 * I'm not really sure what the /right/ thing to do here is, these types of 863 * I'm not really sure what the /right/ thing to do here is, these types of
860 * item shouldn't exist anyway, but returning the ratio is probably the best bet.." 864 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
861 */ 865 */
862 return SPECIALISATION_EFFECT; 866 return SPECIALISATION_EFFECT;
863 } 867 }
864 868
865 if (map->shopitems) 869 if (map->shopitems)
867 if (items[i].typenum == item->type || (!items[i].typenum && !likedness)) 871 if (items[i].typenum == item->type || (!items[i].typenum && !likedness))
868 likedness = items[i].strength; 872 likedness = items[i].strength;
869 873
870 if (likedness > 100) 874 if (likedness > 100)
871 { /* someone has been rather silly with the map headers. */ 875 { /* someone has been rather silly with the map headers. */
872 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, &map->path); 876 LOG (llevDebug, "shop_specialisation ratio: item %s on map %s is above 100%%\n", item->debug_desc (), &map->path);
873 likedness = 100; 877 likedness = 100;
874 } 878 }
875 879
876 if (likedness < -100) 880 if (likedness < -100)
877 { 881 {
878 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, &map->path); 882 LOG (llevDebug, "shop_specialisation ratio: item %s on map %s is below -100%%\n", item->debug_desc (), &map->path);
879 likedness = -100; 883 likedness = -100;
880 } 884 }
881 885
882 return lerp (double (likedness), -100., 100., SPECIALISATION_EFFECT, 1.); 886 return lerp (double (likedness), -100., 100., SPECIALISATION_EFFECT, 1.);
883} 887}
901 ? DISLIKE_RATIO 905 ? DISLIKE_RATIO
902 : 1.; 906 : 1.;
903} 907}
904 908
905/* limit the value of items based on the wealth of the shop. If the item is close 909/* limit the value of items based on the wealth of the shop. If the item is close
906 * to the maximum value a shop will offer, we start to reduce it, if the item is 910 * to the maximum value a shop will offer, we start to reduce it, if the item is
907 * below the minimum value the shop is prepared to trade in, then we don't 911 * below the minimum value the shop is prepared to trade in, then we don't
908 * want it and offer nothing. If it isn't a shop, check whether we should do generic 912 * want it and offer nothing. If it isn't a shop, check whether we should do generic
909 * value reduction. 913 * value reduction.
910 * 914 *
911 */ 915 */
912static sint64 916static sint64
913value_limit (sint64 val, int quantity, const object *who, int isshop) 917value_limit (sint64 val, int quantity, const object *who, int isshop)
914{ 918{
915 sint64 newval, unit_price, tmpshopmax; 919 sint64 newval, unit_price, tmpshopmax;
955{ 959{
956 dynbuf_text buf; 960 dynbuf_text buf;
957 maptile *map = op->map; 961 maptile *map = op->map;
958 962
959 /*shopitems *items=map->shopitems; */ 963 /*shopitems *items=map->shopitems; */
960 int pos = 0, i; 964 int i;
961 double opinion = 0; 965 double opinion = 0;
962 966
963 if (op->type != PLAYER) 967 if (op->type != PLAYER)
964 return 0; 968 return 0;
965 969
1031 1035
1032struct shopinv 1036struct shopinv
1033{ 1037{
1034 char *item_sort; 1038 char *item_sort;
1035 char *item_real; 1039 char *item_real;
1040 sint64 value;
1036 uint16 type; 1041 uint16 type;
1037 uint32 nrof; 1042 uint32 nrof;
1038}; 1043};
1039 1044
1040/* There are a lot fo extra casts in here just to suppress warnings - it 1045/* There are a lot fo extra casts in here just to suppress warnings - it
1073 * so the display is properly. 1078 * so the display is properly.
1074 */ 1079 */
1075 if (tmp->nrof == 0) 1080 if (tmp->nrof == 0)
1076 items[*numitems].nrof++; 1081 items[*numitems].nrof++;
1077 items[*numitems].type = tmp->type; 1082 items[*numitems].type = tmp->type;
1083
1084 items[*numitems].value = tmp->value;
1078 1085
1079 switch (tmp->type) 1086 switch (tmp->type)
1080 { 1087 {
1081#if 0 1088#if 0
1082 case BOOTS: 1089 case BOOTS:
1094#endif 1101#endif
1095 1102
1096 default: 1103 default:
1097 items[*numitems].item_sort = strdup (query_base_name (tmp, 0)); 1104 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1098 items[*numitems].item_real = strdup (query_base_name (tmp, 1)); 1105 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1106 items[*numitems].value += tmp->value;
1099 (*numitems)++; 1107 (*numitems)++;
1100 break; 1108 break;
1101 } 1109 }
1102 1110
1103 tmp->set_flag (FLAG_UNPAID); 1111 tmp->set_flag (FLAG_UNPAID);
1105 1113
1106void 1114void
1107shop_listing (object *sign, object *op) 1115shop_listing (object *sign, object *op)
1108{ 1116{
1109 int i, j, x1, x2, y1, y2; 1117 int i, j, x1, x2, y1, y2;
1110 const char *shop_coords = sign->kv (shstr_shop_coords); 1118 const char *shop_coords = sign->kv [shstr_shop_coords];
1111 object *stack; 1119 object *stack;
1112 shopinv *items; 1120 shopinv *items;
1113 1121
1114 /* Should never happen, but just in case a monster does apply a sign */ 1122 /* Should never happen, but just in case a monster does apply a sign */
1115 if (!op->is_player ()) 1123 if (!op->is_player ())
1159 { 1167 {
1160 /* Collapse items of the same name together */ 1168 /* Collapse items of the same name together */
1161 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real)) 1169 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real))
1162 items[i + 1].nrof += items[i].nrof; 1170 items[i + 1].nrof += items[i].nrof;
1163 else 1171 else
1164 buf.printf (" %4d %s\n", items[i].nrof ? items[i].nrof : 1, items[i].nrof == 1 ? items[i].item_sort : items[i].item_real); 1172 {
1173 buf.printf (
1174 " %4d %s\n for %s\n",
1175 items[i].nrof ? items[i].nrof : 1,
1176 items[i].nrof == 1 ? items[i].item_sort : items[i].item_real,
1177 cost_string_from_value (items[i].value, op->flag [FLAG_WIZ] ? 0 : 1));
1178 }
1165 1179
1166 free (items[i].item_sort); 1180 free (items[i].item_sort);
1167 free (items[i].item_real); 1181 free (items[i].item_real);
1168 } 1182 }
1169 1183

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines