ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.C
Revision: 1.88
Committed: Sun May 1 13:18:24 2011 UTC (13 years ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.87: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 *
4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen
7 *
8 * 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 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * 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 * <http://www.gnu.org/licenses/>.
21 *
22 * The authors can be reached via e-mail to <support@deliantra.net>
23 */
24
25 #include <global.h>
26 #include <spells.h>
27 #include <skills.h>
28 #include <living.h>
29 #include <sproto.h>
30
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
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.
35 * setting this value above 1 or to a negative value would have interesting,
36 * (though not useful) effects.
37 */
38 #define SPECIALISATION_EFFECT .5
39
40 // price a shopkeeper will give someone that is not of their race
41 #define DISLIKE_RATIO 0.8
42
43 static void pay_from_container (object *pl, object *pouch, sint64 &to_pay);
44 static sint64 value_limit (sint64 val, int quantity, const object *who, int isshop);
45 static double shop_specialisation_ratio (const object *item, const maptile *map);
46 static double shop_greed (const maptile *map);
47
48 /* Added F_TRUE flag to define.h to mean that the price should not
49 * be adjusted by players charisma. With F_TRUE, it returns the amount
50 * that the item is worth, if it was sold, but unadjusted by charisma.
51 * This is needed for alchemy, to to determine what value of gold nuggets
52 * should be given (the gold nuggets, when sold, will have the adjustment
53 * by charisma done at that time). NULL could have been passed as the
54 * who parameter, but then the adjustment for expensive items (>10000)
55 * would not be done.
56 *
57 * 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 *
60 * 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 * specialise in what is being traded will give better prices than those that do not.
63 *
64 * 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 * 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 * thus remained 0.
69 *
70 * Mark Wedel (mwedel@pyramid.com)
71 */
72
73 static sint64 approx_range;
74
75 sint64
76 query_cost (const object *tmp, object *who, int flag)
77 {
78 double val;
79 int no_bargain;
80 int identified;
81 int not_cursed;
82 int approximate;
83 int shop;
84
85 approx_range = 0;
86
87 no_bargain = flag & F_NO_BARGAIN;
88 identified = flag & F_IDENTIFIED;
89 not_cursed = flag & F_NOT_CURSED;
90 approximate = flag & F_APPROX;
91 shop = flag & F_SHOP;
92 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP);
93
94 int number = tmp->number_of ();
95
96 if (tmp->type == MONEY)
97 return number * tmp->value;
98
99 if (tmp->type == GEM)
100 {
101 if (flag == F_TRUE)
102 return number * tmp->value;
103
104 if (flag == F_BUY)
105 return 1.03 * number * tmp->value;
106
107 if (flag == F_SELL)
108 return 0.97 * number * tmp->value;
109
110 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ());
111 return 0;
112 }
113
114 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
115 {
116 if (!not_cursed && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
117 return 0;
118 else
119 val = number * tmp->value;
120 }
121 /* This area deals with objects that are not identified, but can be */
122 else
123 {
124 if (flag == F_BUY)
125 {
126 LOG (llevError | logBacktrace, "Asking for buy-value of unidentified object: %s\n", tmp->debug_desc ());
127 val = tmp->arch->value * 50 * number;
128 }
129 else
130 { /* Trying to sell something, or get true value */
131 if (tmp->type == POTION)
132 val = number * 40; /* Don't want to give anything away */
133 else
134 {
135 /* Get 2/3'rd value for applied objects, 1/3'rd for totally
136 * unknown objects
137 */
138 if (tmp->flag [FLAG_BEEN_APPLIED])
139 val = number * tmp->arch->value * 2 / 3;
140 else
141 val = number * tmp->arch->value / 3;
142 }
143 }
144 }
145
146 /* If the item has been applied or identifed or does not need to be
147 * identified, AND the object is magical and the archetype is non
148 * magical, then change values accordingly. The tmp->arch==NULL is
149 * really just a check to prevent core dumps for when it checks
150 * tmp->arch->magic for any magic. The check for archetype
151 * magic is to not give extra money for archetypes that are by
152 * default magical. This is because the archetype value should have
153 * already figured in that value.
154 */
155 if ((tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified || tmp->flag [FLAG_BEEN_APPLIED])
156 && tmp->magic && (!tmp->arch || !tmp->arch->magic))
157 {
158 if (tmp->magic > 0)
159 val *= 3 * tmp->magic * tmp->magic * tmp->magic;
160 else
161 /* Note that tmp->magic is negative, so that this
162 * will actually be something like val /=2, /=3, etc.
163 */
164 val /= 1 - tmp->magic;
165 }
166
167 if (tmp->type == WAND)
168 {
169 /* Value of the wand is multiplied by the number of
170 * charges. the treasure code already sets up the value
171 * 50 charges is used as the baseline.
172 */
173 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
174 val *= tmp->stats.food;
175 /* if not identified, presume one charge */
176 val /= 50;
177 }
178
179 /* Limit amount of money you can get for really great items. */
180 if (flag == F_SELL)
181 val = value_limit (val, number, who, shop);
182
183 // use a nonlinear price adjustment. as my predecessor said, don't change
184 // the archetypes, its work required for balancing, and we don't care.
185 //val = pow (val, 1.05);
186
187 /* This modification is for bargaining skill.
188 * Now only players with max level in bargaining
189 * AND Cha = 30 will get optimal price.
190 * Thus charisma will never get useless.
191 * -b.e. edler@heydernet.de
192 */
193
194 if (who && who->is_player ())
195 {
196 int lev_bargain = 0;
197 int lev_identify = 0;
198
199 if (!no_bargain)
200 if (object *skill = find_skill_by_name (who, shstr_bargaining))
201 lev_bargain = skill->level;
202
203 if (const typedata *tmptype = get_typedata (tmp->type))
204 {
205 if (int idskill1 = tmptype->identifyskill)
206 {
207 int idskill2 = tmptype->identifyskill2;
208
209 if (find_skill_by_number (who, idskill1))
210 lev_identify = find_skill_by_number (who, idskill1)->level;
211
212 if (idskill2 && find_skill_by_number (who, idskill2))
213 lev_identify += find_skill_by_number (who, idskill2)->level;
214 }
215 }
216
217 /* ratio determines how much of the price modification
218 * will come from the basic stat charisma
219 * the rest will come from the level in bargaining skill
220 */
221 const double cha_ratio = 0.40;
222 double bargaining = max (0., 1. - powf (double (lev_bargain) / MAXLEVEL_TREASURE, 0.25));
223 double charisma = (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.);
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);
229
230 if (flag == F_BUY)
231 val += val * factor;
232 else if (flag == F_SELL)
233 val -= val * factor;
234
235 // now find a price range. the less good we can judge, the larger the range is
236 // then the range is adjusted randomly around the correct value
237 if (approximate)
238 approx_range = val / sqrt (lev_identify * 3 + 1);
239 }
240
241 /* I don't think this should really happen - if it does, it indicates and
242 * overflow of diff above. That should only happen if
243 * we are selling objects - in that case, the person just
244 * gets no money.
245 */
246 if ((sint64) val < 0)
247 val = 0;
248
249 /* Unidentified stuff won't sell for more than 10gp */
250 if (flag == F_SELL && !tmp->flag [FLAG_IDENTIFIED] && tmp->need_identify () && !identified)
251 min_it (val, 1000);
252
253 /* if we are in a shop, check how the type of shop should affect the price */
254 if (shop && who)
255 {
256 if (flag == F_SELL)
257 val *= shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map);
258 else if (flag == F_BUY)
259 {
260 /*
261 * when buying, if the item was sold by another player, it is ok to
262 * let the item be sold cheaper, according to the specialisation of
263 * the shop. If a player sold an item here, then his sale price was
264 * multiplied by the specialisation ratio, to do the same to the buy
265 * price will not generate extra money. However, the
266 * same is not true of generated items, these have to /divide/ by the
267 * specialisation, so that the price is never less than what they could
268 * be sold for (otherwise players could camp map resets to make money).
269 * In game terms, a non-specialist shop, might not recognise the true
270 * value of the items they sell (much like how people sometimes find
271 * antiques in a junk shop in real life).
272 */
273 if (tmp->flag [FLAG_PLAYER_SOLD])
274 val *= shop_specialisation_ratio (tmp, who->map);
275 else
276 val /= shop_specialisation_ratio (tmp, who->map);
277
278 val *= shop_greed (who->map) / shopkeeper_approval (who->map, who);
279 }
280
281 /* we will also have an extra 0-5% variation between shops of the same type
282 * for valuable items (below a value of 50 this effect wouldn't be very
283 * pointful, and could give fun with rounding.
284 */
285 //TODO: why use cosf at all, just % and scale linearly, gives more even distribution
286 if (val > 50)
287 val *= 1 + .05f * cosf ((tmp->uuid.seq & 0xffff) * M_PI * 2. / 0x10000);
288 }
289
290 return val;
291 }
292
293 /* Find the coin type that is worth more the 'c'. Starts at the
294 * cointype placement.
295 */
296
297 static archetype *
298 find_next_coin (sint64 c, int *cointype)
299 {
300 archetype *coin;
301
302 do
303 {
304 if (!coins [*cointype])
305 return 0;
306
307 coin = archetype::find (coins [*cointype]);
308
309 if (!coin)
310 return 0;
311
312 *cointype += 1;
313 }
314 while (coin->value > c);
315
316 return coin;
317 }
318
319 /* This returns a string of how much something is worth based on
320 * an integer being passed.
321 * cost is the cost we need to represent.
322 * While cost is 64 bit, the number of any coin is still really
323 * limited to 32 bit (size of nrof field). If it turns out players
324 * have so much money that they have more than 2 billion platinum
325 * coins, there are certainly issues - the easiest fix at that
326 * time is to add a higher denomination (mithril piece with
327 * 10,000 silver or something)
328 */
329 const char *
330 cost_string_from_value (sint64 cost, int approx)
331 {
332 archetype *coin, *next_coin;
333 int num, cointype = 0;
334
335 coin = find_next_coin (cost, &cointype);
336 if (!coin)
337 return "nothing";
338
339 num = cost / coin->value;
340 /* so long as nrof is 32 bit, this is true.
341 * If it takes more coins than a person can possibly carry, this
342 * is basically true.
343 */
344 if (cost / coin->value > UINT32_MAX)
345 return "an unimaginable sum of money";
346
347 cost -= num * (sint64)coin->value;
348
349 char *buf = format ("%d %s", num, num > 1 ? &coin->object::name_pl : &coin->object::name);
350
351 next_coin = find_next_coin (cost, &cointype);
352 if (!next_coin || approx)
353 return buf;
354
355 coin = next_coin;
356 num = cost / coin->value;
357 cost -= num * (sint64)coin->value;
358
359 return format ("%s and %d %s", buf, num, num > 1 ? &coin->object::name_pl : &coin->object::name);
360 }
361
362 const char *
363 query_cost_string (const object *tmp, object *who, int flag)
364 {
365 sint64 real_value = query_cost (tmp, who, flag);
366 int idskill1 = 0;
367 int idskill2 = 0;
368 const typedata *tmptype;
369
370 tmptype = get_typedata (tmp->type);
371 if (tmptype)
372 {
373 idskill1 = tmptype->identifyskill;
374 idskill2 = tmptype->identifyskill2;
375 }
376
377 /* we show an approximate price if
378 * 1) we are approximating
379 * 2) there either is no id skill(s) for the item, or we don't have them
380 * 3) we don't have bargaining skill either
381 */
382 if (flag & F_APPROX)
383 {
384 if (!idskill1 || !find_skill_by_number (who, idskill1))
385 {
386 if (!idskill2 || !find_skill_by_number (who, idskill2))
387 {
388 if (!find_skill_by_name (who, shstr_bargaining))
389 {
390 int num, cointype = 0;
391 archetype *coin = find_next_coin (real_value, &cointype);
392
393 if (!coin)
394 return "nothing";
395
396 num = real_value / coin->value;
397
398 if (num == 1)
399 return format ("about one %s", &coin->object::name);
400 else if (num < 5)
401 return format ("a few %s", &coin->object::name_pl);
402 else if (num < 10)
403 return format ("several %s", &coin->object::name_pl);
404 else if (num < 25)
405 return format ("a moderate amount of %s", &coin->object::name_pl);
406 else if (num < 100)
407 return format ("lots of %s", &coin->object::name_pl);
408 else if (num < 1000)
409 return format ("a great many %s", &coin->object::name_pl);
410 else
411 return format ("a vast quantity of %s", &coin->object::name_pl);
412 }
413 }
414 }
415
416 if (approx_range)
417 {
418 int hash = tmp->random_seed () & 1023;
419 sint64 lo = real_value - (approx_range * hash >> 10);
420
421 return format ("between %s and %s",
422 cost_string_from_value (lo, 1),
423 cost_string_from_value (lo + approx_range, 1));
424 }
425 }
426
427 return cost_string_from_value (real_value, 0);
428 }
429
430 /* This function finds out how much money the player is carrying,
431 * including what is in containers.
432 */
433 sint64
434 query_money (const object *op)
435 {
436 object *tmp;
437 sint64 total = 0;
438
439 if (op->type != PLAYER && op->type != CONTAINER)
440 {
441 LOG (llevError, "Query money called with non player/container\n");
442 return 0;
443 }
444
445 for (tmp = op->inv; tmp; tmp = tmp->below)
446 if (tmp->type == MONEY)
447 total += tmp->nrof * (sint64)tmp->value;
448 else if (tmp->type == CONTAINER && tmp->flag [FLAG_APPLIED] && (!tmp->race || tmp->race.contains (shstr_gold)))
449 total += query_money (tmp);
450
451 return total;
452 }
453
454 /* TCHIZE: This function takes the amount of money from the
455 * the player inventory and from it's various pouches using the
456 * pay_from_container function.
457 * returns 0 if not possible. 1 if success
458 */
459 int
460 pay_for_amount (sint64 to_pay, object *pl)
461 {
462 object *pouch;
463
464 if (to_pay == 0)
465 return 1;
466
467 if (to_pay > query_money (pl))
468 return 0;
469
470 pay_from_container (pl, pl, to_pay);
471
472 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
473 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
474 pay_from_container (pl, pouch, to_pay);
475
476 pl->update_stats ();
477 return 1;
478 }
479
480 /* DAMN: This is now a wrapper for pay_from_container, which is
481 * called for the player, then for each active container that can hold
482 * money until op is paid for. Change will be left wherever the last
483 * of the price was paid from.
484 */
485 int
486 pay_for_item (object *op, object *pl)
487 {
488 sint64 to_pay = query_cost (op, pl, F_BUY | F_SHOP);
489 object *pouch;
490 sint64 saved_money;
491
492 if (to_pay == 0)
493 return 1;
494
495 if (to_pay > query_money (pl))
496 return 0;
497
498 /* We compare the paid price with the one for a player
499 * without bargaining skill.
500 * This determins the amount of exp (if any) gained for bargaining.
501 */
502 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay;
503
504 if (saved_money > 0)
505 change_exp (pl, saved_money, shstr_bargaining, SK_EXP_NONE);
506
507 pay_from_container (pl, pl, to_pay);
508
509 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
510 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
511 pay_from_container (pl, pouch, to_pay);
512
513 pl->update_stats ();
514
515 return 1;
516 }
517
518 /* This pays for the item, and takes the proper amount of money off
519 * the player.
520 * CF 0.91.4 - this function is mostly redone in order to fix a bug
521 * with weight not be subtracted properly. We now remove and
522 * insert the coin objects - this should update the weight
523 * appropriately
524 *
525 * DAMN: This function is used for the player, then for any active
526 * containers that can hold money.
527 *
528 * pouch is the container (pouch or player) to remove the coins from.
529 * to_pay is the required amount.
530 * returns the amount still missing after using "pouch".
531 */
532 static void
533 pay_from_container (object *pl, object *pouch, sint64 &to_pay)
534 {
535 int count, i;
536 object *tmp, *next;
537 archetype *at;
538
539 if (pouch->type != PLAYER && pouch->type != CONTAINER)
540 return;
541
542 object *coin_objs[NUM_COINS] = { 0 };
543
544 /* This hunk should remove all the money objects from the player/container */
545 for (tmp = pouch->inv; tmp; tmp = next)
546 {
547 next = tmp->below;
548
549 if (tmp->type == MONEY)
550 {
551 for (i = 0; i < NUM_COINS; i++)
552 {
553 if (tmp->value == tmp->arch->value && !strcmp (coins[NUM_COINS - 1 - i], tmp->arch->archname))
554 {
555 // This should not happen, but if it does, just merge the two.
556 if (coin_objs [i])
557 {
558 LOG (llevError, "%s has two money entries of (%s)\n", &pouch->name, coins[NUM_COINS - 1 - i]);
559 coin_objs[i]->nrof += tmp->nrof;
560 tmp->destroy ();
561 }
562 else
563 {
564 tmp->remove ();
565 coin_objs[i] = tmp;
566 }
567
568 break;
569 }
570 }
571
572 if (i == NUM_COINS)
573 LOG (llevError, "in pay_for_item: Did not find string match for %s\n", &tmp->arch->archname);
574 }
575 }
576
577 /* Fill in any gaps in the coin_objs array - needed to make change. */
578 /* Note that the coin_objs array goes from least value to greatest value */
579 for (i = 0; i < NUM_COINS; i++)
580 if (!coin_objs[i])
581 {
582 at = archetype::find (coins[NUM_COINS - 1 - i]);
583
584 if (at == NULL)
585 LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]);
586
587 coin_objs[i] = at->instance ();
588 coin_objs[i]->nrof = 0;
589 }
590
591 for (i = 0; i < NUM_COINS; i++)
592 {
593 object &coin = *coin_objs[i];
594 sint64 num_coins = min ((to_pay + coin.value - 1) / coin.value, (sint64) coin.nrof);
595 to_pay -= num_coins * coin.value;
596
597 coin.nrof -= num_coins;
598 /* Now start making change. Start at the coin value
599 * below the one we just did, and work down to
600 * the lowest value.
601 */
602 count = i - 1;
603
604 while (to_pay < 0 && count >= 0)
605 {
606 num_coins = (-to_pay) / coin_objs[count]->value;
607 coin_objs[count]->nrof += num_coins;
608 to_pay += num_coins * coin_objs[count]->value;
609 count--;
610 }
611 }
612
613 for (i = 0; i < NUM_COINS; i++)
614 if (coin_objs[i]->nrof)
615 insert_ob_in_ob (coin_objs [i], pouch);
616 else
617 coin_objs[i]->destroy ();
618 }
619
620 /* Checks all unpaid items in op's inventory, adds up all the money they
621 * have, and checks that they can actually afford what they want to buy.
622 * Returns 1 if they can, and 0 if they can't. also prints an appropriate message
623 * to the player
624 */
625 int
626 can_pay (object *pl)
627 {
628 int unpaid_count = 0;
629 sint64 unpaid_price = 0;
630 sint64 player_wealth = query_money (pl);
631
632 if (!pl || pl->type != PLAYER)
633 {
634 LOG (llevError, "can_pay(): called against something that isn't a player\n");
635 return 0;
636 }
637
638 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
639 if (item->flag [FLAG_UNPAID])
640 {
641 unpaid_count++;
642 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP);
643 }
644
645 if (unpaid_price > player_wealth)
646 {
647 dynbuf_text &buf = msg_dynbuf; buf.clear ();
648
649 buf << "You have " << unpaid_count
650 << " unpaid item(s) that would cost you " << cost_string_from_value (unpaid_price, 0)
651 << ". You need another " << cost_string_from_value (unpaid_price - player_wealth, 0)
652 << " to be able to afford that. "
653 "H<You cannot leave a shop without paying - drop unpaid items first to be able to leave.>";
654
655 pl->failmsg (buf);
656
657 return 0;
658 }
659 else
660 return 1;
661 }
662
663 /* Better get_payment, descends containers looking for
664 * unpaid items, and pays for them.
665 * returns 0 if the player still has unpaid items.
666 * returns 1 if the player has paid for everything.
667 * pl is the player buying the stuff.
668 */
669 int
670 get_payment (object *pl)
671 {
672 for (;;)
673 {
674 next_item:
675
676 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op)
677 {
678 if (op->flag [FLAG_UNPAID])
679 {
680 const char *buf = query_cost_string (op, pl, F_BUY | F_SHOP);
681
682 if (!pay_for_item (op, pl))
683 {
684 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
685
686 op->clr_flag (FLAG_UNPAID);
687 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op));
688 op->set_flag (FLAG_UNPAID);
689 return 0;
690 }
691 else
692 {
693 op->clr_flag (FLAG_UNPAID);
694 op->clr_flag (FLAG_PLAYER_SOLD);
695 new_draw_info_format (NDI_UNIQUE, 0, pl, "You paid %s for %s.", buf, query_name (op));
696
697 if (!merge_ob (op, op->env->inv))
698 esrv_update_item (UPD_FLAGS, pl, op);
699
700 goto next_item;
701 }
702 }
703 }
704
705 return 1;
706 }
707 }
708
709 /* written by elmex:
710 * moved this code from sell_item () here to have a function
711 * that pays the player an amount. Mainly put the code here to
712 * be able to call it from a plugin.
713 *
714 * If the player can't carry all the money that is paid, it gets inserted
715 * in his inventory anyway. This is the best alternative to not pay any money
716 * or put it on the ground under the player. This way the player can still
717 * go somewhere and unload the money at a safe place.
718 *
719 */
720 void
721 pay_player (object *pl, sint64 amount)
722 {
723 int count = 0;
724 archetype *at = 0;
725 object *pouch = 0, *tmp = 0;
726
727 for (count = 0; coins[count]; count++)
728 {
729 at = archetype::find (coins[count]);
730
731 if (at == NULL)
732 LOG (llevError, "Could not find %s archetype\n", coins[count]);
733 else if ((amount / at->value) > 0)
734 {
735 for (pouch = pl->inv; pouch; pouch = pouch->below)
736 {
737 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && pouch->race.contains (shstr_gold))
738 {
739 int w = at->weight * (100 - pouch->stats.Str) / 100;
740 int n = amount / at->value;
741
742 if (w == 0)
743 w = 1; /* Prevent divide by zero */
744
745 if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit))
746 {
747 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n)
748 n = (pouch->weight_limit - pouch->carrying) / w;
749
750 object *tmp = at->instance ();
751 tmp->nrof = n;
752 amount -= tmp->nrof * tmp->value;
753 pouch->insert (tmp);
754 }
755 }
756 }
757
758 if (amount / at->value > 0)
759 {
760 object *tmp = at->instance ();
761 tmp->nrof = amount / tmp->value;
762 amount -= tmp->nrof * tmp->value;
763 pl->insert (tmp);
764 }
765 }
766 }
767
768 if (amount != 0)
769 LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount);
770 }
771
772 /* elmex: this is for the bank plugin :( */
773 sint64
774 pay_player_arch (object *pl, const char *arch, sint64 amount)
775 {
776 if (amount)
777 {
778 object *ob = archetype::get (arch);
779
780 if (!ob)
781 return 0;
782
783 ob->nrof = amount;
784 pl->insert (ob);
785 }
786
787 return 1;
788 }
789
790 /* Modified function to give out platinum coins. This function uses
791 * the coins[] array to know what coins are available, just like
792 * buy item.
793 *
794 * Modified to fill available race: gold containers before dumping
795 * remaining coins in character's inventory.
796 */
797 bool
798 sell_item (object *op, object *pl)
799 {
800 sint64 amount = query_cost (op, pl, F_SELL | F_SHOP), extra_gain;
801
802 if (pl == NULL || pl->type != PLAYER)
803 {
804 LOG (llevDebug, "Object other than player tried to sell something.\n");
805 return false;
806 }
807
808 op->custom_name = 0;
809
810 if (!amount)
811 {
812 new_draw_info_format (NDI_UNIQUE, 0, pl, "We're not interested in %s.",
813 query_name (op));
814 // elmex: change: the player now gets the item back if the shop is not
815 // interested in it.
816 return false;
817 }
818
819 /* We compare the price with the one for a player
820 * without bargaining skill.
821 * This determins the amount of exp (if any) gained for bargaining.
822 * exp/10 -> 1 for each gold coin
823 */
824 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP);
825
826 if (extra_gain > 0)
827 change_exp (pl, extra_gain / 10, shstr_bargaining, SK_EXP_NONE);
828
829 pay_player (pl, amount);
830
831 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.",
832 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op));
833 pl->play_sound (sound_find ("shop_sell"));
834
835 op->set_flag (FLAG_UNPAID);
836 identify (op);
837
838 return true;
839 }
840
841 /* returns a double that is the ratio of the price that a shop will offer for
842 * item based on the shops specialisation. Does not take account of greed,
843 * returned value is between SPECIALISATION_EFFECT and 1.
844 */
845 static double
846 shop_specialisation_ratio (const object *item, const maptile *map)
847 {
848 shopitems *items = map->shopitems;
849 int likedness = 0;
850 int i;
851
852 if (item == NULL)
853 {
854 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", &map->path);
855 return 0;
856 }
857
858 if (!item->type)
859 {
860 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
861 /*
862 * I'm not really sure what the /right/ thing to do here is, these types of
863 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
864 */
865 return SPECIALISATION_EFFECT;
866 }
867
868 if (map->shopitems)
869 for (i = 0; i < items[0].index; i++)
870 if (items[i].typenum == item->type || (!items[i].typenum && !likedness))
871 likedness = items[i].strength;
872
873 if (likedness > 100)
874 { /* someone has been rather silly with the map headers. */
875 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, &map->path);
876 likedness = 100;
877 }
878
879 if (likedness < -100)
880 {
881 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, &map->path);
882 likedness = -100;
883 }
884
885 return lerp (double (likedness), -100., 100., SPECIALISATION_EFFECT, 1.);
886 }
887
888 /*returns the greed of the shop on map, or 1 if it isn't specified. */
889 static double
890 shop_greed (const maptile *map)
891 {
892 return map->shopgreed
893 ? map->shopgreed
894 : 1.;
895 }
896
897 /* Returns a double based on how much the shopkeeper approves of the player.
898 * this is based on the race of the shopkeeper and that of the player.
899 */
900 double
901 shopkeeper_approval (const maptile *map, const object *player)
902 {
903 return map->shoprace && player->race != map->shoprace
904 ? DISLIKE_RATIO
905 : 1.;
906 }
907
908 /* limit the value of items based on the wealth of the shop. If the item is close
909 * to the maximum value a shop will offer, we start to reduce it, if the item is
910 * below the minimum value the shop is prepared to trade in, then we don't
911 * want it and offer nothing. If it isn't a shop, check whether we should do generic
912 * value reduction.
913 *
914 */
915 static sint64
916 value_limit (sint64 val, int quantity, const object *who, int isshop)
917 {
918 sint64 newval, unit_price, tmpshopmax;
919 maptile *map;
920
921 unit_price = val / quantity;
922
923 if (!isshop || !who)
924 {
925 if (unit_price > 250000)
926 newval = (sint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.);
927 else
928 newval = unit_price;
929 }
930 else
931 {
932 if (!who->map)
933 {
934 LOG (llevError, "value_limit: asked shop price for ob %s on NULL map\n", &who->name);
935 return val;
936 }
937
938 map = who->map;
939
940 tmpshopmax = map->shopmax ? map->shopmax : 100000; // 20 royalties default
941
942 if (map->shopmin && unit_price < map->shopmin)
943 return 0;
944 else if (unit_price > tmpshopmax / 2)
945 newval = min ((tmpshopmax / 2) + isqrt (unit_price - tmpshopmax / 2), tmpshopmax);
946 else
947 newval = unit_price;
948 }
949
950 newval *= quantity;
951
952 return newval;
953 }
954
955 /* gives a desciption of the shop on their current map to the player op. */
956 int
957 describe_shop (const object *op)
958 {
959 dynbuf_text buf;
960 maptile *map = op->map;
961
962 /*shopitems *items=map->shopitems; */
963 int pos = 0, i;
964 double opinion = 0;
965
966 if (op->type != PLAYER)
967 return 0;
968
969 /*check if there is a shop specified for this map */
970 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax)
971 {
972 buf << "From looking at the nearby shop you determine that it trades in ";
973 int lastcomma = 0, prevcomma = 0;
974
975 if (map->shopitems)
976 for (i = 0; i < map->shopitems[0].index; i++)
977 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
978 {
979 buf << map->shopitems[i].name_pl;
980 prevcomma = lastcomma;
981 lastcomma = buf.size (); // remember offset
982 buf << ", ";
983 }
984
985 if (lastcomma)
986 {
987 buf.splice (lastcomma, 2);
988
989 if (prevcomma)
990 buf.splice (prevcomma, 2, " and ");
991 }
992 else
993 buf << "a little of everything.";
994
995 buf << ".\n\n";
996
997 if (map->shopmax)
998 buf << "It won't trade for items above " << cost_string_from_value (map->shopmax, 0) << ".\n\n";
999
1000 if (map->shopmin)
1001 buf << "It won't trade in items worth less than " << cost_string_from_value (map->shopmin, 0) << ".\n\n";
1002
1003 if (map->shopgreed)
1004 {
1005 if (map->shopgreed > 2.0)
1006 buf << "It tends to overcharge massively.\n\n";
1007 else if (map->shopgreed > 1.5)
1008 buf << "It tends to overcharge substantially.\n\n";
1009 else if (map->shopgreed > 1.1)
1010 buf << "It tends to overcharge slightly.\n\n";
1011 else if (map->shopgreed < 0.9)
1012 buf << "It tends to undercharge.\n\n";
1013 }
1014
1015 if (map->shoprace)
1016 {
1017 opinion = shopkeeper_approval (map, op);
1018
1019 if (opinion > 0.8)
1020 buf << "You think the shopkeeper likes you.\n\n";
1021 else if (opinion > 0.5)
1022 buf << "The shopkeeper seems unconcerned by you.\n\n";
1023 else
1024 buf << "The shopkeeper seems to have taken a dislike to you.\n\n";
1025 }
1026 }
1027 else
1028 buf << "There is no shop nearby.\n\n";
1029
1030 op->contr->infobox (MSG_CHANNEL ("shopinfo"), buf);
1031
1032 return 1;
1033 }
1034
1035 struct shopinv
1036 {
1037 char *item_sort;
1038 char *item_real;
1039 sint64 value;
1040 uint16 type;
1041 uint32 nrof;
1042 };
1043
1044 /* There are a lot fo extra casts in here just to suppress warnings - it
1045 * makes it look uglier than it really it.
1046 * The format of the strings we get is type:name. So we first want to
1047 * sort by type (numerical) - if the same type, then sort by name.
1048 */
1049 static int
1050 shop_sort (const void *a1, const void *a2)
1051 {
1052 shopinv *s1 = (shopinv *) a1, *s2 = (shopinv *) a2;
1053
1054 if (s1->type < s2->type)
1055 return -1;
1056
1057 if (s1->type > s2->type)
1058 return 1;
1059
1060 /* the type is the same (what atoi gets), so do a strcasecmp to sort
1061 * via alphabetical order
1062 */
1063 return strcasecmp (s1->item_sort, s2->item_sort);
1064 }
1065
1066 static void
1067 add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated)
1068 {
1069 /* clear unpaid flag so that doesn't come up in query
1070 * string. We clear nrof so that we can better sort
1071 * the object names.
1072 */
1073
1074 tmp->clr_flag (FLAG_UNPAID);
1075 items[*numitems].nrof = tmp->nrof;
1076 /* Non mergable items have nrof of 0, but count them as one
1077 * so the display is properly.
1078 */
1079 if (tmp->nrof == 0)
1080 items[*numitems].nrof++;
1081 items[*numitems].type = tmp->type;
1082
1083 items[*numitems].value = tmp->value;
1084
1085 switch (tmp->type)
1086 {
1087 #if 0
1088 case BOOTS:
1089 case GLOVES:
1090 case RING:
1091 case AMULET:
1092 case BRACERS:
1093 case GIRDLE:
1094 sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL));
1095 items[*numitems].item_sort = strdup (buf);
1096 sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL));
1097 items[*numitems].item_real = strdup (buf);
1098 (*numitems)++;
1099 break;
1100 #endif
1101
1102 default:
1103 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1104 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1105 items[*numitems].value += tmp->value;
1106 (*numitems)++;
1107 break;
1108 }
1109
1110 tmp->set_flag (FLAG_UNPAID);
1111 }
1112
1113 void
1114 shop_listing (object *sign, object *op)
1115 {
1116 int i, j, x1, x2, y1, y2;
1117 const char *shop_coords = sign->kv [shstr_shop_coords];
1118 object *stack;
1119 shopinv *items;
1120
1121 /* Should never happen, but just in case a monster does apply a sign */
1122 if (!op->is_player ())
1123 return;
1124
1125 dynbuf_text &buf = msg_dynbuf; buf.clear ();
1126
1127 if (!(shop_coords && sscanf (shop_coords, "%d,%d,%d,%d", &x1, &y1, &x2, &y2)))
1128 {
1129 x1 = 0;
1130 y1 = 0;
1131 x2 = op->map->width - 1;
1132 y2 = op->map->height - 1;
1133 }
1134
1135 int numallocated = 40;
1136 int numitems = 0;
1137 items = (shopinv *)malloc (sizeof (shopinv) * numallocated);
1138
1139 /* Find all the appropriate items */
1140 for (i = x1; i <= x2; i++)
1141 for (j = y1; j < y2; j++)
1142 if (op->map->is_in_shop (i, j))
1143 {
1144 stack = GET_MAP_OB (op->map, i, j);
1145
1146 while (stack)
1147 {
1148 if (stack->flag [FLAG_UNPAID])
1149 {
1150 if (numitems == numallocated)
1151 items = (shopinv *)realloc (items, sizeof (shopinv) * (numallocated *= 2));
1152
1153 add_shop_item (stack, items, &numitems, &numallocated);
1154 }
1155
1156 stack = stack->above;
1157 }
1158 }
1159
1160 buf << (numitems ? "T<This shop contains:>\n\n"
1161 : "T<This shop is currently empty.>");
1162
1163 qsort (items, numitems, sizeof (shopinv), (int (*)(const void *, const void *)) shop_sort);
1164
1165 for (i = 0; i < numitems; i++)
1166 {
1167 /* Collapse items of the same name together */
1168 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real))
1169 items[i + 1].nrof += items[i].nrof;
1170 else
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 }
1178
1179 free (items[i].item_sort);
1180 free (items[i].item_real);
1181 }
1182
1183 op->contr->infobox (MSG_CHANNEL ("shopitems"), buf);
1184
1185 free (items);
1186 }
1187
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
1190 floor tile. this possibly will make map bugs where shopfloors are above
1191 floors more obvious.
1192 */
1193 bool
1194 maptile::is_in_shop (int x, int y) const
1195 {
1196 for (object *floor = at (x, y).bot; floor; floor = floor->above)
1197 if (floor->flag [FLAG_IS_FLOOR])
1198 return floor->type == SHOP_FLOOR;
1199
1200 return false;
1201 }
1202