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.81 by root, Wed Apr 28 19:20:48 2010 UTC vs.
Revision 1.90 by root, Tue Jan 3 11:25:37 2012 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
79 int no_bargain; 79 int no_bargain;
80 int identified; 80 int identified;
81 int not_cursed; 81 int not_cursed;
82 int approximate; 82 int approximate;
83 int shop; 83 int shop;
84 double diff;
85 84
86 approx_range = 0; 85 approx_range = 0;
87 86
88 no_bargain = flag & F_NO_BARGAIN; 87 no_bargain = flag & F_NO_BARGAIN;
89 identified = flag & F_IDENTIFIED; 88 identified = flag & F_IDENTIFIED;
170 /* Value of the wand is multiplied by the number of 169 /* Value of the wand is multiplied by the number of
171 * charges. the treasure code already sets up the value 170 * charges. the treasure code already sets up the value
172 * 50 charges is used as the baseline. 171 * 50 charges is used as the baseline.
173 */ 172 */
174 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified) 173 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
175 val *= tmp->stats.food / 50; 174 val *= tmp->stats.food;
176 else /* if not identified, presume one charge */ 175 /* if not identified, presume one charge */
177 val /= 50; 176 val /= 50;
178 } 177 }
179 178
180 /* Limit amount of money you can get for really great items. */ 179 /* Limit amount of money you can get for really great items. */
181 if (flag == F_SELL) 180 if (flag == F_SELL)
182 val = value_limit (val, number, who, shop); 181 val = value_limit (val, number, who, shop);
190 * AND Cha = 30 will get optimal price. 189 * AND Cha = 30 will get optimal price.
191 * Thus charisma will never get useless. 190 * Thus charisma will never get useless.
192 * -b.e. edler@heydernet.de 191 * -b.e. edler@heydernet.de
193 */ 192 */
194 193
195 if (who && who->type == PLAYER) 194 if (who && who->is_player ())
196 { 195 {
197 int lev_bargain = 0; 196 int lev_bargain = 0;
198 int lev_identify = 0; 197 int lev_identify = 0;
199 198
200 if (find_skill_by_number (who, SK_BARGAINING)) 199 if (!no_bargain)
201 lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level; 200 if (object *skill = find_skill_by_name (who, shstr_bargaining))
201 lev_bargain = skill->level;
202 202
203 if (const typedata *tmptype = get_typedata (tmp->type)) 203 if (const typedata *tmptype = get_typedata (tmp->type))
204 { 204 {
205 if (int idskill1 = tmptype->identifyskill) 205 if (int idskill1 = tmptype->identifyskill)
206 { 206 {
217 /* ratio determines how much of the price modification 217 /* ratio determines how much of the price modification
218 * will come from the basic stat charisma 218 * will come from the basic stat charisma
219 * the rest will come from the level in bargaining skill 219 * the rest will come from the level in bargaining skill
220 */ 220 */
221 const double cha_ratio = 0.40; 221 const double cha_ratio = 0.40;
222 222 double bargaining = max (0., 1. - powf (double (lev_bargain) / MAXLEVEL_TREASURE, 0.25));
223 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / MAXLEVEL_TREASURE, 0.25);
224 diff = (1. - cha_ratio) * diff + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.); 223 double charisma = (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.);
225 diff = .02 + (.80 - .02) * diff; 224
225 double factor = (1. - cha_ratio) * bargaining + cha_ratio * charisma;
226
227 // scale 0..1 to 2 .. 80%
228 factor = lerp (factor, 0., 1., 0.02, 0.80);
226 229
227 if (flag == F_BUY) 230 if (flag == F_BUY)
228 val += val * diff; 231 val += val * factor;
229 else if (flag == F_SELL) 232 else if (flag == F_SELL)
230 val -= val * diff; 233 val -= val * factor;
231 234
232 // now find a price range. the less good we can judge, the larger the range is 235 // now find a price range. the less good we can judge, the larger the range is
233 // then the range is adjusted randomly around the correct value 236 // then the range is adjusted randomly around the correct value
234 if (approximate) 237 if (approximate)
235 approx_range = val / sqrt (lev_identify * 3 + 1); 238 approx_range = val / sqrt (lev_identify * 3 + 1);
380 { 383 {
381 if (!idskill1 || !find_skill_by_number (who, idskill1)) 384 if (!idskill1 || !find_skill_by_number (who, idskill1))
382 { 385 {
383 if (!idskill2 || !find_skill_by_number (who, idskill2)) 386 if (!idskill2 || !find_skill_by_number (who, idskill2))
384 { 387 {
385 if (!find_skill_by_number (who, SK_BARGAINING)) 388 if (!find_skill_by_name (who, shstr_bargaining))
386 { 389 {
387 int num, cointype = 0; 390 int num, cointype = 0;
388 archetype *coin = find_next_coin (real_value, &cointype); 391 archetype *coin = find_next_coin (real_value, &cointype);
389 392
390 if (!coin) 393 if (!coin)
440 } 443 }
441 444
442 for (tmp = op->inv; tmp; tmp = tmp->below) 445 for (tmp = op->inv; tmp; tmp = tmp->below)
443 if (tmp->type == MONEY) 446 if (tmp->type == MONEY)
444 total += tmp->nrof * (sint64)tmp->value; 447 total += tmp->nrof * (sint64)tmp->value;
445 else if (tmp->type == CONTAINER && tmp->flag [FLAG_APPLIED] && (!tmp->race || tmp->race.contains ("gold"))) 448 else if (tmp->type == CONTAINER && tmp->flag [FLAG_APPLIED] && (!tmp->race || tmp->race.contains (shstr_gold)))
446 total += query_money (tmp); 449 total += query_money (tmp);
447 450
448 return total; 451 return total;
449} 452}
450 453
465 return 0; 468 return 0;
466 469
467 pay_from_container (pl, pl, to_pay); 470 pay_from_container (pl, pl, to_pay);
468 471
469 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 472 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
470 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains ("gold"))) 473 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
471 pay_from_container (pl, pouch, to_pay); 474 pay_from_container (pl, pouch, to_pay);
472 475
473 pl->update_stats (); 476 pl->update_stats ();
474 return 1; 477 return 1;
475} 478}
497 * This determins the amount of exp (if any) gained for bargaining. 500 * This determins the amount of exp (if any) gained for bargaining.
498 */ 501 */
499 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay; 502 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay;
500 503
501 if (saved_money > 0) 504 if (saved_money > 0)
502 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE); 505 change_exp (pl, saved_money, shstr_bargaining, SK_EXP_NONE);
503 506
504 pay_from_container (pl, pl, to_pay); 507 pay_from_container (pl, pl, to_pay);
505 508
506 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 509 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
507 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains ("gold"))) 510 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains (shstr_gold)))
508 pay_from_container (pl, pouch, to_pay); 511 pay_from_container (pl, pouch, to_pay);
509 512
510 pl->update_stats (); 513 pl->update_stats ();
511 514
512 return 1; 515 return 1;
729 LOG (llevError, "Could not find %s archetype\n", coins[count]); 732 LOG (llevError, "Could not find %s archetype\n", coins[count]);
730 else if ((amount / at->value) > 0) 733 else if ((amount / at->value) > 0)
731 { 734 {
732 for (pouch = pl->inv; pouch; pouch = pouch->below) 735 for (pouch = pl->inv; pouch; pouch = pouch->below)
733 { 736 {
734 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && pouch->race.contains ("gold")) 737 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && pouch->race.contains (shstr_gold))
735 { 738 {
736 int w = at->weight * (100 - pouch->stats.Str) / 100; 739 int w = at->weight * (100 - pouch->stats.Str) / 100;
737 int n = amount / at->value; 740 int n = amount / at->value;
738 741
739 if (w == 0) 742 if (w == 0)
819 * exp/10 -> 1 for each gold coin 822 * exp/10 -> 1 for each gold coin
820 */ 823 */
821 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP); 824 extra_gain = amount - query_cost (op, pl, F_SELL | F_NO_BARGAIN | F_SHOP);
822 825
823 if (extra_gain > 0) 826 if (extra_gain > 0)
824 change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE); 827 change_exp (pl, extra_gain / 10, shstr_bargaining, SK_EXP_NONE);
825 828
826 pay_player (pl, amount); 829 pay_player (pl, amount);
827 830
828 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.", 831 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.",
829 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op)); 832 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op));
852 return 0; 855 return 0;
853 } 856 }
854 857
855 if (!item->type) 858 if (!item->type)
856 { 859 {
857 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n"); 860 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type: %s\n", item->debug_desc ());
858 /* 861 /*
859 * I'm not really sure what the /right/ thing to do here is, these types of 862 * 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.." 863 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
861 */ 864 */
862 return SPECIALISATION_EFFECT; 865 return SPECIALISATION_EFFECT;
867 if (items[i].typenum == item->type || (!items[i].typenum && !likedness)) 870 if (items[i].typenum == item->type || (!items[i].typenum && !likedness))
868 likedness = items[i].strength; 871 likedness = items[i].strength;
869 872
870 if (likedness > 100) 873 if (likedness > 100)
871 { /* someone has been rather silly with the map headers. */ 874 { /* someone has been rather silly with the map headers. */
872 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, &map->path); 875 LOG (llevDebug, "shop_specialisation ratio: item %s on map %s is above 100%%\n", item->debug_desc (), &map->path);
873 likedness = 100; 876 likedness = 100;
874 } 877 }
875 878
876 if (likedness < -100) 879 if (likedness < -100)
877 { 880 {
878 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, &map->path); 881 LOG (llevDebug, "shop_specialisation ratio: item %s on map %s is below -100%%\n", item->debug_desc (), &map->path);
879 likedness = -100; 882 likedness = -100;
880 } 883 }
881 884
882 return lerp (double (likedness), -100., 100., SPECIALISATION_EFFECT, 1.); 885 return lerp (double (likedness), -100., 100., SPECIALISATION_EFFECT, 1.);
883} 886}
1031 1034
1032struct shopinv 1035struct shopinv
1033{ 1036{
1034 char *item_sort; 1037 char *item_sort;
1035 char *item_real; 1038 char *item_real;
1039 sint64 value;
1036 uint16 type; 1040 uint16 type;
1037 uint32 nrof; 1041 uint32 nrof;
1038}; 1042};
1039 1043
1040/* There are a lot fo extra casts in here just to suppress warnings - it 1044/* There are a lot fo extra casts in here just to suppress warnings - it
1073 * so the display is properly. 1077 * so the display is properly.
1074 */ 1078 */
1075 if (tmp->nrof == 0) 1079 if (tmp->nrof == 0)
1076 items[*numitems].nrof++; 1080 items[*numitems].nrof++;
1077 items[*numitems].type = tmp->type; 1081 items[*numitems].type = tmp->type;
1082
1083 items[*numitems].value = tmp->value;
1078 1084
1079 switch (tmp->type) 1085 switch (tmp->type)
1080 { 1086 {
1081#if 0 1087#if 0
1082 case BOOTS: 1088 case BOOTS:
1094#endif 1100#endif
1095 1101
1096 default: 1102 default:
1097 items[*numitems].item_sort = strdup (query_base_name (tmp, 0)); 1103 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1098 items[*numitems].item_real = strdup (query_base_name (tmp, 1)); 1104 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1105 items[*numitems].value += tmp->value;
1099 (*numitems)++; 1106 (*numitems)++;
1100 break; 1107 break;
1101 } 1108 }
1102 1109
1103 tmp->set_flag (FLAG_UNPAID); 1110 tmp->set_flag (FLAG_UNPAID);
1105 1112
1106void 1113void
1107shop_listing (object *sign, object *op) 1114shop_listing (object *sign, object *op)
1108{ 1115{
1109 int i, j, x1, x2, y1, y2; 1116 int i, j, x1, x2, y1, y2;
1110 const char *shop_coords = sign->kv (shstr_shop_coords); 1117 const char *shop_coords = sign->kv [shstr_shop_coords];
1111 object *stack; 1118 object *stack;
1112 shopinv *items; 1119 shopinv *items;
1113 1120
1114 /* Should never happen, but just in case a monster does apply a sign */ 1121 /* Should never happen, but just in case a monster does apply a sign */
1115 if (!op->is_player ()) 1122 if (!op->is_player ())
1159 { 1166 {
1160 /* Collapse items of the same name together */ 1167 /* Collapse items of the same name together */
1161 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real)) 1168 if ((i + 1) < numitems && !strcmp (items[i].item_real, items[i + 1].item_real))
1162 items[i + 1].nrof += items[i].nrof; 1169 items[i + 1].nrof += items[i].nrof;
1163 else 1170 else
1164 buf.printf (" %4d %s\n", items[i].nrof ? items[i].nrof : 1, items[i].nrof == 1 ? items[i].item_sort : items[i].item_real); 1171 {
1172 buf.printf (
1173 " %4d %s\n for %s\n",
1174 items[i].nrof ? items[i].nrof : 1,
1175 items[i].nrof == 1 ? items[i].item_sort : items[i].item_real,
1176 cost_string_from_value (items[i].value, op->flag [FLAG_WIZ] ? 0 : 1));
1177 }
1165 1178
1166 free (items[i].item_sort); 1179 free (items[i].item_sort);
1167 free (items[i].item_real); 1180 free (items[i].item_real);
1168 } 1181 }
1169 1182

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines