xref: /dragonfly/games/larn/tok.c (revision a632cd2d33eae3cdf365948061576a303057c733)
1 /* tok.c            Larn is copyrighted 1986 by Noah Morgan. */
2 /* $FreeBSD: src/games/larn/tok.c,v 1.5 1999/11/16 02:57:25 billf Exp $ */
3 #include <sys/types.h>
4 #include <sys/ioctl.h>
5 #include <sys/wait.h>
6 #include "header.h"
7 
8 /* Keystrokes (roughly) between checkpoints */
9 #define CHECKPOINT_INTERVAL   400
10 
11 static char lastok = 0;
12 int yrepcount = 0, dayplay = 0;
13 #ifndef FLUSHNO
14 #define FLUSHNO 5
15 #endif /* FLUSHNO */
16 static int flushno = FLUSHNO; /* input queue flushing threshold */
17 #define MAXUM 52              /* maximum number of user re-named monsters */
18 #define MAXMNAME 40           /* max length of a monster re-name */
19 static char usermonster[MAXUM][MAXMNAME];         /* the user named monster name goes here */
20 static char usermpoint = 0;   /* the user monster pointer */
21 
22 /*
23           lexical analyzer for larn
24  */
25 int
yylex(void)26 yylex(void)
27 {
28           char cc;
29           int ic;
30           if (hit2flag) {
31                     hit2flag = 0;
32                     yrepcount = 0;
33                     return (' ');
34           }
35           if (yrepcount > 0) {
36                     --yrepcount;
37                     return (lastok);
38           } else
39                     yrepcount = 0;
40           if (yrepcount == 0) {
41                     bottomdo();
42                     showplayer();
43           }                             /* show where the player is */
44           lflush();
45           while (1) {
46                     c[BYTESIN]++;
47                     /* check for periodic checkpointing */
48                     if (ckpflag)
49                               if ((c[BYTESIN] % CHECKPOINT_INTERVAL) == 0) {
50 #ifndef DOCHECKPOINTS
51                                         savegame(ckpfile);
52 #else
53                                         wait(0);  /* wait for other forks to finish */
54                                         if (fork() == 0) {
55                                                   savegame(ckpfile);
56                                                   exit(0);
57                                         }
58 #endif
59 #ifdef TIMECHECK
60                                         if (dayplay == 0)
61                                                   if (playable()) {
62                                                             cursor(1, 19);
63                                                             lprcat("\nSorry, but it is now time for work.  Your game has been saved.\n");
64                                                             beep();
65                                                             lflush();
66                                                             savegame(savefilename);
67                                                             wizard = nomove = 1;
68                                                             sleep(4);
69                                                             died(-257);
70                                                   }
71 #endif /* TIMECHECK */
72                               }
73 
74                     do {                /* if keyboard input buffer is too big, flush some of it */
75                               ioctl(0, FIONREAD, &ic);
76                               if (ic > flushno)
77                                         read(0, &cc, 1);
78                     } while (ic > flushno);
79 
80                     if (read(0, &cc, 1) != 1)
81                               return (lastok = -1);
82 
83                     if (cc == 'Y' - 64) {         /* control Y -- shell escape */
84                               resetscroll();
85                               clear();  /* scrolling region, home, clear, no attributes */
86                               if ((ic = fork()) == 0) {     /* child */
87                                         /* revoke */
88                                         setgid(getgid());
89                                         execl("/bin/csh", "csh", NULL);
90                                         exit(1);
91                               }
92                               wait(0);
93                               if (ic < 0) {       /* error */
94                                         write(2, "Can't fork off a shell!\n", 25);
95                                         sleep(2);
96                               }
97 
98                               setscroll();
99                               return (lastok = 'L' - 64);   /* redisplay screen */
100                     }
101 
102                     if ((cc <= '9') && (cc >= '0')) {
103                               yrepcount = yrepcount * 10 + cc - '0';
104                     } else {
105                               if (yrepcount > 0)
106                                         --yrepcount;
107                               return (lastok = cc);
108                     }
109           }
110 }
111 
112 /*
113  *        flushall()                    Function to flush all type-ahead in the input buffer
114  */
115 void
flushall(void)116 flushall(void)
117 {
118           char cc;
119           int ic;
120           for (;;) {                    /* if keyboard input buffer is too big, flush some of it */
121                     ioctl(0, FIONREAD, &ic);
122                     if (ic <= 0)
123                               return;
124                     while (ic > 0) {
125                               read(0, &cc, 1);
126                               --ic;
127                     }                   /* gobble up the byte */
128           }
129 }
130 
131 /*
132           function to set the desired hardness
133           enter with hard= -1 for default hardness, else any desired hardness
134  */
135 void
sethard(int hard)136 sethard(int hard)
137 {
138           int j, k, i;
139           j = c[HARDGAME];
140           hashewon();
141           if (restorflag == 0) {        /* don't set c[HARDGAME] if restoring game */
142                     if (hard >= 0)
143                               c[HARDGAME] = hard;
144           } else
145                     c[HARDGAME] = j;    /* set c[HARDGAME] to proper value if restoring game */
146 
147           if ((k = c[HARDGAME]) != 0)
148                     for (j = 0; j <= MAXMONST + 8; j++) {
149                               i = ((6 + k) * monster[j].hitpoints + 1) / 6;
150                               monster[j].hitpoints = (i < 0) ? 32767 : i;
151                               i = ((6 + k) * monster[j].damage + 1) / 5;
152                               monster[j].damage = (i > 127) ? 127 : i;
153                               i = (10 * monster[j].gold) / (10 + k);
154                               monster[j].gold = (i > 32767) ? 32767 : i;
155                               i = monster[j].armorclass - k;
156                               monster[j].armorclass = (i < -127) ? -127 : i;
157                               i = (7 * monster[j].experience) / (7 + k) + 1;
158                               monster[j].experience = (i <= 0) ? 1 : i;
159                     }
160 }
161 
162 /*
163           function to read and process the larn options file
164  */
165 void
readopts(void)166 readopts(void)
167 {
168           char *i;
169           int j, k;
170           int flag;
171 
172           flag = 1;           /* set to 0 if a name is specified */
173           if (lopen(optsfile) < 0) {
174                     strcpy(logname, loginname);
175                     return;                            /* user name if no character name */
176           }
177           do {
178                     if ((i = (char *)lgetw()) == NULL)
179                               break;    /* check for EOF */
180                     while ((*i == ' ') || (*i == '\t'))
181                               i++;      /* eat leading whitespace */
182                     switch (*i) {
183                     case 'b':
184                               if (strcmp(i, "bold-objects") == 0)
185                                         boldon = 1;
186                               break;
187 
188                     case 'e':
189                               if (strcmp(i, "enable-checkpointing") == 0)
190                                         ckpflag = 1;
191                               break;
192 
193                     case 'i':
194                               if (strcmp(i, "inverse-objects") == 0)
195                                         boldon = 0;
196                               break;
197 
198                     case 'f':
199                               if (strcmp(i, "female") == 0)
200                                         sex = 0;  /* male or female */
201                               break;
202 
203                     case 'm':
204                               if (strcmp(i, "monster:") == 0) {       /* name favorite monster */
205                                         if ((i = lgetw()) == NULL)
206                                                   break;
207                                         if (strlen(i) >= MAXMNAME)
208                                                   i[MAXMNAME - 1] = 0;
209                                         strcpy(usermonster[(int)usermpoint], i);
210                                         if (usermpoint >= MAXUM)
211                                                   break;              /* defined all of em */
212                                         if (isalpha(j = usermonster[(int)usermpoint][0])) {
213                                                   for (k = 1; k < MAXMONST + 8; k++)      /* find monster */
214                                                             if (monstnamelist[k] == j) {
215                                                                       monster[k].name = &usermonster[(int)usermpoint++][0];
216                                                                       break;
217                                                             }
218                                         }
219                               } else if (strcmp(i, "male") == 0)
220                                         sex = 1;
221                               break;
222 
223                     case 'n':
224                               if (strcmp(i, "name:") == 0) {          /* defining players name */
225                                         if ((i = lgetw()) == NULL)
226                                                   break;
227                                         if (strlen(i) >= LOGNAMESIZE) i[LOGNAMESIZE - 1] = 0;
228                                         strcpy(logname, i);
229                                         flag = 0;
230                               } else if (strcmp(i, "no-introduction") == 0)
231                                         nowelcome = 1;
232                               else if (strcmp(i, "no-beep") == 0)
233                                         nobeep = 1;
234                               break;
235 
236                     case 'p':
237                               if (strcmp(i, "process-name:") == 0) {
238                                         if ((i = lgetw()) == NULL)
239                                                   break;
240                                         if (strlen(i) >= PSNAMESIZE)
241                                                   i[PSNAMESIZE - 1] = 0;
242                                         strcpy(psname, i);
243                               } else if (strcmp(i, "play-day-play") == 0)
244                                         dayplay = 1;
245                               break;
246 
247                     case 's':
248                               if (strcmp(i, "savefile:") == 0) {      /* defining savefilename */
249                                         if ((i = lgetw()) == NULL)
250                                                   break;
251                                         strcpy(savefilename, i);
252                                         flag = 0;
253                               }
254                               break;
255                     }
256           } while (*i);
257           if (flag)
258                     strcpy(logname, loginname);
259 }
260