… | |
… | |
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; |
… | |
… | |
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->type == 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 | |
|
|
223 | diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / MAXLEVEL_TREASURE, 0.25); |
222 | double bargaining = min (0., 1. - powf (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); |
… | |
… | |
324 | * 10,000 silver or something) |
327 | * 10,000 silver or something) |
325 | */ |
328 | */ |
326 | const char * |
329 | const char * |
327 | cost_string_from_value (sint64 cost, int approx) |
330 | cost_string_from_value (sint64 cost, int approx) |
328 | { |
331 | { |
329 | static char buf[MAX_BUF]; |
|
|
330 | archetype *coin, *next_coin; |
332 | archetype *coin, *next_coin; |
331 | int num, cointype = 0; |
333 | int num, cointype = 0; |
332 | |
334 | |
333 | coin = find_next_coin (cost, &cointype); |
335 | coin = find_next_coin (cost, &cointype); |
334 | if (coin == NULL) |
336 | if (!coin) |
335 | return "nothing"; |
337 | return "nothing"; |
336 | |
338 | |
337 | num = cost / coin->value; |
339 | num = cost / coin->value; |
338 | /* so long as nrof is 32 bit, this is true. |
340 | /* so long as nrof is 32 bit, this is true. |
339 | * If it takes more coins than a person can possibly carry, this |
341 | * If it takes more coins than a person can possibly carry, this |
340 | * is basically true. |
342 | * is basically true. |
341 | */ |
343 | */ |
342 | if ((cost / coin->value) > UINT32_MAX) |
344 | if (cost / coin->value > UINT32_MAX) |
343 | { |
|
|
344 | strcpy (buf, "an unimaginable sum of money"); |
345 | return "an unimaginable sum of money"; |
345 | return buf; |
|
|
346 | } |
|
|
347 | |
346 | |
348 | cost -= num * (sint64)coin->value; |
347 | cost -= num * (sint64)coin->value; |
349 | |
348 | |
350 | sprintf (buf, "%d %s", num, num > 1 ? &coin->object::name_pl : &coin->object::name); |
349 | char *buf = format ("%d %s", num, num > 1 ? &coin->object::name_pl : &coin->object::name); |
351 | |
350 | |
352 | next_coin = find_next_coin (cost, &cointype); |
351 | next_coin = find_next_coin (cost, &cointype); |
353 | if (next_coin == NULL || approx) |
352 | if (!next_coin || approx) |
354 | return buf; |
353 | return buf; |
355 | |
354 | |
356 | coin = next_coin; |
355 | coin = next_coin; |
357 | num = cost / coin->value; |
356 | num = cost / coin->value; |
358 | cost -= num * (sint64)coin->value; |
357 | cost -= num * (sint64)coin->value; |
359 | |
358 | |
360 | sprintf (buf + strlen (buf), " and %d %s", num, num > 1 ? &coin->object::name_pl : &coin->object::name); |
359 | return format ("%s and %d %s", buf, num, num > 1 ? &coin->object::name_pl : &coin->object::name); |
361 | |
|
|
362 | return buf; |
|
|
363 | } |
360 | } |
364 | |
361 | |
365 | const char * |
362 | const char * |
366 | query_cost_string (const object *tmp, object *who, int flag) |
363 | query_cost_string (const object *tmp, object *who, int flag) |
367 | { |
364 | { |
… | |
… | |
386 | { |
383 | { |
387 | if (!idskill1 || !find_skill_by_number (who, idskill1)) |
384 | if (!idskill1 || !find_skill_by_number (who, idskill1)) |
388 | { |
385 | { |
389 | if (!idskill2 || !find_skill_by_number (who, idskill2)) |
386 | if (!idskill2 || !find_skill_by_number (who, idskill2)) |
390 | { |
387 | { |
391 | if (!find_skill_by_number (who, SK_BARGAINING)) |
388 | if (!find_skill_by_name (who, shstr_bargaining)) |
392 | { |
389 | { |
393 | static char buf[MAX_BUF]; |
|
|
394 | int num, cointype = 0; |
390 | int num, cointype = 0; |
395 | archetype *coin = find_next_coin (real_value, &cointype); |
391 | archetype *coin = find_next_coin (real_value, &cointype); |
396 | |
392 | |
397 | if (coin == NULL) |
393 | if (!coin) |
398 | return "nothing"; |
394 | return "nothing"; |
399 | |
395 | |
400 | num = real_value / coin->value; |
396 | num = real_value / coin->value; |
401 | |
397 | |
402 | if (num == 1) |
398 | if (num == 1) |
403 | sprintf (buf, "about one %s", &coin->object::name); |
399 | return format ("about one %s", &coin->object::name); |
404 | else if (num < 5) |
400 | else if (num < 5) |
405 | sprintf (buf, "a few %s", &coin->object::name_pl); |
401 | return format ("a few %s", &coin->object::name_pl); |
406 | else if (num < 10) |
402 | else if (num < 10) |
407 | sprintf (buf, "several %s", &coin->object::name_pl); |
403 | return format ("several %s", &coin->object::name_pl); |
408 | else if (num < 25) |
404 | else if (num < 25) |
409 | sprintf (buf, "a moderate amount of %s", &coin->object::name_pl); |
405 | return format ("a moderate amount of %s", &coin->object::name_pl); |
410 | else if (num < 100) |
406 | else if (num < 100) |
411 | sprintf (buf, "lots of %s", &coin->object::name_pl); |
407 | return format ("lots of %s", &coin->object::name_pl); |
412 | else if (num < 1000) |
408 | else if (num < 1000) |
413 | sprintf (buf, "a great many %s", &coin->object::name_pl); |
409 | return format ("a great many %s", &coin->object::name_pl); |
414 | else |
410 | else |
415 | sprintf (buf, "a vast quantity of %s", &coin->object::name_pl); |
411 | return format ("a vast quantity of %s", &coin->object::name_pl); |
416 | |
|
|
417 | return buf; |
|
|
418 | } |
412 | } |
419 | } |
413 | } |
420 | } |
414 | } |
421 | |
415 | |
422 | int hash = ((unsigned int) tmp->count * 174364621) & 1023; |
|
|
423 | |
|
|
424 | if (approx_range) |
416 | if (approx_range) |
425 | { |
417 | { |
|
|
418 | int hash = tmp->random_seed () & 1023; |
426 | sint64 lo = (sint64) real_value - (approx_range * hash >> 10); |
419 | sint64 lo = real_value - (approx_range * hash >> 10); |
427 | static char buf[MAX_BUF]; |
|
|
428 | |
420 | |
429 | sprintf (buf, "between %s", cost_string_from_value (lo, 1)); |
421 | return format ("between %s and %s", |
430 | sprintf (buf + strlen (buf), " and %s", cost_string_from_value (lo + approx_range, 1)); |
422 | cost_string_from_value (lo, 1), |
431 | |
423 | cost_string_from_value (lo + approx_range, 1)); |
432 | return buf; |
|
|
433 | } |
424 | } |
434 | } |
425 | } |
435 | |
426 | |
436 | return cost_string_from_value (real_value, 0); |
427 | return cost_string_from_value (real_value, 0); |
437 | } |
428 | } |
… | |
… | |
509 | * This determins the amount of exp (if any) gained for bargaining. |
500 | * This determins the amount of exp (if any) gained for bargaining. |
510 | */ |
501 | */ |
511 | 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; |
512 | |
503 | |
513 | if (saved_money > 0) |
504 | if (saved_money > 0) |
514 | change_exp (pl, saved_money, "bargaining", SK_EXP_NONE); |
505 | change_exp (pl, saved_money, shstr_bargaining, SK_EXP_NONE); |
515 | |
506 | |
516 | pay_from_container (pl, pl, to_pay); |
507 | pay_from_container (pl, pl, to_pay); |
517 | |
508 | |
518 | for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) |
509 | for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) |
519 | 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 ("gold"))) |
… | |
… | |
684 | |
675 | |
685 | for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op) |
676 | for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op) |
686 | { |
677 | { |
687 | if (op->flag [FLAG_UNPAID]) |
678 | if (op->flag [FLAG_UNPAID]) |
688 | { |
679 | { |
689 | char buf[MAX_BUF]; |
|
|
690 | snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP)); |
680 | const char *buf = query_cost_string (op, pl, F_BUY | F_SHOP); |
691 | |
681 | |
692 | if (!pay_for_item (op, pl)) |
682 | if (!pay_for_item (op, pl)) |
693 | { |
683 | { |
694 | sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl); |
684 | sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl); |
695 | |
685 | |
… | |
… | |
700 | } |
690 | } |
701 | else |
691 | else |
702 | { |
692 | { |
703 | op->clr_flag (FLAG_UNPAID); |
693 | op->clr_flag (FLAG_UNPAID); |
704 | op->clr_flag (FLAG_PLAYER_SOLD); |
694 | op->clr_flag (FLAG_PLAYER_SOLD); |
705 | new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op)); |
695 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You paid %s for %s.", buf, query_name (op)); |
706 | |
696 | |
707 | if (!merge_ob (op, op->env->inv)) |
697 | if (!merge_ob (op, op->env->inv)) |
708 | esrv_update_item (UPD_FLAGS, pl, op); |
698 | esrv_update_item (UPD_FLAGS, pl, op); |
709 | |
699 | |
710 | goto next_item; |
700 | goto next_item; |
… | |
… | |
832 | * exp/10 -> 1 for each gold coin |
822 | * exp/10 -> 1 for each gold coin |
833 | */ |
823 | */ |
834 | 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); |
835 | |
825 | |
836 | if (extra_gain > 0) |
826 | if (extra_gain > 0) |
837 | change_exp (pl, extra_gain / 10, "bargaining", SK_EXP_NONE); |
827 | change_exp (pl, extra_gain / 10, shstr_bargaining, SK_EXP_NONE); |
838 | |
828 | |
839 | pay_player (pl, amount); |
829 | pay_player (pl, amount); |
840 | |
830 | |
841 | 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.", |
842 | 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)); |
… | |
… | |
1073 | } |
1063 | } |
1074 | |
1064 | |
1075 | static void |
1065 | static void |
1076 | add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated) |
1066 | add_shop_item (object *tmp, shopinv * items, int *numitems, int *numallocated) |
1077 | { |
1067 | { |
1078 | #if 0 |
|
|
1079 | char buf[MAX_BUF]; |
|
|
1080 | #endif |
|
|
1081 | /* clear unpaid flag so that doesn't come up in query |
1068 | /* clear unpaid flag so that doesn't come up in query |
1082 | * string. We clear nrof so that we can better sort |
1069 | * string. We clear nrof so that we can better sort |
1083 | * the object names. |
1070 | * the object names. |
1084 | */ |
1071 | */ |
1085 | |
1072 | |