Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison src/cluecheck.c @ 2:2719a89505ba
First entry of Paradise Server 2.9 patch 10 Beta
author | darius |
---|---|
date | Sat, 06 Dec 1997 04:37:01 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:4d6502ffaa5e | 2:2719a89505ba |
---|---|
1 /*-------------------------------------------------------------------------- | |
2 NETREK II -- Paradise | |
3 | |
4 Permission to use, copy, modify, and distribute this software and its | |
5 documentation, or any derivative works thereof, for any NON-COMMERCIAL | |
6 purpose and without fee is hereby granted, provided that this copyright | |
7 notice appear in all copies. No representations are made about the | |
8 suitability of this software for any purpose. This software is provided | |
9 "as is" without express or implied warranty. | |
10 | |
11 Xtrek Copyright 1986 Chris Guthrie | |
12 Netrek (Xtrek II) Copyright 1989 Kevin P. Smith | |
13 Scott Silvey | |
14 Paradise II (Netrek II) Copyright 1993 Larry Denys | |
15 Kurt Olsen | |
16 Brandon Gillespie | |
17 --------------------------------------------------------------------------*/ | |
18 | |
19 #include "config.h" | |
20 #include <stdio.h> | |
21 #include <sys/types.h> | |
22 #include <sys/stat.h> | |
23 #include "defs.h" | |
24 #include "data.h" | |
25 #include "struct.h" | |
26 #include "shmem.h" | |
27 | |
28 #ifdef CLUECHECK1 | |
29 | |
30 /* ----------------- ROBS CLUECHECK -------------------- */ | |
31 | |
32 static char clueword[40]; | |
33 | |
34 void | |
35 set_clue_word(word) | |
36 char *word; | |
37 { | |
38 strncpy(clueword, word, sizeof(clueword)); | |
39 clueword[sizeof(clueword) - 1] = 0; | |
40 } | |
41 | |
42 #ifdef MOTD_SUPPORT | |
43 static char *motdstring = 0; | |
44 static int motdlen = 0; | |
45 | |
46 void free_motdstruct(); | |
47 #endif | |
48 | |
49 /* read the MOTD into core so we can parse it later */ | |
50 void | |
51 init_motdbuf(fname) | |
52 char *fname; | |
53 { | |
54 #ifdef MOTD_SUPPORT | |
55 struct stat stats; | |
56 FILE *fp; | |
57 | |
58 if (motdstring != 0) | |
59 { | |
60 free_motdstruct(); | |
61 free(motdstring); | |
62 motdstring = 0; | |
63 motdlen = 0; | |
64 } | |
65 | |
66 if (!configvals->cluecheck || | |
67 configvals->cluecheck != CC_MOTD) | |
68 return; /* don't waste the memory if we're not clue | |
69 * checking from the MOTD */ | |
70 | |
71 if (0 > stat(fname, &stats)) | |
72 { | |
73 perror("statting file"); | |
74 return; | |
75 } | |
76 | |
77 motdlen = stats.st_size; | |
78 | |
79 motdstring = (char *) malloc(motdlen + 1); | |
80 fp = fopen(fname, "r"); | |
81 if (0 == fp) | |
82 { | |
83 perror("opening file"); | |
84 exit(1); | |
85 } | |
86 fread(motdstring, motdlen, 1, fp); | |
87 #endif | |
88 } | |
89 | |
90 static int page; | |
91 static int isfirst; | |
92 | |
93 #ifdef MOTD_SUPPORT | |
94 | |
95 static int line, wordn; | |
96 | |
97 /* structures for the internal representation of the MOTD */ | |
98 #define LINESPERPAGE 38 | |
99 | |
100 struct word | |
101 { | |
102 char *s; | |
103 }; | |
104 | |
105 struct line | |
106 { | |
107 struct word *words; | |
108 int nwords; | |
109 }; | |
110 | |
111 struct page | |
112 { | |
113 struct line lines[LINESPERPAGE]; | |
114 int nlines; | |
115 struct page *next; | |
116 }; | |
117 | |
118 struct page *motdhead = 0; | |
119 | |
120 | |
121 | |
122 #define MAXATTEMPTS 10 | |
123 void | |
124 find_suitable_motd_word() | |
125 { | |
126 int attempts; | |
127 int pagecount; | |
128 int i; | |
129 struct page *currp; | |
130 | |
131 | |
132 for (pagecount = 0, currp = motdhead; | |
133 currp; | |
134 pagecount++, currp = currp->next) | |
135 ; | |
136 | |
137 if (pagecount > 10) | |
138 pagecount = 10; | |
139 | |
140 for (attempts = 0; pagecount > 1 && attempts < MAXATTEMPTS; attempts++) | |
141 { | |
142 /* the first page is excluded. Everybody sees that */ | |
143 page = 1 + lrand48() % (pagecount - 1); | |
144 | |
145 for (i = 0, currp = motdhead; i < page; i++, currp = currp->next) | |
146 ; | |
147 if (currp->nlines < 1) | |
148 continue; | |
149 if (lrand48() & 1) | |
150 { | |
151 /* get first word */ | |
152 isfirst = 1; | |
153 for (line = 0; line < currp->nlines; line++) | |
154 if (currp->lines[line].nwords > 0) | |
155 break; | |
156 if (line >= currp->nlines) | |
157 continue; | |
158 wordn = 0; | |
159 } | |
160 else | |
161 { | |
162 /* get last word */ | |
163 isfirst = 0; | |
164 for (line = currp->nlines - 1; line >= 0; line--) | |
165 if (currp->lines[line].nwords > 0) | |
166 break; | |
167 if (line < 0) | |
168 continue; | |
169 wordn = currp->lines[line].nwords - 1; | |
170 } | |
171 set_clue_word(currp->lines[line].words[wordn].s); | |
172 /* | |
173 * printf("%s word on page %d (line %d word %d) is %s\n", | |
174 * isfirst?"first":"last", page+1, line+1, wordn+1, clueword); | |
175 */ | |
176 return; | |
177 } | |
178 page = -1; | |
179 } | |
180 | |
181 #if 0 | |
182 /* for the day when we have line numbers in the MOTD. */ | |
183 void | |
184 find_suitable_word2() | |
185 { | |
186 int attempts; | |
187 int pagecount; | |
188 int i; | |
189 struct page *currp; | |
190 | |
191 | |
192 for (pagecount = 0, currp = motdhead; currp; pagecount++, currp = currp->next) | |
193 ; | |
194 | |
195 for (attempts = 0; attempts < 10; attempts++) | |
196 { | |
197 page = lrand48() % pagecount; | |
198 for (i = 0, currp = motdhead; i < page; i++, currp = currp->next) | |
199 ; | |
200 if (currp->nlines < 1) | |
201 continue; | |
202 line = lrand48() % currp->nlines; | |
203 if (currp->lines[line].nwords < 1) | |
204 continue; | |
205 wordn = lrand48() % currp->lines[line].nwords; | |
206 set_clue_word(currp->lines[line].words[wordn].s); | |
207 printf("word on page %d line %d word %d is %s\n", | |
208 page + 1, line + 1, wordn + 1, clueword); | |
209 return; | |
210 } | |
211 clueword[0] = 0; | |
212 } | |
213 #endif | |
214 | |
215 #if 0 | |
216 /* useful for debugging the MOTD parsing routine */ | |
217 void | |
218 printout_motd() | |
219 { | |
220 struct page *currp; | |
221 int i, j; | |
222 for (currp = motdhead; currp; currp = currp->next) | |
223 { | |
224 for (i = 0; i < currp->nlines; i++) | |
225 { | |
226 for (j = 0; j < currp->lines[i].nwords; j++) | |
227 { | |
228 printf("%s ", currp->lines[i].words[j].s); | |
229 } | |
230 printf("\n"); | |
231 } | |
232 printf("\014"); | |
233 } | |
234 } | |
235 #endif | |
236 | |
237 | |
238 void | |
239 parse_motd() | |
240 { | |
241 struct page **currp; | |
242 int idx; | |
243 | |
244 if (motdhead) | |
245 return; | |
246 | |
247 currp = &motdhead; | |
248 | |
249 idx = 0; | |
250 while (idx < motdlen) | |
251 { | |
252 int validword; | |
253 char *wordbegin; | |
254 | |
255 validword = 1; | |
256 | |
257 /* skip whitespace */ | |
258 while (!isalpha(motdstring[idx]) && motdstring[idx] != '\n' && idx < motdlen) | |
259 idx++; | |
260 if (idx >= motdlen) | |
261 break; | |
262 | |
263 if (0 == *currp) | |
264 { | |
265 *currp = malloc(sizeof(**currp)); | |
266 (*currp)->nlines = 1; | |
267 (*currp)->lines[0].nwords = 0; | |
268 (*currp)->next = 0; | |
269 } | |
270 | |
271 if (motdstring[idx] == '\n') | |
272 { | |
273 idx++; | |
274 if (0 == strncmp(&motdstring[idx], "\t@@@", 4)) | |
275 break; | |
276 else if (0 == strncmp(&motdstring[idx], "\t@@b", 4)) | |
277 { | |
278 if (*currp) | |
279 currp = &(*currp)->next; | |
280 idx += 4; | |
281 } | |
282 else | |
283 { | |
284 struct line *currl = &(*currp)->lines[(*currp)->nlines - 1]; | |
285 currl->words = realloc(currl->words, sizeof(*currl->words) * currl->nwords); | |
286 if ((*currp)->nlines >= LINESPERPAGE) | |
287 currp = &(*currp)->next; | |
288 else | |
289 { | |
290 (*currp)->lines[(*currp)->nlines].nwords = 0; | |
291 (*currp)->nlines++; | |
292 } | |
293 } | |
294 continue; | |
295 } | |
296 wordbegin = &motdstring[idx]; | |
297 while (isalpha(motdstring[idx]) && idx < motdlen) | |
298 { | |
299 #if 0 | |
300 if (!isalpha(motdstring[idx])) | |
301 validword = 0; | |
302 #endif | |
303 idx++; | |
304 } | |
305 | |
306 if (0 && !validword) | |
307 continue; | |
308 | |
309 { | |
310 struct line *currl = &(*currp)->lines[(*currp)->nlines - 1]; | |
311 int len; | |
312 | |
313 if (currl->nwords == 0) | |
314 { | |
315 int size = 40; | |
316 int j; | |
317 currl->words = malloc(sizeof(struct word) * size); | |
318 for (j = 0; j < size; j++) | |
319 { | |
320 currl->words[j].s = 0; | |
321 } | |
322 } | |
323 len = (&motdstring[idx]) - wordbegin; | |
324 currl->words[currl->nwords].s = malloc(len + 1); | |
325 strncpy(currl->words[currl->nwords].s, wordbegin, len); | |
326 currl->words[currl->nwords].s[len] = 0; | |
327 currl->nwords++; | |
328 } | |
329 } | |
330 } | |
331 #endif | |
332 | |
333 /**********************************************************************/ | |
334 | |
335 char **phrases = 0; | |
336 int num_phrases = 0; | |
337 | |
338 void | |
339 parse_clue_phrases() | |
340 { | |
341 char *s; | |
342 int size; | |
343 | |
344 if (phrases) | |
345 return; | |
346 | |
347 phrases = (char **) malloc(sizeof(*phrases) * (size = 20)); | |
348 | |
349 for (s = cluephrase_storage; *s; s += strlen(s) + 1) | |
350 { | |
351 phrases[num_phrases] = s; | |
352 num_phrases++; | |
353 if (num_phrases >= size) | |
354 phrases = (char **) realloc(phrases, sizeof(*phrases) * (size *= 2)); | |
355 } | |
356 | |
357 phrases = (char **) realloc(phrases, sizeof(*phrases) * num_phrases); | |
358 } | |
359 | |
360 /**********************************************************************/ | |
361 | |
362 | |
363 #define BERATE(msg) pmessage( (msg), me->p_no, MINDIV, " CC") | |
364 | |
365 /* print the message that tells the person how to respond to the clue check */ | |
366 void | |
367 remind_cluecheck() | |
368 { | |
369 char buf[120]; | |
370 BERATE("This is a clue check! You must send yourself the message"); | |
371 BERATE(" cluecheck [phrase]"); | |
372 if (page >= 0) | |
373 { | |
374 sprintf(buf, "where [phrase] is the %s word on page %d of the MOTD.", | |
375 isfirst ? "first" : "last", page + 1); | |
376 } | |
377 else | |
378 { | |
379 /* man, the MOTD had no good words */ | |
380 sprintf(buf, "where [phrase] is %s", clueword); | |
381 } | |
382 BERATE(buf); | |
383 if (me->p_cluecountdown > 60) | |
384 sprintf(buf, "If you don't answer within %g minutes, you will be kicked out of", me->p_cluecountdown / (60.0 * 10)); | |
385 else | |
386 sprintf(buf, "If you don't answer within %d seconds, you will be kicked out of", me->p_cluecountdown / 10); | |
387 BERATE(buf); | |
388 BERATE("the game and publicly humiliated."); | |
389 #if 0 | |
390 BERATE("If you are a complete newbie, then"); | |
391 BERATE("you probably don't even realize that you can read the MOTD while"); | |
392 BERATE("playing (shift-M)."); | |
393 #endif | |
394 } | |
395 | |
396 /* | |
397 * if other methods of getting clue words fail, then we've always got this | |
398 * list of words | |
399 */ | |
400 static char *fallback_cluewords[] = { | |
401 | |
402 /* terms: */ | |
403 "bomb", "ogg", "scum", "stoneage", "scout", "taxi", "base", | |
404 "buttorp", "flee", "planet", "star", "warp", "impulse", "hive", | |
405 "repair", "shipyard", "fuel", "arable", "metal", "dilithium", | |
406 "standard", "thin", "tainted", "toxic", "phaser", "torp", "photon", | |
407 "plasma", "missile", "fighter", "tractor", "pressor", | |
408 | |
409 /* what quarks are made of: */ | |
410 "satan", "beer", "jesus", "sex", "cthulhu", | |
411 | |
412 /* two food groups: */ | |
413 /* "grilledcheesesandwich", annoyed too many people */ "ketchup", "caffeine", | |
414 | |
415 /* the men: */ | |
416 /* "a fungusamongus", people have difficulty with this one */ | |
417 "Bubbles", "Hammor", "Key", "Kaos", "Lynx", | |
418 "Thought", "Brazilian", "Ogre", | |
419 | |
420 /* the big five: */ | |
421 "Paradise", "Arctica", "Aedile", "Eden", "Minuet", | |
422 | |
423 /* what you are: */ | |
424 "twink" | |
425 }; | |
426 | |
427 #define NUM_CLUEWORDS ( sizeof(fallback_cluewords) \ | |
428 / sizeof(*fallback_cluewords)) | |
429 | |
430 /* | |
431 * Once in a great while (hour?) the server demands a clue check from the | |
432 * player. This makes sure you are paying attention. | |
433 */ | |
434 void | |
435 demand_clue() | |
436 { | |
437 clueword[0] = 0; | |
438 page = -1; | |
439 switch (configvals->cluesource) | |
440 { | |
441 case CC_MOTD: | |
442 #ifdef MOTD_SUPPORT | |
443 parse_motd(); | |
444 | |
445 find_suitable_motd_word(); | |
446 #endif | |
447 break; | |
448 case CC_PHRASE_LIST_FILE: | |
449 parse_clue_phrases(); | |
450 | |
451 if (num_phrases) | |
452 { | |
453 set_clue_word(phrases[lrand48() % num_phrases]); | |
454 } | |
455 break; /* uh, NYI */ | |
456 case CC_COMPILED_IN_PHRASE_LIST: | |
457 break; /* that's actually the fallback case below: */ | |
458 } | |
459 if (*clueword == 0) /* didn't find one! */ | |
460 set_clue_word(fallback_cluewords[lrand48() % NUM_CLUEWORDS]); | |
461 | |
462 me->p_cluecountdown = configvals->cluetime * TICKSPERSEC; | |
463 | |
464 remind_cluecheck(); | |
465 } | |
466 | |
467 /* every tick, check the person's clue status */ | |
468 void | |
469 countdown_clue() | |
470 { | |
471 if (me->p_status == POUTFIT || me->p_status == PTQUEUE) | |
472 return; | |
473 if (me->p_cluedelay > 0) | |
474 { | |
475 me->p_cluedelay--; | |
476 if (me->p_cluedelay < 1 | |
477 && (me->p_stats.st_cluesuccess < 25 | |
478 || lrand48() % 20 < 1)) | |
479 { | |
480 /* uhoh, time for another cluecheck */ | |
481 demand_clue(); | |
482 } | |
483 } | |
484 else if (me->p_cluecountdown > 0) | |
485 { | |
486 char buf[120]; | |
487 | |
488 /* under the gun here */ | |
489 me->p_cluecountdown--; | |
490 if (me->p_cluecountdown > 0) | |
491 return; | |
492 | |
493 /* uhoh, we have a twink */ | |
494 | |
495 me->p_status = PEXPLODE; | |
496 me->p_explode = 10; | |
497 me->p_whydead = KQUIT; | |
498 | |
499 sprintf(buf, "%s (%s) was blasted out of existence due to terminal", | |
500 me->p_name, twoletters(me)); | |
501 pmessage(buf, -1, MALL, MSERVA); | |
502 pmessage("stupidity (failure to read messages).", -1, MALL, MSERVA); | |
503 pmessage("Let this be a lesson to the rest of you twinks!", -1, MALL, MSERVA); | |
504 } | |
505 else | |
506 { | |
507 me->p_cluedelay = 40; | |
508 } | |
509 } | |
510 | |
511 /* the person sent themselves the message "cluecheck..." */ | |
512 int | |
513 accept_cluecheck(word) | |
514 char *word; | |
515 { | |
516 int i; | |
517 char buf[120]; | |
518 | |
519 if (me->p_cluedelay > 0) | |
520 { | |
521 sprintf(buf, "Don't worry %s. You aren't under a clue check yet.", | |
522 me->p_name); | |
523 BERATE(buf); | |
524 } | |
525 else if (*word) | |
526 { | |
527 for (i = 0; word[i] && clueword[i]; i++) | |
528 { | |
529 if (tolower(word[i]) != tolower(clueword[i])) | |
530 break; | |
531 } | |
532 | |
533 if (word[i] || clueword[i]) | |
534 { | |
535 sprintf(buf, "Nice try, %s. Guess again. It's not %s.", | |
536 me->p_name, word); | |
537 BERATE(buf); | |
538 BERATE("Send yourself the message `cluecheck' if you need another hint."); | |
539 } | |
540 else | |
541 { | |
542 sprintf(buf, "Good show, %s. I won't bother you again for a while.", | |
543 me->p_name); | |
544 BERATE(buf); | |
545 me->p_cluedelay = (configvals->cluedelay / 2) + | |
546 lrand48() % (configvals->cluedelay / 2); | |
547 me->p_cluedelay *= TICKSPERSEC; | |
548 | |
549 me->p_stats.st_cluesuccess++; | |
550 } | |
551 } | |
552 else | |
553 { | |
554 remind_cluecheck(); | |
555 } | |
556 return 1; | |
557 } | |
558 | |
559 /**********************************************************************/ | |
560 | |
561 #ifdef MOTD_SUPPORT | |
562 void | |
563 free_word(wd) | |
564 struct word *wd; | |
565 { | |
566 free(wd->s); | |
567 } | |
568 | |
569 void | |
570 free_line(ln) | |
571 struct line *ln; | |
572 { | |
573 int i; | |
574 for (i = 0; i < ln->nwords; i++) | |
575 free_word(&ln->words[i]); | |
576 free(ln->words); | |
577 } | |
578 | |
579 void | |
580 free_page(pg) | |
581 struct page *pg; | |
582 { | |
583 int i; | |
584 for (i = 0; i < LINESPERPAGE; i++) | |
585 { | |
586 free_line(&pg->lines[i]); | |
587 } | |
588 } | |
589 | |
590 void | |
591 free_motdstruct() | |
592 { | |
593 struct page *temp; | |
594 while (motdhead) | |
595 { | |
596 temp = motdhead; | |
597 motdhead = temp->next; | |
598 | |
599 free_page(temp); | |
600 free(temp); | |
601 } | |
602 } | |
603 #endif | |
604 | |
605 #endif /* CLUECHECK1 */ | |
606 | |
607 #ifdef CLUECHECK2 | |
608 | |
609 /* ---------[ CLUECHECK2 -> Brandons hacked version of CLUECHECK1 ]--------- */ | |
610 | |
611 /* | |
612 * // I munged this (sorry Rob). Using me->p_cluecountdown: // if it is | |
613 * 0 you have not been checked yet // if it is 1 your time is up. // | |
614 * if it is -1 you should not be checked. // if it is anything greater | |
615 * than one you are under the timer | |
616 */ | |
617 | |
618 /* -------------------------[ Globals (eep) ]------------------------- */ | |
619 | |
620 #define TellLINE { pmessage("", me->p_no, MINDIV, "***! Cluecheck !**! Cluecheck !**! Cluecheck !**! Cluecheck !**! Cluecheck !***"); } | |
621 | |
622 #define NUM_CLUEWORDS (sizeof(fallback_cluewords) / \ | |
623 sizeof(*fallback_cluewords)) | |
624 #define CLUE_GETOUTOFIT 7 | |
625 | |
626 char **phrases = 0; | |
627 int num_phrases = 0; | |
628 static char clueword[40]; | |
629 | |
630 /* | |
631 * // if other methods of getting clue words fail, then we've always got // | |
632 * this list of words | |
633 */ | |
634 | |
635 static char *fallback_cluewords[] = { | |
636 /* make it simple, if they want more they can make a .cluecheck file */ | |
637 "bomb", "ogg", "scum", "stoneage", "scout", "taxi", "base", | |
638 "buttorp", "flee", "planet", "star", "warp", "impulse", "hive", | |
639 "repair", "shipyard", "fuel", "arable", "metal", "dilithium", | |
640 "standard", "thin", "tainted", "toxic", "phaser", "torp", "photon", | |
641 "plasma", "missile", "fighter", "tractor", "pressor", | |
642 }; | |
643 | |
644 /* -------------------------[ Functions ]------------------------- */ | |
645 | |
646 void | |
647 set_clue_word(char *word) | |
648 { | |
649 strncpy(clueword, word, sizeof(clueword)); | |
650 clueword[sizeof(clueword) - 1] = 0; | |
651 } | |
652 | |
653 void | |
654 parse_clue_phrases() | |
655 { | |
656 char *s; | |
657 int size; | |
658 | |
659 if (phrases) | |
660 return; | |
661 | |
662 phrases = (char **) malloc(sizeof(*phrases) * (size = 20)); | |
663 | |
664 for (s = cluephrase_storage; *s; s += strlen(s) + 1) | |
665 { | |
666 phrases[num_phrases] = s; | |
667 num_phrases++; | |
668 if (num_phrases >= size) | |
669 phrases = (char **) realloc(phrases, sizeof(*phrases) * (size *= 2)); | |
670 } | |
671 | |
672 phrases = (char **) realloc(phrases, sizeof(*phrases) * num_phrases); | |
673 } | |
674 | |
675 /* | |
676 * // print the message that tells the person how to respond to the clue | |
677 * check | |
678 */ | |
679 void | |
680 remind_cluecheck() | |
681 { | |
682 char buf[120]; | |
683 | |
684 pmessage("", me->p_no, MINDIV, "*******************************************************************************"); | |
685 TellLINE; | |
686 sprintf(buf, " Send yourself: \"cluecheck %s\"", clueword); | |
687 pmessage(buf, me->p_no, MINDIV, ""); | |
688 | |
689 if (me->p_cluecountdown > (60 * TICKSPERSEC)) | |
690 { | |
691 sprintf(buf, | |
692 " Answer within %.2g minutes or be ejected from the game.", | |
693 (me->p_cluecountdown / (60.0 * TICKSPERSEC))); | |
694 pmessage(buf, me->p_no, MINDIV, ""); | |
695 } | |
696 else | |
697 { | |
698 sprintf(buf, | |
699 "** ANSWER ** within %d seconds or be ejected from the game.", | |
700 (me->p_cluecountdown / 10)); | |
701 pmessage(buf, me->p_no, MINDIV, ""); | |
702 } | |
703 pmessage("", me->p_no, MINDIV, "*******************************************************************************"); | |
704 | |
705 } | |
706 | |
707 /* called the first time */ | |
708 void | |
709 demand_clue() | |
710 { | |
711 char buf[255]; | |
712 char syou[32]; | |
713 clueword[0] = 0; | |
714 | |
715 sprintf(syou, "%s->YOU", SERVNAME); | |
716 /* higher than rank CLUE_GETOUTOFIT get ... out of it */ | |
717 if (me->p_stats.st_rank > CLUE_GETOUTOFIT /* if my rank is high enough */ | |
718 || me->p_stats.st_royal == GODLIKE + 1 /* or I'm Q */ ) | |
719 { | |
720 TellLINE; | |
721 pmessage("Due to your ranking status, I will let you off the hook.", | |
722 me->p_no, MINDIV, syou); | |
723 me->p_cluecountdown = -1; | |
724 return; | |
725 } | |
726 else if (me->p_stats.st_cluesuccess > configvals->cluecheck) | |
727 { | |
728 TellLINE; | |
729 sprintf(buf, "You have passed the cluecheck the required %d times.", | |
730 configvals->cluecheck); | |
731 pmessage(buf, me->p_no, MINDIV, syou); | |
732 me->p_cluecountdown = -1; | |
733 return; | |
734 } | |
735 | |
736 parse_clue_phrases(); | |
737 | |
738 if (num_phrases) | |
739 set_clue_word(phrases[lrand48() % num_phrases]); | |
740 if (*clueword == 0) /* didn't find one! */ | |
741 set_clue_word(fallback_cluewords[lrand48() % NUM_CLUEWORDS]); | |
742 me->p_cluecountdown = configvals->cluetime * TICKSPERSEC; | |
743 | |
744 remind_cluecheck(); | |
745 } | |
746 | |
747 | |
748 /* every tick, check the person's clue status */ | |
749 void | |
750 countdown_clue() | |
751 { | |
752 if (me->p_cluecountdown != -1) | |
753 { | |
754 if (me->p_status == POUTFIT | |
755 || me->p_status == PTQUEUE | |
756 || me->p_status == POBSERVE) | |
757 return; | |
758 | |
759 /* let bases off the hook */ | |
760 if (me->p_ship.s_type == 5 || me->p_ship.s_type == 9) | |
761 return; | |
762 | |
763 if (me->p_cluedelay > 0) | |
764 { | |
765 me->p_cluedelay--; | |
766 return; | |
767 } | |
768 | |
769 /* is it greater than one? */ | |
770 if (me->p_cluecountdown > 0) | |
771 { | |
772 char buf[255]; | |
773 | |
774 /* under the gun here */ | |
775 me->p_cluecountdown--; | |
776 | |
777 if (me->p_cluecountdown == 150 * TICKSPERSEC | |
778 || me->p_cluecountdown == 60 * TICKSPERSEC | |
779 || me->p_cluecountdown == 10 * TICKSPERSEC) | |
780 { | |
781 remind_cluecheck(); | |
782 return; | |
783 } | |
784 | |
785 /* is it still greater than 1? */ | |
786 else if (me->p_cluecountdown > 0) | |
787 return; | |
788 | |
789 /* uhoh, we have a twink */ | |
790 me->p_status = PEXPLODE; | |
791 me->p_explode = 10; | |
792 me->p_whydead = KQUIT; | |
793 me->p_cluecountdown = -1; | |
794 | |
795 sprintf(buf, "%s (%s) was ejected for failing a cluecheck.", | |
796 me->p_name, twoletters(me)); | |
797 pmessage(buf, SERVNAME, MALL, " ** CLUECHECK **"); | |
798 | |
799 #ifdef MAIL_CLUELETTER | |
800 sprintf(buf, "%s %s %s", build_path(MAILCLUECHECK), | |
801 me->p_login, me->p_full_hostname); | |
802 system(buf); | |
803 #endif | |
804 } | |
805 else | |
806 { | |
807 /* | |
808 * they aren't -1, they are greater than 1, so they havn't been checked | |
809 * yet | |
810 */ | |
811 demand_clue(); | |
812 } | |
813 } | |
814 } | |
815 | |
816 | |
817 /* | |
818 * // the person sent themselves the message "cluecheck..." // called in | |
819 * controls (message.c) | |
820 */ | |
821 int | |
822 accept_cluecheck(char *word) | |
823 { | |
824 int i; | |
825 char buf[120]; | |
826 char syou[32]; | |
827 | |
828 sprintf(syou, "%s->YOU", SERVNAME); | |
829 if (me->p_cluecountdown == -1 || !me->p_cluecountdown) | |
830 { | |
831 pmessage("You are not under a cluecheck.", | |
832 me->p_no, MINDIV, syou); | |
833 return; | |
834 } | |
835 else if (*word) | |
836 { | |
837 for (i = 0; word[i] && clueword[i]; i++) | |
838 { | |
839 if (tolower(word[i]) != tolower(clueword[i])) | |
840 break; | |
841 } | |
842 | |
843 if (word[i] || clueword[i]) | |
844 { | |
845 sprintf(buf, "Nice try, guess again. It is not \"%s\".", word); | |
846 pmessage(buf, me->p_no, MINDIV, syou); | |
847 pmessage( | |
848 "Send the message \"cluecheck\" to yourself for another hint.", | |
849 me->p_no, MINDIV, syou); | |
850 } | |
851 else | |
852 { | |
853 sprintf(buf, | |
854 "Good show %s. I won't bother you again for a while.", | |
855 me->p_name); | |
856 pmessage(buf, me->p_no, MINDIV, syou); | |
857 me->p_stats.st_cluesuccess++; | |
858 me->p_cluecountdown = -1; | |
859 } | |
860 } | |
861 else | |
862 { | |
863 remind_cluecheck(); | |
864 } | |
865 sprintf(buf, "You have passed the cluecheck %d times.", | |
866 me->p_stats.st_cluesuccess); | |
867 pmessage(buf, me->p_no, MINDIV, syou); | |
868 return 1; | |
869 } | |
870 | |
871 #endif /* CLUECHECK2 */ |