From fc767d9b3b123f6bdf37e30b78200c06f042b570 Mon Sep 17 00:00:00 2001 From: haranp Date: Sat, 14 Jul 2007 12:57:54 +0000 Subject: Rewrite of the shopping code. Much cleaner now. Hopefully I didn't break anything. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1861 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/itemprop.cc | 12 +- crawl-ref/source/items.cc | 5 + crawl-ref/source/shopping.cc | 379 ++++++++++++++++++------------------------- crawl-ref/source/stuff.cc | 18 +- 4 files changed, 179 insertions(+), 235 deletions(-) diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index 1e8d20ae10..8162a4cd88 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -460,15 +460,16 @@ bool item_ident( const item_def &item, unsigned long flags ) void set_ident_flags( item_def &item, unsigned long flags ) { - const bool known_before = fully_identified(item); item.flags |= flags; if (notes_are_active() && !(item.flags & ISFLAG_NOTED_ID) && - !known_before && fully_identified(item) && is_interesting_item(item)) + fully_identified(item) && is_interesting_item(item)) { - /* make a note of it */ + // make a note of it take_note(Note(NOTE_ID_ITEM, 0, 0, item.name(DESC_NOCAP_A).c_str(), origin_desc(item).c_str())); - item.flags |= ISFLAG_NOTED_ID; + // sometimes (e.g. shops) you can ID an item before you get it; + // don't note twice in those cases + item.flags |= (ISFLAG_NOTED_ID | ISFLAG_NOTED_GET); } } @@ -517,8 +518,7 @@ unsigned long full_ident_mask( const item_def& item ) if (item_type_known(item)) flagset &= (~ISFLAG_KNOW_TYPE); - if ( is_random_artefact(item) || - is_fixed_artefact(item) ) + if ( is_artefact(item) ) { flagset |= ISFLAG_KNOW_PROPERTIES; } diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 926876ead5..e9c781c5ce 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -852,6 +852,11 @@ static void check_note_item(item_def &item) take_note(Note(NOTE_GET_ITEM, 0, 0, item.name(DESC_NOCAP_A).c_str(), origin_desc(item).c_str())); item.flags |= ISFLAG_NOTED_GET; + + // If it's already fully identified when picked up, don't take + // further notes. + if ( fully_identified(item) ) + item.flags |= ISFLAG_NOTED_ID; } } diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc index 6836137cca..003a418d1b 100644 --- a/crawl-ref/source/shopping.cc +++ b/crawl-ref/source/shopping.cc @@ -40,9 +40,9 @@ #include "stuff.h" #include "view.h" -static void in_a_shop(char shoppy); -static char more3(); -static void purchase( int shop, int item_got, int cost); +static void in_a_shop(int shopidx); +static void more3(); +static void purchase( int shop, int item_got, int cost, bool id); static void shop_print(const char *shoppy, int sh_line); static std::string hyphenated_suffix(char prev, char last) @@ -87,7 +87,7 @@ static void list_shop_keys(const std::string &purchasable) gotoxy(1, numlines - 1); std::string pkeys = purchase_keys(purchasable); - if (pkeys.length()) + if (!pkeys.empty()) pkeys = "[" + pkeys + "] Buy Item"; snprintf(buf, sizeof buf, @@ -106,239 +106,191 @@ static void list_shop_keys(const std::string &purchasable) fs.display(); } -static void in_a_shop( char shoppy ) +static std::vector shop_stock(int shopidx) { - shop_struct& the_shop = env.shop[shoppy]; - - cursor_control coff(false); - - FixedVector < int, 20 > shop_items; - - char st_pass[ ITEMNAME_SIZE ] = ""; - unsigned char ft; - std::string purchasable; - - clrscr(); - int itty = 0; - int gp_value; // Should eliminate gotos instead of initializing here - - ShopInfo &si = stashes.get_shop(the_shop.x, the_shop.y); - - { - std::string welcome_message = "Welcome to "; - welcome_message += shop_name(the_shop.x, the_shop.y); - welcome_message += "!"; - shop_print(welcome_message.c_str(), 20); - } - - more3(); + std::vector result; - activate_notes(false); /* should do a better job here */ - - const bool id_stock = shoptype_identifies_stock(the_shop.type); + int itty = igrd[0][5 + shopidx]; - print_stock: - clrscr(); - itty = igrd[0][5 + shoppy]; - - si.reset(); - - if (itty == NON_ITEM) + while ( itty != NON_ITEM ) { - shop_print("I'm sorry, my shop is empty now.", 20); - more3(); - goto goodbye; + result.push_back( itty ); + itty = mitm[itty].link; } + return result; +} - for (int i = 1; i < 20; i++) +static int shop_item_value(const item_def& item, int greed, bool id) +{ + int result = (greed * item_value(item, id) / 10); + if ( you.duration[DUR_BARGAIN] ) // 20% discount { - shop_items[i - 1] = itty; - - if (itty == NON_ITEM) - { - shop_items[i - 1] = NON_ITEM; - continue; - } - - itty = mitm[itty].link; + result *= 8; + result /= 10; } + + if (result < 1) + result = 1; - itty = igrd[0][5 + shoppy]; + return result; +} - purchasable.clear(); - for (int i = 1; i < 18; i++) +static std::string shop_print_stock( const std::vector& stock, + const shop_struct& shop ) +{ + ShopInfo &si = stashes.get_shop(shop.x, shop.y); + const bool id = shoptype_identifies_stock(shop.type); + std::string purchasable; + for (unsigned int i = 0; i < stock.size(); ++i) { - const char c = i + 96; - - gotoxy(1, i); - - gp_value = the_shop.greed * item_value(mitm[itty], id_stock); - gp_value /= 10; - - if ( you.duration[DUR_BARGAIN] ) // 20% discount - { - gp_value *= 8; - gp_value /= 10; - } - - if (gp_value <= 1) - gp_value = 1; - + const int gp_value = shop_item_value(mitm[stock[i]], shop.greed, id); const bool can_afford = (you.gold >= gp_value); - textcolor( can_afford ? LIGHTGREEN : LIGHTRED ); + gotoxy(1, i+1); + const char c = i + 'a'; if (can_afford) purchasable += c; + textcolor( can_afford ? LIGHTGREEN : LIGHTRED ); cprintf("%c - ", c); - textcolor((i % 2) ? WHITE : LIGHTGREY); - - cprintf("%s", mitm[itty].name(DESC_NOCAP_A, false, id_stock).c_str()); - - si.add_item(mitm[itty], gp_value); - - gotoxy(60, i); - cprintf("%5d gold", gp_value); - if (mitm[itty].link == NON_ITEM) - break; - - itty = mitm[itty].link; + textcolor((i % 2) ? LIGHTGREY : WHITE); + cprintf("%-56s%5d gold", + mitm[stock[i]].name(DESC_NOCAP_A, false, id).c_str(), + gp_value); + si.add_item(mitm[stock[i]], gp_value); } - textcolor(LIGHTGREY); + return purchasable; +} - list_shop_keys(purchasable); - - purchase: - snprintf( info, INFO_SIZE, "You have %d gold piece%s.", you.gold, - (you.gold == 1) ? "" : "s" ); - - textcolor(YELLOW); - shop_print(info, 19); - - textcolor(CYAN); - - snprintf(st_pass, sizeof st_pass, - "What would you like to %s?", - purchasable.length()? "purchase" : "do"); - shop_print(st_pass, 20); - textcolor(LIGHTGREY); +static void in_a_shop( int shopidx ) +{ + const shop_struct& shop = env.shop[shopidx]; - ft = get_ch(); + cursor_control coff(false); - if (ft == 'x' || ft == ESCAPE) - goto goodbye; + const std::string hello = "Welcome to " + shop_name(shop.x, shop.y) + "!"; + shop_print(hello.c_str(), 20); - if (ft == '\\') + more3(); + + const bool id_stock = shoptype_identifies_stock(shop.type); + + while ( true ) { - check_item_knowledge(); - goto print_stock; - } + stashes.get_shop(shop.x, shop.y).reset(); + + std::vector stock = shop_stock(shopidx); - if (ft == 'v') - { + clrscr(); + if ( stock.empty() ) + { + shop_print("I'm sorry, my shop is empty now.", 20); + more3(); + return; + } + + const std::string purchasable = shop_print_stock(stock, shop); + list_shop_keys(purchasable); + + snprintf( info, INFO_SIZE, "You have %d gold piece%s.", you.gold, + (you.gold == 1) ? "" : "s" ); + textcolor(YELLOW); + shop_print(info, 19); + + snprintf( info, INFO_SIZE, "What would you like to %s?", + purchasable.length()? "purchase" : "do"); textcolor(CYAN); - shop_print("Examine which item?", 20); + shop_print(info, 20); + textcolor(LIGHTGREY); - ft = get_ch(); - // wonder whether this should be recoded to permit uppercase, too? {dlb} - if (ft < 'a' || ft > 'z') - goto huh; + int ft = get_ch(); + + if ( ft == '\\' ) + check_item_knowledge(); + else if (ft == 'x' || ft == ESCAPE) + break; + else if (ft == 'v') + { + textcolor(CYAN); + shop_print("Examine which item?", 20); + textcolor(LIGHTGREY); - ft -= 'a'; // see above comment {dlb} + bool is_ok = true; - if (ft > 18) - goto huh; + ft = get_ch(); + if ( !isalpha(ft) ) + { + is_ok = false; + } + else + { + ft = tolower(ft) - 'a'; + if ( ft >= static_cast(stock.size()) ) + is_ok = false; + } - if (shop_items[ft] == NON_ITEM) + if ( !is_ok ) + { + shop_print("Huh?", 20); + more3(); + continue; + } + + // A hack to make the description more useful. + // In theory, the user could kill the process at this + // point and end up with valid ID for the item. + // That's not very useful, though, because it doesn't set + // type-ID and once you can access the item (by buying it) + // you have its full ID anyway. Worst case, it won't get + // noted when you buy it. + item_def& item = mitm[stock[ft]]; + const unsigned long old_flags = item.flags; + if ( id_stock ) + item.flags |= ISFLAG_IDENT_MASK; + describe_item(item); + if ( id_stock ) + item.flags = old_flags; + } + else if (ft == '?' || ft == '*') + invent(-1, false); + else if ( !isalpha(ft) ) { - shop_print("I'm sorry, you seem to be confused.", 20); + shop_print("Huh?", 20); more3(); - goto purchase; } + else + { + ft = tolower(ft) - 'a'; + if (ft >= static_cast(stock.size()) ) + { + shop_print("No such item.", 20); + more3(); + continue; + } - // A hack to make the description more useful. - // In theory, the user could kill the process at this - // point and end up with valid ID for the item. - // That's not very useful, though, because it doesn't set - // type-ID and once you can access the item (by buying it) - // you have its full ID anyway. Worst case, it won't get - // noted when you buy it. - item_def& item = mitm[shop_items[ft]]; - const unsigned long old_flags = item.flags; - if ( id_stock ) - item.flags |= ISFLAG_IDENT_MASK; - describe_item(item); - if ( id_stock ) - item.flags = old_flags; - - goto print_stock; - } - - if (ft == '?' || ft == '*') - { - invent(-1, false); - goto print_stock; - } - - if (ft < 'a' || ft > 'z') // see earlier comments re: uppercase {dlb} - { - huh: - shop_print("Huh?", 20); - more3(); - goto purchase; - } - - ft -= 'a'; // see earlier comments re: uppercase {dlb} - - if (ft > 18) - goto huh; - - if (shop_items[ft] == NON_ITEM) - { - shop_print("I'm sorry, you seem to be confused.", 20); - more3(); - goto purchase; - } - - gp_value = the_shop.greed*item_value(mitm[shop_items[ft]],id_stock)/10; - if ( you.duration[DUR_BARGAIN] ) // 20% discount - { - gp_value *= 8; - gp_value /= 10; - } + item_def& item = mitm[stock[ft]]; + + const int gp_value = shop_item_value(item, shop.greed, id_stock); + if (gp_value > you.gold) + { + shop_print("I'm sorry, you don't seem to have enough money.", + 20); + more3(); + } + else + { + snprintf(info, INFO_SIZE, "Purchase %s (%d gold)? [y/n]", + item.name(DESC_NOCAP_A).c_str(), gp_value); + shop_print(info, 20); - if (gp_value > you.gold) - { - shop_print("I'm sorry, you don't seem to have enough money.", 20); - more3(); - goto purchase; - } - snprintf(info, INFO_SIZE, "Purchase %s (%d gold)? [y/n]", - mitm[shop_items[ft]].name(DESC_NOCAP_A).c_str(), gp_value); - shop_print(info, 20); - if ( yesno(NULL, true, 'n', false, false, true) ) - { - if ( id_stock ) - { - // Identify the item and its type. - item_def& pitem = mitm[shop_items[ft]]; - set_ident_type(pitem.base_type, pitem.sub_type, ID_KNOWN_TYPE); - set_ident_flags(pitem, ISFLAG_IDENT_MASK); + if ( yesno(NULL, true, 'n', false, false, true) ) + purchase( shopidx, stock[ft], gp_value, id_stock ); + } } - // purchase() will take the note if necessary. - purchase( shoppy, shop_items[ft], gp_value ); } - - goto print_stock; - - goodbye: - shop_print("Goodbye!", 20); - more3(); - - activate_notes(true); } bool shoptype_identifies_stock(int shoptype) @@ -359,20 +311,15 @@ static void shop_print( const char *shoppy, int sh_lines ) cprintf(" "); } -static char more3() +static void more3() { - char keyin = 0; - gotoxy(70, 20); cprintf("-more-"); - keyin = getch(); - if (keyin == 0) - getch(); - //clear_line(); - return keyin; + get_ch(); + return; } -static void purchase( int shop, int item_got, int cost ) +static void purchase( int shop, int item_got, int cost, bool id ) { you.gold -= cost; @@ -380,15 +327,12 @@ static void purchase( int shop, int item_got, int cost ) origin_purchased(item); - if ( fully_identified(item) && is_interesting_item(item) ) + if ( id ) { - activate_notes(true); - - take_note(Note(NOTE_ID_ITEM, 0, 0, - item.name(DESC_NOCAP_A).c_str(), - origin_desc(item).c_str())); - - activate_notes(false); + // Identify the item and its type. + // This also takes the ID note if necessary. + set_ident_type(item.base_type, item.sub_type, ID_KNOWN_TYPE); + set_ident_flags(item, ISFLAG_IDENT_MASK); } const int quant = item.quantity; @@ -1526,10 +1470,8 @@ void shop() int i; for (i = 0; i < MAX_SHOPS; i++) - { if (env.shop[i].x == you.x_pos && env.shop[i].y == you.y_pos) break; - } if (i == MAX_SHOPS) { @@ -1538,10 +1480,7 @@ void shop() } in_a_shop(i); - - you.redraw_gold = 1; burden_change(); - redraw_screen(); } // end shop() diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 7a33c5684d..4bc380a939 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -432,15 +432,15 @@ void redraw_screen(void) { draw_border(); - you.redraw_hit_points = 1; - you.redraw_magic_points = 1; - you.redraw_strength = 1; - you.redraw_intelligence = 1; - you.redraw_dexterity = 1; - you.redraw_armour_class = 1; - you.redraw_evasion = 1; - you.redraw_gold = 1; - you.redraw_experience = 1; + you.redraw_hit_points = true; + you.redraw_magic_points = true; + you.redraw_strength = true; + you.redraw_intelligence = true; + you.redraw_dexterity = true; + you.redraw_armour_class = true; + you.redraw_evasion = true; + you.redraw_gold = true; + you.redraw_experience = true; you.wield_change = true; set_redraw_status( -- cgit v1.2.3-54-g00ecf