ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.c
(Generate patch)

Comparing deliantra/server/server/shop.c (file contents):
Revision 1.1 by root, Fri Feb 3 07:14:37 2006 UTC vs.
Revision 1.13 by root, Wed Jul 5 21:02:50 2006 UTC

1/* 1/*
2 * static char *rcsid_shop_c = 2 * static char *rcsid_shop_c =
3 * "$Id: shop.c,v 1.1 2006/02/03 07:14:37 root Exp $"; 3 * "$Id: shop.c,v 1.13 2006/07/05 21:02:50 root Exp $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
43 * setting this value above 1 or to a negative value would have interesting, 43 * setting this value above 1 or to a negative value would have interesting,
44 * (though not useful) effects. 44 * (though not useful) effects.
45 */ 45 */
46#define SPECIALISATION_EFFECT 0.5 46#define SPECIALISATION_EFFECT 0.5
47 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 */ 48/* price a shopkeeper will give someone they neither like nor dislike */
52#define NEUTRAL_RATIO 0.8 49#define NEUTRAL_RATIO 0.8
53 50
54static uint64 pay_from_container(object *pl, object *pouch, uint64 to_pay); 51static uint64 pay_from_container(object *pl, object *pouch, uint64 to_pay);
55static uint64 value_limit(uint64 val, int quantity, object *who, int isshop); 52static uint64 value_limit(uint64 val, int quantity, const object *who, int isshop);
53static double shop_specialisation_ratio(const object *item, const mapstruct *map);
54static double shop_greed(const mapstruct *map);
56 55
57#define NUM_COINS 3 /* number of coin types */ 56#define NUM_COINS 4 /* number of coin types */
58static char *coins[] = {"platinacoin", "goldcoin", "silvercoin", NULL}; 57static const char* const coins[] = {"royalty", "platinacoin", "goldcoin", "silvercoin", NULL};
59 58
60/* Added F_TRUE flag to define.h to mean that the price should not 59/* Added F_TRUE flag to define.h to mean that the price should not
61 * be adjusted by players charisma. With F_TRUE, it returns the amount 60 * be adjusted by players charisma. With F_TRUE, it returns the amount
62 * that the item is worth, if it was sold, but unadjusted by charisma. 61 * that the item is worth, if it was sold, but unadjusted by charisma.
63 * This is needed for alchemy, to to determine what value of gold nuggets 62 * This is needed for alchemy, to to determine what value of gold nuggets
79 * divisions took place, the value got rounded to 0 (Being an int), and 78 * divisions took place, the value got rounded to 0 (Being an int), and
80 * thus remained 0. 79 * thus remained 0.
81 * 80 *
82 * Mark Wedel (mwedel@pyramid.com) 81 * Mark Wedel (mwedel@pyramid.com)
83 */ 82 */
83
84static uint64 approx_range;
85
84uint64 query_cost(object *tmp, object *who, int flag) { 86uint64 query_cost(const object *tmp, object *who, int flag) {
85 uint64 val; 87 uint64 val;
86 int number; /* used to better calculate value */ 88 int number; /* used to better calculate value */
87 int no_bargain; 89 int no_bargain;
88 int identified; 90 int identified;
89 int not_cursed; 91 int not_cursed;
90 int approximate; 92 int approximate;
91 int shop; 93 int shop;
92 float diff; 94 double diff;
93 float ratio; 95
96 approx_range = 0;
94 97
95 no_bargain = flag & F_NO_BARGAIN; 98 no_bargain = flag & F_NO_BARGAIN;
96 identified = flag & F_IDENTIFIED; 99 identified = flag & F_IDENTIFIED;
97 not_cursed = flag & F_NOT_CURSED; 100 not_cursed = flag & F_NOT_CURSED;
98 approximate = flag & F_APPROX; 101 approximate = flag & F_APPROX;
177 else /* if not identified, presume one charge */ 180 else /* if not identified, presume one charge */
178 val/=50; 181 val/=50;
179 } 182 }
180 183
181 /* Limit amount of money you can get for really great items. */ 184 /* Limit amount of money you can get for really great items. */
182 if (flag==F_TRUE || flag==F_SELL) 185 if (flag==F_SELL)
183 val=value_limit(val, number, who, shop); 186 val=value_limit(val, number, who, shop);
187
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.2);
184 191
185 /* This modification is for bargaining skill. 192 /* This modification is for bargaining skill.
186 * Now only players with max level in bargaining 193 * Now only players with max level in bargaining
187 * AND Cha = 30 will get optimal price. 194 * AND Cha = 30 will get optimal price.
188 * Thus charisma will never get useless. 195 * Thus charisma will never get useless.
194 int lev_identify = 0; 201 int lev_identify = 0;
195 int idskill1=0; 202 int idskill1=0;
196 int idskill2=0; 203 int idskill2=0;
197 const typedata *tmptype; 204 const typedata *tmptype;
198 205
199 /* ratio determines how much of the price modification
200 * will come from the basic stat charisma
201 * the rest will come from the level in bargaining skill
202 */
203 ratio = 0.5;
204 tmptype=get_typedata(tmp->type); 206 tmptype=get_typedata(tmp->type);
205 207
206 if (find_skill_by_number(who,SK_BARGAINING)) { 208 if (find_skill_by_number(who,SK_BARGAINING)) {
207 lev_bargain = find_skill_by_number(who,SK_BARGAINING)->level; 209 lev_bargain = find_skill_by_number(who,SK_BARGAINING)->level;
208 } 210 }
217 lev_identify += find_skill_by_number(who,idskill2)->level; 219 lev_identify += find_skill_by_number(who,idskill2)->level;
218 } 220 }
219 } 221 }
220 } 222 }
221 else LOG(llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->name); 223 else LOG(llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->name);
222 if ( !no_bargain && (lev_bargain>0) ) 224
223 diff = (0.8 - 0.6*((lev_bargain+settings.max_level*0.05) 225 /* ratio determines how much of the price modification
224 /(settings.max_level*1.05))); 226 * will come from the basic stat charisma
225 else 227 * the rest will come from the level in bargaining skill
226 diff = 0.8; 228 */
229 const double cha_ratio = 0.45;
230
231 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / (double)settings.max_level, 0.25);
227 232
228 diff *= 1-ratio; 233 diff = (1. - cha_ratio) * diff
234 + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.);
235
236 diff = .02 + (0.80. - .02) * diff;
229 237
230 /* Diff is now a float between 0.2 and 0.8 */ 238 if (flag == F_BUY) val += val * diff;
231 diff+=(cha_bonus[who->stats.Cha]-1)/(1+cha_bonus[who->stats.Cha])*ratio; 239 else if (flag == F_SELL) val -= val * diff;
232 240
233 /* we need to multiply these by 4.0 to keep buy costs roughly the same 241 // now find a price range. the less good we can judge, the larger the range is
234 * (otherwise, you could buy a potion of charisma for around 400 pp. 242 // then the range is adjusted randomly around the correct value
235 * Arguable, the costs in the archetypes should be updated to better
236 * reflect values (potion charisma list for 1250 gold)
237 */
238 if(flag==F_BUY)
239 val=(4*val*(long)(1000*(1+diff)))/1000;
240 else if (flag==F_SELL)
241 val=(4*val*(long)(1000*(1-diff)))/1000;
242 else val *=4;
243
244 /* If we are approximating, then the value returned should be allowed to be wrong
245 * however merely using a random number each time will not be sufficiant, as then
246 * multiple examinations would give different answers, so we'll use the count
247 * instead. By taking the sine of the count, a value between -1 and 1 is
248 * generated, we then divide by the square root of the bargaining skill and the
249 * appropriate identification skills, so that higher level players get better estimates.
250 * (we need a +1 there in case we would otherwise be dividing by zero.
251 */
252 if (approximate) 243 if (approximate)
253 val = (sint64)val + (sint64)((sint64)val*(sin(tmp->count)/sqrt(lev_bargain+lev_identify*2+1.0))); 244 approx_range = val / sqrt (lev_identify * 3 + 1);
254 } 245 }
255 246
256 /* I don't think this should really happen - if it does, it indicates and 247 /* I don't think this should really happen - if it does, it indicates and
257 * overflow of diff above. That shoudl only happen if 248 * overflow of diff above. That shoudl only happen if
258 * we are selling objects - in that case, the person just 249 * we are selling objects - in that case, the person just
328 * have so much money that they have more than 2 billion platinum 319 * have so much money that they have more than 2 billion platinum
329 * coins, there are certainly issues - the easiest fix at that 320 * coins, there are certainly issues - the easiest fix at that
330 * time is to add a higher denomination (mithril piece with 321 * time is to add a higher denomination (mithril piece with
331 * 10,000 silver or something) 322 * 10,000 silver or something)
332 */ 323 */
333const char *cost_string_from_value(uint64 cost) 324static const char *cost_string_from_value(uint64 cost, int approx)
334{ 325{
335 static char buf[MAX_BUF]; 326 static char buf[MAX_BUF];
336 archetype *coin, *next_coin; 327 archetype *coin, *next_coin;
337 char *endbuf;
338 int num, cointype = 0; 328 int num, cointype = 0;
339 329
340 coin = find_next_coin(cost, &cointype); 330 coin = find_next_coin(cost, &cointype);
341 if (coin == NULL) 331 if (coin == NULL)
342 return "nothing"; 332 return "nothing";
350 strcpy(buf,"an unimaginable sum of money."); 340 strcpy(buf,"an unimaginable sum of money.");
351 return buf; 341 return buf;
352 } 342 }
353 343
354 cost -= (uint64)num * (uint64)coin->clone.value; 344 cost -= (uint64)num * (uint64)coin->clone.value;
355 if (num == 1) 345 sprintf(buf, "%d %s", num, num > 1 ? coin->clone.name_pl : coin->clone.name);
356 sprintf(buf, "1 %s", coin->clone.name);
357 else
358 sprintf(buf, "%d %ss", num, coin->clone.name);
359 346
360 next_coin = find_next_coin(cost, &cointype); 347 next_coin = find_next_coin(cost, &cointype);
361 if (next_coin == NULL) 348 if (next_coin == NULL || approx)
362 return buf; 349 return buf;
363 350
364 do {
365 endbuf = buf + strlen(buf);
366
367 coin = next_coin; 351 coin = next_coin;
368 num = cost / coin->clone.value; 352 num = cost / coin->clone.value;
369 cost -= (uint64)num * (uint64)coin->clone.value; 353 cost -= (uint64)num * (uint64)coin->clone.value;
370 354
371 if (cost == 0) 355 sprintf (buf + strlen (buf), " and %d %s", num, num > 1 ? coin->clone.name_pl : coin->clone.name);
372 next_coin = NULL; 356
373 else
374 next_coin = find_next_coin(cost, &cointype);
375
376 if (next_coin) {
377 /* There will be at least one more string to add to the list,
378 * use a comma.
379 */
380 strcat(endbuf, ", "); endbuf += 2;
381 } else {
382 strcat(endbuf, " and "); endbuf += 5;
383 }
384 if (num == 1)
385 sprintf(endbuf, "1 %s", coin->clone.name);
386 else
387 sprintf(endbuf, "%d %ss", num, coin->clone.name);
388 } while (next_coin);
389
390 return buf; 357 return buf;
391} 358}
392 359
393const char *query_cost_string(object *tmp,object *who,int flag) { 360const char *query_cost_string(const object *tmp,object *who,int flag) {
394 uint64 real_value = query_cost(tmp,who,flag); 361 uint64 real_value = query_cost(tmp,who,flag);
395 int idskill1=0; 362 int idskill1=0;
396 int idskill2=0; 363 int idskill2=0;
397 const typedata *tmptype; 364 const typedata *tmptype;
398 365
434 sprintf(buf, "a vast quantity of %s", coin->clone.name_pl); 401 sprintf(buf, "a vast quantity of %s", coin->clone.name_pl);
435 return buf; 402 return buf;
436 } 403 }
437 } 404 }
438 } 405 }
406
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 }
439 } 419 }
420
440 return cost_string_from_value(real_value); 421 return cost_string_from_value (real_value, 0);
441} 422}
442 423
443/* This function finds out how much money the player is carrying, 424/* This function finds out how much money the player is carrying,
444 * including what is in containers. 425 * including what is in containers.
445 */ 426 */
446uint64 query_money(object *op) { 427uint64 query_money(const object *op) {
447 object *tmp; 428 object *tmp;
448 uint64 total=0; 429 uint64 total=0;
449 430
450 if (op->type!=PLAYER && op->type!=CONTAINER) { 431 if (op->type!=PLAYER && op->type!=CONTAINER) {
451 LOG(llevError, "Query money called with non player/container\n"); 432 LOG(llevError, "Query money called with non player/container\n");
642 uint64 unpaid_price = 0; 623 uint64 unpaid_price = 0;
643 uint64 player_wealth = query_money(pl); 624 uint64 player_wealth = query_money(pl);
644 object *item; 625 object *item;
645 uint32 coincount[NUM_COINS]; 626 uint32 coincount[NUM_COINS];
646 if (!pl || pl->type != PLAYER) { 627 if (!pl || pl->type != PLAYER) {
647 LOG(llevError, "can_pay(): called against something that isn't a player"); 628 LOG(llevError, "can_pay(): called against something that isn't a player\n");
648 return 0; 629 return 0;
649 } 630 }
650 for (i=0; i< NUM_COINS; i++) coincount[i] = 0; 631 for (i=0; i< NUM_COINS; i++) coincount[i] = 0;
651 for (item = pl->inv;item;) { 632 for (item = pl->inv;item;) {
652 if QUERY_FLAG(item, FLAG_UNPAID) { 633 if QUERY_FLAG(item, FLAG_UNPAID) {
665 else item = NULL; 646 else item = NULL;
666 } 647 }
667 if (unpaid_price > player_wealth) { 648 if (unpaid_price > player_wealth) {
668 char buf[MAX_BUF], coinbuf[MAX_BUF]; 649 char buf[MAX_BUF], coinbuf[MAX_BUF];
669 int denominations = 0; 650 int denominations = 0;
670 sprintf(buf, "You have %d unpaid items that would cost you %s, but you only have", 651 int has_coins = NUM_COINS;
652 char cost[MAX_BUF];
653 char missing[MAX_BUF];
654
671 unpaid_count, cost_string_from_value(unpaid_price)); 655 sprintf(cost, "%s", cost_string_from_value (unpaid_price, 0));
672 for (i=0; i< NUM_COINS; i++) { 656 sprintf(missing, "%s", cost_string_from_value (unpaid_price - player_wealth, 0));
673 if (coincount[i] > 0 && coins[i]) { 657
674 denominations++; 658 sprintf(buf, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.",
675 sprintf(coinbuf, " %d %s,", coincount[i], find_archetype(coins[i])->clone.name_pl); 659 unpaid_count, cost, missing);
676 strcat (buf, coinbuf);
677 }
678 }
679 if (denominations > 1) make_list_like(buf);
680 new_draw_info(NDI_UNIQUE, 0, pl, buf); 660 new_draw_info(NDI_UNIQUE, 0, pl, buf);
681 return 0; 661 return 0;
682 } 662 }
683 else return 1; 663 else return 1;
684} 664}
714 buf[MAX_BUF-1] = '\0'; 694 buf[MAX_BUF-1] = '\0';
715 if(!pay_for_item(op,pl)) { 695 if(!pay_for_item(op,pl)) {
716 uint64 i=query_cost(op,pl,F_BUY | F_SHOP) - query_money(pl); 696 uint64 i=query_cost(op,pl,F_BUY | F_SHOP) - query_money(pl);
717 CLEAR_FLAG(op, FLAG_UNPAID); 697 CLEAR_FLAG(op, FLAG_UNPAID);
718 new_draw_info_format(NDI_UNIQUE, 0, pl, 698 new_draw_info_format(NDI_UNIQUE, 0, pl,
719 "You lack %s to buy %s.", cost_string_from_value(i), 699 "You lack %s to buy %s.", cost_string_from_value (i, 0),
720 query_name(op)); 700 query_name(op));
721 SET_FLAG(op, FLAG_UNPAID); 701 SET_FLAG(op, FLAG_UNPAID);
722 return 0; 702 return 0;
723 } else { 703 } else {
724 object *tmp; 704 object *tmp;
842/* returns a double that is the ratio of the price that a shop will offer for 822/* returns a double that is the ratio of the price that a shop will offer for
843 * item based on the shops specialisation. Does not take account of greed, 823 * item based on the shops specialisation. Does not take account of greed,
844 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any 824 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any
845 * event is never less than 0.1 (calling functions divide by it) 825 * event is never less than 0.1 (calling functions divide by it)
846 */ 826 */
847double shop_specialisation_ratio(object *item, mapstruct *map) { 827static double shop_specialisation_ratio(const object *item, const mapstruct *map) {
848 shopitems *items=map->shopitems; 828 shopitems *items=map->shopitems;
849 double ratio = SPECIALISATION_EFFECT, likedness=0.001; 829 double ratio = SPECIALISATION_EFFECT, likedness=0.001;
850 int i; 830 int i;
851 831
852 if (item==NULL) { 832 if (item==NULL) {
853 LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s", map->path); 833 LOG(llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
854 return 0; 834 return 0;
855 } 835 }
856 if (!item->type) { 836 if (!item->type) {
857 LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type"); 837 LOG(llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
858 /* 838 /*
859 * I'm not really sure what the /right/ thing to do here is, these types of 839 * I'm not really sure what the /right/ thing to do here is, these types of
860 * item shouldn't exist anyway, but returning the ratio is probably the best bet.." 840 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
861 */ 841 */
862 return ratio; 842 return ratio;
880 if (ratio <= 0.1) ratio=0.1; /* if the ratio were much lower than this, we would get silly prices */ 860 if (ratio <= 0.1) ratio=0.1; /* if the ratio were much lower than this, we would get silly prices */
881 return ratio; 861 return ratio;
882} 862}
883 863
884/*returns the greed of the shop on map, or 1 if it isn't specified. */ 864/*returns the greed of the shop on map, or 1 if it isn't specified. */
885double shop_greed(mapstruct *map) { 865static double shop_greed(const mapstruct *map) {
886 double greed=1.0; 866 double greed=1.0;
887 if (map->shopgreed) 867 if (map->shopgreed)
888 return map->shopgreed; 868 return map->shopgreed;
889 return greed; 869 return greed;
890} 870}
891 871
892/* Returns a double based on how much the shopkeeper approves of the player. 872/* Returns a double based on how much the shopkeeper approves of the player.
893 * this is based on the race of the shopkeeper and that of the player. 873 * this is based on the race of the shopkeeper and that of the player.
894 */ 874 */
895double shopkeeper_approval(mapstruct *map, object *player) { 875double shopkeeper_approval(const mapstruct *map, const object *player) {
896 double approval=1.0; 876 double approval=1.0;
897 877
898 if (map->shoprace) { 878 if (map->shoprace) {
899 approval=NEUTRAL_RATIO; 879 approval=NEUTRAL_RATIO;
900 if (player->race && !strcmp(player->race, map->shoprace)) approval = 1.0; 880 if (player->race && !strcmp(player->race, map->shoprace)) approval = 1.0;
907 * below the minimum value the shop is prepared to trade in, then we don't 887 * below the minimum value the shop is prepared to trade in, then we don't
908 * want it and offer nothing. If it isn't a shop, check whether we should do generic 888 * want it and offer nothing. If it isn't a shop, check whether we should do generic
909 * value reduction. 889 * value reduction.
910 * 890 *
911 */ 891 */
912static uint64 value_limit(uint64 val, int quantity, object *who, int isshop) { 892static uint64 value_limit(uint64 val, int quantity, const object *who, int isshop) {
913 uint64 newval, unit_price; 893 uint64 newval, unit_price;
914 mapstruct *map; 894 mapstruct *map;
915 unit_price=val/quantity; 895 unit_price=val/quantity;
916 if (!isshop || !who) { 896 if (!isshop || !who) {
917 if (unit_price > 10000) 897 if (unit_price > 250000)
918 newval=8000+isqrt(unit_price)*20; 898 newval = 250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.;
919 else 899 else
920 newval=unit_price; 900 newval=unit_price;
921 } else { 901 } else {
922 if (!who->map) { 902 if (!who->map) {
923 LOG(llevError, "value_limit: asked shop price for ob %s on NULL map", who->name); 903 LOG(llevError, "value_limit: asked shop price for ob %s on NULL map\n", who->name);
924 return val; 904 return val;
925 } 905 }
926 map=who->map; 906 map=who->map;
927 if (map->shopmin && unit_price < map->shopmin) return 0; 907 if (map->shopmin && unit_price < map->shopmin) return 0;
928 else if (map->shopmax && unit_price > map->shopmax/2) 908 else if (map->shopmax && unit_price > map->shopmax/2)
929 newval=MIN((map->shopmax/2)+isqrt(unit_price-map->shopmax/2), map->shopmax); 909 newval=MIN((map->shopmax/2)+isqrt(unit_price-map->shopmax/2), map->shopmax);
930 else if (unit_price>10000) 910 else if (unit_price > 250000)
931 newval=8000+isqrt(unit_price)*20; 911 newval = 250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.;
932 else 912 else
933 newval=unit_price; 913 newval=unit_price;
934 } 914 }
935 newval *= quantity; 915 newval *= quantity;
936 return newval; 916 return newval;
937} 917}
938 918
939/* gives a desciption of the shop on their current map to the player op. */ 919/* gives a desciption of the shop on their current map to the player op. */
940int describe_shop(object *op) { 920int describe_shop(const object *op) {
941 mapstruct *map = op->map; 921 mapstruct *map = op->map;
942 /*shopitems *items=map->shopitems;*/ 922 /*shopitems *items=map->shopitems;*/
943 int pos=0, i; 923 int pos=0, i;
944 double opinion=0; 924 double opinion=0;
945 char tmp[MAX_BUF]="\0"; 925 char tmp[MAX_BUF]="\0";
962 make_list_like(tmp); 942 make_list_like(tmp);
963 new_draw_info_format(NDI_UNIQUE, 0, op, "%s", tmp); 943 new_draw_info_format(NDI_UNIQUE, 0, op, "%s", tmp);
964 944
965 if (map->shopmax) 945 if (map->shopmax)
966 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade for items above %s.", 946 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade for items above %s.",
967 cost_string_from_value(map->shopmax)); 947 cost_string_from_value(map->shopmax, 0));
968 if (map->shopmin) 948 if (map->shopmin)
969 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade in items worth less than %s.", 949 new_draw_info_format(NDI_UNIQUE,0,op,"It won't trade in items worth less than %s.",
970 cost_string_from_value(map->shopmin)); 950 cost_string_from_value(map->shopmin, 0));
971 if (map->shopgreed) { 951 if (map->shopgreed) {
972 if (map->shopgreed >2.0) 952 if (map->shopgreed >2.0)
973 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge massively."); 953 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge massively.");
974 else if (map->shopgreed >1.5) 954 else if (map->shopgreed >1.5)
975 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge substantially."); 955 new_draw_info(NDI_UNIQUE,0,op,"It tends to overcharge substantially.");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines