134600Sbostic /* 234600Sbostic * Phantasia 3.3.2 -- Interterminal fantasy game 334600Sbostic * 434600Sbostic * Edward A. Estes 534600Sbostic * AT&T, March 12, 1986 634600Sbostic */ 734600Sbostic 834600Sbostic /* DISCLAIMER: 934600Sbostic * 1034600Sbostic * This game is distributed for free as is. It is not guaranteed to work 1134600Sbostic * in every conceivable environment. It is not even guaranteed to work 1234600Sbostic * in ANY environment. 1334600Sbostic * 1434600Sbostic * This game is distributed without notice of copyright, therefore it 1534600Sbostic * may be used in any manner the recipient sees fit. However, the 1634600Sbostic * author assumes no responsibility for maintaining or revising this 1734600Sbostic * game, in its original form, or any derivitives thereof. 1834600Sbostic * 1934600Sbostic * The author shall not be responsible for any loss, cost, or damage, 2034600Sbostic * including consequential damage, caused by reliance on this material. 2134600Sbostic * 2234600Sbostic * The author makes no warranties, express or implied, including warranties 2334600Sbostic * of merchantability or fitness for a particular purpose or use. 2434600Sbostic * 2534600Sbostic * AT&T is in no way connected with this game. 2634600Sbostic */ 2734600Sbostic 28*37051Sbostic #include <sys/types.h> 29*37051Sbostic #include <pwd.h> 30*37051Sbostic 3134600Sbostic /* 3234600Sbostic * The program allocates as much file space as it needs to store characters, 3334600Sbostic * so the possibility exists for the character file to grow without bound. 3434600Sbostic * The file is purged upon normal entry to try to avoid that problem. 3534600Sbostic * A similar problem exists for energy voids. To alleviate the problem here, 3634600Sbostic * the void file is cleared with every new king, and a limit is placed 3734600Sbostic * on the size of the energy void file. 3834600Sbostic */ 3934600Sbostic 4034600Sbostic /* 4134600Sbostic * Put one line of text into the file 'motd' for announcements, etc. 4234600Sbostic */ 4334600Sbostic 4434600Sbostic /* 4534600Sbostic * If ENEMY is #defined, a list of restricted login names is checked 4634600Sbostic * in the file 'enemy'. These names are listed, one per line, with 4734600Sbostic * no trailing blanks. 4834600Sbostic */ 4934600Sbostic 5034600Sbostic /* 5134600Sbostic * The scoreboard file is updated when someone dies, and keeps track 5234600Sbostic * of the highest character to date for that login. 5334600Sbostic * Being purged from the character file does not cause the scoreboard 5434600Sbostic * to be updated. 5534600Sbostic */ 5634600Sbostic 5734600Sbostic /* 5834600Sbostic * All source files are set up for 'vi' with shiftwidth=4, tabstop=8. 5934600Sbostic */ 6034600Sbostic 6134600Sbostic /**/ 6234600Sbostic 6334600Sbostic /* 6434600Sbostic * main.c Main routines for Phantasia 6534600Sbostic */ 6634600Sbostic 6734600Sbostic #include "include.h" 6834600Sbostic 6934600Sbostic /*************************************************************************** 7034600Sbostic / FUNCTION NAME: main() 7134600Sbostic / 7234600Sbostic / FUNCTION: initialize state, and call main process 7334600Sbostic / 7434600Sbostic / AUTHOR: E. A. Estes, 12/4/85 7534600Sbostic / 7634600Sbostic / ARGUMENTS: 7734600Sbostic / int argc - argument count 7834600Sbostic / char **argv - argument vector 7934600Sbostic / 8034600Sbostic / RETURN VALUE: none 8134600Sbostic / 8234600Sbostic / MODULES CALLED: monstlist(), checkenemy(), ok_to_play(), activelist(), 8334600Sbostic / throneroom(), checkbattle(), readmessage(), changestats(), writerecord(), 8434600Sbostic / tradingpost(), adjuststats(), recallplayer(), displaystats(), checktampered(), 8534600Sbostic / fabs(), rollnewplayer(), time(), exit(), sqrt(), floor(), wmove(), 8634600Sbostic / signal(), strcat(), purgeoldplayers(), getuid(), isatty(), wclear(), 8734600Sbostic / strcpy(), system(), altercoordinates(), cleanup(), waddstr(), procmain(), 8834600Sbostic / playinit(), leavegame(), localtime(), getanswer(), neatstuff(), initialstate(), 8934600Sbostic / scorelist(), titlelist() 9034600Sbostic / 9134600Sbostic / GLOBAL INPUTS: *Login, Throne, Wizard, Player, *stdscr, Changed, Databuf[], 9234600Sbostic / Fileloc, Helpfile[], Stattable[] 9334600Sbostic / 9434600Sbostic / GLOBAL OUTPUTS: Wizard, Player, Changed, Fileloc, Timeout, *Statptr 9534600Sbostic / 9634600Sbostic / DESCRIPTION: 9734600Sbostic / Process arguments, initialize program, and loop forever processing 9834600Sbostic / player input. 9934600Sbostic / 10034600Sbostic /***************************************************************************/ 10134600Sbostic 10234600Sbostic main(argc, argv) 10334600Sbostic int argc; 10434600Sbostic char **argv; 10534600Sbostic { 10634600Sbostic bool noheader = FALSE; /* set if don't want header */ 10734600Sbostic bool headeronly = FALSE; /* set if only want header */ 10834600Sbostic bool examine = FALSE; /* set if examine a character */ 10934600Sbostic long seconds; /* for time of day */ 11034600Sbostic double dtemp; /* for temporary calculations */ 11134600Sbostic 11234600Sbostic initialstate(); /* init globals */ 11334600Sbostic 11434600Sbostic #ifdef ENEMY 11534600Sbostic checkenemy(); /* check if denied access */ 11634600Sbostic #endif 11734600Sbostic 11834600Sbostic /* process arguments */ 11934600Sbostic while (--argc && (*++argv)[0] == '-') 12034600Sbostic switch ((*argv)[1]) 12134600Sbostic { 12234600Sbostic case 's': /* short */ 12334600Sbostic noheader = TRUE; 12434600Sbostic break; 12534600Sbostic 12634600Sbostic case 'H': /* Header */ 12734600Sbostic headeronly = TRUE; 12834600Sbostic break; 12934600Sbostic 13034600Sbostic case 'a': /* all users */ 13134600Sbostic activelist(); 13234600Sbostic cleanup(TRUE); 13334600Sbostic /*NOTREACHED*/ 13434600Sbostic 13534600Sbostic case 'p': /* purge old players */ 13634600Sbostic purgeoldplayers(); 13734600Sbostic cleanup(TRUE); 13834600Sbostic /*NOTREACHED*/ 13934600Sbostic 14034600Sbostic case 'S': /* set 'Wizard' */ 14134600Sbostic Wizard = (getuid() == UID); 14234600Sbostic break; 14334600Sbostic 14434600Sbostic case 'x': /* examine */ 14534600Sbostic examine = TRUE; 14634600Sbostic break; 14734600Sbostic 14834600Sbostic case 'm': /* monsters */ 14934600Sbostic monstlist(); 15034600Sbostic cleanup(TRUE); 15134600Sbostic /*NOTREACHED*/ 15234600Sbostic 15334600Sbostic case 'b': /* scoreboard */ 15434600Sbostic scorelist(); 15534600Sbostic cleanup(TRUE); 15634600Sbostic /*NOTREACHED*/ 15734600Sbostic 15834600Sbostic case 'h': /* help */ 15934600Sbostic cleanup(FALSE); 16034600Sbostic strcpy(Databuf, "cat "); 16134600Sbostic system(strcat(Databuf, Helpfile)); 16234600Sbostic exit(0); 16334600Sbostic /*NOTREACHED*/ 16434600Sbostic } 16534600Sbostic 16634600Sbostic if (!isatty(0)) /* don't let non-tty's play */ 16734600Sbostic cleanup(TRUE); 16834600Sbostic /*NOTREACHED*/ 16934600Sbostic 17034600Sbostic playinit(); /* set up to catch signals, init curses */ 17134600Sbostic 17234600Sbostic if (examine) 17334600Sbostic { 17434600Sbostic changestats(FALSE); 17534600Sbostic cleanup(TRUE); 17634600Sbostic /*NOTREACHED*/ 17734600Sbostic } 17834600Sbostic 17934600Sbostic if (!noheader) 18034600Sbostic { 18134600Sbostic titlelist(); 18234600Sbostic purgeoldplayers(); /* clean up old characters */ 18334600Sbostic } 18434600Sbostic 18534600Sbostic if (headeronly) 18634600Sbostic cleanup(TRUE); 18734600Sbostic /*NOTREACHED*/ 18834600Sbostic 18934600Sbostic do 19034600Sbostic /* get the player structure filled */ 19134600Sbostic { 19234600Sbostic Fileloc = -1L; 19334600Sbostic 19434600Sbostic mvaddstr(22, 17, "Do you have a character to run [Q = Quit] ? "); 19534600Sbostic 19634600Sbostic switch (getanswer("NYQ", FALSE)) 19734600Sbostic { 19834600Sbostic case 'Y': 19934600Sbostic Fileloc = recallplayer(); 20034600Sbostic break; 20134600Sbostic 20234600Sbostic case 'Q': 20334600Sbostic cleanup(TRUE); 20434600Sbostic /*NOTREACHED*/ 20534600Sbostic 20634600Sbostic default: 20734600Sbostic Fileloc = rollnewplayer(); 20834600Sbostic break; 20934600Sbostic } 21034600Sbostic clear(); 21134600Sbostic } 21234600Sbostic while (Fileloc < 0L); 21334600Sbostic 21434600Sbostic if (Player.p_level > 5.0) 21534600Sbostic /* low level players have long timeout */ 21634600Sbostic Timeout = TRUE; 21734600Sbostic 21834600Sbostic /* update some important player statistics */ 21934600Sbostic strcpy(Player.p_login, Login); 22034600Sbostic time(&seconds); 22134600Sbostic Player.p_lastused = localtime(&seconds)->tm_yday; 22234600Sbostic Player.p_status = S_PLAYING; 22334600Sbostic writerecord(&Player, Fileloc); 22434600Sbostic 22534600Sbostic Statptr = &Stattable[Player.p_type]; /* initialize pointer */ 22634600Sbostic 22734600Sbostic /* catch interrupts */ 22834600Sbostic #ifdef BSD41 22934600Sbostic sigset(SIGINT, interrupt); 23034600Sbostic #endif 23134600Sbostic #ifdef BSD42 23234600Sbostic signal(SIGINT, interrupt); 23334600Sbostic #endif 23434600Sbostic #ifdef SYS3 23534600Sbostic signal(SIGINT, interrupt); 23634600Sbostic #endif 23734600Sbostic #ifdef SYS5 23834600Sbostic signal(SIGINT, interrupt); 23934600Sbostic #endif 24034600Sbostic 24134600Sbostic altercoordinates(Player.p_x, Player.p_y, A_FORCED); /* set some flags */ 24234600Sbostic 24334600Sbostic clear(); 24434600Sbostic 24534600Sbostic for (;;) 24634600Sbostic /* loop forever, processing input */ 24734600Sbostic { 24834600Sbostic 24934600Sbostic adjuststats(); /* cleanup stats */ 25034600Sbostic 25134600Sbostic if (Throne && Player.p_crowns == 0 && Player.p_specialtype != SC_KING) 25234600Sbostic /* not allowed on throne -- move */ 25334600Sbostic { 25434600Sbostic mvaddstr(5,0,"You're not allowed in the Lord's Chamber without a crown.\n"); 25534600Sbostic altercoordinates(0.0, 0.0, A_NEAR); 25634600Sbostic } 25734600Sbostic 25834600Sbostic checktampered(); /* check for energy voids, etc. */ 25934600Sbostic 26034600Sbostic if (Player.p_status != S_CLOAKED 26134600Sbostic /* not cloaked */ 26234600Sbostic && (dtemp = fabs(Player.p_x)) == fabs(Player.p_y) 26334600Sbostic /* |x| = |y| */ 26434600Sbostic && !Throne) 26534600Sbostic /* not on throne */ 26634600Sbostic { 26734600Sbostic dtemp = sqrt(dtemp / 100.0); 26834600Sbostic if (floor(dtemp) == dtemp) 26934600Sbostic /* |x| / 100 == n*n; at a trading post */ 27034600Sbostic { 27134600Sbostic tradingpost(); 27234600Sbostic clear(); 27334600Sbostic } 27434600Sbostic } 27534600Sbostic 27634600Sbostic checkbattle(); /* check for player to player battle */ 27734600Sbostic neatstuff(); /* gurus, medics, etc. */ 27834600Sbostic 27934600Sbostic if (Player.p_status == S_CLOAKED) 28034600Sbostic /* costs 3 mana per turn to be cloaked */ 28134600Sbostic if (Player.p_mana > 3.0) 28234600Sbostic Player.p_mana -= 3.0; 28334600Sbostic else 28434600Sbostic /* ran out of mana, uncloak */ 28534600Sbostic { 28634600Sbostic Player.p_status = S_PLAYING; 28734600Sbostic Changed = TRUE; 28834600Sbostic } 28934600Sbostic 29034600Sbostic if (Player.p_status != S_PLAYING && Player.p_status != S_CLOAKED) 29134600Sbostic /* change status back to S_PLAYING */ 29234600Sbostic { 29334600Sbostic Player.p_status = S_PLAYING; 29434600Sbostic Changed = TRUE; 29534600Sbostic } 29634600Sbostic 29734600Sbostic if (Changed) 29834600Sbostic /* update file only if important stuff has changed */ 29934600Sbostic { 30034600Sbostic writerecord(&Player, Fileloc); 30134600Sbostic Changed = FALSE; 30234600Sbostic continue; 30334600Sbostic } 30434600Sbostic 30534600Sbostic readmessage(); /* read message, if any */ 30634600Sbostic 30734600Sbostic displaystats(); /* print statistics */ 30834600Sbostic 30934600Sbostic move(6, 0); 31034600Sbostic 31134600Sbostic if (Throne) 31234600Sbostic /* maybe make king, print prompt, etc. */ 31334600Sbostic throneroom(); 31434600Sbostic 31534600Sbostic /* print status line */ 31634600Sbostic addstr("1:Move 2:Players 3:Talk 4:Stats 5:Quit "); 31734600Sbostic if (Player.p_level >= MEL_CLOAK && Player.p_magiclvl >= ML_CLOAK) 31834600Sbostic addstr("6:Cloak "); 31934600Sbostic if (Player.p_level >= MEL_TELEPORT && Player.p_magiclvl >= ML_TELEPORT) 32034600Sbostic addstr("7:Teleport "); 32134600Sbostic if (Player.p_specialtype >= SC_COUNCIL || Wizard) 32234600Sbostic addstr("8:Intervene "); 32334600Sbostic 32434600Sbostic procmain(); /* process input */ 32534600Sbostic } 32634600Sbostic } 32734600Sbostic /**/ 32834600Sbostic /************************************************************************ 32934600Sbostic / 33034600Sbostic / FUNCTION NAME: initialstate() 33134600Sbostic / 33234600Sbostic / FUNCTION: initialize some important global variable 33334600Sbostic / 33434600Sbostic / AUTHOR: E. A. Estes, 12/4/85 33534600Sbostic / 33634600Sbostic / ARGUMENTS: none 33734600Sbostic / 33834600Sbostic / RETURN VALUE: none 33934600Sbostic / 34034600Sbostic / MODULES CALLED: time(), fopen(), srandom(), error(), getuid(), getlogin(), 34134600Sbostic / getpwuid() 34234600Sbostic / 34334600Sbostic / GLOBAL INPUTS: Peoplefile[], Voidfile[], Messfile[], Monstfile[] 34434600Sbostic / 34534600Sbostic / GLOBAL OUTPUTS: *Energyvoidfp, Echo, Marsh, *Login, Users, Beyond, 34634600Sbostic / Throne, Wizard, Changed, Okcount, Timeout, Windows, *Monstfp, *Messagefp, 34734600Sbostic / *Playersfp 34834600Sbostic / 34934600Sbostic / DESCRIPTION: 35034600Sbostic / Set global flags, and open files which remain open. 35134600Sbostic / 35234600Sbostic /************************************************************************/ 35334600Sbostic 35434600Sbostic initialstate() 35534600Sbostic { 35634600Sbostic Beyond = FALSE; 35734600Sbostic Marsh = FALSE; 35834600Sbostic Throne = FALSE; 35934600Sbostic Changed = FALSE; 36034600Sbostic Wizard = FALSE; 36134600Sbostic Timeout = FALSE; 36234600Sbostic Users = 0; 36334600Sbostic Windows = FALSE; 36434600Sbostic Echo = TRUE; 36534600Sbostic 36634600Sbostic /* setup login name */ 36734600Sbostic if ((Login = getlogin()) == NULL) 36834600Sbostic Login = getpwuid(getuid())->pw_name; 36934600Sbostic 37034600Sbostic /* open some files */ 37134600Sbostic if ((Playersfp = fopen(Peoplefile, "r+")) == NULL) 37234600Sbostic error(Peoplefile); 37334600Sbostic /*NOTREACHED*/ 37434600Sbostic 37534600Sbostic if ((Monstfp = fopen(Monstfile, "r+")) == NULL) 37634600Sbostic error(Monstfile); 37734600Sbostic /*NOTREACHED*/ 37834600Sbostic 37934600Sbostic if ((Messagefp = fopen(Messfile, "r")) == NULL) 38034600Sbostic error(Messfile); 38134600Sbostic /*NOTREACHED*/ 38234600Sbostic 38334600Sbostic if ((Energyvoidfp = fopen(Voidfile, "r+")) == NULL) 38434600Sbostic error(Voidfile); 38534600Sbostic /*NOTREACHED*/ 38634600Sbostic 38734600Sbostic srandom((unsigned) time((long *) NULL)); /* prime random numbers */ 38834600Sbostic } 38934600Sbostic /**/ 39034600Sbostic /************************************************************************ 39134600Sbostic / 39234600Sbostic / FUNCTION NAME: rollnewplayer() 39334600Sbostic / 39434600Sbostic / FUNCTION: roll up a new character 39534600Sbostic / 39634600Sbostic / AUTHOR: E. A. Estes, 12/4/85 39734600Sbostic / 39834600Sbostic / ARGUMENTS: none 39934600Sbostic / 40034600Sbostic / RETURN VALUE: none 40134600Sbostic / 40234600Sbostic / MODULES CALLED: initplayer(), allocrecord(), truncstring(), fabs(), wmove(), 40334600Sbostic / wclear(), sscanf(), strcmp(), genchar(), waddstr(), findname(), mvprintw(), 40434600Sbostic / getanswer(), getstring() 40534600Sbostic / 40634600Sbostic / GLOBAL INPUTS: Other, Wizard, Player, *stdscr, Databuf[] 40734600Sbostic / 40834600Sbostic / GLOBAL OUTPUTS: Echo 40934600Sbostic / 41034600Sbostic / DESCRIPTION: 41134600Sbostic / Prompt player, and roll up new character. 41234600Sbostic / 41334600Sbostic /************************************************************************/ 41434600Sbostic 41534600Sbostic long 41634600Sbostic rollnewplayer() 41734600Sbostic { 41834600Sbostic int chartype; /* character type */ 41934600Sbostic int ch; /* input */ 42034600Sbostic 42134600Sbostic initplayer(&Player); /* initialize player structure */ 42234600Sbostic 42334600Sbostic clear(); 42434600Sbostic mvaddstr(4, 21, "Which type of character do you want:"); 42534600Sbostic mvaddstr(8, 4, "1:Magic User 2:Fighter 3:Elf 4:Dwarf 5:Halfling 6:Experimento "); 42634600Sbostic if (Wizard) { 42734600Sbostic addstr("7:Super ? "); 42834600Sbostic chartype = getanswer("1234567", FALSE); 42934600Sbostic } 43034600Sbostic else { 43134600Sbostic addstr("? "); 43234600Sbostic chartype = getanswer("123456", FALSE); 43334600Sbostic } 43434600Sbostic 43534600Sbostic do 43634600Sbostic { 43734600Sbostic genchar(chartype); /* roll up a character */ 43834600Sbostic 43934600Sbostic /* print out results */ 44034600Sbostic mvprintw(12, 14, 44134600Sbostic "Strength : %2.0f Quickness: %2.0f Mana : %2.0f\n", 44234600Sbostic Player.p_strength, Player.p_quickness, Player.p_mana); 44334600Sbostic mvprintw(13, 14, 44434600Sbostic "Energy Level: %2.0f Brains : %2.0f Magic Level: %2.0f\n", 44534600Sbostic Player.p_energy, Player.p_brains, Player.p_magiclvl); 44634600Sbostic 44734600Sbostic if (Player.p_type == C_EXPER || Player.p_type == C_SUPER) 44834600Sbostic break; 44934600Sbostic 45034600Sbostic mvaddstr(14, 14, "Type '1' to keep >"); 45134600Sbostic ch = getanswer(" ", TRUE); 45234600Sbostic } 45334600Sbostic while (ch != '1'); 45434600Sbostic 45534600Sbostic if (Player.p_type == C_EXPER || Player.p_type == C_SUPER) 45634600Sbostic /* get coordinates for experimento */ 45734600Sbostic for (;;) 45834600Sbostic { 45934600Sbostic mvaddstr(16, 0, "Enter the X Y coordinates of your experimento ? "); 46034600Sbostic getstring(Databuf, SZ_DATABUF); 46134613Sbostic sscanf(Databuf, "%lf %lf", &Player.p_x, &Player.p_y); 46234600Sbostic 46334600Sbostic if (fabs(Player.p_x) > D_EXPER || fabs(Player.p_y) > D_EXPER) 46434600Sbostic mvaddstr(17, 0, "Invalid coordinates. Try again.\n"); 46534600Sbostic else 46634600Sbostic break; 46734600Sbostic } 46834600Sbostic 46934600Sbostic for (;;) 47034600Sbostic /* name the new character */ 47134600Sbostic { 47234600Sbostic mvprintw(18, 0, 47334600Sbostic "Give your character a name [up to %d characters] ? ", SZ_NAME - 1); 47434600Sbostic getstring(Player.p_name, SZ_NAME); 47534600Sbostic truncstring(Player.p_name); /* remove trailing blanks */ 47634600Sbostic 47734600Sbostic if (Player.p_name[0] == '\0') 47834600Sbostic /* no null names */ 47934600Sbostic mvaddstr(19, 0, "Invalid name."); 48034600Sbostic else if (findname(Player.p_name, &Other) >= 0L) 48134600Sbostic /* cannot have duplicate names */ 48234600Sbostic mvaddstr(19, 0, "Name already in use."); 48334600Sbostic else 48434600Sbostic /* name is acceptable */ 48534600Sbostic break; 48634600Sbostic 48734600Sbostic addstr(" Pick another.\n"); 48834600Sbostic } 48934600Sbostic 49034600Sbostic /* get a password for character */ 49134600Sbostic Echo = FALSE; 49234600Sbostic 49334600Sbostic do 49434600Sbostic { 49534600Sbostic mvaddstr(20, 0, "Give your character a password [up to 8 characters] ? "); 49634600Sbostic getstring(Player.p_password, SZ_PASSWORD); 49734600Sbostic mvaddstr(21, 0, "One more time to verify ? "); 49834600Sbostic getstring(Databuf, SZ_PASSWORD); 49934600Sbostic } 50034600Sbostic while (strcmp(Player.p_password, Databuf) != 0); 50134600Sbostic 50234600Sbostic Echo = TRUE; 50334600Sbostic 50434600Sbostic return(allocrecord()); 50534600Sbostic } 50634600Sbostic /**/ 50734600Sbostic /************************************************************************ 50834600Sbostic / 50934600Sbostic / FUNCTION NAME: procmain() 51034600Sbostic / 51134600Sbostic / FUNCTION: process input from player 51234600Sbostic / 51334600Sbostic / AUTHOR: E. A. Estes, 12/4/85 51434600Sbostic / 51534600Sbostic / ARGUMENTS: none 51634600Sbostic / 51734600Sbostic / RETURN VALUE: none 51834600Sbostic / 51934600Sbostic / MODULES CALLED: dotampered(), changestats(), inputoption(), allstatslist(), 52034600Sbostic / fopen(), wmove(), drandom(), sscanf(), fclose(), altercoordinates(), 52134600Sbostic / waddstr(), fprintf(), distance(), userlist(), leavegame(), encounter(), 52234600Sbostic / getstring(), wclrtobot() 52334600Sbostic / 52434600Sbostic / GLOBAL INPUTS: Circle, Illcmd[], Throne, Wizard, Player, *stdscr, 52534600Sbostic / Databuf[], Illmove[], Messfile[] 52634600Sbostic / 52734600Sbostic / GLOBAL OUTPUTS: Player, Changed 52834600Sbostic / 52934600Sbostic / DESCRIPTION: 53034600Sbostic / Process main menu options. 53134600Sbostic / 53234600Sbostic /************************************************************************/ 53334600Sbostic 53434600Sbostic procmain() 53534600Sbostic { 53634600Sbostic int ch; /* input */ 53734600Sbostic double x; /* desired new x coordinate */ 53834600Sbostic double y; /* desired new y coordinate */ 53934600Sbostic double temp; /* for temporary calculations */ 54034600Sbostic FILE *fp; /* for opening files */ 54134600Sbostic register int loop; /* a loop counter */ 54234600Sbostic bool hasmoved = FALSE; /* set if player has moved */ 54334600Sbostic 54434600Sbostic ch = inputoption(); 54534600Sbostic mvaddstr(4, 0, "\n\n"); /* clear status area */ 54634600Sbostic 54734600Sbostic move(7, 0); 54834600Sbostic clrtobot(); /* clear data on bottom area of screen */ 54934600Sbostic 55034600Sbostic if (Player.p_specialtype == SC_VALAR && (ch == '1' || ch == '7')) 55134600Sbostic /* valar cannot move */ 55234600Sbostic ch = ' '; 55334600Sbostic 55434600Sbostic switch (ch) 55534600Sbostic { 55634600Sbostic case 'K': /* move up/north */ 55734600Sbostic case 'N': 55834600Sbostic x = Player.p_x; 55934600Sbostic y = Player.p_y + MAXMOVE(); 56034600Sbostic hasmoved = TRUE; 56134600Sbostic break; 56234600Sbostic 56334600Sbostic case 'J': /* move down/south */ 56434600Sbostic case 'S': 56534600Sbostic x = Player.p_x; 56634600Sbostic y = Player.p_y - MAXMOVE(); 56734600Sbostic hasmoved = TRUE; 56834600Sbostic break; 56934600Sbostic 57034600Sbostic case 'L': /* move right/east */ 57134600Sbostic case 'E': 57234600Sbostic x = Player.p_x + MAXMOVE(); 57334600Sbostic y = Player.p_y; 57434600Sbostic hasmoved = TRUE; 57534600Sbostic break; 57634600Sbostic 57734600Sbostic case 'H': /* move left/west */ 57834600Sbostic case 'W': 57934600Sbostic x = Player.p_x - MAXMOVE(); 58034600Sbostic y = Player.p_y; 58134600Sbostic hasmoved = TRUE; 58234600Sbostic break; 58334600Sbostic 58434600Sbostic default: /* rest */ 58534600Sbostic Player.p_energy += (Player.p_maxenergy + Player.p_shield) / 15.0 58634600Sbostic + Player.p_level / 3.0 + 2.0; 58734600Sbostic Player.p_energy = 58834600Sbostic MIN(Player.p_energy, Player.p_maxenergy + Player.p_shield); 58934600Sbostic 59034600Sbostic if (Player.p_status != S_CLOAKED) 59134600Sbostic /* cannot find mana if cloaked */ 59234600Sbostic { 59334600Sbostic Player.p_mana += (Circle + Player.p_level) / 4.0; 59434600Sbostic 59534600Sbostic if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne) 59634600Sbostic /* wandering monster */ 59734600Sbostic encounter(-1); 59834600Sbostic } 59934600Sbostic break; 60034600Sbostic 60134600Sbostic case 'X': /* change/examine a character */ 60234600Sbostic changestats(TRUE); 60334600Sbostic break; 60434600Sbostic 60534600Sbostic case '1': /* move */ 60634600Sbostic for (loop = 3; loop; --loop) 60734600Sbostic { 60834600Sbostic mvaddstr(4, 0, "X Y Coordinates ? "); 60934600Sbostic getstring(Databuf, SZ_DATABUF); 61034600Sbostic 61134613Sbostic if (sscanf(Databuf, "%lf %lf", &x, &y) != 2) 61234600Sbostic mvaddstr(5, 0, "Try again\n"); 61334600Sbostic else if (distance(Player.p_x, x, Player.p_y, y) > MAXMOVE()) 61434600Sbostic ILLMOVE(); 61534600Sbostic else 61634600Sbostic { 61734600Sbostic hasmoved = TRUE; 61834600Sbostic break; 61934600Sbostic } 62034600Sbostic } 62134600Sbostic break; 62234600Sbostic 62334600Sbostic case '2': /* players */ 62434600Sbostic userlist(TRUE); 62534600Sbostic break; 62634600Sbostic 62734600Sbostic case '3': /* message */ 62834600Sbostic mvaddstr(4, 0, "Message ? "); 62934600Sbostic getstring(Databuf, SZ_DATABUF); 63034600Sbostic /* we open the file for writing to erase any data which is already there */ 63134600Sbostic fp = fopen(Messfile, "w"); 63234600Sbostic if (Databuf[0] != '\0') 63334600Sbostic fprintf(fp, "%s: %s", Player.p_name, Databuf); 63434600Sbostic fclose(fp); 63534600Sbostic break; 63634600Sbostic 63734600Sbostic case '4': /* stats */ 63834600Sbostic allstatslist(); 63934600Sbostic break; 64034600Sbostic 64134600Sbostic case '5': /* good-bye */ 64234600Sbostic leavegame(); 64334600Sbostic /*NOTREACHED*/ 64434600Sbostic 64534600Sbostic case '6': /* cloak */ 64634600Sbostic if (Player.p_level < MEL_CLOAK || Player.p_magiclvl < ML_CLOAK) 64734600Sbostic ILLCMD(); 64834600Sbostic else if (Player.p_status == S_CLOAKED) 64934600Sbostic Player.p_status = S_PLAYING; 65034600Sbostic else if (Player.p_mana < MM_CLOAK) 65134600Sbostic mvaddstr(5, 0, "No mana left.\n"); 65234600Sbostic else 65334600Sbostic { 65434600Sbostic Changed = TRUE; 65534600Sbostic Player.p_mana -= MM_CLOAK; 65634600Sbostic Player.p_status = S_CLOAKED; 65734600Sbostic } 65834600Sbostic break; 65934600Sbostic 66034600Sbostic case '7': /* teleport */ 66134600Sbostic /* 66234600Sbostic * conditions for teleport 66334600Sbostic * - 20 per (level plus magic level) 66434600Sbostic * - OR council of the wise or valar or ex-valar 66534600Sbostic * - OR transport from throne 66634600Sbostic * transports from throne cost no mana 66734600Sbostic */ 66834600Sbostic if (Player.p_level < MEL_TELEPORT || Player.p_magiclvl < ML_TELEPORT) 66934600Sbostic ILLCMD(); 67034600Sbostic else 67134600Sbostic for (loop = 3; loop; --loop) 67234600Sbostic { 67334600Sbostic mvaddstr(4, 0, "X Y Coordinates ? "); 67434600Sbostic getstring(Databuf, SZ_DATABUF); 67534600Sbostic 67634613Sbostic if (sscanf(Databuf, "%lf %lf", &x, &y) == 2) 67734600Sbostic { 67834600Sbostic temp = distance(Player.p_x, x, Player.p_y, y); 67934600Sbostic if (!Throne 68034600Sbostic /* can transport anywhere from throne */ 68134600Sbostic && Player.p_specialtype <= SC_COUNCIL 68234600Sbostic /* council, valar can transport anywhere */ 68334600Sbostic && temp > (Player.p_level + Player.p_magiclvl) * 20.0) 68434600Sbostic /* can only move 20 per exp. level + mag. level */ 68534600Sbostic ILLMOVE(); 68634600Sbostic else 68734600Sbostic { 68834600Sbostic temp = (temp / 75.0 + 1.0) * 20.0; /* mana used */ 68934600Sbostic 69034600Sbostic if (!Throne && temp > Player.p_mana) 69134600Sbostic mvaddstr(5, 0, "Not enough power for that distance.\n"); 69234600Sbostic else 69334600Sbostic { 69434600Sbostic if (!Throne) 69534600Sbostic Player.p_mana -= temp; 69634600Sbostic hasmoved = TRUE; 69734600Sbostic break; 69834600Sbostic } 69934600Sbostic } 70034600Sbostic } 70134600Sbostic } 70234600Sbostic break; 70334600Sbostic 70434600Sbostic case 'C': 70534600Sbostic case '9': /* monster */ 70634600Sbostic if (Throne) 70734600Sbostic /* no monsters while on throne */ 70834600Sbostic mvaddstr(5, 0, "No monsters in the chamber!\n"); 70934600Sbostic else if (Player.p_specialtype != SC_VALAR) 71034600Sbostic /* the valar cannot call monsters */ 71134600Sbostic { 71234600Sbostic Player.p_sin += 1e-6; 71334600Sbostic encounter(-1); 71434600Sbostic } 71534600Sbostic break; 71634600Sbostic 71734600Sbostic case '0': /* decree */ 71834600Sbostic if (Wizard || Player.p_specialtype == SC_KING && Throne) 71934600Sbostic /* kings must be on throne to decree */ 72034600Sbostic dotampered(); 72134600Sbostic else 72234600Sbostic ILLCMD(); 72334600Sbostic break; 72434600Sbostic 72534600Sbostic case '8': /* intervention */ 72634600Sbostic if (Wizard || Player.p_specialtype >= SC_COUNCIL) 72734600Sbostic dotampered(); 72834600Sbostic else 72934600Sbostic ILLCMD(); 73034600Sbostic break; 73134600Sbostic } 73234600Sbostic 73334600Sbostic if (hasmoved) 73434600Sbostic /* player has moved -- alter coordinates, and do random monster */ 73534600Sbostic { 73634600Sbostic altercoordinates(x, y, A_SPECIFIC); 73734600Sbostic 73834600Sbostic if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne) 73934600Sbostic encounter(-1); 74034600Sbostic } 74134600Sbostic } 74234600Sbostic /**/ 74334600Sbostic #ifdef ENEMY 74434600Sbostic /************************************************************************ 74534600Sbostic / 74634600Sbostic / FUNCTION NAME: checkenemy() 74734600Sbostic / 74834600Sbostic / FUNCTION: check login name against enemy list 74934600Sbostic / 75034600Sbostic / AUTHOR: E. A. Estes, 12/4/85 75134600Sbostic / 75234600Sbostic / ARGUMENTS: none 75334600Sbostic / 75434600Sbostic / RETURN VALUE: none 75534600Sbostic / 75634600Sbostic / MODULES CALLED: fopen(), fgets(), strcmp(), fclose(), printf(), cleanup() 75734600Sbostic / 75834600Sbostic / GLOBAL INPUTS: *Login, Databuf[], Enemyfile[] 75934600Sbostic / 76034600Sbostic / GLOBAL OUTPUTS: none 76134600Sbostic / 76234600Sbostic / DESCRIPTION: 76334600Sbostic / The enemy file has a list of login names which are denied 76434600Sbostic / access to Phantasia. 76534600Sbostic / We scan this list and exit if the current login name is 76634600Sbostic / found in the list. 76734600Sbostic / 76834600Sbostic /************************************************************************/ 76934600Sbostic 77034600Sbostic checkenemy() 77134600Sbostic { 77234600Sbostic FILE *fp; /* to open enemy file */ 77334600Sbostic 77434600Sbostic /* check hit list of restricted accounts */ 77534600Sbostic if ((fp = fopen(Enemyfile, "r")) != NULL) 77634600Sbostic { 77734600Sbostic while (fgets(Databuf, SZ_DATABUF, fp) != NULL) 77834600Sbostic if (strcmp(Login, Databuf) == 0) 77934600Sbostic { 78034600Sbostic printf ("The Phantasia privileges for the account \"%s\" have been revoked.\n", Login); 78134600Sbostic printf ("Mail comments to %s.\n", WIZARD); 78234600Sbostic fclose(fp); 78334600Sbostic cleanup(TRUE); 78434600Sbostic /*NOTREACHED*/ 78534600Sbostic } 78634600Sbostic fclose (fp); 78734600Sbostic } 78834600Sbostic } 78934600Sbostic #endif 79034600Sbostic 79134600Sbostic /**/ 79234600Sbostic /************************************************************************ 79334600Sbostic / 79434600Sbostic / FUNCTION NAME: titlelist() 79534600Sbostic / 79634600Sbostic / FUNCTION: print title page 79734600Sbostic / 79834600Sbostic / AUTHOR: E. A. Estes, 12/4/85 79934600Sbostic / 80034600Sbostic / ARGUMENTS: none 80134600Sbostic / 80234600Sbostic / RETURN VALUE: none 80334600Sbostic / 80434600Sbostic / MODULES CALLED: fread(), fseek(), fopen(), fgets(), wmove(), strcpy(), 80534600Sbostic / fclose(), strlen(), waddstr(), sprintf(), wrefresh() 80634600Sbostic / 80734600Sbostic / GLOBAL INPUTS: Lines, Other, *stdscr, Databuf[], Lastdead[], Motdfile[], 80834600Sbostic / *Playersfp 80934600Sbostic / 81034600Sbostic / GLOBAL OUTPUTS: Lines 81134600Sbostic / 81234600Sbostic / DESCRIPTION: 81334600Sbostic / Print important information about game, players, etc. 81434600Sbostic / 81534600Sbostic /************************************************************************/ 81634600Sbostic 81734600Sbostic titlelist() 81834600Sbostic { 81934600Sbostic register FILE *fp; /* used for opening various files */ 82034600Sbostic bool councilfound = FALSE; /* set if we find a member of the council */ 82134600Sbostic bool kingfound = FALSE; /* set if we find a king */ 82234600Sbostic double hiexp, nxtexp; /* used for finding the two highest players */ 82334600Sbostic double hilvl, nxtlvl; /* used for finding the two highest players */ 82434600Sbostic char hiname[21], nxtname[21];/* used for finding the two highest players */ 82534600Sbostic 82634600Sbostic 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)!"); 82734600Sbostic 82834600Sbostic /* print message of the day */ 82934600Sbostic if ((fp = fopen(Motdfile, "r")) != NULL 83034600Sbostic && fgets(Databuf, SZ_DATABUF, fp) != NULL) 83134600Sbostic { 83234600Sbostic mvaddstr(2, 40 - strlen(Databuf) / 2, Databuf); 83334600Sbostic fclose(fp); 83434600Sbostic } 83534600Sbostic 83634600Sbostic /* search for king */ 83734600Sbostic fseek(Playersfp, 0L, 0); 83834600Sbostic while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) 83934600Sbostic if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED) 84034600Sbostic /* found the king */ 84134600Sbostic { 84234600Sbostic sprintf(Databuf, "The present ruler is %s Level:%.0f", 84334600Sbostic Other.p_name, Other.p_level); 84434600Sbostic mvaddstr(4, 40 - strlen(Databuf) / 2, Databuf); 84534600Sbostic kingfound = TRUE; 84634600Sbostic break; 84734600Sbostic } 84834600Sbostic 84934600Sbostic if (!kingfound) 85034600Sbostic mvaddstr(4, 24, "There is no ruler at this time."); 85134600Sbostic 85234600Sbostic /* search for valar */ 85334600Sbostic fseek(Playersfp, 0L, 0); 85434600Sbostic while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) 85534600Sbostic if (Other.p_specialtype == SC_VALAR && Other.p_status != S_NOTUSED) 85634600Sbostic /* found the valar */ 85734600Sbostic { 85834600Sbostic sprintf(Databuf, "The Valar is %s Login: %s", Other.p_name, Other.p_login); 85934600Sbostic mvaddstr(6, 40 - strlen(Databuf) / 2 , Databuf); 86034600Sbostic break; 86134600Sbostic } 86234600Sbostic 86334600Sbostic /* search for council of the wise */ 86434600Sbostic fseek(Playersfp, 0L, 0); 86534600Sbostic Lines = 10; 86634600Sbostic while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) 86734600Sbostic if (Other.p_specialtype == SC_COUNCIL && Other.p_status != S_NOTUSED) 86834600Sbostic /* found a member of the council */ 86934600Sbostic { 87034600Sbostic if (!councilfound) 87134600Sbostic { 87234600Sbostic mvaddstr(8, 30, "Council of the Wise:"); 87334600Sbostic councilfound = TRUE; 87434600Sbostic } 87534600Sbostic 87634600Sbostic /* This assumes a finite (<=5) number of C.O.W.: */ 87734600Sbostic sprintf(Databuf, "%s Login: %s", Other.p_name, Other.p_login); 87834600Sbostic mvaddstr(Lines++, 40 - strlen(Databuf) / 2, Databuf); 87934600Sbostic } 88034600Sbostic 88134600Sbostic /* search for the two highest players */ 88234600Sbostic nxtname[0] = hiname[0] = '\0'; 88334600Sbostic hiexp = 0.0; 88434600Sbostic nxtlvl = hilvl = 0; 88534600Sbostic 88634600Sbostic fseek(Playersfp, 0L, 0); 88734600Sbostic while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) 88834600Sbostic if (Other.p_experience > hiexp && Other.p_specialtype <= SC_KING && Other.p_status != S_NOTUSED) 88934600Sbostic /* highest found so far */ 89034600Sbostic { 89134600Sbostic nxtexp = hiexp; 89234600Sbostic hiexp = Other.p_experience; 89334600Sbostic nxtlvl = hilvl; 89434600Sbostic hilvl = Other.p_level; 89534600Sbostic strcpy(nxtname, hiname); 89634600Sbostic strcpy(hiname, Other.p_name); 89734600Sbostic } 89834600Sbostic else if (Other.p_experience > nxtexp 89934600Sbostic && Other.p_specialtype <= SC_KING 90034600Sbostic && Other.p_status != S_NOTUSED) 90134600Sbostic /* next highest found so far */ 90234600Sbostic { 90334600Sbostic nxtexp = Other.p_experience; 90434600Sbostic nxtlvl = Other.p_level; 90534600Sbostic strcpy(nxtname, Other.p_name); 90634600Sbostic } 90734600Sbostic 90834600Sbostic mvaddstr(15, 28, "Highest characters are:"); 90934600Sbostic sprintf(Databuf, "%s Level:%.0f and %s Level:%.0f", 91034600Sbostic hiname, hilvl, nxtname, nxtlvl); 91134600Sbostic mvaddstr(17, 40 - strlen(Databuf) / 2, Databuf); 91234600Sbostic 91334600Sbostic /* print last to die */ 91434600Sbostic if ((fp = fopen(Lastdead,"r")) != NULL 91534600Sbostic && fgets(Databuf, SZ_DATABUF, fp) != NULL) 91634600Sbostic { 91734600Sbostic mvaddstr(19, 25, "The last character to die was:"); 91834600Sbostic mvaddstr(20, 40 - strlen(Databuf) / 2,Databuf); 91934600Sbostic fclose(fp); 92034600Sbostic } 92134600Sbostic 92234600Sbostic refresh(); 92334600Sbostic } 92434600Sbostic /**/ 92534600Sbostic /************************************************************************ 92634600Sbostic / 92734600Sbostic / FUNCTION NAME: recallplayer() 92834600Sbostic / 92934600Sbostic / FUNCTION: find a character on file 93034600Sbostic / 93134600Sbostic / AUTHOR: E. A. Estes, 12/4/85 93234600Sbostic / 93334600Sbostic / ARGUMENTS: none 93434600Sbostic / 93534600Sbostic / RETURN VALUE: none 93634600Sbostic / 93734600Sbostic / MODULES CALLED: writerecord(), truncstring(), more(), death(), wmove(), 93834600Sbostic / wclear(), strcmp(), printw(), cleanup(), waddstr(), findname(), mvprintw(), 93934600Sbostic / getanswer(), getstring() 94034600Sbostic / 94134600Sbostic / GLOBAL INPUTS: Player, *stdscr, Databuf[] 94234600Sbostic / 94334600Sbostic / GLOBAL OUTPUTS: Echo, Player 94434600Sbostic / 94534600Sbostic / DESCRIPTION: 94634600Sbostic / Search for a character of a certain name, and check password. 94734600Sbostic / 94834600Sbostic /************************************************************************/ 94934600Sbostic 95034600Sbostic long 95134600Sbostic recallplayer() 95234600Sbostic { 95334600Sbostic long loc = 0L; /* location in player file */ 95434600Sbostic register int loop; /* loop counter */ 95534600Sbostic int ch; /* input */ 95634600Sbostic 95734600Sbostic clear(); 95834600Sbostic mvprintw(10, 0, "What was your character's name ? "); 95934600Sbostic getstring(Databuf, SZ_NAME); 96034600Sbostic truncstring(Databuf); 96134600Sbostic 96234600Sbostic if ((loc = findname(Databuf, &Player)) >= 0L) 96334600Sbostic /* found character */ 96434600Sbostic { 96534600Sbostic Echo = FALSE; 96634600Sbostic 96734600Sbostic for (loop = 0; loop < 2; ++loop) 96834600Sbostic { 96934600Sbostic /* prompt for password */ 97034600Sbostic mvaddstr(11, 0, "Password ? "); 97134600Sbostic getstring(Databuf, SZ_PASSWORD); 97234600Sbostic if (strcmp(Databuf, Player.p_password) == 0) 97334600Sbostic /* password good */ 97434600Sbostic { 97534600Sbostic Echo = TRUE; 97634600Sbostic 97734600Sbostic if (Player.p_status != S_OFF) 97834600Sbostic /* player did not exit normally last time */ 97934600Sbostic { 98034600Sbostic clear(); 98134600Sbostic addstr("Your character did not exit normally last time.\n"); 98234600Sbostic addstr("If you think you have good cause to have your character saved,\n"); 98334600Sbostic printw("you may quit and mail your reason to '%s'.\n", WIZARD); 98434600Sbostic addstr("Otherwise, continuing spells certain death.\n"); 98534600Sbostic addstr("Do you want to quit ? "); 98634600Sbostic ch = getanswer("YN", FALSE); 98734600Sbostic if (ch == 'Y') 98834600Sbostic { 98934600Sbostic Player.p_status = S_HUNGUP; 99034600Sbostic writerecord(&Player, loc); 99134600Sbostic cleanup(TRUE); 99234600Sbostic /*NOTREACHED*/ 99334600Sbostic } 99434600Sbostic death("Stupidity"); 99534600Sbostic /*NOTREACHED*/ 99634600Sbostic } 99734600Sbostic return(loc); 99834600Sbostic } 99934600Sbostic else 100034600Sbostic mvaddstr(12, 0, "No good.\n"); 100134600Sbostic } 100234600Sbostic 100334600Sbostic Echo = TRUE; 100434600Sbostic } 100534600Sbostic else 100634600Sbostic mvaddstr(11, 0, "Not found.\n"); 100734600Sbostic 100834600Sbostic more(13); 100934600Sbostic return(-1L); 101034600Sbostic } 101134600Sbostic /**/ 101234600Sbostic /************************************************************************ 101334600Sbostic / 101434600Sbostic / FUNCTION NAME: neatstuff() 101534600Sbostic / 101634600Sbostic / FUNCTION: do random stuff 101734600Sbostic / 101834600Sbostic / AUTHOR: E. A. Estes, 3/3/86 101934600Sbostic / 102034600Sbostic / ARGUMENTS: none 102134600Sbostic / 102234600Sbostic / RETURN VALUE: none 102334600Sbostic / 102434600Sbostic / MODULES CALLED: collecttaxes(), floor(), wmove(), drandom(), infloat(), 102534600Sbostic / waddstr(), mvprintw(), getanswer() 102634600Sbostic / 102734600Sbostic / GLOBAL INPUTS: Player, *stdscr, *Statptr 102834600Sbostic / 102934600Sbostic / GLOBAL OUTPUTS: Player 103034600Sbostic / 103134600Sbostic / DESCRIPTION: 103234600Sbostic / Handle gurus, medics, etc. 103334600Sbostic / 103434600Sbostic /************************************************************************/ 103534600Sbostic 103634600Sbostic neatstuff() 103734600Sbostic { 103834600Sbostic double temp; /* for temporary calculations */ 103934600Sbostic int ch; /* input */ 104034600Sbostic 104134600Sbostic switch ((int) ROLL(0.0, 100.0)) 104234600Sbostic { 104334600Sbostic case 1: 104434600Sbostic case 2: 104534600Sbostic if (Player.p_poison > 0.0) 104634600Sbostic { 104734600Sbostic mvaddstr(4, 0, "You've found a medic! How much will you offer to be cured ? "); 104834600Sbostic temp = floor(infloat()); 104934600Sbostic if (temp < 0.0 || temp > Player.p_gold) 105034600Sbostic /* negative gold, or more than available */ 105134600Sbostic { 105234600Sbostic mvaddstr(6, 0, "He was not amused, and made you worse.\n"); 105334600Sbostic Player.p_poison += 1.0; 105434600Sbostic } 105534600Sbostic else if (drandom() / 2.0 > (temp + 1.0) / MAX(Player.p_gold, 1)) 105634600Sbostic /* medic wants 1/2 of available gold */ 105734600Sbostic mvaddstr(5, 0, "Sorry, he wasn't interested.\n"); 105834600Sbostic else 105934600Sbostic { 106034600Sbostic mvaddstr(5, 0, "He accepted."); 106134600Sbostic Player.p_poison = MAX(0.0, Player.p_poison - 1.0); 106234600Sbostic Player.p_gold -= temp; 106334600Sbostic } 106434600Sbostic } 106534600Sbostic break; 106634600Sbostic 106734600Sbostic case 3: 106834600Sbostic mvaddstr(4, 0, "You've been caught raping and pillaging!\n"); 106934600Sbostic Player.p_experience += 4000.0; 107034600Sbostic Player.p_sin += 0.5; 107134600Sbostic break; 107234600Sbostic 107334600Sbostic case 4: 107434600Sbostic temp = ROLL(10.0, 75.0); 107534600Sbostic mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp); 107634600Sbostic ch = getanswer("NY", FALSE); 107734600Sbostic 107834600Sbostic if (ch == 'Y') 107934600Sbostic collecttaxes(temp, 0.0); 108034600Sbostic break; 108134600Sbostic 108234600Sbostic case 5: 108334600Sbostic if (Player.p_sin > 1.0) 108434600Sbostic { 108534600Sbostic mvaddstr(4, 0, "You've found a Holy Orb!\n"); 108634600Sbostic Player.p_sin -= 0.25; 108734600Sbostic } 108834600Sbostic break; 108934600Sbostic 109034600Sbostic case 6: 109134600Sbostic if (Player.p_poison < 1.0) 109234600Sbostic { 109334600Sbostic mvaddstr(4, 0, "You've been hit with a plague!\n"); 109434600Sbostic Player.p_poison += 1.0; 109534600Sbostic } 109634600Sbostic break; 109734600Sbostic 109834600Sbostic case 7: 109934600Sbostic mvaddstr(4, 0, "You've found some holy water.\n"); 110034600Sbostic ++Player.p_holywater; 110134600Sbostic break; 110234600Sbostic 110334600Sbostic case 8: 110434600Sbostic mvaddstr(4, 0, "You've met a Guru. . ."); 110534600Sbostic if (drandom() * Player.p_sin > 1.0) 110634600Sbostic addstr("You disgusted him with your sins!\n"); 110734600Sbostic else if (Player.p_poison > 0.0) 110834600Sbostic { 110934600Sbostic addstr("He looked kindly upon you, and cured you.\n"); 111034600Sbostic Player.p_poison = 0.0; 111134600Sbostic } 111234600Sbostic else 111334600Sbostic { 111434600Sbostic addstr("He rewarded you for your virtue.\n"); 111534600Sbostic Player.p_mana += 50.0; 111634600Sbostic Player.p_shield += 2.0; 111734600Sbostic } 111834600Sbostic break; 111934600Sbostic 112034600Sbostic case 9: 112134600Sbostic mvaddstr(4, 0, "You've found an amulet.\n"); 112234600Sbostic ++Player.p_amulets; 112334600Sbostic break; 112434600Sbostic 112534600Sbostic case 10: 112634600Sbostic if (Player.p_blindness) 112734600Sbostic { 112834600Sbostic mvaddstr(4, 0, "You've regained your sight!\n"); 112934600Sbostic Player.p_blindness = FALSE; 113034600Sbostic } 113134600Sbostic break; 113234600Sbostic 113334600Sbostic default: /* deal with poison */ 113434600Sbostic if (Player.p_poison > 0.0) 113534600Sbostic { 113634600Sbostic temp = Player.p_poison * Statptr->c_weakness 113734600Sbostic * Player.p_maxenergy / 600.0; 113834600Sbostic if (Player.p_energy > Player.p_maxenergy / 10.0 113934600Sbostic && temp + 5.0 < Player.p_energy) 114034600Sbostic Player.p_energy -= temp; 114134600Sbostic } 114234600Sbostic break; 114334600Sbostic } 114434600Sbostic } 114534600Sbostic /**/ 114634600Sbostic /************************************************************************ 114734600Sbostic / 114834600Sbostic / FUNCTION NAME: genchar() 114934600Sbostic / 115034600Sbostic / FUNCTION: generate a random character 115134600Sbostic / 115234600Sbostic / AUTHOR: E. A. Estes, 12/4/85 115334600Sbostic / 115434600Sbostic / ARGUMENTS: 115534600Sbostic / int type - ASCII value of character type to generate 115634600Sbostic / 115734600Sbostic / RETURN VALUE: none 115834600Sbostic / 115934600Sbostic / MODULES CALLED: floor(), drandom() 116034600Sbostic / 116134600Sbostic / GLOBAL INPUTS: Wizard, Player, Stattable[] 116234600Sbostic / 116334600Sbostic / GLOBAL OUTPUTS: Player 116434600Sbostic / 116534600Sbostic / DESCRIPTION: 116634600Sbostic / Use the lookup table for rolling stats. 116734600Sbostic / 116834600Sbostic /************************************************************************/ 116934600Sbostic 117034600Sbostic genchar(type) 117134600Sbostic int type; 117234600Sbostic { 117334600Sbostic register int subscript; /* used for subscripting into Stattable */ 117434600Sbostic register struct charstats *statptr;/* for pointing into Stattable */ 117534600Sbostic 117634600Sbostic subscript = type - '1'; 117734600Sbostic 117834600Sbostic if (subscript < C_MAGIC || subscript > C_EXPER) 117934600Sbostic if (subscript != C_SUPER || !Wizard) 118034600Sbostic /* fighter is default */ 118134600Sbostic subscript = C_FIGHTER; 118234600Sbostic 118334600Sbostic statptr = &Stattable[subscript]; 118434600Sbostic 118534600Sbostic Player.p_quickness = 118634600Sbostic ROLL(statptr->c_quickness.base, statptr->c_quickness.interval); 118734600Sbostic Player.p_strength = 118834600Sbostic ROLL(statptr->c_strength.base, statptr->c_strength.interval); 118934600Sbostic Player.p_mana = 119034600Sbostic ROLL(statptr->c_mana.base, statptr->c_mana.interval); 119134600Sbostic Player.p_maxenergy = 119234600Sbostic Player.p_energy = 119334600Sbostic ROLL(statptr->c_energy.base, statptr->c_energy.interval); 119434600Sbostic Player.p_brains = 119534600Sbostic ROLL(statptr->c_brains.base, statptr->c_brains.interval); 119634600Sbostic Player.p_magiclvl = 119734600Sbostic ROLL(statptr->c_magiclvl.base, statptr->c_magiclvl.interval); 119834600Sbostic 119934600Sbostic Player.p_type = subscript; 120034600Sbostic 120134600Sbostic if (Player.p_type == C_HALFLING) 120234600Sbostic /* give halfling some experience */ 120334600Sbostic Player.p_experience = ROLL(600.0, 200.0); 120434600Sbostic } 120534600Sbostic /**/ 120634600Sbostic /************************************************************************ 120734600Sbostic / 120834600Sbostic / FUNCTION NAME: playinit() 120934600Sbostic / 121034600Sbostic / FUNCTION: initialize for playing game 121134600Sbostic / 121234600Sbostic / AUTHOR: E. A. Estes, 12/4/85 121334600Sbostic / 121434600Sbostic / ARGUMENTS: none 121534600Sbostic / 121634600Sbostic / RETURN VALUE: none 121734600Sbostic / 121834600Sbostic / MODULES CALLED: signal(), wclear(), noecho(), crmode(), initscr(), 121934600Sbostic / wrefresh() 122034600Sbostic / 122134600Sbostic / GLOBAL INPUTS: *stdscr, ill_sig() 122234600Sbostic / 122334600Sbostic / GLOBAL OUTPUTS: Windows 122434600Sbostic / 122534600Sbostic / DESCRIPTION: 122634600Sbostic / Catch a bunch of signals, and turn on curses stuff. 122734600Sbostic / 122834600Sbostic /************************************************************************/ 122934600Sbostic 123034600Sbostic playinit() 123134600Sbostic { 123234600Sbostic /* catch/ingnore signals */ 123334600Sbostic 123434600Sbostic #ifdef BSD41 123534600Sbostic sigignore(SIGQUIT); 123634600Sbostic sigignore(SIGALRM); 123734600Sbostic sigignore(SIGTERM); 123834600Sbostic sigignore(SIGTSTP); 123934600Sbostic sigignore(SIGTTIN); 124034600Sbostic sigignore(SIGTTOU); 124134600Sbostic sighold(SIGINT); 124234600Sbostic sigset(SIGHUP, ill_sig); 124334600Sbostic sigset(SIGTRAP, ill_sig); 124434600Sbostic sigset(SIGIOT, ill_sig); 124534600Sbostic sigset(SIGEMT, ill_sig); 124634600Sbostic sigset(SIGFPE, ill_sig); 124734600Sbostic sigset(SIGBUS, ill_sig); 124834600Sbostic sigset(SIGSEGV, ill_sig); 124934600Sbostic sigset(SIGSYS, ill_sig); 125034600Sbostic sigset(SIGPIPE, ill_sig); 125134600Sbostic #endif 125234600Sbostic #ifdef BSD42 125334600Sbostic signal(SIGQUIT, ill_sig); 125434600Sbostic signal(SIGALRM, SIG_IGN); 125534600Sbostic signal(SIGTERM, SIG_IGN); 125634600Sbostic signal(SIGTSTP, SIG_IGN); 125734600Sbostic signal(SIGTTIN, SIG_IGN); 125834600Sbostic signal(SIGTTOU, SIG_IGN); 125934600Sbostic signal(SIGINT, ill_sig); 126034600Sbostic signal(SIGHUP, SIG_DFL); 126134600Sbostic signal(SIGTRAP, ill_sig); 126234600Sbostic signal(SIGIOT, ill_sig); 126334600Sbostic signal(SIGEMT, ill_sig); 126434600Sbostic signal(SIGFPE, ill_sig); 126534600Sbostic signal(SIGBUS, ill_sig); 126634600Sbostic signal(SIGSEGV, ill_sig); 126734600Sbostic signal(SIGSYS, ill_sig); 126834600Sbostic signal(SIGPIPE, ill_sig); 126934600Sbostic #endif 127034600Sbostic #ifdef SYS3 127134600Sbostic signal(SIGINT, SIG_IGN); 127234600Sbostic signal(SIGQUIT, SIG_IGN); 127334600Sbostic signal(SIGTERM, SIG_IGN); 127434600Sbostic signal(SIGALRM, SIG_IGN); 127534600Sbostic signal(SIGHUP, ill_sig); 127634600Sbostic signal(SIGTRAP, ill_sig); 127734600Sbostic signal(SIGIOT, ill_sig); 127834600Sbostic signal(SIGEMT, ill_sig); 127934600Sbostic signal(SIGFPE, ill_sig); 128034600Sbostic signal(SIGBUS, ill_sig); 128134600Sbostic signal(SIGSEGV, ill_sig); 128234600Sbostic signal(SIGSYS, ill_sig); 128334600Sbostic signal(SIGPIPE, ill_sig); 128434600Sbostic #endif 128534600Sbostic #ifdef SYS5 128634600Sbostic signal(SIGINT, SIG_IGN); 128734600Sbostic signal(SIGQUIT, SIG_IGN); 128834600Sbostic signal(SIGTERM, SIG_IGN); 128934600Sbostic signal(SIGALRM, SIG_IGN); 129034600Sbostic signal(SIGHUP, ill_sig); 129134600Sbostic signal(SIGTRAP, ill_sig); 129234600Sbostic signal(SIGIOT, ill_sig); 129334600Sbostic signal(SIGEMT, ill_sig); 129434600Sbostic signal(SIGFPE, ill_sig); 129534600Sbostic signal(SIGBUS, ill_sig); 129634600Sbostic signal(SIGSEGV, ill_sig); 129734600Sbostic signal(SIGSYS, ill_sig); 129834600Sbostic signal(SIGPIPE, ill_sig); 129934600Sbostic #endif 130034600Sbostic 130134600Sbostic initscr(); /* turn on curses */ 130234600Sbostic noecho(); /* do not echo input */ 130334600Sbostic crmode(); /* do not process erase, kill */ 130434600Sbostic clear(); 130534600Sbostic refresh(); 130634600Sbostic Windows = TRUE; /* mark the state */ 130734600Sbostic } 130834600Sbostic 130934600Sbostic /**/ 131034600Sbostic /************************************************************************ 131134600Sbostic / 131234600Sbostic / FUNCTION NAME: cleanup() 131334600Sbostic / 131434600Sbostic / FUNCTION: close some files, and maybe exit 131534600Sbostic / 131634600Sbostic / AUTHOR: E. A. Estes, 12/4/85 131734600Sbostic / 131834600Sbostic / ARGUMENTS: 131934600Sbostic / bool doexit - exit flag 132034600Sbostic / 132134600Sbostic / RETURN VALUE: none 132234600Sbostic / 132334600Sbostic / MODULES CALLED: exit(), wmove(), fclose(), endwin(), nocrmode(), wrefresh() 132434600Sbostic / 132534600Sbostic / GLOBAL INPUTS: *Energyvoidfp, LINES, *stdscr, Windows, *Monstfp, 132634600Sbostic / *Messagefp, *Playersfp 132734600Sbostic / 132834600Sbostic / GLOBAL OUTPUTS: none 132934600Sbostic / 133034600Sbostic / DESCRIPTION: 133134600Sbostic / Close all open files. If we are "in curses" terminate curses. 133234600Sbostic / If 'doexit' is set, exit, otherwise return. 133334600Sbostic / 133434600Sbostic /************************************************************************/ 133534600Sbostic 133634600Sbostic cleanup(doexit) 133734600Sbostic bool doexit; 133834600Sbostic { 133934600Sbostic if (Windows) 134034600Sbostic { 134134600Sbostic move(LINES - 2, 0); 134234600Sbostic refresh(); 134334600Sbostic nocrmode(); 134434600Sbostic endwin(); 134534600Sbostic } 134634600Sbostic 134734600Sbostic fclose(Playersfp); 134834600Sbostic fclose(Monstfp); 134934600Sbostic fclose(Messagefp); 135034600Sbostic fclose(Energyvoidfp); 135134600Sbostic 135234600Sbostic if (doexit) 135334600Sbostic exit(0); 135434600Sbostic /*NOTREACHED*/ 135534600Sbostic } 1356