Crossfire Server, Trunk  R21524
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 *obj) {
71  // When there are zero objects, there is really one.
72  const int number = NROF(obj);
73  const bool identified = is_identified(obj);
74  uint64_t val = (uint64_t)obj->value * number;
75 
76  // Objects with price adjustments skip the rest of the calculations.
77  const char *key = object_get_value(obj, "price_adjustment");
78  if (key != NULL) {
79  float ratio = atof(key);
80  return val * ratio;
81  }
82 
83  // Money and gems have fixed prices at shops.
84  if (obj->type == MONEY || obj->type == GEM) {
85  return val;
86  }
87 
88  // If unidentified, price item based on its archetype.
89  if (!identified && obj->arch) {
90  val = obj->arch->clone.value * number;
91  }
92 
98  if (QUERY_FLAG(obj, FLAG_BLESSED)){
99  val *= 1.15;
100  } else if (QUERY_FLAG(obj, FLAG_CURSED)) {
101  val *= 0.8;
102  } else if (QUERY_FLAG(obj, FLAG_DAMNED)) {
103  val *= 0.6;
104  }
105 
106  // If an item is identified to have an enchantment above its archetype
107  // enchantment, increase price exponentially.
108  if (obj->arch != NULL && identified) {
109  int diff = obj->magic - obj->arch->clone.magic;
110  val *= pow(1.15, diff);
111  }
112 
113  // FIXME: Is the 'baseline' 50 charges per wand?
114  if (obj->type == WAND) {
115  val *= obj->stats.food / 50.0;
116  }
117 
118  /* we need to multiply these by 4.0 to keep buy costs roughly the same
119  * (otherwise, you could buy a potion of charisma for around 400 pp.
120  * Arguable, the costs in the archetypes should be updated to better
121  * reflect values (potion charisma list for 1250 gold)
122  */
123  val *= 4; // FIXME
124 
125  return val;
126 }
127 
128 uint64_t price_approx(const object *tmp, object *who) {
129  uint64_t val = price_base(tmp);
130 
131  /* If we are approximating, then the value returned should
132  * be allowed to be wrong however merely using a random number
133  * each time will not be sufficient, as then multiple examinations
134  * would give different answers, so we'll use the count instead.
135  * By taking the sine of the count, a value between -1 and 1 is
136  * generated, we then divide by the square root of the bargaining
137  * skill and the appropriate identification skills, so that higher
138  * level players get better estimates. (We need a +1 there to
139  * prevent dividing by zero.)
140  */
141  const typedata *tmptype = get_typedata(tmp->type);
142  int lev_identify = 0;
143 
144  if (tmptype) {
145  int idskill1 = tmptype->identifyskill;
146  if (idskill1) {
147  int idskill2 = tmptype->identifyskill2;
148  if (find_skill_by_number(who, idskill1)) {
149  lev_identify = find_skill_by_number(who, idskill1)->level;
150  }
151  if (idskill2 && find_skill_by_number(who, idskill2)) {
152  lev_identify += find_skill_by_number(who, idskill2)->level;
153  }
154  }
155  } else {
156  LOG(llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->name);
157  }
158  val += val * (sin(tmp->count) / sqrt(lev_identify * 3 + 1.0));
159 
160  return val;
161 }
162 
169 static float shop_buy_multiplier(int charisma) {
170  float multiplier = 1 / (0.38 * pow(1.06, charisma));
171 
172  if (multiplier > 2) {
173  return 2;
174  } else if (multiplier < 0.5) {
175  return 0.5;
176  } else {
177  return multiplier;
178  }
179 }
180 
188 static float shop_bargain_multiplier(int lev_bargain) {
189  return 1 - 0.5 * lev_bargain / settings.max_level;
190 }
191 
192 uint64_t shop_price_buy(const object *tmp, object *who) {
193  assert(who != NULL && who->type == PLAYER);
194  uint64_t val = price_base(tmp);
195 
196  const char *key = object_get_value(tmp, "price_adjustment_buy");
197  if (key != NULL) {
198  float ratio = atof(key);
199  return val * ratio;
200  }
201 
202  if (tmp->type == GEM) {
203  return 1.03 * val;
204  }
205 
206  // Further reduce the sell price of cursed and damned items.
207  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
208  val *= 0.8;
209  }
210 
211  int bargain_level = 0;
213  bargain_level = find_skill_by_number(who, SK_BARGAINING)->level;
214  }
215 
216  float multiplier = shop_bargain_multiplier(bargain_level);
217  multiplier *= shop_buy_multiplier(who->stats.Cha);
218 
219  // Limit buy price multiplier to 0.5, no matter what.
220  val *= multiplier > 0.5 ? multiplier : 0.5;
221 
222  /*
223  * When buying, if the item was sold by another player, it is
224  * ok to let the item be sold cheaper, according to the
225  * specialisation of the shop. If a player sold an item here,
226  * then his sale price was multiplied by the specialisation
227  * ratio, to do the same to the buy price will not generate
228  * extra money. However, the same is not true of generated
229  * items, these have to /divide/ by the specialisation, so
230  * that the price is never less than what they could
231  * be sold for (otherwise players could camp map resets to
232  * make money).
233  * In game terms, a non-specialist shop might not recognise
234  * the true value of the items it sells (much like how people
235  * sometimes find antiques in a junk shop in real life).
236  */
237  if (QUERY_FLAG(tmp, FLAG_PLAYER_SOLD)) {
238  val = (int64_t)val*shop_greed(who->map)
239  *shop_specialisation_ratio(tmp, who->map)
240  /shop_approval(who->map, who);
241  } else {
242  val = (int64_t)val*shop_greed(who->map)
243  /(shop_specialisation_ratio(tmp, who->map)
244  *shop_approval(who->map, who));
245  }
246 
247  return val;
248 }
249 
250 uint64_t shop_price_sell(const object *tmp, object *who) {
251  assert(who != NULL && who->type == PLAYER);
252  uint64_t val = price_base(tmp);
253 
254  const char *key = object_get_value(tmp, "price_adjustment_sell");
255  if (key != NULL) {
256  float ratio = atof(key);
257  return val * ratio;
258  }
259 
260  if (tmp->type == GEM) {
261  return 0.97 * val;
262  }
263 
264  // Shops value unidentified items less.
265  if (!is_identified(tmp)) {
266  if (tmp->arch != NULL) {
267  // Unidentified standard objects are only worth a little less.
268  if (QUERY_FLAG(tmp, FLAG_BEEN_APPLIED)) {
269  val *= 0.85;
270  } else {
271  val *= 0.70;
272  }
273  } else {
274  // No archetype, so probably an artifact.
275  val /= 2;
276  }
277  }
278 
279  // Selling to shops yields roughly 50% of the base price.
280  val /= 2;
281 
282  /* Limit amount of money you can get for really great items. */
283  int number = NROF(tmp);
284  val = value_limit(val, number, who, 1);
285 
286  val = (int64_t)val*shop_specialisation_ratio(tmp, who->map)*
287  shop_approval(who->map, who)/shop_greed(who->map);
288  return val;
289 }
290 
302 static archetype *find_next_coin(uint64_t c, int *cointype) {
303  archetype *coin;
304 
305  do {
306  if (coins[*cointype] == NULL)
307  return NULL;
308  coin = find_archetype(coins[*cointype]);
309  if (coin == NULL)
310  return NULL;
311  *cointype += 1;
312  } while (coin->clone.value > (int64_t) c);
313 
314  return coin;
315 }
316 
334 char* cost_string_from_value(uint64_t cost, int largest_coin) {
335  archetype *coin, *next_coin;
336  uint32_t num;
337  int cointype = largest_coin;
338 
339  if (cointype < 0)
340  cointype = 0;
341  else if (cointype >= NUM_COINS)
342  cointype = NUM_COINS - 1;
343 
345  coin = find_next_coin(cost, &cointype);
346  if (coin == NULL) {
347  stringbuffer_append_string(buf, "nothing");
348  goto done;
349  }
350 
351  num = cost/coin->clone.value;
352  /* so long as nrof is 32 bit, this is true.
353  * If it takes more coins than a person can possibly carry, this
354  * is basically true.
355  */
356  if ((cost/coin->clone.value) > UINT32_MAX) {
357  stringbuffer_append_string(buf, "an unimaginable sum of money.");
358  goto done;
359  }
360 
361  cost -= (uint64_t)num*(uint64_t)coin->clone.value;
362  if (num == 1)
363  stringbuffer_append_printf(buf, "1 %s", coin->clone.name);
364  else
365  stringbuffer_append_printf(buf, "%u %ss", num, coin->clone.name);
366 
367  next_coin = find_next_coin(cost, &cointype);
368  if (next_coin == NULL)
369  goto done;
370 
371  do {
372  coin = next_coin;
373  num = cost/coin->clone.value;
374  cost -= (uint64_t)num*(uint64_t)coin->clone.value;
375 
376  if (cost == 0)
377  next_coin = NULL;
378  else
379  next_coin = find_next_coin(cost, &cointype);
380 
381  if (next_coin) {
382  /* There will be at least one more string to add to the list,
383  * use a comma.
384  */
385  stringbuffer_append_string(buf, ", ");
386  } else {
387  stringbuffer_append_string(buf, " and ");
388  }
389  if (num == 1)
390  stringbuffer_append_printf(buf, "1 %s", coin->clone.name);
391  else
392  stringbuffer_append_printf(buf, "%u %ss", num, coin->clone.name);
393  } while (next_coin);
394 
395 done:
396  return stringbuffer_finish(buf);
397 }
398 
409 static StringBuffer *real_money_value(const object *coin, StringBuffer *buf) {
410  assert(coin->type == MONEY);
411  assert(buf);
412 
413  stringbuffer_append_printf(buf, "%ld %s", (long)coin->nrof, coin->nrof == 1 ? coin->name : coin->name_pl);
414  return buf;
415 }
416 
417 char *cost_str(uint64_t cost) {
419 }
420 
421 char *cost_approx_str(const object *tmp, object *who) {
422  uint64_t approx_val = price_approx(tmp, who);
423  int idskill1 = 0;
424  int idskill2 = 0;
425  const typedata *tmptype;
426 
428 
429  /* money it's pretty hard to not give the exact price, so skip all logic and just return the real value. */
430  if (tmp->type == MONEY) {
431  return stringbuffer_finish(real_money_value(tmp, buf));
432  }
433 
434  tmptype = get_typedata(tmp->type);
435  if (tmptype) {
436  idskill1 = tmptype->identifyskill;
437  idskill2 = tmptype->identifyskill2;
438  }
439 
440  /* we show an approximate price if
441  * 1) we are approximating
442  * 2) there either is no id skill(s) for the item, or we don't have them
443  * 3) we don't have bargaining skill either
444  */
445  if (!idskill1 || !find_skill_by_number(who, idskill1)) {
446  if (!idskill2 || !find_skill_by_number(who, idskill2)) {
447  if (!find_skill_by_number(who, SK_BARGAINING)) {
448  int num;
449  int cointype = LARGEST_COIN_GIVEN;
450  archetype *coin = find_next_coin(approx_val, &cointype);
451 
452  if (coin == NULL) {
453  stringbuffer_append_string(buf, "nothing");
454  return stringbuffer_finish(buf);
455  }
456 
457  num = approx_val/coin->clone.value;
458  if (num == 1)
459  stringbuffer_append_printf(buf, "about one %s", coin->clone.name);
460  else if (num < 5)
461  stringbuffer_append_printf(buf, "a few %s", coin->clone.name_pl);
462  else if (num < 10)
463  stringbuffer_append_printf(buf, "several %s", coin->clone.name_pl);
464  else if (num < 25)
465  stringbuffer_append_printf(buf, "a moderate amount of %s", coin->clone.name_pl);
466  else if (num < 100)
467  stringbuffer_append_printf(buf, "lots of %s", coin->clone.name_pl);
468  else if (num < 1000)
469  stringbuffer_append_printf(buf, "a great many %s", coin->clone.name_pl);
470  else
471  stringbuffer_append_printf(buf, "a vast quantity of %s", coin->clone.name_pl);
472  return stringbuffer_finish(buf);
473  }
474  }
475  }
476 
477  // If we get here, return the price we guessed.
478  stringbuffer_delete(buf);
479  return cost_str(approx_val);
480 }
481 
482 uint64_t query_money(const object *op) {
483  uint64_t total = 0;
484 
485  if (op->type != PLAYER && op->type != CONTAINER) {
486  LOG(llevError, "Query money called with non player/container\n");
487  return 0;
488  }
489  FOR_INV_PREPARE(op, tmp) {
490  if (tmp->type == MONEY) {
491  total += (uint64_t)tmp->nrof*(uint64_t)tmp->value;
492  } else if (tmp->type == CONTAINER
493  && QUERY_FLAG(tmp, FLAG_APPLIED)
494  && (tmp->race == NULL || strstr(tmp->race, "gold"))) {
495  total += query_money(tmp);
496  }
497  } FOR_INV_FINISH();
498  return total;
499 }
500 
513 int pay_for_amount(uint64_t to_pay, object *pl) {
514  if (to_pay == 0)
515  return 1;
516  if (to_pay > query_money(pl))
517  return 0;
518 
519  to_pay = pay_from_container(pl, pl, to_pay);
520 
521  FOR_INV_PREPARE(pl, pouch) {
522  if (to_pay <= 0)
523  break;
524  if (pouch->type == CONTAINER
525  && QUERY_FLAG(pouch, FLAG_APPLIED)
526  && (pouch->race == NULL || strstr(pouch->race, "gold"))) {
527  to_pay = pay_from_container(pl, pouch, to_pay);
528  }
529  } FOR_INV_FINISH();
530  if (to_pay > 0) {
531  LOG(llevError, "pay_for_amount: Cannot remove enough money -- %"FMT64U" remains\n", to_pay);
532  }
533 
534  fix_object(pl);
535  return 1;
536 }
537 
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 
691 static uint64_t pay_from_container(object *pl, object *pouch, uint64_t to_pay) {
692  size_t i;
693  int64_t remain;
694  object *coin_objs[NUM_COINS];
695  object *other_money[16]; /* collects MONEY objects not matching coins[] */
696  size_t other_money_len; /* number of allocated entries in other_money[] */
697  archetype *at;
698 
699  if (pouch->type != PLAYER && pouch->type != CONTAINER)
700  return to_pay;
701 
702  remain = to_pay;
703  for (i = 0; i < NUM_COINS; i++)
704  coin_objs[i] = NULL;
705 
706  /* This hunk should remove all the money objects from the player/container */
707  other_money_len = 0;
708  FOR_INV_PREPARE(pouch, tmp) {
709  if (tmp->type == MONEY) {
710  for (i = 0; i < NUM_COINS; i++) {
711  if (!strcmp(coins[NUM_COINS-1-i], tmp->arch->name)
712  && (tmp->value == tmp->arch->clone.value)) {
713  /* This should not happen, but if it does, just
714  * merge the two.
715  */
716  if (coin_objs[i] != NULL) {
717  LOG(llevError, "%s has two money entries of (%s)\n", pouch->name, coins[NUM_COINS-1-i]);
718  object_remove(tmp);
719  coin_objs[i]->nrof += tmp->nrof;
721  } else {
722  object_remove(tmp);
723  coin_objs[i] = tmp;
724  }
725  break;
726  }
727  }
728  if (i == NUM_COINS) {
729  if (other_money_len >= sizeof(other_money)/sizeof(*other_money)) {
730  LOG(llevError, "pay_for_item: Cannot store non-standard money object %s\n", tmp->arch->name);
731  } else {
732  object_remove(tmp);
733  other_money[other_money_len++] = tmp;
734  }
735  }
736  }
737  } FOR_INV_FINISH();
738 
739  /* Fill in any gaps in the coin_objs array - needed to make change. */
740  /* Note that the coin_objs array goes from least value to greatest value */
741  for (i = 0; i < NUM_COINS; i++)
742  if (coin_objs[i] == NULL) {
743  at = find_archetype(coins[NUM_COINS-1-i]);
744  if (at == NULL) {
745  continue;
746  }
747  coin_objs[i] = object_new();
748  object_copy(&at->clone, coin_objs[i]);
749  coin_objs[i]->nrof = 0;
750  }
751 
752  /* Try to pay from standard coins first. */
753  remain = remove_value(coin_objs, remain);
754 
755  /* Now pay from non-standard coins until all is paid. */
756  for (i = 0; i < other_money_len && remain > 0; i++) {
757  uint32_t nrof;
758  object *coin;
759 
760  coin = other_money[i];
761 
762  /* Find the minimal number of coins to use. This prevents converting
763  * excess non-standard coins to standard money.
764  */
765  nrof = (remain+coin->value-1)/coin->value;
766  if (nrof > coin->nrof) {
767  nrof = coin->nrof;
768  }
769  coin->nrof -= nrof;
770  add_value(coin_objs, nrof*coin->value);
771 
772  remain = remove_value(coin_objs, remain);
773  }
774 
775  /* re-insert remaining coins into player */
776  insert_objects(pl, pouch, coin_objs, NUM_COINS);
777  insert_objects(pl, pouch, other_money, other_money_len);
778 
779  return(remain);
780 }
781 
796 static void count_unpaid(object *pl, object *item, int *unpaid_count, uint64_t *unpaid_price, uint32_t *coincount) {
797  int i;
798 
800  if (QUERY_FLAG(item, FLAG_UNPAID)) {
801  (*unpaid_count)++;
802  (*unpaid_price) += shop_price_buy(item, pl);
803  }
804  /* Merely converting the player's monetary wealth won't do.
805  * If we did that, we could print the wrong numbers for the
806  * coins, so we count the money instead.
807  */
808  for (i = 0; i < NUM_COINS; i++)
809  if (!strcmp(coins[i], item->arch->name)) {
810  coincount[i] += item->nrof;
811  break;
812  }
813  if (item->inv)
814  count_unpaid(pl, item->inv, unpaid_count, unpaid_price, coincount);
816 }
817 
830 int can_pay(object *pl) {
831  int unpaid_count = 0, i;
832  uint64_t unpaid_price = 0;
833  uint64_t player_wealth = query_money(pl);
834  uint32_t coincount[NUM_COINS];
835 
836  if (!pl || pl->type != PLAYER) {
837  LOG(llevError, "can_pay(): called against something that isn't a player\n");
838  return 0;
839  }
840 
841  for (i = 0; i < NUM_COINS; i++)
842  coincount[i] = 0;
843 
844  count_unpaid(pl, pl->inv, &unpaid_count, &unpaid_price, coincount);
845 
846  if (unpaid_price > player_wealth) {
847  char buf[MAX_BUF], coinbuf[MAX_BUF];
848  int denominations = 0;
849  char *value = cost_str(unpaid_price);
850 
851  snprintf(buf, sizeof(buf), "You have %d unpaid items that would cost you %s, ", unpaid_count, value);
852  free(value);
853  for (i = 0; i < NUM_COINS; i++) {
854  if (coincount[i] > 0 && coins[i]) {
855  if (denominations == 0)
856  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "but you only have");
857  denominations++;
858  archetype *arch = find_archetype(coins[i]);
859  if (arch != NULL)
860  {
861  snprintf(coinbuf, sizeof(coinbuf), " %u %s,", coincount[i], arch->clone.name_pl);
862  snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s", coinbuf);
863  }
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 
883 int shop_pay_unpaid(object *pl, object *op) {
884  char name_op[MAX_BUF];
885  int ret = 1;
886 
887  if (op != NULL && op->inv)
888  ret = shop_pay_unpaid(pl, op->inv);
889 
890  if (!ret)
891  return 0;
892 
893  if (op != NULL && op->below)
894  ret = shop_pay_unpaid(pl, op->below);
895 
896  if (!ret)
897  return 0;
898 
899  if (op != NULL && QUERY_FLAG(op, FLAG_UNPAID)) {
900  uint64_t price = shop_price_buy(op, pl);
901  if (!pay_for_item(op, pl)) {
902  uint64_t i = price - query_money(pl);
903  char *missing = cost_str(i);
904 
905  CLEAR_FLAG(op, FLAG_UNPAID);
906  query_name(op, name_op, MAX_BUF);
909  "You lack %s to buy %s.",
910  missing, name_op);
911  free(missing);
912  SET_FLAG(op, FLAG_UNPAID);
913  return 0;
914  } else {
915  // Event hook for buying an item.
916  // TODO: Figure out how to pass in the shop owner for player shops.
917  if (execute_event(op, EVENT_BOUGHT, pl, NULL, NULL, SCRIPT_FIX_ALL) != 0)
918  return 0;
919  object *tmp;
920  char *value = cost_str(price);
921 
922  CLEAR_FLAG(op, FLAG_UNPAID);
924  query_name(op, name_op, MAX_BUF);
927  "You paid %s for %s.",
928  value, name_op);
929  free(value);
930  tmp = object_merge(op, NULL);
931  if (pl->type == PLAYER && !tmp) {
932  /* If item wasn't merged we update it. If merged, object_merge() handled everything for us. */
934  }
935  }
936  }
937  return 1;
938 }
939 
951 void sell_item(object *op, object *pl) {
952  object *tmp;
953  archetype *at;
954  char obj_name[MAX_BUF];
955 
956  query_name(op, obj_name, MAX_BUF);
957 
958  if (pl == NULL || pl->type != PLAYER) {
959  LOG(llevDebug, "Object other than player tried to sell something.\n");
960  return;
961  }
962 
963  if (execute_event(op, EVENT_SELLING, pl, NULL, NULL, SCRIPT_FIX_ALL) != 0)
964  return;
965 
966  if (op->custom_name)
968 
969  uint64_t price = shop_price_sell(op, pl);
970  if (price == 0) {
973  "We're not interested in %s.",
974  obj_name);
975  return;
976  }
977 
978  /* We compare the price with the one for a player
979  * without bargaining skill.
980  * This determins the amount of exp (if any) gained for bargaining.
981  * exp/10 -> 1 for each gold coin
982  */
983  int64_t extra_gain = price - price_base(op);
984  if (extra_gain > 0) {
985  change_exp(pl, extra_gain/10, "bargaining", SK_EXP_NONE);
986  }
987 
988  char *value_str = cost_str(price);
990  "You receive %s for %s.", value_str, obj_name);
991  free(value_str);
992 
993  for (int count = LARGEST_COIN_GIVEN; coins[count] != NULL; count++) {
994  at = find_archetype(coins[count]);
995  if (at == NULL)
996  LOG(llevError, "Could not find %s archetype\n", coins[count]);
997  else if ((price/at->clone.value) > 0) {
998  FOR_INV_PREPARE(pl, pouch) {
999  if (pouch->type == CONTAINER
1000  && QUERY_FLAG(pouch, FLAG_APPLIED)
1001  && pouch->race
1002  && strstr(pouch->race, "gold")) {
1003  int w = at->clone.weight*(100-pouch->stats.Str)/100;
1004  int n = price/at->clone.value;
1005 
1006  if (w == 0)
1007  w = 1; /* Prevent divide by zero */
1008  if (n > 0
1009  && (!pouch->weight_limit || pouch->carrying+w <= pouch->weight_limit)) {
1010  if (pouch->weight_limit
1011  && (pouch->weight_limit-pouch->carrying)/w < n)
1012  n = (pouch->weight_limit-pouch->carrying)/w;
1013 
1014  tmp = object_new();
1015  object_copy(&at->clone, tmp);
1016  tmp->nrof = n;
1017  price -= (uint64_t)tmp->nrof*(uint64_t)tmp->value;
1018  tmp = object_insert_in_ob(tmp, pouch);
1019  esrv_update_item(UPD_WEIGHT, pl, pl);
1020  }
1021  }
1022  } FOR_INV_FINISH();
1023  if (price/at->clone.value > 0) {
1024  tmp = object_new();
1025  object_copy(&at->clone, tmp);
1026  tmp->nrof = price/tmp->value;
1027  price -= (uint64_t)tmp->nrof*(uint64_t)tmp->value;
1028  tmp = object_insert_in_ob(tmp, pl);
1029  esrv_update_item(UPD_WEIGHT, pl, pl);
1030  }
1031  }
1032  }
1033 
1034  if (price != 0) {
1035  LOG(llevError, "Warning - payment not zero: %" PRIo64 "\n", price);
1036  }
1037 
1038  SET_FLAG(op, FLAG_UNPAID);
1039  identify(op);
1040 }
1041 
1055 static double shop_specialisation_ratio(const object *item, const mapstruct *map) {
1056  shopitems *items = map->shopitems;
1057  double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
1058  int i;
1059 
1060  if (item == NULL) {
1061  LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
1062  return 0;
1063  }
1064  if (item->type == (uint8_t)-1) {
1065  LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
1066  /*
1067  * I'm not really sure what the /right/ thing to do here is,
1068  * these types of item shouldn't exist anyway, but returning
1069  * the ratio is probably the best bet.."
1070  */
1071  return ratio;
1072  }
1073  if (map->shopitems) {
1074  for (i = 0; i < items[0].index; i++)
1075  if (items[i].typenum == item->type || (items[i].typenum == -1 && likedness == 0.001))
1076  likedness = items[i].strength/100.0;
1077  }
1078  if (likedness > 1.0) { /* someone has been rather silly with the map headers. */
1079  LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, map->path);
1080  likedness = 1.0;
1081  }
1082  if (likedness < -1.0) {
1083  LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, map->path);
1084  likedness = -1.0;
1085  }
1086  ratio = ratio+(1.0-ratio)*likedness;
1087  if (ratio <= 0.1)
1088  ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
1089  return ratio;
1090 }
1091 
1100 static double shop_greed(const mapstruct *map) {
1101  double greed = 1.0;
1102 
1103  if (map->shopgreed)
1104  return map->shopgreed;
1105  return greed;
1106 }
1107 
1108 double shop_approval(const mapstruct *map, const object *player) {
1109  double approval = 1.0;
1110 
1111  if (map->shoprace) {
1112  approval = NEUTRAL_RATIO;
1113  if (player->race && !strcmp(player->race, map->shoprace))
1114  approval = 1.0;
1115  }
1116  return approval;
1117 }
1118 
1138 static uint64_t value_limit(uint64_t val, int quantity, const object *who, int isshop) {
1139  uint64_t newval, unit_price;
1140  mapstruct *map;
1141 
1142  unit_price = val/quantity;
1143  if (!isshop || !who) {
1144  if (unit_price > 10000)
1145  newval = 8000+isqrt(unit_price)*20;
1146  else
1147  newval = unit_price;
1148  } else {
1149  if (!who->map) {
1150  LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name);
1151  return val;
1152  }
1153  map = who->map;
1154  if (map->shopmin && unit_price < map->shopmin)
1155  return 0;
1156  else if (map->shopmax && unit_price > map->shopmax/2)
1157  newval = MIN((map->shopmax/2)+isqrt(unit_price-map->shopmax/2), map->shopmax);
1158  else if (unit_price > 10000)
1159  newval = 8000+isqrt(unit_price)*20;
1160  else
1161  newval = unit_price;
1162  }
1163  newval *= quantity;
1164  return newval;
1165 }
1166 
1172 int shop_describe(const object *op) {
1173  mapstruct *map = op->map;
1174  /*shopitems *items=map->shopitems;*/
1175  int pos = 0, i;
1176  double opinion = 0;
1177  char tmp[MAX_BUF] = "\0", *value;
1178 
1179  if (op->type != PLAYER)
1180  return 0;
1181 
1182  /*check if there is a shop specified for this map */
1183  if (map->shopitems
1184  || map->shopgreed
1185  || map->shoprace
1186  || map->shopmin
1187  || map->shopmax) {
1189  "From looking at the nearby shop you determine that it trades in:");
1190 
1191  if (map->shopitems) {
1192  for (i = 0; i < map->shopitems[0].index; i++) {
1193  if (map->shopitems[i].name && map->shopitems[i].strength > 10) {
1194  snprintf(tmp+pos, sizeof(tmp)-pos, "%s, ", map->shopitems[i].name_pl);
1195  pos += strlen(tmp+pos);
1196  }
1197  }
1198  }
1199  if (!pos)
1200  strcpy(tmp, "a little of everything.");
1201 
1202  /* format the string into a list */
1203  make_list_like(tmp);
1204  draw_ext_info(NDI_UNIQUE, 0, op,
1206 
1207  if (map->shopmax) {
1208  value = cost_str(map->shopmax);
1211  "It won't trade for items above %s.",
1212  value);
1213  free(value);
1214  }
1215 
1216  if (map->shopmin) {
1217  value = cost_str(map->shopmin);
1220  "It won't trade in items worth less than %s.",
1221  value);
1222  free(value);
1223  }
1224 
1225  if (map->shopgreed) {
1226  if (map->shopgreed > 2.0)
1227  draw_ext_info(NDI_UNIQUE, 0, op,
1229  "It tends to overcharge massively.");
1230  else if (map->shopgreed > 1.5)
1231  draw_ext_info(NDI_UNIQUE, 0, op,
1233  "It tends to overcharge substantially.");
1234  else if (map->shopgreed > 1.1)
1235  draw_ext_info(NDI_UNIQUE, 0, op,
1237  "It tends to overcharge slightly.");
1238  else if (map->shopgreed < 0.9)
1239  draw_ext_info(NDI_UNIQUE, 0, op,
1241  "It tends to undercharge.");
1242  }
1243  if (map->shoprace) {
1244  opinion = shop_approval(map, op);
1245  if (opinion > 0.8)
1246  draw_ext_info(NDI_UNIQUE, 0, op,
1248  "You think the shopkeeper likes you.");
1249  else if (opinion > 0.5)
1250  draw_ext_info(NDI_UNIQUE, 0, op,
1252  "The shopkeeper seems unconcerned by you.");
1253  else
1254  draw_ext_info(NDI_UNIQUE, 0, op,
1256  "The shopkeeper seems to have taken a dislike to you.");
1257  }
1259  "There is no shop nearby.");
1260 
1261  return 1;
1262 }
1263 
1267 static bool coords_in_shop(mapstruct *map, int x, int y) {
1268  FOR_MAP_PREPARE(map, x, y, floor)
1269  if (floor->type == SHOP_FLOOR) return true;
1270  FOR_MAP_FINISH();
1271  return false;
1272 }
1273 
1274 bool shop_contains(object *ob) {
1275  if (!ob->map) return 0;
1276  return coords_in_shop(ob->map, ob->x, ob->y);
1277 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:316
char path[HUGE_BUF]
Definition: map.h:365
Definition: object.h:274
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:696
#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:302
static const char *const coins[]
Definition: shop.c:57
uint64_t query_money(const object *op)
Definition: shop.c:482
static StringBuffer * real_money_value(const object *coin, StringBuffer *buf)
Definition: shop.c:409
const char * race
Definition: object.h:318
uint64_t shop_price_sell(const object *tmp, object *who)
Definition: shop.c:250
#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:1267
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
int16_t max_level
Definition: global.h:304
static double shop_specialisation_ratio(const object *item, const mapstruct *map)
Definition: shop.c:1055
#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:343
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4135
Definition: object.h:137
static uint64_t value_limit(uint64_t val, int quantity, const object *who, int isshop)
Definition: shop.c:1138
static uint32_t NROF(const object *const ob)
Definition: object.h:612
double shop_approval(const mapstruct *map, const object *player)
Definition: shop.c:1108
uint64_t shop_price_buy(const object *tmp, object *who)
Definition: shop.c:192
object clone
Definition: object.h:472
bool shop_contains(object *ob)
Definition: shop.c:1274
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:796
#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:367
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:311
Definition: object.h:467
Definition: object.h:220
#define FOR_OB_AND_BELOW_FINISH()
Definition: define.h:792
#define MIN(x, y)
Definition: compat.h:17
int typenum
Definition: map.h:308
int can_pay(object *pl)
Definition: shop.c:830
uint64_t price_approx(const object *tmp, object *who)
Definition: shop.c:128
const typedata * get_typedata(int itemtype)
Definition: item.c:315
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:1325
int16_t y
Definition: object.h:326
int pay_for_item(object *op, object *pl)
Definition: shop.c:551
int is_identified(const object *op)
Definition: item.c:1313
static int64_t remove_value(object *coin_objs[], int64_t remain)
Definition: shop.c:598
object * object_new(void)
Definition: object.c:1019
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:2601
char * cost_string_from_value(uint64_t cost, int largest_coin)
Definition: shop.c:334
int32_t weight
Definition: object.h:366
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 FOR_INV_FINISH()
Definition: define.h:715
#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:421
static double shop_greed(const mapstruct *map)
Definition: shop.c:1100
struct obj * below
Definition: object.h:287
#define EVENT_BOUGHT
Definition: plugin.h:67
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:272
#define EVENT_SELLING
Definition: plugin.h:74
int pay_for_amount(uint64_t to_pay, object *pl)
Definition: shop.c:513
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:205
#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:2162
#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:883
signed __int64 int64_t
Definition: win32.h:168
int identifyskill2
Definition: define.h:94
#define FOR_MAP_FINISH()
Definition: define.h:768
#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:691
static float shop_buy_multiplier(int charisma)
Definition: shop.c:169
const char * custom_name
Definition: object.h:434
tag_t count
Definition: object.h:299
const char * name_pl
Definition: map.h:307
living stats
Definition: object.h:369
struct archt * arch
Definition: object.h:414
#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:417
uint8_t type
Definition: object.h:339
struct Settings settings
Definition: init.c:39
#define SK_EXP_NONE
Definition: skills.h:80
Definition: map.h:305
#define FLAG_APPLIED
Definition: define.h:235
void sell_item(object *op, object *pl)
Definition: shop.c:951
object * object_merge(object *op, object *top)
Definition: object.c:1799
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: main.c:365
#define UPD_NAME
Definition: newclient.h:293
#define FOR_OB_AND_BELOW_PREPARE(op_)
Definition: define.h:788
#define SPECIALISATION_EFFECT
Definition: shop.c:39
object * identify(object *op)
Definition: item.c:1383
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
static float shop_bargain_multiplier(int lev_bargain)
Definition: shop.c:188
void object_copy(const object *src_ob, object *dest_ob)
Definition: object.c:826
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:761
struct shopitem * shopitems
Definition: map.h:356
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:580
char * shoprace
Definition: map.h:357
object * find_skill_by_number(object *who, int skillno)
Definition: main.c:352
Definition: map.h:325
Definition: object.h:167
#define NEUTRAL_RATIO
Definition: shop.c:45
int shop_describe(const object *op)
Definition: shop.c:1172
uint64_t price_base(const object *obj)
Definition: shop.c:70
int16_t level
Definition: object.h:352
void fix_object(object *op)
Definition: living.c:1120
int32_t value
Definition: object.h:351
int8_t magic
Definition: object.h:349
const char * name
Definition: object.h:468
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:708
void object_remove(object *op)
Definition: object.c:1587
int32_t food
Definition: living.h:48