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.67 by root, Mon Apr 27 01:38:49 2009 UTC vs.
Revision 1.92 by root, Mon Oct 29 23:55:55 2012 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 (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 9 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your option) any later version. 11 * option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
20 * 21 *
21 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 23 */
23 24
24#include <global.h> 25#include <global.h>
25#include <spells.h> 26#include <spells.h>
26#include <skills.h> 27#include <skills.h>
27#include <living.h> 28#include <living.h>
28#include <sproto.h> 29#include <sproto.h>
29#include <math.h>
30 30
31/* this is a measure of how effective store specialisation is. A general store 31/* 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 32 * 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 33 * 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. 34 * therefore making this number higher, makes specialisation less effective.
79 int no_bargain; 79 int no_bargain;
80 int identified; 80 int identified;
81 int not_cursed; 81 int not_cursed;
82 int approximate; 82 int approximate;
83 int shop; 83 int shop;
84 double diff;
85 84
86 approx_range = 0; 85 approx_range = 0;
87 86
88 no_bargain = flag & F_NO_BARGAIN; 87 no_bargain = flag & F_NO_BARGAIN;
89 identified = flag & F_IDENTIFIED; 88 identified = flag & F_IDENTIFIED;
90 not_cursed = flag & F_NOT_CURSED; 89 not_cursed = flag & F_NOT_CURSED;
91 approximate = flag & F_APPROX; 90 approximate = flag & F_APPROX;
92 shop = flag & F_SHOP; 91 shop = flag & F_SHOP;
93 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP); 92 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP);
94 93
94 int number = tmp->number_of ();
95
95 if (tmp->type == MONEY) 96 if (tmp->type == MONEY)
96 return tmp->nrof * tmp->value; 97 return number * tmp->value;
97 98
98 if (tmp->type == GEM) 99 if (tmp->type == GEM)
99 { 100 {
100 if (flag == F_TRUE) 101 if (flag == F_TRUE)
101 return (tmp->nrof * tmp->value); 102 return number * tmp->value;
102 103
103 if (flag == F_BUY) 104 if (flag == F_BUY)
104 return (sint64) (1.03 * tmp->nrof * tmp->value); 105 return 1.03 * number * tmp->value;
105 106
106 if (flag == F_SELL) 107 if (flag == F_SELL)
107 return (sint64) (0.97 * tmp->nrof * tmp->value); 108 return 0.97 * number * tmp->value;
108 109
109 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ()); 110 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ());
110 return 0; 111 return 0;
111 } 112 }
112 113
113 int number = tmp->number_of ();
114
115 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified) 114 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
116 { 115 {
117 if (!not_cursed && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 116 if (!not_cursed && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
118 return 0; 117 return 0;
119 else 118 else
120 val = tmp->value * number; 119 val = number * tmp->value;
121 } 120 }
122 /* This area deals with objects that are not identified, but can be */ 121 /* This area deals with objects that are not identified, but can be */
123 else 122 else
124 { 123 {
125 if (flag == F_BUY) 124 if (flag == F_BUY)
134 else 133 else
135 { 134 {
136 /* Get 2/3'rd value for applied objects, 1/3'rd for totally 135 /* Get 2/3'rd value for applied objects, 1/3'rd for totally
137 * unknown objects 136 * unknown objects
138 */ 137 */
139 if (QUERY_FLAG (tmp, FLAG_BEEN_APPLIED)) 138 if (tmp->flag [FLAG_BEEN_APPLIED])
140 val = number * tmp->arch->value * 2 / 3; 139 val = number * tmp->arch->value * 2 / 3;
141 else 140 else
142 val = number * tmp->arch->value / 3; 141 val = number * tmp->arch->value / 3;
143 } 142 }
144 } 143 }
145 } 144 }
146 145
147 /* If the item has been applied or identifed or does not need to be 146 /* If the item has been applied or identifed or does not need to be
151 * tmp->arch->magic for any magic. The check for archetype 150 * tmp->arch->magic for any magic. The check for archetype
152 * magic is to not give extra money for archetypes that are by 151 * magic is to not give extra money for archetypes that are by
153 * default magical. This is because the archetype value should have 152 * default magical. This is because the archetype value should have
154 * already figured in that value. 153 * already figured in that value.
155 */ 154 */
156 if ((QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified || 155 if ((tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified || tmp->flag [FLAG_BEEN_APPLIED])
157 QUERY_FLAG (tmp, FLAG_BEEN_APPLIED)) && tmp->magic && (tmp->arch == NULL || !tmp->arch->magic)) 156 && tmp->magic && (!tmp->arch || !tmp->arch->magic))
158 { 157 {
159 if (tmp->magic > 0) 158 if (tmp->magic > 0)
160 val *= (3 * tmp->magic * tmp->magic * tmp->magic); 159 val *= 3 * tmp->magic * tmp->magic * tmp->magic;
161 else 160 else
162 /* Note that tmp->magic is negative, so that this 161 /* Note that tmp->magic is negative, so that this
163 * will actually be something like val /=2, /=3, etc. 162 * will actually be something like val /=2, /=3, etc.
164 */ 163 */
165 val /= (1 - tmp->magic); 164 val /= 1 - tmp->magic;
166 } 165 }
167 166
168 if (tmp->type == WAND) 167 if (tmp->type == WAND)
169 { 168 {
170 /* Value of the wand is multiplied by the number of 169 /* Value of the wand is multiplied by the number of
171 * charges. the treasure code already sets up the value 170 * charges. the treasure code already sets up the value
172 * 50 charges is used as the baseline. 171 * 50 charges is used as the baseline.
173 */ 172 */
174 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified) 173 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
175 val = (val * tmp->stats.food) / 50; 174 val *= tmp->stats.food;
176 else /* if not identified, presume one charge */ 175 /* if not identified, presume one charge */
177 val /= 50; 176 val /= 50;
178 } 177 }
179 178
180 /* Limit amount of money you can get for really great items. */ 179 /* Limit amount of money you can get for really great items. */
181 if (flag == F_SELL) 180 if (flag == F_SELL)
182 val = value_limit ((sint64) val, number, who, shop); 181 val = value_limit (val, number, who, shop);
183 182
184 // use a nonlinear price adjustment. as my predecessor said, don't change 183 // use a nonlinear price adjustment. as my predecessor said, don't change
185 // the archetypes, its work required for balancing, and we don't care. 184 // the archetypes, its work required for balancing, and we don't care.
186 //val = pow (val, 1.05); 185 //val = pow (val, 1.05);
187 186
190 * AND Cha = 30 will get optimal price. 189 * AND Cha = 30 will get optimal price.
191 * Thus charisma will never get useless. 190 * Thus charisma will never get useless.
192 * -b.e. edler@heydernet.de 191 * -b.e. edler@heydernet.de
193 */ 192 */
194 193
195 if (who && who->type == PLAYER) 194 if (who && who->is_player ())
196 { 195 {
197 int lev_bargain = 0; 196 int lev_bargain = 0;
198 int lev_identify = 0; 197 int lev_identify = 0;
199 198
200 if (find_skill_by_number (who, SK_BARGAINING)) 199 if (!no_bargain)
201 lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level; 200 if (object *skill = find_skill_by_name (who, shstr_bargaining))
201 lev_bargain = skill->level;
202 202
203 if (const typedata *tmptype = get_typedata (tmp->type)) 203 if (const typedata *tmptype = get_typedata (tmp->type))
204 { 204 {
205 if (int idskill1 = tmptype->identifyskill) 205 if (int idskill1 = tmptype->identifyskill)
206 { 206 {
217 /* ratio determines how much of the price modification 217 /* ratio determines how much of the price modification
218 * will come from the basic stat charisma 218 * will come from the basic stat charisma
219 * the rest will come from the level in bargaining skill 219 * the rest will come from the level in bargaining skill
220 */ 220 */
221 const double cha_ratio = 0.40; 221 const double cha_ratio = 0.40;
222 222 double bargaining = max (0., 1. - powf (double (lev_bargain) / MAXLEVEL_TREASURE, 0.25));
223 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / (double) settings.max_level, 0.25);
224 diff = (1. - cha_ratio) * diff + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.); 223 double charisma = (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.);
225 diff = .02 + (.80 - .02) * diff; 224
225 double factor = (1. - cha_ratio) * bargaining + cha_ratio * charisma;
226
227 // scale 0..1 to 2 .. 80%
228 factor = lerp (factor, 0., 1., 0.02, 0.80);
226 229
227 if (flag == F_BUY) 230 if (flag == F_BUY)
228 val += val * diff; 231 val += val * factor;
229 else if (flag == F_SELL) 232 else if (flag == F_SELL)
230 val -= val * diff; 233 val -= val * factor;
231 234
232 // now find a price range. the less good we can judge, the larger the range is 235 // 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 236 // then the range is adjusted randomly around the correct value
234 if (approximate) 237 if (approximate)
235 approx_range = sint64 (val / sqrt (lev_identify * 3 + 1)); 238 approx_range = val / sqrt (lev_identify * 3 + 1);
236 } 239 }
237 240
238 /* I don't think this should really happen - if it does, it indicates and 241 /* I don't think this should really happen - if it does, it indicates and
239 * overflow of diff above. That should only happen if 242 * overflow of diff above. That should only happen if
240 * we are selling objects - in that case, the person just 243 * we are selling objects - in that case, the person just
241 * gets no money. 244 * gets no money.
242 */ 245 */
243 if ((sint64) val < 0) 246 if ((sint64) val < 0)
244 val = 0; 247 val = 0;
245 248
246 /* Unidentified stuff won't sell for more than 60gp */ 249 /* Unidentified stuff won't sell for more than 10gp */
247 if (flag == F_SELL && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && need_identify (tmp) && !identified) 250 if (flag == F_SELL && !tmp->flag [FLAG_IDENTIFIED] && tmp->need_identify () && !identified)
248 { 251 min_it (val, 1000);
249 val = (val > 600) ? 600 : val;
250 }
251 252
252 /* if we are in a shop, check how the type of shop should affect the price */ 253 /* if we are in a shop, check how the type of shop should affect the price */
253 if (shop && who) 254 if (shop && who)
254 { 255 {
255 if (flag == F_SELL) 256 if (flag == F_SELL)
256 val = (val * shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map)); 257 val *= shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map);
257 else if (flag == F_BUY) 258 else if (flag == F_BUY)
258 { 259 {
259 /* 260 /*
260 * when buying, if the item was sold by another player, it is ok to 261 * when buying, if the item was sold by another player, it is ok to
261 * let the item be sold cheaper, according to the specialisation of 262 * let the item be sold cheaper, according to the specialisation of
267 * be sold for (otherwise players could camp map resets to make money). 268 * be sold for (otherwise players could camp map resets to make money).
268 * In game terms, a non-specialist shop, might not recognise the true 269 * In game terms, a non-specialist shop, might not recognise the true
269 * value of the items they sell (much like how people sometimes find 270 * value of the items they sell (much like how people sometimes find
270 * antiques in a junk shop in real life). 271 * antiques in a junk shop in real life).
271 */ 272 */
272 if (QUERY_FLAG (tmp, FLAG_PLAYER_SOLD)) 273 if (tmp->flag [FLAG_PLAYER_SOLD])
273 val = (val * shop_greed (who->map) * shop_specialisation_ratio (tmp, who->map) / shopkeeper_approval (who->map, who)); 274 val *= shop_specialisation_ratio (tmp, who->map);
274 else 275 else
275 val = (val * shop_greed (who->map) / (shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who))); 276 val /= shop_specialisation_ratio (tmp, who->map);
277
278 val *= shop_greed (who->map) / shopkeeper_approval (who->map, who);
276 } 279 }
277 280
278 /* we will also have an extra 0-5% variation between shops of the same type 281 /* 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 282 * for valuable items (below a value of 50 this effect wouldn't be very
280 * pointful, and could give fun with rounding. 283 * pointful, and could give fun with rounding.
281 */ 284 */
282 //TODO: why use cosf at all, just % and scale linearly, gives more even distribution 285 //TODO: why use cosf at all, just % and scale linearly, gives more even distribution
283 if (val > 50) 286 if (val > 50)
284 val += float (val) * .05f * cosf ((tmp->uuid.seq & 0xffff) * float (M_PI * 2. / 0x10000)); 287 val *= 1 + .05f * cosf ((tmp->uuid.seq & 0xffff) * M_PI * 2. / 0x10000);
285 } 288 }
286 289
287 return (sint64) val; 290 return val;
288} 291}
289 292
290/* Find the coin type that is worth more the 'c'. Starts at the 293/* Find the coin type that is worth more the 'c'. Starts at the
291 * cointype placement. 294 * cointype placement.
292 */ 295 */
296{ 299{
297 archetype *coin; 300 archetype *coin;
298 301
299 do 302 do
300 { 303 {
301 if (coins[*cointype] == NULL) 304 if (!coins [*cointype])
302 return NULL; 305 return 0;
306
303 coin = archetype::find (coins[*cointype]); 307 coin = archetype::find (coins [*cointype]);
308
304 if (coin == NULL) 309 if (!coin)
305 return NULL; 310 return 0;
311
306 *cointype += 1; 312 *cointype += 1;
307 } 313 }
308 while (coin->value > c); 314 while (coin->value > c);
309 315
310 return coin; 316 return coin;
321 * 10,000 silver or something) 327 * 10,000 silver or something)
322 */ 328 */
323const char * 329const char *
324cost_string_from_value (sint64 cost, int approx) 330cost_string_from_value (sint64 cost, int approx)
325{ 331{
326 static char buf[MAX_BUF];
327 archetype *coin, *next_coin; 332 archetype *coin, *next_coin;
328 int num, cointype = 0; 333 int num, cointype = 0;
329 334
330 coin = find_next_coin (cost, &cointype); 335 coin = find_next_coin (cost, &cointype);
331 if (coin == NULL) 336 if (!coin)
332 return "nothing"; 337 return "nothing";
333 338
334 num = cost / coin->value; 339 num = cost / coin->value;
335 /* so long as nrof is 32 bit, this is true. 340 /* so long as nrof is 32 bit, this is true.
336 * If it takes more coins than a person can possibly carry, this 341 * If it takes more coins than a person can possibly carry, this
337 * is basically true. 342 * is basically true.
338 */ 343 */
339 if ((cost / coin->value) > UINT32_MAX) 344 if (cost / coin->value > UINT32_MAX)
340 {
341 strcpy (buf, "an unimaginable sum of money"); 345 return "an unimaginable sum of money";
342 return buf;
343 }
344 346
345 cost -= num * (sint64)coin->value; 347 cost -= num * (sint64)coin->value;
346 348
347 sprintf (buf, "%d %s", num, num > 1 ? &coin->object::name_pl : &coin->object::name); 349 char *buf = format ("%d %s", num, num > 1 ? &coin->object::name_pl : &coin->object::name);
348 350
349 next_coin = find_next_coin (cost, &cointype); 351 next_coin = find_next_coin (cost, &cointype);
350 if (next_coin == NULL || approx) 352 if (!next_coin || approx)
351 return buf; 353 return buf;
352 354
353 coin = next_coin; 355 coin = next_coin;
354 num = cost / coin->value; 356 num = cost / coin->value;
355 cost -= num * (sint64)coin->value; 357 cost -= num * (sint64)coin->value;
356 358
357 sprintf (buf + strlen (buf), " and %d %s", num, num > 1 ? &coin->object::name_pl : &coin->object::name); 359 return format ("%s and %d %s", buf, num, num > 1 ? &coin->object::name_pl : &coin->object::name);
358
359 return buf;
360} 360}
361 361
362const char * 362const char *
363query_cost_string (const object *tmp, object *who, int flag) 363query_cost_string (const object *tmp, object *who, int flag)
364{ 364{
383 { 383 {
384 if (!idskill1 || !find_skill_by_number (who, idskill1)) 384 if (!idskill1 || !find_skill_by_number (who, idskill1))
385 { 385 {
386 if (!idskill2 || !find_skill_by_number (who, idskill2)) 386 if (!idskill2 || !find_skill_by_number (who, idskill2))
387 { 387 {
388 if (!find_skill_by_number (who, SK_BARGAINING)) 388 if (!find_skill_by_name (who, shstr_bargaining))
389 { 389 {
390 static char buf[MAX_BUF];
391 int num, cointype = 0; 390 int num, cointype = 0;
392 archetype *coin = find_next_coin (real_value, &cointype); 391 archetype *coin = find_next_coin (real_value, &cointype);
393 392
394 if (coin == NULL) 393 if (!coin)
395 return "nothing"; 394 return "nothing";
396 395
397 num = real_value / coin->value; 396 num = real_value / coin->value;
398 397
399 if (num == 1) 398 if (num == 1)
400 sprintf (buf, "about one %s", &coin->object::name); 399 return format ("about one %s", &coin->object::name);
401 else if (num < 5) 400 else if (num < 5)
402 sprintf (buf, "a few %s", &coin->object::name_pl); 401 return format ("a few %s", &coin->object::name_pl);
403 else if (num < 10) 402 else if (num < 10)
404 sprintf (buf, "several %s", &coin->object::name_pl); 403 return format ("several %s", &coin->object::name_pl);
405 else if (num < 25) 404 else if (num < 25)
406 sprintf (buf, "a moderate amount of %s", &coin->object::name_pl); 405 return format ("a moderate amount of %s", &coin->object::name_pl);
407 else if (num < 100) 406 else if (num < 100)
408 sprintf (buf, "lots of %s", &coin->object::name_pl); 407 return format ("lots of %s", &coin->object::name_pl);
409 else if (num < 1000) 408 else if (num < 1000)
410 sprintf (buf, "a great many %s", &coin->object::name_pl); 409 return format ("a great many %s", &coin->object::name_pl);
411 else 410 else
412 sprintf (buf, "a vast quantity of %s", &coin->object::name_pl); 411 return format ("a vast quantity of %s", &coin->object::name_pl);
413
414 return buf;
415 } 412 }
416 } 413 }
417 } 414 }
418 415
419 int hash = ((unsigned int) tmp->count * 174364621) & 1023;
420
421 if (approx_range) 416 if (approx_range)
422 { 417 {
418 int hash = tmp->random_seed () & 1023;
423 sint64 lo = (sint64) real_value - (approx_range * hash >> 10); 419 sint64 lo = real_value - (approx_range * hash >> 10);
424 static char buf[MAX_BUF];
425 420
426 sprintf (buf, "between %s", cost_string_from_value (lo, 1)); 421 return format ("between %s and %s",
427 sprintf (buf + strlen (buf), " and %s", cost_string_from_value (lo + approx_range, 1)); 422 cost_string_from_value (lo, 1),
428 423 cost_string_from_value (lo + approx_range, 1));
429 return buf;
430 } 424 }
431 } 425 }
432 426
433 return cost_string_from_value (real_value, 0); 427 return cost_string_from_value (real_value, 0);
434} 428}
449 } 443 }
450 444
451 for (tmp = op->inv; tmp; tmp = tmp->below) 445 for (tmp = op->inv; tmp; tmp = tmp->below)
452 if (tmp->type == MONEY) 446 if (tmp->type == MONEY)
453 total += tmp->nrof * (sint64)tmp->value; 447 total += tmp->nrof * (sint64)tmp->value;
454 else if (tmp->type == CONTAINER && QUERY_FLAG (tmp, FLAG_APPLIED) && (!tmp->race || tmp->race.contains ("gold"))) 448 else if (tmp->type == CONTAINER && tmp->flag [FLAG_APPLIED] && (!tmp->race || tmp->race.contains (shstr_gold)))
455 total += query_money (tmp); 449 total += query_money (tmp);
456 450
457 return total; 451 return total;
458} 452}
459 453
474 return 0; 468 return 0;
475 469
476 pay_from_container (pl, pl, to_pay); 470 pay_from_container (pl, pl, to_pay);
477 471
478 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 472 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
479 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (!pouch->race || pouch->race.contains ("gold"))) 473 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
480 pay_from_container (pl, pouch, to_pay); 474 pay_from_container (pl, pouch, to_pay);
481 475
482 pl->update_stats (); 476 pl->update_stats ();
483 return 1; 477 return 1;
484} 478}
506 * This determins the amount of exp (if any) gained for bargaining. 500 * This determins the amount of exp (if any) gained for bargaining.
507 */ 501 */
508 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay; 502 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay;
509 503
510 if (saved_money > 0) 504 if (saved_money > 0)
511 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE); 505 change_exp (pl, saved_money, shstr_bargaining, SK_EXP_NONE);
512 506
513 pay_from_container (pl, pl, to_pay); 507 pay_from_container (pl, pl, to_pay);
514 508
515 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 509 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
516 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (!pouch->race || pouch->race.contains ("gold"))) 510 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
517 pay_from_container (pl, pouch, to_pay); 511 pay_from_container (pl, pouch, to_pay);
518 512
519 pl->update_stats (); 513 pl->update_stats ();
520 514
521 return 1; 515 return 1;
588 at = archetype::find (coins[NUM_COINS - 1 - i]); 582 at = archetype::find (coins[NUM_COINS - 1 - i]);
589 583
590 if (at == NULL) 584 if (at == NULL)
591 LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]); 585 LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]);
592 586
593 coin_objs[i] = arch_to_object (at); 587 coin_objs[i] = at->instance ();
594 coin_objs[i]->nrof = 0; 588 coin_objs[i]->nrof = 0;
595 } 589 }
596 590
597 for (i = 0; i < NUM_COINS; i++) 591 for (i = 0; i < NUM_COINS; i++)
598 { 592 {
599 object &coin = *coin_objs[i]; 593 object &coin = *coin_objs[i];
600 sint64 num_coins = min ((to_pay + coin.value - 1) / coin.value, coin.nrof); 594 sint64 num_coins = min ((to_pay + coin.value - 1) / coin.value, (sint64) coin.nrof);
601 to_pay -= num_coins * coin.value; 595 to_pay -= num_coins * coin.value;
602 596
603 coin.nrof -= num_coins; 597 coin.nrof -= num_coins;
604 /* Now start making change. Start at the coin value 598 /* Now start making change. Start at the coin value
605 * below the one we just did, and work down to 599 * below the one we just did, and work down to
640 LOG (llevError, "can_pay(): called against something that isn't a player\n"); 634 LOG (llevError, "can_pay(): called against something that isn't a player\n");
641 return 0; 635 return 0;
642 } 636 }
643 637
644 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item) 638 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
645 if (QUERY_FLAG (item, FLAG_UNPAID)) 639 if (item->flag [FLAG_UNPAID])
646 { 640 {
647 unpaid_count++; 641 unpaid_count++;
648 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP); 642 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP);
649 } 643 }
650 644
679 { 673 {
680 next_item: 674 next_item:
681 675
682 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op) 676 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op)
683 { 677 {
684 if (QUERY_FLAG (op, FLAG_UNPAID)) 678 if (op->flag [FLAG_UNPAID])
685 { 679 {
686 char buf[MAX_BUF];
687 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP)); 680 const char *buf = query_cost_string (op, pl, F_BUY | F_SHOP);
688 681
689 if (!pay_for_item (op, pl)) 682 if (!pay_for_item (op, pl))
690 { 683 {
691 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl); 684 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
692 685
693 CLEAR_FLAG (op, FLAG_UNPAID); 686 op->clr_flag (FLAG_UNPAID);
694 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op)); 687 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op));
695 SET_FLAG (op, FLAG_UNPAID); 688 op->set_flag (FLAG_UNPAID);
696 return 0; 689 return 0;
697 } 690 }
698 else 691 else
699 { 692 {
700 CLEAR_FLAG (op, FLAG_UNPAID); 693 op->clr_flag (FLAG_UNPAID);
701 CLEAR_FLAG (op, FLAG_PLAYER_SOLD); 694 op->clr_flag (FLAG_PLAYER_SOLD);
702 new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op)); 695 new_draw_info_format (NDI_UNIQUE, 0, pl, "You paid %s for %s.", buf, query_name (op));
703 696
704 if (!merge_ob (op, op->env->inv)) 697 if (!merge_ob (op, op->env->inv))
705 esrv_update_item (UPD_FLAGS, pl, op); 698 esrv_update_item (UPD_FLAGS, pl, op);
706 699
707 goto next_item; 700 goto next_item;
727void 720void
728pay_player (object *pl, sint64 amount) 721pay_player (object *pl, sint64 amount)
729{ 722{
730 int count = 0; 723 int count = 0;
731 archetype *at = 0; 724 archetype *at = 0;
732 object *pouch = 0, *tmp = 0; 725 object *pouch = 0;
733 726
734 for (count = 0; coins[count]; count++) 727 for (count = 0; coins[count]; count++)
735 { 728 {
736 at = archetype::find (coins[count]); 729 at = archetype::find (coins[count]);
737 730
739 LOG (llevError, "Could not find %s archetype\n", coins[count]); 732 LOG (llevError, "Could not find %s archetype\n", coins[count]);
740 else if ((amount / at->value) > 0) 733 else if ((amount / at->value) > 0)
741 { 734 {
742 for (pouch = pl->inv; pouch; pouch = pouch->below) 735 for (pouch = pl->inv; pouch; pouch = pouch->below)
743 { 736 {
744 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && pouch->race.contains ("gold")) 737 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && pouch->race.contains (shstr_gold))
745 { 738 {
746 int w = at->weight * (100 - pouch->stats.Str) / 100; 739 int w = at->weight * (100 - pouch->stats.Str) / 100;
747 int n = amount / at->value; 740 int n = amount / at->value;
748 741
749 if (w == 0) 742 if (w == 0)
752 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit)) 745 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit))
753 { 746 {
754 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) 747 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n)
755 n = (pouch->weight_limit - pouch->carrying) / w; 748 n = (pouch->weight_limit - pouch->carrying) / w;
756 749
757 object *tmp = arch_to_object (at); 750 object *tmp = at->instance ();
758 tmp->nrof = n; 751 tmp->nrof = n;
759 amount -= tmp->nrof * tmp->value; 752 amount -= tmp->nrof * tmp->value;
760 pouch->insert (tmp); 753 pouch->insert (tmp);
761 } 754 }
762 } 755 }
763 } 756 }
764 757
765 if (amount / at->value > 0) 758 if (amount / at->value > 0)
766 { 759 {
767 object *tmp = arch_to_object (at); 760 object *tmp = at->instance ();
768 tmp->nrof = amount / tmp->value; 761 tmp->nrof = amount / tmp->value;
769 amount -= tmp->nrof * tmp->value; 762 amount -= tmp->nrof * tmp->value;
770 pl->insert (tmp); 763 pl->insert (tmp);
771 } 764 }
772 } 765 }
829 * exp/10 -> 1 for each gold coin 822 * exp/10 -> 1 for each gold coin
830 */ 823 */
831 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP); 824 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP);
832 825
833 if (extra_gain > 0) 826 if (extra_gain > 0)
834 change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE); 827 change_exp (pl, extra_gain / 10, shstr_bargaining, SK_EXP_NONE);
835 828
836 pay_player (pl, amount); 829 pay_player (pl, amount);
837 830
838 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.", 831 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.",
839 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op)); 832 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op));
840 pl->play_sound (sound_find ("shop_sell")); 833 pl->play_sound (sound_find ("shop_sell"));
841 834
842 SET_FLAG (op, FLAG_UNPAID); 835 op->set_flag (FLAG_UNPAID);
843 identify (op); 836 identify (op);
844 837
845 return true; 838 return true;
846} 839}
847 840
851 */ 844 */
852static double 845static double
853shop_specialisation_ratio (const object *item, const maptile *map) 846shop_specialisation_ratio (const object *item, const maptile *map)
854{ 847{
855 shopitems *items = map->shopitems; 848 shopitems *items = map->shopitems;
856 double likedness = 0.; 849 int likedness = 0;
857 int i; 850 int i;
858 851
859 if (item == NULL) 852 if (item == NULL)
860 { 853 {
861 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", &map->path); 854 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", &map->path);
862 return 0; 855 return 0;
863 } 856 }
864 857
865 if (!item->type) 858 if (!item->type)
866 { 859 {
867 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n"); 860 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type: %s\n", item->debug_desc ());
868 /* 861 /*
869 * I'm not really sure what the /right/ thing to do here is, these types of 862 * I'm not really sure what the /right/ thing to do here is, these types of
870 * item shouldn't exist anyway, but returning the ratio is probably the best bet.." 863 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
871 */ 864 */
872 return SPECIALISATION_EFFECT; 865 return SPECIALISATION_EFFECT;
873 } 866 }
874 867
875 if (map->shopitems) 868 if (map->shopitems)
876 {
877 for (i = 0; i < items[0].index; i++) 869 for (i = 0; i < items[0].index; i++)
878 if (items[i].typenum == item->type || (!items[i].typenum && likedness == 0.001)) 870 if (items[i].typenum == item->type || (!items[i].typenum && !likedness))
879 likedness = items[i].strength / 100.0; 871 likedness = items[i].strength;
880 }
881 872
882 if (likedness > 1.0) 873 if (likedness > 100)
883 { /* someone has been rather silly with the map headers. */ 874 { /* someone has been rather silly with the map headers. */
884 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, &map->path); 875 LOG (llevDebug, "shop_specialisation ratio: item %s on map %s is above 100%%\n", item->debug_desc (), &map->path);
885 likedness = 1.0; 876 likedness = 100;
886 } 877 }
887 878
888 if (likedness < -1.0) 879 if (likedness < -100)
889 { 880 {
890 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, &map->path); 881 LOG (llevDebug, "shop_specialisation ratio: item %s on map %s is below -100%%\n", item->debug_desc (), &map->path);
891 likedness = -1.0; 882 likedness = -100;
892 } 883 }
893 884
894 return lerp (likedness, -1., 1., SPECIALISATION_EFFECT, 1.); 885 return lerp (double (likedness), -100., 100., SPECIALISATION_EFFECT, 1.);
895} 886}
896 887
897/*returns the greed of the shop on map, or 1 if it isn't specified. */ 888/*returns the greed of the shop on map, or 1 if it isn't specified. */
898static double 889static double
899shop_greed (const maptile *map) 890shop_greed (const maptile *map)
917/* limit the value of items based on the wealth of the shop. If the item is close 908/* limit the value of items based on the wealth of the shop. If the item is close
918 * to the maximum value a shop will offer, we start to reduce it, if the item is 909 * to the maximum value a shop will offer, we start to reduce it, if the item is
919 * below the minimum value the shop is prepared to trade in, then we don't 910 * below the minimum value the shop is prepared to trade in, then we don't
920 * want it and offer nothing. If it isn't a shop, check whether we should do generic 911 * want it and offer nothing. If it isn't a shop, check whether we should do generic
921 * value reduction. 912 * value reduction.
922 * 913 *
923 */ 914 */
924static sint64 915static sint64
925value_limit (sint64 val, int quantity, const object *who, int isshop) 916value_limit (sint64 val, int quantity, const object *who, int isshop)
926{ 917{
927 sint64 newval, unit_price, tmpshopmax; 918 sint64 newval, unit_price, tmpshopmax;
949 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default 940 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default
950 941
951 if (map->shopmin && unit_price < map->shopmin) 942 if (map->shopmin && unit_price < map->shopmin)
952 return 0; 943 return 0;
953 else if (unit_price > tmpshopmax / 2) 944 else if (unit_price > tmpshopmax / 2)
954 newval = MIN ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax); 945 newval = min ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax);
955 else 946 else
956 newval = unit_price; 947 newval = unit_price;
957 } 948 }
958 949
959 newval *= quantity; 950 newval *= quantity;
963 954
964/* gives a desciption of the shop on their current map to the player op. */ 955/* gives a desciption of the shop on their current map to the player op. */
965int 956int
966describe_shop (const object *op) 957describe_shop (const object *op)
967{ 958{
959 dynbuf_text buf;
968 maptile *map = op->map; 960 maptile *map = op->map;
969 961
970 /*shopitems *items=map->shopitems; */ 962 /*shopitems *items=map->shopitems; */
971 int pos = 0, i; 963 int i;
972 double opinion = 0; 964 double opinion = 0;
973 char tmp[MAX_BUF] = "\0";
974 965
975 if (op->type != PLAYER) 966 if (op->type != PLAYER)
976 return 0; 967 return 0;
977 968
978 /*check if there is a shop specified for this map */ 969 /*check if there is a shop specified for this map */
979 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax) 970 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax)
980 { 971 {
981 new_draw_info (NDI_UNIQUE, 0, op, "From looking at the nearby shop you determine that it trades in:"); 972 buf << "From looking at the nearby shop you determine that it trades in ";
973 int lastcomma = 0, prevcomma = 0;
982 974
983 if (map->shopitems) 975 if (map->shopitems)
984 for (i = 0; i < map->shopitems[0].index; i++) 976 for (i = 0; i < map->shopitems[0].index; i++)
985 if (map->shopitems[i].name && map->shopitems[i].strength > 10) 977 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
986 { 978 {
987 snprintf (tmp + pos, sizeof (tmp) - pos, "%s, ", map->shopitems[i].name_pl); 979 buf << map->shopitems[i].name_pl;
988 pos += strlen (tmp + pos); 980 prevcomma = lastcomma;
981 lastcomma = buf.size (); // remember offset
982 buf << ", ";
989 } 983 }
990 984
991 if (!pos) 985 if (lastcomma)
986 {
987 buf.splice (lastcomma, 2);
988
989 if (prevcomma)
990 buf.splice (prevcomma, 2, " and ");
991 }
992 else
992 strcat (tmp, "a little of everything."); 993 buf << "a little of everything.";
993 994
994 /* format the string into a list */ 995 buf << ".\n\n";
995 make_list_like (tmp);
996 new_draw_info_format (NDI_UNIQUE, 0, op, "%s", tmp);
997 996
998 if (map->shopmax) 997 if (map->shopmax)
999 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade for items above %s.", cost_string_from_value (map->shopmax, 0)); 998 buf << "It won't trade for items above " << cost_string_from_value (map->shopmax, 0) << ".\n\n";
1000 999
1001 if (map->shopmin) 1000 if (map->shopmin)
1002 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade in items worth less than %s.", cost_string_from_value (map->shopmin, 0)); 1001 buf << "It won't trade in items worth less than " << cost_string_from_value (map->shopmin, 0) << ".\n\n";
1003 1002
1004 if (map->shopgreed) 1003 if (map->shopgreed)
1005 { 1004 {
1006 if (map->shopgreed > 2.0) 1005 if (map->shopgreed > 2.0)
1007 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge massively."); 1006 buf << "It tends to overcharge massively.\n\n";
1008 else if (map->shopgreed > 1.5) 1007 else if (map->shopgreed > 1.5)
1009 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge substantially."); 1008 buf << "It tends to overcharge substantially.\n\n";
1010 else if (map->shopgreed > 1.1) 1009 else if (map->shopgreed > 1.1)
1011 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge slightly."); 1010 buf << "It tends to overcharge slightly.\n\n";
1012 else if (map->shopgreed < 0.9) 1011 else if (map->shopgreed < 0.9)
1013 new_draw_info (NDI_UNIQUE, 0, op, "It tends to undercharge."); 1012 buf << "It tends to undercharge.\n\n";
1014 } 1013 }
1015 1014
1016 if (map->shoprace) 1015 if (map->shoprace)
1017 { 1016 {
1018 opinion = shopkeeper_approval (map, op); 1017 opinion = shopkeeper_approval (map, op);
1018
1019 if (opinion > 0.8) 1019 if (opinion > 0.8)
1020 new_draw_info (NDI_UNIQUE, 0, op, "You think the shopkeeper likes you."); 1020 buf << "You think the shopkeeper likes you.\n\n";
1021 else if (opinion > 0.5) 1021 else if (opinion > 0.5)
1022 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems unconcerned by you."); 1022 buf << "The shopkeeper seems unconcerned by you.\n\n";
1023 else 1023 else
1024 new_draw_info (NDI_UNIQUE, 0, op, "The shopkeeper seems to have taken a dislike to you."); 1024 buf << "The shopkeeper seems to have taken a dislike to you.\n\n";
1025 } 1025 }
1026 } 1026 }
1027 else 1027 else
1028 new_draw_info (NDI_UNIQUE, 0, op, "There is no shop nearby."); 1028 buf << "There is no shop nearby.\n\n";
1029
1030 op->contr->infobox (MSG_CHANNEL ("shopinfo"), buf);
1029 1031
1030 return 1; 1032 return 1;
1031} 1033}
1032 1034
1033struct shopinv 1035struct shopinv
1034{ 1036{
1035 char *item_sort; 1037 char *item_sort;
1036 char *item_real; 1038 char *item_real;
1039 sint64 value;
1037 uint16 type; 1040 uint16 type;
1038 uint32 nrof; 1041 uint32 nrof;
1039}; 1042};
1040 1043
1041/* There are a lot fo extra casts in here just to suppress warnings - it 1044/* There are a lot fo extra casts in here just to suppress warnings - it
1061} 1064}
1062 1065
1063static void 1066static void
1064add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated) 1067add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated)
1065{ 1068{
1066#if 0
1067 char buf[MAX_BUF];
1068#endif
1069 /* clear unpaid flag so that doesn't come up in query 1069 /* clear unpaid flag so that doesn't come up in query
1070 * string. We clear nrof so that we can better sort 1070 * string. We clear nrof so that we can better sort
1071 * the object names. 1071 * the object names.
1072 */ 1072 */
1073 1073
1074 CLEAR_FLAG (tmp, FLAG_UNPAID); 1074 tmp->clr_flag (FLAG_UNPAID);
1075 items[*numitems].nrof = tmp->nrof; 1075 items[*numitems].nrof = tmp->nrof;
1076 /* Non mergable items have nrof of 0, but count them as one 1076 /* Non mergable items have nrof of 0, but count them as one
1077 * so the display is properly. 1077 * so the display is properly.
1078 */ 1078 */
1079 if (tmp->nrof == 0) 1079 if (tmp->nrof == 0)
1080 items[*numitems].nrof++; 1080 items[*numitems].nrof++;
1081 items[*numitems].type = tmp->type; 1081 items[*numitems].type = tmp->type;
1082
1083 items[*numitems].value = tmp->value;
1082 1084
1083 switch (tmp->type) 1085 switch (tmp->type)
1084 { 1086 {
1085#if 0 1087#if 0
1086 case BOOTS: 1088 case BOOTS:
1098#endif 1100#endif
1099 1101
1100 default: 1102 default:
1101 items[*numitems].item_sort = strdup (query_base_name (tmp, 0)); 1103 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1102 items[*numitems].item_real = strdup (query_base_name (tmp, 1)); 1104 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1105 items[*numitems].value += tmp->value;
1103 (*numitems)++; 1106 (*numitems)++;
1104 break; 1107 break;
1105 } 1108 }
1106 SET_FLAG (tmp, FLAG_UNPAID); 1109
1110 tmp->set_flag (FLAG_UNPAID);
1107} 1111}
1108 1112
1109void 1113void
1110shop_listing (object *sign, object *op) 1114shop_listing (object *sign, object *op)
1111{ 1115{
1112 int i, j, x1, x2, y1, y2; 1116 int i, j, x1, x2, y1, y2;
1113 const char *shop_coords = sign->kv (shstr_shop_coords); 1117 const char *shop_coords = sign->kv [shstr_shop_coords];
1114 object *stack; 1118 object *stack;
1115 shopinv *items; 1119 shopinv *items;
1116 1120
1117 /* Should never happen, but just in case a monster does apply a sign */ 1121 /* Should never happen, but just in case a monster does apply a sign */
1118 if (!op->is_player ()) 1122 if (!op->is_player ())
1133 items = (shopinv *)malloc (sizeof (shopinv) * numallocated); 1137 items = (shopinv *)malloc (sizeof (shopinv) * numallocated);
1134 1138
1135 /* Find all the appropriate items */ 1139 /* Find all the appropriate items */
1136 for (i = x1; i <= x2; i++) 1140 for (i = x1; i <= x2; i++)
1137 for (j = y1; j < y2; j++) 1141 for (j = y1; j < y2; j++)
1138 if (is_in_shop (op->map, i, j)) 1142 if (op->map->is_in_shop (i, j))
1139 { 1143 {
1140 stack = GET_MAP_OB (op->map, i, j); 1144 stack = GET_MAP_OB (op->map, i, j);
1141 1145
1142 while (stack) 1146 while (stack)
1143 { 1147 {
1144 if (QUERY_FLAG (stack, FLAG_UNPAID)) 1148 if (stack->flag [FLAG_UNPAID])
1145 { 1149 {
1146 if (numitems == numallocated) 1150 if (numitems == numallocated)
1147 items = (shopinv *)realloc (items, sizeof (shopinv) * (numallocated *= 2)); 1151 items = (shopinv *)realloc (items, sizeof (shopinv) * (numallocated *= 2));
1148 1152
1149 add_shop_item (stack, items, &numitems, &numallocated); 1153 add_shop_item (stack, items, &numitems, &numallocated);
1162 { 1166 {
1163 /* Collapse items of the same name together */ 1167 /* Collapse items of the same name together */
1164 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real)) 1168 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real))
1165 items[i + 1].nrof += items[i].nrof; 1169 items[i + 1].nrof += items[i].nrof;
1166 else 1170 else
1167 buf.printf (" %4d %s\n", items[i].nrof ? items[i].nrof : 1, items[i].nrof == 1 ? items[i].item_sort : items[i].item_real); 1171 {
1172 buf.printf (
1173 " %4d %s\n for %s\n",
1174 items[i].nrof ? items[i].nrof : 1,
1175 items[i].nrof == 1 ? items[i].item_sort : items[i].item_real,
1176 cost_string_from_value (items[i].value, op->flag [FLAG_WIZ] ? 0 : 1));
1177 }
1168 1178
1169 free (items[i].item_sort); 1179 free (items[i].item_sort);
1170 free (items[i].item_real); 1180 free (items[i].item_real);
1171 } 1181 }
1172 1182
1173 op->contr->infobox (MSG_CHANNEL ("shopitems"), buf); 1183 op->contr->infobox (MSG_CHANNEL ("shopitems"), buf);
1174 1184
1175 free (items); 1185 free (items);
1176}
1177
1178/* elmex: this function checks whether the object is in a shop */
1179bool
1180is_in_shop (object *o)
1181{
1182 if (!o->is_on_map ())
1183 return false;
1184
1185 return is_in_shop (o->map, o->x, o->y);
1186} 1186}
1187 1187
1188/* elmex: this function checks whether we are in a shop or not 1188/* elmex: this function checks whether we are in a shop or not
1189 - change 2007-11-26: enhanced the O(n) case by stopping at the first 1189 - change 2007-11-26: enhanced the O(n) case by stopping at the first
1190 floor tile. this possibly will make map bugs where shopfloors are above 1190 floor tile. this possibly will make map bugs where shopfloors are above
1191 floors more obvious. 1191 floors more obvious.
1192*/ 1192*/
1193
1194bool 1193bool
1195is_in_shop (maptile *map, int x, int y) 1194maptile::is_in_shop (int x, int y) const
1196{ 1195{
1197 for (object *floor = GET_MAP_OB (map, x, y); floor; floor = floor->above) 1196 for (object *floor = at (x, y).bot; floor; floor = floor->above)
1198 if (QUERY_FLAG (floor, FLAG_IS_FLOOR)) 1197 if (floor->flag [FLAG_IS_FLOOR])
1199 return floor->type == SHOP_FLOOR; 1198 return floor->type == SHOP_FLOOR;
1200 1199
1201 return false; 1200 return false;
1202} 1201}
1203 1202

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines