Crossfire Server, Trunk  R21041
shop.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
21 #include "global.h"
22 
23 #include <assert.h>
24 #include <math.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "shop.h"
29 #include "sproto.h"
30 
39 #define SPECIALISATION_EFFECT 0.5
40 
42 #define DISAPPROVAL_RATIO 0.2
43 
45 #define NEUTRAL_RATIO 0.8
46 
47 static uint64_t pay_from_container(object *pl, object *pouch, uint64_t to_pay);
48 static uint64_t value_limit(uint64_t val, int quantity, const object *who, int isshop);
49 static double shop_specialisation_ratio(const object *item, const mapstruct *map);
50 static double shop_greed(const mapstruct *map);
51 
52 #define NUM_COINS 5
54 #define LARGEST_COIN_GIVEN 2
57 static const char *const coins[] = {
58  "ambercoin",
59  "jadecoin",
60  "platinacoin",
61  "goldcoin",
62  "silvercoin",
63  NULL
64 };
65 
70 uint64_t price_base(const object *tmp) {
71  // When there are zero objects, there is really one.
72  const int number = (tmp->nrof == 0) ? 1 : tmp->nrof;
73  const bool identified =
75  uint64_t val = (uint64_t)tmp->value * number;
76 
77  // Objects with price adjustments skip the rest of the calculations.
78  const char *key = object_get_value(tmp, "price_adjustment");
79  if (key != NULL) {
80  float ratio = atof(key);
81  return val * ratio;
82  }
83 
84  // Money and gems have fixed prices at shops.
85  if (tmp->type == MONEY || tmp->type == GEM) {
86  return val;
87  }
88 
89  // If unidentified, price item based on its archetype.
90  if (!identified && tmp->arch) {
91  val = tmp->arch->clone.value * number;
92  }
93 
99  if (QUERY_FLAG(tmp, FLAG_BLESSED)){
100  val *= 1.15;
101  } else if (QUERY_FLAG(tmp, FLAG_CURSED)) {
102  val *= 0.8;
103  } else if (QUERY_FLAG(tmp, FLAG_DAMNED)) {
104  val *= 0.6;
105  }
106 
107  // If an item is identified to have an enchantment above its archetype
108  // enchantment, increase price exponentially.
109  if (tmp->arch != NULL && identified) {
110  int diff = tmp->magic - tmp->arch->clone.magic;
111  val *= pow(1.15, diff);
112  }
113 
114  // FIXME: Is the 'baseline' 50 charges per wand?
115  if (tmp->type == WAND) {
116  val *= tmp->stats.food / 50.0;
117  }
118 
119  /* we need to multiply these by 4.0 to keep buy costs roughly the same
120  * (otherwise, you could buy a potion of charisma for around 400 pp.
121  * Arguable, the costs in the archetypes should be updated to better
122  * reflect values (potion charisma list for 1250 gold)
123  */
124  val *= 4; // FIXME
125 
126  return val;
127 }
128 
129 uint64_t price_approx(const object *tmp, object *who) {
130  uint64_t val = price_base(tmp);
131 
132  /* If we are approximating, then the value returned should
133  * be allowed to be wrong however merely using a random number
134  * each time will not be sufficient, as then multiple examinations
135  * would give different answers, so we'll use the count instead.
136  * By taking the sine of the count, a value between -1 and 1 is
137  * generated, we then divide by the square root of the bargaining
138  * skill and the appropriate identification skills, so that higher
139  * level players get better estimates. (We need a +1 there to
140  * prevent dividing by zero.)
141  */
142  const typedata *tmptype = get_typedata(tmp->type);
143  int lev_identify = 0;
144 
145  if (tmptype) {
146  int idskill1 = tmptype->identifyskill;
147  if (idskill1) {
148  int idskill2 = tmptype->identifyskill2;
149  if (find_skill_by_number(who, idskill1)) {
150  lev_identify = find_skill_by_number(who, idskill1)->level;
151  }
152  if (idskill2 && find_skill_by_number(who, idskill2)) {
153  lev_identify += find_skill_by_number(who, idskill2)->level;
154  }
155  }
156  } else {
157  LOG(llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->name);
158  }
159  val += val * (sin(tmp->count) / sqrt(lev_identify * 3 + 1.0));
160 
161  return val;
162 }
163 
170 static float shop_buy_multiplier(int charisma) {
171  float multiplier = 1 / (0.38 * pow(1.06, charisma));
172 
173  if (multiplier > 2) {
174  return 2;
175  } else if (multiplier < 0.5) {
176  return 0.5;
177  } else {
178  return multiplier;
179  }
180 }
181 
189 static float shop_bargain_multiplier(int lev_bargain) {
190  return 1 - 0.5 * lev_bargain / settings.max_level;
191 }
192 
193 uint64_t shop_price_buy(const object *tmp, object *who) {
194  assert(who != NULL && who->type == PLAYER);
195  uint64_t val = price_base(tmp);
196 
197  const char *key = object_get_value(tmp, "price_adjustment_buy");
198  if (key != NULL) {
199  float ratio = atof(key);
200  return val * ratio;
201  }
202 
203  if (tmp->type == GEM) {
204  return 1.03 * val;
205  }
206 
207  // Further reduce the sell price of cursed and damned items.
208  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
209  val *= 0.8;
210  }
211 
212  int bargain_level = 0;
214  bargain_level = find_skill_by_number(who, SK_BARGAINING)->level;
215  }
216 
217  float multiplier = shop_bargain_multiplier(bargain_level);
218  multiplier *= shop_buy_multiplier(who->stats.Cha);
219 
220  // Limit buy price multiplier to 0.5, no matter what.
221  val *= multiplier > 0.5 ? multiplier : 0.5;
222 
223  /*
224  * When buying, if the item was sold by another player, it is
225  * ok to let the item be sold cheaper, according to the
226  * specialisation of the shop. If a player sold an item here,
227  * then his sale price was multiplied by the specialisation
228  * ratio, to do the same to the buy price will not generate
229  * extra money. However, the same is not true of generated
230  * items, these have to /divide/ by the specialisation, so
231  * that the price is never less than what they could
232  * be sold for (otherwise players could camp map resets to
233  * make money).
234  * In game terms, a non-specialist shop might not recognise
235  * the true value of the items it sells (much like how people
236  * sometimes find antiques in a junk shop in real life).
237  */
238  if (QUERY_FLAG(tmp, FLAG_PLAYER_SOLD)) {
239  val = (int64_t)val*shop_greed(who->map)
240  *shop_specialisation_ratio(tmp, who->map)
241  /shop_approval(who->map, who);
242  } else {
243  val = (int64_t)val*shop_greed(who->map)
244  /(shop_specialisation_ratio(tmp, who->map)
245  *shop_approval(who->map, who));
246  }
247 
248  return val;
249 }
250 
251 uint64_t shop_price_sell(const object *tmp, object *who) {
252  assert(who != NULL && who->type == PLAYER);
253  uint64_t val = price_base(tmp);
254  bool identified = QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp);
255 
256  const char *key = object_get_value(tmp, "price_adjustment_sell");
257  if (key != NULL) {
258  float ratio = atof(key);
259  return val * ratio;
260  }
261 
262  if (tmp->type == GEM) {
263  return 0.97 * val;
264  }
265 
266  // Shops value unidentified items less.
267  if (!identified) {
268  if (tmp->arch != NULL) {
269  // Unidentified standard objects are only worth a little less.
270  if (QUERY_FLAG(tmp, FLAG_BEEN_APPLIED)) {
271  val *= 0.85;
272  } else {
273  val *= 0.70;
274  }
275  } else {
276  // No archetype, so probably an artifact.
277  val /= 2;
278  }
279  }
280 
281  // Selling to shops yields roughly 50% of the base price.
282  val /= 2;
283 
284  /* Limit amount of money you can get for really great items. */
285  int number = (tmp->nrof == 0) ? 1 : tmp->nrof;
286  val = value_limit(val, number, who, 1);
287 
288  val = (int64_t)val*shop_specialisation_ratio(tmp, who->map)*
289  shop_approval(who->map, who)/shop_greed(who->map);
290  return val;
291 }
292 
304 static archetype *find_next_coin(uint64_t c, int *cointype) {
305  archetype *coin;
306 
307  do {
308  if (coins[*cointype] == NULL)
309  return NULL;
310  coin = find_archetype(coins[*cointype]);
311  if (coin == NULL)
312  return NULL;
313  *cointype += 1;
314  } while (coin->clone.value > (int64_t) c);
315 
316  return coin;
317 }
318 
338 char* cost_string_from_value(uint64_t cost, int largest_coin) {
339  archetype *coin, *next_coin;
340  uint32_t num;
341  int cointype = largest_coin;
342 
343  if (cointype < 0)
344  cointype = 0;
345  else if (cointype >= NUM_COINS)
346  cointype = NUM_COINS - 1;
347 
349  coin = find_next_coin(cost, &cointype);
350  if (coin == NULL) {
351  stringbuffer_append_string(buf, "nothing");
352  goto done;
353  }
354 
355  num = cost/coin->clone.value;
356  /* so long as nrof is 32 bit, this is true.
357  * If it takes more coins than a person can possibly carry, this
358  * is basically true.
359  */
360  if ((cost/coin->clone.value) > UINT32_MAX) {
361  stringbuffer_append_string(buf, "an unimaginable sum of money.");
362  goto done;
363  }
364 
365  cost -= (uint64_t)num*(uint64_t)coin->clone.value;
366  if (num == 1)
367  stringbuffer_append_printf(buf, "1 %s", coin->clone.name);
368  else
369  stringbuffer_append_printf(buf, "%u %ss", num, coin->clone.name);
370 
371  next_coin = find_next_coin(cost, &cointype);
372  if (next_coin == NULL)
373  goto done;
374 
375  do {
376  coin = next_coin;
377  num = cost/coin->clone.value;
378  cost -= (uint64_t)num*(uint64_t)coin->clone.value;
379 
380  if (cost == 0)
381  next_coin = NULL;
382  else
383  next_coin = find_next_coin(cost, &cointype);
384 
385  if (next_coin) {
386  /* There will be at least one more string to add to the list,
387  * use a comma.
388  */
389  stringbuffer_append_string(buf, ", ");
390  } else {
391  stringbuffer_append_string(buf, " and ");
392  }
393  if (num == 1)
394  stringbuffer_append_printf(buf, "1 %s", coin->clone.name);
395  else
396  stringbuffer_append_printf(buf, "%u %ss", num, coin->clone.name);
397  } while (next_coin);
398 
399 done:
400  return stringbuffer_finish(buf);
401 }
402 
413 static StringBuffer *real_money_value(const object *coin, StringBuffer *buf) {
414  assert(coin->type == MONEY);
415  assert(buf);
416 
417  stringbuffer_append_printf(buf, "%ld %s", (long)coin->nrof, coin->nrof == 1 ? coin->name : coin->name_pl);
418  return buf;
419 }
420 
421 char *cost_str(uint64_t cost) {
423 }
424 
425 char *cost_approx_str(const object *tmp, object *who) {
426  uint64_t approx_val = price_approx(tmp, who);
427  int idskill1 = 0;
428  int idskill2 = 0;
429  const typedata *tmptype;
430 
432 
433  /* money it's pretty hard to not give the exact price, so skip all logic and just return the real value. */
434  if (tmp->type == MONEY) {
435  return stringbuffer_finish(real_money_value(tmp, buf));
436  }
437 
438  tmptype = get_typedata(tmp->type);
439  if (tmptype) {
440  idskill1 = tmptype->identifyskill;
441  idskill2 = tmptype->identifyskill2;
442  }
443 
444  /* we show an approximate price if
445  * 1) we are approximating
446  * 2) there either is no id skill(s) for the item, or we don't have them
447  * 3) we don't have bargaining skill either
448  */
449  if (!idskill1 || !find_skill_by_number(who, idskill1)) {
450  if (!idskill2 || !find_skill_by_number(who, idskill2)) {
451  if (!find_skill_by_number(who, SK_BARGAINING)) {
452  int num;
453  int cointype = LARGEST_COIN_GIVEN;
454  archetype *coin = find_next_coin(approx_val, &cointype);
455 
456  if (coin == NULL) {
457  stringbuffer_append_string(buf, "nothing");
458  return stringbuffer_finish(buf);
459  }
460 
461  num = approx_val/coin->clone.value;
462  if (num == 1)
463  stringbuffer_append_printf(buf, "about one %s", coin->clone.name);
464  else if (num < 5)
465  stringbuffer_append_printf(buf, "a few %s", coin->clone.name_pl);
466  else if (num < 10)
467  stringbuffer_append_printf(buf, "several %s", coin->clone.name_pl);
468  else if (num < 25)
469  stringbuffer_append_printf(buf, "a moderate amount of %s", coin->clone.name_pl);
470  else if (num < 100)
471  stringbuffer_append_printf(buf, "lots of %s", coin->clone.name_pl);
472  else if (num < 1000)
473  stringbuffer_append_printf(buf, "a great many %s", coin->clone.name_pl);
474  else
475  stringbuffer_append_printf(buf, "a vast quantity of %s", coin->clone.name_pl);
476  return stringbuffer_finish(buf);
477  }
478  }
479  }
480 
481  // If we get here, return the price we guessed.
482  stringbuffer_delete(buf);
483  return cost_str(approx_val);
484 }
485 
486 uint64_t query_money(const object *op) {
487  uint64_t total = 0;
488 
489  if (op->type != PLAYER && op->type != CONTAINER) {
490  LOG(llevError, "Query money called with non player/container\n");
491  return 0;
492  }
493  FOR_INV_PREPARE(op, tmp) {
494  if (tmp->type == MONEY) {
495  total += (uint64_t)tmp->nrof*(uint64_t)tmp->value;
496  } else if (tmp->type == CONTAINER
497  && QUERY_FLAG(tmp, FLAG_APPLIED)
498  && (tmp->race == NULL || strstr(tmp->race, "gold"))) {
499  total += query_money(tmp);
500  }
501  } FOR_INV_FINISH();
502  return total;
503 }
504 
517 int pay_for_amount(uint64_t to_pay, object *pl) {
518  if (to_pay == 0)
519  return 1;
520  if (to_pay > query_money(pl))
521  return 0;
522 
523  to_pay = pay_from_container(pl, pl, to_pay);
524 
525  FOR_INV_PREPARE(pl, pouch) {
526  if (to_pay <= 0)
527  break;
528  if (pouch->type == CONTAINER
529  && QUERY_FLAG(pouch, FLAG_APPLIED)
530  && (pouch->race == NULL || strstr(pouch->race, "gold"))) {
531  to_pay = pay_from_container(pl, pouch, to_pay);
532  }
533  } FOR_INV_FINISH();
534  if (to_pay > 0) {
535  LOG(llevError, "pay_for_amount: Cannot remove enough money -- %"FMT64U" remains\n", to_pay);
536  }
537 
538  fix_object(pl);
539  return 1;
540 }
541 
556 int pay_for_item(object *op, object *pl) {
557  uint64_t to_pay = shop_price_buy(op, pl);
558 
559  if (to_pay == 0)
560  return 1;
561  if (to_pay > query_money(pl))
562  return 0;
563 
564  /* We compare the paid price with the one for a player
565  * without bargaining skill.
566  * This determins the amount of exp (if any) gained for bargaining.
567  */
568  int64_t saved_money = price_base(op) - to_pay;
569  if (saved_money > 0)
570  change_exp(pl, saved_money, "bargaining", SK_EXP_NONE);
571 
572  to_pay = pay_from_container(pl, pl, to_pay);
573 
574  FOR_INV_PREPARE(pl, pouch) {
575  if (to_pay <= 0)
576  break;
577  if (pouch->type == CONTAINER
578  && QUERY_FLAG(pouch, FLAG_APPLIED)
579  && (pouch->race == NULL || strstr(pouch->race, "gold"))) {
580  to_pay = pay_from_container(pl, pouch, to_pay);
581  }
582  } FOR_INV_FINISH();
583  if (to_pay > 0) {
584  LOG(llevError, "pay_for_item: Cannot remove enough money -- %"FMT64U" remains\n", to_pay);
585  }
587  SET_FLAG(op, FLAG_WAS_WIZ);
588  fix_object(pl);
589  return 1;
590 }
591 
603 static int64_t remove_value(object *coin_objs[], int64_t remain) {
604  int i;
605 
606  for (i = 0; i < NUM_COINS; i++) {
607  int count;
608  int64_t num_coins;
609 
610  if ((int64_t)coin_objs[i]->nrof * coin_objs[i]->value > remain) {
611  num_coins = remain/coin_objs[i]->value;
612  if ((uint64_t)num_coins*(uint64_t)coin_objs[i]->value < (uint64_t) remain) {
613  num_coins++;
614  }
615  } else {
616  num_coins = coin_objs[i]->nrof;
617  }
618  remain -= (int64_t)num_coins*(int64_t)coin_objs[i]->value;
619  coin_objs[i]->nrof -= num_coins;
620  /* Now start making change. Start at the coin value
621  * below the one we just did, and work down to
622  * the lowest value.
623  */
624  count = i-1;
625  while (remain < 0 && count >= 0) {
626  num_coins = -remain/coin_objs[count]->value;
627  coin_objs[count]->nrof += num_coins;
628  remain += num_coins*coin_objs[count]->value;
629  count--;
630  }
631  }
632 
633  return remain;
634 }
635 
644 static void add_value(object *coin_objs[], int64_t value) {
645  int i;
646 
647  for (i = NUM_COINS-LARGEST_COIN_GIVEN-1; i >= 0; i--) {
648  uint32_t nrof;
649 
650  nrof = (uint32_t)(value/coin_objs[i]->value);
651  value -= nrof*coin_objs[i]->value;
652  coin_objs[i]->nrof += nrof;
653  }
654 }
655 
668 static void insert_objects(object *pl, object *container, object *objects[], int objects_len) {
669  int i, one = 0;
670 
671  for (i = 0; i < objects_len; i++) {
672  if (objects[i]->nrof > 0) {
673  object_insert_in_ob(objects[i], container);
674  one = 1;
675  } else {
676  object_free_drop_inventory(objects[i]);
677  }
678  }
679  if (one)
680  esrv_update_item(UPD_WEIGHT, pl, container);
681 }
682 
699 static uint64_t pay_from_container(object *pl, object *pouch, uint64_t to_pay) {
700  size_t i;
701  int64_t remain;
702  object *coin_objs[NUM_COINS];
703  object *other_money[16]; /* collects MONEY objects not matching coins[] */
704  size_t other_money_len; /* number of allocated entries in other_money[] */
705  archetype *at;
706 
707  if (pouch->type != PLAYER && pouch->type != CONTAINER)
708  return to_pay;
709 
710  remain = to_pay;
711  for (i = 0; i < NUM_COINS; i++)
712  coin_objs[i] = NULL;
713 
714  /* This hunk should remove all the money objects from the player/container */
715  other_money_len = 0;
716  FOR_INV_PREPARE(pouch, tmp) {
717  if (tmp->type == MONEY) {
718  for (i = 0; i < NUM_COINS; i++) {
719  if (!strcmp(coins[NUM_COINS-1-i], tmp->arch->name)
720  && (tmp->value == tmp->arch->clone.value)) {
721  /* This should not happen, but if it does, just
722  * merge the two.
723  */
724  if (coin_objs[i] != NULL) {
725  LOG(llevError, "%s has two money entries of (%s)\n", pouch->name, coins[NUM_COINS-1-i]);
726  object_remove(tmp);
727  coin_objs[i]->nrof += tmp->nrof;
729  } else {
730  object_remove(tmp);
731  coin_objs[i] = tmp;
732  }
733  break;
734  }
735  }
736  if (i == NUM_COINS) {
737  if (other_money_len >= sizeof(other_money)/sizeof(*other_money)) {
738  LOG(llevError, "pay_for_item: Cannot store non-standard money object %s\n", tmp->arch->name);
739  } else {
740  object_remove(tmp);
741  other_money[other_money_len++] = tmp;
742  }
743  }
744  }
745  } FOR_INV_FINISH();
746 
747  /* Fill in any gaps in the coin_objs array - needed to make change. */
748  /* Note that the coin_objs array goes from least value to greatest value */
749  for (i = 0; i < NUM_COINS; i++)
750  if (coin_objs[i] == NULL) {
751  at = find_archetype(coins[NUM_COINS-1-i]);
752  if (at == NULL)
753  LOG(llevError, "Could not find %s archetype\n", coins[NUM_COINS-1-i]);
754  coin_objs[i] = object_new();
755  object_copy(&at->clone, coin_objs[i]);
756  coin_objs[i]->nrof = 0;
757  }
758 
759  /* Try to pay from standard coins first. */
760  remain = remove_value(coin_objs, remain);
761 
762  /* Now pay from non-standard coins until all is paid. */
763  for (i = 0; i < other_money_len && remain > 0; i++) {
764  uint32_t nrof;
765  object *coin;
766 
767  coin = other_money[i];
768 
769  /* Find the minimal number of coins to use. This prevents converting
770  * excess non-standard coins to standard money.
771  */
772  nrof = (remain+coin->value-1)/coin->value;
773  if (nrof > coin->nrof) {
774  nrof = coin->nrof;
775  }
776  coin->nrof -= nrof;
777  add_value(coin_objs, nrof*coin->value);
778 
779  remain = remove_value(coin_objs, remain);
780  }
781 
782  /* re-insert remaining coins into player */
783  insert_objects(pl, pouch, coin_objs, NUM_COINS);
784  insert_objects(pl, pouch, other_money, other_money_len);
785 
786  return(remain);
787 }
788 
805 static void count_unpaid(object *pl, object *item, int *unpaid_count, uint64_t *unpaid_price, uint32_t *coincount) {
806  int i;
807 
809  if (QUERY_FLAG(item, FLAG_UNPAID)) {
810  (*unpaid_count)++;
811  (*unpaid_price) += shop_price_buy(item, pl);
812  }
813  /* Merely converting the player's monetary wealth won't do.
814  * If we did that, we could print the wrong numbers for the
815  * coins, so we count the money instead.
816  */
817  for (i = 0; i < NUM_COINS; i++)
818  if (!strcmp(coins[i], item->arch->name)) {
819  coincount[i] += item->nrof;
820  break;
821  }
822  if (item->inv)
823  count_unpaid(pl, item->inv, unpaid_count, unpaid_price, coincount);
825 }
826 
839 int can_pay(object *pl) {
840  int unpaid_count = 0, i;
841  uint64_t unpaid_price = 0;
842  uint64_t player_wealth = query_money(pl);
843  uint32_t coincount[NUM_COINS];
844 
845  if (!pl || pl->type != PLAYER) {
846  LOG(llevError, "can_pay(): called against something that isn't a player\n");
847  return 0;
848  }
849 
850  for (i = 0; i < NUM_COINS; i++)
851  coincount[i] = 0;
852 
853  count_unpaid(pl, pl->inv, &unpaid_count, &unpaid_price, coincount);
854 
855  if (unpaid_price > player_wealth) {
856  char buf[MAX_BUF], coinbuf[MAX_BUF];
857  int denominations = 0;
858  char *value = cost_str(unpaid_price);
859 
860  snprintf(buf, sizeof(buf), "You have %d unpaid items that would cost you %s, ", unpaid_count, value);
861  free(value);
862  for (i = 0; i < NUM_COINS; i++) {
863  if (coincount[i] > 0 && coins[i]) {
864  if (denominations == 0)
865  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "but you only have");
866  denominations++;
867  snprintf(coinbuf, sizeof(coinbuf), " %u %s,", coincount[i], find_archetype(coins[i])->clone.name_pl);
868  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s", coinbuf);
869  }
870  }
871  if (denominations == 0)
872  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "but you don't have any money.");
873  else if (denominations > 1)
874  make_list_like(buf);
876  MSG_TYPE_SHOP_PAYMENT, buf);
877  return 0;
878  } else
879  return 1;
880 }
881 
882 int shop_pay_unpaid(object *pl, object *op) {
883  char name_op[MAX_BUF];
884  int ret = 1;
885 
886  if (op != NULL && op->inv)
887  ret = shop_pay_unpaid(pl, op->inv);
888 
889  if (!ret)
890  return 0;
891 
892  if (op != NULL && op->below)
893  ret = shop_pay_unpaid(pl, op->below);
894 
895  if (!ret)
896  return 0;
897 
898  if (op != NULL && QUERY_FLAG(op, FLAG_UNPAID)) {
899  uint64_t price = shop_price_buy(op, pl);
900  if (!pay_for_item(op, pl)) {
901  uint64_t i = price - query_money(pl);
902  char *missing = cost_str(i);
903 
904  CLEAR_FLAG(op, FLAG_UNPAID);
905  query_name(op, name_op, MAX_BUF);
908  "You lack %s to buy %s.",
909  missing, name_op);
910  free(missing);
911  SET_FLAG(op, FLAG_UNPAID);
912  return 0;
913  } else {
914  object *tmp;
915  char *value = cost_str(price);
916 
917  CLEAR_FLAG(op, FLAG_UNPAID);
919  query_name(op, name_op, MAX_BUF);
922  "You paid %s for %s.",
923  value, name_op);
924  free(value);
925  tmp = object_merge(op, NULL);
926  if (pl->type == PLAYER && !tmp) {
927  /* If item wasn't merged we update it. If merged, object_merge() handled everything for us. */
929  }
930  }
931  }
932  return 1;
933 }
934 
948 void sell_item(object *op, object *pl) {
949  object *tmp;
950  archetype *at;
951  char obj_name[MAX_BUF];
952 
953  query_name(op, obj_name, MAX_BUF);
954 
955  if (pl == NULL || pl->type != PLAYER) {
956  LOG(llevDebug, "Object other than player tried to sell something.\n");
957  return;
958  }
959 
960  if (execute_event(op, EVENT_SELLING, pl, NULL, NULL, SCRIPT_FIX_ALL) != 0)
961  return;
962 
963  if (op->custom_name)
965 
966  uint64_t price = shop_price_sell(op, pl);
967  if (price == 0) {
970  "We're not interested in %s.",
971  obj_name);
972  return;
973  }
974 
975  /* We compare the price with the one for a player
976  * without bargaining skill.
977  * This determins the amount of exp (if any) gained for bargaining.
978  * exp/10 -> 1 for each gold coin
979  */
980  int64_t extra_gain = price - price_base(op);
981  if (extra_gain > 0) {
982  change_exp(pl, extra_gain/10, "bargaining", SK_EXP_NONE);
983  }
984 
985  char *value_str = cost_str(price);
987  "You receive %s for %s.", value_str, obj_name);
988  free(value_str);
989 
990  for (int count = LARGEST_COIN_GIVEN; coins[count] != NULL; count++) {
991  at = find_archetype(coins[count]);
992  if (at == NULL)
993  LOG(llevError, "Could not find %s archetype\n", coins[count]);
994  else if ((price/at->clone.value) > 0) {
995  FOR_INV_PREPARE(pl, pouch) {
996  if (pouch->type == CONTAINER
997  && QUERY_FLAG(pouch, FLAG_APPLIED)
998  && pouch->race
999  && strstr(pouch->race, "gold")) {
1000  int w = at->clone.weight*(100-pouch->stats.Str)/100;
1001  int n = price/at->clone.value;
1002 
1003  if (w == 0)
1004  w = 1; /* Prevent divide by zero */
1005  if (n > 0
1006  && (!pouch->weight_limit || pouch->carrying+w <= pouch->weight_limit)) {
1007  if (pouch->weight_limit
1008  && (pouch->weight_limit-pouch->carrying)/w < n)
1009  n = (pouch->weight_limit-pouch->carrying)/w;
1010 
1011  tmp = object_new();
1012  object_copy(&at->clone, tmp);
1013  tmp->nrof = n;
1014  price -= (uint64_t)tmp->nrof*(uint64_t)tmp->value;
1015  tmp = object_insert_in_ob(tmp, pouch);
1016  esrv_update_item(UPD_WEIGHT, pl, pl);
1017  }
1018  }
1019  } FOR_INV_FINISH();
1020  if (price/at->clone.value > 0) {
1021  tmp = object_new();
1022  object_copy(&at->clone, tmp);
1023  tmp->nrof = price/tmp->value;
1024  price -= (uint64_t)tmp->nrof*(uint64_t)tmp->value;
1025  tmp = object_insert_in_ob(tmp, pl);
1026  esrv_update_item(UPD_WEIGHT, pl, pl);
1027  }
1028  }
1029  }
1030 
1031  if (price != 0) {
1032  LOG(llevError, "Warning - payment not zero: %" PRIo64 "\n", price);
1033  }
1034 
1035  SET_FLAG(op, FLAG_UNPAID);
1036  identify(op);
1037 }
1038 
1052 static double shop_specialisation_ratio(const object *item, const mapstruct *map) {
1053  shopitems *items = map->shopitems;
1054  double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
1055  int i;
1056 
1057  if (item == NULL) {
1058  LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
1059  return 0;
1060  }
1061  if (item->type == (uint8_t)-1) {
1062  LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
1063  /*
1064  * I'm not really sure what the /right/ thing to do here is,
1065  * these types of item shouldn't exist anyway, but returning
1066  * the ratio is probably the best bet.."
1067  */
1068  return ratio;
1069  }
1070  if (map->shopitems) {
1071  for (i = 0; i < items[0].index; i++)
1072  if (items[i].typenum == item->type || (items[i].typenum == -1 && likedness == 0.001))
1073  likedness = items[i].strength/100.0;
1074  }
1075  if (likedness > 1.0) { /* someone has been rather silly with the map headers. */
1076  LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, map->path);
1077  likedness = 1.0;
1078  }
1079  if (likedness < -1.0) {
1080  LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, map->path);
1081  likedness = -1.0;
1082  }
1083  ratio = ratio+(1.0-ratio)*likedness;
1084  if (ratio <= 0.1)
1085  ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
1086  return ratio;
1087 }
1088 
1097 static double shop_greed(const mapstruct *map) {
1098  double greed = 1.0;
1099 
1100  if (map->shopgreed)
1101  return map->shopgreed;
1102  return greed;
1103 }
1104 
1105 double shop_approval(const mapstruct *map, const object *player) {
1106  double approval = 1.0;
1107 
1108  if (map->shoprace) {
1109  approval = NEUTRAL_RATIO;
1110  if (player->race && !strcmp(player->race, map->shoprace))
1111  approval = 1.0;
1112  }
1113  return approval;
1114 }
1115 
1135 static uint64_t value_limit(uint64_t val, int quantity, const object *who, int isshop) {
1136  uint64_t newval, unit_price;
1137  mapstruct *map;
1138 
1139  unit_price = val/quantity;
1140  if (!isshop || !who) {
1141  if (unit_price > 10000)
1142  newval = 8000+isqrt(unit_price)*20;
1143  else
1144  newval = unit_price;
1145  } else {
1146  if (!who->map) {
1147  LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name);
1148  return val;
1149  }
1150  map = who->map;
1151  if (map->shopmin && unit_price < map->shopmin)
1152  return 0;
1153  else if (map->shopmax && unit_price > map->shopmax/2)
1154  newval = MIN((map->shopmax/2)+isqrt(unit_price-map->shopmax/2), map->shopmax);
1155  else if (unit_price > 10000)
1156  newval = 8000+isqrt(unit_price)*20;
1157  else
1158  newval = unit_price;
1159  }
1160  newval *= quantity;
1161  return newval;
1162 }
1163 
1164 int shop_describe(const object *op) {
1165  mapstruct *map = op->map;
1166  /*shopitems *items=map->shopitems;*/
1167  int pos = 0, i;
1168  double opinion = 0;
1169  char tmp[MAX_BUF] = "\0", *value;
1170 
1171  if (op->type != PLAYER)
1172  return 0;
1173 
1174  /*check if there is a shop specified for this map */
1175  if (map->shopitems
1176  || map->shopgreed
1177  || map->shoprace
1178  || map->shopmin
1179  || map->shopmax) {
1181  "From looking at the nearby shop you determine that it trades in:");
1182 
1183  if (map->shopitems) {
1184  for (i = 0; i < map->shopitems[0].index; i++) {
1185  if (map->shopitems[i].name && map->shopitems[i].strength > 10) {
1186  snprintf(tmp+pos, sizeof(tmp)-pos, "%s, ", map->shopitems[i].name_pl);
1187  pos += strlen(tmp+pos);
1188  }
1189  }
1190  }
1191  if (!pos)
1192  strcpy(tmp, "a little of everything.");
1193 
1194  /* format the string into a list */
1195  make_list_like(tmp);
1196  draw_ext_info(NDI_UNIQUE, 0, op,
1198 
1199  if (map->shopmax) {
1200  value = cost_str(map->shopmax);
1203  "It won't trade for items above %s.",
1204  value);
1205  free(value);
1206  }
1207 
1208  if (map->shopmin) {
1209  value = cost_str(map->shopmin);
1212  "It won't trade in items worth less than %s.",
1213  value);
1214  free(value);
1215  }
1216 
1217  if (map->shopgreed) {
1218  if (map->shopgreed > 2.0)
1219  draw_ext_info(NDI_UNIQUE, 0, op,
1221  "It tends to overcharge massively.");
1222  else if (map->shopgreed > 1.5)
1223  draw_ext_info(NDI_UNIQUE, 0, op,
1225  "It tends to overcharge substantially.");
1226  else if (map->shopgreed > 1.1)
1227  draw_ext_info(NDI_UNIQUE, 0, op,
1229  "It tends to overcharge slightly.");
1230  else if (map->shopgreed < 0.9)
1231  draw_ext_info(NDI_UNIQUE, 0, op,
1233  "It tends to undercharge.");
1234  }
1235  if (map->shoprace) {
1236  opinion = shop_approval(map, op);
1237  if (opinion > 0.8)
1238  draw_ext_info(NDI_UNIQUE, 0, op,
1240  "You think the shopkeeper likes you.");
1241  else if (opinion > 0.5)
1242  draw_ext_info(NDI_UNIQUE, 0, op,
1244  "The shopkeeper seems unconcerned by you.");
1245  else
1246  draw_ext_info(NDI_UNIQUE, 0, op,
1248  "The shopkeeper seems to have taken a dislike to you.");
1249  }
1251  "There is no shop nearby.");
1252 
1253  return 1;
1254 }
1255 
1259 static bool coords_in_shop(mapstruct *map, int x, int y) {
1260  FOR_MAP_PREPARE(map, x, y, floor)
1261  if (floor->type == SHOP_FLOOR) return true;
1262  FOR_MAP_FINISH();
1263  return false;
1264 }
1265 
1266 bool shop_contains(object *ob) {
1267  if (!ob->map) return 0;
1268  return coords_in_shop(ob->map, ob->x, ob->y);
1269 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:315
char path[HUGE_BUF]
Definition: map.h:365
uint64_t price_base(const object *tmp)
Definition: shop.c:70
Definition: player.h:92
#define FLAG_PLAYER_SOLD
Definition: define.h:252
double shopgreed
Definition: map.h:358
archetype * find_archetype(const char *name)
Definition: arch.c:692
#define FLAG_DAMNED
Definition: define.h:318
#define FLAG_UNPAID
Definition: define.h:236
#define MSG_TYPE_SHOP_LISTING
Definition: newclient.h:486
static archetype * find_next_coin(uint64_t c, int *cointype)
Definition: shop.c:304
static const char *const coins[]
Definition: shop.c:57
uint64_t query_money(const object *op)
Definition: shop.c:486
static StringBuffer * real_money_value(const object *coin, StringBuffer *buf)
Definition: shop.c:413
const char * race
Definition: object.h:318
uint64_t shop_price_sell(const object *tmp, object *who)
Definition: shop.c:251
#define MSG_TYPE_SHOP_SELL
Definition: newclient.h:492
#define SET_FLAG(xyz, p)
Definition: define.h:223
unsigned char uint8_t
Definition: win32.h:161
int identifyskill
Definition: define.h:93
#define NUM_COINS
Definition: shop.c:52
static bool coords_in_shop(mapstruct *map, int x, int y)
Definition: shop.c:1259
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
int16_t max_level
Definition: global.h:299
static double shop_specialisation_ratio(const object *item, const mapstruct *map)
Definition: shop.c:1052
#define FMT64U
Definition: compat.h:13
#define MSG_TYPE_SHOP_PAYMENT
Definition: newclient.h:489
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.c:342
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4264
Definition: object.h:137
static uint64_t value_limit(uint64_t val, int quantity, const object *who, int isshop)
Definition: shop.c:1135
double shop_approval(const mapstruct *map, const object *player)
Definition: shop.c:1105
uint64_t shop_price_buy(const object *tmp, object *who)
Definition: shop.c:193
object clone
Definition: object.h:470
bool shop_contains(object *ob)
Definition: shop.c:1266
int isqrt(int n)
Definition: utils.c:586
static void count_unpaid(object *pl, object *item, int *unpaid_count, uint64_t *unpaid_price, uint32_t *coincount)
Definition: shop.c:805
#define FLAG_BLESSED
Definition: define.h:378
const char * name
Definition: map.h:306
static void insert_objects(object *pl, object *container, object *objects[], int objects_len)
Definition: shop.c:668
#define FALSE
Definition: compat.h:11
#define SCRIPT_FIX_ALL
Definition: global.h:361
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:310
Definition: object.h:465
Definition: object.h:220
#define FOR_OB_AND_BELOW_FINISH()
Definition: define.h:791
#define MIN(x, y)
Definition: compat.h:17
int typenum
Definition: map.h:308
int can_pay(object *pl)
Definition: shop.c:839
uint64_t price_approx(const object *tmp, object *who)
Definition: shop.c:129
const typedata * get_typedata(int itemtype)
Definition: item.c:335
static void add_value(object *coin_objs[], int64_t value)
Definition: shop.c:644
void make_list_like(char *input)
Definition: utils.c:395
void object_free_drop_inventory(object *ob)
Definition: object.c:1389
int16_t y
Definition: object.h:326
int pay_for_item(object *op, object *pl)
Definition: shop.c:556
static int64_t remove_value(object *coin_objs[], int64_t remain)
Definition: shop.c:603
object * object_new(void)
Definition: object.c:1068
const char * name_pl
Definition: object.h:315
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
int index
Definition: map.h:311
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2705
char * cost_string_from_value(uint64_t cost, int largest_coin)
Definition: shop.c:338
int32_t weight
Definition: object.h:365
int8_t strength
Definition: map.h:309
struct mapdef * map
Definition: object.h:297
#define snprintf
Definition: win32.h:46
uint64_t shopmin
Definition: map.h:359
#define FLAG_IDENTIFIED
Definition: define.h:261
#define FOR_INV_FINISH()
Definition: define.h:714
#define MSG_TYPE_SHOP_MISC
Definition: newclient.h:493
object * objects
Definition: object.c:60
const char * name
Definition: object.h:311
char * cost_approx_str(const object *tmp, object *who)
Definition: shop.c:425
static double shop_greed(const mapstruct *map)
Definition: shop.c:1097
struct obj * below
Definition: object.h:287
uint32_t nrof
Definition: object.h:333
int8_t Cha
Definition: living.h:36
#define UPD_FLAGS
Definition: newclient.h:290
uint8_t real_wiz
Definition: global.h:267
#define EVENT_SELLING
Definition: plugin.h:79
int pay_for_amount(uint64_t to_pay, object *pl)
Definition: shop.c:517
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:206
#define MSG_TYPE_SHOP
Definition: newclient.h:378
#define UPD_WEIGHT
Definition: newclient.h:291
unsigned __int64 uint64_t
Definition: win32.h:167
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
Definition: living.c:2102
#define FLAG_BEEN_APPLIED
Definition: define.h:324
#define MAX_BUF
Definition: define.h:35
int16_t x
Definition: object.h:326
int shop_pay_unpaid(object *pl, object *op)
Definition: shop.c:882
signed __int64 int64_t
Definition: win32.h:168
int identifyskill2
Definition: define.h:94
#define FOR_MAP_FINISH()
Definition: define.h:767
int need_identify(const object *op)
Definition: item.c:1332
#define FLAG_CURSED
Definition: define.h:317
unsigned int uint32_t
Definition: win32.h:162
Definition: object.h:107
static uint64_t pay_from_container(object *pl, object *pouch, uint64_t to_pay)
Definition: shop.c:699
static float shop_buy_multiplier(int charisma)
Definition: shop.c:170
const char * custom_name
Definition: object.h:432
tag_t count
Definition: object.h:299
const char * name_pl
Definition: map.h:307
living stats
Definition: object.h:368
struct archt * arch
Definition: object.h:412
#define LARGEST_COIN_GIVEN
Definition: shop.c:54
void stringbuffer_delete(StringBuffer *sb)
Definition: stringbuffer.c:71
uint64_t shopmax
Definition: map.h:360
char * cost_str(uint64_t cost)
Definition: shop.c:421
uint8_t type
Definition: object.h:338
struct Settings settings
Definition: init.c:40
#define SK_EXP_NONE
Definition: skills.h:81
Definition: map.h:305
#define FLAG_APPLIED
Definition: define.h:235
void sell_item(object *op, object *pl)
Definition: shop.c:948
object * object_merge(object *op, object *top)
Definition: object.c:1884
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: main.c:364
#define UPD_NAME
Definition: newclient.h:293
#define FOR_OB_AND_BELOW_PREPARE(op_)
Definition: define.h:787
#define SPECIALISATION_EFFECT
Definition: shop.c:39
object * identify(object *op)
Definition: item.c:1438
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
static float shop_bargain_multiplier(int lev_bargain)
Definition: shop.c:189
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:869
struct obj * inv
Definition: object.h:290
#define NDI_UNIQUE
Definition: newclient.h:245
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
#define FLAG_WAS_WIZ
Definition: define.h:234
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:760
struct shopitem * shopitems
Definition: map.h:356
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:626
char * shoprace
Definition: map.h:357
object * find_skill_by_number(object *who, int skillno)
Definition: main.c:351
Definition: map.h:325
Definition: object.h:167
#define NEUTRAL_RATIO
Definition: shop.c:45
int shop_describe(const object *op)
Definition: shop.c:1164
int16_t level
Definition: object.h:351
void fix_object(object *op)
Definition: living.c:1119
int32_t value
Definition: object.h:350
int8_t magic
Definition: object.h:348
const char * name
Definition: object.h:466
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
void object_remove(object *op)
Definition: object.c:1669
int32_t food
Definition: living.h:48