1 1.15 dholland /* $NetBSD: inventory.c,v 1.15 2011/08/26 06:18:17 dholland Exp $ */ 2 1.3 cgd 3 1.1 cgd /* 4 1.3 cgd * Copyright (c) 1988, 1993 5 1.3 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * This code is derived from software contributed to Berkeley by 8 1.1 cgd * Timothy C. Stoehr. 9 1.1 cgd * 10 1.1 cgd * Redistribution and use in source and binary forms, with or without 11 1.1 cgd * modification, are permitted provided that the following conditions 12 1.1 cgd * are met: 13 1.1 cgd * 1. Redistributions of source code must retain the above copyright 14 1.1 cgd * notice, this list of conditions and the following disclaimer. 15 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 cgd * notice, this list of conditions and the following disclaimer in the 17 1.1 cgd * documentation and/or other materials provided with the distribution. 18 1.9 agc * 3. Neither the name of the University nor the names of its contributors 19 1.1 cgd * may be used to endorse or promote products derived from this software 20 1.1 cgd * without specific prior written permission. 21 1.1 cgd * 22 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 cgd * SUCH DAMAGE. 33 1.1 cgd */ 34 1.1 cgd 35 1.5 lukem #include <sys/cdefs.h> 36 1.1 cgd #ifndef lint 37 1.3 cgd #if 0 38 1.3 cgd static char sccsid[] = "@(#)inventory.c 8.1 (Berkeley) 5/31/93"; 39 1.3 cgd #else 40 1.15 dholland __RCSID("$NetBSD: inventory.c,v 1.15 2011/08/26 06:18:17 dholland Exp $"); 41 1.3 cgd #endif 42 1.1 cgd #endif /* not lint */ 43 1.1 cgd 44 1.1 cgd /* 45 1.1 cgd * inventory.c 46 1.1 cgd * 47 1.1 cgd * This source herein may be modified and/or distributed by anybody who 48 1.1 cgd * so desires, with the following restrictions: 49 1.1 cgd * 1.) No portion of this notice shall be removed. 50 1.1 cgd * 2.) Credit shall not be taken for the creation of this source. 51 1.1 cgd * 3.) This code is not to be traded, sold, or used for personal 52 1.1 cgd * gain or profit. 53 1.1 cgd * 54 1.1 cgd */ 55 1.1 cgd 56 1.11 dholland #include <stdarg.h> 57 1.1 cgd #include "rogue.h" 58 1.1 cgd 59 1.1 cgd boolean is_wood[WANDS]; 60 1.6 hubertf const char *press_space = " --press space to continue--"; 61 1.1 cgd 62 1.13 dholland static const char *const wand_materials[WAND_MATERIALS] = { 63 1.1 cgd "steel ", 64 1.1 cgd "bronze ", 65 1.1 cgd "gold ", 66 1.1 cgd "silver ", 67 1.1 cgd "copper ", 68 1.1 cgd "nickel ", 69 1.1 cgd "cobalt ", 70 1.1 cgd "tin ", 71 1.1 cgd "iron ", 72 1.1 cgd "magnesium ", 73 1.1 cgd "chrome ", 74 1.1 cgd "carbon ", 75 1.1 cgd "platinum ", 76 1.1 cgd "silicon ", 77 1.1 cgd "titanium ", 78 1.1 cgd 79 1.1 cgd "teak ", 80 1.1 cgd "oak ", 81 1.1 cgd "cherry ", 82 1.1 cgd "birch ", 83 1.1 cgd "pine ", 84 1.1 cgd "cedar ", 85 1.1 cgd "redwood ", 86 1.1 cgd "balsa ", 87 1.1 cgd "ivory ", 88 1.1 cgd "walnut ", 89 1.1 cgd "maple ", 90 1.1 cgd "mahogany ", 91 1.1 cgd "elm ", 92 1.1 cgd "palm ", 93 1.1 cgd "wooden " 94 1.1 cgd }; 95 1.1 cgd 96 1.13 dholland static const char *const gems[GEMS] = { 97 1.1 cgd "diamond ", 98 1.1 cgd "stibotantalite ", 99 1.1 cgd "lapi-lazuli ", 100 1.1 cgd "ruby ", 101 1.1 cgd "emerald ", 102 1.1 cgd "sapphire ", 103 1.1 cgd "amethyst ", 104 1.1 cgd "quartz ", 105 1.1 cgd "tiger-eye ", 106 1.1 cgd "opal ", 107 1.1 cgd "agate ", 108 1.1 cgd "turquoise ", 109 1.1 cgd "pearl ", 110 1.1 cgd "garnet " 111 1.1 cgd }; 112 1.1 cgd 113 1.13 dholland static const char *const syllables[MAXSYLLABLES] = { 114 1.1 cgd "blech ", 115 1.1 cgd "foo ", 116 1.1 cgd "barf ", 117 1.1 cgd "rech ", 118 1.1 cgd "bar ", 119 1.1 cgd "blech ", 120 1.1 cgd "quo ", 121 1.1 cgd "bloto ", 122 1.1 cgd "oh ", 123 1.1 cgd "caca ", 124 1.1 cgd "blorp ", 125 1.1 cgd "erp ", 126 1.1 cgd "festr ", 127 1.1 cgd "rot ", 128 1.1 cgd "slie ", 129 1.1 cgd "snorf ", 130 1.1 cgd "iky ", 131 1.1 cgd "yuky ", 132 1.1 cgd "ooze ", 133 1.1 cgd "ah ", 134 1.1 cgd "bahl ", 135 1.1 cgd "zep ", 136 1.1 cgd "druhl ", 137 1.1 cgd "flem ", 138 1.1 cgd "behil ", 139 1.1 cgd "arek ", 140 1.1 cgd "mep ", 141 1.1 cgd "zihr ", 142 1.1 cgd "grit ", 143 1.1 cgd "kona ", 144 1.1 cgd "kini ", 145 1.1 cgd "ichi ", 146 1.1 cgd "tims ", 147 1.1 cgd "ogr ", 148 1.1 cgd "oo ", 149 1.1 cgd "ighr ", 150 1.1 cgd "coph ", 151 1.1 cgd "swerr ", 152 1.1 cgd "mihln ", 153 1.1 cgd "poxi " 154 1.1 cgd }; 155 1.1 cgd 156 1.1 cgd #define COMS 48 157 1.1 cgd 158 1.1 cgd struct id_com_s { 159 1.1 cgd short com_char; 160 1.6 hubertf const char *com_desc; 161 1.1 cgd }; 162 1.1 cgd 163 1.13 dholland static const struct id_com_s com_id_tab[COMS] = { 164 1.5 lukem {'?', "? prints help"}, 165 1.5 lukem {'r', "r read scroll"}, 166 1.5 lukem {'/', "/ identify object"}, 167 1.5 lukem {'e', "e eat food"}, 168 1.5 lukem {'h', "h left "}, 169 1.5 lukem {'w', "w wield a weapon"}, 170 1.5 lukem {'j', "j down"}, 171 1.5 lukem {'W', "W wear armor"}, 172 1.5 lukem {'k', "k up"}, 173 1.5 lukem {'T', "T take armor off"}, 174 1.5 lukem {'l', "l right"}, 175 1.5 lukem {'P', "P put on ring"}, 176 1.5 lukem {'y', "y up & left"}, 177 1.5 lukem {'R', "R remove ring"}, 178 1.5 lukem {'u', "u up & right"}, 179 1.5 lukem {'d', "d drop object"}, 180 1.5 lukem {'b', "b down & left"}, 181 1.5 lukem {'c', "c call object"}, 182 1.5 lukem {'n', "n down & right"}, 183 1.5 lukem {'\0', "<SHIFT><dir>: run that way"}, 184 1.5 lukem {')', ") print current weapon"}, 185 1.5 lukem {'\0', "<CTRL><dir>: run till adjacent"}, 186 1.5 lukem {']', "] print current armor"}, 187 1.5 lukem {'f', "f<dir> fight till death or near death"}, 188 1.5 lukem {'=', "= print current rings"}, 189 1.5 lukem {'t', "t<dir> throw something"}, 190 1.5 lukem {'\001', "^A print Hp-raise average"}, 191 1.5 lukem {'m', "m<dir> move onto without picking up"}, 192 1.5 lukem {'z', "z<dir> zap a wand in a direction"}, 193 1.5 lukem {'o', "o examine/set options"}, 194 1.5 lukem {'^', "^<dir> identify trap type"}, 195 1.5 lukem {'\022', "^R redraw screen"}, 196 1.5 lukem {'&', "& save screen into 'rogue.screen'"}, 197 1.5 lukem {'s', "s search for trap/secret door"}, 198 1.5 lukem {'\020', "^P repeat last message"}, 199 1.5 lukem {'>', "> go down a staircase"}, 200 1.5 lukem {'\033', "^[ cancel command"}, 201 1.5 lukem {'<', "< go up a staircase"}, 202 1.5 lukem {'S', "S save game"}, 203 1.5 lukem {'.', ". rest for a turn"}, 204 1.5 lukem {'Q', "Q quit"}, 205 1.5 lukem {',', ", pick something up"}, 206 1.5 lukem {'!', "! shell escape"}, 207 1.5 lukem {'i', "i inventory"}, 208 1.5 lukem {'F', "F<dir> fight till either of you dies"}, 209 1.5 lukem {'I', "I inventory single item"}, 210 1.5 lukem {'v', "v print version number"}, 211 1.5 lukem {'q', "q quaff potion" } 212 1.1 cgd }; 213 1.1 cgd 214 1.14 dholland static int get_com_id(int *, short); 215 1.14 dholland static int pr_com_id(int); 216 1.14 dholland static int pr_motion_char(int); 217 1.14 dholland 218 1.5 lukem void 219 1.13 dholland inventory(const object *pack, unsigned short mask) 220 1.1 cgd { 221 1.1 cgd object *obj; 222 1.11 dholland short i = 0, j; 223 1.11 dholland size_t maxlen = 0, n; 224 1.1 cgd short row, col; 225 1.1 cgd 226 1.11 dholland struct { 227 1.11 dholland short letter; 228 1.11 dholland short sepchar; 229 1.11 dholland char desc[DCOLS]; 230 1.12 dholland char savebuf[DCOLS+8]; 231 1.11 dholland } descs[MAX_PACK_COUNT+1]; 232 1.11 dholland 233 1.11 dholland 234 1.1 cgd obj = pack->next_object; 235 1.1 cgd 236 1.1 cgd if (!obj) { 237 1.11 dholland messagef(0, "your pack is empty"); 238 1.1 cgd return; 239 1.1 cgd } 240 1.1 cgd while (obj) { 241 1.1 cgd if (obj->what_is & mask) { 242 1.11 dholland descs[i].letter = obj->ichar; 243 1.11 dholland descs[i].sepchar = ((obj->what_is & ARMOR) && obj->is_protected) 244 1.1 cgd ? '}' : ')'; 245 1.11 dholland get_desc(obj, descs[i].desc, sizeof(descs[i].desc)); 246 1.11 dholland n = strlen(descs[i].desc) + 4; 247 1.11 dholland if (n > maxlen) { 248 1.1 cgd maxlen = n; 249 1.1 cgd } 250 1.11 dholland i++; 251 1.11 dholland /*assert(i<=MAX_PACK_COUNT);*/ 252 1.1 cgd } 253 1.1 cgd obj = obj->next_object; 254 1.1 cgd } 255 1.1 cgd if (maxlen < 27) maxlen = 27; 256 1.11 dholland if (maxlen > DCOLS-2) maxlen = DCOLS-2; 257 1.1 cgd col = DCOLS - (maxlen + 2); 258 1.1 cgd 259 1.11 dholland for (row = 0; ((row <= i) && (row < DROWS)); row++) { 260 1.11 dholland for (j = col; j < DCOLS; j++) { 261 1.11 dholland descs[row].savebuf[j-col] = mvinch(row, j); 262 1.11 dholland } 263 1.11 dholland descs[row].savebuf[j-col] = 0; 264 1.11 dholland if (row < i) { 265 1.12 dholland mvprintw(row, col, " %c%c %s", 266 1.12 dholland descs[row].letter, descs[row].sepchar, 267 1.11 dholland descs[row].desc); 268 1.11 dholland } 269 1.11 dholland else { 270 1.11 dholland mvaddstr(row, col, press_space); 271 1.1 cgd } 272 1.1 cgd clrtoeol(); 273 1.1 cgd } 274 1.1 cgd refresh(); 275 1.1 cgd wait_for_ack(); 276 1.1 cgd 277 1.1 cgd move(0, 0); 278 1.1 cgd clrtoeol(); 279 1.1 cgd 280 1.11 dholland for (j = 1; ((j <= i) && (j < DROWS)); j++) { 281 1.11 dholland mvaddstr(j, col, descs[j].savebuf); 282 1.1 cgd } 283 1.1 cgd } 284 1.1 cgd 285 1.5 lukem void 286 1.13 dholland id_com(void) 287 1.1 cgd { 288 1.1 cgd int ch = 0; 289 1.1 cgd short i, j, k; 290 1.1 cgd 291 1.1 cgd while (ch != CANCEL) { 292 1.1 cgd check_message(); 293 1.11 dholland messagef(0, "Character you want help for (* for all):"); 294 1.1 cgd 295 1.1 cgd refresh(); 296 1.1 cgd ch = getchar(); 297 1.1 cgd 298 1.1 cgd switch(ch) { 299 1.1 cgd case LIST: 300 1.1 cgd { 301 1.1 cgd char save[(((COMS / 2) + (COMS % 2)) + 1)][DCOLS]; 302 1.1 cgd short rows = (((COMS / 2) + (COMS % 2)) + 1); 303 1.5 lukem boolean need_two_screens = FALSE; 304 1.1 cgd 305 1.1 cgd if (rows > LINES) { 306 1.1 cgd need_two_screens = 1; 307 1.1 cgd rows = LINES; 308 1.1 cgd } 309 1.1 cgd k = 0; 310 1.1 cgd 311 1.1 cgd for (i = 0; i < rows; i++) { 312 1.1 cgd for (j = 0; j < DCOLS; j++) { 313 1.1 cgd save[i][j] = mvinch(i, j); 314 1.1 cgd } 315 1.1 cgd } 316 1.1 cgd MORE: 317 1.1 cgd for (i = 0; i < rows; i++) { 318 1.1 cgd move(i, 0); 319 1.1 cgd clrtoeol(); 320 1.1 cgd } 321 1.1 cgd for (i = 0; i < (rows-1); i++) { 322 1.1 cgd if (i < (LINES-1)) { 323 1.1 cgd if (((i + i) < COMS) && ((i+i+k) < COMS)) { 324 1.1 cgd mvaddstr(i, 0, com_id_tab[i+i+k].com_desc); 325 1.1 cgd } 326 1.1 cgd if (((i + i + 1) < COMS) && ((i+i+k+1) < COMS)) { 327 1.1 cgd mvaddstr(i, (DCOLS/2), 328 1.1 cgd com_id_tab[i+i+k+1].com_desc); 329 1.1 cgd } 330 1.1 cgd } 331 1.1 cgd } 332 1.1 cgd mvaddstr(rows - 1, 0, need_two_screens ? more : press_space); 333 1.1 cgd refresh(); 334 1.1 cgd wait_for_ack(); 335 1.1 cgd 336 1.1 cgd if (need_two_screens) { 337 1.1 cgd k += ((rows-1) * 2); 338 1.1 cgd need_two_screens = 0; 339 1.1 cgd goto MORE; 340 1.1 cgd } 341 1.1 cgd for (i = 0; i < rows; i++) { 342 1.1 cgd move(i, 0); 343 1.1 cgd for (j = 0; j < DCOLS; j++) { 344 1.1 cgd addch(save[i][j]); 345 1.1 cgd } 346 1.1 cgd } 347 1.1 cgd } 348 1.1 cgd break; 349 1.1 cgd default: 350 1.1 cgd if (!pr_com_id(ch)) { 351 1.1 cgd if (!pr_motion_char(ch)) { 352 1.1 cgd check_message(); 353 1.11 dholland messagef(0, "unknown character"); 354 1.1 cgd } 355 1.1 cgd } 356 1.1 cgd ch = CANCEL; 357 1.1 cgd break; 358 1.1 cgd } 359 1.1 cgd } 360 1.1 cgd } 361 1.1 cgd 362 1.14 dholland static int 363 1.13 dholland pr_com_id(int ch) 364 1.1 cgd { 365 1.1 cgd int i; 366 1.1 cgd 367 1.1 cgd if (!get_com_id(&i, ch)) { 368 1.1 cgd return(0); 369 1.1 cgd } 370 1.1 cgd check_message(); 371 1.11 dholland messagef(0, "%s", com_id_tab[i].com_desc); 372 1.1 cgd return(1); 373 1.1 cgd } 374 1.1 cgd 375 1.14 dholland static int 376 1.13 dholland get_com_id(int *indexp, short ch) 377 1.1 cgd { 378 1.1 cgd short i; 379 1.1 cgd 380 1.1 cgd for (i = 0; i < COMS; i++) { 381 1.1 cgd if (com_id_tab[i].com_char == ch) { 382 1.7 tron *indexp = i; 383 1.1 cgd return(1); 384 1.1 cgd } 385 1.1 cgd } 386 1.1 cgd return(0); 387 1.1 cgd } 388 1.1 cgd 389 1.14 dholland static int 390 1.13 dholland pr_motion_char(int ch) 391 1.1 cgd { 392 1.1 cgd if ( (ch == 'J') || 393 1.1 cgd (ch == 'K') || 394 1.1 cgd (ch == 'L') || 395 1.1 cgd (ch == 'H') || 396 1.1 cgd (ch == 'Y') || 397 1.1 cgd (ch == 'U') || 398 1.1 cgd (ch == 'N') || 399 1.1 cgd (ch == 'B') || 400 1.1 cgd (ch == '\012') || 401 1.1 cgd (ch == '\013') || 402 1.1 cgd (ch == '\010') || 403 1.1 cgd (ch == '\014') || 404 1.1 cgd (ch == '\025') || 405 1.1 cgd (ch == '\031') || 406 1.1 cgd (ch == '\016') || 407 1.1 cgd (ch == '\002')) { 408 1.11 dholland const char *until; 409 1.10 christos int n = 0; /* XXX: GCC */ 410 1.1 cgd if (ch <= '\031') { 411 1.1 cgd ch += 96; 412 1.11 dholland until = " until adjacent"; 413 1.1 cgd } else { 414 1.1 cgd ch += 32; 415 1.11 dholland until = ""; 416 1.1 cgd } 417 1.12 dholland (void)get_com_id(&n, ch); 418 1.1 cgd check_message(); 419 1.11 dholland messagef(0, "run %s%s", com_id_tab[n].com_desc + 8, until); 420 1.1 cgd return(1); 421 1.1 cgd } else { 422 1.1 cgd return(0); 423 1.1 cgd } 424 1.1 cgd } 425 1.1 cgd 426 1.5 lukem void 427 1.13 dholland mix_colors(void) 428 1.1 cgd { 429 1.1 cgd short i, j, k; 430 1.8 mrg char t[MAX_ID_TITLE_LEN]; 431 1.1 cgd 432 1.1 cgd for (i = 0; i <= 32; i++) { 433 1.1 cgd j = get_rand(0, (POTIONS - 1)); 434 1.1 cgd k = get_rand(0, (POTIONS - 1)); 435 1.11 dholland strlcpy(t, id_potions[j].title, sizeof(t)); 436 1.11 dholland strlcpy(id_potions[j].title, id_potions[k].title, 437 1.11 dholland sizeof(id_potions[j].title)); 438 1.11 dholland strlcpy(id_potions[k].title, t, sizeof(id_potions[k].title)); 439 1.1 cgd } 440 1.1 cgd } 441 1.1 cgd 442 1.5 lukem void 443 1.13 dholland make_scroll_titles(void) 444 1.1 cgd { 445 1.1 cgd short i, j, n; 446 1.1 cgd short sylls, s; 447 1.11 dholland size_t maxlen = sizeof(id_scrolls[0].title); 448 1.1 cgd 449 1.1 cgd for (i = 0; i < SCROLS; i++) { 450 1.1 cgd sylls = get_rand(2, 5); 451 1.12 dholland (void)strlcpy(id_scrolls[i].title, "'", maxlen); 452 1.1 cgd 453 1.1 cgd for (j = 0; j < sylls; j++) { 454 1.1 cgd s = get_rand(1, (MAXSYLLABLES-1)); 455 1.12 dholland (void)strlcat(id_scrolls[i].title, syllables[s], 456 1.11 dholland maxlen); 457 1.1 cgd } 458 1.11 dholland /* trim trailing space */ 459 1.1 cgd n = strlen(id_scrolls[i].title); 460 1.11 dholland id_scrolls[i].title[n-1] = 0; 461 1.11 dholland 462 1.12 dholland (void)strlcat(id_scrolls[i].title, "' ", maxlen); 463 1.11 dholland } 464 1.11 dholland } 465 1.11 dholland 466 1.11 dholland struct sbuf { 467 1.11 dholland char *buf; 468 1.11 dholland size_t maxlen; 469 1.11 dholland }; 470 1.11 dholland 471 1.13 dholland static void sbuf_init(struct sbuf *s, char *buf, size_t maxlen); 472 1.13 dholland static void sbuf_addstr(struct sbuf *s, const char *str); 473 1.15 dholland static void sbuf_addf(struct sbuf *s, const char *fmt, ...) __printflike(2,3); 474 1.13 dholland static void desc_count(struct sbuf *s, int n); 475 1.13 dholland static void desc_called(struct sbuf *s, const object *); 476 1.11 dholland 477 1.11 dholland static 478 1.11 dholland void 479 1.13 dholland sbuf_init(struct sbuf *s, char *buf, size_t maxlen) 480 1.11 dholland { 481 1.11 dholland s->buf = buf; 482 1.11 dholland s->maxlen = maxlen; 483 1.11 dholland /*assert(maxlen>0);*/ 484 1.11 dholland s->buf[0] = 0; 485 1.11 dholland } 486 1.11 dholland 487 1.11 dholland static 488 1.11 dholland void 489 1.13 dholland sbuf_addstr(struct sbuf *s, const char *str) 490 1.11 dholland { 491 1.11 dholland strlcat(s->buf, str, s->maxlen); 492 1.11 dholland } 493 1.11 dholland 494 1.11 dholland static 495 1.11 dholland void 496 1.11 dholland sbuf_addf(struct sbuf *s, const char *fmt, ...) 497 1.11 dholland { 498 1.11 dholland va_list ap; 499 1.11 dholland size_t initlen; 500 1.11 dholland 501 1.11 dholland initlen = strlen(s->buf); 502 1.11 dholland va_start(ap, fmt); 503 1.11 dholland vsnprintf(s->buf+initlen, s->maxlen-initlen, fmt, ap); 504 1.11 dholland va_end(ap); 505 1.11 dholland } 506 1.11 dholland 507 1.11 dholland static 508 1.11 dholland void 509 1.13 dholland desc_count(struct sbuf *s, int n) 510 1.11 dholland { 511 1.11 dholland if (n == 1) { 512 1.11 dholland sbuf_addstr(s, "an "); 513 1.11 dholland } else { 514 1.11 dholland sbuf_addf(s, "%d ", n); 515 1.1 cgd } 516 1.1 cgd } 517 1.1 cgd 518 1.11 dholland static 519 1.5 lukem void 520 1.13 dholland desc_called(struct sbuf *s, const object *obj) 521 1.11 dholland { 522 1.11 dholland struct id *id_table; 523 1.11 dholland 524 1.11 dholland id_table = get_id_table(obj); 525 1.11 dholland sbuf_addstr(s, name_of(obj)); 526 1.11 dholland sbuf_addstr(s, "called "); 527 1.11 dholland sbuf_addstr(s, id_table[obj->which_kind].title); 528 1.11 dholland } 529 1.11 dholland 530 1.11 dholland void 531 1.13 dholland get_desc(const object *obj, char *desc, size_t desclen) 532 1.1 cgd { 533 1.6 hubertf const char *item_name; 534 1.1 cgd struct id *id_table; 535 1.11 dholland struct sbuf db; 536 1.11 dholland unsigned short objtype_id_status; 537 1.1 cgd 538 1.1 cgd if (obj->what_is == AMULET) { 539 1.12 dholland (void)strlcpy(desc, "the amulet of Yendor ", desclen); 540 1.1 cgd return; 541 1.1 cgd } 542 1.1 cgd 543 1.1 cgd if (obj->what_is == GOLD) { 544 1.11 dholland snprintf(desc, desclen, "%d pieces of gold", obj->quantity); 545 1.1 cgd return; 546 1.1 cgd } 547 1.1 cgd 548 1.11 dholland item_name = name_of(obj); 549 1.11 dholland id_table = get_id_table(obj); 550 1.11 dholland if (wizard || id_table == NULL) { 551 1.11 dholland objtype_id_status = IDENTIFIED; 552 1.11 dholland } 553 1.11 dholland else { 554 1.11 dholland objtype_id_status = id_table[obj->which_kind].id_status; 555 1.11 dholland } 556 1.11 dholland if (obj->what_is & (WEAPON | ARMOR | WAND | RING)) { 557 1.11 dholland if (obj->identified) { 558 1.11 dholland objtype_id_status = IDENTIFIED; 559 1.1 cgd } 560 1.1 cgd } 561 1.11 dholland 562 1.11 dholland sbuf_init(&db, desc, desclen); 563 1.11 dholland 564 1.11 dholland switch (obj->what_is) { 565 1.11 dholland case FOOD: 566 1.1 cgd if (obj->which_kind == RATION) { 567 1.1 cgd if (obj->quantity > 1) { 568 1.11 dholland sbuf_addf(&db, 569 1.11 dholland "%d rations of %s", obj->quantity, 570 1.11 dholland item_name); 571 1.1 cgd } else { 572 1.11 dholland sbuf_addf(&db, "some %s", item_name); 573 1.1 cgd } 574 1.1 cgd } else { 575 1.11 dholland sbuf_addf(&db, "an %s", item_name); 576 1.1 cgd } 577 1.11 dholland break; 578 1.11 dholland case SCROL: 579 1.11 dholland desc_count(&db, obj->quantity); 580 1.11 dholland if (objtype_id_status==UNIDENTIFIED) { 581 1.11 dholland sbuf_addstr(&db, item_name); 582 1.11 dholland sbuf_addstr(&db, "entitled: "); 583 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].title); 584 1.11 dholland } else if (objtype_id_status==CALLED) { 585 1.11 dholland desc_called(&db, obj); 586 1.11 dholland } else { 587 1.11 dholland sbuf_addstr(&db, item_name); 588 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].real); 589 1.1 cgd } 590 1.1 cgd break; 591 1.11 dholland case POTION: 592 1.11 dholland desc_count(&db, obj->quantity); 593 1.11 dholland if (objtype_id_status==UNIDENTIFIED) { 594 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].title); 595 1.11 dholland sbuf_addstr(&db, item_name); 596 1.11 dholland } else if (objtype_id_status==CALLED) { 597 1.11 dholland desc_called(&db, obj); 598 1.11 dholland } else { 599 1.11 dholland sbuf_addstr(&db, item_name); 600 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].real); 601 1.1 cgd } 602 1.1 cgd break; 603 1.11 dholland case WAND: 604 1.11 dholland desc_count(&db, obj->quantity); 605 1.11 dholland if (objtype_id_status==UNIDENTIFIED) { 606 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].title); 607 1.11 dholland sbuf_addstr(&db, item_name); 608 1.11 dholland } else if (objtype_id_status==CALLED) { 609 1.11 dholland desc_called(&db, obj); 610 1.11 dholland } else { 611 1.11 dholland sbuf_addstr(&db, item_name); 612 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].real); 613 1.1 cgd if (wizard || obj->identified) { 614 1.11 dholland sbuf_addf(&db, "[%d]", obj->class); 615 1.1 cgd } 616 1.11 dholland } 617 1.11 dholland break; 618 1.11 dholland case RING: 619 1.11 dholland desc_count(&db, obj->quantity); 620 1.11 dholland if (objtype_id_status==UNIDENTIFIED) { 621 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].title); 622 1.11 dholland sbuf_addstr(&db, item_name); 623 1.11 dholland } else if (objtype_id_status==CALLED) { 624 1.11 dholland desc_called(&db, obj); 625 1.11 dholland } else { 626 1.11 dholland if ((wizard || obj->identified) && 627 1.11 dholland (obj->which_kind == DEXTERITY || 628 1.11 dholland obj->which_kind == ADD_STRENGTH)) { 629 1.11 dholland sbuf_addf(&db, "%+d ", obj->class); 630 1.1 cgd } 631 1.11 dholland sbuf_addstr(&db, item_name); 632 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].real); 633 1.1 cgd } 634 1.1 cgd break; 635 1.11 dholland case ARMOR: 636 1.11 dholland /* no desc_count() */ 637 1.11 dholland if (objtype_id_status==UNIDENTIFIED) { 638 1.11 dholland sbuf_addstr(&db, id_table[obj->which_kind].title); 639 1.11 dholland } else { 640 1.11 dholland sbuf_addf(&db, "%+d %s[%d] ", obj->d_enchant, 641 1.11 dholland id_table[obj->which_kind].title, 642 1.11 dholland get_armor_class(obj)); 643 1.11 dholland } 644 1.11 dholland break; 645 1.11 dholland case WEAPON: 646 1.11 dholland desc_count(&db, obj->quantity); 647 1.11 dholland if (objtype_id_status==UNIDENTIFIED) { 648 1.11 dholland sbuf_addstr(&db, name_of(obj)); 649 1.11 dholland } else { 650 1.11 dholland sbuf_addf(&db, "%+d,%+d %s", 651 1.11 dholland obj->hit_enchant, obj->d_enchant, 652 1.11 dholland name_of(obj)); 653 1.1 cgd } 654 1.11 dholland break; 655 1.1 cgd } 656 1.11 dholland 657 1.1 cgd if (obj->in_use_flags & BEING_WIELDED) { 658 1.11 dholland sbuf_addstr(&db, "in hand"); 659 1.1 cgd } else if (obj->in_use_flags & BEING_WORN) { 660 1.11 dholland sbuf_addstr(&db, "being worn"); 661 1.1 cgd } else if (obj->in_use_flags & ON_LEFT_HAND) { 662 1.11 dholland sbuf_addstr(&db, "on left hand"); 663 1.1 cgd } else if (obj->in_use_flags & ON_RIGHT_HAND) { 664 1.11 dholland sbuf_addstr(&db, "on right hand"); 665 1.11 dholland } 666 1.11 dholland 667 1.11 dholland if (!strncmp(db.buf, "an ", 3)) { 668 1.11 dholland if (!is_vowel(db.buf[3])) { 669 1.11 dholland memmove(db.buf+2, db.buf+3, strlen(db.buf+3)+1); 670 1.11 dholland db.buf[1] = ' '; 671 1.11 dholland } 672 1.1 cgd } 673 1.1 cgd } 674 1.1 cgd 675 1.5 lukem void 676 1.13 dholland get_wand_and_ring_materials(void) 677 1.1 cgd { 678 1.1 cgd short i, j; 679 1.1 cgd boolean used[WAND_MATERIALS]; 680 1.1 cgd 681 1.1 cgd for (i = 0; i < WAND_MATERIALS; i++) { 682 1.1 cgd used[i] = 0; 683 1.1 cgd } 684 1.1 cgd for (i = 0; i < WANDS; i++) { 685 1.1 cgd do { 686 1.1 cgd j = get_rand(0, WAND_MATERIALS-1); 687 1.1 cgd } while (used[j]); 688 1.1 cgd used[j] = 1; 689 1.12 dholland (void)strlcpy(id_wands[i].title, wand_materials[j], 690 1.11 dholland sizeof(id_wands[i].title)); 691 1.1 cgd is_wood[i] = (j > MAX_METAL); 692 1.1 cgd } 693 1.1 cgd for (i = 0; i < GEMS; i++) { 694 1.1 cgd used[i] = 0; 695 1.1 cgd } 696 1.1 cgd for (i = 0; i < RINGS; i++) { 697 1.1 cgd do { 698 1.1 cgd j = get_rand(0, GEMS-1); 699 1.1 cgd } while (used[j]); 700 1.1 cgd used[j] = 1; 701 1.12 dholland (void)strlcpy(id_rings[i].title, gems[j], 702 1.11 dholland sizeof(id_rings[i].title)); 703 1.1 cgd } 704 1.1 cgd } 705 1.1 cgd 706 1.5 lukem void 707 1.13 dholland single_inv(short ichar) 708 1.1 cgd { 709 1.11 dholland short ch, ch2; 710 1.1 cgd char desc[DCOLS]; 711 1.1 cgd object *obj; 712 1.1 cgd 713 1.1 cgd ch = ichar ? ichar : pack_letter("inventory what?", ALL_OBJECTS); 714 1.1 cgd 715 1.1 cgd if (ch == CANCEL) { 716 1.1 cgd return; 717 1.1 cgd } 718 1.1 cgd if (!(obj = get_letter_object(ch))) { 719 1.11 dholland messagef(0, "no such item."); 720 1.1 cgd return; 721 1.1 cgd } 722 1.11 dholland ch2 = ((obj->what_is & ARMOR) && obj->is_protected) ? '}' : ')'; 723 1.11 dholland get_desc(obj, desc, sizeof(desc)); 724 1.11 dholland messagef(0, "%c%c %s", ch, ch2, desc); 725 1.1 cgd } 726 1.1 cgd 727 1.1 cgd struct id * 728 1.13 dholland get_id_table(const object *obj) 729 1.1 cgd { 730 1.1 cgd switch(obj->what_is) { 731 1.1 cgd case SCROL: 732 1.1 cgd return(id_scrolls); 733 1.1 cgd case POTION: 734 1.1 cgd return(id_potions); 735 1.1 cgd case WAND: 736 1.1 cgd return(id_wands); 737 1.1 cgd case RING: 738 1.1 cgd return(id_rings); 739 1.1 cgd case WEAPON: 740 1.1 cgd return(id_weapons); 741 1.1 cgd case ARMOR: 742 1.1 cgd return(id_armors); 743 1.1 cgd } 744 1.12 dholland return((struct id *)0); 745 1.1 cgd } 746 1.1 cgd 747 1.5 lukem void 748 1.13 dholland inv_armor_weapon(boolean is_weapon) 749 1.1 cgd { 750 1.1 cgd if (is_weapon) { 751 1.1 cgd if (rogue.weapon) { 752 1.1 cgd single_inv(rogue.weapon->ichar); 753 1.1 cgd } else { 754 1.11 dholland messagef(0, "not wielding anything"); 755 1.1 cgd } 756 1.1 cgd } else { 757 1.1 cgd if (rogue.armor) { 758 1.1 cgd single_inv(rogue.armor->ichar); 759 1.1 cgd } else { 760 1.11 dholland messagef(0, "not wearing anything"); 761 1.1 cgd } 762 1.1 cgd } 763 1.1 cgd } 764 1.1 cgd 765 1.5 lukem void 766 1.13 dholland id_type(void) 767 1.1 cgd { 768 1.6 hubertf const char *id; 769 1.1 cgd int ch; 770 1.1 cgd 771 1.11 dholland messagef(0, "what do you want identified?"); 772 1.1 cgd 773 1.1 cgd ch = rgetchar(); 774 1.1 cgd 775 1.1 cgd if ((ch >= 'A') && (ch <= 'Z')) { 776 1.1 cgd id = m_names[ch-'A']; 777 1.1 cgd } else if (ch < 32) { 778 1.1 cgd check_message(); 779 1.1 cgd return; 780 1.1 cgd } else { 781 1.1 cgd switch(ch) { 782 1.1 cgd case '@': 783 1.1 cgd id = "you"; 784 1.1 cgd break; 785 1.1 cgd case '%': 786 1.1 cgd id = "staircase"; 787 1.1 cgd break; 788 1.1 cgd case '^': 789 1.1 cgd id = "trap"; 790 1.1 cgd break; 791 1.1 cgd case '+': 792 1.1 cgd id = "door"; 793 1.1 cgd break; 794 1.1 cgd case '-': 795 1.1 cgd case '|': 796 1.1 cgd id = "wall of a room"; 797 1.1 cgd break; 798 1.1 cgd case '.': 799 1.1 cgd id = "floor"; 800 1.1 cgd break; 801 1.1 cgd case '#': 802 1.1 cgd id = "passage"; 803 1.1 cgd break; 804 1.1 cgd case ' ': 805 1.1 cgd id = "solid rock"; 806 1.1 cgd break; 807 1.1 cgd case '=': 808 1.1 cgd id = "ring"; 809 1.1 cgd break; 810 1.1 cgd case '?': 811 1.1 cgd id = "scroll"; 812 1.1 cgd break; 813 1.1 cgd case '!': 814 1.1 cgd id = "potion"; 815 1.1 cgd break; 816 1.1 cgd case '/': 817 1.1 cgd id = "wand or staff"; 818 1.1 cgd break; 819 1.1 cgd case ')': 820 1.1 cgd id = "weapon"; 821 1.1 cgd break; 822 1.1 cgd case ']': 823 1.1 cgd id = "armor"; 824 1.1 cgd break; 825 1.1 cgd case '*': 826 1.1 cgd id = "gold"; 827 1.1 cgd break; 828 1.1 cgd case ':': 829 1.1 cgd id = "food"; 830 1.1 cgd break; 831 1.1 cgd case ',': 832 1.1 cgd id = "the Amulet of Yendor"; 833 1.1 cgd break; 834 1.1 cgd default: 835 1.1 cgd id = "unknown character"; 836 1.1 cgd break; 837 1.1 cgd } 838 1.1 cgd } 839 1.1 cgd check_message(); 840 1.11 dholland messagef(0, "'%c': %s", ch, id); 841 1.1 cgd } 842