ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.C
Revision: 1.9
Committed: Thu Sep 7 10:01:58 2006 UTC (17 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.8: +9 -11 lines
Log Message:
Some cleanups.

File Contents

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