ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.c
Revision: 1.8
Committed: Mon Jun 26 00:06:43 2006 UTC (17 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.7: +1 -1 lines
Log Message:
Base reckoned prices on the true prices. The old code based the
approximation on the shop price, which makes no sense at all, as guessing
what the item might sell for in the shop is useless, as you get told the
exact price anyways. Outisde a shop, it also makes no sense.

File Contents

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