1 /* $Id$ */
2 /*
3 * Client-side store stuff.
4 */
5
6 #include "angband.h"
7
8 bool leave_store;
9 int store_top = 0;
10
11
12
13 /*
14 * ToME show_building, ripped for client - Jir -
15 */
display_store_action()16 void display_store_action()
17 {
18 int i;
19 /* BIG_MAP leads to big shops */
20 int spacer = (screen_hgt > SCREEN_HGT) ? 14 : 0;
21
22 for (i = 0; i < 6; i++) {
23 if (!c_store.actions[i]) continue;
24
25 c_put_str(c_store.action_attr[i], c_store.action_name[i],
26 21 + spacer + (i / 2), 20 + (30 * (i % 2)));
27 }
28 }
29
display_entry(int pos,int entries)30 static void display_entry(int pos, int entries) {
31 object_type *o_ptr;
32 int i, x;
33 char o_name[ONAME_LEN];
34 char out_val[MSG_LEN];
35
36 int maxwid = 75;
37
38 /* Get the item */
39 o_ptr = &store.stock[pos];
40
41 /* Get the "offset" */
42 i = (pos % entries);
43
44 /* Label it, clear the line --(-- */
45 (void)sprintf(out_val, "%c) ", I2A(i));
46 prt(out_val, i + 6, 0);
47
48 /* Describe an item in the home */
49 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN) {
50 maxwid = 75;
51
52 /* Leave room for weights, if necessary -DRS- */
53 if (c_cfg.show_weights) maxwid -= 10;
54
55 /* Describe the object */
56 strcpy(o_name, store_names[pos]);
57 o_name[maxwid] = '\0';
58 c_put_str(o_ptr->attr, o_name, i + 6, 3);
59
60 /* Show weights */
61 if (c_cfg.show_weights) {
62 /* Only show the weight of an individual item */
63 int wgt = o_ptr->weight;
64 (void)sprintf(out_val, "%3d.%d lb", wgt / 10, wgt % 10);
65 put_str(out_val, i + 6, 68);
66 }
67 } else {
68 /* Must leave room for the "price" */
69 maxwid = 65;
70
71 /* Leave room for weights, if necessary -DRS- */
72 if (c_cfg.show_weights) maxwid -= 7;
73
74 /* Describe the object (fully) */
75 strcpy(o_name, store_names[pos]);
76 o_name[maxwid] = '\0';
77 c_put_str(o_ptr->attr, o_name, i + 6, 3);
78
79 /* Show weights */
80 if (c_cfg.show_weights) {
81 /* Only show the weight of an individual item */
82 int wgt = o_ptr->weight;
83 (void)sprintf(out_val, "%3d.%d", wgt / 10, wgt % 10);
84 put_str(out_val, i + 6, 61);
85 }
86
87 x = store_prices[pos];
88 if (x >= 0) {
89 /* Actually draw the price (not fixed) */
90 (void)sprintf(out_val, "%9d ", x);
91 c_put_str(p_ptr->au < x ? TERM_L_DARK : TERM_WHITE, out_val, i + 6, 68);
92 }
93 }
94 }
95
96
97
display_inventory(void)98 void display_inventory(void) {
99 int i, k, entries = 12;
100
101 /* BIG_MAP leads to big shops */
102 if (screen_hgt > SCREEN_HGT) entries = 26; /* we don't have 34 letters in the alphabet =p */
103
104 for (k = 0; k < entries; k++) {
105 /* Do not display "dead" items */
106 if (store_top + k >= store.stock_num) break;
107
108 /* Display that one */
109 display_entry(store_top + k, entries);
110 }
111
112 /* Erase the extra lines and the "more" prompt */
113 for (i = k; i <= entries; i++) prt("", i + 6, 0);
114
115 /* Assume "no current page" */
116 put_str(" ", 5, 20);
117
118 /* Visual reminder of "more items" */
119 if (store.stock_num > entries) {
120 /* Show "more" reminder (after the last item) */
121 prt("-more-", k + 6, 3);
122
123 /* Indicate the "current page" */
124 put_str(format("(Page %d of %d)%s%s",
125 store_top / entries + 1, store.stock_num == 0 ? 1 : (store.stock_num + entries - 1) / entries,
126 store_top / entries + 1 >= 10 ? "" : " ", (store.stock_num + entries - 1) / entries >= 10 ? "" : " "),
127 5, 20);
128 }
129
130 /* Hack - Get rid of the cursor - mikaelh */
131 Term->scr->cx = Term->wid;
132 Term->scr->cu = 1;
133 }
134
135 /*
136 * Get the ID of a store item and return its value -RAK-
137 */
get_stock(int * com_val,cptr pmt,int i,int j)138 static int get_stock(int *com_val, cptr pmt, int i, int j)
139 {
140 char command;
141 char out_val[160];
142
143 /* Paranoia XXX XXX XXX */
144 clear_topline_forced();
145
146 /* Assume failure */
147 *com_val = (-1);
148
149 /* Build the prompt */
150 (void)sprintf(out_val, "(Items %c-%c, ESC to exit) %s",
151 I2A(i), I2A(j), pmt);
152
153 /* Ask until done */
154 while (TRUE)
155 {
156 int k;
157
158 /* Escape */
159 if (!get_com(out_val, &command)) break;
160
161 /* Convert */
162 k = (islower(command) ? A2I(command) : -1);
163
164 /* Legal responses */
165 if ((k >= i) && (k <= j))
166 {
167 *com_val = k;
168 break;
169 }
170
171 /* Oops */
172 bell();
173 }
174
175 /* Clear the prompt */
176 clear_topline();
177
178 /* Cancel */
179 if (command == ESCAPE) return (FALSE);
180
181 /* Success */
182 return (TRUE);
183 }
184
185
186
187
188 /* XXX Bad design.. store code really should be rewritten. - Jir - */
store_examine(void)189 static void store_examine(void)
190 {
191 int i;
192 int item;
193
194 object_type *o_ptr;
195 char out_val[160];
196
197 /* BIG_MAP leads to big shops */
198 int entries = (screen_hgt > SCREEN_HGT) ? 26 : 12;
199
200
201 /* Empty? */
202 if (store.stock_num <= 0) {
203 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN)
204 c_msg_print("Your home is empty.");
205 else c_msg_print("I am currently out of stock.");
206 return;
207 }
208
209 /* Find the number of objects on this and following pages */
210 i = (store.stock_num - store_top);
211
212 /* And then restrict it to the current page */
213 if (i > entries) i = entries;
214
215 /* Prompt */
216 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN)
217 sprintf(out_val, "Which item do you want to examine? ");
218 else
219 sprintf(out_val, "Which item do you want to examine? ");
220
221 /* Get the item number to be bought */
222 if (!get_stock(&item, out_val, 0, i-1)) return;
223
224 /* Get the actual index */
225 item = item + store_top;
226
227 /* Get the actual item */
228 o_ptr = &store.stock[item];
229
230 /* Tell the server */
231 if (is_realm_book(o_ptr)) show_browse(o_ptr);
232 else if (o_ptr->tval == TV_BOOK &&
233 (!is_custom_tome(o_ptr->sval) || o_ptr->xtra1))
234 browse_school_spell(-(item + 1), o_ptr->sval, o_ptr->pval);
235 else Send_store_examine(item);
236 }
237
238
store_purchase(void)239 static void store_purchase(void) {
240 int i, amt, amt_afford;
241 int item;
242
243 object_type *o_ptr;
244 char out_val[160];
245
246 /* BIG_MAP leads to big shops */
247 int entries = (screen_hgt > SCREEN_HGT) ? 26 : 12;
248
249
250 /* Empty? */
251 if (store.stock_num <= 0) {
252 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN)
253 c_msg_print("Your home is empty.");
254 else c_msg_print("I am currently out of stock.");
255 return;
256 }
257
258
259 /* Find the number of objects on this and following pages */
260 i = (store.stock_num - store_top);
261
262 /* And then restrict it to the current page */
263 if (i > entries) i = entries;
264
265 /* Prompt */
266 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN)
267 sprintf(out_val, "Which item do you want to take? ");
268 else
269 sprintf(out_val, "Which item are you interested in? ");
270
271 /* Get the item number to be bought */
272 if (!get_stock(&item, out_val, 0, i-1)) return;
273
274 /* Get the actual index */
275 item = item + store_top;
276
277 /* Get the actual item */
278 o_ptr = &store.stock[item];
279
280 /* Client-side check already, for item stacks: Too expensive? */
281 if (store_prices[item] > p_ptr->au) {
282 c_msg_print("You do not have enough gold.");
283 return;
284 }
285
286 /* Assume the player wants just one of them */
287 amt = 1;
288
289 /* Find out how many the player wants */
290 if (o_ptr->number > 1) {
291 /* Hack -- note cost of "fixed" items */
292 if (store_num != STORE_HOME || store_num == STORE_HOME_DUN) {
293 c_msg_print(format("That costs %d gold per item.", store_prices[item]));
294
295 if (store_prices[item] > 0) amt_afford = p_ptr->au / store_prices[item];
296 else amt_afford = o_ptr->number;
297
298 /* Get a quantity */
299 if (o_ptr->number <= amt_afford)
300 amt = c_get_quantity(NULL, o_ptr->number);
301 else if (amt_afford > 1) {
302 inkey_letter_all = TRUE;
303 sprintf(out_val, "Quantity (1-\377y%d\377w, 'a' or spacebar for all): ", amt_afford);
304 amt = c_get_quantity(out_val, amt_afford);
305 } else {
306 sprintf(out_val, "Quantity (\377y1\377w): ");
307 amt = c_get_quantity(out_val, 1);
308 }
309 } else {
310 /* Get a quantity */
311 amt = c_get_quantity(NULL, o_ptr->number);
312 }
313
314 /* Allow user abort */
315 if (amt <= 0) return;
316 }
317
318 /* Tell the server */
319 Send_store_purchase(item, amt);
320 }
321
322 /* helper functions for store_chat(), also to be used for
323 pasting store items in the middle of a chat line similar to
324 new '\\x' feature for inven/equip-pasting. - C. Blue */
store_paste_where(char * where)325 void store_paste_where(char *where) {
326 snprintf(where, 17, "\377s(%d,%d) \377%c%c\377s:",
327 p_ptr->wpos.wx, p_ptr->wpos.wy,
328 color_attr_to_char(c_store.store_attr),
329 c_store.store_char);
330 }
store_paste_item(char * out_val,int item)331 void store_paste_item(char *out_val, int item) {
332 char price[16];
333
334 /* Get shop price if any */
335 /* Home doesn't price items */
336 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN) {
337 sprintf(out_val, " %s", store_names[item]);
338 /* Player stores with '@S-' inscription neither (museum mode) */
339 } else if (store_prices[item] < 0) {
340 sprintf(out_val, " %s", store_names[item]);
341 /* Normal [player-]store */
342 } else {
343 /* Convert the price to more readable format */
344 if (store_prices[item] >= 10000000)
345 snprintf(price, 16, "%dM", store_prices[item] / 1000000);
346 else if (store_prices[item] >= 10000)
347 snprintf(price, 16, "%dk", store_prices[item] / 1000);
348 else
349 snprintf(price, 16, "%d", store_prices[item]);
350
351 sprintf(out_val, "%s (%s Au)", store_names[item], price);
352 }
353 }
354
store_chat(void)355 static void store_chat(void) {
356 int i, item;
357
358 char out_val[MSG_LEN], buf[MSG_LEN];
359 char where[17];
360
361 /* BIG_MAP leads to big shops */
362 int entries = (screen_hgt > SCREEN_HGT) ? 26 : 12;
363
364
365 /* Empty? */
366 if (store.stock_num <= 0) {
367 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN)
368 c_msg_print("Your home is empty.");
369 else c_msg_print("I am currently out of stock.");
370 return;
371 }
372
373
374 /* Find the number of objects on this and following pages */
375 i = (store.stock_num - store_top);
376
377 /* And then restrict it to the current page */
378 if (i > entries) i = entries;
379
380 /* Prompt */
381 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN)
382 sprintf(out_val, "Which item? ");
383 else
384 sprintf(out_val, "Which item? ");
385
386 /* Get the item number to be pasted */
387 if (!get_stock(&item, out_val, 0, i - 1)) return;
388
389 /* Get the actual index */
390 item = item + store_top;
391
392 store_paste_where(where);
393 store_paste_item(out_val, item);
394
395 /* Tell the server */
396 snprintf(buf, MSG_LEN - 1, "%s %s", where, out_val);
397 buf[MSG_LEN - 1] = 0;
398 Send_paste_msg(buf);
399 }
400
store_sell(void)401 static void store_sell(void)
402 {
403 int item, amt;
404
405 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN) {
406 if (!c_get_item(&item, "Drop what? ", (USE_EQUIP | USE_INVEN)))
407 return;
408 } else if (store_num == STORE_MATHOM_HOUSE) {
409 if (!c_get_item(&item, "Donate what? ", (USE_EQUIP | USE_INVEN)))
410 return;
411 } else {
412 if (!c_get_item(&item, "Sell what? ", (USE_EQUIP | USE_INVEN)))
413 return;
414 }
415
416 /* Get an amount */
417 if (inventory[item].number > 1) {
418 if (is_cheap_misc(inventory[item].tval) && c_cfg.whole_ammo_stack && !verified_item) amt = inventory[item].number;
419 else {
420 inkey_letter_all = TRUE;
421 amt = c_get_quantity("How many ('a' or spacebar for all)? ", inventory[item].number);
422 }
423 } else amt = 1;
424
425 /* Hack -- verify for Museum(Mathom house) */
426 if (store_num == STORE_MATHOM_HOUSE)
427 {
428 char out_val[160];
429
430 if (inventory[item].number == amt)
431 sprintf(out_val, "Really donate %s?", inventory_name[item]);
432 else
433 sprintf(out_val, "Really donate %d of your %s?", amt, inventory_name[item]);
434 if (!get_check2(out_val, FALSE)) return;
435 }
436
437 /* Tell the server */
438 Send_store_sell(item, amt);
439 }
440
store_do_command(int num)441 static void store_do_command(int num) {
442 int i, amt, gold;
443 int item, item2;
444 u16b action = c_store.actions[num];
445 u16b bact = c_store.bact[num];
446 /* BIG_MAP leads to big shops */
447 int entries = (screen_hgt > SCREEN_HGT) ? 26 : 12;
448
449 char out_val[160];
450
451 i = amt = gold = item = item2 = 0;
452
453 /* lazy job for 'older' commands */
454 switch (bact) {
455 case BACT_SELL:
456 store_sell();
457 return;
458 break;
459 case BACT_BUY:
460 store_purchase();
461 return;
462 break;
463 case BACT_EXAMINE:
464 store_examine();
465 return;
466 break;
467 }
468
469 if (c_store.flags[num] & BACT_F_STORE_ITEM) {
470 /* Empty? */
471 if (store.stock_num <= 0) {
472 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN)
473 c_msg_print("Your home is empty.");
474 else c_msg_print("I am currently out of stock.");
475 return;
476 }
477
478
479 /* Find the number of objects on this and following pages */
480 i = (store.stock_num - store_top);
481
482 /* And then restrict it to the current page */
483 if (i > entries) i = entries;
484
485 /* Prompt */
486 sprintf(out_val, "Which item? ");
487
488 /* Get the item number to be bought */
489 if (!get_stock(&item, out_val, 0, i-1)) return;
490
491 /* Get the actual index */
492 item = item + store_top;
493 }
494
495 if (c_store.flags[num] & BACT_F_INVENTORY) {
496 if (!c_get_item(&item, "Which item? ", (USE_EQUIP | USE_INVEN)))
497 return;
498 }
499
500 if (c_store.flags[num] & BACT_F_GOLD) {
501 /* Get how much */
502 inkey_letter_all = TRUE;
503 gold = c_get_quantity("How much gold ('a' or spacebar for all)? ", -1);
504
505 /* Send it */
506 if (!gold) return;
507 }
508
509 if (c_store.flags[num] & BACT_F_HARDCODE) {
510 /* Nothing for now */
511 }
512
513 Send_store_command(action, item, item2, amt, gold);
514 }
515
store_process_command(int cmd)516 static void store_process_command(int cmd) {
517 int i;
518 bool allow_w_t = TRUE;
519
520 /* BIG_MAP leads to big shops */
521 int entries = (screen_hgt > SCREEN_HGT) ? 26 : 12;
522
523 for (i = 0; i < 6; i++) {
524 if (!c_store.actions[i]) continue;
525
526 if (c_store.letter[i] == cmd) {
527 store_do_command(i);
528 return;
529 }
530
531 /* only allow wear/wield and take-off in stores that do not
532 already provide special functions of their own on those keys */
533 if (c_cfg.rogue_like_commands) {
534 if (c_store.letter[i] == 'w' ||
535 //c_store.letter[i] == KTRL('W') ||
536 c_store.letter[i] == 'T') allow_w_t = FALSE;
537 } else {
538 if (c_store.letter[i] == 'w' ||
539 c_store.letter[i] == 'W' ||
540 c_store.letter[i] == 't') allow_w_t = FALSE;
541 }
542 }
543
544 /* hack: translate p/s into d/g and vice versa, for extra comfort */
545 for (i = 0; i < 6; i++) {
546 if (!c_store.actions[i]) continue;
547
548 switch (c_store.letter[i]) {
549 case 'p':
550 if (cmd == 'g') {
551 store_do_command(i);
552 return;
553 }
554 break;
555 case 's':
556 if (cmd == 'd') {
557 store_do_command(i);
558 return;
559 }
560 break;
561 case 'g':
562 if (cmd == 'p') {
563 store_do_command(i);
564 return;
565 }
566 break;
567 case 'd':
568 if (cmd == 's') {
569 store_do_command(i);
570 return;
571 }
572 break;
573 case 'x':
574 #if 0 /* nope, change of plans for future changes: use shift+I to inspect _own_ items instead! */
575 //(future change: replace x by I in ba_info, and I/s by D) -- case 'I':
576 if (cmd == 'I' || cmd == 'l' || cmd == 'x') {
577 store_do_command(i);
578 return;
579 }
580 #else
581 if (cmd == 'l' || cmd == 'x') {
582 store_do_command(i);
583 return;
584 }
585 #endif
586 break;
587 }
588 }
589
590 /* Parse the command */
591 i = 0; /* for jumping to page 1/2/3/4 */
592 switch (cmd) {
593 /* Leave */
594 case ESCAPE:
595 case KTRL('X'):
596 leave_store = TRUE;
597 break;
598
599 case KTRL('T'):
600 /* Take a screenshot */
601 xhtml_screenshot("screenshot????");
602 break;
603
604 /* Browse */
605 case ' ':
606 if (store.stock_num <= entries) {
607 if (store_top) {
608 /*
609 * Hack - Allowing going back to first page after buying
610 * last item on the second page. - mikaelh */
611 store_top = 0;
612 display_inventory();
613 } else {
614 c_msg_print("Entire inventory is shown.");
615 }
616 } else {
617 store_top += entries;
618 if (store_top >= store.stock_num) store_top = 0;
619 display_inventory();
620 }
621 break;
622
623 /* Allow to browse backwards via BACKSPACE */
624 case '\b':
625 if (store.stock_num <= entries) {
626 if (store_top) {
627 /* see above - C. Blue */
628 store_top = 0;
629 display_inventory();
630 } else {
631 c_msg_print("Entire inventory is shown.");
632 }
633 } else {
634 store_top -= entries;
635 if (store_top < 0) store_top = ((store.stock_num - 1) / entries) * entries;
636 display_inventory();
637 }
638 break;
639
640 /* go to page n */
641 case '0': i++;
642 case '9': i++;
643 case '8': i++;
644 case '7': i++;
645 case '6': i++;
646 case '5': i++;
647 case '4': i++;
648 case '3': i++;
649 case '2': i++;
650 case '1':
651 if (store.stock_num > entries * i) {
652 store_top = entries * i;
653 display_inventory();
654 }
655 #if 0 /* suppress message, in case STORE_INVEN_MAX doesn't actually support all 10 pages. It'd look silyl. */
656 else c_msg_format("Page %d is empty.", i + 1);
657 #endif
658 break;
659
660 /* Paste on Chat */
661 case 'c':
662 store_chat();
663 break;
664
665 /* allow to actually chat from within a store, might be cool for
666 notifying others of items other than just pasting into chat */
667 case ':':
668 cmd_message();
669 break;
670
671 /* allow inspecting _own_ items while in a store! */
672 case 'I':
673 cmd_observe();
674 break;
675
676 /* Ignore return */
677 case '\r':
678 break;
679
680 /* Equipment list */
681 case 'e':
682 cmd_equip();
683 break;
684
685 /* Inventory list */
686 case 'i':
687 cmd_inven();
688 break;
689
690 #ifdef USE_SOUND_2010
691 case KTRL('C'):
692 case KTRL('Q')://rl
693 toggle_music();
694 break;
695 case KTRL('N'):
696 case KTRL('V')://rl
697 toggle_audio();
698 break;
699 #endif
700
701 case '{':
702 cmd_inscribe();
703 break;
704 case '}':
705 cmd_uninscribe();
706 break;
707
708 /* special feat for some stores: allow wear/wield and take-off..
709 'emulating' rogue-like key mapping option for now, sigh */
710 case 'w':
711 if (allow_w_t) cmd_wield();
712 else cmd_raw_key(cmd);
713 break;
714 case 'W':
715 if (c_cfg.rogue_like_commands || !allow_w_t) cmd_raw_key(cmd);
716 else cmd_wield2();
717 break;
718 case KTRL('W'):
719 if (!c_cfg.rogue_like_commands || !allow_w_t) cmd_raw_key(cmd);
720 else cmd_wield2();
721 break;
722 case 't':
723 if (c_cfg.rogue_like_commands || !allow_w_t) cmd_raw_key(cmd);
724 else cmd_take_off();
725 break;
726 case 'T':
727 if (!c_cfg.rogue_like_commands || !allow_w_t) cmd_raw_key(cmd);
728 else cmd_take_off();
729 break;
730
731 default:
732 cmd_raw_key(cmd);
733 break;
734 }
735 }
736
c_store_prt_gold(void)737 void c_store_prt_gold(void) {
738 char out_val[64];
739 /* BIG_MAP leads to big shops */
740 int spacer = (screen_hgt > SCREEN_HGT) ? 14 : 0;
741
742 prt("Gold Remaining: ", 19 + spacer, 53);
743
744 sprintf(out_val, "%9d", p_ptr->au);
745 if (p_ptr->au < 1000000000) strcat(out_val, " "); //hack to correctly clear line for players moving huge amounts
746 prt(out_val, 19 + spacer, 68);
747
748 /* Hack -- show balance (if not 0) */
749 if (store_num == STORE_MERCHANTS_GUILD && p_ptr->balance) {
750 prt("Your balance : ", 20 + spacer, 53);
751
752 sprintf(out_val, "%9d", p_ptr->balance);
753 if (p_ptr->au < 1000000000) strcat(out_val, " ");
754 prt(out_val, 20 + spacer, 68);
755 } else {
756 /* Erase part of the screen */
757 Term_erase(0, 20 + spacer, 255);
758 }
759 }
760
do_redraw_store(void)761 void do_redraw_store(void) {
762 redraw_store = FALSE;
763
764 if (shopping) {
765 /* hack: Display changed capacity if we just extended the house */
766 if ((store_num == STORE_HOME || store_num == STORE_HOME_DUN)
767 && c_store.max_cost) {
768 char buf[1024];
769 sprintf(buf, "%s (Stock: %d/%d)", c_store.store_name, store.stock_num, c_store.max_cost);
770 prt(buf, 3, 50);
771 }
772 display_inventory();
773 }
774 }
775
display_store(void)776 void display_store(void) {
777 int i;
778 char buf[1024];
779 /* BIG_MAP leads to big shops */
780 int spacer = (screen_hgt > SCREEN_HGT) ? 14 : 0;
781
782 /* Save the term */
783 Term_save();
784
785 /* We are "shopping" */
786 shopping = TRUE;
787
788 /* Clear screen */
789 Term_clear();
790
791 store_top = 0;
792
793 /* The "Home" is special */
794 if (store_num == STORE_HOME || store_num == STORE_HOME_DUN) {
795 /* Put the owner name (usually "Your House/Home") */
796 sprintf(buf, "%s", c_store.owner_name);
797 put_str(buf, 3, 10);
798
799 /* Show the store name (usually blank for houses) and -hack- max_cost is the capacity */
800 if (c_store.max_cost)
801 sprintf(buf, "%s (Stock: %d/%d)", c_store.store_name, store.stock_num, c_store.max_cost);
802 else
803 sprintf(buf, "%s", c_store.store_name);
804 prt(buf, 3, 50);
805
806 /* Label the item descriptions */
807 put_str("Item Description", 5, 3);
808
809 /* If showing weights, show label */
810 if (c_cfg.show_weights) put_str("Weight", 5, 70);
811 }
812
813 /* Normal stores */
814 else {
815 /* Put the owner name and race */
816 sprintf(buf, "%s", c_store.owner_name);
817 put_str(buf, 3, 10);
818
819 /* Show the max price in the store (above prices) */
820 if (!c_store.max_cost) {
821 /* improve it a bit visually for player stores who don't buy anything */
822 sprintf(buf, "%s", c_store.store_name);
823 } else {
824 sprintf(buf, "%s (%d)", c_store.store_name, c_store.max_cost);
825 }
826 prt(buf, 3, 50);
827
828 /* Label the item descriptions */
829 put_str("Item Description", 5, 3);
830
831 /* If showing weights, show label */
832 if (c_cfg.show_weights) put_str("Weight", 5, 60);
833
834 /* Label the asking price (in stores) */
835 put_str("Price", 5, 72);
836
837 /* Display the players remaining gold */
838 c_store_prt_gold();
839 }
840
841 /* Display the inventory */
842 display_inventory();
843
844 /* Don't leave */
845 leave_store = FALSE;
846
847 /* Start at the top */
848 store_top = 0;
849
850 /* Interact with player */
851 while (!leave_store) {
852 /* Hack -- Clear line 1 */
853 prt("", 1, 0);
854
855 /* Clear */
856 clear_from(21 + spacer);
857
858 /* Prompt */
859 #if 0
860 prt("You may: ", 21 + spacer, 0);
861
862 /* Basic commands */
863 prt(" ESC) Exit.", 22 + spacer, 0);
864
865 /* Browse if necessary */
866 if (store.stock_num > 12 + spacer) prt(" SPACE) Next page", 23 + spacer, 0);
867 #else /* new: also show 1..n for jumping directly to a page */
868 prt("ESC) Exit store", 21 + spacer, 0);
869 if (store.stock_num > 12 + spacer) {
870 prt("SPACE) Next page", 22 + spacer, 0);
871 prt(format("1-%d)%s Go to page", (store.stock_num - 1) / (12 + spacer) + 1, (store.stock_num - 1) / (12 + spacer) + 1 >= 10 ? "" : " "), 23 + spacer, 0);
872 }
873 #endif
874
875 #if 0
876 /* Home commands */
877 if ((store_num == STORE_HOME || store_num == STORE_HOME_DUN) && FALSE) {
878 prt(" g) Get an item.", 22 + spacer, 30);
879 prt(" d) Drop an item.", 23 + spacer, 30);
880
881 prt(" x) eXamine an item.", 22 + spacer, 60);
882 }
883 /* Shop commands XXX XXX XXX */
884 else
885 #endif
886 display_store_action();
887
888 /* Hack - Get rid of the cursor - mikaelh */
889 Term->scr->cx = Term->wid;
890 Term->scr->cu = 1;
891
892 i = inkey();
893
894 if (i) {
895 /* Process the command */
896 store_process_command(i);
897 }
898 }
899
900 /* Tell the server that we're outta here */
901 Send_store_leave();
902
903 /* Clear the screen */
904 Term_clear();
905
906 /* We are no longer "shopping" */
907 shopping = FALSE;
908 store.stock_num = 0;
909
910 /* Flush any events that happened */
911 Flush_queue();
912
913 /* reload the term */
914 Term_load();
915 }
916
917 /* For the new SPECIAL flag for non-inven stores - C. Blue */
display_store_special(void)918 void display_store_special(void) {
919 int i;
920 char buf[1024];
921 /* BIG_MAP leads to big shops */
922 int spacer = (screen_hgt > SCREEN_HGT) ? 14 : 0;
923
924 /* Save the term */
925 Term_save();
926
927 /* We are "shopping" */
928 shopping = TRUE;
929
930 /* Clear screen */
931 Term_clear();
932
933 /* Put the owner name and race */
934 sprintf(buf, "%s", c_store.owner_name);
935 put_str(buf, 3, 10);
936
937 sprintf(buf, "%s", c_store.store_name);
938 prt(buf, 3, 50);
939
940 /* Display the players remaining gold */
941 c_store_prt_gold();
942
943 /* Don't leave */
944 leave_store = FALSE;
945
946 /* Start at the top */
947 store_top = 0;
948
949 /* Interact with player */
950 while (!leave_store) {
951 /* Hack -- Clear line 1 */
952 prt("", 1, 0);
953
954 /* Clear */
955 clear_from(21 + spacer);
956
957 /* Prompt */
958 #if 0 /* keep consistent with display_store() */
959 prt("You may: ", 21 + spacer, 0);
960
961 /* Basic commands */
962 prt(" ESC) Exit.", 22 + spacer, 0);
963 #else
964 prt("ESC) Exit store", 21 + spacer, 0);
965 #endif
966
967 #if 0
968 /* Browse if necessary */
969 if (store.stock_num > 12 + spacer) prt(" SPACE) Next page", 23 + spacer, 0);
970 #endif
971
972 /* Shop commands XXX XXX XXX */
973 display_store_action();
974
975 /* Hack - Get rid of the cursor - mikaelh */
976 Term->scr->cx = Term->wid;
977 Term->scr->cu = 1;
978
979 i = inkey();
980
981 if (i) {
982 /* Process the command */
983 store_process_command(i);
984 }
985 }
986
987 /* Tell the server that we're outta here */
988 Send_store_leave();
989
990 /* Clear the screen */
991 Term_clear();
992
993 /* We are no longer "shopping" */
994 shopping = FALSE;
995 store.stock_num = 0;
996
997 /* Flush any events that happened */
998 Flush_queue();
999
1000 /* reload the term */
1001 Term_load();
1002 }
1003