Crossfire Server, Trunk  R21017
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 
66 uint64_t price_base(const object *tmp) {
67  // When there are zero objects, there is really one.
68  int number = (tmp->nrof == 0) ? 1 : tmp->nrof;
69  uint64_t val = (uint64_t)tmp->value * number;
70  bool identified = QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp);
71 
72  // Objects with price adjustments skip the rest of the calculations.
73  const char *key = object_get_value(tmp, "price_adjustment");
74  if (key != NULL) {
75  float ratio = atof(key);
76  return val * ratio;
77  }
78 
79  // Money and gems have fixed prices at shops.
80  if (tmp->type == MONEY || tmp->type == GEM) {
81  return val;
82  }
83 
84  // If not identified, assume it is a collection of base items.
85  if (!identified && tmp->arch)
86  {
87  val = tmp->arch->clone.value * number;
88  }
89 
95  if (QUERY_FLAG(tmp, FLAG_BLESSED)){
96  val *= 1.15;
97  } else if (QUERY_FLAG(tmp, FLAG_CURSED)) {
98  val *= 0.8;
99  } else if (QUERY_FLAG(tmp, FLAG_DAMNED)) {
100  val *= 0.6;
101  }
102 
103  // If an item has an archetype and is identified, compare its base enchantment.
104  if (tmp->arch != NULL && identified) {
105  int diff = tmp->magic - tmp->arch->clone.magic;
106  val *= pow(1.15, diff);
107  }
108 
109  // FIXME: Is the 'baseline' 50 charges per wand?
110  if (tmp->type == WAND) {
111  val *= tmp->stats.food / 50.0;
112  }
113 
114  /* we need to multiply these by 4.0 to keep buy costs roughly the same
115  * (otherwise, you could buy a potion of charisma for around 400 pp.
116  * Arguable, the costs in the archetypes should be updated to better
117  * reflect values (potion charisma list for 1250 gold)
118  */
119  val *= 4;
120 
121  return val;
122 }
123 
124 uint64_t price_approx(const object *tmp, object *who) {
125  uint64_t val = price_base(tmp);
126 
127  /* If we are approximating, then the value returned should
128  * be allowed to be wrong however merely using a random number
129  * each time will not be sufficient, as then multiple examinations
130  * would give different answers, so we'll use the count instead.
131  * By taking the sine of the count, a value between -1 and 1 is
132  * generated, we then divide by the square root of the bargaining
133  * skill and the appropriate identification skills, so that higher
134  * level players get better estimates. (We need a +1 there to
135  * prevent dividing by zero.)
136  */
137  const typedata *tmptype = get_typedata(tmp->type);
138  int lev_identify = 0;
139 
140  if (tmptype) {
141  int idskill1 = tmptype->identifyskill;
142  if (idskill1) {
143  int idskill2 = tmptype->identifyskill2;
144  if (find_skill_by_number(who, idskill1)) {
145  lev_identify = find_skill_by_number(who, idskill1)->level;
146  }
147  if (idskill2 && find_skill_by_number(who, idskill2)) {
148  lev_identify += find_skill_by_number(who, idskill2)->level;
149  }
150  }
151  } else {
152  LOG(llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->name);
153  }
154  val += val * (sin(tmp->count) / sqrt(lev_identify * 3 + 1.0));
155 
156  return val;
157 }
158 
165 static float shop_buy_multiplier(int charisma) {
166  float multiplier = 1 / (0.38 * pow(1.06, charisma));
167 
168  if (multiplier > 2) {
169  return 2;
170  } else if (multiplier < 0.5) {
171  return 0.5;
172  } else {
173  return multiplier;
174  }
175 }
176 
184 static float shop_bargain_multiplier(int lev_bargain) {
185  return 1 - 0.5 * lev_bargain / settings.max_level;
186 }
187 
188 uint64_t shop_price_buy(const object *tmp, object *who) {
189  assert(who != NULL && who->type == PLAYER);
190  uint64_t val = price_base(tmp);
191 
192  const char *key = object_get_value(tmp, "price_adjustment_buy");
193  if (key != NULL) {
194  float ratio = atof(key);
195  return val * ratio;
196  }
197 
198  if (tmp->type == GEM) {
199  return 1.03 * val;
200  }
201 
202  // Further reduce the sell price of cursed and damned items.
203  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
204  val *= 0.8;
205  }
206 
207  int bargain_level = 0;
209  bargain_level = find_skill_by_number(who, SK_BARGAINING)->level;
210  }
211 
212  float multiplier = shop_bargain_multiplier(bargain_level);
213  multiplier *= shop_buy_multiplier(who->stats.Cha);
214 
215  // Limit buy price multiplier to 0.5, no matter what.
216  val *= multiplier > 0.5 ? multiplier : 0.5;
217 
218  /*
219  * When buying, if the item was sold by another player, it is
220  * ok to let the item be sold cheaper, according to the
221  * specialisation of the shop. If a player sold an item here,
222  * then his sale price was multiplied by the specialisation
223  * ratio, to do the same to the buy price will not generate
224  * extra money. However, the same is not true of generated
225  * items, these have to /divide/ by the specialisation, so
226  * that the price is never less than what they could
227  * be sold for (otherwise players could camp map resets to
228  * make money).
229  * In game terms, a non-specialist shop might not recognise
230  * the true value of the items it sells (much like how people
231  * sometimes find antiques in a junk shop in real life).
232  */
233  if (QUERY_FLAG(tmp, FLAG_PLAYER_SOLD)) {
234  val = (int64_t)val*shop_greed(who->map)
235  *shop_specialisation_ratio(tmp, who->map)
236  /shop_approval(who->map, who);
237  } else {
238  val = (int64_t)val*shop_greed(who->map)
239  /(shop_specialisation_ratio(tmp, who->map)
240  *shop_approval(who->map, who));
241  }
242 
243  return val;
244 }
245 
246 uint64_t shop_price_sell(const object *tmp, object *who) {
247  assert(who != NULL && who->type == PLAYER);
248  uint64_t val = price_base(tmp);
249  bool identified = QUERY_FLAG(tmp, FLAG_IDENTIFIED) || !need_identify(tmp);
250 
251  const char *key = object_get_value(tmp, "price_adjustment_sell");
252  if (key != NULL) {
253  float ratio = atof(key);
254  return val * ratio;
255  }
256 
257  if (tmp->type == GEM) {
258  return 0.97 * val;
259  }
260 
261  // Shops value unidentified items less.
262  if (!identified) {
263  if (tmp->arch != NULL) {
264  // Unidentified standard objects are only worth a little less.
265  if (QUERY_FLAG(tmp, FLAG_BEEN_APPLIED)) {
266  val *= 0.85;
267  } else {
268  val *= 0.70;
269  }
270  } else {
271  // No archetype, so probably an artifact.
272  val /= 2;
273  }
274  }
275 
276  // Selling to shops yields roughly 50% of the base price.
277  val /= 2;
278 
279  /* Limit amount of money you can get for really great items. */
280  int number = (tmp->nrof == 0) ? 1 : tmp->nrof;
281  val = value_limit(val, number, who, 1);
282 
283  val = (int64_t)val*shop_specialisation_ratio(tmp, who->map)*
284  shop_approval(who->map, who)/shop_greed(who->map);
285  return val;
286 }
287 
299 static archetype *find_next_coin(uint64_t c, int *cointype) {
300  archetype *coin;
301 
302  do {
303  if (coins[*cointype] == NULL)
304  return NULL;
305  coin = find_archetype(coins[*cointype]);
306  if (coin == NULL)
307  return NULL;
308  *cointype += 1;
309  } while (coin->clone.value > (int64_t) c);
310 
311  return coin;
312 }
313 
333 char* cost_string_from_value(uint64_t cost, int largest_coin) {
334  archetype *coin, *next_coin;
335  uint32_t num;
336  int cointype = largest_coin;
337 
338  if (cointype < 0)
339  cointype = 0;
340  else if (cointype >= NUM_COINS)
341  cointype = NUM_COINS - 1;
342 
344  coin = find_next_coin(cost, &cointype);
345  if (coin == NULL) {
346  stringbuffer_append_string(buf, "nothing");
347  goto done;
348  }
349 
350  num = cost/coin->clone.value;
351  /* so long as nrof is 32 bit, this is true.
352  * If it takes more coins than a person can possibly carry, this
353  * is basically true.
354  */
355  if ((cost/coin->clone.value) > UINT32_MAX) {
356  stringbuffer_append_string(buf, "an unimaginable sum of money.");
357  goto done;
358  }
359 
360  cost -= (uint64_t)num*(uint64_t)coin->clone.value;
361  if (num == 1)
362  stringbuffer_append_printf(buf, "1 %s", coin->clone.name);
363  else
364  stringbuffer_append_printf(buf, "%u %ss", num, coin->clone.name);
365 
366  next_coin = find_next_coin(cost, &cointype);
367  if (next_coin == NULL)
368  goto done;
369 
370  do {
371  coin = next_coin;
372  num = cost/coin->clone.value;
373  cost -= (uint64_t)num*(uint64_t)coin->clone.value;
374 
375  if (cost == 0)
376  next_coin = NULL;
377  else
378  next_coin = find_next_coin(cost, &cointype);
379 
380  if (next_coin) {
381  /* There will be at least one more string to add to the list,
382  * use a comma.
383  */
384  stringbuffer_append_string(buf, ", ");
385  } else {
386  stringbuffer_append_string(buf, " and ");
387  }
388  if (num == 1)
389  stringbuffer_append_printf(buf, "1 %s", coin->clone.name);
390  else
391  stringbuffer_append_printf(buf, "%u %ss", num, coin->clone.name);
392  } while (next_coin);
393 
394 done:
395  return stringbuffer_finish(buf);
396 }
397 
408 static StringBuffer *real_money_value(const object *coin, StringBuffer *buf) {
409  assert(coin->type == MONEY);
410  assert(buf);
411 
412  stringbuffer_append_printf(buf, "%ld %s", (long)coin->nrof, coin->nrof == 1 ? coin->name : coin->name_pl);
413  return buf;
414 }
415 
416 char *cost_str(uint64_t cost) {
418 }
419 
420 char *cost_approx_str(const object *tmp, object *who) {
421  uint64_t approx_val = price_approx(tmp, who);
422  int idskill1 = 0;
423  int idskill2 = 0;
424  const typedata *tmptype;
425 
427 
428  /* money it's pretty hard to not give the exact price, so skip all logic and just return the real value. */
429  if (tmp->type == MONEY) {
430  return stringbuffer_finish(real_money_value(tmp, buf));
431  }
432 
433  tmptype = get_typedata(tmp->type);
434  if (tmptype) {
435  idskill1 = tmptype->identifyskill;
436  idskill2 = tmptype->identifyskill2;
437  }
438 
439  /* we show an approximate price if
440  * 1) we are approximating
441  * 2) there either is no id skill(s) for the item, or we don't have them
442  * 3) we don't have bargaining skill either
443  */
444  if (!idskill1 || !find_skill_by_number(who, idskill1)) {
445  if (!idskill2 || !find_skill_by_number(who, idskill2)) {
446  if (!find_skill_by_number(who, SK_BARGAINING)) {
447  int num;
448  int cointype = LARGEST_COIN_GIVEN;
449  archetype *coin = find_next_coin(approx_val, &cointype);
450 
451  if (coin == NULL) {
452  stringbuffer_append_string(buf, "nothing");
453  return stringbuffer_finish(buf);
454  }
455 
456  num = approx_val/coin->clone.value;
457  if (num == 1)
458  stringbuffer_append_printf(buf, "about one %s", coin->clone.name);
459  else if (num < 5)
460  stringbuffer_append_printf(buf, "a few %s", coin->clone.name_pl);
461  else if (num < 10)
462  stringbuffer_append_printf(buf, "several %s", coin->clone.name_pl);
463  else if (num < 25)
464  stringbuffer_append_printf(buf, "a moderate amount of %s", coin->clone.name_pl);
465  else if (num < 100)
466  stringbuffer_append_printf(buf, "lots of %s", coin->clone.name_pl);
467  else if (num < 1000)
468  stringbuffer_append_printf(buf, "a great many %s", coin->clone.name_pl);
469  else
470  stringbuffer_append_printf(buf, "a vast quantity of %s", coin->clone.name_pl);
471  return stringbuffer_finish(buf);
472  }
473  }
474  }
475 
476  // If we get here, return the price we guessed.
477  stringbuffer_delete(buf);
478  return cost_str(approx_val);
479 }
480 
481 uint64_t query_money(const object *op) {
482  uint64_t total = 0;
483 
484  if (op->type != PLAYER && op->type != CONTAINER) {
485  LOG(llevError, "Query money called with non player/container\n");
486  return 0;
487  }
488  FOR_INV_PREPARE(op, tmp) {
489  if (tmp->type == MONEY) {
490  total += (uint64_t)tmp->nrof*(uint64_t)tmp->value;
491  } else if (tmp->type == CONTAINER
492  && QUERY_FLAG(tmp, FLAG_APPLIED)
493  && (tmp->race == NULL || strstr(tmp->race, "gold"))) {
494  total += query_money(tmp);
495  }
496  } FOR_INV_FINISH();
497  return total;
498 }
499 
512 int pay_for_amount(uint64_t to_pay, object *pl) {
513  if (to_pay == 0)
514  return 1;
515  if (to_pay > query_money(pl))
516  return 0;
517 
518  to_pay = pay_from_container(pl, pl, to_pay);
519 
520  FOR_INV_PREPARE(pl, pouch) {
521  if (to_pay <= 0)
522  break;
523  if (pouch->type == CONTAINER
524  && QUERY_FLAG(pouch, FLAG_APPLIED)
525  && (pouch->race == NULL || strstr(pouch->race, "gold"))) {
526  to_pay = pay_from_container(pl, pouch, to_pay);
527  }
528  } FOR_INV_FINISH();
529  if (to_pay > 0) {
530  LOG(llevError, "pay_for_amount: Cannot remove enough money -- %"FMT64U" remains\n", to_pay);
531  }
532 
533  fix_object(pl);
534  return 1;
535 }
536 
551 int pay_for_item(object *op, object *pl) {
552  uint64_t to_pay = shop_price_buy(op, pl);
553 
554  if (to_pay == 0)
555  return 1;
556  if (to_pay > query_money(pl))
557  return 0;
558 
559  /* We compare the paid price with the one for a player
560  * without bargaining skill.
561  * This determins the amount of exp (if any) gained for bargaining.
562  */
563  int64_t saved_money = price_base(op) - to_pay;
564  if (saved_money > 0)
565  change_exp(pl, saved_money, "bargaining", SK_EXP_NONE);
566 
567  to_pay = pay_from_container(pl, pl, to_pay);
568 
569  FOR_INV_PREPARE(pl, pouch) {
570  if (to_pay <= 0)
571  break;
572  if (pouch->type == CONTAINER
573  && QUERY_FLAG(pouch, FLAG_APPLIED)
574  && (pouch->race == NULL || strstr(pouch->race, "gold"))) {
575  to_pay = pay_from_container(pl, pouch, to_pay);
576  }
577  } FOR_INV_FINISH();
578  if (to_pay > 0) {
579  LOG(llevError, "pay_for_item: Cannot remove enough money -- %"FMT64U" remains\n", to_pay);
580  }
582  SET_FLAG(op, FLAG_WAS_WIZ);
583  fix_object(pl);
584  return 1;
585 }
586 
598 static int64_t remove_value(object *coin_objs[], int64_t remain) {
599  int i;
600 
601  for (i = 0; i < NUM_COINS; i++) {
602  int count;
603  int64_t num_coins;
604 
605  if ((int64_t)coin_objs[i]->nrof * coin_objs[i]->value > remain) {
606  num_coins = remain/coin_objs[i]->value;
607  if ((uint64_t)num_coins*(uint64_t)coin_objs[i]->value < (uint64_t) remain) {
608  num_coins++;
609  }
610  } else {
611  num_coins = coin_objs[i]->nrof;
612  }
613  remain -= (int64_t)num_coins*(int64_t)coin_objs[i]->value;
614  coin_objs[i]->nrof -= num_coins;
615  /* Now start making change. Start at the coin value
616  * below the one we just did, and work down to
617  * the lowest value.
618  */
619  count = i-1;
620  while (remain < 0 && count >= 0) {
621  num_coins = -remain/coin_objs[count]->value;
622  coin_objs[count]->nrof += num_coins;
623  remain += num_coins*coin_objs[count]->value;
624  count--;
625  }
626  }
627 
628  return remain;
629 }
630 
639 static void add_value(object *coin_objs[], int64_t value) {
640  int i;
641 
642  for (i = NUM_COINS-LARGEST_COIN_GIVEN-1; i >= 0; i--) {
643  uint32_t nrof;
644 
645  nrof = (uint32_t)(value/coin_objs[i]->value);
646  value -= nrof*coin_objs[i]->value;
647  coin_objs[i]->nrof += nrof;
648  }
649 }
650 
663 static void insert_objects(object *pl, object *container, object *objects[], int objects_len) {
664  int i, one = 0;
665 
666  for (i = 0; i < objects_len; i++) {
667  if (objects[i]->nrof > 0) {
668  object_insert_in_ob(objects[i], container);
669  one = 1;
670  } else {
671  object_free_drop_inventory(objects[i]);
672  }
673  }
674  if (one)
675  esrv_update_item(UPD_WEIGHT, pl, container);
676 }
677 
694 static uint64_t pay_from_container(object *pl, object *pouch, uint64_t to_pay) {
695  size_t i;
696  int64_t remain;
697  object *coin_objs[NUM_COINS];
698  object *other_money[16]; /* collects MONEY objects not matching coins[] */
699  size_t other_money_len; /* number of allocated entries in other_money[] */
700  archetype *at;
701 
702  if (pouch->type != PLAYER && pouch->type != CONTAINER)
703  return to_pay;
704 
705  remain = to_pay;
706  for (i = 0; i < NUM_COINS; i++)
707  coin_objs[i] = NULL;
708 
709  /* This hunk should remove all the money objects from the player/container */
710  other_money_len = 0;
711  FOR_INV_PREPARE(pouch, tmp) {
712  if (tmp->type == MONEY) {
713  for (i = 0; i < NUM_COINS; i++) {
714  if (!strcmp(coins[NUM_COINS-1-i], tmp->arch->name)
715  && (tmp->value == tmp->arch->clone.value)) {
716  /* This should not happen, but if it does, just
717  * merge the two.
718  */
719  if (coin_objs[i] != NULL) {
720  LOG(llevError, "%s has two money entries of (%s)\n", pouch->name, coins[NUM_COINS-1-i]);
721  object_remove(tmp);
722  coin_objs[i]->nrof += tmp->nrof;
724  } else {
725  object_remove(tmp);
726  coin_objs[i] = tmp;
727  }
728  break;
729  }
730  }
731  if (i == NUM_COINS) {
732  if (other_money_len >= sizeof(other_money)/sizeof(*other_money)) {
733  LOG(llevError, "pay_for_item: Cannot store non-standard money object %s\n", tmp->arch->name);
734  } else {
735  object_remove(tmp);
736  other_money[other_money_len++] = tmp;
737  }
738  }
739  }
740  } FOR_INV_FINISH();
741 
742  /* Fill in any gaps in the coin_objs array - needed to make change. */
743  /* Note that the coin_objs array goes from least value to greatest value */
744  for (i = 0; i < NUM_COINS; i++)
745  if (coin_objs[i] == NULL) {
746  at = find_archetype(coins[NUM_COINS-1-i]);
747  if (at == NULL)
748  LOG(llevError, "Could not find %s archetype\n", coins[NUM_COINS-1-i]);
749  coin_objs[i] = object_new();
750  object_copy(&at->clone, coin_objs[i]);
751  coin_objs[i]->nrof = 0;
752  }
753 
754  /* Try to pay from standard coins first. */
755  remain = remove_value(coin_objs, remain);
756 
757  /* Now pay from non-standard coins until all is paid. */
758  for (i = 0; i < other_money_len && remain > 0; i++) {
759  uint32_t nrof;
760  object *coin;
761 
762  coin = other_money[i];
763 
764  /* Find the minimal number of coins to use. This prevents converting
765  * excess non-standard coins to standard money.
766  */
767  nrof = (remain+coin->value-1)/coin->value;
768  if (nrof > coin->nrof) {
769  nrof = coin->nrof;
770  }
771  coin->nrof -= nrof;
772  add_value(coin_objs, nrof*coin->value);
773 
774  remain = remove_value(coin_objs, remain);
775  }
776 
777  /* re-insert remaining coins into player */
778  insert_objects(pl, pouch, coin_objs, NUM_COINS);
779  insert_objects(pl, pouch, other_money, other_money_len);
780 
781  return(remain);
782 }
783 
800 static void count_unpaid(object *pl, object *item, int *unpaid_count, uint64_t *unpaid_price, uint32_t *coincount) {
801  int i;
802 
804  if (QUERY_FLAG(item, FLAG_UNPAID)) {
805  (*unpaid_count)++;
806  (*unpaid_price) += shop_price_buy(item, pl);
807  }
808  /* Merely converting the player's monetary wealth won't do.
809  * If we did that, we could print the wrong numbers for the
810  * coins, so we count the money instead.
811  */
812  for (i = 0; i < NUM_COINS; i++)
813  if (!strcmp(coins[i], item->arch->name)) {
814  coincount[i] += item->nrof;
815  break;
816  }
817  if (item->inv)
818  count_unpaid(pl, item->inv, unpaid_count, unpaid_price, coincount);
820 }
821 
834 int can_pay(object *pl) {
835  int unpaid_count = 0, i;
836  uint64_t unpaid_price = 0;
837  uint64_t player_wealth = query_money(pl);
838  uint32_t coincount[NUM_COINS];
839 
840  if (!pl || pl->type != PLAYER) {
841  LOG(llevError, "can_pay(): called against something that isn't a player\n");
842  return 0;
843  }
844 
845  for (i = 0; i < NUM_COINS; i++)
846  coincount[i] = 0;
847 
848  count_unpaid(pl, pl->inv, &unpaid_count, &unpaid_price, coincount);
849 
850  if (unpaid_price > player_wealth) {
851  char buf[MAX_BUF], coinbuf[MAX_BUF];
852  int denominations = 0;
853  char *value = cost_str(unpaid_price);
854 
855  snprintf(buf, sizeof(buf), "You have %d unpaid items that would cost you %s, ", unpaid_count, value);
856  free(value);
857  for (i = 0; i < NUM_COINS; i++) {
858  if (coincount[i] > 0 && coins[i]) {
859  if (denominations == 0)
860  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "but you only have");
861  denominations++;
862  snprintf(coinbuf, sizeof(coinbuf), " %u %s,", coincount[i], find_archetype(coins[i])->clone.name_pl);
863  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s", coinbuf);
864  }
865  }
866  if (denominations == 0)
867  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "but you don't have any money.");
868  else if (denominations > 1)
869  make_list_like(buf);
871  MSG_TYPE_SHOP_PAYMENT, buf);
872  return 0;
873  } else
874  return 1;
875 }
876 
877 int shop_pay_unpaid(object *pl, object *op) {
878  char name_op[MAX_BUF];
879  int ret = 1;
880 
881  if (op != NULL && op->inv)
882  ret = shop_pay_unpaid(pl, op->inv);
883 
884  if (!ret)
885  return 0;
886 
887  if (op != NULL && op->below)
888  ret = shop_pay_unpaid(pl, op->below);
889 
890  if (!ret)
891  return 0;
892 
893  if (op != NULL && QUERY_FLAG(op, FLAG_UNPAID)) {
894  uint64_t price = shop_price_buy(op, pl);
895  if (!pay_for_item(op, pl)) {
896  uint64_t i = price - query_money(pl);
897  char *missing = cost_str(i);
898 
899  CLEAR_FLAG(op, FLAG_UNPAID);
900  query_name(op, name_op, MAX_BUF);
903  "You lack %s to buy %s.",
904  missing, name_op);
905  free(missing);
906  SET_FLAG(op, FLAG_UNPAID);
907  return 0;
908  } else {
909  object *tmp;
910  char *value = cost_str(price);
911 
912  CLEAR_FLAG(op, FLAG_UNPAID);
914  query_name(op, name_op, MAX_BUF);
917  "You paid %s for %s.",
918  value, name_op);
919  free(value);
920  tmp = object_merge(op, NULL);
921  if (pl->type == PLAYER && !tmp) {
922  /* If item wasn't merged we update it. If merged, object_merge() handled everything for us. */
924  }
925  }
926  }
927  return 1;
928 }
929 
943 void sell_item(object *op, object *pl) {
944  object *tmp;
945  archetype *at;
946  char obj_name[MAX_BUF];
947 
948  query_name(op, obj_name, MAX_BUF);
949 
950  if (pl == NULL || pl->type != PLAYER) {
951  LOG(llevDebug, "Object other than player tried to sell something.\n");
952  return;
953  }
954 
955  if (execute_event(op, EVENT_SELLING, pl, NULL, NULL, SCRIPT_FIX_ALL) != 0)
956  return;
957 
958  if (op->custom_name)
960 
961  uint64_t price = shop_price_sell(op, pl);
962  if (price == 0) {
965  "We're not interested in %s.",
966  obj_name);
967  return;
968  }
969 
970  /* We compare the price with the one for a player
971  * without bargaining skill.
972  * This determins the amount of exp (if any) gained for bargaining.
973  * exp/10 -> 1 for each gold coin
974  */
975  int64_t extra_gain = price - price_base(op);
976  if (extra_gain > 0) {
977  change_exp(pl, extra_gain/10, "bargaining", SK_EXP_NONE);
978  }
979 
980  char *value_str = cost_str(price);
982  "You receive %s for %s.", value_str, obj_name);
983  free(value_str);
984 
985  for (int count = LARGEST_COIN_GIVEN; coins[count] != NULL; count++) {
986  at = find_archetype(coins[count]);
987  if (at == NULL)
988  LOG(llevError, "Could not find %s archetype\n", coins[count]);
989  else if ((price/at->clone.value) > 0) {
990  FOR_INV_PREPARE(pl, pouch) {
991  if (pouch->type == CONTAINER
992  && QUERY_FLAG(pouch, FLAG_APPLIED)
993  && pouch->race
994  && strstr(pouch->race, "gold")) {
995  int w = at->clone.weight*(100-pouch->stats.Str)/100;
996  int n = price/at->clone.value;
997 
998  if (w == 0)
999  w = 1; /* Prevent divide by zero */
1000  if (n > 0
1001  && (!pouch->weight_limit || pouch->carrying+w <= pouch->weight_limit)) {
1002  if (pouch->weight_limit
1003  && (pouch->weight_limit-pouch->carrying)/w < n)
1004  n = (pouch->weight_limit-pouch->carrying)/w;
1005 
1006  tmp = object_new();
1007  object_copy(&at->clone, tmp);
1008  tmp->nrof = n;
1009  price -= (uint64_t)tmp->nrof*(uint64_t)tmp->value;
1010  tmp = object_insert_in_ob(tmp, pouch);
1011  esrv_update_item(UPD_WEIGHT, pl, pl);
1012  }
1013  }
1014  } FOR_INV_FINISH();
1015  if (price/at->clone.value > 0) {
1016  tmp = object_new();
1017  object_copy(&at->clone, tmp);
1018  tmp->nrof = price/tmp->value;
1019  price -= (uint64_t)tmp->nrof*(uint64_t)tmp->value;
1020  tmp = object_insert_in_ob(tmp, pl);
1021  esrv_update_item(UPD_WEIGHT, pl, pl);
1022  }
1023  }
1024  }
1025 
1026  if (price != 0) {
1027  LOG(llevError, "Warning - payment not zero: %" PRIo64 "\n", price);
1028  }
1029 
1030  SET_FLAG(op, FLAG_UNPAID);
1031  identify(op);
1032 }
1033 
1047 static double shop_specialisation_ratio(const object *item, const mapstruct *map) {
1048  shopitems *items = map->shopitems;
1049  double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
1050  int i;
1051 
1052  if (item == NULL) {
1053  LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
1054  return 0;
1055  }
1056  if (item->type == (uint8_t)-1) {
1057  LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
1058  /*
1059  * I'm not really sure what the /right/ thing to do here is,
1060  * these types of item shouldn't exist anyway, but returning
1061  * the ratio is probably the best bet.."
1062  */
1063  return ratio;
1064  }
1065  if (map->shopitems) {
1066  for (i = 0; i < items[0].index; i++)
1067  if (items[i].typenum == item->type || (items[i].typenum == -1 && likedness == 0.001))
1068  likedness = items[i].strength/100.0;
1069  }
1070  if (likedness > 1.0) { /* someone has been rather silly with the map headers. */
1071  LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, map->path);
1072  likedness = 1.0;
1073  }
1074  if (likedness < -1.0) {
1075  LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, map->path);
1076  likedness = -1.0;
1077  }
1078  ratio = ratio+(1.0-ratio)*likedness;
1079  if (ratio <= 0.1)
1080  ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
1081  return ratio;
1082 }
1083 
1092 static double shop_greed(const mapstruct *map) {
1093  double greed = 1.0;
1094 
1095  if (map->shopgreed)
1096  return map->shopgreed;
1097  return greed;
1098 }
1099 
1100 double shop_approval(const mapstruct *map, const object *player) {
1101  double approval = 1.0;
1102 
1103  if (map->shoprace) {
1104  approval = NEUTRAL_RATIO;
1105  if (player->race && !strcmp(player->race, map->shoprace))
1106  approval = 1.0;
1107  }
1108  return approval;
1109 }
1110 
1130 static uint64_t value_limit(uint64_t val, int quantity, const object *who, int isshop) {
1131  uint64_t newval, unit_price;
1132  mapstruct *map;
1133 
1134  unit_price = val/quantity;
1135  if (!isshop || !who) {
1136  if (unit_price > 10000)
1137  newval = 8000+isqrt(unit_price)*20;
1138  else
1139  newval = unit_price;
1140  } else {
1141  if (!who->map) {
1142  LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name);
1143  return val;
1144  }
1145  map = who->map;
1146  if (map->shopmin && unit_price < map->shopmin)
1147  return 0;
1148  else if (map->shopmax && unit_price > map->shopmax/2)
1149  newval = MIN((map->shopmax/2)+isqrt(unit_price-map->shopmax/2), map->shopmax);
1150  else if (unit_price > 10000)
1151  newval = 8000+isqrt(unit_price)*20;
1152  else
1153  newval = unit_price;
1154  }
1155  newval *= quantity;
1156  return newval;
1157 }
1158 
1159 int shop_describe(const object *op) {
1160  mapstruct *map = op->map;
1161  /*shopitems *items=map->shopitems;*/
1162  int pos = 0, i;
1163  double opinion = 0;
1164  char tmp[MAX_BUF] = "\0", *value;
1165 
1166  if (op->type != PLAYER)
1167  return 0;
1168 
1169  /*check if there is a shop specified for this map */
1170  if (map->shopitems
1171  || map->shopgreed
1172  || map->shoprace
1173  || map->shopmin
1174  || map->shopmax) {
1176  "From looking at the nearby shop you determine that it trades in:");
1177 
1178  if (map->shopitems) {
1179  for (i = 0; i < map->shopitems[0].index; i++) {
1180  if (map->shopitems[i].name && map->shopitems[i].strength > 10) {
1181  snprintf(tmp+pos, sizeof(tmp)-pos, "%s, ", map->shopitems[i].name_pl);
1182  pos += strlen(tmp+pos);
1183  }
1184  }
1185  }
1186  if (!pos)
1187  strcpy(tmp, "a little of everything.");
1188 
1189  /* format the string into a list */
1190  make_list_like(tmp);
1191  draw_ext_info(NDI_UNIQUE, 0, op,
1193 
1194  if (map->shopmax) {
1195  value = cost_str(map->shopmax);
1198  "It won't trade for items above %s.",
1199  value);
1200  free(value);
1201  }
1202 
1203  if (map->shopmin) {
1204  value = cost_str(map->shopmin);
1207  "It won't trade in items worth less than %s.",
1208  value);
1209  free(value);
1210  }
1211 
1212  if (map->shopgreed) {
1213  if (map->shopgreed > 2.0)
1214  draw_ext_info(NDI_UNIQUE, 0, op,
1216  "It tends to overcharge massively.");
1217  else if (map->shopgreed > 1.5)
1218  draw_ext_info(NDI_UNIQUE, 0, op,
1220  "It tends to overcharge substantially.");
1221  else if (map->shopgreed > 1.1)
1222  draw_ext_info(NDI_UNIQUE, 0, op,
1224  "It tends to overcharge slightly.");
1225  else if (map->shopgreed < 0.9)
1226  draw_ext_info(NDI_UNIQUE, 0, op,
1228  "It tends to undercharge.");
1229  }
1230  if (map->shoprace) {
1231  opinion = shop_approval(map, op);
1232  if (opinion > 0.8)
1233  draw_ext_info(NDI_UNIQUE, 0, op,
1235  "You think the shopkeeper likes you.");
1236  else if (opinion > 0.5)
1237  draw_ext_info(NDI_UNIQUE, 0, op,
1239  "The shopkeeper seems unconcerned by you.");
1240  else
1241  draw_ext_info(NDI_UNIQUE, 0, op,
1243  "The shopkeeper seems to have taken a dislike to you.");
1244  }
1246  "There is no shop nearby.");
1247 
1248  return 1;
1249 }
1250 
1254 static bool coords_in_shop(mapstruct *map, int x, int y) {
1255  FOR_MAP_PREPARE(map, x, y, floor)
1256  if (floor->type == SHOP_FLOOR) return true;
1257  FOR_MAP_FINISH();
1258  return false;
1259 }
1260 
1261 bool shop_contains(object *ob) {
1262  if (!ob->map) return 0;
1263  return coords_in_shop(ob->map, ob->x, ob->y);
1264 }
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:66
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:299
static const char *const coins[]
Definition: shop.c:57
uint64_t query_money(const object *op)
Definition: shop.c:481
static StringBuffer * real_money_value(const object *coin, StringBuffer *buf)
Definition: shop.c:408
const char * race
Definition: object.h:318
uint64_t shop_price_sell(const object *tmp, object *who)
Definition: shop.c:246
#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:1254
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:1047
#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:1130
double shop_approval(const mapstruct *map, const object *player)
Definition: shop.c:1100
uint64_t shop_price_buy(const object *tmp, object *who)
Definition: shop.c:188
object clone
Definition: object.h:470
bool shop_contains(object *ob)
Definition: shop.c:1261
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:800
#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:663
#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:834
uint64_t price_approx(const object *tmp, object *who)
Definition: shop.c:124
const typedata * get_typedata(int itemtype)
Definition: item.c:335
static void add_value(object *coin_objs[], int64_t value)
Definition: shop.c:639
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:551
static int64_t remove_value(object *coin_objs[], int64_t remain)
Definition: shop.c:598
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:333
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:420
static double shop_greed(const mapstruct *map)
Definition: shop.c:1092
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:512
#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:877
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:694
static float shop_buy_multiplier(int charisma)
Definition: shop.c:165
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:416
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:943
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:184
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:1159
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