|
|
1.1 ! root 1: /* ! 2: * Phantasia 3.3.2 -- Interterminal fantasy game ! 3: * ! 4: * Edward A. Estes ! 5: * AT&T, March 12, 1986 ! 6: */ ! 7: ! 8: /* DISCLAIMER: ! 9: * ! 10: * This game is distributed for free as is. It is not guaranteed to work ! 11: * in every conceivable environment. It is not even guaranteed to work ! 12: * in ANY environment. ! 13: * ! 14: * This game is distributed without notice of copyright, therefore it ! 15: * may be used in any manner the recipient sees fit. However, the ! 16: * author assumes no responsibility for maintaining or revising this ! 17: * game, in its original form, or any derivitives thereof. ! 18: * ! 19: * The author shall not be responsible for any loss, cost, or damage, ! 20: * including consequential damage, caused by reliance on this material. ! 21: * ! 22: * The author makes no warranties, express or implied, including warranties ! 23: * of merchantability or fitness for a particular purpose or use. ! 24: * ! 25: * AT&T is in no way connected with this game. ! 26: */ ! 27: ! 28: /* ! 29: * The program allocates as much file space as it needs to store characters, ! 30: * so the possibility exists for the character file to grow without bound. ! 31: * The file is purged upon normal entry to try to avoid that problem. ! 32: * A similar problem exists for energy voids. To alleviate the problem here, ! 33: * the void file is cleared with every new king, and a limit is placed ! 34: * on the size of the energy void file. ! 35: */ ! 36: ! 37: /* ! 38: * Put one line of text into the file 'motd' for announcements, etc. ! 39: */ ! 40: ! 41: /* ! 42: * If ENEMY is #defined, a list of restricted login names is checked ! 43: * in the file 'enemy'. These names are listed, one per line, with ! 44: * no trailing blanks. ! 45: */ ! 46: ! 47: /* ! 48: * The scoreboard file is updated when someone dies, and keeps track ! 49: * of the highest character to date for that login. ! 50: * Being purged from the character file does not cause the scoreboard ! 51: * to be updated. ! 52: */ ! 53: ! 54: /* ! 55: * All source files are set up for 'vi' with shiftwidth=4, tabstop=8. ! 56: */ ! 57: ! 58: /**/ ! 59: ! 60: /* ! 61: * main.c Main routines for Phantasia ! 62: */ ! 63: ! 64: #include "include.h" ! 65: ! 66: /*************************************************************************** ! 67: / FUNCTION NAME: main() ! 68: / ! 69: / FUNCTION: initialize state, and call main process ! 70: / ! 71: / AUTHOR: E. A. Estes, 12/4/85 ! 72: / ! 73: / ARGUMENTS: ! 74: / int argc - argument count ! 75: / char **argv - argument vector ! 76: / ! 77: / RETURN VALUE: none ! 78: / ! 79: / MODULES CALLED: monstlist(), checkenemy(), ok_to_play(), activelist(), ! 80: / throneroom(), checkbattle(), readmessage(), changestats(), writerecord(), ! 81: / tradingpost(), adjuststats(), recallplayer(), displaystats(), checktampered(), ! 82: / fabs(), rollnewplayer(), time(), exit(), sqrt(), floor(), wmove(), ! 83: / signal(), strcat(), purgeoldplayers(), getuid(), isatty(), wclear(), ! 84: / strcpy(), system(), altercoordinates(), cleanup(), waddstr(), procmain(), ! 85: / playinit(), leavegame(), localtime(), getanswer(), neatstuff(), initialstate(), ! 86: / scorelist(), titlelist() ! 87: / ! 88: / GLOBAL INPUTS: *Login, Throne, Wizard, Player, *stdscr, Changed, Databuf[], ! 89: / Fileloc, Helpfile[], Stattable[] ! 90: / ! 91: / GLOBAL OUTPUTS: Wizard, Player, Changed, Fileloc, Timeout, *Statptr ! 92: / ! 93: / DESCRIPTION: ! 94: / Process arguments, initialize program, and loop forever processing ! 95: / player input. ! 96: / ! 97: /***************************************************************************/ ! 98: ! 99: main(argc, argv) ! 100: int argc; ! 101: char **argv; ! 102: { ! 103: bool noheader = FALSE; /* set if don't want header */ ! 104: bool headeronly = FALSE; /* set if only want header */ ! 105: bool examine = FALSE; /* set if examine a character */ ! 106: long seconds; /* for time of day */ ! 107: double dtemp; /* for temporary calculations */ ! 108: ! 109: initialstate(); /* init globals */ ! 110: ! 111: #ifdef ENEMY ! 112: checkenemy(); /* check if denied access */ ! 113: #endif ! 114: ! 115: /* process arguments */ ! 116: while (--argc && (*++argv)[0] == '-') ! 117: switch ((*argv)[1]) ! 118: { ! 119: case 's': /* short */ ! 120: noheader = TRUE; ! 121: break; ! 122: ! 123: case 'H': /* Header */ ! 124: headeronly = TRUE; ! 125: break; ! 126: ! 127: case 'a': /* all users */ ! 128: activelist(); ! 129: cleanup(TRUE); ! 130: /*NOTREACHED*/ ! 131: ! 132: case 'p': /* purge old players */ ! 133: purgeoldplayers(); ! 134: cleanup(TRUE); ! 135: /*NOTREACHED*/ ! 136: ! 137: case 'S': /* set 'Wizard' */ ! 138: Wizard = (getuid() == UID); ! 139: break; ! 140: ! 141: case 'x': /* examine */ ! 142: examine = TRUE; ! 143: break; ! 144: ! 145: case 'm': /* monsters */ ! 146: monstlist(); ! 147: cleanup(TRUE); ! 148: /*NOTREACHED*/ ! 149: ! 150: case 'b': /* scoreboard */ ! 151: scorelist(); ! 152: cleanup(TRUE); ! 153: /*NOTREACHED*/ ! 154: ! 155: case 'h': /* help */ ! 156: cleanup(FALSE); ! 157: strcpy(Databuf, "cat "); ! 158: system(strcat(Databuf, Helpfile)); ! 159: exit(0); ! 160: /*NOTREACHED*/ ! 161: } ! 162: ! 163: if (!isatty(0)) /* don't let non-tty's play */ ! 164: cleanup(TRUE); ! 165: /*NOTREACHED*/ ! 166: ! 167: playinit(); /* set up to catch signals, init curses */ ! 168: ! 169: if (examine) ! 170: { ! 171: changestats(FALSE); ! 172: cleanup(TRUE); ! 173: /*NOTREACHED*/ ! 174: } ! 175: ! 176: if (!noheader) ! 177: { ! 178: titlelist(); ! 179: purgeoldplayers(); /* clean up old characters */ ! 180: } ! 181: ! 182: if (headeronly) ! 183: cleanup(TRUE); ! 184: /*NOTREACHED*/ ! 185: ! 186: #ifdef OK_TO_PLAY ! 187: if (!ok_to_play()) ! 188: { ! 189: mvaddstr(23, 27, "Sorry, you can't play now.\n"); ! 190: cleanup(TRUE); ! 191: /*NOTREACHED*/ ! 192: } ! 193: #endif ! 194: ! 195: do ! 196: /* get the player structure filled */ ! 197: { ! 198: Fileloc = -1L; ! 199: ! 200: mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? "); ! 201: ! 202: switch (getanswer("NYQ", FALSE)) ! 203: { ! 204: case 'Y': ! 205: Fileloc = recallplayer(); ! 206: break; ! 207: ! 208: case 'Q': ! 209: cleanup(TRUE); ! 210: /*NOTREACHED*/ ! 211: ! 212: default: ! 213: Fileloc = rollnewplayer(); ! 214: break; ! 215: } ! 216: clear(); ! 217: } ! 218: while (Fileloc < 0L); ! 219: ! 220: if (Player.p_level > 5.0) ! 221: /* low level players have long timeout */ ! 222: Timeout = TRUE; ! 223: ! 224: /* update some important player statistics */ ! 225: strcpy(Player.p_login, Login); ! 226: time(&seconds); ! 227: Player.p_lastused = localtime(&seconds)->tm_yday; ! 228: Player.p_status = S_PLAYING; ! 229: writerecord(&Player, Fileloc); ! 230: ! 231: Statptr = &Stattable[Player.p_type]; /* initialize pointer */ ! 232: ! 233: /* catch interrupts */ ! 234: #ifdef BSD41 ! 235: sigset(SIGINT, interrupt); ! 236: #endif ! 237: #ifdef BSD42 ! 238: signal(SIGINT, interrupt); ! 239: #endif ! 240: #ifdef SYS3 ! 241: signal(SIGINT, interrupt); ! 242: #endif ! 243: #ifdef SYS5 ! 244: signal(SIGINT, interrupt); ! 245: #endif ! 246: ! 247: altercoordinates(Player.p_x, Player.p_y, A_FORCED); /* set some flags */ ! 248: ! 249: clear(); ! 250: ! 251: for (;;) ! 252: /* loop forever, processing input */ ! 253: { ! 254: #ifdef OK_TO_PLAY ! 255: if (!ok_to_play()) ! 256: { ! 257: mvaddstr(6, 0, "Whoops! Can't play now.\n"); ! 258: leavegame(); ! 259: /*NOTREACHED*/ ! 260: } ! 261: #endif ! 262: ! 263: adjuststats(); /* cleanup stats */ ! 264: ! 265: if (Throne && Player.p_crowns == 0 && Player.p_specialtype != SC_KING) ! 266: /* not allowed on throne -- move */ ! 267: { ! 268: mvaddstr(5,0,"You're not allowed in the Lord's Chamber without a crown.\n"); ! 269: altercoordinates(0.0, 0.0, A_NEAR); ! 270: } ! 271: ! 272: checktampered(); /* check for energy voids, etc. */ ! 273: ! 274: if (Player.p_status != S_CLOAKED ! 275: /* not cloaked */ ! 276: && (dtemp = fabs(Player.p_x)) == fabs(Player.p_y) ! 277: /* |x| = |y| */ ! 278: && !Throne) ! 279: /* not on throne */ ! 280: { ! 281: dtemp = sqrt(dtemp / 100.0); ! 282: if (floor(dtemp) == dtemp) ! 283: /* |x| / 100 == n*n; at a trading post */ ! 284: { ! 285: tradingpost(); ! 286: clear(); ! 287: } ! 288: } ! 289: ! 290: checkbattle(); /* check for player to player battle */ ! 291: neatstuff(); /* gurus, medics, etc. */ ! 292: ! 293: if (Player.p_status == S_CLOAKED) ! 294: /* costs 3 mana per turn to be cloaked */ ! 295: if (Player.p_mana > 3.0) ! 296: Player.p_mana -= 3.0; ! 297: else ! 298: /* ran out of mana, uncloak */ ! 299: { ! 300: Player.p_status = S_PLAYING; ! 301: Changed = TRUE; ! 302: } ! 303: ! 304: if (Player.p_status != S_PLAYING && Player.p_status != S_CLOAKED) ! 305: /* change status back to S_PLAYING */ ! 306: { ! 307: Player.p_status = S_PLAYING; ! 308: Changed = TRUE; ! 309: } ! 310: ! 311: if (Changed) ! 312: /* update file only if important stuff has changed */ ! 313: { ! 314: writerecord(&Player, Fileloc); ! 315: Changed = FALSE; ! 316: continue; ! 317: } ! 318: ! 319: readmessage(); /* read message, if any */ ! 320: ! 321: displaystats(); /* print statistics */ ! 322: ! 323: move(6, 0); ! 324: ! 325: if (Throne) ! 326: /* maybe make king, print prompt, etc. */ ! 327: throneroom(); ! 328: ! 329: /* print status line */ ! 330: addstr("1:Move 2:Players 3:Talk 4:Stats 5:Quit "); ! 331: if (Player.p_level >= MEL_CLOAK && Player.p_magiclvl >= ML_CLOAK) ! 332: addstr("6:Cloak "); ! 333: if (Player.p_level >= MEL_TELEPORT && Player.p_magiclvl >= ML_TELEPORT) ! 334: addstr("7:Teleport "); ! 335: if (Player.p_specialtype >= SC_COUNCIL || Wizard) ! 336: addstr("8:Intervene "); ! 337: ! 338: procmain(); /* process input */ ! 339: } ! 340: } ! 341: /**/ ! 342: /************************************************************************ ! 343: / ! 344: / FUNCTION NAME: initialstate() ! 345: / ! 346: / FUNCTION: initialize some important global variable ! 347: / ! 348: / AUTHOR: E. A. Estes, 12/4/85 ! 349: / ! 350: / ARGUMENTS: none ! 351: / ! 352: / RETURN VALUE: none ! 353: / ! 354: / MODULES CALLED: time(), fopen(), srandom(), error(), getuid(), getlogin(), ! 355: / getpwuid() ! 356: / ! 357: / GLOBAL INPUTS: Peoplefile[], Voidfile[], Messfile[], Monstfile[] ! 358: / ! 359: / GLOBAL OUTPUTS: *Energyvoidfp, Echo, Marsh, *Login, Users, Beyond, ! 360: / Throne, Wizard, Changed, Okcount, Timeout, Windows, *Monstfp, *Messagefp, ! 361: / *Playersfp ! 362: / ! 363: / DESCRIPTION: ! 364: / Set global flags, and open files which remain open. ! 365: / ! 366: /************************************************************************/ ! 367: ! 368: initialstate() ! 369: { ! 370: Beyond = FALSE; ! 371: Marsh = FALSE; ! 372: Throne = FALSE; ! 373: Changed = FALSE; ! 374: Wizard = FALSE; ! 375: Timeout = FALSE; ! 376: Users = 0; ! 377: Windows = FALSE; ! 378: Echo = TRUE; ! 379: #ifdef OK_TO_PLAY ! 380: Okcount = 0; ! 381: #endif ! 382: ! 383: /* setup login name */ ! 384: if ((Login = getlogin()) == NULL) ! 385: Login = getpwuid(getuid())->pw_name; ! 386: ! 387: /* open some files */ ! 388: if ((Playersfp = fopen(Peoplefile, "r+")) == NULL) ! 389: error(Peoplefile); ! 390: /*NOTREACHED*/ ! 391: ! 392: if ((Monstfp = fopen(Monstfile, "r+")) == NULL) ! 393: error(Monstfile); ! 394: /*NOTREACHED*/ ! 395: ! 396: if ((Messagefp = fopen(Messfile, "r")) == NULL) ! 397: error(Messfile); ! 398: /*NOTREACHED*/ ! 399: ! 400: if ((Energyvoidfp = fopen(Voidfile, "r+")) == NULL) ! 401: error(Voidfile); ! 402: /*NOTREACHED*/ ! 403: ! 404: srandom((unsigned) time((long *) NULL)); /* prime random numbers */ ! 405: } ! 406: /**/ ! 407: /************************************************************************ ! 408: / ! 409: / FUNCTION NAME: rollnewplayer() ! 410: / ! 411: / FUNCTION: roll up a new character ! 412: / ! 413: / AUTHOR: E. A. Estes, 12/4/85 ! 414: / ! 415: / ARGUMENTS: none ! 416: / ! 417: / RETURN VALUE: none ! 418: / ! 419: / MODULES CALLED: initplayer(), allocrecord(), truncstring(), fabs(), wmove(), ! 420: / wclear(), sscanf(), strcmp(), genchar(), waddstr(), findname(), mvprintw(), ! 421: / getanswer(), getstring() ! 422: / ! 423: / GLOBAL INPUTS: Other, Wizard, Player, *stdscr, Databuf[] ! 424: / ! 425: / GLOBAL OUTPUTS: Echo ! 426: / ! 427: / DESCRIPTION: ! 428: / Prompt player, and roll up new character. ! 429: / ! 430: /************************************************************************/ ! 431: ! 432: long ! 433: rollnewplayer() ! 434: { ! 435: int chartype; /* character type */ ! 436: int ch; /* input */ ! 437: ! 438: initplayer(&Player); /* initialize player structure */ ! 439: ! 440: clear(); ! 441: mvaddstr(4, 21, "Which type of character do you want:"); ! 442: mvaddstr(8, 4, "1:Magic User 2:Fighter 3:Elf 4:Dwarf 5:Halfling 6:Experimento "); ! 443: if (Wizard) { ! 444: addstr("7:Super ? "); ! 445: chartype = getanswer("1234567", FALSE); ! 446: } ! 447: else { ! 448: addstr("? "); ! 449: chartype = getanswer("123456", FALSE); ! 450: } ! 451: ! 452: do ! 453: { ! 454: genchar(chartype); /* roll up a character */ ! 455: ! 456: /* print out results */ ! 457: mvprintw(12, 14, ! 458: "Strength : %2.0f Quickness: %2.0f Mana : %2.0f\n", ! 459: Player.p_strength, Player.p_quickness, Player.p_mana); ! 460: mvprintw(13, 14, ! 461: "Energy Level: %2.0f Brains : %2.0f Magic Level: %2.0f\n", ! 462: Player.p_energy, Player.p_brains, Player.p_magiclvl); ! 463: ! 464: if (Player.p_type == C_EXPER || Player.p_type == C_SUPER) ! 465: break; ! 466: ! 467: mvaddstr(14, 14, "Type '1' to keep >"); ! 468: ch = getanswer(" ", TRUE); ! 469: } ! 470: while (ch != '1'); ! 471: ! 472: if (Player.p_type == C_EXPER || Player.p_type == C_SUPER) ! 473: /* get coordinates for experimento */ ! 474: for (;;) ! 475: { ! 476: mvaddstr(16, 0, "Enter the X Y coordinates of your experimento ? "); ! 477: getstring(Databuf, SZ_DATABUF); ! 478: sscanf(Databuf, "%lf %lf", &Player.p_x, &Player.p_y); ! 479: ! 480: if (fabs(Player.p_x) > D_EXPER || fabs(Player.p_y) > D_EXPER) ! 481: mvaddstr(17, 0, "Invalid coordinates. Try again.\n"); ! 482: else ! 483: break; ! 484: } ! 485: ! 486: for (;;) ! 487: /* name the new character */ ! 488: { ! 489: mvprintw(18, 0, ! 490: "Give your character a name [up to %d characters] ? ", SZ_NAME - 1); ! 491: getstring(Player.p_name, SZ_NAME); ! 492: truncstring(Player.p_name); /* remove trailing blanks */ ! 493: ! 494: if (Player.p_name[0] == '\0') ! 495: /* no null names */ ! 496: mvaddstr(19, 0, "Invalid name."); ! 497: else if (findname(Player.p_name, &Other) >= 0L) ! 498: /* cannot have duplicate names */ ! 499: mvaddstr(19, 0, "Name already in use."); ! 500: else ! 501: /* name is acceptable */ ! 502: break; ! 503: ! 504: addstr(" Pick another.\n"); ! 505: } ! 506: ! 507: /* get a password for character */ ! 508: Echo = FALSE; ! 509: ! 510: do ! 511: { ! 512: mvaddstr(20, 0, "Give your character a password [up to 8 characters] ? "); ! 513: getstring(Player.p_password, SZ_PASSWORD); ! 514: mvaddstr(21, 0, "One more time to verify ? "); ! 515: getstring(Databuf, SZ_PASSWORD); ! 516: } ! 517: while (strcmp(Player.p_password, Databuf) != 0); ! 518: ! 519: Echo = TRUE; ! 520: ! 521: return(allocrecord()); ! 522: } ! 523: /**/ ! 524: /************************************************************************ ! 525: / ! 526: / FUNCTION NAME: procmain() ! 527: / ! 528: / FUNCTION: process input from player ! 529: / ! 530: / AUTHOR: E. A. Estes, 12/4/85 ! 531: / ! 532: / ARGUMENTS: none ! 533: / ! 534: / RETURN VALUE: none ! 535: / ! 536: / MODULES CALLED: dotampered(), changestats(), inputoption(), allstatslist(), ! 537: / fopen(), wmove(), drandom(), sscanf(), fclose(), altercoordinates(), ! 538: / waddstr(), fprintf(), distance(), userlist(), leavegame(), encounter(), ! 539: / getstring(), wclrtobot() ! 540: / ! 541: / GLOBAL INPUTS: Circle, Illcmd[], Throne, Wizard, Player, *stdscr, ! 542: / Databuf[], Illmove[], Messfile[] ! 543: / ! 544: / GLOBAL OUTPUTS: Player, Changed ! 545: / ! 546: / DESCRIPTION: ! 547: / Process main menu options. ! 548: / ! 549: /************************************************************************/ ! 550: ! 551: procmain() ! 552: { ! 553: int ch; /* input */ ! 554: double x; /* desired new x coordinate */ ! 555: double y; /* desired new y coordinate */ ! 556: double temp; /* for temporary calculations */ ! 557: FILE *fp; /* for opening files */ ! 558: register int loop; /* a loop counter */ ! 559: bool hasmoved = FALSE; /* set if player has moved */ ! 560: ! 561: ch = inputoption(); ! 562: mvaddstr(4, 0, "\n\n"); /* clear status area */ ! 563: ! 564: move(7, 0); ! 565: clrtobot(); /* clear data on bottom area of screen */ ! 566: ! 567: if (Player.p_specialtype == SC_VALAR && (ch == '1' || ch == '7')) ! 568: /* valar cannot move */ ! 569: ch = ' '; ! 570: ! 571: switch (ch) ! 572: { ! 573: case 'K': /* move up/north */ ! 574: case 'N': ! 575: x = Player.p_x; ! 576: y = Player.p_y + MAXMOVE(); ! 577: hasmoved = TRUE; ! 578: break; ! 579: ! 580: case 'J': /* move down/south */ ! 581: case 'S': ! 582: x = Player.p_x; ! 583: y = Player.p_y - MAXMOVE(); ! 584: hasmoved = TRUE; ! 585: break; ! 586: ! 587: case 'L': /* move right/east */ ! 588: case 'E': ! 589: x = Player.p_x + MAXMOVE(); ! 590: y = Player.p_y; ! 591: hasmoved = TRUE; ! 592: break; ! 593: ! 594: case 'H': /* move left/west */ ! 595: case 'W': ! 596: x = Player.p_x - MAXMOVE(); ! 597: y = Player.p_y; ! 598: hasmoved = TRUE; ! 599: break; ! 600: ! 601: default: /* rest */ ! 602: Player.p_energy += (Player.p_maxenergy + Player.p_shield) / 15.0 ! 603: + Player.p_level / 3.0 + 2.0; ! 604: Player.p_energy = ! 605: MIN(Player.p_energy, Player.p_maxenergy + Player.p_shield); ! 606: ! 607: if (Player.p_status != S_CLOAKED) ! 608: /* cannot find mana if cloaked */ ! 609: { ! 610: Player.p_mana += (Circle + Player.p_level) / 4.0; ! 611: ! 612: if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne) ! 613: /* wandering monster */ ! 614: encounter(-1); ! 615: } ! 616: break; ! 617: ! 618: case 'X': /* change/examine a character */ ! 619: changestats(TRUE); ! 620: break; ! 621: ! 622: case '1': /* move */ ! 623: for (loop = 3; loop; --loop) ! 624: { ! 625: mvaddstr(4, 0, "X Y Coordinates ? "); ! 626: getstring(Databuf, SZ_DATABUF); ! 627: ! 628: if (sscanf(Databuf, "%lf %lf", &x, &y) != 2) ! 629: mvaddstr(5, 0, "Try again\n"); ! 630: else if (distance(Player.p_x, x, Player.p_y, y) > MAXMOVE()) ! 631: ILLMOVE(); ! 632: else ! 633: { ! 634: hasmoved = TRUE; ! 635: break; ! 636: } ! 637: } ! 638: break; ! 639: ! 640: case '2': /* players */ ! 641: userlist(TRUE); ! 642: break; ! 643: ! 644: case '3': /* message */ ! 645: mvaddstr(4, 0, "Message ? "); ! 646: getstring(Databuf, SZ_DATABUF); ! 647: /* we open the file for writing to erase any data which is already there */ ! 648: fp = fopen(Messfile, "w"); ! 649: if (Databuf[0] != '\0') ! 650: fprintf(fp, "%s: %s", Player.p_name, Databuf); ! 651: fclose(fp); ! 652: break; ! 653: ! 654: case '4': /* stats */ ! 655: allstatslist(); ! 656: break; ! 657: ! 658: case '5': /* good-bye */ ! 659: leavegame(); ! 660: /*NOTREACHED*/ ! 661: ! 662: case '6': /* cloak */ ! 663: if (Player.p_level < MEL_CLOAK || Player.p_magiclvl < ML_CLOAK) ! 664: ILLCMD(); ! 665: else if (Player.p_status == S_CLOAKED) ! 666: Player.p_status = S_PLAYING; ! 667: else if (Player.p_mana < MM_CLOAK) ! 668: mvaddstr(5, 0, "No mana left.\n"); ! 669: else ! 670: { ! 671: Changed = TRUE; ! 672: Player.p_mana -= MM_CLOAK; ! 673: Player.p_status = S_CLOAKED; ! 674: } ! 675: break; ! 676: ! 677: case '7': /* teleport */ ! 678: /* ! 679: * conditions for teleport ! 680: * - 20 per (level plus magic level) ! 681: * - OR council of the wise or valar or ex-valar ! 682: * - OR transport from throne ! 683: * transports from throne cost no mana ! 684: */ ! 685: if (Player.p_level < MEL_TELEPORT || Player.p_magiclvl < ML_TELEPORT) ! 686: ILLCMD(); ! 687: else ! 688: for (loop = 3; loop; --loop) ! 689: { ! 690: mvaddstr(4, 0, "X Y Coordinates ? "); ! 691: getstring(Databuf, SZ_DATABUF); ! 692: ! 693: if (sscanf(Databuf, "%lf %lf", &x, &y) == 2) ! 694: { ! 695: temp = distance(Player.p_x, x, Player.p_y, y); ! 696: if (!Throne ! 697: /* can transport anywhere from throne */ ! 698: && Player.p_specialtype <= SC_COUNCIL ! 699: /* council, valar can transport anywhere */ ! 700: && temp > (Player.p_level + Player.p_magiclvl) * 20.0) ! 701: /* can only move 20 per exp. level + mag. level */ ! 702: ILLMOVE(); ! 703: else ! 704: { ! 705: temp = (temp / 75.0 + 1.0) * 20.0; /* mana used */ ! 706: ! 707: if (!Throne && temp > Player.p_mana) ! 708: mvaddstr(5, 0, "Not enough power for that distance.\n"); ! 709: else ! 710: { ! 711: if (!Throne) ! 712: Player.p_mana -= temp; ! 713: hasmoved = TRUE; ! 714: break; ! 715: } ! 716: } ! 717: } ! 718: } ! 719: break; ! 720: ! 721: case 'C': ! 722: case '9': /* monster */ ! 723: if (Throne) ! 724: /* no monsters while on throne */ ! 725: mvaddstr(5, 0, "No monsters in the chamber!\n"); ! 726: else if (Player.p_specialtype != SC_VALAR) ! 727: /* the valar cannot call monsters */ ! 728: { ! 729: Player.p_sin += 1e-6; ! 730: encounter(-1); ! 731: } ! 732: break; ! 733: ! 734: case '0': /* decree */ ! 735: if (Wizard || Player.p_specialtype == SC_KING && Throne) ! 736: /* kings must be on throne to decree */ ! 737: dotampered(); ! 738: else ! 739: ILLCMD(); ! 740: break; ! 741: ! 742: case '8': /* intervention */ ! 743: if (Wizard || Player.p_specialtype >= SC_COUNCIL) ! 744: dotampered(); ! 745: else ! 746: ILLCMD(); ! 747: break; ! 748: } ! 749: ! 750: if (hasmoved) ! 751: /* player has moved -- alter coordinates, and do random monster */ ! 752: { ! 753: altercoordinates(x, y, A_SPECIFIC); ! 754: ! 755: if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne) ! 756: encounter(-1); ! 757: } ! 758: } ! 759: /**/ ! 760: #ifdef ENEMY ! 761: /************************************************************************ ! 762: / ! 763: / FUNCTION NAME: checkenemy() ! 764: / ! 765: / FUNCTION: check login name against enemy list ! 766: / ! 767: / AUTHOR: E. A. Estes, 12/4/85 ! 768: / ! 769: / ARGUMENTS: none ! 770: / ! 771: / RETURN VALUE: none ! 772: / ! 773: / MODULES CALLED: fopen(), fgets(), strcmp(), fclose(), printf(), cleanup() ! 774: / ! 775: / GLOBAL INPUTS: *Login, Databuf[], Enemyfile[] ! 776: / ! 777: / GLOBAL OUTPUTS: none ! 778: / ! 779: / DESCRIPTION: ! 780: / The enemy file has a list of login names which are denied ! 781: / access to Phantasia. ! 782: / We scan this list and exit if the current login name is ! 783: / found in the list. ! 784: / ! 785: /************************************************************************/ ! 786: ! 787: checkenemy() ! 788: { ! 789: FILE *fp; /* to open enemy file */ ! 790: ! 791: /* check hit list of restricted accounts */ ! 792: if ((fp = fopen(Enemyfile, "r")) != NULL) ! 793: { ! 794: while (fgets(Databuf, SZ_DATABUF, fp) != NULL) ! 795: if (strcmp(Login, Databuf) == 0) ! 796: { ! 797: printf ("The Phantasia privileges for the account \"%s\" have been revoked.\n", Login); ! 798: printf ("Mail comments to %s.\n", WIZARD); ! 799: fclose(fp); ! 800: cleanup(TRUE); ! 801: /*NOTREACHED*/ ! 802: } ! 803: fclose (fp); ! 804: } ! 805: } ! 806: #endif ! 807: ! 808: /**/ ! 809: /************************************************************************ ! 810: / ! 811: / FUNCTION NAME: titlelist() ! 812: / ! 813: / FUNCTION: print title page ! 814: / ! 815: / AUTHOR: E. A. Estes, 12/4/85 ! 816: / ! 817: / ARGUMENTS: none ! 818: / ! 819: / RETURN VALUE: none ! 820: / ! 821: / MODULES CALLED: fread(), fseek(), fopen(), fgets(), wmove(), strcpy(), ! 822: / fclose(), strlen(), waddstr(), sprintf(), wrefresh() ! 823: / ! 824: / GLOBAL INPUTS: Lines, Other, *stdscr, Databuf[], Lastdead[], Motdfile[], ! 825: / *Playersfp ! 826: / ! 827: / GLOBAL OUTPUTS: Lines ! 828: / ! 829: / DESCRIPTION: ! 830: / Print important information about game, players, etc. ! 831: / ! 832: /************************************************************************/ ! 833: ! 834: titlelist() ! 835: { ! 836: register FILE *fp; /* used for opening various files */ ! 837: bool councilfound = FALSE; /* set if we find a member of the council */ ! 838: bool kingfound = FALSE; /* set if we find a king */ ! 839: double hiexp, nxtexp; /* used for finding the two highest players */ ! 840: double hilvl, nxtlvl; /* used for finding the two highest players */ ! 841: char hiname[21], nxtname[21];/* used for finding the two highest players */ ! 842: ! 843: mvaddstr(0, 14, "W e l c o m e t o P h a n t a s i a (vers. 3.3.2)!"); ! 844: ! 845: /* print message of the day */ ! 846: if ((fp = fopen(Motdfile, "r")) != NULL ! 847: && fgets(Databuf, SZ_DATABUF, fp) != NULL) ! 848: { ! 849: mvaddstr(2, 40 - strlen(Databuf) / 2, Databuf); ! 850: fclose(fp); ! 851: } ! 852: ! 853: /* search for king */ ! 854: fseek(Playersfp, 0L, 0); ! 855: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 856: if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED) ! 857: /* found the king */ ! 858: { ! 859: sprintf(Databuf, "The present ruler is %s Level:%.0f", ! 860: Other.p_name, Other.p_level); ! 861: mvaddstr(4, 40 - strlen(Databuf) / 2, Databuf); ! 862: kingfound = TRUE; ! 863: break; ! 864: } ! 865: ! 866: if (!kingfound) ! 867: mvaddstr(4, 24, "There is no ruler at this time."); ! 868: ! 869: /* search for valar */ ! 870: fseek(Playersfp, 0L, 0); ! 871: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 872: if (Other.p_specialtype == SC_VALAR && Other.p_status != S_NOTUSED) ! 873: /* found the valar */ ! 874: { ! 875: sprintf(Databuf, "The Valar is %s Login: %s", Other.p_name, Other.p_login); ! 876: mvaddstr(6, 40 - strlen(Databuf) / 2 , Databuf); ! 877: break; ! 878: } ! 879: ! 880: /* search for council of the wise */ ! 881: fseek(Playersfp, 0L, 0); ! 882: Lines = 10; ! 883: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 884: if (Other.p_specialtype == SC_COUNCIL && Other.p_status != S_NOTUSED) ! 885: /* found a member of the council */ ! 886: { ! 887: if (!councilfound) ! 888: { ! 889: mvaddstr(8, 30, "Council of the Wise:"); ! 890: councilfound = TRUE; ! 891: } ! 892: ! 893: /* This assumes a finite (<=5) number of C.O.W.: */ ! 894: sprintf(Databuf, "%s Login: %s", Other.p_name, Other.p_login); ! 895: mvaddstr(Lines++, 40 - strlen(Databuf) / 2, Databuf); ! 896: } ! 897: ! 898: /* search for the two highest players */ ! 899: nxtname[0] = hiname[0] = '\0'; ! 900: hiexp = 0.0; ! 901: nxtlvl = hilvl = 0; ! 902: ! 903: fseek(Playersfp, 0L, 0); ! 904: while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) ! 905: if (Other.p_experience > hiexp && Other.p_specialtype <= SC_KING && Other.p_status != S_NOTUSED) ! 906: /* highest found so far */ ! 907: { ! 908: nxtexp = hiexp; ! 909: hiexp = Other.p_experience; ! 910: nxtlvl = hilvl; ! 911: hilvl = Other.p_level; ! 912: strcpy(nxtname, hiname); ! 913: strcpy(hiname, Other.p_name); ! 914: } ! 915: else if (Other.p_experience > nxtexp ! 916: && Other.p_specialtype <= SC_KING ! 917: && Other.p_status != S_NOTUSED) ! 918: /* next highest found so far */ ! 919: { ! 920: nxtexp = Other.p_experience; ! 921: nxtlvl = Other.p_level; ! 922: strcpy(nxtname, Other.p_name); ! 923: } ! 924: ! 925: mvaddstr(15, 28, "Highest characters are:"); ! 926: sprintf(Databuf, "%s Level:%.0f and %s Level:%.0f", ! 927: hiname, hilvl, nxtname, nxtlvl); ! 928: mvaddstr(17, 40 - strlen(Databuf) / 2, Databuf); ! 929: ! 930: /* print last to die */ ! 931: if ((fp = fopen(Lastdead,"r")) != NULL ! 932: && fgets(Databuf, SZ_DATABUF, fp) != NULL) ! 933: { ! 934: mvaddstr(19, 25, "The last character to die was:"); ! 935: mvaddstr(20, 40 - strlen(Databuf) / 2,Databuf); ! 936: fclose(fp); ! 937: } ! 938: ! 939: refresh(); ! 940: } ! 941: /**/ ! 942: /************************************************************************ ! 943: / ! 944: / FUNCTION NAME: recallplayer() ! 945: / ! 946: / FUNCTION: find a character on file ! 947: / ! 948: / AUTHOR: E. A. Estes, 12/4/85 ! 949: / ! 950: / ARGUMENTS: none ! 951: / ! 952: / RETURN VALUE: none ! 953: / ! 954: / MODULES CALLED: writerecord(), truncstring(), more(), death(), wmove(), ! 955: / wclear(), strcmp(), printw(), cleanup(), waddstr(), findname(), mvprintw(), ! 956: / getanswer(), getstring() ! 957: / ! 958: / GLOBAL INPUTS: Player, *stdscr, Databuf[] ! 959: / ! 960: / GLOBAL OUTPUTS: Echo, Player ! 961: / ! 962: / DESCRIPTION: ! 963: / Search for a character of a certain name, and check password. ! 964: / ! 965: /************************************************************************/ ! 966: ! 967: long ! 968: recallplayer() ! 969: { ! 970: long loc = 0L; /* location in player file */ ! 971: register int loop; /* loop counter */ ! 972: int ch; /* input */ ! 973: ! 974: clear(); ! 975: mvprintw(10, 0, "What was your character's name ? "); ! 976: getstring(Databuf, SZ_NAME); ! 977: truncstring(Databuf); ! 978: ! 979: if ((loc = findname(Databuf, &Player)) >= 0L) ! 980: /* found character */ ! 981: { ! 982: Echo = FALSE; ! 983: ! 984: for (loop = 0; loop < 2; ++loop) ! 985: { ! 986: /* prompt for password */ ! 987: mvaddstr(11, 0, "Password ? "); ! 988: getstring(Databuf, SZ_PASSWORD); ! 989: if (strcmp(Databuf, Player.p_password) == 0) ! 990: /* password good */ ! 991: { ! 992: Echo = TRUE; ! 993: ! 994: if (Player.p_status != S_OFF) ! 995: /* player did not exit normally last time */ ! 996: { ! 997: clear(); ! 998: addstr("Your character did not exit normally last time.\n"); ! 999: addstr("If you think you have good cause to have your character saved,\n"); ! 1000: printw("you may quit and mail your reason to '%s'.\n", WIZARD); ! 1001: addstr("Otherwise, continuing spells certain death.\n"); ! 1002: addstr("Do you want to quit ? "); ! 1003: ch = getanswer("YN", FALSE); ! 1004: if (ch == 'Y') ! 1005: { ! 1006: Player.p_status = S_HUNGUP; ! 1007: writerecord(&Player, loc); ! 1008: cleanup(TRUE); ! 1009: /*NOTREACHED*/ ! 1010: } ! 1011: death("Stupidity"); ! 1012: /*NOTREACHED*/ ! 1013: } ! 1014: return(loc); ! 1015: } ! 1016: else ! 1017: mvaddstr(12, 0, "No good.\n"); ! 1018: } ! 1019: ! 1020: Echo = TRUE; ! 1021: } ! 1022: else ! 1023: mvaddstr(11, 0, "Not found.\n"); ! 1024: ! 1025: more(13); ! 1026: return(-1L); ! 1027: } ! 1028: /**/ ! 1029: /************************************************************************ ! 1030: / ! 1031: / FUNCTION NAME: neatstuff() ! 1032: / ! 1033: / FUNCTION: do random stuff ! 1034: / ! 1035: / AUTHOR: E. A. Estes, 3/3/86 ! 1036: / ! 1037: / ARGUMENTS: none ! 1038: / ! 1039: / RETURN VALUE: none ! 1040: / ! 1041: / MODULES CALLED: collecttaxes(), floor(), wmove(), drandom(), infloat(), ! 1042: / waddstr(), mvprintw(), getanswer() ! 1043: / ! 1044: / GLOBAL INPUTS: Player, *stdscr, *Statptr ! 1045: / ! 1046: / GLOBAL OUTPUTS: Player ! 1047: / ! 1048: / DESCRIPTION: ! 1049: / Handle gurus, medics, etc. ! 1050: / ! 1051: /************************************************************************/ ! 1052: ! 1053: neatstuff() ! 1054: { ! 1055: double temp; /* for temporary calculations */ ! 1056: int ch; /* input */ ! 1057: ! 1058: switch ((int) ROLL(0.0, 100.0)) ! 1059: { ! 1060: case 1: ! 1061: case 2: ! 1062: if (Player.p_poison > 0.0) ! 1063: { ! 1064: mvaddstr(4, 0, "You've found a medic! How much will you offer to be cured ? "); ! 1065: temp = floor(infloat()); ! 1066: if (temp < 0.0 || temp > Player.p_gold) ! 1067: /* negative gold, or more than available */ ! 1068: { ! 1069: mvaddstr(6, 0, "He was not amused, and made you worse.\n"); ! 1070: Player.p_poison += 1.0; ! 1071: } ! 1072: else if (drandom() / 2.0 > (temp + 1.0) / MAX(Player.p_gold, 1)) ! 1073: /* medic wants 1/2 of available gold */ ! 1074: mvaddstr(5, 0, "Sorry, he wasn't interested.\n"); ! 1075: else ! 1076: { ! 1077: mvaddstr(5, 0, "He accepted."); ! 1078: Player.p_poison = MAX(0.0, Player.p_poison - 1.0); ! 1079: Player.p_gold -= temp; ! 1080: } ! 1081: } ! 1082: break; ! 1083: ! 1084: case 3: ! 1085: mvaddstr(4, 0, "You've been caught raping and pillaging!\n"); ! 1086: Player.p_experience += 4000.0; ! 1087: Player.p_sin += 0.5; ! 1088: break; ! 1089: ! 1090: case 4: ! 1091: temp = ROLL(10.0, 75.0); ! 1092: mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp); ! 1093: ch = getanswer("NY", FALSE); ! 1094: ! 1095: if (ch == 'Y') ! 1096: collecttaxes(temp, 0.0); ! 1097: break; ! 1098: ! 1099: case 5: ! 1100: if (Player.p_sin > 1.0) ! 1101: { ! 1102: mvaddstr(4, 0, "You've found a Holy Orb!\n"); ! 1103: Player.p_sin -= 0.25; ! 1104: } ! 1105: break; ! 1106: ! 1107: case 6: ! 1108: if (Player.p_poison < 1.0) ! 1109: { ! 1110: mvaddstr(4, 0, "You've been hit with a plague!\n"); ! 1111: Player.p_poison += 1.0; ! 1112: } ! 1113: break; ! 1114: ! 1115: case 7: ! 1116: mvaddstr(4, 0, "You've found some holy water.\n"); ! 1117: ++Player.p_holywater; ! 1118: break; ! 1119: ! 1120: case 8: ! 1121: mvaddstr(4, 0, "You've met a Guru. . ."); ! 1122: if (drandom() * Player.p_sin > 1.0) ! 1123: addstr("You disgusted him with your sins!\n"); ! 1124: else if (Player.p_poison > 0.0) ! 1125: { ! 1126: addstr("He looked kindly upon you, and cured you.\n"); ! 1127: Player.p_poison = 0.0; ! 1128: } ! 1129: else ! 1130: { ! 1131: addstr("He rewarded you for your virtue.\n"); ! 1132: Player.p_mana += 50.0; ! 1133: Player.p_shield += 2.0; ! 1134: } ! 1135: break; ! 1136: ! 1137: case 9: ! 1138: mvaddstr(4, 0, "You've found an amulet.\n"); ! 1139: ++Player.p_amulets; ! 1140: break; ! 1141: ! 1142: case 10: ! 1143: if (Player.p_blindness) ! 1144: { ! 1145: mvaddstr(4, 0, "You've regained your sight!\n"); ! 1146: Player.p_blindness = FALSE; ! 1147: } ! 1148: break; ! 1149: ! 1150: default: /* deal with poison */ ! 1151: if (Player.p_poison > 0.0) ! 1152: { ! 1153: temp = Player.p_poison * Statptr->c_weakness ! 1154: * Player.p_maxenergy / 600.0; ! 1155: if (Player.p_energy > Player.p_maxenergy / 10.0 ! 1156: && temp + 5.0 < Player.p_energy) ! 1157: Player.p_energy -= temp; ! 1158: } ! 1159: break; ! 1160: } ! 1161: } ! 1162: /**/ ! 1163: /************************************************************************ ! 1164: / ! 1165: / FUNCTION NAME: genchar() ! 1166: / ! 1167: / FUNCTION: generate a random character ! 1168: / ! 1169: / AUTHOR: E. A. Estes, 12/4/85 ! 1170: / ! 1171: / ARGUMENTS: ! 1172: / int type - ASCII value of character type to generate ! 1173: / ! 1174: / RETURN VALUE: none ! 1175: / ! 1176: / MODULES CALLED: floor(), drandom() ! 1177: / ! 1178: / GLOBAL INPUTS: Wizard, Player, Stattable[] ! 1179: / ! 1180: / GLOBAL OUTPUTS: Player ! 1181: / ! 1182: / DESCRIPTION: ! 1183: / Use the lookup table for rolling stats. ! 1184: / ! 1185: /************************************************************************/ ! 1186: ! 1187: genchar(type) ! 1188: int type; ! 1189: { ! 1190: register int subscript; /* used for subscripting into Stattable */ ! 1191: register struct charstats *statptr;/* for pointing into Stattable */ ! 1192: ! 1193: subscript = type - '1'; ! 1194: ! 1195: if (subscript < C_MAGIC || subscript > C_EXPER) ! 1196: if (subscript != C_SUPER || !Wizard) ! 1197: /* fighter is default */ ! 1198: subscript = C_FIGHTER; ! 1199: ! 1200: statptr = &Stattable[subscript]; ! 1201: ! 1202: Player.p_quickness = ! 1203: ROLL(statptr->c_quickness.base, statptr->c_quickness.interval); ! 1204: Player.p_strength = ! 1205: ROLL(statptr->c_strength.base, statptr->c_strength.interval); ! 1206: Player.p_mana = ! 1207: ROLL(statptr->c_mana.base, statptr->c_mana.interval); ! 1208: Player.p_maxenergy = ! 1209: Player.p_energy = ! 1210: ROLL(statptr->c_energy.base, statptr->c_energy.interval); ! 1211: Player.p_brains = ! 1212: ROLL(statptr->c_brains.base, statptr->c_brains.interval); ! 1213: Player.p_magiclvl = ! 1214: ROLL(statptr->c_magiclvl.base, statptr->c_magiclvl.interval); ! 1215: ! 1216: Player.p_type = subscript; ! 1217: ! 1218: if (Player.p_type == C_HALFLING) ! 1219: /* give halfling some experience */ ! 1220: Player.p_experience = ROLL(600.0, 200.0); ! 1221: } ! 1222: /**/ ! 1223: /************************************************************************ ! 1224: / ! 1225: / FUNCTION NAME: playinit() ! 1226: / ! 1227: / FUNCTION: initialize for playing game ! 1228: / ! 1229: / AUTHOR: E. A. Estes, 12/4/85 ! 1230: / ! 1231: / ARGUMENTS: none ! 1232: / ! 1233: / RETURN VALUE: none ! 1234: / ! 1235: / MODULES CALLED: signal(), wclear(), noecho(), crmode(), initscr(), ! 1236: / wrefresh() ! 1237: / ! 1238: / GLOBAL INPUTS: *stdscr, ill_sig() ! 1239: / ! 1240: / GLOBAL OUTPUTS: Windows ! 1241: / ! 1242: / DESCRIPTION: ! 1243: / Catch a bunch of signals, and turn on curses stuff. ! 1244: / ! 1245: /************************************************************************/ ! 1246: ! 1247: playinit() ! 1248: { ! 1249: /* catch/ingnore signals */ ! 1250: ! 1251: #ifdef BSD41 ! 1252: sigignore(SIGQUIT); ! 1253: sigignore(SIGALRM); ! 1254: sigignore(SIGTERM); ! 1255: sigignore(SIGTSTP); ! 1256: sigignore(SIGTTIN); ! 1257: sigignore(SIGTTOU); ! 1258: sighold(SIGINT); ! 1259: sigset(SIGHUP, ill_sig); ! 1260: sigset(SIGTRAP, ill_sig); ! 1261: sigset(SIGIOT, ill_sig); ! 1262: sigset(SIGEMT, ill_sig); ! 1263: sigset(SIGFPE, ill_sig); ! 1264: sigset(SIGBUS, ill_sig); ! 1265: sigset(SIGSEGV, ill_sig); ! 1266: sigset(SIGSYS, ill_sig); ! 1267: sigset(SIGPIPE, ill_sig); ! 1268: #endif ! 1269: #ifdef BSD42 ! 1270: signal(SIGQUIT, ill_sig); ! 1271: signal(SIGALRM, SIG_IGN); ! 1272: signal(SIGTERM, SIG_IGN); ! 1273: signal(SIGTSTP, SIG_IGN); ! 1274: signal(SIGTTIN, SIG_IGN); ! 1275: signal(SIGTTOU, SIG_IGN); ! 1276: signal(SIGINT, ill_sig); ! 1277: signal(SIGHUP, SIG_DFL); ! 1278: signal(SIGTRAP, ill_sig); ! 1279: signal(SIGIOT, ill_sig); ! 1280: signal(SIGEMT, ill_sig); ! 1281: signal(SIGFPE, ill_sig); ! 1282: signal(SIGBUS, ill_sig); ! 1283: signal(SIGSEGV, ill_sig); ! 1284: signal(SIGSYS, ill_sig); ! 1285: signal(SIGPIPE, ill_sig); ! 1286: #endif ! 1287: #ifdef SYS3 ! 1288: signal(SIGINT, SIG_IGN); ! 1289: signal(SIGQUIT, SIG_IGN); ! 1290: signal(SIGTERM, SIG_IGN); ! 1291: signal(SIGALRM, SIG_IGN); ! 1292: signal(SIGHUP, ill_sig); ! 1293: signal(SIGTRAP, ill_sig); ! 1294: signal(SIGIOT, ill_sig); ! 1295: signal(SIGEMT, ill_sig); ! 1296: signal(SIGFPE, ill_sig); ! 1297: signal(SIGBUS, ill_sig); ! 1298: signal(SIGSEGV, ill_sig); ! 1299: signal(SIGSYS, ill_sig); ! 1300: signal(SIGPIPE, ill_sig); ! 1301: #endif ! 1302: #ifdef SYS5 ! 1303: signal(SIGINT, SIG_IGN); ! 1304: signal(SIGQUIT, SIG_IGN); ! 1305: signal(SIGTERM, SIG_IGN); ! 1306: signal(SIGALRM, SIG_IGN); ! 1307: signal(SIGHUP, ill_sig); ! 1308: signal(SIGTRAP, ill_sig); ! 1309: signal(SIGIOT, ill_sig); ! 1310: signal(SIGEMT, ill_sig); ! 1311: signal(SIGFPE, ill_sig); ! 1312: signal(SIGBUS, ill_sig); ! 1313: signal(SIGSEGV, ill_sig); ! 1314: signal(SIGSYS, ill_sig); ! 1315: signal(SIGPIPE, ill_sig); ! 1316: #endif ! 1317: ! 1318: initscr(); /* turn on curses */ ! 1319: noecho(); /* do not echo input */ ! 1320: crmode(); /* do not process erase, kill */ ! 1321: clear(); ! 1322: refresh(); ! 1323: Windows = TRUE; /* mark the state */ ! 1324: } ! 1325: ! 1326: /**/ ! 1327: /************************************************************************ ! 1328: / ! 1329: / FUNCTION NAME: cleanup() ! 1330: / ! 1331: / FUNCTION: close some files, and maybe exit ! 1332: / ! 1333: / AUTHOR: E. A. Estes, 12/4/85 ! 1334: / ! 1335: / ARGUMENTS: ! 1336: / bool doexit - exit flag ! 1337: / ! 1338: / RETURN VALUE: none ! 1339: / ! 1340: / MODULES CALLED: exit(), wmove(), fclose(), endwin(), nocrmode(), wrefresh() ! 1341: / ! 1342: / GLOBAL INPUTS: *Energyvoidfp, LINES, *stdscr, Windows, *Monstfp, ! 1343: / *Messagefp, *Playersfp ! 1344: / ! 1345: / GLOBAL OUTPUTS: none ! 1346: / ! 1347: / DESCRIPTION: ! 1348: / Close all open files. If we are "in curses" terminate curses. ! 1349: / If 'doexit' is set, exit, otherwise return. ! 1350: / ! 1351: /************************************************************************/ ! 1352: ! 1353: cleanup(doexit) ! 1354: bool doexit; ! 1355: { ! 1356: if (Windows) ! 1357: { ! 1358: move(LINES - 2, 0); ! 1359: refresh(); ! 1360: nocrmode(); ! 1361: endwin(); ! 1362: } ! 1363: ! 1364: fclose(Playersfp); ! 1365: fclose(Monstfp); ! 1366: fclose(Messagefp); ! 1367: fclose(Energyvoidfp); ! 1368: ! 1369: if (doexit) ! 1370: exit(0); ! 1371: /*NOTREACHED*/ ! 1372: } ! 1373: /**/ ! 1374: #ifdef OK_TO_PLAY ! 1375: #include <sys/types.h> ! 1376: #include <utmp.h> /* used for counting users on system */ ! 1377: ! 1378: /************************************************************************ ! 1379: / ! 1380: / FUNCTION NAME: ok_to_play() ! 1381: / ! 1382: / FUNCTION: indicate whether playing is allowed ! 1383: / ! 1384: / AUTHOR: E. A. Estes, 12/4/85 ! 1385: / ! 1386: / ARGUMENTS: none ! 1387: / ! 1388: / RETURN VALUE: ! 1389: / FALSE if playing is not allowed ! 1390: / TRUE if playing is allowed ! 1391: / ! 1392: / MODULES CALLED: time(), fread(), fopen(), fclose(), localtime() ! 1393: / ! 1394: / GLOBAL INPUTS: Wizard, Okcount ! 1395: / ! 1396: / GLOBAL OUTPUTS: Okcount ! 1397: / ! 1398: / DESCRIPTION: ! 1399: / This function is provided to allow one to restrict access to the game. ! 1400: / Tailor this routine as appropriate. ! 1401: / Return FALSE if playing is not allowed at this time. ! 1402: / ! 1403: /************************************************************************/ ! 1404: ! 1405: ok_to_play() ! 1406: { ! 1407: register struct tm *tp; /* to get time of day */ ! 1408: register int numusers = 0; /* number of users on system */ ! 1409: FILE *fp; /* to open files */ ! 1410: long now; /* present time */ ! 1411: struct utmp ubuf; /* to read 'utmp' file */ ! 1412: ! 1413: if (Wizard) ! 1414: /* wizard can always play */ ! 1415: return(TRUE); ! 1416: ! 1417: if (Okcount >= 5) ! 1418: Okcount = 0; ! 1419: if (Okcount++ > 0) ! 1420: /* only check every 5 times */ ! 1421: return(TRUE); ! 1422: ! 1423: /* check time of day */ ! 1424: time(&now); ! 1425: tp = localtime(&now); ! 1426: if (((tp->tm_hour > 8 && tp->tm_hour < 12) /* 8-noon */ ! 1427: || (tp->tm_hour > 12 && tp->tm_hour < 16)) /* 1-4 pm */ ! 1428: && (tp->tm_wday != 0 && tp->tm_wday != 6)) /* not a weekend */ ! 1429: return(FALSE); ! 1430: ! 1431: /* check # of users */ ! 1432: if ((fp = fopen("/etc/utmp", "r")) != NULL) ! 1433: { ! 1434: while (fread((char *) &ubuf, sizeof(ubuf), 1, fp) == 1) ! 1435: #ifdef SYS5 ! 1436: if (ubuf.ut_type == USER_PROCESS) ! 1437: #else ! 1438: if (ubuf.ut_name[0] != '\0') ! 1439: #endif ! 1440: ++numusers; ! 1441: fclose(fp); ! 1442: ! 1443: if (numusers > N_MAXUSERS) ! 1444: return(FALSE); ! 1445: } ! 1446: return(TRUE); ! 1447: } ! 1448: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.