ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.c
Revision: 1.3
Committed: Wed May 24 01:51:09 2006 UTC (18 years ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.2: +12 -1 lines
Log Message:
Fixed bug where the shop would say to the player "... but you only have"
and end there if the player had no coins to spend.

File Contents

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