Changeset 37

Show
Ignore:
Timestamp:
04/09/07 17:39:27 (1 year ago)
Author:
takkaria
Message:

Make the store code use the new list functions. Controversial change, probably, and still has some crashes; documented in bug #6.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/scripts/pkg_win

    r15 r37  
    3434 
    3535cp ../*.exe . 
    36 cp ../changes.txt ../AUTHORS ../THANKS ../TODO ../COPYING ../readme.txt . 
     36cp ../changes.txt ../AUTHORS ../THANKS ../COPYING ../readme.txt . 
    3737 
    3838cp ../lib/edit/*.txt lib/edit 
  • trunk/src/store.c

    r36 r37  
    1313#include "script.h" 
    1414 
    15 /*** Various file-wide definitions ***/ 
    16  
    17 /** Store display stuff **/ 
     15/*** Constants and definitions ***/ 
    1816 
    1917/* Easy names for the elements of the 'scr_places' arrays. */ 
     
    2927        LOC_HELP_PROMPT, 
    3028        LOC_AU, 
     29        LOC_WEIGHT, 
    3130 
    3231        LOC_MAX 
     
    3736static unsigned int scr_places_y[LOC_MAX]; 
    3837 
     38 
    3939/* State flags */ 
    40 #define STORE_HELP             0x000001 
    41 #define STORE_INVEN_CHANGE     0x000002 
    42 #define STORE_GOLD_CHANGE      0x000004 
    43 #define STORE_HELP_CHANGE      0x000008 
    44 #define STORE_FRAME_CHANGE     0x000010 
    45 #define STORE_MORE_CHANGE      0x000020 
    46 #define STORE_SIZE_CHANGE      0x000040 
     40#define STORE_GOLD_CHANGE      0x01 
     41#define STORE_FRAME_CHANGE     0x02 
     42#define STORE_INVEN            0x10 
    4743 
    4844/* Compound flag for the initial display of a store */ 
    49 #define STORE_INIT_CHANGE \ 
    50         (STORE_INVEN_CHANGE | STORE_FRAME_CHANGE | STORE_GOLD_CHANGE | \ 
    51          STORE_HELP_CHANGE | STORE_SIZE_CHANGE) 
    52  
    53  
    54 /** Variables to maintain state -- these shouldn't really exist ***/ 
     45#define STORE_INIT_CHANGE               (STORE_FRAME_CHANGE | STORE_GOLD_CHANGE) 
     46 
     47 
     48/** Variables to maintain state XXX ***/ 
    5549 
    5650/* Current store number */ 
    5751static int store_current; 
    5852 
    59 /* Item at the top of the current store display */ 
    60 static int store_top; 
    61  
    6253/* Flags for the display */ 
    63 static u32b store_flags; 
    64  
    65  
    66  
    67  
    68 /*** Utility function ***/ 
     54static u16b store_flags; 
     55 
     56 
     57 
     58 
     59/*** Utilities ***/ 
    6960 
    7061/* 
     
    7869 
    7970 
     71/* Randomly select one of the entries in an array */ 
     72#define ONE_OF(x)       x[rand_int(N_ELEMENTS(x))] 
     73 
     74 
    8075 
    8176/*** Flavour text stuff ***/ 
     77 
     78/* 
     79 * Shopkeeper welcome messages. 
     80 * 
     81 * The shopkeeper's name must come first, then the character's name. 
     82 */ 
     83static const char *comment_welcome[] = 
     84{ 
     85        "", 
     86        "%s nods to you.", 
     87        "%s says hello.", 
     88        "%s: \"See anything you like, adventurer?\"", 
     89        "%s: \"How may I help you, %s?\"", 
     90        "%s: \"Welcome back, %s.\"", 
     91        "%s: \"A pleasure to see you again, %s.\"", 
     92        "%s: \"How may I be of assistance, good %s?\"", 
     93        "%s: \"You do honour to my humble store, noble %s.\"", 
     94        "%s: \"I and my family are entirely at your service, glorious %s.\"" 
     95}; 
    8296 
    8397/* 
     
    89103        "You bastard!", 
    90104        "You hear someone sobbing...", 
    91         "The shopkeeper howls in agony!" 
     105        "The shopkeeper howls in agony!", 
     106        "The shopkeeper wails in anguish!", 
     107        "The shopkeeper beats his head against the counter." 
    92108}; 
    93109 
     
    97113        "You fiend!", 
    98114        "The shopkeeper curses at you.", 
    99         "The shopkeeper glares at you." 
     115        "The shopkeeper glares at you.", 
    100116}; 
    101117 
     
    114130        "Cool!", 
    115131        "You've made my day!", 
     132        "The shopkeeper sniggers.", 
    116133        "The shopkeeper giggles.", 
    117134        "The shopkeeper laughs loudly." 
     
    123140        "I think I'll retire!", 
    124141        "The shopkeeper jumps for joy.", 
    125         "The shopkeeper smiles gleefully." 
     142        "The shopkeeper smiles gleefully.", 
     143        "Wow.  I'm going to name my new villa in your honour." 
    126144}; 
    127145 
    128 /* Randomly select one of the entries in an array */ 
    129 #define ONE_OF(x)       x[rand_int(N_ELEMENTS(x))] 
     146 
     147 
     148/* 
     149 * The greeting a shopkeeper gives the character says a lot about his 
     150 * general attitude. 
     151 * 
     152 * Taken and modified from Sangband 1.0. 
     153 */ 
     154static void prt_welcome(const owner_type *ot_ptr) 
     155
     156        char short_name[20]; 
     157        const char *player_name; 
     158 
     159        const char *owner_name = &b_name[ot_ptr->owner_name]; 
     160        int i = p_ptr->lev / 5; 
     161 
     162        /* Only show the message one in four times to stop it being irritating. */ 
     163        if (!rand_int(4)) return; 
     164 
     165        /* Welcome the character */ 
     166        if (i) 
     167        { 
     168                int j; 
     169 
     170                /* Extract the first name of the store owner (stop before the first space) */ 
     171                for (j = 0; owner_name[j] && owner_name[j] != ' '; j++) 
     172                        short_name[j] = owner_name[j]; 
     173 
     174                /* Truncate the name */ 
     175                short_name[j] = '\0'; 
     176 
     177 
     178                /* Get a title for the character */ 
     179                if (i == 4)           player_name = c_text + cp_ptr->title[(p_ptr->lev - 1) / 5]; 
     180                else if (rand_int(2)) player_name = op_ptr->full_name; 
     181                else                  player_name = "sir"; 
     182 
     183                /* Balthazar says "Welcome" */ 
     184                prt(format(comment_welcome[i], short_name, player_name), 0, 0); 
     185        } 
     186
     187 
    130188 
    131189 
     
    154212} 
    155213 
     214 
     215 
     216 
     217/*** Check if a store will buy an object ***/ 
    156218 
    157219/* 
     
    397459{ 
    398460        int i, t = 0; 
     461 
    399462        for (i = 0; i < num; i++) 
    400         { 
    401463                t += ((max > 1) ? rand_int(max) : 1); 
    402         } 
     464 
    403465        return (t); 
    404466} 
     
    485547        /* Pick a discount */ 
    486548        if (cost < 5) 
    487         { 
    488549                discount = 0; 
    489         } 
     550 
    490551        else if (rand_int(25) == 0) 
    491         { 
    492552                discount = 10; 
    493         } 
     553 
    494554        else if (rand_int(50) == 0) 
    495         { 
    496555                discount = 25; 
    497         } 
     556 
    498557        else if (rand_int(150) == 0) 
    499         { 
    500558                discount = 50; 
    501         } 
     559 
    502560        else if (rand_int(300) == 0) 
    503         { 
    504561                discount = 75; 
    505         } 
     562 
    506563        else if (rand_int(500) == 0) 
    507         { 
    508564                discount = 90; 
    509         } 
    510565 
    511566 
     
    658713} 
    659714 
    660  
    661 /* 
    662  * Determine if the current store will purchase the given object 
    663  */ 
    664 static bool store_will_buy_tester(const object_type *o_ptr) 
    665 { 
    666         return store_will_buy(store_current, o_ptr); 
    667 } 
    668715 
    669716 
     
    12421289}; 
    12431290 
    1244 #define STAPLES_SIZE (sizeof staples / sizeof staples[0]) 
    1245  
    12461291/* 
    12471292 * Create all staple items. 
     
    12521297 
    12531298        /* Iterate through staples */ 
    1254         for (i = 0; (unsigned int) i < STAPLES_SIZE; i++) 
     1299        for (i = 0; (unsigned int) i < N_ELEMENTS(staples); i++) 
    12551300        { 
    12561301                /* Ignore this one */ 
     
    14341479 * Current screen layout: 
    14351480 *  line 0: reserved for messages 
    1436  *  line 1: shopkeeper and their purse 
     1481 *  line 1: shopkeeper and their purse / item buying price 
    14371482 *  line 2: empty 
    14381483 *  line 3: table headers 
     
    14561501static void store_display_recalc(void) 
    14571502{ 
     1503        int wid, hgt; 
     1504        Term_get_size(&wid, &hgt); 
     1505 
     1506        /* Clip the width at a maximum of 104 (enough room for an 80-char item name) */ 
     1507        if (wid > 104) wid = 100; 
     1508 
     1509        /* Clip the text_out function at two smaller than the screen width */ 
     1510        text_out_wrap = wid - 2; 
     1511 
     1512 
    14581513        /* X co-ords first */ 
    1459         scr_places_x[LOC_PRICE] = Term->wid - 14; 
    1460         scr_places_x[LOC_AU] = Term->wid - 26; 
     1514        scr_places_x[LOC_PRICE] = wid - 14; 
     1515        scr_places_x[LOC_AU] = wid - 26; 
     1516        scr_places_x[LOC_OWNER] = wid - 2; 
     1517        scr_places_x[LOC_WEIGHT] = wid - 14; 
     1518 
     1519        /* Add space for for prices */ 
     1520        if (store_current != STORE_HOME) 
     1521                scr_places_x[LOC_WEIGHT] -= 10; 
    14611522 
    14621523        /* Then Y */ 
     
    14651526        scr_places_y[LOC_ITEMS_START] = 4; 
    14661527 
    1467         scr_places_y[LOC_ITEMS_END] = Term->hgt - 5; 
    1468         scr_places_y[LOC_MORE] = Term->hgt - 4; 
    1469         scr_places_y[LOC_HELP_CLEAR] = Term->hgt - 3; 
    1470         scr_places_y[LOC_HELP_PROMPT] = Term->hgt - 2; 
    1471         scr_places_y[LOC_AU] = Term->hgt - 2; 
    1472  
    1473         if (store_flags & (STORE_HELP)) 
    1474         { 
    1475                 scr_places_y[LOC_ITEMS_END] -= 2; 
    1476                 scr_places_y[LOC_MORE] -= 2; 
    1477                 scr_places_y[LOC_HELP_CLEAR] -= 2; 
    1478                 scr_places_y[LOC_HELP_PROMPT] -= 1; 
    1479                 scr_places_y[LOC_AU] -= 3; 
    1480         } 
     1528        scr_places_y[LOC_ITEMS_END] = hgt - 7; 
     1529        scr_places_y[LOC_MORE] = hgt - 6; 
     1530        scr_places_y[LOC_HELP_CLEAR] = hgt - 5; 
     1531        scr_places_y[LOC_HELP_PROMPT] = hgt - 3; 
     1532        scr_places_y[LOC_AU] = hgt - 5; 
    14811533} 
    14821534 
     
    14911543 
    14921544 
    1493 /* 
    1494  * Convert a one character label into a store item index. 
    1495  * 
    1496  * Return "-1" if the label does not indicate a real store item. 
    1497  */ 
    1498 static s16b label_to_store(int c) 
    1499 
    1500         int i; 
    1501  
    1502         /* Convert */ 
    1503         i = (islower((unsigned char)c) ? A2I(c) : -1); 
    1504  
    1505         /* Verify the index */ 
    1506         if ((i < 0) || (i >= store[store_current].stock_num)) return (-1); 
    1507  
    1508         /* Return the index */ 
    1509         return (i); 
    1510 
    1511  
    1512 #define weight_pos(s)     (Term->wid - ((s == STORE_HOME) ? (14) : (24))) 
    1513  
    1514 /* 
    1515  * Redisplay a single store entry 
    1516  */ 
    1517 static void store_display_entry(int item) 
     1545static struct sell_objs 
     1546
     1547        object_type *o_ptr; 
     1548        int index; 
     1549} sellable[INVEN_TOTAL]; 
     1550 
     1551static int sellable_total; 
     1552 
     1553void inven_compile_list(void) 
     1554
     1555        object_type *o_ptr; 
     1556        int i, sell_idx = 0; 
     1557 
     1558        /* Wipe the sellable array */ 
     1559        C_WIPE(&sellable, INVEN_TOTAL, struct sell_objs); 
     1560 
     1561        /* Go over all the inventory items */ 
     1562        for (i = 0; i < INVEN_TOTAL; i++) 
     1563        { 
     1564                /* Get a copy of the item */ 
     1565                o_ptr = &inventory[i]; 
     1566 
     1567                /* Forget (nothing)s */ 
     1568                if (!o_ptr->k_idx) 
     1569                        continue; 
     1570 
     1571                /* Make sure the store will buy this kind of object */ 
     1572                if (!store_will_buy(store_current, o_ptr)) 
     1573                        continue; 
     1574 
     1575                /* Check it's not cursed */ 
     1576                if ((i >= INVEN_WIELD) && cursed_p(o_ptr)) 
     1577                        continue; 
     1578 
     1579                /* Add to list */ 
     1580                sellable[sell_idx].o_ptr = o_ptr; 
     1581                sellable[sell_idx].index = i; 
     1582                sell_idx++; 
     1583        } 
     1584 
     1585        /* Keep track of the total */ 
     1586        sellable_total = sell_idx; 
     1587 
     1588        return; 
     1589
     1590 
     1591/* 
     1592 * Display a single invenory entry 
     1593 */ 
     1594static void inven_display_entry(menu_type *menu, int oid, bool cursor, int row, int col, int width) 
    15181595{ 
    15191596        object_type *o_ptr; 
     
    15221599        char o_name[80]; 
    15231600        char out_val[160]; 
    1524         byte colour; 
    1525  
    1526         store_type *st_ptr = &store[store_current]; 
    1527  
    1528         int where = (item - store_top) + scr_places_y[LOC_ITEMS_START]; 
    1529  
     1601        int max_cost = store_owner(store_current)->max_cost; 
     1602 
     1603        (void)menu; 
     1604        (void)cursor; 
     1605        (void)width; 
    15301606 
    15311607        /* Get the object */ 
    1532         o_ptr = &st_ptr->stock[item]
     1608        o_ptr = sellable[oid].o_ptr
    15331609 
    15341610        /* Describe the object */ 
    15351611        object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); 
    15361612 
    1537         /* Label it, clear the line */ 
    1538         prt(format("%c) ", store_to_label(item)), where, 0); 
    1539  
    15401613        /* Display the object */ 
    1541         c_put_str(tval_to_attr[o_ptr->tval & 0x7F], o_name, where, 3); 
     1614        c_put_str(tval_to_attr[o_ptr->tval & 0x7F], o_name, row, col); 
    15421615 
    15431616        /* Show weights */ 
     
    15471620 
    15481621                sprintf(out_val, "%3d.%d lb", wgt / 10, wgt % 10); 
    1549                 put_str(out_val, where, weight_pos(store_current)); 
     1622                put_str(out_val, row, scr_places_x[LOC_WEIGHT]); 
    15501623        } 
    15511624 
     
    15541627        { 
    15551628                /* Extract the "minimum" price */ 
    1556                 x = price_item(o_ptr, FALSE); 
    1557  
    1558                 /* Make sure the player can afford it */ 
    1559                 if ((unsigned int) p_ptr->au < (unsigned int) x) 
    1560                         colour = TERM_SLATE; 
    1561                 else 
    1562                         colour = TERM_WHITE; 
     1629                x = price_item(o_ptr, TRUE); 
     1630 
     1631                /* Cap at store limit */ 
     1632                if (x > max_cost) x = max_cost; 
    15631633 
    15641634                /* Actually draw the price */ 
     
    15691639                        sprintf(out_val, "%9ld    ", (long)x); 
    15701640 
    1571                 c_put_str(colour, out_val, where, scr_places_x[LOC_PRICE]); 
    1572         } 
    1573 
    1574  
    1575  
    1576 /* 
    1577  * Display a store's inventory. 
    1578  */ 
    1579 static void store_display_inventory(void) 
    1580 
    1581         int i, start, end; 
    1582         int no_items; 
     1641                c_put_str(TERM_WHITE, out_val, row, scr_places_x[LOC_PRICE]); 
     1642        } 
     1643
     1644 
     1645 
     1646 
     1647 
     1648/* 
     1649 * Redisplay a single store entry 
     1650 */ 
     1651static void store_display_entry(menu_type *menu, int oid, bool cursor, int row, int col, int width) 
     1652
     1653        object_type *o_ptr; 
     1654        s32b x; 
     1655 
     1656        char o_name[80]; 
     1657        char out_val[160]; 
     1658        byte colour; 
    15831659 
    15841660        store_type *st_ptr = &store[store_current]; 
    15851661 
    1586         /* Get number of items to show */ 
    1587         start = scr_places_y[LOC_ITEMS_START]; 
    1588         end = scr_places_y[LOC_ITEMS_END]; 
    1589  
    1590         no_items = (end - start) + 1; 
    1591  
    1592         /* Display items */ 
    1593         for (i = 0; i < no_items; i++) 
    1594         { 
    1595                 /* Clear non-items */ 
    1596                 if ((store_top + i) >= st_ptr->stock_num) 
    1597                         prt("", start + i, 0); 
    1598  
    1599                 /* Display items */ 
     1662        (void)menu; 
     1663        (void)cursor; 
     1664        (void)width; 
     1665 
     1666        /* Get the object */ 
     1667        o_ptr = &st_ptr->stock[oid]; 
     1668 
     1669        /* Describe the object */ 
     1670        object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); 
     1671 
     1672        /* Display the object */ 
     1673        c_put_str(tval_to_attr[o_ptr->tval & 0x7F], o_name, row, col); 
     1674 
     1675        /* Show weights */ 
     1676        if (show_weights) 
     1677        { 
     1678                int wgt = o_ptr->weight; 
     1679 
     1680                sprintf(out_val, "%3d.%d lb", wgt / 10, wgt % 10); 
     1681                put_str(out_val, row, scr_places_x[LOC_WEIGHT]); 
     1682        } 
     1683 
     1684        /* Describe an object (fully) in a store */ 
     1685        if (store_current != STORE_HOME) 
     1686        { 
     1687                /* Extract the "minimum" price */ 
     1688                x = price_item(o_ptr, FALSE); 
     1689 
     1690                /* Make sure the player can afford it */ 
     1691                if ((unsigned int) p_ptr->au < (unsigned int) x) 
     1692                        colour = TERM_SLATE; 
    16001693                else 
    1601                         store_display_entry(store_top + i); 
    1602         } 
    1603 
    1604  
     1694                        colour = TERM_WHITE; 
     1695 
     1696                /* Actually draw the price */ 
     1697                if (((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF)) && 
     1698                    (o_ptr->number > 1)) 
     1699                        sprintf(out_val, "%9ld avg", (long)x); 
     1700                else 
     1701                        sprintf(out_val, "%9ld    ", (long)x); 
     1702 
     1703                c_put_str(colour, out_val, row, scr_places_x[LOC_PRICE]); 
     1704        } 
     1705
    16051706 
    16061707 
     
    16211722        { 
    16221723                /* Put the owner name */ 
    1623                 put_str("Your Home", 3, 0); 
     1724                put_str("Your Home", scr_places_y[LOC_OWNER], 2); 
    16241725 
    16251726                /* Label the object descriptions */ 
    1626                 put_str("Item Description", 5, 3); 
     1727                if (store_flags & STORE_INVEN) 
     1728                        put_str("Your Inventory", scr_places_y[LOC_HEADER], 1); 
     1729                else 
     1730                        put_str("Home Inventory", scr_places_y[LOC_HEADER], 1); 
    16271731 
    16281732                /* If showing weights, show label */ 
    16291733                if (show_weights) 
    1630                         put_str("Weight", 5, weight_pos(store_current) + 2); 
     1734                        put_str("Weight", 5, scr_places_x[LOC_WEIGHT] + 2); 
    16311735        } 
    16321736 
     
    16441748                /* Show the max price in the store (above prices) */ 
    16451749                strnfmt(buf, sizeof(buf), "%s (%ld)", store_name, (long)(ot_ptr->max_cost)); 
    1646                 prt(buf, scr_places_y[LOC_OWNER], (Term->wid - strlen(buf) - 2)); 
     1750                prt(buf, scr_places_y[LOC_OWNER], scr_places_x[LOC_OWNER] - strlen(buf)); 
    16471751 
    16481752                /* Label the object descriptions */ 
    1649                 put_str("Item Description", scr_places_y[LOC_HEADER], 3); 
     1753                if (store_flags & STORE_INVEN) 
     1754                        put_str("Your Inventory", scr_places_y[LOC_HEADER], 1); 
     1755                else 
     1756                        put_str("Store Inventory", scr_places_y[LOC_HEADER], 1); 
    16501757 
    16511758                /* If showing weights, show label */ 
    16521759                if (show_weights) 
    1653                         put_str("Weight", scr_places_y[LOC_HEADER], weight_pos(store_current) + 2); 
     1760                        put_str("Weight", scr_places_y[LOC_HEADER], scr_places_x[LOC_WEIGHT] + 2); 
    16541761 
    16551762                /* Label the asking price (in stores) */ 
     
    16691776        clear_from(scr_places_y[LOC_HELP_CLEAR]); 
    16701777 
    1671         if (store_flags & STORE_HELP) 
    1672         { 
    1673                 /* Prepare help hooks */ 
    1674                 text_out_hook = text_out_to_screen; 
    1675                 text_out_indent = 1; 
    1676                 Term_gotoxy(1, help_loc); 
    1677  
    1678                 text_out("Use the "); 
    1679                 text_out_c(TERM_L_GREEN, "movement keys"); 
    1680                 text_out(" and the "); 
    1681                 text_out_c(TERM_L_GREEN, "spacebar"); 
    1682                 text_out(" to navigate the store's inventory, '"); 
    1683  
    1684                 text_out_c(TERM_L_GREEN, "p"); 
    1685                 text_out("' to obtain an item, '"); 
    1686  
    1687                 text_out_c(TERM_L_GREEN, "s"); 
    1688  
    1689                 if (store_current == STORE_HOME) text_out("' to deposit"); 
    1690                 else text_out("' to sell"); 
    1691  
    1692                 text_out(" an item, '"); 
    1693  
    1694                 if (rogue_like_commands) 
    1695                         text_out_c(TERM_L_GREEN, "x"); 
     1778        /* Prepare help hooks */ 
     1779        text_out_hook = text_out_to_screen; 
     1780        text_out_indent = 1; 
     1781        Term_gotoxy(1, help_loc); 
     1782 
     1783        text_out("Use the "); 
     1784        text_out_c(TERM_L_GREEN, "movement keys"); 
     1785        text_out(" to navigate "); 
     1786 
     1787        if (store_flags & STORE_INVEN) 
     1788                text_out("your"); 
     1789        else 
     1790                text_out("the store's"); 
     1791 
     1792        text_out(" inventory, '"); 
     1793 
     1794        if (rogue_like_commands) 
     1795                text_out_c(TERM_L_GREEN, "x"); 
     1796        else 
     1797        { 
     1798                if (store_flags & STORE_INVEN) 
     1799                        text_out_c(TERM_L_GREEN, "I"); 
    16961800                else 
    16971801                        text_out_c(TERM_L_GREEN, "l"); 
    1698  
    1699                 text_out("' to look at item, or '"); 
    1700                 text_out_c(TERM_L_GREEN, "ESC"); 
    1701                 text_out("' to exit the building."); 
    1702  
    1703                 text_out_indent = 0; 
    1704         } 
     1802        } 
     1803 
     1804        text_out("' to examine an item, or '"); 
     1805 
     1806        text_out_c(TERM_L_GREEN, "Enter"); 
     1807        text_out("' to "); 
     1808 
     1809        if (store_flags & STORE_INVEN) 
     1810                text_out("sell"); 
    17051811        else 
    1706         { 
    1707                 /* Prompt */ 
    1708                 prt("Press '?' for help.", help_loc, 1); 
    1709         } 
     1812                text_out("obtain"); 
     1813 
     1814        text_out(" an item.  If you want to "); 
     1815 
     1816        if (store_flags & STORE_INVEN) 
     1817        { 
     1818                if (store_current == STORE_HOME) text_out("pick up"); 
     1819                else text_out("purchase"); 
     1820        } 
     1821        else 
     1822        { 
     1823                if (store_current == STORE_HOME) text_out("deposit"); 
     1824                else text_out("sell"); 
     1825        } 
     1826 
     1827        text_out(" items, press '"); 
     1828 
     1829        text_out_c(TERM_L_GREEN, "TAB"); 
     1830        text_out("' or '"); 
     1831 
     1832        if (store_flags & STORE_INVEN) 
     1833                text_out_c(TERM_L_GREEN, "p"); 
     1834        else 
     1835                text_out_c(TERM_L_GREEN, "s"); 
     1836 
     1837        text_out("'.  "); 
     1838 
     1839        text_out_c(TERM_L_GREEN, "ESC"); 
     1840        text_out(" exits the building."); 
     1841 
     1842        text_out_indent = 0; 
    17101843} 
    17111844 
     
    17161849static void store_redraw(void) 
    17171850{ 
    1718         if ((store_flags & (STORE_SIZE_CHANGE)) || 
    1719             (store_flags & (STORE_HELP_CHANGE))) 
    1720         { 
    1721                 store_display_recalc(); 
    1722                 store_flags &= ~(STORE_SIZE_CHANGE); 
    1723         } 
    1724  
    17251851        if (store_flags & (STORE_FRAME_CHANGE)) 
    17261852        { 
    17271853                store_display_frame(); 
     1854                store_display_help(); 
    17281855                store_flags &= ~(STORE_FRAME_CHANGE); 
    1729         } 
    1730  
    1731         if (store_flags & (STORE_HELP_CHANGE)) 
    1732         { 
    1733                 store_display_help(); 
    1734                 store_flags &= ~(STORE_HELP_CHANGE); 
    1735                 store_flags |= (STORE_GOLD_CHANGE | STORE_INVEN_CHANGE); 
    1736         } 
    1737  
    1738         if (store_flags & (STORE_INVEN_CHANGE)) 
    1739         { 
    1740                 store_display_inventory(); 
    1741                 store_flags &= ~(STORE_INVEN_CHANGE); 
    1742                 store_flags |= (STORE_MORE_CHANGE); 
    1743         } 
    1744  
    1745         if (store_flags & (STORE_MORE_CHANGE)) 
    1746         { 
    1747                 const char *p; 
    1748                 store_type *st_ptr = &store[store_current]; 
    1749                 int no_items = (scr_places_y[LOC_ITEMS_END] - 
    1750                                 scr_places_y[LOC_ITEMS_START]) + 1; 
    1751  
    1752                 /* Visual reminder of more items */ 
    1753                 if ((store_top + no_items) >= st_ptr->stock_num) 
    1754                 { 
    1755                         if (store_top > 0) p = " < more"; 
    1756                         else              p = ""; 
    1757                 } 
    1758                 else 
    1759                 { 
    1760                         if (store_top > 0) p = " < more >"; 
    1761                         else              p = "   more >"; 
    1762                 } 
    1763  
    1764                 prt(p, scr_places_y[LOC_MORE], 0); 
    1765  
    1766                 store_flags &= ~(STORE_MORE_CHANGE); 
    17671856        } 
    17681857 
     
    17731862                store_flags &= ~(STORE_GOLD_CHANGE); 
    17741863        } 
    1775  
    1776         /* Reset the cursor */ 
    1777         Term_gotoxy(0, 0); 
    1778 
    1779  
    1780 /* 
    1781  * Hook for terminal size change 
    1782  */ 
    1783 void store_display_resize(void) 
    1784 
    1785         /* Mark the change */ 
    1786         store_flags |= STORE_SIZE_CHANGE; 
    1787  
    1788         /* Redraw */ 
    1789         store_redraw(); 
    1790 
    1791  
    1792  
    1793 /*** User interaction bits ***/ 
    1794  
    1795 /* 
    1796  * Get the index of a store object. 
    1797  * Return TRUE if an object was selected 
    1798  */ 
    1799 static bool get_stock(int *com_val, cptr pmt) 
    1800 
    1801         int item; 
    1802         char which; 
    1803         char buf[160]; 
    1804         char o_name[80]; 
    1805         char out_val[160]; 
    1806         object_type *o_ptr; 
    1807         store_type *st_ptr = &store[store_current]; 
    1808  
    1809 #ifdef ALLOW_REPEAT 
    1810  
    1811         /* Get the item index */ 
    1812         if (repeat_pull(com_val)) 
    1813         { 
    1814                 /* Verify the item */ 
    1815                 if ((*com_val >= 0) && (*com_val <= (st_ptr->stock_num - 1))) 
    1816                 { 
    1817                         /* Success */ 
    1818                         return (TRUE); 
    1819                 } 
    1820                 else 
    1821                 { 
    1822                         /* Invalid repeat - reset it */ 
    1823                         repeat_clear(); 
    1824                 } 
    1825         } 
    1826  
    1827 #endif /* ALLOW_REPEAT */ 
    1828  
    1829         /* Assume failure */ 
    1830         *com_val = (-1); 
    1831  
    1832         /* Build the prompt */ 
    1833         strnfmt(buf, sizeof(buf), "%s (%c-%c, ESC to exit)", 
    1834                 pmt, store_to_label(0), store_to_label(st_ptr->stock_num - 1)); 
    1835  
    1836         /* Ask until done */ 
    1837         while (TRUE) 
    1838         { 
    1839                 bool verify; 
    1840  
    1841                 /* Escape */ 
    1842                 if (!get_com(buf, &which)) return (FALSE); 
    1843  
    1844                 /* Note verify */ 
    1845                 verify = (isupper((unsigned char)which) ? TRUE : FALSE); 
    1846  
    1847                 /* Lowercase */ 
    1848                 which = tolower((unsigned char)which); 
    1849  
    1850                 /* Convert response to item */ 
    1851                 item = label_to_store(which); 
    1852  
    1853                 /* Oops */ 
    1854                 if (item < 0) 
    1855                 { 
    1856                         /* Oops */ 
    1857                         bell("Illegal store object choice!"); 
    1858  
    1859                         continue; 
    1860                 } 
    1861  
    1862                 /* No verification */ 
    1863                 if (!verify) break; 
    1864  
    1865                 /* Object */ 
    1866                 o_ptr = &st_ptr->stock[item]; 
    1867  
    1868                 /* Describe */ 
    1869                 object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); 
    1870  
    1871                 /* Prompt */ 
    1872                 strnfmt(out_val, sizeof(out_val), "Try %s? ", o_name); 
    1873  
    1874                 /* Query */ 
    1875                 if (!get_check(out_val)) return (FALSE); 
    1876  
    1877                 /* Done */ 
    1878                 break; 
    1879         } 
    1880  
    1881         /* Save item */ 
    1882         (*com_val) = item; 
    1883  
    1884 #ifdef ALLOW_REPEAT 
    1885  
    1886         repeat_push(*com_val); 
    1887  
    1888 #endif /* ALLOW_REPEAT */ 
     1864
     1865 
     1866 
     1867/*** Higher-level code ***/ 
     1868 
     1869 
     1870static bool store_get_check(const char *prompt) 
     1871
     1872        char ch; 
     1873 
     1874        /* Prompt for it */ 
     1875        prt(prompt, 0, 0); 
     1876 
     1877        /* Get an answer */ 
     1878        ch = inkey(); 
     1879 
     1880        /* Erase the prompt */ 
     1881        prt("", 0, 0); 
     1882 
     1883        if (ch == ESCAPE) return (FALSE); 
     1884        if (strchr("Nn", ch)) return (FALSE); 
    18891885 
    18901886        /* Success */ 
     
    18931889 
    18941890 
    1895 /*** Higher-level code ***/ 
    1896  
    1897  
    18981891 
    18991892/* 
    19001893 * Buy an object from a store 
    19011894 */ 
    1902 static void store_purchase(void) 
    1903 
    1904         int n; 
    1905         int amt, item, item_new; 
     1895static bool store_purchase(int item) 
     1896
     1897        int amt, item_new; 
    19061898 
    19071899        store_type *st_ptr = &store[store_current]; 
     
    19141906        char o_name[80]; 
    19151907 
    1916         cptr take_prompt = "Which item are you interested in? "; 
    1917         cptr take_home = "Which item do you want to take? "; 
    1918  
    1919         cptr p = take_prompt; 
    1920  
    19211908        s32b price; 
    1922  
    1923         /* Empty? */ 
    1924         if (st_ptr->stock_num <= 0) 
    1925         { 
    1926                 if (store_current == STORE_HOME) 
    1927                         msg_print("Your home is empty."); 
    1928                 else 
    1929                         msg_print("I am currently out of stock."); 
    1930  
    1931                 return; 
    1932         } 
    1933  
    1934  
    1935         /* Prompt */ 
    1936         if (store_current == STORE_HOME) p = take_home; 
    1937  
    1938         /* Get the object number to be bought */ 
    1939         if (!get_stock(&item, p)) return; 
    19401909 
    19411910        /* Get the actual object */ 
    19421911        o_ptr = &st_ptr->stock[item]; 
    19431912 
     1913        /* Clear all current messages */ 
     1914        msg_flag = FALSE; 
     1915        prt("", 0, 0); 
     1916 
    19441917        if (store_current == STORE_HOME) 
    19451918        { 
    1946                 /* Get a quantity */ 
    1947                 amt = get_quantity(NULL, o_ptr->number)
     1919                /* Stores always take one */ 
     1920                amt = 1
    19481921        } 
    19491922        else 
     
    19611934 
    19621935                        /* Abort now */ 
    1963                         return
     1936                        return FALSE
    19641937                } 
    19651938 
     
    19731946 
    19741947        /* Allow user abort */ 
    1975         if (amt <= 0) return
     1948        if (amt <= 0) return FALSE
    19761949 
    19771950        /* Get local object */ 
     
    19951968        { 
    19961969                msg_print("You cannot carry that many items."); 
    1997                 return
     1970                return FALSE
    19981971        } 
    19991972 
     
    20151988                prt(format("Price: %d", price), 1, 0); 
    20161989 
    2017                 /* Remind the user what they're buying */ 
    2018                 msg_format("Buying %s (%c).", o_name, store_to_label(item)); 
    2019                 message_flush(); 
    2020  
    20211990                /* Confirm purchase */ 
    2022                 response = get_check("Buy? "); 
     1991                response = store_get_check(format("Buy %s? [ESC, any other key to accept]", o_name)); 
    20231992                screen_load(); 
    20241993 
    20251994                /* Negative response, so give up */ 
    2026                 if (!response) return
     1995                if (!response) return FALSE
    20271996 
    20281997 
     
    20692038                /* Handle stuff */ 
    20702039                handle_stuff(); 
    2071  
    2072                 /* Note how many slots the store used to have */ 
    2073                 n = st_ptr->stock_num; 
    20742040 
    20752041                /* Remove the bought objects from the store */ 
     
    21052071                                store_maint(store_current); 
    21062072                        } 
    2107  
    2108                         /* Start over */ 
    2109                         store_top = 0; 
    2110                 } 
    2111  
    2112                 /* The object is gone */ 
    2113                 else if (st_ptr->stock_num != n) 
    2114                 { 
    2115                         /* Reset visible area to avoid weirdness */ 
    2116                         store_top = 0; 
    2117                 } 
    2118  
    2119                 /* Redraw inventory */ 
    2120                 store_flags |= STORE_INVEN_CHANGE; 
    2121  
     2073                } 
    21222074        } 
    21232075 
     
    21392091                /* Handle stuff */ 
    21402092                handle_stuff(); 
    2141  
    2142                 /* Take note if we take the last one */ 
    2143                 n = st_ptr->stock_num; 
    21442093 
    21452094                /* Remove the items from the home */ 
    21462095                store_item_increase(store_current, item, -amt); 
    21472096                store_item_optimize(store_current, item); 
    2148  
    2149                 /* The object is gone */ 
    2150                 if (st_ptr->stock_num != n) 
    2151                 { 
    2152                         /* Reset visible area to avoid weirdness */ 
    2153                         store_top = 0; 
    2154                 } 
    2155  
    2156                 /* Redraw inventory */ 
    2157                 store_flags |= STORE_INVEN_CHANGE; 
    21582097        } 
    21592098 
    21602099        /* Not kicked out */ 
    2161         return
     2100        return TRUE
    21622101} 
    21632102 
     
    21662105 * Sell an object, or drop if it we're in the home. 
    21672106 */ 
    2168 static void store_sell(void) 
    2169 
    2170         int item, item_pos; 
     2107static void store_sell(int item) 
     2108
    21712109        int amt; 
    21722110 
     
    21752113        object_type object_type_body; 
    21762114 
    2177         cptr q; 
    2178     &nb