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