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.10 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.23 by root, Thu Dec 14 22:45:41 2006 UTC

1
2/*
3 * static char *rcsid_shop_c =
4 * "$Id: shop.C,v 1.10 2006/09/10 15:59:57 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
28*/ 22*/
29 23
30#include <global.h> 24#include <global.h>
31#include <spells.h> 25#include <spells.h>
32#include <skills.h> 26#include <skills.h>
47#define SPECIALISATION_EFFECT 0.5 41#define SPECIALISATION_EFFECT 0.5
48 42
49/* price a shopkeeper will give someone they neither like nor dislike */ 43/* price a shopkeeper will give someone they neither like nor dislike */
50#define NEUTRAL_RATIO 0.8 44#define NEUTRAL_RATIO 0.8
51 45
52static uint64 pay_from_container (object *pl, object *pouch, uint64 to_pay); 46static void pay_from_container (object *pl, object *pouch, sint64 &to_pay);
53static uint64 value_limit (uint64 val, int quantity, const object *who, int isshop); 47static sint64 value_limit (sint64 val, int quantity, const object *who, int isshop);
54static double shop_specialisation_ratio (const object *item, const mapstruct *map); 48static double shop_specialisation_ratio (const object *item, const maptile *map);
55static double shop_greed (const mapstruct *map); 49static double shop_greed (const maptile *map);
56 50
57#define NUM_COINS 4 /* number of coin types */ 51#define NUM_COINS 4 /* number of coin types */
58static const char *const coins[] = { "royalty", "platinacoin", "goldcoin", "silvercoin", NULL }; 52static const char *const coins[] = { "royalty", "platinacoin", "goldcoin", "silvercoin", NULL };
59 53
60/* Added F_TRUE flag to define.h to mean that the price should not 54/* Added F_TRUE flag to define.h to mean that the price should not
80 * thus remained 0. 74 * thus remained 0.
81 * 75 *
82 * Mark Wedel (mwedel@pyramid.com) 76 * Mark Wedel (mwedel@pyramid.com)
83 */ 77 */
84 78
85static uint64 approx_range; 79static sint64 approx_range;
86 80
87uint64 81sint64
88query_cost (const object *tmp, object *who, int flag) 82query_cost (const object *tmp, object *who, int flag)
89{ 83{
90 double val; 84 double val;
91 int number; /* used to better calculate value */ 85 int number; /* used to better calculate value */
92 int no_bargain; 86 int no_bargain;
104 approximate = flag & F_APPROX; 98 approximate = flag & F_APPROX;
105 shop = flag & F_SHOP; 99 shop = flag & F_SHOP;
106 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP); 100 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP);
107 101
108 if (tmp->type == MONEY) 102 if (tmp->type == MONEY)
109 return (tmp->nrof * tmp->value); 103 return tmp->nrof * tmp->value;
104
110 if (tmp->type == GEM) 105 if (tmp->type == GEM)
111 { 106 {
112 if (flag == F_TRUE) 107 if (flag == F_TRUE)
113 return (tmp->nrof * tmp->value); 108 return (tmp->nrof * tmp->value);
109
114 if (flag == F_BUY) 110 if (flag == F_BUY)
115 return (uint64) (1.03 * tmp->nrof * tmp->value); 111 return (sint64) (1.03 * tmp->nrof * tmp->value);
112
116 if (flag == F_SELL) 113 if (flag == F_SELL)
117 return (uint64) (0.97 * tmp->nrof * tmp->value); 114 return (sint64) (0.97 * tmp->nrof * tmp->value);
115
118 LOG (llevError, "Query_cost: Gem type with unknown flag : %d\n", flag); 116 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ());
119 return 0; 117 return 0;
120 } 118 }
119
121 number = tmp->nrof; 120 number = tmp->nrof;
122 if (number == 0) 121 if (number == 0)
123 number = 1; 122 number = 1;
124 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified) 123 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified)
125 { 124 {
200 val /= 50; 199 val /= 50;
201 } 200 }
202 201
203 /* Limit amount of money you can get for really great items. */ 202 /* Limit amount of money you can get for really great items. */
204 if (flag == F_SELL) 203 if (flag == F_SELL)
205 val = value_limit ((uint64) val, number, who, shop); 204 val = value_limit ((sint64) val, number, who, shop);
206 205
207 // use a nonlinear price adjustment. as my predecessor said, don't change 206 // use a nonlinear price adjustment. as my predecessor said, don't change
208 // the archetypes, its work required for balancing, and we don't care. 207 // the archetypes, its work required for balancing, and we don't care.
209 //val = pow (val, 1.05); 208 //val = pow (val, 1.05);
210 209
224 const typedata *tmptype; 223 const typedata *tmptype;
225 224
226 tmptype = get_typedata (tmp->type); 225 tmptype = get_typedata (tmp->type);
227 226
228 if (find_skill_by_number (who, SK_BARGAINING)) 227 if (find_skill_by_number (who, SK_BARGAINING))
229 {
230 lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level; 228 lev_bargain = find_skill_by_number (who, SK_BARGAINING)->level;
231 } 229
232 if (tmptype) 230 if (tmptype)
233 { 231 {
234 idskill1 = tmptype->identifyskill; 232 idskill1 = tmptype->identifyskill;
233
235 if (idskill1) 234 if (idskill1)
236 { 235 {
237 idskill2 = tmptype->identifyskill2; 236 idskill2 = tmptype->identifyskill2;
237
238 if (find_skill_by_number (who, idskill1)) 238 if (find_skill_by_number (who, idskill1))
239 {
240 lev_identify = find_skill_by_number (who, idskill1)->level; 239 lev_identify = find_skill_by_number (who, idskill1)->level;
241 } 240
242 if (idskill2 && find_skill_by_number (who, idskill2)) 241 if (idskill2 && find_skill_by_number (who, idskill2))
243 {
244 lev_identify += find_skill_by_number (who, idskill2)->level; 242 lev_identify += find_skill_by_number (who, idskill2)->level;
245 }
246 } 243 }
247 } 244 }
248 else 245 else
249 LOG (llevError, "Query_cost: item %s hasn't got a valid type\n", &tmp->name); 246 LOG (llevError, "Query_cost: item %s hasn't got a valid type\n", tmp->debug_desc ());
250 247
251 /* ratio determines how much of the price modification 248 /* ratio determines how much of the price modification
252 * will come from the basic stat charisma 249 * will come from the basic stat charisma
253 * the rest will come from the level in bargaining skill 250 * the rest will come from the level in bargaining skill
254 */ 251 */
266 val -= (val * diff); 263 val -= (val * diff);
267 264
268 // now find a price range. the less good we can judge, the larger the range is 265 // now find a price range. the less good we can judge, the larger the range is
269 // then the range is adjusted randomly around the correct value 266 // then the range is adjusted randomly around the correct value
270 if (approximate) 267 if (approximate)
271 approx_range = uint64 (val / sqrt (lev_identify * 3 + 1)); 268 approx_range = sint64 (val / sqrt (lev_identify * 3 + 1));
272 } 269 }
273 270
274 /* I don't think this should really happen - if it does, it indicates and 271 /* I don't think this should really happen - if it does, it indicates and
275 * overflow of diff above. That shoudl only happen if 272 * overflow of diff above. That shoudl only happen if
276 * we are selling objects - in that case, the person just 273 * we are selling objects - in that case, the person just
315 * pointful, and could give fun with rounding. 312 * pointful, and could give fun with rounding.
316 */ 313 */
317 if (who->map->path != NULL && val > 50) 314 if (who->map->path != NULL && val > 50)
318 val = (val + 0.05 * (sint64) val * cos (tmp->count + strlen (who->map->path))); 315 val = (val + 0.05 * (sint64) val * cos (tmp->count + strlen (who->map->path)));
319 } 316 }
320 return (uint64) val; 317 return (sint64) val;
321} 318}
322 319
323/* Find the coin type that is worth more the 'c'. Starts at the 320/* Find the coin type that is worth more the 'c'. Starts at the
324 * cointype placement. 321 * cointype placement.
325 */ 322 */
326 323
327static archetype * 324static archetype *
328find_next_coin (uint64 c, int *cointype) 325find_next_coin (sint64 c, int *cointype)
329{ 326{
330 archetype *coin; 327 archetype *coin;
331 328
332 do 329 do
333 { 330 {
334 if (coins[*cointype] == NULL) 331 if (coins[*cointype] == NULL)
335 return NULL; 332 return NULL;
336 coin = find_archetype (coins[*cointype]); 333 coin = archetype::find (coins[*cointype]);
337 if (coin == NULL) 334 if (coin == NULL)
338 return NULL; 335 return NULL;
339 *cointype += 1; 336 *cointype += 1;
340 } 337 }
341 while ((uint64) coin->clone.value > c); 338 while (coin->clone.value > c);
342 339
343 return coin; 340 return coin;
344} 341}
345 342
346/* This returns a string of how much something is worth based on 343/* This returns a string of how much something is worth based on
352 * coins, there are certainly issues - the easiest fix at that 349 * coins, there are certainly issues - the easiest fix at that
353 * time is to add a higher denomination (mithril piece with 350 * time is to add a higher denomination (mithril piece with
354 * 10,000 silver or something) 351 * 10,000 silver or something)
355 */ 352 */
356const char * 353const char *
357cost_string_from_value (uint64 cost, int approx) 354cost_string_from_value (sint64 cost, int approx)
358{ 355{
359 static char buf[MAX_BUF]; 356 static char buf[MAX_BUF];
360 archetype *coin, *next_coin; 357 archetype *coin, *next_coin;
361 int num, cointype = 0; 358 int num, cointype = 0;
362 359
373 { 370 {
374 strcpy (buf, "an unimaginable sum of money"); 371 strcpy (buf, "an unimaginable sum of money");
375 return buf; 372 return buf;
376 } 373 }
377 374
378 cost -= (uint64) num *(uint64) coin->clone.value; 375 cost -= num * (sint64)coin->clone.value;
379 376
380 sprintf (buf, "%d %s", num, num > 1 ? &coin->clone.name_pl : &coin->clone.name); 377 sprintf (buf, "%d %s", num, num > 1 ? &coin->clone.name_pl : &coin->clone.name);
381 378
382 next_coin = find_next_coin (cost, &cointype); 379 next_coin = find_next_coin (cost, &cointype);
383 if (next_coin == NULL || approx) 380 if (next_coin == NULL || approx)
384 return buf; 381 return buf;
385 382
386 coin = next_coin; 383 coin = next_coin;
387 num = cost / coin->clone.value; 384 num = cost / coin->clone.value;
388 cost -= (uint64) num *(uint64) coin->clone.value; 385 cost -= num * (sint64)coin->clone.value;
389 386
390 sprintf (buf + strlen (buf), " and %d %s", num, num > 1 ? &coin->clone.name_pl : &coin->clone.name); 387 sprintf (buf + strlen (buf), " and %d %s", num, num > 1 ? &coin->clone.name_pl : &coin->clone.name);
391 388
392 return buf; 389 return buf;
393} 390}
394 391
395const char * 392const char *
396query_cost_string (const object *tmp, object *who, int flag) 393query_cost_string (const object *tmp, object *who, int flag)
397{ 394{
398 uint64 real_value = query_cost (tmp, who, flag); 395 sint64 real_value = query_cost (tmp, who, flag);
399 int idskill1 = 0; 396 int idskill1 = 0;
400 int idskill2 = 0; 397 int idskill2 = 0;
401 const typedata *tmptype; 398 const typedata *tmptype;
402 399
403 tmptype = get_typedata (tmp->type); 400 tmptype = get_typedata (tmp->type);
449 446
450 int hash = ((unsigned int) tmp->count * 174364621) & 1023; 447 int hash = ((unsigned int) tmp->count * 174364621) & 1023;
451 448
452 if (approx_range) 449 if (approx_range)
453 { 450 {
454 uint64 lo = (sint64) real_value - (approx_range * hash >> 10); 451 sint64 lo = (sint64) real_value - (approx_range * hash >> 10);
455 static char buf[MAX_BUF]; 452 static char buf[MAX_BUF];
456 453
457 sprintf (buf, "between %s", cost_string_from_value (lo, 1)); 454 sprintf (buf, "between %s", cost_string_from_value (lo, 1));
458 sprintf (buf + strlen (buf), " and %s", cost_string_from_value (lo + approx_range, 1)); 455 sprintf (buf + strlen (buf), " and %s", cost_string_from_value (lo + approx_range, 1));
459 456
465} 462}
466 463
467/* This function finds out how much money the player is carrying, 464/* This function finds out how much money the player is carrying,
468 * including what is in containers. 465 * including what is in containers.
469 */ 466 */
470uint64 467sint64
471query_money (const object *op) 468query_money (const object *op)
472{ 469{
473 object *tmp; 470 object *tmp;
474 uint64 total = 0; 471 sint64 total = 0;
475 472
476 if (op->type != PLAYER && op->type != CONTAINER) 473 if (op->type != PLAYER && op->type != CONTAINER)
477 { 474 {
478 LOG (llevError, "Query money called with non player/container\n"); 475 LOG (llevError, "Query money called with non player/container\n");
479 return 0; 476 return 0;
480 } 477 }
478
481 for (tmp = op->inv; tmp; tmp = tmp->below) 479 for (tmp = op->inv; tmp; tmp = tmp->below)
482 {
483 if (tmp->type == MONEY) 480 if (tmp->type == MONEY)
484 {
485 total += (uint64) tmp->nrof * (uint64) tmp->value; 481 total += tmp->nrof * (sint64)tmp->value;
486 }
487 else if (tmp->type == CONTAINER && QUERY_FLAG (tmp, FLAG_APPLIED) && (tmp->race == NULL || strstr (tmp->race, "gold"))) 482 else if (tmp->type == CONTAINER && QUERY_FLAG (tmp, FLAG_APPLIED) && (tmp->race == NULL || strstr (tmp->race, "gold")))
488 {
489 total += query_money (tmp); 483 total += query_money (tmp);
490 } 484
491 }
492 return total; 485 return total;
493} 486}
494 487
495/* TCHIZE: This function takes the amount of money from the 488/* TCHIZE: This function takes the amount of money from the
496 * the player inventory and from it's various pouches using the 489 * the player inventory and from it's various pouches using the
497 * pay_from_container function. 490 * pay_from_container function.
498 * returns 0 if not possible. 1 if success 491 * returns 0 if not possible. 1 if success
499 */ 492 */
500int 493int
501pay_for_amount (uint64 to_pay, object *pl) 494pay_for_amount (sint64 to_pay, object *pl)
502{ 495{
503 object *pouch; 496 object *pouch;
504 497
505 if (to_pay == 0) 498 if (to_pay == 0)
506 return 1; 499 return 1;
500
507 if (to_pay > query_money (pl)) 501 if (to_pay > query_money (pl))
508 return 0; 502 return 0;
509 503
510 to_pay = pay_from_container (pl, pl, to_pay); 504 pay_from_container (pl, pl, to_pay);
511 505
512 for (pouch = pl->inv; (pouch != NULL) && (to_pay > 0); pouch = pouch->below) 506 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
513 {
514 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr (pouch->race, "gold"))) 507 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr (pouch->race, "gold")))
515 {
516 to_pay = pay_from_container (pl, pouch, to_pay); 508 pay_from_container (pl, pouch, to_pay);
517 } 509
518 }
519 fix_player (pl); 510 fix_player (pl);
520 return 1; 511 return 1;
521} 512}
522 513
523/* DAMN: This is now a wrapper for pay_from_container, which is 514/* DAMN: This is now a wrapper for pay_from_container, which is
526 * of the price was paid from. 517 * of the price was paid from.
527 */ 518 */
528int 519int
529pay_for_item (object *op, object *pl) 520pay_for_item (object *op, object *pl)
530{ 521{
531 uint64 to_pay = query_cost (op, pl, F_BUY | F_SHOP); 522 sint64 to_pay = query_cost (op, pl, F_BUY | F_SHOP);
532 object *pouch; 523 object *pouch;
533 uint64 saved_money; 524 sint64 saved_money;
534 525
535 if (to_pay == 0) 526 if (to_pay == 0)
536 return 1; 527 return 1;
528
537 if (to_pay > query_money (pl)) 529 if (to_pay > query_money (pl))
538 return 0; 530 return 0;
539 531
540 /* We compare the paid price with the one for a player 532 /* We compare the paid price with the one for a player
541 * without bargaining skill. 533 * without bargaining skill.
544 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay; 536 saved_money = query_cost (op, pl, F_BUY | F_NO_BARGAIN | F_SHOP) - to_pay;
545 537
546 if (saved_money > 0) 538 if (saved_money > 0)
547 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE); 539 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE);
548 540
549 to_pay = pay_from_container (pl, pl, to_pay); 541 pay_from_container (pl, pl, to_pay);
550 542
551 for (pouch = pl->inv; (pouch != NULL) && (to_pay > 0); pouch = pouch->below) 543 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
552 {
553 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr (pouch->race, "gold"))) 544 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (pouch->race == NULL || strstr (pouch->race, "gold")))
554 {
555 to_pay = pay_from_container (pl, pouch, to_pay); 545 pay_from_container (pl, pouch, to_pay);
556 } 546
557 }
558 if (settings.real_wiz == FALSE && QUERY_FLAG (pl, FLAG_WAS_WIZ)) 547 if (settings.real_wiz == FALSE && QUERY_FLAG (pl, FLAG_WAS_WIZ))
559 SET_FLAG (op, FLAG_WAS_WIZ); 548 SET_FLAG (op, FLAG_WAS_WIZ);
549
560 fix_player (pl); 550 fix_player (pl);
561 return 1; 551 return 1;
562} 552}
563 553
564/* This pays for the item, and takes the proper amount of money off 554/* This pays for the item, and takes the proper amount of money off
573 * 563 *
574 * pouch is the container (pouch or player) to remove the coins from. 564 * pouch is the container (pouch or player) to remove the coins from.
575 * to_pay is the required amount. 565 * to_pay is the required amount.
576 * returns the amount still missing after using "pouch". 566 * returns the amount still missing after using "pouch".
577 */ 567 */
578static uint64 568static void
579pay_from_container (object *pl, object *pouch, uint64 to_pay) 569pay_from_container (object *pl, object *pouch, sint64 &to_pay)
580{ 570{
581 int count, i; 571 int count, i;
582 uint64 remain; 572 object *tmp, *next;
583 object *tmp, *coin_objs[NUM_COINS], *next;
584 archetype *at; 573 archetype *at;
585 574
586 if (pouch->type != PLAYER && pouch->type != CONTAINER) 575 if (pouch->type != PLAYER && pouch->type != CONTAINER)
587 return to_pay; 576 return;
588 577
589 remain = to_pay; 578 object *coin_objs[NUM_COINS] = { 0 };
590 for (i = 0; i < NUM_COINS; i++)
591 coin_objs[i] = NULL;
592 579
593 /* This hunk should remove all the money objects from the player/container */ 580 /* This hunk should remove all the money objects from the player/container */
594 for (tmp = pouch->inv; tmp; tmp = next) 581 for (tmp = pouch->inv; tmp; tmp = next)
595 { 582 {
596 next = tmp->below; 583 next = tmp->below;
597 584
598 if (tmp->type == MONEY) 585 if (tmp->type == MONEY)
599 { 586 {
600 for (i = 0; i < NUM_COINS; i++) 587 for (i = 0; i < NUM_COINS; i++)
601 { 588 {
602 if (!strcmp (coins[NUM_COINS - 1 - i], tmp->arch->name) && (tmp->value == tmp->arch->clone.value)) 589 if (tmp->value == tmp->arch->clone.value && !strcmp (coins[NUM_COINS - 1 - i], tmp->arch->name))
603 { 590 {
604
605 /* This should not happen, but if it does, just * 591 // This should not happen, but if it does, just merge the two.
606 * merge the two. */
607 if (coin_objs[i] != NULL) 592 if (coin_objs [i])
608 { 593 {
609 LOG (llevError, "%s has two money entries of (%s)\n", &pouch->name, coins[NUM_COINS - 1 - i]); 594 LOG (llevError, "%s has two money entries of (%s)\n", &pouch->name, coins[NUM_COINS - 1 - i]);
610 remove_ob (tmp); 595 tmp->remove ();
611 coin_objs[i]->nrof += tmp->nrof; 596 coin_objs[i]->nrof += tmp->nrof;
612 esrv_del_item (pl->contr, tmp->count); 597 esrv_del_item (pl->contr, tmp->count);
613 free_object (tmp); 598 tmp->destroy ();
614 } 599 }
615 else 600 else
616 { 601 {
617 remove_ob (tmp); 602 tmp->remove ();
603
618 if (pouch->type == PLAYER) 604 if (pouch->type == PLAYER)
619 esrv_del_item (pl->contr, tmp->count); 605 esrv_del_item (pl->contr, tmp->count);
606
620 coin_objs[i] = tmp; 607 coin_objs[i] = tmp;
621 } 608 }
609
622 break; 610 break;
623 } 611 }
624 } 612 }
613
625 if (i == NUM_COINS) 614 if (i == NUM_COINS)
626 LOG (llevError, "in pay_for_item: Did not find string match for %s\n", &tmp->arch->name); 615 LOG (llevError, "in pay_for_item: Did not find string match for %s\n", &tmp->arch->name);
627 } 616 }
628 } 617 }
629 618
630 /* Fill in any gaps in the coin_objs array - needed to make change. */ 619 /* Fill in any gaps in the coin_objs array - needed to make change. */
631 /* Note that the coin_objs array goes from least value to greatest value */ 620 /* Note that the coin_objs array goes from least value to greatest value */
632 for (i = 0; i < NUM_COINS; i++) 621 for (i = 0; i < NUM_COINS; i++)
633 if (coin_objs[i] == NULL) 622 if (!coin_objs[i])
634 { 623 {
635 at = find_archetype (coins[NUM_COINS - 1 - i]); 624 at = archetype::find (coins[NUM_COINS - 1 - i]);
625
636 if (at == NULL) 626 if (at == NULL)
637 LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]); 627 LOG (llevError, "Could not find %s archetype\n", coins[NUM_COINS - 1 - i]);
628
638 coin_objs[i] = arch_to_object (at); 629 coin_objs[i] = arch_to_object (at);
639 coin_objs[i]->nrof = 0; 630 coin_objs[i]->nrof = 0;
640 } 631 }
641 632
642 for (i = 0; i < NUM_COINS; i++) 633 for (i = 0; i < NUM_COINS; i++)
643 { 634 {
644 int num_coins; 635 object &coin = *coin_objs[i];
636 sint64 num_coins = min ((to_pay + coin.value - 1) / coin.value, coin.nrof);
637 to_pay -= num_coins * coin.value;
645 638
646 if (coin_objs[i]->nrof * coin_objs[i]->value > remain)
647 {
648 num_coins = remain / coin_objs[i]->value;
649 if ((uint64) num_coins * (uint64) coin_objs[i]->value < remain)
650 num_coins++;
651 }
652 else
653 {
654 num_coins = coin_objs[i]->nrof;
655 }
656 remain -= (sint64) num_coins *(sint64) coin_objs[i]->value;
657
658 coin_objs[i]->nrof -= num_coins; 639 coin.nrof -= num_coins;
659 /* Now start making change. Start at the coin value 640 /* Now start making change. Start at the coin value
660 * below the one we just did, and work down to 641 * below the one we just did, and work down to
661 * the lowest value. 642 * the lowest value.
662 */ 643 */
663 count = i - 1; 644 count = i - 1;
645
664 while (remain < 0 && count >= 0) 646 while (to_pay < 0 && count >= 0)
665 { 647 {
666 num_coins = -remain / coin_objs[count]->value; 648 num_coins = (-to_pay) / coin_objs[count]->value;
667 coin_objs[count]->nrof += num_coins; 649 coin_objs[count]->nrof += num_coins;
668 remain += num_coins * coin_objs[count]->value; 650 to_pay += num_coins * coin_objs[count]->value;
669 count--; 651 count--;
670 } 652 }
671 } 653 }
654
672 for (i = 0; i < NUM_COINS; i++) 655 for (i = 0; i < NUM_COINS; i++)
673 { 656 {
674 if (coin_objs[i]->nrof) 657 if (coin_objs[i]->nrof)
675 { 658 {
676 object *tmp = insert_ob_in_ob (coin_objs[i], pouch); 659 object *tmp = insert_ob_in_ob (coin_objs[i], pouch);
677 660
678 esrv_send_item (pl, tmp); 661 esrv_send_item (pl, tmp);
679 esrv_send_item (pl, pouch); 662 esrv_send_item (pl, pouch);
663
680 if (pl != pouch) 664 if (pl != pouch)
681 esrv_update_item (UPD_WEIGHT, pl, pouch); 665 esrv_update_item (UPD_WEIGHT, pl, pouch);
666
682 if (pl->type != PLAYER) 667 if (pl->type != PLAYER)
683 {
684 esrv_send_item (pl, pl); 668 esrv_send_item (pl, pl);
685 }
686 } 669 }
687 else 670 else
688 { 671 coin_objs[i]->destroy ();
689 free_object (coin_objs[i]);
690 }
691 } 672 }
692 return (remain);
693} 673}
694 674
695/* Checks all unpaid items in op's inventory, adds up all the money they 675/* Checks all unpaid items in op's inventory, adds up all the money they
696 * have, and checks that they can actually afford what they want to buy. 676 * have, and checks that they can actually afford what they want to buy.
697 * Returns 1 if they can, and 0 if they can't. also prints an appropriate message 677 * Returns 1 if they can, and 0 if they can't. also prints an appropriate message
698 * to the player 678 * to the player
699 */ 679 */
700
701int 680int
702can_pay (object *pl) 681can_pay (object *pl)
703{ 682{
704 int unpaid_count = 0, i; 683 int unpaid_count = 0;
705 uint64 unpaid_price = 0; 684 sint64 unpaid_price = 0;
706 uint64 player_wealth = query_money (pl); 685 sint64 player_wealth = query_money (pl);
707 object *item;
708 uint32 coincount[NUM_COINS];
709 686
710 if (!pl || pl->type != PLAYER) 687 if (!pl || pl->type != PLAYER)
711 { 688 {
712 LOG (llevError, "can_pay(): called against something that isn't a player\n"); 689 LOG (llevError, "can_pay(): called against something that isn't a player\n");
713 return 0; 690 return 0;
714 } 691 }
715 for (i = 0; i < NUM_COINS; i++) 692
716 coincount[i] = 0; 693 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
717 for (item = pl->inv; item;) 694 if (QUERY_FLAG (item, FLAG_UNPAID))
718 {
719 if QUERY_FLAG
720 (item, FLAG_UNPAID)
721 { 695 {
722 unpaid_count++; 696 unpaid_count++;
723 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP); 697 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP);
724 } 698 }
725 /* merely converting the player's monetary wealth won't do, if we did that, 699
726 * we could print the wrong numbers for the coins, so we count the money instead
727 */
728 for (i = 0; i < NUM_COINS; i++)
729 if (!strcmp (coins[i], item->arch->name))
730 coincount[i] += item->nrof;
731 if (item->inv)
732 item = item->inv;
733 else if (item->below)
734 item = item->below;
735 else if (item->env && item->env != pl && item->env->below)
736 item = item->env->below;
737 else
738 item = NULL;
739 }
740 if (unpaid_price > player_wealth) 700 if (unpaid_price > player_wealth)
741 { 701 {
742 char buf[MAX_BUF]; 702 char buf[MAX_BUF];
743 char cost[MAX_BUF]; 703 char cost[MAX_BUF];
744 char missing[MAX_BUF]; 704 char missing[MAX_BUF];
745 705
746 sprintf (cost, "%s", cost_string_from_value (unpaid_price, 0)); 706 snprintf (cost, MAX_BUF, "%s", cost_string_from_value (unpaid_price, 0));
747 sprintf (missing, "%s", cost_string_from_value (unpaid_price - player_wealth, 0)); 707 snprintf (missing, MAX_BUF, "%s", cost_string_from_value (unpaid_price - player_wealth, 0));
748 708
749 sprintf (buf, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.", 709 snprintf (buf, MAX_BUF, "You have %d unpaid items that would cost you %s. You need another %s to be able to afford that.",
750 unpaid_count, cost, missing); 710 unpaid_count, cost, missing);
751 new_draw_info (NDI_UNIQUE, 0, pl, buf); 711 new_draw_info (NDI_UNIQUE, 0, pl, buf);
712
752 return 0; 713 return 0;
753 } 714 }
754 else 715 else
755 return 1; 716 return 1;
756} 717}
757
758 718
759/* Better get_payment, descends containers looking for 719/* Better get_payment, descends containers looking for
760 * unpaid items, and pays for them. 720 * unpaid items, and pays for them.
761 * returns 0 if the player still has unpaid items. 721 * returns 0 if the player still has unpaid items.
762 * returns 1 if the player has paid for everything. 722 * returns 1 if the player has paid for everything.
763 * pl is the player buying the stuff. 723 * pl is the player buying the stuff.
764 * op is the object we are examining. If op has
765 * and inventory, we examine that. IF there are objects
766 * below op, we descend down.
767 */ 724 */
768int 725int
769get_payment (object *pl, object *op) 726get_payment (object *pl)
770{ 727{
771 char buf[MAX_BUF]; 728 for (;;)
772 int ret = 1;
773
774 if (op != NULL && op->inv)
775 ret = get_payment (pl, op->inv);
776
777 if (!ret)
778 return 0;
779
780 if (op != NULL && op->below)
781 ret = get_payment (pl, op->below);
782
783 if (!ret)
784 return 0;
785
786 if (op != NULL && QUERY_FLAG (op, FLAG_UNPAID))
787 { 729 {
788 strncpy (buf, query_cost_string (op, pl, F_BUY | F_SHOP), MAX_BUF); 730 next_item:
789 buf[MAX_BUF - 1] = '\0';
790 if (!pay_for_item (op, pl))
791 {
792 uint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
793 731
794 CLEAR_FLAG (op, FLAG_UNPAID); 732 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op)
795 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op));
796 SET_FLAG (op, FLAG_UNPAID);
797 return 0;
798 } 733 {
799 else
800 {
801 object *tmp;
802 tag_t c = op->count;
803
804 CLEAR_FLAG (op, FLAG_UNPAID); 734 if (QUERY_FLAG (op, FLAG_UNPAID))
805 CLEAR_FLAG (op, FLAG_PLAYER_SOLD);
806 new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op));
807 tmp = merge_ob (op, NULL);
808 if (pl->type == PLAYER)
809 { 735 {
810 if (tmp) 736 char buf[MAX_BUF];
811 { /* it was merged */ 737 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP));
812 esrv_del_item (pl->contr, c); 738
813 op = tmp; 739 if (!pay_for_item (op, pl))
740 {
741 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
742
743 CLEAR_FLAG (op, FLAG_UNPAID);
744 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op));
745 SET_FLAG (op, FLAG_UNPAID);
746 return 0;
814 } 747 }
748 else
749 {
750 object *tmp;
751
752 CLEAR_FLAG (op, FLAG_UNPAID);
753 CLEAR_FLAG (op, FLAG_PLAYER_SOLD);
754 new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op));
755 tmp = merge_ob (op, NULL);
756
757 if (pl->type == PLAYER)
758 {
759 if (tmp)
760 { /* it was merged */
761 esrv_del_item (pl->contr, op->count);
762 op = tmp;
763 }
764
815 esrv_send_item (pl, op); 765 esrv_send_item (pl, op);
766 }
767
768 goto next_item;
769 }
816 } 770 }
817 } 771 }
818 } 772
819 return 1; 773 return 1;
774 }
820} 775}
821 776
822/* written by elmex: 777/* written by elmex:
823 * moved this code from sell_item () here to have a function 778 * moved this code from sell_item () here to have a function
824 * that pays the player an amount. Mainly put the code here to 779 * that pays the player an amount. Mainly put the code here to
829 * or put it on the ground under the player. This way the player can still 784 * or put it on the ground under the player. This way the player can still
830 * go somewhere and unload the money at a safe place. 785 * go somewhere and unload the money at a safe place.
831 * 786 *
832 */ 787 */
833void 788void
834pay_player (object *pl, uint64 amount) 789pay_player (object *pl, sint64 amount)
835{ 790{
836 int count = 0; 791 int count = 0;
837 archetype *at = 0; 792 archetype *at = 0;
838 object *pouch = 0, *tmp = 0; 793 object *pouch = 0, *tmp = 0;
839 794
840 for (count = 0; coins[count] != NULL; count++) 795 for (count = 0; coins[count] != NULL; count++)
841 { 796 {
842 at = find_archetype (coins[count]); 797 at = archetype::find (coins[count]);
843 798
844 if (at == NULL) 799 if (at == NULL)
845 LOG (llevError, "Could not find %s archetype\n", coins[count]); 800 LOG (llevError, "Could not find %s archetype\n", coins[count]);
846 else if ((amount / at->clone.value) > 0) 801 else if ((amount / at->clone.value) > 0)
847 { 802 {
860 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n) 815 if (pouch->weight_limit && (pouch->weight_limit - pouch->carrying) / w < n)
861 n = (pouch->weight_limit - pouch->carrying) / w; 816 n = (pouch->weight_limit - pouch->carrying) / w;
862 817
863 tmp = arch_to_object (at); 818 tmp = arch_to_object (at);
864 tmp->nrof = n; 819 tmp->nrof = n;
865 amount -= (uint64) tmp->nrof * (uint64) tmp->value; 820 amount -= tmp->nrof * tmp->value;
866 tmp = insert_ob_in_ob (tmp, pouch); 821 tmp = insert_ob_in_ob (tmp, pouch);
867 esrv_send_item (pl, tmp); 822 esrv_send_item (pl, tmp);
868 esrv_send_item (pl, pouch); 823 esrv_send_item (pl, pouch);
869 esrv_update_item (UPD_WEIGHT, pl, pouch); 824 esrv_update_item (UPD_WEIGHT, pl, pouch);
870 esrv_send_item (pl, pl); 825 esrv_send_item (pl, pl);
874 829
875 if (amount / at->clone.value > 0) 830 if (amount / at->clone.value > 0)
876 { 831 {
877 tmp = arch_to_object (at); 832 tmp = arch_to_object (at);
878 tmp->nrof = amount / tmp->value; 833 tmp->nrof = amount / tmp->value;
879 amount -= (uint64) tmp->nrof * (uint64) tmp->value; 834 amount -= tmp->nrof * tmp->value;
880 tmp = insert_ob_in_ob (tmp, pl); 835 tmp = insert_ob_in_ob (tmp, pl);
881 esrv_send_item (pl, tmp); 836 esrv_send_item (pl, tmp);
882 esrv_send_item (pl, pl); 837 esrv_send_item (pl, pl);
883 } 838 }
884 } 839 }
885 } 840 }
886 841
887 if (amount != 0) 842 if (amount != 0)
888#ifndef WIN32
889 LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount); 843 LOG (llevError, "Warning - payment in pay_player () not zero: %llu\n", amount);
890#else
891 LOG (llevError, "Warning - payment in pay_player () not zero: %I64u\n", amount);
892#endif
893} 844}
894 845
895/* elmex: this is for the bank plugin :( */ 846/* elmex: this is for the bank plugin :( */
896uint64 847sint64
897pay_player_arch (object *pl, const char *arch, uint64 amount) 848pay_player_arch (object *pl, const char *arch, sint64 amount)
898{ 849{
899 archetype *at = find_archetype (arch); 850 archetype *at = archetype::find (arch);
900 object *tmp = NULL; 851 object *tmp = NULL;
901 852
902 if (at == NULL) 853 if (at == NULL)
903 return 0; 854 return 0;
904 855
922 * remaining coins in character's inventory. 873 * remaining coins in character's inventory.
923 */ 874 */
924void 875void
925sell_item (object *op, object *pl) 876sell_item (object *op, object *pl)
926{ 877{
927 uint64 amount = query_cost (op, pl, F_SELL | F_SHOP), extra_gain; 878 sint64 amount = query_cost (op, pl, F_SELL | F_SHOP), extra_gain;
928 879
929 if (pl == NULL || pl->type != PLAYER) 880 if (pl == NULL || pl->type != PLAYER)
930 { 881 {
931 LOG (llevDebug, "Object other than player tried to sell something.\n"); 882 LOG (llevDebug, "Object other than player tried to sell something.\n");
932 return; 883 return;
974 * item based on the shops specialisation. Does not take account of greed, 925 * item based on the shops specialisation. Does not take account of greed,
975 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any 926 * returned value is between (2*SPECIALISATION_EFFECT-1) and 1 and in any
976 * event is never less than 0.1 (calling functions divide by it) 927 * event is never less than 0.1 (calling functions divide by it)
977 */ 928 */
978static double 929static double
979shop_specialisation_ratio (const object *item, const mapstruct *map) 930shop_specialisation_ratio (const object *item, const maptile *map)
980{ 931{
981 shopitems *items = map->shopitems; 932 shopitems *items = map->shopitems;
982 double ratio = SPECIALISATION_EFFECT, likedness = 0.001; 933 double ratio = SPECIALISATION_EFFECT, likedness = 0.001;
983 int i; 934 int i;
984 935
985 if (item == NULL) 936 if (item == NULL)
986 { 937 {
987 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path); 938 LOG (llevError, "shop_specialisation_ratio: passed a NULL item for map %s\n", map->path);
988 return 0; 939 return 0;
989 } 940 }
941
990 if (!item->type) 942 if (!item->type)
991 { 943 {
992 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n"); 944 LOG (llevError, "shop_specialisation_ratio: passed an item with an invalid type\n");
993 /* 945 /*
994 * I'm not really sure what the /right/ thing to do here is, these types of 946 * I'm not really sure what the /right/ thing to do here is, these types of
995 * item shouldn't exist anyway, but returning the ratio is probably the best bet.." 947 * item shouldn't exist anyway, but returning the ratio is probably the best bet.."
996 */ 948 */
997 return ratio; 949 return ratio;
998 } 950 }
951
999 if (map->shopitems) 952 if (map->shopitems)
1000 { 953 {
1001 for (i = 0; i < items[0].index; i++) 954 for (i = 0; i < items[0].index; i++)
1002 if (items[i].typenum == item->type || (!items[i].typenum && likedness == 0.001)) 955 if (items[i].typenum == item->type || (!items[i].typenum && likedness == 0.001))
1003 likedness = items[i].strength / 100.0; 956 likedness = items[i].strength / 100.0;
1004 } 957 }
958
1005 if (likedness > 1.0) 959 if (likedness > 1.0)
1006 { /* someone has been rather silly with the map headers. */ 960 { /* someone has been rather silly with the map headers. */
1007 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, map->path); 961 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is above 100%%\n", item->type, map->path);
1008 likedness = 1.0; 962 likedness = 1.0;
1009 } 963 }
964
1010 if (likedness < -1.0) 965 if (likedness < -1.0)
1011 { 966 {
1012 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, map->path); 967 LOG (llevDebug, "shop_specialisation ratio: item type %d on map %s is below -100%%\n", item->type, map->path);
1013 likedness = -1.0; 968 likedness = -1.0;
1014 } 969 }
970
1015 ratio = ratio + (1.0 - ratio) * likedness; 971 ratio = ratio + (1.0 - ratio) * likedness;
972
1016 if (ratio <= 0.1) 973 if (ratio <= 0.1)
1017 ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */ 974 ratio = 0.1; /* if the ratio were much lower than this, we would get silly prices */
975
1018 return ratio; 976 return ratio;
1019} 977}
1020 978
1021/*returns the greed of the shop on map, or 1 if it isn't specified. */ 979/*returns the greed of the shop on map, or 1 if it isn't specified. */
1022static double 980static double
1023shop_greed (const mapstruct *map) 981shop_greed (const maptile *map)
1024{ 982{
1025 double greed = 1.0; 983 double greed = 1.0;
1026 984
1027 if (map->shopgreed) 985 if (map->shopgreed)
1028 return map->shopgreed; 986 return map->shopgreed;
1031 989
1032/* Returns a double based on how much the shopkeeper approves of the player. 990/* Returns a double based on how much the shopkeeper approves of the player.
1033 * this is based on the race of the shopkeeper and that of the player. 991 * this is based on the race of the shopkeeper and that of the player.
1034 */ 992 */
1035double 993double
1036shopkeeper_approval (const mapstruct *map, const object *player) 994shopkeeper_approval (const maptile *map, const object *player)
1037{ 995{
1038 double approval = 1.0; 996 double approval = 1.0;
1039 997
1040 if (map->shoprace) 998 if (map->shoprace)
1041 { 999 {
1042 approval = NEUTRAL_RATIO; 1000 approval = NEUTRAL_RATIO;
1043 if (player->race && !strcmp (player->race, map->shoprace)) 1001 if (player->race && !strcmp (player->race, map->shoprace))
1044 approval = 1.0; 1002 approval = 1.0;
1045 } 1003 }
1004
1046 return approval; 1005 return approval;
1047} 1006}
1048 1007
1049/* limit the value of items based on the wealth of the shop. If the item is close 1008/* limit the value of items based on the wealth of the shop. If the item is close
1050 * to the maximum value a shop will offer, we start to reduce it, if the item is 1009 * to the maximum value a shop will offer, we start to reduce it, if the item is
1051 * below the minimum value the shop is prepared to trade in, then we don't 1010 * below the minimum value the shop is prepared to trade in, then we don't
1052 * want it and offer nothing. If it isn't a shop, check whether we should do generic 1011 * want it and offer nothing. If it isn't a shop, check whether we should do generic
1053 * value reduction. 1012 * value reduction.
1054 * 1013 *
1055 */ 1014 */
1056static uint64 1015static sint64
1057value_limit (uint64 val, int quantity, const object *who, int isshop) 1016value_limit (sint64 val, int quantity, const object *who, int isshop)
1058{ 1017{
1059 uint64 newval, unit_price, tmpshopmax; 1018 sint64 newval, unit_price, tmpshopmax;
1060 mapstruct *map; 1019 maptile *map;
1061 1020
1062 unit_price = val / quantity; 1021 unit_price = val / quantity;
1063 1022
1064 if (!isshop || !who) 1023 if (!isshop || !who)
1065 { 1024 {
1066 if (unit_price > 250000) 1025 if (unit_price > 250000)
1067 newval = (uint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.); 1026 newval = (sint64) (250000. - pow (250000., .75) * 65. + pow (unit_price, .75) * 65.);
1068 else 1027 else
1069 newval = unit_price; 1028 newval = unit_price;
1070 } 1029 }
1071 else 1030 else
1072 { 1031 {
1095 1054
1096/* gives a desciption of the shop on their current map to the player op. */ 1055/* gives a desciption of the shop on their current map to the player op. */
1097int 1056int
1098describe_shop (const object *op) 1057describe_shop (const object *op)
1099{ 1058{
1100 mapstruct *map = op->map; 1059 maptile *map = op->map;
1101 1060
1102 /*shopitems *items=map->shopitems; */ 1061 /*shopitems *items=map->shopitems; */
1103 int pos = 0, i; 1062 int pos = 0, i;
1104 double opinion = 0; 1063 double opinion = 0;
1105 char tmp[MAX_BUF] = "\0"; 1064 char tmp[MAX_BUF] = "\0";
1109 1068
1110 /*check if there is a shop specified for this map */ 1069 /*check if there is a shop specified for this map */
1111 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax) 1070 if (map->shopitems || map->shopgreed || map->shoprace || map->shopmin || map->shopmax)
1112 { 1071 {
1113 new_draw_info (NDI_UNIQUE, 0, op, "From looking at the nearby shop you determine that it trades in:"); 1072 new_draw_info (NDI_UNIQUE, 0, op, "From looking at the nearby shop you determine that it trades in:");
1073
1114 if (map->shopitems) 1074 if (map->shopitems)
1115 {
1116 for (i = 0; i < map->shopitems[0].index; i++) 1075 for (i = 0; i < map->shopitems[0].index; i++)
1076 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
1117 { 1077 {
1118 if (map->shopitems[i].name && map->shopitems[i].strength > 10)
1119 {
1120 snprintf (tmp + pos, sizeof (tmp) - pos, "%s, ", map->shopitems[i].name_pl); 1078 snprintf (tmp + pos, sizeof (tmp) - pos, "%s, ", map->shopitems[i].name_pl);
1121 pos += strlen (tmp + pos); 1079 pos += strlen (tmp + pos);
1122 }
1123 } 1080 }
1124 } 1081
1125 if (!pos) 1082 if (!pos)
1126 strcat (tmp, "a little of everything."); 1083 strcat (tmp, "a little of everything.");
1127 1084
1128 /* format the string into a list */ 1085 /* format the string into a list */
1129 make_list_like (tmp); 1086 make_list_like (tmp);
1130 new_draw_info_format (NDI_UNIQUE, 0, op, "%s", tmp); 1087 new_draw_info_format (NDI_UNIQUE, 0, op, "%s", tmp);
1131 1088
1132 if (map->shopmax) 1089 if (map->shopmax)
1133 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade for items above %s.", cost_string_from_value (map->shopmax, 0)); 1090 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade for items above %s.", cost_string_from_value (map->shopmax, 0));
1091
1134 if (map->shopmin) 1092 if (map->shopmin)
1135 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade in items worth less than %s.", cost_string_from_value (map->shopmin, 0)); 1093 new_draw_info_format (NDI_UNIQUE, 0, op, "It won't trade in items worth less than %s.", cost_string_from_value (map->shopmin, 0));
1094
1136 if (map->shopgreed) 1095 if (map->shopgreed)
1137 { 1096 {
1138 if (map->shopgreed > 2.0) 1097 if (map->shopgreed > 2.0)
1139 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge massively."); 1098 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge massively.");
1140 else if (map->shopgreed > 1.5) 1099 else if (map->shopgreed > 1.5)
1142 else if (map->shopgreed > 1.1) 1101 else if (map->shopgreed > 1.1)
1143 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge slightly."); 1102 new_draw_info (NDI_UNIQUE, 0, op, "It tends to overcharge slightly.");
1144 else if (map->shopgreed < 0.9) 1103 else if (map->shopgreed < 0.9)
1145 new_draw_info (NDI_UNIQUE, 0, op, "It tends to undercharge."); 1104 new_draw_info (NDI_UNIQUE, 0, op, "It tends to undercharge.");
1146 } 1105 }
1106
1147 if (map->shoprace) 1107 if (map->shoprace)
1148 { 1108 {
1149 opinion = shopkeeper_approval (map, op); 1109 opinion = shopkeeper_approval (map, op);
1150 if (opinion > 0.8) 1110 if (opinion > 0.8)
1151 new_draw_info (NDI_UNIQUE, 0, op, "You think the shopkeeper likes you."); 1111 new_draw_info (NDI_UNIQUE, 0, op, "You think the shopkeeper likes you.");
1158 else 1118 else
1159 new_draw_info (NDI_UNIQUE, 0, op, "There is no shop nearby."); 1119 new_draw_info (NDI_UNIQUE, 0, op, "There is no shop nearby.");
1160 1120
1161 return 1; 1121 return 1;
1162} 1122}
1123
1163typedef struct shopinv 1124struct shopinv
1164{ 1125{
1165 char *item_sort; 1126 char *item_sort;
1166 char *item_real; 1127 char *item_real;
1167 uint16 type; 1128 uint16 type;
1168 uint32 nrof; 1129 uint32 nrof;
1169} shopinv; 1130};
1170 1131
1171/* There are a lot fo extra casts in here just to suppress warnings - it 1132/* There are a lot fo extra casts in here just to suppress warnings - it
1172 * makes it look uglier than it really it. 1133 * makes it look uglier than it really it.
1173 * The format of the strings we get is type:name. So we first want to 1134 * The format of the strings we get is type:name. So we first want to
1174 * sort by type (numerical) - if the same type, then sort by name. 1135 * sort by type (numerical) - if the same type, then sort by name.
1180 1141
1181 if (s1->type < s2->type) 1142 if (s1->type < s2->type)
1182 return -1; 1143 return -1;
1183 if (s1->type > s2->type) 1144 if (s1->type > s2->type)
1184 return 1; 1145 return 1;
1146
1185 /* the type is the same (what atoi gets), so do a strcasecmp to sort 1147 /* the type is the same (what atoi gets), so do a strcasecmp to sort
1186 * via alphabetical order 1148 * via alphabetical order
1187 */ 1149 */
1188 return strcasecmp (s1->item_sort, s2->item_sort); 1150 return strcasecmp (s1->item_sort, s2->item_sort);
1189} 1151}
1216 case RING: 1178 case RING:
1217 case AMULET: 1179 case AMULET:
1218 case BRACERS: 1180 case BRACERS:
1219 case GIRDLE: 1181 case GIRDLE:
1220 sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL)); 1182 sprintf (buf, "%s %s", query_base_name (tmp, 0), describe_item (tmp, NULL));
1221 items[*numitems].item_sort = strdup_local (buf); 1183 items[*numitems].item_sort = strdup (buf);
1222 sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL)); 1184 sprintf (buf, "%s %s", query_name (tmp), describe_item (tmp, NULL));
1223 items[*numitems].item_real = strdup_local (buf); 1185 items[*numitems].item_real = strdup (buf);
1224 (*numitems)++; 1186 (*numitems)++;
1225 break; 1187 break;
1226#endif 1188#endif
1227 1189
1228 default: 1190 default:
1229 items[*numitems].item_sort = strdup_local (query_base_name (tmp, 0)); 1191 items[*numitems].item_sort = strdup (query_base_name (tmp, 0));
1230 items[*numitems].item_real = strdup_local (query_base_name (tmp, 1)); 1192 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1231 (*numitems)++; 1193 (*numitems)++;
1232 break; 1194 break;
1233 } 1195 }
1234 SET_FLAG (tmp, FLAG_UNPAID); 1196 SET_FLAG (tmp, FLAG_UNPAID);
1235} 1197}
1284 stack = stack->above; 1246 stack = stack->above;
1285 } 1247 }
1286 } 1248 }
1287 } 1249 }
1288 } 1250 }
1251
1289 free (map_mark); 1252 free (map_mark);
1253
1290 if (numitems == 0) 1254 if (numitems == 0)
1291 { 1255 {
1292 new_draw_info (NDI_UNIQUE, 0, op, "The shop is currently empty.\n"); 1256 new_draw_info (NDI_UNIQUE, 0, op, "The shop is currently empty.\n");
1293 free (items); 1257 free (items);
1294 return; 1258 return;
1295 } 1259 }
1260
1296 qsort (items, numitems, sizeof (shopinv), (int (*)(const void *, const void *)) shop_sort); 1261 qsort (items, numitems, sizeof (shopinv), (int (*)(const void *, const void *)) shop_sort);
1297 1262
1298 for (i = 0; i < numitems; i++) 1263 for (i = 0; i < numitems; i++)
1299 { 1264 {
1300 /* Collapse items of the same name together */ 1265 /* Collapse items of the same name together */
1325 return is_in_shop (o->map, o->x, o->y); 1290 return is_in_shop (o->map, o->x, o->y);
1326} 1291}
1327 1292
1328/* elmex: this function checks whether we are in a shop or not */ 1293/* elmex: this function checks whether we are in a shop or not */
1329bool 1294bool
1330is_in_shop (mapstruct *map, int x, int y) 1295is_in_shop (maptile *map, int x, int y)
1331{ 1296{
1332 for (object *floor = get_map_ob (map, x, y); floor; floor = floor->above) 1297 for (object *floor = get_map_ob (map, x, y); floor; floor = floor->above)
1333 if (floor->type == SHOP_FLOOR) 1298 if (floor->type == SHOP_FLOOR)
1334 return true; 1299 return true;
1335 1300

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines