ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.c
Revision: 1.1
Committed: Fri Feb 3 07:14:37 2006 UTC (18 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Branch point for: UPSTREAM
Log Message:
Initial revision

File Contents

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