ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.C
Revision: 1.5
Committed: Tue Aug 29 07:34:00 2006 UTC (17 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.4: +4 -4 lines
Log Message:
nuke transports

File Contents

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