1*0e5bc969Sandvar /* $NetBSD: main.c,v 1.25 2022/06/27 22:41:28 andvar Exp $ */
2dcfebd78Scgd
386a62b8dSjtc /*
486a62b8dSjtc * Phantasia 3.3.2 -- Interterminal fantasy game
586a62b8dSjtc *
686a62b8dSjtc * Edward A. Estes
786a62b8dSjtc * AT&T, March 12, 1986
886a62b8dSjtc */
986a62b8dSjtc
1086a62b8dSjtc /* DISCLAIMER:
1186a62b8dSjtc *
1286a62b8dSjtc * This game is distributed for free as is. It is not guaranteed to work
1386a62b8dSjtc * in every conceivable environment. It is not even guaranteed to work
1486a62b8dSjtc * in ANY environment.
1586a62b8dSjtc *
1686a62b8dSjtc * This game is distributed without notice of copyright, therefore it
1786a62b8dSjtc * may be used in any manner the recipient sees fit. However, the
1886a62b8dSjtc * author assumes no responsibility for maintaining or revising this
1986a62b8dSjtc * game, in its original form, or any derivitives thereof.
2086a62b8dSjtc *
2186a62b8dSjtc * The author shall not be responsible for any loss, cost, or damage,
2286a62b8dSjtc * including consequential damage, caused by reliance on this material.
2386a62b8dSjtc *
2486a62b8dSjtc * The author makes no warranties, express or implied, including warranties
2586a62b8dSjtc * of merchantability or fitness for a particular purpose or use.
2686a62b8dSjtc *
2786a62b8dSjtc * AT&T is in no way connected with this game.
2886a62b8dSjtc */
2986a62b8dSjtc
3086a62b8dSjtc #include <sys/types.h>
31e28fc908Sdholland #include <sys/stat.h>
320cf018c1Sdholland #include <err.h>
33e28fc908Sdholland #include <math.h>
3486a62b8dSjtc #include <pwd.h>
35e28fc908Sdholland #include <setjmp.h>
36e28fc908Sdholland #include <stdio.h>
37e28fc908Sdholland #include <stdlib.h>
38e28fc908Sdholland #include <string.h>
39e28fc908Sdholland #include <unistd.h>
40e28fc908Sdholland
41e28fc908Sdholland #include "macros.h"
42e28fc908Sdholland #include "phantdefs.h"
43e28fc908Sdholland #include "phantstruct.h"
44e28fc908Sdholland #include "phantglobs.h"
45e28fc908Sdholland #include "pathnames.h"
46e28fc908Sdholland
47e28fc908Sdholland #undef bool
48e28fc908Sdholland #include <curses.h>
4986a62b8dSjtc
5086a62b8dSjtc /*
5186a62b8dSjtc * The program allocates as much file space as it needs to store characters,
5286a62b8dSjtc * so the possibility exists for the character file to grow without bound.
5386a62b8dSjtc * The file is purged upon normal entry to try to avoid that problem.
5486a62b8dSjtc * A similar problem exists for energy voids. To alleviate the problem here,
5586a62b8dSjtc * the void file is cleared with every new king, and a limit is placed
5686a62b8dSjtc * on the size of the energy void file.
5786a62b8dSjtc */
5886a62b8dSjtc
5986a62b8dSjtc /*
6086a62b8dSjtc * Put one line of text into the file 'motd' for announcements, etc.
6186a62b8dSjtc */
6286a62b8dSjtc
6386a62b8dSjtc /*
6486a62b8dSjtc * The scoreboard file is updated when someone dies, and keeps track
6586a62b8dSjtc * of the highest character to date for that login.
6686a62b8dSjtc * Being purged from the character file does not cause the scoreboard
6786a62b8dSjtc * to be updated.
6886a62b8dSjtc */
6986a62b8dSjtc
7086a62b8dSjtc
7186a62b8dSjtc /*
7286a62b8dSjtc * main.c Main routines for Phantasia
7386a62b8dSjtc */
7486a62b8dSjtc
755305281bSdholland static void genchar(int);
765305281bSdholland static void initialstate(void);
775305281bSdholland static void neatstuff(void);
785305281bSdholland static void playinit(void);
795305281bSdholland static void procmain(void);
805305281bSdholland static long recallplayer(void);
815305281bSdholland static long rollnewplayer(void);
825305281bSdholland static void titlelist(void);
835305281bSdholland
8473a79751Swiz int main(int, char **);
8586a62b8dSjtc
86a232aee2Slukem int
main(int argc,char ** argv)87c7a109ccSdholland main(int argc, char **argv)
8886a62b8dSjtc {
8986a62b8dSjtc bool noheader = FALSE; /* set if don't want header */
9086a62b8dSjtc bool headeronly = FALSE; /* set if only want header */
9186a62b8dSjtc bool examine = FALSE; /* set if examine a character */
92c4816c32Scgd time_t seconds; /* for time of day */
9386a62b8dSjtc double dtemp; /* for temporary calculations */
9486a62b8dSjtc
9586a62b8dSjtc initialstate(); /* init globals */
9686a62b8dSjtc
9786a62b8dSjtc /* process arguments */
9886a62b8dSjtc while (--argc && (*++argv)[0] == '-')
99a232aee2Slukem switch ((*argv)[1]) {
10086a62b8dSjtc case 's': /* short */
10186a62b8dSjtc noheader = TRUE;
10286a62b8dSjtc break;
10386a62b8dSjtc
10486a62b8dSjtc case 'H': /* Header */
10586a62b8dSjtc headeronly = TRUE;
10686a62b8dSjtc break;
10786a62b8dSjtc
10886a62b8dSjtc case 'a': /* all users */
10986a62b8dSjtc activelist();
11086a62b8dSjtc cleanup(TRUE);
111fbffadb9Smrg __unreachable();
11286a62b8dSjtc /* NOTREACHED */
11386a62b8dSjtc
11486a62b8dSjtc case 'p': /* purge old players */
11586a62b8dSjtc purgeoldplayers();
11686a62b8dSjtc cleanup(TRUE);
117fbffadb9Smrg __unreachable();
11886a62b8dSjtc /* NOTREACHED */
11986a62b8dSjtc
12086a62b8dSjtc case 'S': /* set 'Wizard' */
12186a62b8dSjtc Wizard = !getuid();
12286a62b8dSjtc break;
12386a62b8dSjtc
12486a62b8dSjtc case 'x': /* examine */
12586a62b8dSjtc examine = TRUE;
12686a62b8dSjtc break;
12786a62b8dSjtc
12886a62b8dSjtc case 'm': /* monsters */
12986a62b8dSjtc monstlist();
13086a62b8dSjtc cleanup(TRUE);
131fbffadb9Smrg __unreachable();
13286a62b8dSjtc /* NOTREACHED */
13386a62b8dSjtc
13486a62b8dSjtc case 'b': /* scoreboard */
13586a62b8dSjtc scorelist();
13686a62b8dSjtc cleanup(TRUE);
137fbffadb9Smrg __unreachable();
13886a62b8dSjtc /* NOTREACHED */
13986a62b8dSjtc }
14086a62b8dSjtc
14186a62b8dSjtc if (!isatty(0)) /* don't let non-tty's play */
14286a62b8dSjtc cleanup(TRUE);
14386a62b8dSjtc /* NOTREACHED */
14486a62b8dSjtc
14586a62b8dSjtc playinit(); /* set up to catch signals, init curses */
14686a62b8dSjtc
147a232aee2Slukem if (examine) {
14886a62b8dSjtc changestats(FALSE);
14986a62b8dSjtc cleanup(TRUE);
150fbffadb9Smrg __unreachable();
15186a62b8dSjtc /* NOTREACHED */
15286a62b8dSjtc }
153a232aee2Slukem if (!noheader) {
15486a62b8dSjtc titlelist();
15586a62b8dSjtc purgeoldplayers(); /* clean up old characters */
15686a62b8dSjtc }
157fbffadb9Smrg if (headeronly) {
15886a62b8dSjtc cleanup(TRUE);
159fbffadb9Smrg __unreachable();
16086a62b8dSjtc /* NOTREACHED */
161fbffadb9Smrg }
16286a62b8dSjtc
16386a62b8dSjtc do
16486a62b8dSjtc /* get the player structure filled */
16586a62b8dSjtc {
16686a62b8dSjtc Fileloc = -1L;
16786a62b8dSjtc
16886a62b8dSjtc mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? ");
16986a62b8dSjtc
170a232aee2Slukem switch (getanswer("NYQ", FALSE)) {
17186a62b8dSjtc case 'Y':
17286a62b8dSjtc Fileloc = recallplayer();
17386a62b8dSjtc break;
17486a62b8dSjtc
17586a62b8dSjtc case 'Q':
17686a62b8dSjtc cleanup(TRUE);
177fbffadb9Smrg __unreachable();
17886a62b8dSjtc /* NOTREACHED */
17986a62b8dSjtc
18086a62b8dSjtc default:
18186a62b8dSjtc Fileloc = rollnewplayer();
18286a62b8dSjtc break;
18386a62b8dSjtc }
18486a62b8dSjtc clear();
18586a62b8dSjtc }
18686a62b8dSjtc while (Fileloc < 0L);
18786a62b8dSjtc
18886a62b8dSjtc if (Player.p_level > 5.0)
18986a62b8dSjtc /* low level players have long timeout */
19086a62b8dSjtc Timeout = TRUE;
19186a62b8dSjtc
19286a62b8dSjtc /* update some important player statistics */
193bee0eddcSdholland strlcpy(Player.p_login, Login, sizeof(Player.p_login));
19486a62b8dSjtc time(&seconds);
19586a62b8dSjtc Player.p_lastused = localtime(&seconds)->tm_yday;
19686a62b8dSjtc Player.p_status = S_PLAYING;
19786a62b8dSjtc writerecord(&Player, Fileloc);
19886a62b8dSjtc
19986a62b8dSjtc Statptr = &Stattable[Player.p_type]; /* initialize pointer */
20086a62b8dSjtc
20186a62b8dSjtc /* catch interrupts */
20286a62b8dSjtc #ifdef BSD41
20386a62b8dSjtc sigset(SIGINT, interrupt);
20486a62b8dSjtc #endif
20586a62b8dSjtc #ifdef BSD42
20686a62b8dSjtc signal(SIGINT, interrupt);
20786a62b8dSjtc #endif
20886a62b8dSjtc #ifdef SYS3
20986a62b8dSjtc signal(SIGINT, interrupt);
21086a62b8dSjtc #endif
21186a62b8dSjtc #ifdef SYS5
21286a62b8dSjtc signal(SIGINT, interrupt);
21386a62b8dSjtc #endif
21486a62b8dSjtc
21586a62b8dSjtc altercoordinates(Player.p_x, Player.p_y, A_FORCED); /* set some flags */
21686a62b8dSjtc
21786a62b8dSjtc clear();
21886a62b8dSjtc
21986a62b8dSjtc for (;;)
22086a62b8dSjtc /* loop forever, processing input */
22186a62b8dSjtc {
22286a62b8dSjtc
22386a62b8dSjtc adjuststats(); /* cleanup stats */
22486a62b8dSjtc
22586a62b8dSjtc if (Throne && Player.p_crowns == 0 && Player.p_specialtype != SC_KING)
22686a62b8dSjtc /* not allowed on throne -- move */
22786a62b8dSjtc {
22886a62b8dSjtc mvaddstr(5, 0, "You're not allowed in the Lord's Chamber without a crown.\n");
22986a62b8dSjtc altercoordinates(0.0, 0.0, A_NEAR);
23086a62b8dSjtc }
23186a62b8dSjtc checktampered();/* check for energy voids, etc. */
23286a62b8dSjtc
23386a62b8dSjtc if (Player.p_status != S_CLOAKED
23486a62b8dSjtc /* not cloaked */
23586a62b8dSjtc && (dtemp = fabs(Player.p_x)) == fabs(Player.p_y)
23686a62b8dSjtc /* |x| = |y| */
23786a62b8dSjtc && !Throne)
23886a62b8dSjtc /* not on throne */
23986a62b8dSjtc {
24086a62b8dSjtc dtemp = sqrt(dtemp / 100.0);
24186a62b8dSjtc if (floor(dtemp) == dtemp)
24286a62b8dSjtc /* |x| / 100 == n*n; at a trading post */
24386a62b8dSjtc {
24486a62b8dSjtc tradingpost();
24586a62b8dSjtc clear();
24686a62b8dSjtc }
24786a62b8dSjtc }
24886a62b8dSjtc checkbattle(); /* check for player to player battle */
24986a62b8dSjtc neatstuff(); /* gurus, medics, etc. */
25086a62b8dSjtc
25104afeca6Sveego if (Player.p_status == S_CLOAKED) {
25286a62b8dSjtc /* costs 3 mana per turn to be cloaked */
25386a62b8dSjtc if (Player.p_mana > 3.0)
25486a62b8dSjtc Player.p_mana -= 3.0;
25586a62b8dSjtc else
25686a62b8dSjtc /* ran out of mana, uncloak */
25786a62b8dSjtc {
25886a62b8dSjtc Player.p_status = S_PLAYING;
25986a62b8dSjtc Changed = TRUE;
26086a62b8dSjtc }
26104afeca6Sveego }
26286a62b8dSjtc
26386a62b8dSjtc if (Player.p_status != S_PLAYING && Player.p_status != S_CLOAKED)
26486a62b8dSjtc /* change status back to S_PLAYING */
26586a62b8dSjtc {
26686a62b8dSjtc Player.p_status = S_PLAYING;
26786a62b8dSjtc Changed = TRUE;
26886a62b8dSjtc }
26986a62b8dSjtc if (Changed)
27086a62b8dSjtc /* update file only if important stuff has changed */
27186a62b8dSjtc {
27286a62b8dSjtc writerecord(&Player, Fileloc);
27386a62b8dSjtc Changed = FALSE;
27486a62b8dSjtc continue;
27586a62b8dSjtc }
27686a62b8dSjtc readmessage(); /* read message, if any */
27786a62b8dSjtc
27886a62b8dSjtc displaystats(); /* print statistics */
27986a62b8dSjtc
28086a62b8dSjtc move(6, 0);
28186a62b8dSjtc
28286a62b8dSjtc if (Throne)
28386a62b8dSjtc /* maybe make king, print prompt, etc. */
28486a62b8dSjtc throneroom();
28586a62b8dSjtc
28686a62b8dSjtc /* print status line */
28786a62b8dSjtc addstr("1:Move 2:Players 3:Talk 4:Stats 5:Quit ");
28886a62b8dSjtc if (Player.p_level >= MEL_CLOAK && Player.p_magiclvl >= ML_CLOAK)
28986a62b8dSjtc addstr("6:Cloak ");
29086a62b8dSjtc if (Player.p_level >= MEL_TELEPORT && Player.p_magiclvl >= ML_TELEPORT)
29186a62b8dSjtc addstr("7:Teleport ");
29286a62b8dSjtc if (Player.p_specialtype >= SC_COUNCIL || Wizard)
29386a62b8dSjtc addstr("8:Intervene ");
29486a62b8dSjtc
29586a62b8dSjtc procmain(); /* process input */
29686a62b8dSjtc }
29786a62b8dSjtc }
29886a62b8dSjtc
2995305281bSdholland static void
initialstate(void)300c7a109ccSdholland initialstate(void)
30186a62b8dSjtc {
30227984797Sjmc struct stat sb;
3030cf018c1Sdholland struct passwd *pw;
30427984797Sjmc
30586a62b8dSjtc Beyond = FALSE;
30686a62b8dSjtc Marsh = FALSE;
30786a62b8dSjtc Throne = FALSE;
30886a62b8dSjtc Changed = FALSE;
30986a62b8dSjtc Wizard = FALSE;
31086a62b8dSjtc Timeout = FALSE;
31186a62b8dSjtc Users = 0;
31286a62b8dSjtc Windows = FALSE;
31386a62b8dSjtc Echo = TRUE;
31486a62b8dSjtc
31586a62b8dSjtc /* setup login name */
3160cf018c1Sdholland if ((Login = getlogin()) == NULL) {
3170cf018c1Sdholland pw = getpwuid(getuid());
3180cf018c1Sdholland if (pw == NULL) {
3190cf018c1Sdholland errx(1, "Who are you?");
3200cf018c1Sdholland }
3210cf018c1Sdholland Login = pw->pw_name;
3220cf018c1Sdholland }
32386a62b8dSjtc
32486a62b8dSjtc /* open some files */
32586a62b8dSjtc if ((Playersfp = fopen(_PATH_PEOPLE, "r+")) == NULL)
32686a62b8dSjtc error(_PATH_PEOPLE);
32786a62b8dSjtc /* NOTREACHED */
3287dc5308dSjsm if (fileno(Playersfp) < 3)
3297dc5308dSjsm exit(1);
33086a62b8dSjtc
33186a62b8dSjtc if ((Monstfp = fopen(_PATH_MONST, "r+")) == NULL)
33286a62b8dSjtc error(_PATH_MONST);
33386a62b8dSjtc /* NOTREACHED */
33486a62b8dSjtc
33586a62b8dSjtc if ((Messagefp = fopen(_PATH_MESS, "r")) == NULL)
33686a62b8dSjtc error(_PATH_MESS);
33786a62b8dSjtc /* NOTREACHED */
33886a62b8dSjtc
33986a62b8dSjtc if ((Energyvoidfp = fopen(_PATH_VOID, "r+")) == NULL)
34086a62b8dSjtc error(_PATH_VOID);
34127984797Sjmc if (fstat(fileno(Energyvoidfp), &sb) == -1)
34227984797Sjmc error("stat");
34327984797Sjmc if (sb.st_size == 0) {
34427984797Sjmc /* initialize grail to new location */
34527984797Sjmc Enrgyvoid.ev_active = TRUE;
34627984797Sjmc Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
34727984797Sjmc Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
34827984797Sjmc writevoid(&Enrgyvoid, 0L);
34927984797Sjmc }
35027984797Sjmc
35186a62b8dSjtc /* NOTREACHED */
35286a62b8dSjtc
353c4816c32Scgd srandom((unsigned) time(NULL)); /* prime random numbers */
35486a62b8dSjtc }
35586a62b8dSjtc
3565305281bSdholland static long
rollnewplayer(void)357c7a109ccSdholland rollnewplayer(void)
35886a62b8dSjtc {
35986a62b8dSjtc int chartype; /* character type */
36086a62b8dSjtc int ch; /* input */
36186a62b8dSjtc
36286a62b8dSjtc initplayer(&Player); /* initialize player structure */
36386a62b8dSjtc
36486a62b8dSjtc clear();
36586a62b8dSjtc mvaddstr(4, 21, "Which type of character do you want:");
366a232aee2Slukem mvaddstr(8, 4,
367a232aee2Slukem "1:Magic User 2:Fighter 3:Elf 4:Dwarf 5:Halfling 6:Experimento ");
36886a62b8dSjtc if (Wizard) {
36986a62b8dSjtc addstr("7:Super ? ");
37086a62b8dSjtc chartype = getanswer("1234567", FALSE);
371a232aee2Slukem } else {
37286a62b8dSjtc addstr("? ");
37386a62b8dSjtc chartype = getanswer("123456", FALSE);
37486a62b8dSjtc }
37586a62b8dSjtc
376a232aee2Slukem do {
37786a62b8dSjtc genchar(chartype); /* roll up a character */
37886a62b8dSjtc
37986a62b8dSjtc /* print out results */
38086a62b8dSjtc mvprintw(12, 14,
38186a62b8dSjtc "Strength : %2.0f Quickness: %2.0f Mana : %2.0f\n",
38286a62b8dSjtc Player.p_strength, Player.p_quickness, Player.p_mana);
38386a62b8dSjtc mvprintw(13, 14,
38486a62b8dSjtc "Energy Level: %2.0f Brains : %2.0f Magic Level: %2.0f\n",
38586a62b8dSjtc Player.p_energy, Player.p_brains, Player.p_magiclvl);
38686a62b8dSjtc
38786a62b8dSjtc if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
38886a62b8dSjtc break;
38986a62b8dSjtc
39086a62b8dSjtc mvaddstr(14, 14, "Type '1' to keep >");
39186a62b8dSjtc ch = getanswer(" ", TRUE);
39286a62b8dSjtc }
39386a62b8dSjtc while (ch != '1');
39486a62b8dSjtc
39586a62b8dSjtc if (Player.p_type == C_EXPER || Player.p_type == C_SUPER)
39686a62b8dSjtc /* get coordinates for experimento */
397a232aee2Slukem for (;;) {
39886a62b8dSjtc mvaddstr(16, 0, "Enter the X Y coordinates of your experimento ? ");
39986a62b8dSjtc getstring(Databuf, SZ_DATABUF);
40086a62b8dSjtc sscanf(Databuf, "%lf %lf", &Player.p_x, &Player.p_y);
40186a62b8dSjtc
40286a62b8dSjtc if (fabs(Player.p_x) > D_EXPER || fabs(Player.p_y) > D_EXPER)
40386a62b8dSjtc mvaddstr(17, 0, "Invalid coordinates. Try again.\n");
40486a62b8dSjtc else
40586a62b8dSjtc break;
40686a62b8dSjtc }
40786a62b8dSjtc
40886a62b8dSjtc for (;;)
40986a62b8dSjtc /* name the new character */
41086a62b8dSjtc {
41186a62b8dSjtc mvprintw(18, 0,
41286a62b8dSjtc "Give your character a name [up to %d characters] ? ", SZ_NAME - 1);
41386a62b8dSjtc getstring(Player.p_name, SZ_NAME);
41486a62b8dSjtc truncstring(Player.p_name); /* remove trailing blanks */
41586a62b8dSjtc
41686a62b8dSjtc if (Player.p_name[0] == '\0')
41786a62b8dSjtc /* no null names */
41886a62b8dSjtc mvaddstr(19, 0, "Invalid name.");
419a232aee2Slukem else
420a232aee2Slukem if (findname(Player.p_name, &Other) >= 0L)
42186a62b8dSjtc /* cannot have duplicate names */
42286a62b8dSjtc mvaddstr(19, 0, "Name already in use.");
42386a62b8dSjtc else
42486a62b8dSjtc /* name is acceptable */
42586a62b8dSjtc break;
42686a62b8dSjtc
42786a62b8dSjtc addstr(" Pick another.\n");
42886a62b8dSjtc }
42986a62b8dSjtc
43086a62b8dSjtc /* get a password for character */
43186a62b8dSjtc Echo = FALSE;
43286a62b8dSjtc
433a232aee2Slukem do {
43486a62b8dSjtc mvaddstr(20, 0, "Give your character a password [up to 8 characters] ? ");
43586a62b8dSjtc getstring(Player.p_password, SZ_PASSWORD);
43696651fe7Shubertf mvaddstr(21, 0, "Enter again to verify: ");
43786a62b8dSjtc getstring(Databuf, SZ_PASSWORD);
43886a62b8dSjtc }
43986a62b8dSjtc while (strcmp(Player.p_password, Databuf) != 0);
44086a62b8dSjtc
44186a62b8dSjtc Echo = TRUE;
44286a62b8dSjtc
44386a62b8dSjtc return (allocrecord());
44486a62b8dSjtc }
44586a62b8dSjtc
4465305281bSdholland static void
procmain(void)447c7a109ccSdholland procmain(void)
44886a62b8dSjtc {
44986a62b8dSjtc int ch; /* input */
45086a62b8dSjtc double x; /* desired new x coordinate */
45186a62b8dSjtc double y; /* desired new y coordinate */
45286a62b8dSjtc double temp; /* for temporary calculations */
45386a62b8dSjtc FILE *fp; /* for opening files */
454a232aee2Slukem int loop; /* a loop counter */
45586a62b8dSjtc bool hasmoved = FALSE; /* set if player has moved */
45686a62b8dSjtc
45786a62b8dSjtc ch = inputoption();
45886a62b8dSjtc mvaddstr(4, 0, "\n\n"); /* clear status area */
45986a62b8dSjtc
46086a62b8dSjtc move(7, 0);
46186a62b8dSjtc clrtobot(); /* clear data on bottom area of screen */
46286a62b8dSjtc
46386a62b8dSjtc if (Player.p_specialtype == SC_VALAR && (ch == '1' || ch == '7'))
46486a62b8dSjtc /* valar cannot move */
46586a62b8dSjtc ch = ' ';
46686a62b8dSjtc
467a232aee2Slukem switch (ch) {
46886a62b8dSjtc case 'K': /* move up/north */
46986a62b8dSjtc case 'N':
47086a62b8dSjtc x = Player.p_x;
47186a62b8dSjtc y = Player.p_y + MAXMOVE();
47286a62b8dSjtc hasmoved = TRUE;
47386a62b8dSjtc break;
47486a62b8dSjtc
47586a62b8dSjtc case 'J': /* move down/south */
47686a62b8dSjtc case 'S':
47786a62b8dSjtc x = Player.p_x;
47886a62b8dSjtc y = Player.p_y - MAXMOVE();
47986a62b8dSjtc hasmoved = TRUE;
48086a62b8dSjtc break;
48186a62b8dSjtc
48286a62b8dSjtc case 'L': /* move right/east */
48386a62b8dSjtc case 'E':
48486a62b8dSjtc x = Player.p_x + MAXMOVE();
48586a62b8dSjtc y = Player.p_y;
48686a62b8dSjtc hasmoved = TRUE;
48786a62b8dSjtc break;
48886a62b8dSjtc
48986a62b8dSjtc case 'H': /* move left/west */
49086a62b8dSjtc case 'W':
49186a62b8dSjtc x = Player.p_x - MAXMOVE();
49286a62b8dSjtc y = Player.p_y;
49386a62b8dSjtc hasmoved = TRUE;
49486a62b8dSjtc break;
49586a62b8dSjtc
49686a62b8dSjtc default: /* rest */
49786a62b8dSjtc Player.p_energy += (Player.p_maxenergy + Player.p_shield) / 15.0
49886a62b8dSjtc + Player.p_level / 3.0 + 2.0;
49986a62b8dSjtc Player.p_energy =
50086a62b8dSjtc MIN(Player.p_energy, Player.p_maxenergy + Player.p_shield);
50186a62b8dSjtc
50286a62b8dSjtc if (Player.p_status != S_CLOAKED)
50386a62b8dSjtc /* cannot find mana if cloaked */
50486a62b8dSjtc {
50586a62b8dSjtc Player.p_mana += (Circle + Player.p_level) / 4.0;
50686a62b8dSjtc
50786a62b8dSjtc if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
50886a62b8dSjtc /* wandering monster */
50986a62b8dSjtc encounter(-1);
51086a62b8dSjtc }
51186a62b8dSjtc break;
51286a62b8dSjtc
51386a62b8dSjtc case 'X': /* change/examine a character */
51486a62b8dSjtc changestats(TRUE);
51586a62b8dSjtc break;
51686a62b8dSjtc
51786a62b8dSjtc case '1': /* move */
518a232aee2Slukem for (loop = 3; loop; --loop) {
51986a62b8dSjtc mvaddstr(4, 0, "X Y Coordinates ? ");
52086a62b8dSjtc getstring(Databuf, SZ_DATABUF);
52186a62b8dSjtc
52286a62b8dSjtc if (sscanf(Databuf, "%lf %lf", &x, &y) != 2)
52386a62b8dSjtc mvaddstr(5, 0, "Try again\n");
52486a62b8dSjtc else
525a232aee2Slukem if (distance(Player.p_x, x, Player.p_y, y) > MAXMOVE())
526a232aee2Slukem ILLMOVE();
527a232aee2Slukem else {
52886a62b8dSjtc hasmoved = TRUE;
52986a62b8dSjtc break;
53086a62b8dSjtc }
53186a62b8dSjtc }
53286a62b8dSjtc break;
53386a62b8dSjtc
53486a62b8dSjtc case '2': /* players */
53586a62b8dSjtc userlist(TRUE);
53686a62b8dSjtc break;
53786a62b8dSjtc
53886a62b8dSjtc case '3': /* message */
53986a62b8dSjtc mvaddstr(4, 0, "Message ? ");
54086a62b8dSjtc getstring(Databuf, SZ_DATABUF);
541a232aee2Slukem /* we open the file for writing to erase any data which is
542a232aee2Slukem * already there */
54386a62b8dSjtc fp = fopen(_PATH_MESS, "w");
54486a62b8dSjtc if (Databuf[0] != '\0')
54586a62b8dSjtc fprintf(fp, "%s: %s", Player.p_name, Databuf);
54686a62b8dSjtc fclose(fp);
54786a62b8dSjtc break;
54886a62b8dSjtc
54986a62b8dSjtc case '4': /* stats */
55086a62b8dSjtc allstatslist();
55186a62b8dSjtc break;
55286a62b8dSjtc
55386a62b8dSjtc case '5': /* good-bye */
55486a62b8dSjtc leavegame();
555fbffadb9Smrg __unreachable();
55686a62b8dSjtc /* NOTREACHED */
55786a62b8dSjtc
55886a62b8dSjtc case '6': /* cloak */
55986a62b8dSjtc if (Player.p_level < MEL_CLOAK || Player.p_magiclvl < ML_CLOAK)
56086a62b8dSjtc ILLCMD();
56186a62b8dSjtc else
562a232aee2Slukem if (Player.p_status == S_CLOAKED)
563a232aee2Slukem Player.p_status = S_PLAYING;
564a232aee2Slukem else
565a232aee2Slukem if (Player.p_mana < MM_CLOAK)
566a232aee2Slukem mvaddstr(5, 0, "No mana left.\n");
567a232aee2Slukem else {
56886a62b8dSjtc Changed = TRUE;
56986a62b8dSjtc Player.p_mana -= MM_CLOAK;
57086a62b8dSjtc Player.p_status = S_CLOAKED;
57186a62b8dSjtc }
57286a62b8dSjtc break;
57386a62b8dSjtc
57486a62b8dSjtc case '7': /* teleport */
57586a62b8dSjtc /*
57686a62b8dSjtc * conditions for teleport
57786a62b8dSjtc * - 20 per (level plus magic level)
57886a62b8dSjtc * - OR council of the wise or valar or ex-valar
57986a62b8dSjtc * - OR transport from throne
58086a62b8dSjtc * transports from throne cost no mana
58186a62b8dSjtc */
58286a62b8dSjtc if (Player.p_level < MEL_TELEPORT || Player.p_magiclvl < ML_TELEPORT)
58386a62b8dSjtc ILLCMD();
58486a62b8dSjtc else
585a232aee2Slukem for (loop = 3; loop; --loop) {
58686a62b8dSjtc mvaddstr(4, 0, "X Y Coordinates ? ");
58786a62b8dSjtc getstring(Databuf, SZ_DATABUF);
58886a62b8dSjtc
589a232aee2Slukem if (sscanf(Databuf, "%lf %lf", &x, &y) == 2) {
59086a62b8dSjtc temp = distance(Player.p_x, x, Player.p_y, y);
59186a62b8dSjtc if (!Throne
59286a62b8dSjtc /* can transport anywhere from throne */
59386a62b8dSjtc && Player.p_specialtype <= SC_COUNCIL
594a232aee2Slukem /* council, valar can transport
595a232aee2Slukem * anywhere */
59686a62b8dSjtc && temp > (Player.p_level + Player.p_magiclvl) * 20.0)
597a232aee2Slukem /* can only move 20 per exp.
598a232aee2Slukem * level + mag. level */
59986a62b8dSjtc ILLMOVE();
600a232aee2Slukem else {
60186a62b8dSjtc temp = (temp / 75.0 + 1.0) * 20.0; /* mana used */
60286a62b8dSjtc
60386a62b8dSjtc if (!Throne && temp > Player.p_mana)
60486a62b8dSjtc mvaddstr(5, 0, "Not enough power for that distance.\n");
605a232aee2Slukem else {
60686a62b8dSjtc if (!Throne)
60786a62b8dSjtc Player.p_mana -= temp;
60886a62b8dSjtc hasmoved = TRUE;
60986a62b8dSjtc break;
61086a62b8dSjtc }
61186a62b8dSjtc }
61286a62b8dSjtc }
61386a62b8dSjtc }
61486a62b8dSjtc break;
61586a62b8dSjtc
61686a62b8dSjtc case 'C':
61786a62b8dSjtc case '9': /* monster */
61886a62b8dSjtc if (Throne)
61986a62b8dSjtc /* no monsters while on throne */
62086a62b8dSjtc mvaddstr(5, 0, "No monsters in the chamber!\n");
621a232aee2Slukem else
622a232aee2Slukem if (Player.p_specialtype != SC_VALAR)
62386a62b8dSjtc /* the valar cannot call monsters */
62486a62b8dSjtc {
62586a62b8dSjtc Player.p_sin += 1e-6;
62686a62b8dSjtc encounter(-1);
62786a62b8dSjtc }
62886a62b8dSjtc break;
62986a62b8dSjtc
63086a62b8dSjtc case '0': /* decree */
631a232aee2Slukem if (Wizard || (Player.p_specialtype == SC_KING && Throne))
63286a62b8dSjtc /* kings must be on throne to decree */
63386a62b8dSjtc dotampered();
63486a62b8dSjtc else
63586a62b8dSjtc ILLCMD();
63686a62b8dSjtc break;
63786a62b8dSjtc
63886a62b8dSjtc case '8': /* intervention */
63986a62b8dSjtc if (Wizard || Player.p_specialtype >= SC_COUNCIL)
64086a62b8dSjtc dotampered();
64186a62b8dSjtc else
64286a62b8dSjtc ILLCMD();
64386a62b8dSjtc break;
64486a62b8dSjtc }
64586a62b8dSjtc
64686a62b8dSjtc if (hasmoved)
647a232aee2Slukem /* player has moved -- alter coordinates, and do random
648a232aee2Slukem * monster */
64986a62b8dSjtc {
65086a62b8dSjtc altercoordinates(x, y, A_SPECIFIC);
65186a62b8dSjtc
65286a62b8dSjtc if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
65386a62b8dSjtc encounter(-1);
65486a62b8dSjtc }
65586a62b8dSjtc }
65686a62b8dSjtc
6575305281bSdholland static void
titlelist(void)658c7a109ccSdholland titlelist(void)
65986a62b8dSjtc {
660a232aee2Slukem FILE *fp; /* used for opening various files */
661a232aee2Slukem bool councilfound = FALSE; /* set if we find a member of the
662a232aee2Slukem * council */
66386a62b8dSjtc bool kingfound = FALSE; /* set if we find a king */
66486a62b8dSjtc double hiexp, nxtexp; /* used for finding the two highest players */
66586a62b8dSjtc double hilvl, nxtlvl; /* used for finding the two highest players */
666a232aee2Slukem char hiname[21], nxtname[21]; /* used for finding the two
667a232aee2Slukem * highest players */
66886a62b8dSjtc
669a232aee2Slukem nxtexp = 0;
670a232aee2Slukem mvaddstr(0, 14,
671a232aee2Slukem "W e l c o m e t o P h a n t a s i a (vers. 3.3.2)!");
67286a62b8dSjtc
67386a62b8dSjtc /* print message of the day */
67486a62b8dSjtc if ((fp = fopen(_PATH_MOTD, "r")) != NULL
675a232aee2Slukem && fgets(Databuf, SZ_DATABUF, fp) != NULL) {
67686a62b8dSjtc mvaddstr(2, 40 - strlen(Databuf) / 2, Databuf);
67786a62b8dSjtc fclose(fp);
67886a62b8dSjtc }
67986a62b8dSjtc /* search for king */
6805fb18dd9Sjsm fseek(Playersfp, 0L, SEEK_SET);
68186a62b8dSjtc while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
682a232aee2Slukem if (Other.p_specialtype == SC_KING &&
683a232aee2Slukem Other.p_status != S_NOTUSED)
68486a62b8dSjtc /* found the king */
68586a62b8dSjtc {
686ebb769aeSdholland snprintf(Databuf, SZ_DATABUF,
687ebb769aeSdholland "The present ruler is %s Level:%.0f",
68886a62b8dSjtc Other.p_name, Other.p_level);
68986a62b8dSjtc mvaddstr(4, 40 - strlen(Databuf) / 2, Databuf);
69086a62b8dSjtc kingfound = TRUE;
69186a62b8dSjtc break;
69286a62b8dSjtc }
69386a62b8dSjtc if (!kingfound)
69486a62b8dSjtc mvaddstr(4, 24, "There is no ruler at this time.");
69586a62b8dSjtc
69686a62b8dSjtc /* search for valar */
6975fb18dd9Sjsm fseek(Playersfp, 0L, SEEK_SET);
69886a62b8dSjtc while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
69986a62b8dSjtc if (Other.p_specialtype == SC_VALAR && Other.p_status != S_NOTUSED)
70086a62b8dSjtc /* found the valar */
70186a62b8dSjtc {
702ebb769aeSdholland snprintf(Databuf, SZ_DATABUF,
703ebb769aeSdholland "The Valar is %s Login: %s",
704ebb769aeSdholland Other.p_name, Other.p_login);
70586a62b8dSjtc mvaddstr(6, 40 - strlen(Databuf) / 2, Databuf);
70686a62b8dSjtc break;
70786a62b8dSjtc }
70886a62b8dSjtc /* search for council of the wise */
7095fb18dd9Sjsm fseek(Playersfp, 0L, SEEK_SET);
71086a62b8dSjtc Lines = 10;
71186a62b8dSjtc while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
71286a62b8dSjtc if (Other.p_specialtype == SC_COUNCIL && Other.p_status != S_NOTUSED)
71386a62b8dSjtc /* found a member of the council */
71486a62b8dSjtc {
715a232aee2Slukem if (!councilfound) {
71686a62b8dSjtc mvaddstr(8, 30, "Council of the Wise:");
71786a62b8dSjtc councilfound = TRUE;
71886a62b8dSjtc }
71986a62b8dSjtc /* This assumes a finite (<=5) number of C.O.W.: */
720ebb769aeSdholland snprintf(Databuf, SZ_DATABUF,
721ebb769aeSdholland "%s Login: %s", Other.p_name, Other.p_login);
72286a62b8dSjtc mvaddstr(Lines++, 40 - strlen(Databuf) / 2, Databuf);
72386a62b8dSjtc }
72486a62b8dSjtc /* search for the two highest players */
72586a62b8dSjtc nxtname[0] = hiname[0] = '\0';
72686a62b8dSjtc hiexp = 0.0;
72786a62b8dSjtc nxtlvl = hilvl = 0;
72886a62b8dSjtc
7295fb18dd9Sjsm fseek(Playersfp, 0L, SEEK_SET);
73086a62b8dSjtc while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
73186a62b8dSjtc if (Other.p_experience > hiexp && Other.p_specialtype <= SC_KING && Other.p_status != S_NOTUSED)
73286a62b8dSjtc /* highest found so far */
73386a62b8dSjtc {
73486a62b8dSjtc nxtexp = hiexp;
73586a62b8dSjtc hiexp = Other.p_experience;
73686a62b8dSjtc nxtlvl = hilvl;
73786a62b8dSjtc hilvl = Other.p_level;
73886a62b8dSjtc strcpy(nxtname, hiname);
73986a62b8dSjtc strcpy(hiname, Other.p_name);
740a232aee2Slukem } else
741a232aee2Slukem if (Other.p_experience > nxtexp
74286a62b8dSjtc && Other.p_specialtype <= SC_KING
74386a62b8dSjtc && Other.p_status != S_NOTUSED)
74486a62b8dSjtc /* next highest found so far */
74586a62b8dSjtc {
74686a62b8dSjtc nxtexp = Other.p_experience;
74786a62b8dSjtc nxtlvl = Other.p_level;
74886a62b8dSjtc strcpy(nxtname, Other.p_name);
74986a62b8dSjtc }
75086a62b8dSjtc mvaddstr(15, 28, "Highest characters are:");
751ebb769aeSdholland snprintf(Databuf, SZ_DATABUF,
752ebb769aeSdholland "%s Level:%.0f and %s Level:%.0f",
75386a62b8dSjtc hiname, hilvl, nxtname, nxtlvl);
75486a62b8dSjtc mvaddstr(17, 40 - strlen(Databuf) / 2, Databuf);
75586a62b8dSjtc
75686a62b8dSjtc /* print last to die */
75786a62b8dSjtc if ((fp = fopen(_PATH_LASTDEAD, "r")) != NULL
758a232aee2Slukem && fgets(Databuf, SZ_DATABUF, fp) != NULL) {
75986a62b8dSjtc mvaddstr(19, 25, "The last character to die was:");
76086a62b8dSjtc mvaddstr(20, 40 - strlen(Databuf) / 2, Databuf);
76186a62b8dSjtc }
762dad51bf4Schristos if (fp)
763dad51bf4Schristos fclose(fp);
76486a62b8dSjtc refresh();
76586a62b8dSjtc }
76686a62b8dSjtc
7675305281bSdholland static long
recallplayer(void)768c7a109ccSdholland recallplayer(void)
76986a62b8dSjtc {
77086a62b8dSjtc long loc = 0L; /* location in player file */
771a232aee2Slukem int loop; /* loop counter */
77286a62b8dSjtc int ch; /* input */
77386a62b8dSjtc
77486a62b8dSjtc clear();
77586a62b8dSjtc mvprintw(10, 0, "What was your character's name ? ");
77686a62b8dSjtc getstring(Databuf, SZ_NAME);
77786a62b8dSjtc truncstring(Databuf);
77886a62b8dSjtc
77986a62b8dSjtc if ((loc = findname(Databuf, &Player)) >= 0L)
78086a62b8dSjtc /* found character */
78186a62b8dSjtc {
78286a62b8dSjtc Echo = FALSE;
78386a62b8dSjtc
784a232aee2Slukem for (loop = 0; loop < 2; ++loop) {
78586a62b8dSjtc /* prompt for password */
78686a62b8dSjtc mvaddstr(11, 0, "Password ? ");
78786a62b8dSjtc getstring(Databuf, SZ_PASSWORD);
78886a62b8dSjtc if (strcmp(Databuf, Player.p_password) == 0)
78986a62b8dSjtc /* password good */
79086a62b8dSjtc {
79186a62b8dSjtc Echo = TRUE;
79286a62b8dSjtc
79386a62b8dSjtc if (Player.p_status != S_OFF)
794a232aee2Slukem /* player did not exit normally last
795a232aee2Slukem * time */
79686a62b8dSjtc {
79786a62b8dSjtc clear();
79886a62b8dSjtc addstr("Your character did not exit normally last time.\n");
79986a62b8dSjtc addstr("If you think you have good cause to have your character saved,\n");
80086a62b8dSjtc printw("you may quit and mail your reason to 'root'.\n");
80186a62b8dSjtc addstr("Otherwise, continuing spells certain death.\n");
80286a62b8dSjtc addstr("Do you want to quit ? ");
80386a62b8dSjtc ch = getanswer("YN", FALSE);
804a232aee2Slukem if (ch == 'Y') {
80586a62b8dSjtc Player.p_status = S_HUNGUP;
80686a62b8dSjtc writerecord(&Player, loc);
80786a62b8dSjtc cleanup(TRUE);
80886a62b8dSjtc /* NOTREACHED */
80986a62b8dSjtc }
81086a62b8dSjtc death("Stupidity");
81186a62b8dSjtc /* NOTREACHED */
81286a62b8dSjtc }
81386a62b8dSjtc return (loc);
814a232aee2Slukem } else
81586a62b8dSjtc mvaddstr(12, 0, "No good.\n");
81686a62b8dSjtc }
81786a62b8dSjtc
81886a62b8dSjtc Echo = TRUE;
819a232aee2Slukem } else
82086a62b8dSjtc mvaddstr(11, 0, "Not found.\n");
82186a62b8dSjtc
82286a62b8dSjtc more(13);
82386a62b8dSjtc return (-1L);
82486a62b8dSjtc }
82586a62b8dSjtc
8265305281bSdholland static void
neatstuff(void)827c7a109ccSdholland neatstuff(void)
82886a62b8dSjtc {
82986a62b8dSjtc double temp; /* for temporary calculations */
83086a62b8dSjtc int ch; /* input */
83186a62b8dSjtc
832a232aee2Slukem switch ((int) ROLL(0.0, 100.0)) {
83386a62b8dSjtc case 1:
83486a62b8dSjtc case 2:
835a232aee2Slukem if (Player.p_poison > 0.0) {
83686a62b8dSjtc mvaddstr(4, 0, "You've found a medic! How much will you offer to be cured ? ");
83786a62b8dSjtc temp = floor(infloat());
83886a62b8dSjtc if (temp < 0.0 || temp > Player.p_gold)
83986a62b8dSjtc /* negative gold, or more than available */
84086a62b8dSjtc {
84186a62b8dSjtc mvaddstr(6, 0, "He was not amused, and made you worse.\n");
84286a62b8dSjtc Player.p_poison += 1.0;
843a232aee2Slukem } else
844a232aee2Slukem if (drandom() / 2.0 > (temp + 1.0) / MAX(Player.p_gold, 1))
84586a62b8dSjtc /* medic wants 1/2 of available gold */
84686a62b8dSjtc mvaddstr(5, 0, "Sorry, he wasn't interested.\n");
847a232aee2Slukem else {
84886a62b8dSjtc mvaddstr(5, 0, "He accepted.");
84986a62b8dSjtc Player.p_poison = MAX(0.0, Player.p_poison - 1.0);
85086a62b8dSjtc Player.p_gold -= temp;
85186a62b8dSjtc }
85286a62b8dSjtc }
85386a62b8dSjtc break;
85486a62b8dSjtc
85586a62b8dSjtc case 3:
85686a62b8dSjtc mvaddstr(4, 0, "You've been caught raping and pillaging!\n");
85786a62b8dSjtc Player.p_experience += 4000.0;
85886a62b8dSjtc Player.p_sin += 0.5;
85986a62b8dSjtc break;
86086a62b8dSjtc
86186a62b8dSjtc case 4:
86286a62b8dSjtc temp = ROLL(10.0, 75.0);
86386a62b8dSjtc mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp);
86486a62b8dSjtc ch = getanswer("NY", FALSE);
86586a62b8dSjtc
86686a62b8dSjtc if (ch == 'Y')
86786a62b8dSjtc collecttaxes(temp, 0.0);
86886a62b8dSjtc break;
86986a62b8dSjtc
87086a62b8dSjtc case 5:
871a232aee2Slukem if (Player.p_sin > 1.0) {
87286a62b8dSjtc mvaddstr(4, 0, "You've found a Holy Orb!\n");
87386a62b8dSjtc Player.p_sin -= 0.25;
87486a62b8dSjtc }
87586a62b8dSjtc break;
87686a62b8dSjtc
87786a62b8dSjtc case 6:
878a232aee2Slukem if (Player.p_poison < 1.0) {
87986a62b8dSjtc mvaddstr(4, 0, "You've been hit with a plague!\n");
88086a62b8dSjtc Player.p_poison += 1.0;
88186a62b8dSjtc }
88286a62b8dSjtc break;
88386a62b8dSjtc
88486a62b8dSjtc case 7:
88586a62b8dSjtc mvaddstr(4, 0, "You've found some holy water.\n");
88686a62b8dSjtc ++Player.p_holywater;
88786a62b8dSjtc break;
88886a62b8dSjtc
88986a62b8dSjtc case 8:
89086a62b8dSjtc mvaddstr(4, 0, "You've met a Guru. . .");
89186a62b8dSjtc if (drandom() * Player.p_sin > 1.0)
89286a62b8dSjtc addstr("You disgusted him with your sins!\n");
893a232aee2Slukem else
894a232aee2Slukem if (Player.p_poison > 0.0) {
89586a62b8dSjtc addstr("He looked kindly upon you, and cured you.\n");
89686a62b8dSjtc Player.p_poison = 0.0;
897a232aee2Slukem } else {
89886a62b8dSjtc addstr("He rewarded you for your virtue.\n");
89986a62b8dSjtc Player.p_mana += 50.0;
90086a62b8dSjtc Player.p_shield += 2.0;
90186a62b8dSjtc }
90286a62b8dSjtc break;
90386a62b8dSjtc
90486a62b8dSjtc case 9:
90586a62b8dSjtc mvaddstr(4, 0, "You've found an amulet.\n");
90686a62b8dSjtc ++Player.p_amulets;
90786a62b8dSjtc break;
90886a62b8dSjtc
90986a62b8dSjtc case 10:
910a232aee2Slukem if (Player.p_blindness) {
91186a62b8dSjtc mvaddstr(4, 0, "You've regained your sight!\n");
91286a62b8dSjtc Player.p_blindness = FALSE;
91386a62b8dSjtc }
91486a62b8dSjtc break;
91586a62b8dSjtc
91686a62b8dSjtc default: /* deal with poison */
917a232aee2Slukem if (Player.p_poison > 0.0) {
91886a62b8dSjtc temp = Player.p_poison * Statptr->c_weakness
91986a62b8dSjtc * Player.p_maxenergy / 600.0;
92086a62b8dSjtc if (Player.p_energy > Player.p_maxenergy / 10.0
92186a62b8dSjtc && temp + 5.0 < Player.p_energy)
92286a62b8dSjtc Player.p_energy -= temp;
92386a62b8dSjtc }
92486a62b8dSjtc break;
92586a62b8dSjtc }
92686a62b8dSjtc }
92786a62b8dSjtc
9285305281bSdholland static void
genchar(int type)929c7a109ccSdholland genchar(int type)
93086a62b8dSjtc {
931a232aee2Slukem int subscript; /* used for subscripting into Stattable */
932092d3130Sjsm const struct charstats *statptr; /* for pointing into Stattable */
93386a62b8dSjtc
93486a62b8dSjtc subscript = type - '1';
93586a62b8dSjtc
93686a62b8dSjtc if (subscript < C_MAGIC || subscript > C_EXPER)
93786a62b8dSjtc if (subscript != C_SUPER || !Wizard)
93886a62b8dSjtc /* fighter is default */
93986a62b8dSjtc subscript = C_FIGHTER;
94086a62b8dSjtc
94186a62b8dSjtc statptr = &Stattable[subscript];
94286a62b8dSjtc
94386a62b8dSjtc Player.p_quickness =
94486a62b8dSjtc ROLL(statptr->c_quickness.base, statptr->c_quickness.interval);
94586a62b8dSjtc Player.p_strength =
94686a62b8dSjtc ROLL(statptr->c_strength.base, statptr->c_strength.interval);
94786a62b8dSjtc Player.p_mana =
94886a62b8dSjtc ROLL(statptr->c_mana.base, statptr->c_mana.interval);
94986a62b8dSjtc Player.p_maxenergy =
95086a62b8dSjtc Player.p_energy =
95186a62b8dSjtc ROLL(statptr->c_energy.base, statptr->c_energy.interval);
95286a62b8dSjtc Player.p_brains =
95386a62b8dSjtc ROLL(statptr->c_brains.base, statptr->c_brains.interval);
95486a62b8dSjtc Player.p_magiclvl =
95586a62b8dSjtc ROLL(statptr->c_magiclvl.base, statptr->c_magiclvl.interval);
95686a62b8dSjtc
95786a62b8dSjtc Player.p_type = subscript;
95886a62b8dSjtc
95986a62b8dSjtc if (Player.p_type == C_HALFLING)
96086a62b8dSjtc /* give halfling some experience */
96186a62b8dSjtc Player.p_experience = ROLL(600.0, 200.0);
96286a62b8dSjtc }
96386a62b8dSjtc
9645305281bSdholland static void
playinit(void)965c7a109ccSdholland playinit(void)
96686a62b8dSjtc {
967*0e5bc969Sandvar /* catch/ignore signals */
96886a62b8dSjtc
96986a62b8dSjtc #ifdef BSD41
97086a62b8dSjtc sigignore(SIGQUIT);
97186a62b8dSjtc sigignore(SIGALRM);
97286a62b8dSjtc sigignore(SIGTERM);
97386a62b8dSjtc sigignore(SIGTSTP);
97486a62b8dSjtc sigignore(SIGTTIN);
97586a62b8dSjtc sigignore(SIGTTOU);
97686a62b8dSjtc sighold(SIGINT);
97786a62b8dSjtc sigset(SIGHUP, ill_sig);
97886a62b8dSjtc sigset(SIGTRAP, ill_sig);
97986a62b8dSjtc sigset(SIGIOT, ill_sig);
98086a62b8dSjtc sigset(SIGEMT, ill_sig);
98186a62b8dSjtc sigset(SIGFPE, ill_sig);
98286a62b8dSjtc sigset(SIGBUS, ill_sig);
98386a62b8dSjtc sigset(SIGSEGV, ill_sig);
98486a62b8dSjtc sigset(SIGSYS, ill_sig);
98586a62b8dSjtc sigset(SIGPIPE, ill_sig);
98686a62b8dSjtc #endif
98786a62b8dSjtc #ifdef BSD42
98886a62b8dSjtc signal(SIGQUIT, ill_sig);
98986a62b8dSjtc signal(SIGALRM, SIG_IGN);
99086a62b8dSjtc signal(SIGTERM, SIG_IGN);
99186a62b8dSjtc signal(SIGTSTP, SIG_IGN);
99286a62b8dSjtc signal(SIGTTIN, SIG_IGN);
99386a62b8dSjtc signal(SIGTTOU, SIG_IGN);
99486a62b8dSjtc signal(SIGINT, ill_sig);
99586a62b8dSjtc signal(SIGHUP, SIG_DFL);
99686a62b8dSjtc signal(SIGTRAP, ill_sig);
99786a62b8dSjtc signal(SIGIOT, ill_sig);
99886a62b8dSjtc signal(SIGEMT, ill_sig);
99986a62b8dSjtc signal(SIGFPE, ill_sig);
100086a62b8dSjtc signal(SIGBUS, ill_sig);
100186a62b8dSjtc signal(SIGSEGV, ill_sig);
100286a62b8dSjtc signal(SIGSYS, ill_sig);
100386a62b8dSjtc signal(SIGPIPE, ill_sig);
100486a62b8dSjtc #endif
100586a62b8dSjtc #ifdef SYS3
100686a62b8dSjtc signal(SIGINT, SIG_IGN);
100786a62b8dSjtc signal(SIGQUIT, SIG_IGN);
100886a62b8dSjtc signal(SIGTERM, SIG_IGN);
100986a62b8dSjtc signal(SIGALRM, SIG_IGN);
101086a62b8dSjtc signal(SIGHUP, ill_sig);
101186a62b8dSjtc signal(SIGTRAP, ill_sig);
101286a62b8dSjtc signal(SIGIOT, ill_sig);
101386a62b8dSjtc signal(SIGEMT, ill_sig);
101486a62b8dSjtc signal(SIGFPE, ill_sig);
101586a62b8dSjtc signal(SIGBUS, ill_sig);
101686a62b8dSjtc signal(SIGSEGV, ill_sig);
101786a62b8dSjtc signal(SIGSYS, ill_sig);
101886a62b8dSjtc signal(SIGPIPE, ill_sig);
101986a62b8dSjtc #endif
102086a62b8dSjtc #ifdef SYS5
102186a62b8dSjtc signal(SIGINT, SIG_IGN);
102286a62b8dSjtc signal(SIGQUIT, SIG_IGN);
102386a62b8dSjtc signal(SIGTERM, SIG_IGN);
102486a62b8dSjtc signal(SIGALRM, SIG_IGN);
102586a62b8dSjtc signal(SIGHUP, ill_sig);
102686a62b8dSjtc signal(SIGTRAP, ill_sig);
102786a62b8dSjtc signal(SIGIOT, ill_sig);
102886a62b8dSjtc signal(SIGEMT, ill_sig);
102986a62b8dSjtc signal(SIGFPE, ill_sig);
103086a62b8dSjtc signal(SIGBUS, ill_sig);
103186a62b8dSjtc signal(SIGSEGV, ill_sig);
103286a62b8dSjtc signal(SIGSYS, ill_sig);
103386a62b8dSjtc signal(SIGPIPE, ill_sig);
103486a62b8dSjtc #endif
103586a62b8dSjtc
1036432ec044Sdrochner if (!initscr()) { /* turn on curses */
1037432ec044Sdrochner fprintf(stderr, "couldn't initialize screen\n");
1038432ec044Sdrochner exit (0);
1039432ec044Sdrochner }
104086a62b8dSjtc noecho(); /* do not echo input */
1041b74595a2Sblymn cbreak(); /* do not process erase, kill */
104286a62b8dSjtc clear();
104386a62b8dSjtc refresh();
104486a62b8dSjtc Windows = TRUE; /* mark the state */
104586a62b8dSjtc }
104686a62b8dSjtc
1047a232aee2Slukem void
cleanup(int doexit)1048c7a109ccSdholland cleanup(int doexit)
104986a62b8dSjtc {
1050a232aee2Slukem if (Windows) {
105186a62b8dSjtc move(LINES - 2, 0);
105286a62b8dSjtc refresh();
1053b74595a2Sblymn nocbreak();
105486a62b8dSjtc endwin();
105586a62b8dSjtc }
105650134cf2Sjsm if (Playersfp)
105786a62b8dSjtc fclose(Playersfp);
105850134cf2Sjsm if (Monstfp)
105986a62b8dSjtc fclose(Monstfp);
106050134cf2Sjsm if (Messagefp)
106186a62b8dSjtc fclose(Messagefp);
106250134cf2Sjsm if (Energyvoidfp)
106386a62b8dSjtc fclose(Energyvoidfp);
106486a62b8dSjtc
106586a62b8dSjtc if (doexit)
106686a62b8dSjtc exit(0);
106786a62b8dSjtc /* NOTREACHED */
106886a62b8dSjtc }
1069