1 | /* |
1 | /* |
2 | * static char *rcsid_shop_c = |
2 | * static char *rcsid_shop_c = |
3 | * "$Id: shop.C,v 1.1 2006/08/13 17:16:04 elmex Exp $"; |
3 | * "$Id: shop.C,v 1.5 2006/08/29 07:34:00 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 | |
… | |
… | |
82 | */ |
82 | */ |
83 | |
83 | |
84 | static uint64 approx_range; |
84 | static uint64 approx_range; |
85 | |
85 | |
86 | uint64 query_cost(const object *tmp, object *who, int flag) { |
86 | uint64 query_cost(const object *tmp, object *who, int flag) { |
87 | uint64 val; |
87 | double val; |
88 | int number; /* used to better calculate value */ |
88 | int number; /* used to better calculate value */ |
89 | int no_bargain; |
89 | int no_bargain; |
90 | int identified; |
90 | int identified; |
91 | int not_cursed; |
91 | int not_cursed; |
92 | int approximate; |
92 | int approximate; |
… | |
… | |
181 | val/=50; |
181 | val/=50; |
182 | } |
182 | } |
183 | |
183 | |
184 | /* Limit amount of money you can get for really great items. */ |
184 | /* Limit amount of money you can get for really great items. */ |
185 | if (flag==F_SELL) |
185 | if (flag==F_SELL) |
186 | val=value_limit(val, number, who, shop); |
186 | val=value_limit((uint64)val, number, who, shop); |
187 | |
187 | |
188 | // use a nonlinear price adjustment. as my predecessor said, don't change |
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. |
189 | // the archetypes, its work required for balancing, and we don't care. |
190 | //val = pow (val, 1.05); |
190 | //val = pow (val, 1.05); |
191 | |
191 | |
… | |
… | |
233 | diff = (1. - cha_ratio) * diff |
233 | diff = (1. - cha_ratio) * diff |
234 | + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.); |
234 | + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.); |
235 | |
235 | |
236 | diff = .02 + (.80 - .02) * diff; |
236 | diff = .02 + (.80 - .02) * diff; |
237 | |
237 | |
238 | if (flag == F_BUY) val += (uint64) (val * diff); |
238 | if (flag == F_BUY) val += (val * diff); |
239 | else if (flag == F_SELL) val -= (uint64) (val * diff); |
239 | else if (flag == F_SELL) val -= (val * diff); |
240 | |
240 | |
241 | // now find a price range. the less good we can judge, the larger the range is |
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 |
242 | // then the range is adjusted randomly around the correct value |
243 | if (approximate) |
243 | if (approximate) |
244 | approx_range = (uint64) (val / sqrt (lev_identify * 3 + 1)); |
244 | approx_range = uint64 (val / sqrt (lev_identify * 3 + 1)); |
245 | } |
245 | } |
246 | |
246 | |
247 | /* 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 |
248 | * overflow of diff above. That shoudl only happen if |
248 | * overflow of diff above. That shoudl only happen if |
249 | * we are selling objects - in that case, the person just |
249 | * we are selling objects - in that case, the person just |
… | |
… | |
258 | } |
258 | } |
259 | |
259 | |
260 | /* if we are in a shop, check how the type of shop should affect the price */ |
260 | /* if we are in a shop, check how the type of shop should affect the price */ |
261 | if (shop && who) { |
261 | if (shop && who) { |
262 | if (flag==F_SELL) |
262 | if (flag==F_SELL) |
263 | val=(uint64) ( |
263 | val= ( |
264 | val |
264 | val |
265 | * shop_specialisation_ratio(tmp, who->map) |
265 | * shop_specialisation_ratio(tmp, who->map) |
266 | * shopkeeper_approval(who->map, who) |
266 | * shopkeeper_approval(who->map, who) |
267 | / shop_greed(who->map) |
267 | / shop_greed(who->map) |
268 | ); |
268 | ); |
… | |
… | |
279 | * In game terms, a non-specialist shop, might not recognise the true |
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 |
280 | * value of the items they sell (much like how people sometimes find |
281 | * antiques in a junk shop in real life). |
281 | * antiques in a junk shop in real life). |
282 | */ |
282 | */ |
283 | if (QUERY_FLAG(tmp, FLAG_PLAYER_SOLD)) |
283 | if (QUERY_FLAG(tmp, FLAG_PLAYER_SOLD)) |
284 | val=(uint64) ( |
284 | val= ( |
285 | val |
285 | val |
286 | * shop_greed(who->map) |
286 | * shop_greed(who->map) |
287 | * shop_specialisation_ratio(tmp, who->map) |
287 | * shop_specialisation_ratio(tmp, who->map) |
288 | / shopkeeper_approval(who->map, who) |
288 | / shopkeeper_approval(who->map, who) |
289 | ); |
289 | ); |
290 | else |
290 | else |
291 | val=(uint64) ( |
291 | val= ( |
292 | val |
292 | val |
293 | * shop_greed(who->map) |
293 | * shop_greed(who->map) |
294 | / (shop_specialisation_ratio(tmp, who->map)*shopkeeper_approval(who->map, who)) |
294 | / (shop_specialisation_ratio(tmp, who->map)*shopkeeper_approval(who->map, who)) |
295 | ); |
295 | ); |
296 | } |
296 | } |
297 | /* we will also have an extra 0-5% variation between shops of the same type |
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 |
298 | * for valuable items (below a value of 50 this effect wouldn't be very |
299 | * pointful, and could give fun with rounding. |
299 | * pointful, and could give fun with rounding. |
300 | */ |
300 | */ |
301 | if(who->map->path!=NULL && val > 50) |
301 | if(who->map->path!=NULL && val > 50) |
302 | val=(uint64) (val+0.05*(sint64)val*cos(tmp->count+strlen(who->map->path))); |
302 | val= (val+0.05*(sint64)val*cos(tmp->count+strlen(who->map->path))); |
303 | } |
303 | } |
304 | return val; |
304 | return (uint64)val; |
305 | } |
305 | } |
306 | |
306 | |
307 | /* Find the coin type that is worth more the 'c'. Starts at the |
307 | /* Find the coin type that is worth more the 'c'. Starts at the |
308 | * cointype placement. |
308 | * cointype placement. |
309 | */ |
309 | */ |
… | |
… | |
330 | * have so much money that they have more than 2 billion platinum |
330 | * have so much money that they have more than 2 billion platinum |
331 | * coins, there are certainly issues - the easiest fix at that |
331 | * coins, there are certainly issues - the easiest fix at that |
332 | * time is to add a higher denomination (mithril piece with |
332 | * time is to add a higher denomination (mithril piece with |
333 | * 10,000 silver or something) |
333 | * 10,000 silver or something) |
334 | */ |
334 | */ |
335 | static const char *cost_string_from_value(uint64 cost, int approx) |
335 | const char *cost_string_from_value(uint64 cost, int approx) |
336 | { |
336 | { |
337 | static char buf[MAX_BUF]; |
337 | static char buf[MAX_BUF]; |
338 | archetype *coin, *next_coin; |
338 | archetype *coin, *next_coin; |
339 | int num, cointype = 0; |
339 | int num, cointype = 0; |
340 | |
340 | |
… | |
… | |
576 | /* Note that the coin_objs array goes from least value to greatest value */ |
576 | /* Note that the coin_objs array goes from least value to greatest value */ |
577 | for (i=0; i<NUM_COINS; i++) |
577 | for (i=0; i<NUM_COINS; i++) |
578 | if (coin_objs[i]==NULL) { |
578 | if (coin_objs[i]==NULL) { |
579 | at = find_archetype(coins[NUM_COINS-1-i]); |
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]); |
580 | if (at==NULL) LOG(llevError, "Could not find %s archetype\n", coins[NUM_COINS-1-i]); |
581 | coin_objs[i] = get_object(); |
581 | coin_objs[i] = arch_to_object (at); |
582 | copy_object(&at->clone, coin_objs[i]); |
|
|
583 | coin_objs[i]->nrof = 0; |
582 | coin_objs[i]->nrof = 0; |
584 | } |
583 | } |
585 | |
584 | |
586 | for (i=0; i<NUM_COINS; i++) { |
585 | for (i=0; i<NUM_COINS; i++) { |
587 | int num_coins; |
586 | int num_coins; |
… | |
… | |
772 | if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit)) |
771 | if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= pouch->weight_limit)) |
773 | { |
772 | { |
774 | if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) |
773 | if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) |
775 | n = (pouch->weight_limit - pouch->carrying) / w; |
774 | n = (pouch->weight_limit - pouch->carrying) / w; |
776 | |
775 | |
777 | tmp = get_object (); |
776 | tmp = arch_to_object (at); |
778 | copy_object (&at->clone, tmp); |
|
|
779 | tmp->nrof = n; |
777 | tmp->nrof = n; |
780 | amount -= (uint64)tmp->nrof * (uint64)tmp->value; |
778 | amount -= (uint64)tmp->nrof * (uint64)tmp->value; |
781 | tmp = insert_ob_in_ob (tmp, pouch); |
779 | tmp = insert_ob_in_ob (tmp, pouch); |
782 | esrv_send_item (pl, tmp); |
780 | esrv_send_item (pl, tmp); |
783 | esrv_send_item (pl, pouch); |
781 | esrv_send_item (pl, pouch); |
… | |
… | |
787 | } |
785 | } |
788 | } |
786 | } |
789 | |
787 | |
790 | if (amount / at->clone.value > 0) |
788 | if (amount / at->clone.value > 0) |
791 | { |
789 | { |
792 | tmp = get_object (); |
790 | tmp = arch_to_object (at); |
793 | copy_object (&at->clone, tmp); |
|
|
794 | tmp->nrof = amount / tmp->value; |
791 | tmp->nrof = amount / tmp->value; |
795 | amount -= (uint64)tmp->nrof * (uint64)tmp->value; |
792 | amount -= (uint64)tmp->nrof * (uint64)tmp->value; |
796 | tmp = insert_ob_in_ob (tmp, pl); |
793 | tmp = insert_ob_in_ob (tmp, pl); |
797 | esrv_send_item (pl, tmp); |
794 | esrv_send_item (pl, tmp); |
798 | esrv_send_item (pl, pl); |
795 | esrv_send_item (pl, pl); |
… | |
… | |
816 | if (at == NULL) |
813 | if (at == NULL) |
817 | return 0; |
814 | return 0; |
818 | |
815 | |
819 | if (amount > 0) |
816 | if (amount > 0) |
820 | { |
817 | { |
821 | tmp = get_object (); |
818 | tmp = arch_to_object (at); |
822 | copy_object (&at->clone, tmp); |
|
|
823 | tmp->nrof = amount; |
819 | tmp->nrof = amount; |
824 | tmp = insert_ob_in_ob (tmp, pl); |
820 | tmp = insert_ob_in_ob (tmp, pl); |
825 | esrv_send_item (pl, tmp); |
821 | esrv_send_item (pl, tmp); |
826 | esrv_send_item (pl, pl); |
822 | esrv_send_item (pl, pl); |
827 | } |
823 | } |