From 673bdae75485d14f759af597c3c62b99601f9a43 Mon Sep 17 00:00:00 2001 From: peterb12 Date: Thu, 21 Jul 2005 02:34:44 +0000 Subject: Initial revision git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3 c06c8d41-db1a-0410-9941-cceddc491573 --- trunk/source/invent.cc | 631 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 631 insertions(+) create mode 100644 trunk/source/invent.cc (limited to 'trunk/source/invent.cc') diff --git a/trunk/source/invent.cc b/trunk/source/invent.cc new file mode 100644 index 0000000000..1a6db7d1bc --- /dev/null +++ b/trunk/source/invent.cc @@ -0,0 +1,631 @@ +/* + * File: invent.cc + * Summary: Functions for inventory related commands. + * Written by: Linley Henzell + * + * Change History (most recent first): + * + * <5> 10/9/99 BCR Added wizard help screen + * <4> 10/1/99 BCR Clarified help screen + * <3> 6/9/99 DML Autopickup + * <2> 5/20/99 BWR Extended screen lines support + * <1> -/--/-- LRH Created + */ + +#include "AppHdr.h" +#include "invent.h" + +#include +#include +#include + +#ifdef DOS +#include +#endif + +#include "externs.h" + +#include "itemname.h" +#include "items.h" +#include "macro.h" +#include "player.h" +#include "shopping.h" +#include "stuff.h" +#include "view.h" + + +const char *command_string( int i ); +const char *wizard_string( int i ); + +unsigned char get_invent( int invent_type ) +{ + unsigned char nothing = invent( invent_type, false ); + + redraw_screen(); + + return (nothing); +} // end get_invent() + +unsigned char invent( int item_class_inv, bool show_price ) +{ + char st_pass[ ITEMNAME_SIZE ] = ""; + + int i, j; + char lines = 0; + unsigned char anything = 0; + char tmp_quant[20] = ""; + char yps = 0; + char temp_id[4][50]; + + const int num_lines = get_number_of_lines(); + + FixedVector< int, NUM_OBJECT_CLASSES > inv_class2; + int inv_count = 0; + unsigned char ki = 0; + +#ifdef DOS_TERM + char buffer[4600]; + + gettext(1, 1, 80, 25, buffer); + window(1, 1, 80, 25); +#endif + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 50; j++) + { + temp_id[i][j] = 1; + } + } + + clrscr(); + + for (i = 0; i < NUM_OBJECT_CLASSES; i++) + inv_class2[i] = 0; + + for (i = 0; i < ENDOFPACK; i++) + { + if (you.inv[i].quantity) + { + inv_class2[ you.inv[i].base_type ]++; + inv_count++; + } + } + + if (!inv_count) + { + cprintf("You aren't carrying anything."); + + if (getch() == 0) + getch(); + + goto putty; + } + + if (item_class_inv != -1) + { + for (i = 0; i < NUM_OBJECT_CLASSES; i++) + { + if (item_class_inv == OBJ_MISSILES && i == OBJ_WEAPONS) + i++; + + if (item_class_inv == OBJ_WEAPONS + && (i == OBJ_STAVES || i == OBJ_MISCELLANY)) + { + i++; + } + + if (item_class_inv == OBJ_SCROLLS && i == OBJ_BOOKS) + i++; + + if (i < NUM_OBJECT_CLASSES && item_class_inv != i) + inv_class2[i] = 0; + } + } + + if ((item_class_inv == -1 && inv_count > 0) + || (item_class_inv != -1 && inv_class2[item_class_inv] > 0) + || (item_class_inv == OBJ_MISSILES && inv_class2[OBJ_WEAPONS] > 0) + || (item_class_inv == OBJ_WEAPONS + && (inv_class2[OBJ_STAVES] > 0 || inv_class2[OBJ_MISCELLANY] > 0)) + || (item_class_inv == OBJ_SCROLLS && inv_class2[OBJ_BOOKS] > 0)) + { + const int cap = carrying_capacity(); + + cprintf( " Inventory: %d.%d aum (%d%% of %d.%d aum maximum)", + you.burden / 10, you.burden % 10, + (you.burden * 100) / cap, cap / 10, cap % 10 ); + lines++; + + for (i = 0; i < 15; i++) + { + if (inv_class2[i] != 0) + { + if (lines > num_lines - 3) + { + gotoxy(1, num_lines); + cprintf("-more-"); + + ki = getch(); + + if (ki == ESCAPE) + { +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + return (ESCAPE); + } + else if (isalpha(ki) || ki == '?' || ki == '*') + { +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + return (ki); + } + + if (ki == 0) + ki = getch(); + + lines = 0; + clrscr(); + gotoxy(1, 1); + anything = 0; + + } + + if (lines > 0) + cprintf(EOL " "); + + textcolor(BLUE); + + switch (i) + { + case OBJ_WEAPONS: cprintf("Hand Weapons"); break; + case OBJ_MISSILES: cprintf("Missiles"); break; + case OBJ_ARMOUR: cprintf("Armour"); break; + case OBJ_WANDS: cprintf("Magical Devices"); break; + case OBJ_FOOD: cprintf("Comestibles"); break; + case OBJ_UNKNOWN_I: cprintf("Books"); break; + case OBJ_SCROLLS: cprintf("Scrolls"); break; + case OBJ_JEWELLERY: cprintf("Jewellery"); break; + case OBJ_POTIONS: cprintf("Potions"); break; + case OBJ_UNKNOWN_II: cprintf("Gems"); break; + case OBJ_BOOKS: cprintf("Books"); break; + case OBJ_STAVES: cprintf("Magical Staves and Rods"); break; + case OBJ_ORBS: cprintf("Orbs of Power"); break; + case OBJ_MISCELLANY: cprintf("Miscellaneous"); break; + case OBJ_CORPSES: cprintf("Carrion"); break; + //case OBJ_GEMSTONES: cprintf("Miscellaneous"); break; + } + + textcolor(LIGHTGREY); + lines++; + + for (j = 0; j < ENDOFPACK; j++) + { + if (lines > num_lines - 2 && inv_count > 0) + { + gotoxy(1, num_lines); + cprintf("-more-"); + ki = getch(); + + if (ki == ESCAPE) + { +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + return (ESCAPE); + } + else if (isalpha(ki) || ki == '?' || ki == '*') + { +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + return (ki); + } + + if (ki == 0) + ki = getch(); + + lines = 0; + clrscr(); + gotoxy(1, 1); + anything = 0; + } + + if (is_valid_item(you.inv[j]) && you.inv[j].base_type==i) + { + anything++; + + if (lines > 0) + cprintf(EOL); + + lines++; + + yps = wherey(); + + in_name( j, DESC_INVENTORY_EQUIP, st_pass ); + cprintf( st_pass ); + + inv_count--; + + + if (show_price) + { + cprintf(" ("); + + itoa( item_value( you.inv[j], temp_id, true ), + tmp_quant, 10 ); + + cprintf( tmp_quant ); + cprintf( " gold)" ); + } + + if (wherey() != yps) + lines++; + } + } // end of j loop + } // end of if inv_class2 + } // end of i loop. + } + else + { + if (item_class_inv == -1) + cprintf("You aren't carrying anything."); + else + { + if (item_class_inv == OBJ_WEAPONS) + cprintf("You aren't carrying any weapons."); + else if (item_class_inv == OBJ_MISSILES) + cprintf("You aren't carrying any ammunition."); + else + cprintf("You aren't carrying any such object."); + + anything++; + } + } + + if (anything > 0) + { + ki = getch(); + + if (isalpha(ki) || ki == '?' || ki == '*') + { +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + return (ki); + } + + if (ki == 0) + ki = getch(); + } + + putty: +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + + return (ki); +} // end invent() + + +// Reads in digits for a count and apprends then to val, the +// return value is the character that stopped the reading. +static unsigned char get_invent_quant( unsigned char keyin, int &quant ) +{ + quant = keyin - '0'; + + for(;;) + { + keyin = get_ch(); + + if (!isdigit( keyin )) + break; + + quant *= 10; + quant += (keyin - '0'); + + if (quant > 9999999) + { + quant = 9999999; + keyin = '\0'; + break; + } + } + + return (keyin); +} + + +// This function prompts the user for an item, handles the '?' and '*' +// listings, and returns the inventory slot to the caller (which if +// must_exist is true (the default) will be an assigned item, with +// a positive quantity. +// +// It returns PROMPT_ABORT if the player hits escape. +// It returns PROMPT_GOT_SPECIAL if the player hits the "other_valid_char". +// +// Note: This function never checks if the item is appropriate. +int prompt_invent_item( const char *prompt, int type_expect, + bool must_exist, bool allow_auto_list, + bool allow_easy_quit, + const char other_valid_char, + int *const count ) +{ + unsigned char keyin = 0; + int ret = -1; + + bool need_redraw = false; + bool need_prompt = true; + bool need_getch = true; + + if (Options.auto_list && allow_auto_list) + { + // pretend the player has hit '?' and setup state. + keyin = invent( type_expect, false ); + + need_getch = false; + + // Don't redraw if we're just going to display another listing + need_redraw = (keyin != '?' && keyin != '*'); + + // A prompt is nice for when we're moving to "count" mode. + need_prompt = (count != NULL && isdigit( keyin )); + } + + for (;;) + { + if (need_redraw) + { + redraw_screen(); + mesclr( true ); + } + + if (need_prompt) + mpr( prompt, MSGCH_PROMPT ); + + if (need_getch) + keyin = get_ch(); + + need_redraw = false; + need_prompt = true; + need_getch = true; + + // Note: We handle any "special" character first, so that + // it can be used to override the others. + if (other_valid_char != '\0' && keyin == other_valid_char) + { + ret = PROMPT_GOT_SPECIAL; + break; + } + else if (keyin == '?' || keyin == '*') + { + // The "view inventory listing" mode. + if (keyin == '*') + keyin = invent( -1, false ); + else + keyin = invent( type_expect, false ); + + need_getch = false; + + // Don't redraw if we're just going to display another listing + need_redraw = (keyin != '?' && keyin != '*'); + + // A prompt is nice for when we're moving to "count" mode. + need_prompt = (count != NULL && isdigit( keyin )); + } + else if (count != NULL && isdigit( keyin )) + { + // The "read in quantity" mode + keyin = get_invent_quant( keyin, *count ); + + need_prompt = false; + need_getch = false; + } + else if (keyin == ESCAPE + || (Options.easy_quit_item_prompts + && allow_easy_quit + && keyin == ' ')) + { + ret = PROMPT_ABORT; + break; + } + else if (isalpha( keyin )) + { + ret = letter_to_index( keyin ); + + if (must_exist && !is_valid_item( you.inv[ret] )) + mpr( "You do not have any such object." ); + else + break; + } + else if (!isspace( keyin )) + { + // we've got a character we don't understand... + canned_msg( MSG_HUH ); + } + } + + return (ret); +} + +void list_commands(bool wizard) +{ + const char *line; + int j = 0; + +#ifdef DOS_TERM + char buffer[4800]; + + window(1, 1, 80, 25); + gettext(1, 1, 80, 25, buffer); +#endif + + clrscr(); + + // BCR - Set to screen length - 1 to display the "more" string + int moreLength = (get_number_of_lines() - 1) * 2; + + for (int i = 0; i < 500; i++) + { + if (wizard) + line = wizard_string( i ); + else + line = command_string( i ); + + if (strlen( line ) != 0) + { + // BCR - If we've reached the end of the screen, clear + if (j == moreLength) + { + gotoxy(2, j / 2 + 1); + cprintf("More..."); + getch(); + clrscr(); + j = 0; + } + + gotoxy( ((j % 2) ? 40 : 2), ((j / 2) + 1) ); + cprintf( line ); + + j++; + } + } + + getch(); + +#ifdef DOS_TERM + puttext(1, 1, 80, 25, buffer); +#endif + + return; +} // end list_commands() + +const char *wizard_string( int i ) +{ + UNUSED( i ); + +#ifdef WIZARD + return((i == 10) ? "a : acquirement" : + (i == 13) ? "A : set all skills to level" : + (i == 15) ? "b : controlled blink" : + (i == 20) ? "B : banish yourself to the Abyss" : + (i == 30) ? "g : add a skill" : + (i == 35) ? "G : remove all monsters" : + (i == 40) ? "h/H : heal yourself (super-Heal)" : + (i == 50) ? "i/I : identify/unidentify inventory": + (i == 70) ? "l : make entrance to labyrinth" : + (i == 80) ? "m/M : create monster by number/name": + (i == 90) ? "o/%% : create an object" : + (i == 100) ? "p : make entrance to pandemonium" : + (i == 110) ? "x : gain an experience level" : + (i == 115) ? "r : change character's species" : + (i == 120) ? "s : gain 20000 skill points" : + (i == 130) ? "S : set skill to level" : + (i == 140) ? "t : tweak object properties" : + (i == 150) ? "X : Receive a gift from Xom" : + (i == 160) ? "z/Z : cast any spell by number/name": + (i == 200) ? "$ : get 1000 gold" : + (i == 210) ? " : create up/down staircase" : + (i == 220) ? "u/d : shift up/down one level" : + (i == 230) ? "~/\" : goto a level" : + (i == 240) ? "( : create a feature" : + (i == 250) ? "] : get a mutation" : + (i == 260) ? "[ : get a demonspawn mutation" : + (i == 270) ? ": : find branch" : + (i == 280) ? "{ : magic mapping" : + (i == 290) ? "^ : gain piety" : + (i == 300) ? "_ : gain religion" : + (i == 310) ? "\' : list items" : + (i == 320) ? "? : list wizard commands" : + (i == 330) ? "| : acquire all unrand artefacts" : + (i == 340) ? "+ : turn item into random artefact" : + (i == 350) ? "= : sum skill points" + : ""); + +#else + return (""); +#endif +} // end wizard_string() + +const char *command_string( int i ) +{ + /* + * BCR - Command printing, case statement + * Note: The numbers in this case indicate the order in which the + * commands will be printed out. Make sure none of these + * numbers is greater than 500, because that is the limit. + * + * Arranged alpha lower, alpha upper, punctuation, ctrl. + * + */ + + return((i == 10) ? "a : use special ability" : + (i == 20) ? "d(#) : drop (exact quantity of) items" : + (i == 30) ? "e : eat food" : + (i == 40) ? "f : fire first available missile" : + (i == 50) ? "i : inventory listing" : + (i == 55) ? "m : check skills" : + (i == 60) ? "o/c : open / close a door" : + (i == 65) ? "p : pray" : + (i == 70) ? "q : quaff a potion" : + (i == 80) ? "r : read a scroll or book" : + (i == 90) ? "s : search adjacent tiles" : + (i == 100) ? "t : throw/shoot an item" : + (i == 110) ? "v : view item description" : + (i == 120) ? "w : wield an item" : + (i == 130) ? "x : examine visible surroundings" : + (i == 135) ? "z : zap a wand" : + (i == 140) ? "A : list abilities/mutations" : + (i == 141) ? "C : check experience" : + (i == 142) ? "D : dissect a corpse" : + (i == 145) ? "E : evoke power of wielded item" : + (i == 150) ? "M : memorise a spell" : + (i == 155) ? "O : overview of the dungeon" : + (i == 160) ? "P/R : put on / remove jewellery" : + (i == 165) ? "Q : quit without saving" : + (i == 168) ? "S : save game and exit" : + (i == 179) ? "V : version information" : + (i == 200) ? "W/T : wear / take off armour" : + (i == 210) ? "X : examine level map" : + (i == 220) ? "Z : cast a spell" : + (i == 240) ? ",/g : pick up items" : + (i == 242) ? "./del: rest one turn" : + (i == 250) ? " : ascend / descend a staircase" : + (i == 270) ? "; : examine occupied tile" : + (i == 280) ? "\\ : check item knowledge" : +#ifdef WIZARD + (i == 290) ? "& : invoke your Wizardly powers" : +#endif + (i == 300) ? "+/- : scroll up/down [level map only]" : + (i == 310) ? "! : shout or command allies" : + (i == 325) ? "^ : describe religion" : + (i == 337) ? "@ : status" : + (i == 340) ? "# : dump character to file" : + (i == 350) ? "= : reassign inventory/spell letters" : + (i == 360) ? "\' : wield item a, or switch to b" : +#ifdef USE_MACROS + (i == 380) ? "` : add macro" : + (i == 390) ? "~ : save macros" : +#endif + (i == 400) ? "] : display worn armour" : + (i == 410) ? "\" : display worn jewellery" : + (i == 420) ? "Ctrl-P : see old messages" : +#ifdef PLAIN_TERM + (i == 430) ? "Ctrl-R : Redraw screen" : +#endif + (i == 440) ? "Ctrl-A : toggle autopickup" : + (i == 450) ? "Ctrl-X : Save game without query" : + +#ifdef ALLOW_DESTROY_ITEM_COMMAND + (i == 455) ? "Ctrl-D : Destroy inventory item" : +#endif + + (i == 460) ? "Shift & DIR : long walk" : + (i == 465) ? "/ DIR : long walk" : + (i == 470) ? "Ctrl & DIR : door; untrap; attack" : + (i == 475) ? "* DIR : door; untrap; attack" : + (i == 478) ? "Shift & 5 on keypad : rest 100 turns" + : ""); +} // end command_string() -- cgit v1.2.3-54-g00ecf