Commit | Line | Data |
---|---|---|
984263bc MD |
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> | |
984263bc | 4 | #include <sys/ioctl.h> |
6693db17 | 5 | #include <sys/wait.h> |
984263bc MD |
6 | #include "header.h" |
7 | ||
6693db17 SW |
8 | /* Keystrokes (roughly) between checkpoints */ |
9 | #define CHECKPOINT_INTERVAL 400 | |
10 | ||
11 | static char lastok = 0; | |
12 | int yrepcount = 0, dayplay = 0; | |
984263bc MD |
13 | #ifndef FLUSHNO |
14 | #define FLUSHNO 5 | |
69e9165e | 15 | #endif /* FLUSHNO */ |
6693db17 SW |
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 */ | |
984263bc MD |
21 | |
22 | /* | |
23 | lexical analyzer for larn | |
24 | */ | |
88fe92e6 PA |
25 | int |
26 | yylex(void) | |
6693db17 | 27 | { |
984263bc MD |
28 | char cc; |
29 | int ic; | |
6693db17 SW |
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 */ | |
984263bc | 44 | lflush(); |
6693db17 | 45 | while (1) { |
984263bc | 46 | c[BYTESIN]++; |
6693db17 | 47 | /* check for periodic checkpointing */ |
984263bc | 48 | if (ckpflag) |
6693db17 | 49 | if ((c[BYTESIN] % CHECKPOINT_INTERVAL) == 0) { |
984263bc | 50 | #ifndef DOCHECKPOINTS |
6693db17 | 51 | savegame(ckpfile); |
984263bc | 52 | #else |
6693db17 SW |
53 | wait(0); /* wait for other forks to finish */ |
54 | if (fork() == 0) { | |
55 | savegame(ckpfile); | |
56 | exit(0); | |
57 | } | |
984263bc | 58 | #endif |
984263bc | 59 | #ifdef TIMECHECK |
6693db17 SW |
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 | } | |
69e9165e | 71 | #endif /* TIMECHECK */ |
984263bc MD |
72 | } |
73 | ||
6693db17 SW |
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); | |
984263bc | 79 | |
6693db17 SW |
80 | if (read(0, &cc, 1) != 1) |
81 | return (lastok = -1); | |
984263bc | 82 | |
6693db17 SW |
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 */ | |
984263bc MD |
87 | /* revoke */ |
88 | setgid(getgid()); | |
6693db17 SW |
89 | execl("/bin/csh", "csh", NULL); |
90 | exit(1); | |
91 | } | |
984263bc | 92 | wait(0); |
6693db17 SW |
93 | if (ic < 0) { /* error */ |
94 | write(2, "Can't fork off a shell!\n", 25); | |
95 | sleep(2); | |
96 | } | |
984263bc MD |
97 | |
98 | setscroll(); | |
6693db17 SW |
99 | return (lastok = 'L' - 64); /* redisplay screen */ |
100 | } | |
984263bc | 101 | |
6693db17 SW |
102 | if ((cc <= '9') && (cc >= '0')) { |
103 | yrepcount = yrepcount * 10 + cc - '0'; | |
104 | } else { | |
105 | if (yrepcount > 0) | |
106 | --yrepcount; | |
107 | return (lastok = cc); | |
984263bc MD |
108 | } |
109 | } | |
6693db17 | 110 | } |
984263bc MD |
111 | |
112 | /* | |
113 | * flushall() Function to flush all type-ahead in the input buffer | |
114 | */ | |
88fe92e6 PA |
115 | void |
116 | flushall(void) | |
6693db17 | 117 | { |
984263bc MD |
118 | char cc; |
119 | int ic; | |
6693db17 SW |
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 */ | |
984263bc | 128 | } |
6693db17 | 129 | } |
984263bc MD |
130 | |
131 | /* | |
132 | function to set the desired hardness | |
133 | enter with hard= -1 for default hardness, else any desired hardness | |
134 | */ | |
88fe92e6 PA |
135 | void |
136 | sethard(int hard) | |
6693db17 SW |
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; | |
984263bc | 159 | } |
6693db17 | 160 | } |
984263bc MD |
161 | |
162 | /* | |
163 | function to read and process the larn options file | |
164 | */ | |
88fe92e6 PA |
165 | void |
166 | readopts(void) | |
6693db17 | 167 | { |
984263bc | 168 | char *i; |
6693db17 | 169 | int j, k; |
984263bc | 170 | int flag; |
984263bc | 171 | |
6693db17 SW |
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 { | |
678e8cc6 | 178 | if ((i = (char *)lgetw()) == NULL) |
6693db17 SW |
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; | |
984263bc | 187 | |
6693db17 SW |
188 | case 'e': |
189 | if (strcmp(i, "enable-checkpointing") == 0) | |
190 | ckpflag = 1; | |
191 | break; | |
984263bc | 192 | |
6693db17 SW |
193 | case 'i': |
194 | if (strcmp(i, "inverse-objects") == 0) | |
195 | boldon = 0; | |
196 | break; | |
984263bc | 197 | |
6693db17 SW |
198 | case 'f': |
199 | if (strcmp(i, "female") == 0) | |
200 | sex = 0; /* male or female */ | |
201 | break; | |
984263bc | 202 | |
6693db17 SW |
203 | case 'm': |
204 | if (strcmp(i, "monster:") == 0) { /* name favorite monster */ | |
678e8cc6 | 205 | if ((i = lgetw()) == NULL) |
984263bc | 206 | break; |
6693db17 SW |
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; | |
984263bc | 217 | } |
6693db17 SW |
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 */ | |
678e8cc6 | 225 | if ((i = lgetw()) == NULL) |
984263bc | 226 | break; |
6693db17 SW |
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; | |
984263bc | 235 | |
6693db17 SW |
236 | case 'p': |
237 | if (strcmp(i, "process-name:") == 0) { | |
678e8cc6 | 238 | if ((i = lgetw()) == NULL) |
984263bc | 239 | break; |
6693db17 SW |
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; | |
984263bc | 246 | |
6693db17 SW |
247 | case 's': |
248 | if (strcmp(i, "savefile:") == 0) { /* defining savefilename */ | |
678e8cc6 | 249 | if ((i = lgetw()) == NULL) |
6693db17 SW |
250 | break; |
251 | strcpy(savefilename, i); | |
252 | flag = 0; | |
253 | } | |
254 | break; | |
255 | } | |
256 | } while (*i); | |
257 | if (flag) | |
258 | strcpy(logname, loginname); | |
259 | } |