ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.C
Revision: 1.40
Committed: Sun Jul 1 05:00:20 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.39: +10 -11 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

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