1 1.16 dholland /* $NetBSD: score.c,v 1.16 2011/08/26 06:18:17 dholland Exp $ */ 2 1.5 cgd 3 1.1 cgd /* 4 1.5 cgd * Copyright (c) 1988, 1993 5 1.5 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.11 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.6 lukem #include <sys/cdefs.h> 36 1.1 cgd #ifndef lint 37 1.5 cgd #if 0 38 1.5 cgd static char sccsid[] = "@(#)score.c 8.1 (Berkeley) 5/31/93"; 39 1.5 cgd #else 40 1.16 dholland __RCSID("$NetBSD: score.c,v 1.16 2011/08/26 06:18:17 dholland Exp $"); 41 1.5 cgd #endif 42 1.1 cgd #endif /* not lint */ 43 1.1 cgd 44 1.1 cgd /* 45 1.1 cgd * score.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.1 cgd #include <stdio.h> 57 1.1 cgd #include "rogue.h" 58 1.1 cgd #include "pathnames.h" 59 1.1 cgd 60 1.15 dholland static void center(short, const char *); 61 1.15 dholland static int get_value(const object *); 62 1.15 dholland static void id_all(void); 63 1.15 dholland static void sell_pack(void); 64 1.16 dholland static void sf_error(void) __dead; 65 1.15 dholland 66 1.6 lukem void 67 1.14 dholland killed_by(const object *monster, short other) 68 1.1 cgd { 69 1.12 dholland const char *mechanism = "killed by something unknown (?)"; 70 1.12 dholland char mechanism_buf[128]; 71 1.12 dholland const char *article; 72 1.12 dholland char message_buf[128]; 73 1.1 cgd 74 1.1 cgd md_ignore_signals(); 75 1.1 cgd 76 1.1 cgd if (other != QUIT) { 77 1.1 cgd rogue.gold = ((rogue.gold * 9) / 10); 78 1.1 cgd } 79 1.1 cgd 80 1.1 cgd if (other) { 81 1.1 cgd switch(other) { 82 1.1 cgd case HYPOTHERMIA: 83 1.12 dholland mechanism = "died of hypothermia"; 84 1.1 cgd break; 85 1.1 cgd case STARVATION: 86 1.12 dholland mechanism = "died of starvation"; 87 1.1 cgd break; 88 1.1 cgd case POISON_DART: 89 1.12 dholland mechanism = "killed by a dart"; 90 1.1 cgd break; 91 1.1 cgd case QUIT: 92 1.12 dholland mechanism = "quit"; 93 1.1 cgd break; 94 1.1 cgd case KFIRE: 95 1.12 dholland mechanism = "killed by fire"; 96 1.1 cgd break; 97 1.1 cgd } 98 1.1 cgd } else { 99 1.1 cgd if (is_vowel(m_names[monster->m_char - 'A'][0])) { 100 1.12 dholland article = "an"; 101 1.1 cgd } else { 102 1.12 dholland article = "a"; 103 1.1 cgd } 104 1.12 dholland snprintf(mechanism_buf, sizeof(mechanism_buf), 105 1.12 dholland "Killed by %s %s", 106 1.12 dholland article, m_names[monster->m_char - 'A']); 107 1.12 dholland mechanism = mechanism_buf; 108 1.1 cgd } 109 1.12 dholland snprintf(message_buf, sizeof(message_buf), 110 1.12 dholland "%s with %ld gold", mechanism, rogue.gold); 111 1.12 dholland 112 1.1 cgd if ((!other) && (!no_skull)) { 113 1.1 cgd clear(); 114 1.1 cgd mvaddstr(4, 32, "__---------__"); 115 1.1 cgd mvaddstr(5, 30, "_~ ~_"); 116 1.1 cgd mvaddstr(6, 29, "/ \\"); 117 1.1 cgd mvaddstr(7, 28, "~ ~"); 118 1.1 cgd mvaddstr(8, 27, "/ \\"); 119 1.1 cgd mvaddstr(9, 27, "| XXXX XXXX |"); 120 1.1 cgd mvaddstr(10, 27, "| XXXX XXXX |"); 121 1.1 cgd mvaddstr(11, 27, "| XXX XXX |"); 122 1.1 cgd mvaddstr(12, 28, "\\ @ /"); 123 1.1 cgd mvaddstr(13, 29, "--\\ @@@ /--"); 124 1.1 cgd mvaddstr(14, 30, "| | @@@ | |"); 125 1.1 cgd mvaddstr(15, 30, "| | | |"); 126 1.1 cgd mvaddstr(16, 30, "| vvVvvvvvvvVvv |"); 127 1.1 cgd mvaddstr(17, 30, "| ^^^^^^^^^^^ |"); 128 1.1 cgd mvaddstr(18, 31, "\\_ _/"); 129 1.1 cgd mvaddstr(19, 33, "~---------~"); 130 1.1 cgd center(21, nick_name); 131 1.12 dholland center(22, message_buf); 132 1.1 cgd } else { 133 1.12 dholland messagef(0, "%s", message_buf); 134 1.1 cgd } 135 1.12 dholland messagef(0, "%s", ""); /* gcc objects to just "" */ 136 1.1 cgd put_scores(monster, other); 137 1.1 cgd } 138 1.1 cgd 139 1.6 lukem void 140 1.14 dholland win(void) 141 1.1 cgd { 142 1.1 cgd unwield(rogue.weapon); /* disarm and relax */ 143 1.1 cgd unwear(rogue.armor); 144 1.1 cgd un_put_on(rogue.left_ring); 145 1.1 cgd un_put_on(rogue.right_ring); 146 1.1 cgd 147 1.1 cgd clear(); 148 1.1 cgd mvaddstr(10, 11, "@ @ @@@ @ @ @ @ @ @@@ @ @ @"); 149 1.1 cgd mvaddstr(11, 11, " @ @ @ @ @ @ @ @ @ @ @ @@ @ @"); 150 1.1 cgd mvaddstr(12, 11, " @ @ @ @ @ @ @ @ @ @ @ @ @ @"); 151 1.1 cgd mvaddstr(13, 11, " @ @ @ @ @ @ @ @ @ @ @ @@"); 152 1.1 cgd mvaddstr(14, 11, " @ @@@ @@@ @@ @@ @@@ @ @ @"); 153 1.1 cgd mvaddstr(17, 11, "Congratulations, you have been admitted to the"); 154 1.1 cgd mvaddstr(18, 11, "Fighters' Guild. You return home, sell all your"); 155 1.1 cgd mvaddstr(19, 11, "treasures at great profit and retire into comfort."); 156 1.12 dholland messagef(0, "%s", ""); /* gcc objects to just "" */ 157 1.12 dholland messagef(0, "%s", ""); /* gcc objects to just "" */ 158 1.1 cgd id_all(); 159 1.1 cgd sell_pack(); 160 1.14 dholland put_scores(NULL, WIN); 161 1.1 cgd } 162 1.1 cgd 163 1.6 lukem void 164 1.14 dholland quit(boolean from_intrpt) 165 1.1 cgd { 166 1.12 dholland char buf[DCOLS]; 167 1.1 cgd short i, orow, ocol; 168 1.1 cgd boolean mc; 169 1.1 cgd 170 1.6 lukem orow = ocol = 0; 171 1.6 lukem mc = FALSE; 172 1.1 cgd md_ignore_signals(); 173 1.1 cgd 174 1.1 cgd if (from_intrpt) { 175 1.1 cgd orow = rogue.row; 176 1.1 cgd ocol = rogue.col; 177 1.1 cgd 178 1.1 cgd mc = msg_cleared; 179 1.1 cgd 180 1.1 cgd for (i = 0; i < DCOLS; i++) { 181 1.1 cgd buf[i] = mvinch(0, i); 182 1.1 cgd } 183 1.1 cgd } 184 1.1 cgd check_message(); 185 1.12 dholland messagef(1, "really quit?"); 186 1.1 cgd if (rgetchar() != 'y') { 187 1.1 cgd md_heed_signals(); 188 1.1 cgd check_message(); 189 1.1 cgd if (from_intrpt) { 190 1.1 cgd for (i = 0; i < DCOLS; i++) { 191 1.1 cgd mvaddch(0, i, buf[i]); 192 1.1 cgd } 193 1.1 cgd msg_cleared = mc; 194 1.1 cgd move(orow, ocol); 195 1.1 cgd refresh(); 196 1.1 cgd } 197 1.1 cgd return; 198 1.1 cgd } 199 1.1 cgd if (from_intrpt) { 200 1.1 cgd clean_up(byebye_string); 201 1.1 cgd } 202 1.1 cgd check_message(); 203 1.14 dholland killed_by(NULL, QUIT); 204 1.1 cgd } 205 1.1 cgd 206 1.12 dholland /* 207 1.12 dholland * The score file on disk is up to ten entries of the form 208 1.12 dholland * score block [80 bytes] 209 1.12 dholland * nickname block [30 bytes] 210 1.12 dholland * 211 1.12 dholland * The score block is to be parsed as follows: 212 1.12 dholland * bytes 0-1 Rank (" 1" to "10") 213 1.12 dholland * bytes 2-4 space padding 214 1.12 dholland * bytes 5-15 Score/gold 215 1.12 dholland * byte 15 up to a ':' Login name 216 1.12 dholland * past the ':' Death mechanism 217 1.12 dholland * 218 1.12 dholland * The nickname block is an alternate name to be printed in place of the 219 1.12 dholland * login name. Both blocks are supposed to contain a null-terminator. 220 1.12 dholland */ 221 1.12 dholland 222 1.12 dholland struct score_entry { 223 1.12 dholland long gold; 224 1.12 dholland char username[80]; 225 1.12 dholland char death[80]; 226 1.12 dholland char nickname[30]; 227 1.12 dholland }; 228 1.12 dholland 229 1.12 dholland #define NUM_SCORE_ENTRIES 10 230 1.12 dholland 231 1.14 dholland static void make_score(struct score_entry *, const object *, int); 232 1.12 dholland 233 1.12 dholland static 234 1.12 dholland void 235 1.14 dholland pad_spaces(char *str, size_t len) 236 1.12 dholland { 237 1.12 dholland size_t x; 238 1.12 dholland for (x=strlen(str); x<len-1; x++) { 239 1.12 dholland str[x] = ' '; 240 1.12 dholland } 241 1.12 dholland str[len-1] = 0; 242 1.12 dholland } 243 1.12 dholland 244 1.12 dholland static 245 1.12 dholland void 246 1.14 dholland unpad_spaces(char *str) 247 1.12 dholland { 248 1.12 dholland size_t x; 249 1.12 dholland for (x=strlen(str); x>0 && str[x-1]==' '; x--); 250 1.12 dholland str[x] = 0; 251 1.12 dholland } 252 1.12 dholland 253 1.12 dholland static 254 1.12 dholland int 255 1.14 dholland read_score_entry(struct score_entry *se, FILE *fp) 256 1.12 dholland { 257 1.12 dholland char score_block[80]; 258 1.12 dholland char nickname_block[30]; 259 1.12 dholland size_t n, x; 260 1.12 dholland 261 1.12 dholland n = fread(score_block, 1, sizeof(score_block), fp); 262 1.12 dholland if (n==0) { 263 1.12 dholland /* EOF */ 264 1.12 dholland return 0; 265 1.12 dholland } 266 1.12 dholland if (n != sizeof(score_block)) { 267 1.12 dholland sf_error(); 268 1.12 dholland } 269 1.12 dholland 270 1.12 dholland n = fread(nickname_block, 1, sizeof(nickname_block), fp); 271 1.12 dholland if (n != sizeof(nickname_block)) { 272 1.12 dholland sf_error(); 273 1.12 dholland } 274 1.12 dholland 275 1.12 dholland xxxx(score_block, sizeof(score_block)); 276 1.12 dholland xxxx(nickname_block, sizeof(nickname_block)); 277 1.12 dholland 278 1.12 dholland /* Ensure null termination */ 279 1.12 dholland score_block[sizeof(score_block)-1] = 0; 280 1.12 dholland nickname_block[sizeof(nickname_block)-1] = 0; 281 1.12 dholland 282 1.12 dholland /* If there are other nulls in the score block, file is corrupt */ 283 1.12 dholland if (strlen(score_block)!=sizeof(score_block)-1) { 284 1.12 dholland sf_error(); 285 1.12 dholland } 286 1.12 dholland /* but this is NOT true of the nickname block */ 287 1.12 dholland 288 1.12 dholland /* quash trailing spaces */ 289 1.12 dholland unpad_spaces(score_block); 290 1.12 dholland unpad_spaces(nickname_block); 291 1.12 dholland 292 1.12 dholland for (x=5; score_block[x] == ' '; x++); 293 1.12 dholland se->gold = lget_number(score_block+x); 294 1.12 dholland 295 1.12 dholland for (x=15; score_block[x] != 0 && score_block[x] != ':'; x++); 296 1.12 dholland if (score_block[x] == 0) { 297 1.12 dholland sf_error(); 298 1.12 dholland } 299 1.12 dholland score_block[x++] = 0; 300 1.12 dholland strlcpy(se->username, score_block+15, sizeof(se->username)); 301 1.12 dholland 302 1.12 dholland strlcpy(se->death, score_block+x, sizeof(se->death)); 303 1.12 dholland strlcpy(se->nickname, nickname_block, sizeof(se->nickname)); 304 1.12 dholland 305 1.12 dholland return 1; 306 1.12 dholland } 307 1.12 dholland 308 1.12 dholland static 309 1.12 dholland void 310 1.14 dholland write_score_entry(const struct score_entry *se, int rank, FILE *fp) 311 1.12 dholland { 312 1.12 dholland char score_block[80]; 313 1.12 dholland char nickname_block[30]; 314 1.12 dholland 315 1.12 dholland /* avoid writing crap to score file */ 316 1.12 dholland memset(score_block, 0, sizeof(score_block)); 317 1.12 dholland memset(nickname_block, 0, sizeof(nickname_block)); 318 1.12 dholland 319 1.12 dholland snprintf(score_block, sizeof(score_block), 320 1.12 dholland "%2d %6ld %s: %s", 321 1.12 dholland rank+1, se->gold, se->username, se->death); 322 1.12 dholland strlcpy(nickname_block, se->nickname, sizeof(nickname_block)); 323 1.12 dholland 324 1.12 dholland /* pad blocks out with spaces */ 325 1.12 dholland pad_spaces(score_block, sizeof(score_block)); 326 1.12 dholland /*pad_spaces(nickname_block, sizeof(nickname_block)); -- wrong! */ 327 1.12 dholland 328 1.12 dholland xxxx(score_block, sizeof(score_block)); 329 1.12 dholland xxxx(nickname_block, sizeof(nickname_block)); 330 1.12 dholland 331 1.12 dholland fwrite(score_block, 1, sizeof(score_block), fp); 332 1.12 dholland fwrite(nickname_block, 1, sizeof(nickname_block), fp); 333 1.12 dholland } 334 1.12 dholland 335 1.6 lukem void 336 1.14 dholland put_scores(const object *monster, short other) 337 1.1 cgd { 338 1.12 dholland short i, rank=-1, found_player = -1, numscores = 0; 339 1.12 dholland struct score_entry scores[NUM_SCORE_ENTRIES]; 340 1.12 dholland const char *name; 341 1.1 cgd FILE *fp; 342 1.10 tron boolean dopause = score_only; 343 1.1 cgd 344 1.1 cgd md_lock(1); 345 1.1 cgd 346 1.8 jsm setegid(egid); 347 1.4 cgd if ((fp = fopen(_PATH_SCOREFILE, "r+")) == NULL && 348 1.4 cgd (fp = fopen(_PATH_SCOREFILE, "w+")) == NULL) { 349 1.8 jsm setegid(gid); 350 1.12 dholland messagef(0, "cannot read/write/create score file"); 351 1.1 cgd sf_error(); 352 1.1 cgd } 353 1.8 jsm setegid(gid); 354 1.1 cgd rewind(fp); 355 1.13 dholland (void)xxx(1); 356 1.1 cgd 357 1.12 dholland for (numscores = 0; numscores < NUM_SCORE_ENTRIES; numscores++) { 358 1.12 dholland if (read_score_entry(&scores[numscores], fp) == 0) { 359 1.1 cgd break; 360 1.1 cgd } 361 1.12 dholland } 362 1.12 dholland 363 1.12 dholland /* Search the score list. */ 364 1.12 dholland for (i=0; i<numscores; i++) { 365 1.12 dholland if (!strcmp(scores[i].username, login_name)) { 366 1.12 dholland /* found our score */ 367 1.12 dholland if (rogue.gold < scores[i].gold) { 368 1.12 dholland /* we didn't do as well as last time */ 369 1.12 dholland score_only = 1; 370 1.12 dholland } else { 371 1.12 dholland /* we did better; mark entry for removal */ 372 1.12 dholland found_player = i; 373 1.1 cgd } 374 1.12 dholland break; 375 1.1 cgd } 376 1.1 cgd } 377 1.12 dholland 378 1.12 dholland /* Remove a superseded entry, if any. */ 379 1.1 cgd if (found_player != -1) { 380 1.12 dholland numscores--; 381 1.12 dholland for (i = found_player; i < numscores; i++) { 382 1.12 dholland scores[i] = scores[i+1]; 383 1.1 cgd } 384 1.1 cgd } 385 1.12 dholland 386 1.12 dholland /* If we're going to insert ourselves, do it now */ 387 1.1 cgd if (!score_only) { 388 1.1 cgd 389 1.12 dholland /* if we aren't better than anyone, add at end. */ 390 1.12 dholland rank = numscores; 391 1.12 dholland 392 1.12 dholland /* Otherwise, find our slot. */ 393 1.12 dholland for (i = 0; i < numscores; i++) { 394 1.12 dholland if (rogue.gold >= scores[i].gold) { 395 1.1 cgd rank = i; 396 1.1 cgd break; 397 1.1 cgd } 398 1.1 cgd } 399 1.12 dholland 400 1.12 dholland if (rank < NUM_SCORE_ENTRIES) { 401 1.12 dholland /* Open up a slot */ 402 1.12 dholland for (i = numscores; i > rank; i--) { 403 1.12 dholland scores[i] = scores[i-1]; 404 1.1 cgd } 405 1.12 dholland numscores++; 406 1.12 dholland 407 1.12 dholland /* Put our info in the slot */ 408 1.12 dholland make_score(&scores[rank], monster, other); 409 1.1 cgd } 410 1.12 dholland 411 1.12 dholland /* Now rewrite the score file */ 412 1.12 dholland 413 1.12 dholland md_ignore_signals(); 414 1.1 cgd rewind(fp); 415 1.13 dholland (void)xxx(1); 416 1.12 dholland 417 1.12 dholland for (i = 0; i < numscores; i++) { 418 1.12 dholland write_score_entry(&scores[i], i, fp); 419 1.12 dholland } 420 1.1 cgd } 421 1.12 dholland md_lock(0); 422 1.12 dholland fclose(fp); 423 1.12 dholland 424 1.12 dholland /* Display the scores */ 425 1.1 cgd 426 1.1 cgd clear(); 427 1.1 cgd mvaddstr(3, 30, "Top Ten Rogueists"); 428 1.1 cgd mvaddstr(8, 0, "Rank Score Name"); 429 1.1 cgd 430 1.12 dholland for (i = 0; i < numscores; i++) { 431 1.1 cgd if (i == rank) { 432 1.1 cgd standout(); 433 1.1 cgd } 434 1.12 dholland 435 1.12 dholland if (scores[i].nickname[0]) { 436 1.12 dholland name = scores[i].nickname; 437 1.1 cgd } else { 438 1.12 dholland name = scores[i].username; 439 1.1 cgd } 440 1.12 dholland 441 1.12 dholland mvprintw(i+10, 0, "%2d %6ld %s: %s", 442 1.12 dholland i+1, scores[i].gold, name, scores[i].death); 443 1.12 dholland 444 1.1 cgd if (i == rank) { 445 1.1 cgd standend(); 446 1.1 cgd } 447 1.1 cgd } 448 1.1 cgd refresh(); 449 1.12 dholland messagef(0, "%s", ""); /* gcc objects to just "" */ 450 1.10 tron if (dopause) { 451 1.12 dholland messagef(0, "%s", ""); 452 1.1 cgd } 453 1.1 cgd clean_up(""); 454 1.1 cgd } 455 1.1 cgd 456 1.12 dholland static 457 1.6 lukem void 458 1.14 dholland make_score(struct score_entry *se, const object *monster, int other) 459 1.1 cgd { 460 1.12 dholland const char *death = "bolts from the blue (?)"; 461 1.12 dholland const char *hasamulet; 462 1.12 dholland char deathbuf[80]; 463 1.1 cgd 464 1.12 dholland se->gold = rogue.gold; 465 1.12 dholland strlcpy(se->username, login_name, sizeof(se->username)); 466 1.1 cgd 467 1.1 cgd if (other) { 468 1.1 cgd switch(other) { 469 1.1 cgd case HYPOTHERMIA: 470 1.12 dholland death = "died of hypothermia"; 471 1.1 cgd break; 472 1.1 cgd case STARVATION: 473 1.12 dholland death = "died of starvation"; 474 1.1 cgd break; 475 1.1 cgd case POISON_DART: 476 1.12 dholland death = "killed by a dart"; 477 1.1 cgd break; 478 1.1 cgd case QUIT: 479 1.12 dholland death = "quit"; 480 1.1 cgd break; 481 1.1 cgd case WIN: 482 1.12 dholland death = "a total winner"; 483 1.1 cgd break; 484 1.1 cgd case KFIRE: 485 1.12 dholland death = "killed by fire"; 486 1.1 cgd break; 487 1.1 cgd } 488 1.1 cgd } else { 489 1.12 dholland const char *mn, *article; 490 1.12 dholland 491 1.12 dholland mn = m_names[monster->m_char - 'A']; 492 1.12 dholland if (is_vowel(mn[0])) { 493 1.12 dholland article = "an"; 494 1.1 cgd } else { 495 1.12 dholland article = "a"; 496 1.1 cgd } 497 1.13 dholland 498 1.12 dholland snprintf(deathbuf, sizeof(deathbuf), 499 1.12 dholland "killed by %s %s", article, mn); 500 1.12 dholland death = deathbuf; 501 1.1 cgd } 502 1.12 dholland 503 1.12 dholland if (other != WIN && has_amulet()) { 504 1.12 dholland hasamulet = " with amulet"; 505 1.12 dholland } else { 506 1.12 dholland hasamulet = ""; 507 1.1 cgd } 508 1.12 dholland 509 1.12 dholland snprintf(se->death, sizeof(se->death), "%s on level %d%s", 510 1.12 dholland death, max_level, hasamulet); 511 1.12 dholland 512 1.12 dholland strlcpy(se->nickname, nick_name, sizeof(se->nickname)); 513 1.1 cgd } 514 1.1 cgd 515 1.6 lukem boolean 516 1.14 dholland is_vowel(short ch) 517 1.1 cgd { 518 1.1 cgd return( (ch == 'a') || 519 1.1 cgd (ch == 'e') || 520 1.1 cgd (ch == 'i') || 521 1.1 cgd (ch == 'o') || 522 1.1 cgd (ch == 'u') ); 523 1.1 cgd } 524 1.1 cgd 525 1.15 dholland static void 526 1.14 dholland sell_pack(void) 527 1.1 cgd { 528 1.1 cgd object *obj; 529 1.1 cgd short row = 2, val; 530 1.1 cgd char buf[DCOLS]; 531 1.1 cgd 532 1.1 cgd obj = rogue.pack.next_object; 533 1.1 cgd 534 1.1 cgd clear(); 535 1.1 cgd mvaddstr(1, 0, "Value Item"); 536 1.1 cgd 537 1.1 cgd while (obj) { 538 1.1 cgd if (obj->what_is != FOOD) { 539 1.1 cgd obj->identified = 1; 540 1.1 cgd val = get_value(obj); 541 1.1 cgd rogue.gold += val; 542 1.1 cgd 543 1.1 cgd if (row < DROWS) { 544 1.12 dholland get_desc(obj, buf, sizeof(buf)); 545 1.12 dholland mvprintw(row++, 0, "%5d %s", val, buf); 546 1.1 cgd } 547 1.1 cgd } 548 1.1 cgd obj = obj->next_object; 549 1.1 cgd } 550 1.1 cgd refresh(); 551 1.1 cgd if (rogue.gold > MAX_GOLD) { 552 1.1 cgd rogue.gold = MAX_GOLD; 553 1.1 cgd } 554 1.12 dholland messagef(0, "%s", ""); /* gcc objects to just "" */ 555 1.1 cgd } 556 1.1 cgd 557 1.15 dholland static int 558 1.14 dholland get_value(const object *obj) 559 1.1 cgd { 560 1.1 cgd short wc; 561 1.1 cgd int val; 562 1.1 cgd 563 1.6 lukem val = 0; 564 1.1 cgd wc = obj->which_kind; 565 1.1 cgd 566 1.1 cgd switch(obj->what_is) { 567 1.1 cgd case WEAPON: 568 1.1 cgd val = id_weapons[wc].value; 569 1.1 cgd if ((wc == ARROW) || (wc == DAGGER) || (wc == SHURIKEN) || 570 1.1 cgd (wc == DART)) { 571 1.1 cgd val *= obj->quantity; 572 1.1 cgd } 573 1.1 cgd val += (obj->d_enchant * 85); 574 1.1 cgd val += (obj->hit_enchant * 85); 575 1.1 cgd break; 576 1.1 cgd case ARMOR: 577 1.1 cgd val = id_armors[wc].value; 578 1.1 cgd val += (obj->d_enchant * 75); 579 1.1 cgd if (obj->is_protected) { 580 1.1 cgd val += 200; 581 1.1 cgd } 582 1.1 cgd break; 583 1.1 cgd case WAND: 584 1.1 cgd val = id_wands[wc].value * (obj->class + 1); 585 1.1 cgd break; 586 1.1 cgd case SCROL: 587 1.1 cgd val = id_scrolls[wc].value * obj->quantity; 588 1.1 cgd break; 589 1.1 cgd case POTION: 590 1.1 cgd val = id_potions[wc].value * obj->quantity; 591 1.1 cgd break; 592 1.1 cgd case AMULET: 593 1.1 cgd val = 5000; 594 1.1 cgd break; 595 1.1 cgd case RING: 596 1.1 cgd val = id_rings[wc].value * (obj->class + 1); 597 1.1 cgd break; 598 1.1 cgd } 599 1.1 cgd if (val <= 0) { 600 1.1 cgd val = 10; 601 1.1 cgd } 602 1.1 cgd return(val); 603 1.1 cgd } 604 1.1 cgd 605 1.15 dholland static void 606 1.14 dholland id_all(void) 607 1.1 cgd { 608 1.1 cgd short i; 609 1.1 cgd 610 1.1 cgd for (i = 0; i < SCROLS; i++) { 611 1.1 cgd id_scrolls[i].id_status = IDENTIFIED; 612 1.1 cgd } 613 1.1 cgd for (i = 0; i < WEAPONS; i++) { 614 1.1 cgd id_weapons[i].id_status = IDENTIFIED; 615 1.1 cgd } 616 1.1 cgd for (i = 0; i < ARMORS; i++) { 617 1.1 cgd id_armors[i].id_status = IDENTIFIED; 618 1.1 cgd } 619 1.1 cgd for (i = 0; i < WANDS; i++) { 620 1.1 cgd id_wands[i].id_status = IDENTIFIED; 621 1.1 cgd } 622 1.1 cgd for (i = 0; i < POTIONS; i++) { 623 1.1 cgd id_potions[i].id_status = IDENTIFIED; 624 1.1 cgd } 625 1.1 cgd } 626 1.1 cgd 627 1.6 lukem void 628 1.14 dholland xxxx(char *buf, short n) 629 1.1 cgd { 630 1.1 cgd short i; 631 1.1 cgd unsigned char c; 632 1.1 cgd 633 1.1 cgd for (i = 0; i < n; i++) { 634 1.1 cgd 635 1.1 cgd /* It does not matter if accuracy is lost during this assignment */ 636 1.13 dholland c = (unsigned char)xxx(0); 637 1.1 cgd 638 1.1 cgd buf[i] ^= c; 639 1.1 cgd } 640 1.1 cgd } 641 1.1 cgd 642 1.1 cgd long 643 1.14 dholland xxx(boolean st) 644 1.1 cgd { 645 1.1 cgd static long f, s; 646 1.1 cgd long r; 647 1.1 cgd 648 1.1 cgd if (st) { 649 1.1 cgd f = 37; 650 1.1 cgd s = 7; 651 1.1 cgd return(0L); 652 1.1 cgd } 653 1.1 cgd r = ((f * s) + 9337) % 8887; 654 1.1 cgd f = s; 655 1.1 cgd s = r; 656 1.1 cgd return(r); 657 1.1 cgd } 658 1.1 cgd 659 1.15 dholland static void 660 1.14 dholland center(short row, const char *buf) 661 1.1 cgd { 662 1.1 cgd short margin; 663 1.1 cgd 664 1.1 cgd margin = ((DCOLS - strlen(buf)) / 2); 665 1.1 cgd mvaddstr(row, margin, buf); 666 1.1 cgd } 667 1.1 cgd 668 1.15 dholland static void 669 1.14 dholland sf_error(void) 670 1.1 cgd { 671 1.1 cgd md_lock(0); 672 1.12 dholland messagef(1, "%s", ""); /* gcc objects to just "" */ 673 1.1 cgd clean_up("sorry, score file is out of order"); 674 1.1 cgd } 675