ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.c
Revision: 1.19
Committed: Tue Jul 11 18:00:46 2006 UTC (17 years, 10 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: LAST_C_VERSION, difficulty_fix_merge_060810_2300
Branch point for: difficulty_fix
Changes since 1.18: +36 -25 lines
Log Message:
added shop default maximum.
removed '.' from moeny string.

File Contents

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