ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.c
Revision: 1.1.1.3 (vendor branch)
Committed: Wed Mar 15 14:05:37 2006 UTC (18 years, 2 months ago) by elmex
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_03_15
Changes since 1.1.1.2: +10 -9 lines
Log Message:
cvs -z9 -d:ext:elmex@cvs.schmorp.de:/schmorpforge import cf.schmorp.de UPSTREAM UPSTREAM_2006_03_15

File Contents

# User Rev Content
1 root 1.1 /*
2     * static char *rcsid_shop_c =
3 elmex 1.1.1.3 * "$Id: shop.c,v 1.53 2006/03/07 21:28:38 akirschbaum Exp $";
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 elmex 1.1.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     #define NUM_COINS 3 /* number of coin types */
60 elmex 1.1.1.2 static const char* const coins[] = {"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 elmex 1.1.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 elmex 1.1.1.3 /* 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 elmex 1.1.1.3 val=(val*(long)(1000*(1+diff)))/1000;
244 root 1.1 else if (flag==F_SELL)
245 elmex 1.1.1.3 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 elmex 1.1.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     sprintf(buf, "%d %ss", num, coin->clone.name);
362    
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 elmex 1.1.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 elmex 1.1.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 elmex 1.1.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     sprintf(buf, "You have %d unpaid items that would cost you %s, but you only have",
674     unpaid_count, cost_string_from_value(unpaid_price));
675     for (i=0; i< NUM_COINS; i++) {
676     if (coincount[i] > 0 && coins[i]) {
677     denominations++;
678     sprintf(coinbuf, " %d %s,", coincount[i], find_archetype(coins[i])->clone.name_pl);
679     strcat (buf, coinbuf);
680     }
681     }
682     if (denominations > 1) make_list_like(buf);
683     new_draw_info(NDI_UNIQUE, 0, pl, buf);
684     return 0;
685     }
686     else return 1;
687     }
688    
689    
690     /* Better get_payment, descends containers looking for
691     * unpaid items, and pays for them.
692     * returns 0 if the player still has unpaid items.
693     * returns 1 if the player has paid for everything.
694     * pl is the player buying the stuff.
695     * op is the object we are examining. If op has
696     * and inventory, we examine that. IF there are objects
697     * below op, we descend down.
698     */
699     int get_payment(object *pl, object *op) {
700     char buf[MAX_BUF];
701     int ret=1;
702    
703     if (op!=NULL&&op->inv)
704     ret = get_payment(pl, op->inv);
705    
706     if (!ret)
707     return 0;
708    
709     if (op!=NULL&&op->below)
710     ret = get_payment (pl, op->below);
711    
712     if (!ret)
713     return 0;
714    
715     if(op!=NULL&&QUERY_FLAG(op,FLAG_UNPAID)) {
716     strncpy(buf,query_cost_string(op,pl,F_BUY | F_SHOP),MAX_BUF);
717     buf[MAX_BUF-1] = '\0';
718     if(!pay_for_item(op,pl)) {
719     uint64 i=query_cost(op,pl,F_BUY | F_SHOP) - query_money(pl);
720     CLEAR_FLAG(op, FLAG_UNPAID);
721     new_draw_info_format(NDI_UNIQUE, 0, pl,
722     "You lack %s to buy %s.", cost_string_from_value(i),
723     query_name(op));
724     SET_FLAG(op, FLAG_UNPAID);
725     return 0;
726     } else {
727     object *tmp;
728     tag_t c = op->count;
729    
730     CLEAR_FLAG(op, FLAG_UNPAID);
731     CLEAR_FLAG(op, FLAG_PLAYER_SOLD);
732     new_draw_info_format(NDI_UNIQUE, 0, op,
733     "You paid %s for %s.",buf,query_name(op));
734     tmp=merge_ob(op,NULL);
735     if (pl->type == PLAYER) {
736     if (tmp) { /* it was merged */
737     esrv_del_item (pl->contr, c);
738     op = tmp;
739     }
740     esrv_send_item(pl, op);
741     }
742     }
743     }
744     return 1;
745     }
746    
747    
748     /* Modified function to give out platinum coins. This function uses
749     * the coins[] array to know what coins are available, just like
750     * buy item.
751     *
752     * Modified to fill available race: gold containers before dumping
753     * remaining coins in character's inventory.
754     */
755     void sell_item(object *op, object *pl) {
756     uint64 i=query_cost(op,pl,F_SELL | F_SHOP), extra_gain;
757     int count;
758     object *tmp, *pouch;
759     archetype *at;
760    
761     if(pl==NULL||pl->type!=PLAYER) {
762     LOG(llevDebug,"Object other than player tried to sell something.\n");
763     return;
764     }
765    
766     if(op->custom_name) FREE_AND_CLEAR_STR(op->custom_name);
767    
768     if(!i) {
769     new_draw_info_format(NDI_UNIQUE, 0, pl,
770     "We're not interested in %s.",query_name(op));
771    
772     /* Even if the character doesn't get anything for it, it may still be
773     * worth something. If so, make it unpaid
774     */
775     if (op->value) {
776     SET_FLAG(op, FLAG_UNPAID);
777     SET_FLAG(op, FLAG_PLAYER_SOLD);
778     }
779     identify(op);
780     return;
781     }
782    
783     /* We compare the price with the one for a player
784     * without bargaining skill.
785     * This determins the amount of exp (if any) gained for bargaining.
786     * exp/10 -> 1 for each gold coin
787     */
788     extra_gain = i - query_cost(op,pl,F_SELL | F_NO_BARGAIN | F_SHOP);
789    
790     if (extra_gain > 0)
791     change_exp(pl,extra_gain/10,"bargaining",SK_EXP_NONE);
792    
793     for (count=0; coins[count]!=NULL; count++) {
794     at = find_archetype(coins[count]);
795     if (at==NULL) LOG(llevError, "Could not find %s archetype\n", coins[count]);
796     else if ((i/at->clone.value) > 0) {
797     for ( pouch=pl->inv ; pouch ; pouch=pouch->below ) {
798     if ( pouch->type==CONTAINER && QUERY_FLAG(pouch, FLAG_APPLIED) && pouch->race && strstr(pouch->race, "gold") ) {
799     int w = at->clone.weight * (100-pouch->stats.Str)/100;
800     int n = i/at->clone.value;
801    
802     if (w==0) w=1; /* Prevent divide by zero */
803     if ( n>0 && (!pouch->weight_limit || pouch->carrying+w<=pouch->weight_limit)) {
804     if (pouch->weight_limit && (pouch->weight_limit-pouch->carrying)/w<n)
805     n = (pouch->weight_limit-pouch->carrying)/w;
806    
807     tmp = get_object();
808     copy_object(&at->clone, tmp);
809     tmp->nrof = n;
810     i -= (uint64)tmp->nrof * (uint64)tmp->value;
811     tmp = insert_ob_in_ob(tmp, pouch);
812     esrv_send_item (pl, tmp);
813     esrv_send_item (pl, pouch);
814     esrv_update_item (UPD_WEIGHT, pl, pouch);
815     esrv_send_item (pl, pl);
816     }
817     }
818     }
819     if (i/at->clone.value > 0) {
820     tmp = get_object();
821     copy_object(&at->clone, tmp);
822     tmp->nrof = i/tmp->value;
823     i -= (uint64)tmp->nrof * (uint64)tmp->value;
824     tmp = insert_ob_in_ob(tmp, pl);
825     esrv_send_item (pl, tmp);
826     esrv_send_item (pl, pl);
827     }
828     }
829     }
830    
831     if (i!=0)
832     #ifndef WIN32
833     LOG(llevError,"Warning - payment not zero: %llu\n", i);
834     #else
835     LOG(llevError,"Warning - payment not zero: %I64u\n", i);
836     #endif
837    
838     new_draw_info_format(NDI_UNIQUE, 0, pl,
839     "You receive %s for %s.",query_cost_string(op,pl,F_SELL | F_SHOP),
840     query_name(op));
841     SET_FLAG(op, FLAG_UNPAID);
842     identify(op);
843     }
844    
845     /* returns a double that is the ratio of the price that a shop will offer for
846     * item based on the shops specialisation. Does not take account of greed,
847     * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any
848     * event is never less than 0.1 (calling functions divide by it)
849     */
850 elmex 1.1.1.2 static double shop_specialisation_ratio(const object *item, const mapstruct *map) {
851 root 1.1 shopitems *items=map->shopitems;
852     double ratio = SPECIALISATION_EFFECT, likedness=0.001;
853     int i;
854    
855     if (item==NULL) {
856 elmex 1.1.1.2 LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
857 root 1.1 return 0;
858     }
859     if (!item->type) {
860 elmex 1.1.1.2 LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
861 root 1.1 /*
862     * I'm not really sure what the /right/ thing to do here is, these types of
863     * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
864     */
865     return ratio;
866     }
867     if (map->shopitems) {
868     for (i=0; i<items[0].index; i++)
869     if (items[i].typenum==item->type || (!items[i].typenum && likedness == 0.001))
870     likedness = items[i].strength/100.0;
871     }
872     if (likedness > 1.0) { /* someone has been rather silly with the map headers. */
873     LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n",
874     item->type, map->path);
875     likedness = 1.0;
876     }
877     if (likedness < -1.0) {
878     LOG(llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n",
879     item->type, map->path);
880     likedness = -1.0;
881     }
882     ratio = ratio + (1.0-ratio) * likedness;
883     if (ratio <= 0.1) ratio=0.1; /* if the ratio were much lower than this, we would get silly prices */
884     return ratio;
885     }
886    
887     /*returns the greed of the shop on map, or 1 if it isn't specified. */
888 elmex 1.1.1.2 static double shop_greed(const mapstruct *map) {
889 root 1.1 double greed=1.0;
890     if (map->shopgreed)
891     return map->shopgreed;
892     return greed;
893     }
894    
895     /* Returns a double based on how much the shopkeeper approves of the player.
896     * this is based on the race of the shopkeeper and that of the player.
897     */
898 elmex 1.1.1.2 double shopkeeper_approval(const mapstruct *map, const object *player) {
899 root 1.1 double approval=1.0;
900    
901     if (map->shoprace) {
902     approval=NEUTRAL_RATIO;
903     if (player->race && !strcmp(player->race, map->shoprace)) approval = 1.0;
904     }
905     return approval;
906     }
907    
908     /* limit the value of items based on the wealth of the shop. If the item is close
909     * to the maximum value a shop will offer, we start to reduce it, if the item is
910     * below the minimum value the shop is prepared to trade in, then we don't
911     * want it and offer nothing. If it isn't a shop, check whether we should do generic
912     * value reduction.
913     *
914     */
915 elmex 1.1.1.2 static uint64 value_limit(uint64 val, int quantity, const object *who, int isshop) {
916 root 1.1 uint64 newval, unit_price;
917     mapstruct *map;
918     unit_price=val/quantity;
919     if (!isshop || !who) {
920     if (unit_price > 10000)
921     newval=8000+isqrt(unit_price)*20;
922     else
923     newval=unit_price;
924     } else {
925     if (!who->map) {
926 elmex 1.1.1.2 LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name);
927 root 1.1 return val;
928     }
929     map=who->map;
930     if (map->shopmin && unit_price < map->shopmin) return 0;
931     else if (map->shopmax && unit_price > map->shopmax/2)
932     newval=MIN((map->shopmax/2)+isqrt(unit_price-map->shopmax/2), map->shopmax);
933     else if (unit_price>10000)
934     newval=8000+isqrt(unit_price)*20;
935     else
936     newval=unit_price;
937     }
938     newval *= quantity;
939     return newval;
940     }
941    
942     /* gives a desciption of the shop on their current map to the player op. */
943 elmex 1.1.1.2 int describe_shop(const object *op) {
944 root 1.1 mapstruct *map = op->map;
945     /*shopitems *items=map->shopitems;*/
946     int pos=0, i;
947     double opinion=0;
948     char tmp[MAX_BUF]="\0";
949     if (op->type != PLAYER) return 0;
950    
951     /*check if there is a shop specified for this map */
952     if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax) {
953     new_draw_info(NDI_UNIQUE,0,op,"From looking at the nearby shop you determine that it trades in:");
954     if (map->shopitems) {
955     for (i=0; i < map->shopitems[0].index; i++) {
956     if (map->shopitems[i].name && map->shopitems[i].strength > 10) {
957     snprintf(tmp+pos, sizeof(tmp)-pos, "%s, ", map->shopitems[i].name_pl);
958     pos += strlen(tmp+pos);
959     }
960     }
961     }
962     if (!pos) strcat(tmp, "a little of everything.");
963    
964     /* format the string into a list */
965     make_list_like(tmp);
966     new_draw_info_format(NDI_UNIQUE, 0, op, "%s", tmp);
967    
968     if (map->shopmax)
969     new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade for items above %s.",
970     cost_string_from_value(map->shopmax));
971     if (map->shopmin)
972     new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade in items worth less than %s.",
973     cost_string_from_value(map->shopmin));
974     if (map->shopgreed) {
975     if (map->shopgreed >2.0)
976     new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge massively.");
977     else if (map->shopgreed >1.5)
978     new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge substantially.");
979     else if (map->shopgreed >1.1)
980     new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge slightly.");
981     else if (map->shopgreed <0.9)
982     new_draw_info(NDI_UNIQUE,0,op,"It tends to undercharge.");
983     }
984     if (map->shoprace) {
985     opinion=shopkeeper_approval(map, op);
986     if (opinion > 0.8)
987     new_draw_info(NDI_UNIQUE,0,op,"You think the shopkeeper likes you.");
988     else if (opinion > 0.5)
989     new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems unconcerned by you.");
990     else
991     new_draw_info(NDI_UNIQUE,0,op,"The shopkeeper seems to have taken a dislike to you.");
992     }
993     }
994     else new_draw_info(NDI_UNIQUE,0,op,"There is no shop nearby.");
995    
996     return 1;
997     }
998     typedef struct shopinv {
999     char *item_sort;
1000     char *item_real;
1001     uint16 type;
1002     uint32 nrof;
1003     } shopinv;
1004    
1005     /* There are a lot fo extra casts in here just to suppress warnings - it
1006     * makes it look uglier than it really it.
1007     * The format of the strings we get is type:name. So we first want to
1008     * sort by type (numerical) - if the same type, then sort by name.
1009     */
1010     static int shop_sort(const void *a1, const void *a2)
1011     {
1012     shopinv *s1 = (shopinv*)a1, *s2= (shopinv*)a2;
1013    
1014     if (s1->type<s2->type) return -1;
1015     if (s1->type>s2->type) return 1;
1016     /* the type is the same (what atoi gets), so do a strcasecmp to sort
1017     * via alphabetical order
1018     */
1019     return strcasecmp(s1->item_sort, s2->item_sort);
1020     }
1021    
1022     static void add_shop_item(object *tmp, shopinv *items, int *numitems, int *numallocated)
1023     {
1024     #if 0
1025     char buf[MAX_BUF];
1026     #endif
1027     /* clear unpaid flag so that doesn't come up in query
1028     * string. We clear nrof so that we can better sort
1029     * the object names.
1030     */
1031    
1032     CLEAR_FLAG(tmp, FLAG_UNPAID);
1033     items[*numitems].nrof=tmp->nrof;
1034     /* Non mergable items have nrof of 0, but count them as one
1035     * so the display is properly.
1036     */
1037     if (tmp->nrof == 0) items[*numitems].nrof++;
1038     items[*numitems].type=tmp->type;
1039    
1040     switch (tmp->type) {
1041     #if 0
1042     case BOOTS:
1043     case GLOVES:
1044     case RING:
1045     case AMULET:
1046     case BRACERS:
1047     case GIRDLE:
1048     sprintf(buf,"%s %s",query_base_name(tmp,0),describe_item(tmp, NULL));
1049     items[*numitems].item_sort = strdup_local(buf);
1050     sprintf(buf,"%s %s",query_name(tmp),describe_item(tmp, NULL));
1051     items[*numitems].item_real = strdup_local(buf);
1052     (*numitems)++;
1053     break;
1054     #endif
1055    
1056     default:
1057     items[*numitems].item_sort = strdup_local(query_base_name(tmp, 0));
1058     items[*numitems].item_real = strdup_local(query_base_name(tmp, 1));
1059     (*numitems)++;
1060     break;
1061     }
1062     SET_FLAG(tmp, FLAG_UNPAID);
1063     }
1064    
1065     void shop_listing(object *op)
1066     {
1067     int i,j,numitems=0,numallocated=0, nx, ny;
1068     char *map_mark = (char *) calloc(MAGIC_MAP_SIZE * MAGIC_MAP_SIZE,1);
1069     object *stack;
1070     shopinv *items;
1071    
1072     /* Should never happen, but just in case a monster does apply a sign */
1073     if (op->type!=PLAYER) return;
1074    
1075     new_draw_info(NDI_UNIQUE, 0, op, "\nThe shop contains:");
1076    
1077     magic_mapping_mark(op, map_mark, 3);
1078     items=malloc(40*sizeof(shopinv));
1079     numallocated=40;
1080    
1081     /* Find all the appropriate items */
1082     for (i=0; i<MAP_WIDTH(op->map); i++) {
1083     for (j=0; j<MAP_HEIGHT(op->map); j++) {
1084     /* magic map code now centers the map on the object at MAGIC_MAP_HALF.
1085     *
1086     */
1087     nx = i - op->x + MAGIC_MAP_HALF;
1088     ny = j - op->y + MAGIC_MAP_HALF;
1089     /* unlikely, but really big shops could run into this issue */
1090     if (nx < 0 || ny < 0 || nx > MAGIC_MAP_SIZE || ny > MAGIC_MAP_SIZE) continue;
1091    
1092     if (map_mark[nx + MAGIC_MAP_SIZE * ny] & FACE_FLOOR) {
1093     stack =get_map_ob(op->map,i,j);
1094    
1095     while (stack) {
1096     if (QUERY_FLAG(stack, FLAG_UNPAID)) {
1097     if (numitems==numallocated) {
1098     items=realloc(items, sizeof(shopinv)*(numallocated+10));
1099     numallocated+=10;
1100     }
1101     add_shop_item(stack, items, &numitems, &numallocated);
1102     }
1103     stack = stack->above;
1104     }
1105     }
1106     }
1107     }
1108     free(map_mark);
1109     if (numitems == 0) {
1110     new_draw_info(NDI_UNIQUE, 0, op, "The shop is currently empty.\n");
1111     free(items);
1112     return;
1113     }
1114     qsort(items, numitems, sizeof(shopinv), (int (*)(const void*, const void*))shop_sort);
1115    
1116     for (i=0; i<numitems; i++) {
1117     /* Collapse items of the same name together */
1118     if ((i+1)<numitems && !strcmp(items[i].item_real, items[i+1].item_real)) {
1119     items[i+1].nrof += items[i].nrof;
1120     free(items[i].item_sort);
1121     free(items[i].item_real);
1122     } else {
1123     new_draw_info_format(NDI_UNIQUE, 0, op, "%d %s",
1124     items[i].nrof? items[i].nrof:1,
1125     items[i].nrof==1?items[i].item_sort: items[i].item_real);
1126     free(items[i].item_sort);
1127     free(items[i].item_real);
1128     }
1129     }
1130     free(items);
1131     }