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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines