1 #include <stdio.h>
2 #include <strings.h>
3 
4 #include "handwave.h"
5 #include "internal.h"
6 
7 static char bigbuf[2048], bigbuf2[2048];
8 static char smallbuf[512];
9 
10 extern void find_castspells();
11 extern void execute_spells(), execute_monsters();
12 extern char *pro_him(), *pro_himself(), *pro_his();
13 
14 static void restrict_gestures(), build_cast_list(), pass_time();
15 static int analyze_endgame();
16 static void setup_turnactive();
17 
erase_queries(self)18 void erase_queries(self)
19 struct realgame *self;
20 {
21     /* free any rocks or questions that require it. At present, none do. */
22 
23     self->numqueries = 0;
24 }
25 
add_query(self,player,qtype,rock)26 void add_query(self, player, qtype, rock)
27 struct realgame *self;
28 int player;
29 int qtype;
30 char *rock;
31 {
32     int qnum = self->numqueries;
33     self->numqueries++;
34 
35     if (self->numqueries >= self->querylist_size) {
36 	self->querylist_size *= 2;
37 	self->querylist = (struct query *)realloc(self->querylist, sizeof(struct query) * self->querylist_size);
38     }
39 
40     self->querylist[qnum].player = player;
41     self->querylist[qnum].qtype = qtype;
42     self->querylist[qnum].rock = rock;
43 }
44 
clear_permstats(ps)45 void clear_permstats(ps)
46 struct permstats *ps;
47 {
48     ps->mind_spell = -1;
49     ps->fl_haste = 0;
50     ps->fl_prot_evil = 0;
51     ps->fl_resist_heat = 0;
52     ps->fl_resist_cold = 0;
53     ps->fl_blindness = 0;
54     ps->fl_invisibility = 0;
55 }
56 
clear_out_spells(fred,wizflag)57 void clear_out_spells(fred, wizflag)
58 union being *fred;
59 int wizflag;
60 {
61     fred->both.mind_spell = (-1);
62     if (!wizflag) {
63 	fred->cre.nowm_spell = (-1);
64     }
65     else {
66 	fred->wiz.delay_time = 0;
67 	fred->wiz.perm_time = 0;
68 	if (fred->wiz.delay_bank != (-1)) {
69 	    fred->wiz.delay_bank = (-1);
70 	}
71     }
72     fred->both.resistant_heat = 0;
73     fred->both.fl_resist_heat = 0;
74     fred->both.resistant_cold = 0;
75     fred->both.fl_resist_cold = 0;
76     fred->both.fl_resist_icestorm = 0;
77     fred->both.mind_spell = -1;
78     fred->both.disease_time = (-1);
79     fred->both.poison_time = (-1);
80     fred->both.prot_from_evil = 0;
81     fred->both.haste = 0;
82     fred->both.timestop = 0;
83     fred->both.invisibility = 0;
84     fred->both.blindness = 0;
85     clear_permstats(&(fred->both.perm));
86 }
87 
InitBeing(fred)88 void InitBeing(fred)
89 union being *fred;
90 {
91     fred->both.alive = 1;
92     fred->both.gender = Gender_NONE;
93     fred->both.name = NULL;
94     fred->both.hitpoints = 777;
95     fred->both.max_hitpoints = 888;
96     fred->both.resistant_heat = 0;
97     fred->both.resistant_cold = 0;
98     fred->both.prot_from_evil = 0;
99     fred->both.haste = 0;
100     fred->both.timestop = 0;
101     fred->both.invisibility = 0;
102     fred->both.blindness = 0;
103     fred->both.poison_time = -1;
104     fred->both.disease_time = -1;
105     fred->both.mind_spell = -1;
106     clear_permstats(&(fred->both.perm));
107     clear_round(fred);
108 }
109 
gesture_name(val)110 char *gesture_name(val)
111 int val;
112 {
113     switch (val) {
114 	case Gesture_DIGIT:
115 	    return "digit";
116 	    break;
117 	case Gesture_FINGERS:
118 	    return "fingers";
119 	    break;
120 	case Gesture_PALM:
121 	    return "palm";
122 	    break;
123 	case Gesture_WAVE:
124 	    return "wave";
125 	    break;
126 	case Gesture_CLAPHALF:
127 	    return "clap";
128 	    break;
129 	case Gesture_SNAP:
130 	    return "snap";
131 	    break;
132 	case Gesture_KNIFE:
133 	    return "stab";
134 	    break;
135 	case Gesture_NOTHING:
136 	    return "nothing";
137 	    break;
138 	default:
139 	    return "ERROR:UNKNOWN";
140 	    break;
141     }
142 }
143 
write_gestures(self,wiz,vall,valr)144 int write_gestures(self, wiz, vall, valr)
145 struct realgame *self;
146 struct wizard *wiz;
147 int vall, valr;
148 {
149     int gnum;
150 
151     if (wiz->numgests+3 >= wiz->gests_size) {
152 	wiz->gests_size *= 2;
153 	wiz->gests = (struct wizgesture *)realloc(wiz->gests, wiz->gests_size * sizeof(struct wizgesture));
154     }
155     gnum = wiz->numgests;
156     wiz->numgests++;
157 
158     wiz->gests[gnum].turnnum = self->turn;
159     wiz->gests[gnum].log_hp = wiz->hitpoints;
160 
161     wiz->gests[gnum].did[0] = vall;
162     wiz->gests[gnum].did[1] = valr;
163     wiz->gests[gnum].invisible = (wiz->invisibility || (self->turntype==Turn_TIMESTOP));
164     wiz->gests[gnum].blind = self->blind_array;
165 
166     return gnum;
167 }
168 
previous_gesture(wiz,gnum,hand)169 int previous_gesture(wiz, gnum, hand)
170 struct wizard *wiz;
171 int gnum, hand;
172 {
173     while (1) {
174 	gnum--;
175 	if (gnum<0)
176 	    return Gesture_NOTHING;
177 	if (wiz->gests[gnum].did[hand] != Gesture_ANTISPELL)
178 	    return wiz->gests[gnum].did[hand];
179     }
180 }
181 
BeginGame(numplayers,names,genders,callbacks,rock)182 game *BeginGame(numplayers, names, genders, callbacks, rock)
183 int numplayers;
184 char **names; /* do not free this */
185 int *genders; /* do not free this */
186 struct interface *callbacks; /* do not free this */
187 char *rock;
188 {
189     struct realgame *self = (struct realgame *)malloc(sizeof(struct realgame));
190     int ix;
191 
192     srandom(getpid() + rock + numplayers);
193 
194     if (!self)
195 	return NULL;
196 
197     self->rock = rock;
198     self->callbacks = (*callbacks); /* copy structure */
199     self->numplayers = numplayers;
200     self->turn = 0;
201     self->turntype = Turn_NORMAL;
202 
203     init_transcript(self);
204 
205     if (numplayers > MAXPLAYERS) {
206 	PrintMsg("Too many players requested.\n");
207 	return NULL;
208     }
209 
210     for (ix=0; ix<self->numplayers; ix++) {
211 	self->wiz[ix] = (struct wizard *)malloc(sizeof(struct wizard));
212 
213 	InitBeing(self->wiz[ix]);
214 
215 	self->wiz[ix]->hitpoints = 15;
216 	self->wiz[ix]->max_hitpoints = 15;
217 	self->wiz[ix]->name = names[ix];
218 	self->wiz[ix]->gender = genders[ix];
219 
220 	self->wiz[ix]->numgests = 0;
221 	self->wiz[ix]->gests_size = 20;
222 	self->wiz[ix]->gests = (struct wizgesture *)malloc(self->wiz[ix]->gests_size * sizeof(struct wizgesture));
223 
224 	self->wiz[ix]->surrendered = 0;
225 	self->wiz[ix]->fl_cast_lightning = 0;
226 	self->wiz[ix]->hand_paralyzed = (-1);
227 	self->wiz[ix]->perm_time = 0;
228 	self->wiz[ix]->delay_time = 0;
229 	self->wiz[ix]->delay_bank = (-1);
230 
231 	sprintf(bigbuf, "%s strides defiantly into the arena. The referee casts the formal Dispel Magic and Anti-Spell on %s....\n", self->wiz[ix]->name, pro_him(self->wiz[ix]->gender));
232 	PrintMsg2(ix, "You advance confidently into the arena. The referee casts the formal Dispel Magic and Anti-Spell on you....\n", bigbuf);
233     }
234 
235     self->cre_size = 4;
236     self->cre = (struct creature *)malloc(sizeof(struct creature) * self->cre_size);
237     self->numcres = 0;
238 
239     self->querylist_size = 8;
240     self->querylist = (struct query *)malloc(sizeof(struct query) * self->querylist_size);
241 
242     self->targetlist_size[0] = 0;
243     self->targetlist_size[1] = 0;
244     self->targetlist_size[2] = 0;
245     self->targetlist[0] = (struct target *)malloc(4);
246     self->targetlist[1] = (struct target *)malloc(4);
247     self->targetlist[2] = (struct target *)malloc(4);
248 
249     self->castlist = NULL;
250     self->hastelist = NULL;
251 
252 #if 0 /* to test name-generation */
253     {
254 	ix = 1;
255 	while (1) {
256 	    create_creature(self, ix, 0);
257 	    printf("%s\n", self->cre[self->numcres-1].name);
258 	    ix++;
259 	    if (ix==7) ix=1;
260 	}
261     }
262 #endif
263 
264     setup_targetlist(self);
265     setup_turnactive(self);
266 
267     return (game *)self;
268 }
269 
270 /* returns -1 if game is still going; playernumber if someone won; MAXPLAYERS for a draw */
RunTurn(pgame,moves)271 int RunTurn(pgame, moves)
272 game *pgame;
273 int *moves;
274 /* moves contains two ints for each player (left, right). The encoding is with Gesture_*. */
275 {
276     struct realgame *self = (struct realgame *)pgame;
277     int ix, jx, kx, gnum;
278     int val, vall, valr;
279     int numdead, numsurr, numlive;
280     int *foundlist;
281     struct castspell **cpt;
282 
283     self->blind_array = 0;
284     for (ix=0; ix<self->numplayers; ix++) {
285 	if (self->wiz[ix]->blindness)
286 	    self->blind_array |= (1<<ix);
287     }
288 
289     /* CHOOSE GESTURES */
290     for (ix=0; ix<self->numplayers; ix++)
291 	if (self->turnactive[ix]) {
292 	    struct wizard *wiz = self->wiz[ix];
293 
294 	    vall = moves[ix*2];
295 	    if (vall<0 || vall>=NUMGESTURES)
296 		vall = Gesture_NOTHING;
297 	    valr = moves[ix*2+1];
298 	    if (valr<0 || valr>=NUMGESTURES)
299 		valr = Gesture_NOTHING;
300 
301 	    gnum = write_gestures(self, wiz, vall, valr);
302 
303 	    wiz->hand_paralyzed = (-1);
304 	    switch (wiz->mind_spell) {
305 		case SP__AMNESIA:
306 		    wiz->gests[gnum].did[0] = previous_gesture(wiz, gnum, 0);
307 		    wiz->gests[gnum].did[1] = previous_gesture(wiz, gnum, 1);
308 		    sprintf(bigbuf, "In a fit of absent-mindedness, %s repeats %s gestures from last turn: %s with the left hand, %s with the right.\n", wiz->name, pro_his(wiz->gender), gesture_name(wiz->gests[gnum].did[0]), gesture_name(wiz->gests[gnum].did[1]));
309 		    PrintMsg(bigbuf);
310 		    break;
311 		case SP__CONFUSION:
312 		    if (wiz->mind_caster==1 && wiz->perm.mind_spell==SP__CONFUSION && wiz->perm.mind_detail!=(-1)) {
313 			jx = (wiz->perm.mind_detail & QuVal_Hand_Left) ? 0 : 1;
314 			wiz->gests[gnum].did[jx] = wiz->perm.mind_detail & (~QuVal_Hand_MASK);
315 		    }
316 		    else {
317 			jx = random() % 2;
318 			wiz->gests[gnum].did[jx] = (random() % 6)+1;
319 		    }
320 		    if (wiz->mind_caster==1 && wiz->perm.mind_spell==SP__CONFUSION) {
321 			wiz->perm.mind_detail = wiz->gests[gnum].did[jx] | (jx ? QuVal_Hand_Right : QuVal_Hand_Left);
322 		    }
323 		    sprintf(bigbuf, "%s accidentally makes a %s with %s %s hand.\n", wiz->name, gesture_name(wiz->gests[gnum].did[jx]), pro_his(wiz->gender), (jx?"right":"left"));
324 		    PrintMsg(bigbuf);
325 		    break;
326 		case SP__CHARM_PERSON:
327 		    if ((wiz->mind_caster & 1024) && wiz->perm.mind_spell==SP__CHARM_PERSON && wiz->perm.mind_detail!=(-1)) {
328 			/* grab detail */
329 			jx = (wiz->perm.mind_detail & QuVal_Hand_Left) ? 0 : 1;
330 			wiz->gests[gnum].did[jx] = wiz->perm.mind_detail & (~QuVal_Hand_MASK);
331 		    }
332 		    else {
333 			/* ask */
334 			int tmpcast = wiz->mind_caster & (~1024);
335 			if (tmpcast >= 128) {
336 			    jx = 1;
337 			    kx = tmpcast - 128;
338 			}
339 			else {
340 			    jx = 0;
341 			    kx = tmpcast;
342 			};
343 			erase_queries(self);
344 			val = (ix+jx*128);
345 			add_query(self, kx, Qu_CharmGesture, (char *)val);
346 			Queries(self->numqueries, self->querylist);
347 			wiz->gests[gnum].did[jx] = self->querylist[0].answer;
348 		    }
349 		    if ((wiz->mind_caster & 1024) && wiz->perm.mind_spell==SP__CHARM_PERSON) {
350 			wiz->perm.mind_detail = wiz->gests[gnum].did[jx] | (jx ? QuVal_Hand_Right : QuVal_Hand_Left);
351 		    }
352 		    sprintf(bigbuf, "%s mysteriously makes a %s with %s %s hand.\n", wiz->name, gesture_name(wiz->gests[gnum].did[jx]), pro_his(wiz->gender), (jx?"right":"left"));
353 		    PrintMsg(bigbuf);
354 		    break;
355 		case SP__FEAR:
356 		    jx=0;
357 		    val = wiz->gests[gnum].did[0];
358 		    if (val==Gesture_NOTHING || val==Gesture_DIGIT || val==Gesture_FINGERS || val==Gesture_SNAP || val==Gesture_CLAPHALF) {
359 			wiz->gests[gnum].did[0] = Gesture_NOTHING;
360 			jx += 1;
361 		    }
362 		    val = wiz->gests[gnum].did[1];
363 		    if (val==Gesture_NOTHING || val==Gesture_DIGIT || val==Gesture_FINGERS || val==Gesture_SNAP || val==Gesture_CLAPHALF) {
364 			wiz->gests[gnum].did[1] = Gesture_NOTHING;
365 			jx += 2;
366 		    }
367 		    switch (jx) {
368 			case 1:
369 			    sprintf(bigbuf, "Terrified, %s does nothing with %s left hand.\n", wiz->name, pro_his(wiz->gender));
370 			    break;
371 			case 2:
372 			    sprintf(bigbuf, "Terrified, %s does nothing with %s right hand.\n", wiz->name, pro_his(wiz->gender));
373 			    break;
374 			case 3:
375 			    sprintf(bigbuf, "Terrified, %s does nothing with either hand.\n", wiz->name);
376 			    break;
377 			case 0:
378 			    sprintf(bigbuf, "%s is terrified, but manages %s gestures anyway.\n", wiz->name, pro_his(wiz->gender));
379 			    break;
380 		    }
381 		    PrintMsg(bigbuf);
382 		    break;
383 		case SP__PARALYSIS:
384 		    jx = wiz->mind_caster;
385 		    switch (previous_gesture(wiz, gnum, jx)) {
386 			case Gesture_PALM:
387 			case Gesture_WAVE:
388 			    val = Gesture_PALM;
389 			    break;
390 			case Gesture_DIGIT:
391 			case Gesture_SNAP:
392 			    val = Gesture_DIGIT;
393 			    break;
394 			case Gesture_FINGERS:
395 			case Gesture_CLAPHALF:
396 			    val = Gesture_FINGERS;
397 			    break;
398 			case Gesture_KNIFE:
399 			    val = Gesture_KNIFE;
400 			    break;
401 			case Gesture_NOTHING:
402 			    val = Gesture_NOTHING;
403 			    break;
404 			default:
405 			    PrintMsg("ERROR: paralysis previous_gesture returned bad value.\n");
406 			    val = Gesture_NOTHING;
407 			    break;
408 		    }
409 		    wiz->gests[gnum].did[jx] = val;
410 		    wiz->hand_paralyzed = jx;
411 		    sprintf(bigbuf, "%s's %s hand is frozen in a %s.\n", wiz->name, (jx?"right":"left"), gesture_name(wiz->gests[gnum].did[jx]));
412 		    PrintMsg(bigbuf);
413 		    break;
414 		default:
415 		    break;
416 	    }
417 	    if (self->turntype != Turn_HASTE)
418 		wiz->mind_spell = (-1); /* for wizards, it's over, man */
419 	    else {
420 		/* spell will affect him for the second half of his hasted turn, so don't wipe it. */
421 	    }
422 
423 	    /* move this down? */
424 	    if (wiz->gests[gnum].did[0] == Gesture_KNIFE
425 		&& wiz->gests[gnum].did[1] == Gesture_KNIFE) {
426 		PrintMsg2(ix, "You cannot stab with both hands!\n", NULL);
427 		wiz->gests[gnum].did[1] = Gesture_NOTHING;
428 	    }
429 	} /* end if self->turnactive[ix] */
430 
431     log_round_header(self);
432     erase_queries(self);
433 
434     /* CHECK FOR SPELLS */
435     for (ix=0; ix<self->numplayers; ix++)
436 	if (self->turnactive[ix]) {
437 	    foundlist = self->wiz[ix]->foundlist;
438 
439 	    find_castspells(foundlist, self->wiz[ix]->numgests, self->wiz[ix]->gests);
440 
441 	    /* CHECK SURRENDER */
442 	    if (foundlist[SP__SURRENDER]) {
443 		foundlist[SP__SURRENDER] = 0;
444 		self->wiz[ix]->surrendered = 1;
445 		sprintf(bigbuf, "%s makes the gesture of surrender!\n", self->wiz[ix]->name);
446 		PrintMsg2(ix, "Oh, dear. You seem to have surrendered.\n", bigbuf);
447 	    }
448 
449 	    restrict_gestures(self, ix);
450 	} /* end if self->turnactive[ix] */
451 
452     Queries(self->numqueries, self->querylist); /* "what spell do you want ot cast with your * hand?" questions. */
453     build_cast_list(self);
454     if (self->turntype == Turn_HASTE) {
455 	self->hastelist = self->castlist;
456 	self->castlist = NULL;
457 	/* self->turn is not incremented */
458 	self->turntype = Turn_NORMAL;
459 	setup_targetlist(self);
460 	setup_turnactive(self);
461 	return (-1);
462     }
463     /* else self->turntype == Turn_NORMAL or Turn_TIMESTOP */
464     if (self->hastelist) {
465 	for (cpt = (&(self->castlist)); (*cpt); cpt = (&((*cpt)->next)));
466 	(*cpt) = self->hastelist;
467 	self->hastelist = NULL;
468     }
469     execute_spells(self);
470     execute_monsters(self);
471     pass_time(self);
472 
473     /* CHECK FOR END-OF-GAME */
474     numlive = 0;
475     numdead = 0;
476     numsurr = 0;
477     for (ix=0; ix<self->numplayers; ix++) {
478 	if (!self->wiz[ix]->alive)
479 	    numdead++;
480 	else if (self->wiz[ix]->surrendered)
481 	    numsurr++;
482 	else
483 	    numlive++;
484     }
485     if (numlive <= 1) {
486 	setup_targetlist(self); /* well, just because */
487 	return analyze_endgame(self, numlive, numdead, numsurr);
488     }
489 
490     /* SURRENDERED WIZARDS ARE NOW EFFECTIVELY DEAD */
491     for (ix=0; ix<self->numplayers; ix++)
492 	if (self->wiz[ix]->surrendered)
493 	    self->wiz[ix]->alive = 0;
494 
495     /* FIGURE OUT WHAT KIND OF TURN IS NEXT */
496     if (self->turntype==Turn_NORMAL)
497 	self->turn++;
498     self->turntype = Turn_NORMAL;
499 
500     jx = 0;
501     for (ix=0; ix<self->numplayers; ix++) {
502 	if (self->wiz[ix]->alive && self->wiz[ix]->timestop) {
503 	    self->wiz[ix]->timestop--;
504 	    if (self->wiz[ix]->timestop) {
505 		jx++;
506 		sprintf(bigbuf, "%s accelerates into a flickering blur.\n", self->wiz[ix]->name);
507 		PrintMsg2(ix, "Everything around you stops dead. The world is silent and motionless.\n", bigbuf);
508 	    }
509 	    else {
510 		sprintf(bigbuf, "%s reappears, moving at normal speed.\n", self->wiz[ix]->name);
511 		PrintMsg2(ix, "Everything begins moving again.\n", bigbuf);
512 	    }
513 	}
514     }
515     for (ix=0; ix<self->numcres; ix++) {
516 	if (self->cre[ix].alive && self->cre[ix].timestop) {
517 	    self->cre[ix].timestop--;
518 	    if (self->cre[ix].timestop) {
519 		jx++;
520 		sprintf(bigbuf, "%s accelerates into a flickering blur.\n", self->cre[ix].name);
521 		PrintMsg(bigbuf);
522 	    }
523 	    else {
524 		sprintf(bigbuf, "%s reappears, moving at normal speed.\n", self->cre[ix].name);
525 		PrintMsg(bigbuf);
526 	    }
527 	}
528     }
529     if (jx) {
530 	self->turntype = Turn_TIMESTOP;
531     }
532     else {
533 	/* no timestop... */
534 	jx = 0;
535 	for (ix=0; ix<self->numplayers; ix++) {
536 	    if (self->wiz[ix]->alive && self->wiz[ix]->haste) {
537 		self->wiz[ix]->haste--;
538 		if (self->wiz[ix]->haste==4) {
539 		    self->wiz[ix]->haste--;
540 		    jx++;
541 		    sprintf(bigbuf, "%s begins moving very quickly.\n", self->wiz[ix]->name);
542 		    PrintMsg2(ix, "Everyone else begins moving very slowly.\n", bigbuf);
543 		}
544 		else if (self->wiz[ix]->haste) {
545 		    jx++;
546 		    sprintf(bigbuf, "%s is still moving quickly.\n", self->wiz[ix]->name);
547 		    PrintMsg2(ix, "Everyone else is still moving slowly.\n", bigbuf);
548 		}
549 		else {
550 		    sprintf(bigbuf, "%s slows down to normal speed.\n", self->wiz[ix]->name);
551 		    PrintMsg2(ix, "Everyone comes back up to normal speed.\n", bigbuf);
552 		}
553 	    }
554 	}
555 	for (ix=0; ix<self->numcres; ix++) {
556 	    if (self->cre[ix].alive && self->cre[ix].haste) {
557 		self->cre[ix].haste--;
558 		if (self->cre[ix].haste==4) {
559 		    self->cre[ix].haste--;
560 		    jx++;
561 		    sprintf(bigbuf, "%s begins moving very quickly.\n", self->cre[ix].name);
562 		    PrintMsg(bigbuf);
563 		}
564 		else if (self->cre[ix].haste) {
565 		    jx++;
566 		    sprintf(bigbuf, "%s is still moving quickly.\n", self->cre[ix].name);
567 		    PrintMsg(bigbuf);
568 		}
569 		else {
570 		    sprintf(bigbuf, "%s slows down to normal speed.\n", self->cre[ix].name);
571 		    PrintMsg(bigbuf);
572 		}
573 	    }
574 	}
575 	if (jx) {
576 	    self->turntype = Turn_HASTE;
577 	}
578     }
579 
580     setup_targetlist(self);
581     setup_turnactive(self);
582     return (-1);
583 }
584 
SeeGesture(pgame,player,asker,buf,size)585 void SeeGesture(pgame, player, asker, buf, size)
586 game *pgame;
587 int player, asker;
588 int *buf;
589 int size;
590 {
591     struct realgame *self = (struct realgame *)pgame;
592     struct wizard *wiz = self->wiz[player];
593 
594     int ix, gnum;
595     for (ix=0, gnum=wiz->numgests-1; ix<size; ix++, gnum--) {
596 	if (gnum<0)
597 	    buf[ix] = (-1);
598 	else {
599 	    if (player!=asker &&
600 		(wiz->gests[gnum].invisible || (wiz->gests[gnum].blind & (1<<asker))))
601 		buf[ix] = Gesture_UNCLEAR | (Gesture_UNCLEAR << 5);
602 	    else
603 		buf[ix] = (wiz->gests[gnum].did[0]) | ((wiz->gests[gnum].did[1]) << 5);
604 	}
605     }
606 }
607 
FreeGame(pgame)608 void FreeGame(pgame)
609 game *pgame;
610 {
611     struct realgame *self = (struct realgame *)pgame;
612     int ix;
613 
614     for (ix=0; ix<self->numplayers; ix++) {
615 	free((char *)self->wiz[ix]);
616     }
617 
618     for (ix=0; ix<self->numcres; ix++) {
619 	free(self->cre[ix].name);
620     }
621     free((char *)self->cre);
622 
623     free((char *)self->querylist);
624 
625     free((char *)self);
626 }
627 
setup_targetlist(self)628 void setup_targetlist(self)
629 struct realgame *self;
630 {
631     int ix, res;
632 
633     if (self->numplayers >= self->targetlist_size[0]) {
634 	self->targetlist_size[0] = self->numplayers*2;
635 	self->targetlist[0] = (struct target *)realloc(self->targetlist[0], sizeof(struct target) * self->targetlist_size[0]);
636     }
637     if (self->numcres >= self->targetlist_size[1]) {
638 	self->targetlist_size[1] = (self->numcres+1)*2;
639 	self->targetlist[1] = (struct target *)realloc(self->targetlist[1], sizeof(struct target) * self->targetlist_size[1]);
640     }
641     if ((self->numplayers+self->numcres) >= self->targetlist_size[2]) {
642 	self->targetlist_size[2] = (self->numplayers+self->numcres)*2;
643 	self->targetlist[2] = (struct target *)realloc(self->targetlist[2], sizeof(struct target) * self->targetlist_size[2]);
644     }
645 
646     res = 0;
647     for (ix=0; ix<self->numplayers; ix++)
648 	if (self->wiz[ix]->alive) {
649 	    self->targetlist[0][res].index = ix | QuVal_Target_Wizard;
650 	    self->targetlist[0][res].name = self->wiz[ix]->name;
651 	    self->targetlist[0][res].stuff = StuffAboutBeing((game *)self, QuVal_Target_Wizard, ix);
652 	    res++;
653 	}
654     self->numtargets[0] = res;
655 
656     res = 0;
657     for (ix=0; ix<self->numcres; ix++)
658 	if (self->cre[ix].alive) {
659 	    self->targetlist[1][res].index = ix | QuVal_Target_Creature;
660 	    self->targetlist[1][res].name = self->cre[ix].name;
661 	    self->targetlist[1][res].stuff = StuffAboutBeing((game *)self, QuVal_Target_Creature, ix);
662 	    res++;
663 	}
664     self->numtargets[1] = res;
665 
666     res = 0;
667     for (ix=0; ix<self->numplayers; ix++)
668 	if (!self->wiz[ix]->alive && !self->wiz[ix]->surrendered) {
669 	    self->targetlist[2][res].index = ix | QuVal_Target_Wizard;
670 	    self->targetlist[2][res].name = self->wiz[ix]->name;
671 	    self->targetlist[2][res].stuff = 0;
672 	    res++;
673 	}
674     for (ix=0; ix<self->numcres; ix++)
675 	if (!self->cre[ix].alive && !self->cre[ix].nocorpse) {
676 	    self->targetlist[2][res].index = ix | QuVal_Target_Creature;
677 	    self->targetlist[2][res].name = self->cre[ix].name;
678 	    self->targetlist[2][res].stuff = 0;
679 	    res++;
680 	}
681     self->numtargets[2] = res;
682 
683 }
684 
NumberOfTargets(pgame,targettype)685 int NumberOfTargets(pgame, targettype)
686 game *pgame;
687 int targettype;
688 {
689     struct realgame *self = (struct realgame *)pgame;
690 
691     if (targettype==QuVal_Target_Wizard) {
692 	return self->numtargets[0];
693     }
694     else if (targettype==QuVal_Target_Creature) {
695 	return self->numtargets[1];
696     }
697     else if (targettype==QuVal_Target_Corpse) {
698 	return self->numtargets[2];
699     }
700     else return 0;
701 }
702 
NumberOfBeings(pgame,targettype)703 int NumberOfBeings(pgame, targettype)
704 game *pgame;
705 int targettype;
706 {
707     struct realgame *self = (struct realgame *)pgame;
708 
709     if (targettype==QuVal_Target_Wizard) {
710 	return self->numplayers;
711     }
712     else if (targettype==QuVal_Target_Creature) {
713 	return self->numcres;
714     }
715     else return 0;
716 }
717 
NameOfTarget(pgame,targettype,targetnum)718 char *NameOfTarget(pgame, targettype, targetnum)
719 game *pgame;
720 int targettype, targetnum;
721 {
722     struct realgame *self = (struct realgame *)pgame;
723 
724     if (targettype==QuVal_Target_Wizard) {
725 	if (targetnum >= 0 && targetnum < self->numtargets[0])
726 	    return self->targetlist[0][targetnum].name;
727 	return "ERROR:NOBODY-wiz";
728     }
729     else if (targettype==QuVal_Target_Creature) {
730 	if (targetnum >= 0 && targetnum < self->numtargets[1])
731 	    return self->targetlist[1][targetnum].name;
732 	return "ERROR:NOBODY-cre";
733     }
734     else if (targettype==QuVal_Target_Corpse) {
735 	if (targetnum >= 0 && targetnum < self->numtargets[2])
736 	    return self->targetlist[2][targetnum].name;
737 	return "ERROR:NOBODY-corpse";
738     }
739     else return "ERROR:NOBODY-atall";
740 }
741 
742 
IndexOfTarget(pgame,targettype,targetnum)743 int IndexOfTarget(pgame, targettype, targetnum)
744 game *pgame;
745 int targettype, targetnum;
746 {
747     struct realgame *self = (struct realgame *)pgame;
748 
749     if (targettype==QuVal_Target_Wizard) {
750 	if (targetnum >= 0 && targetnum < self->numtargets[0])
751 	    return self->targetlist[0][targetnum].index;
752 	return (-1);
753     }
754     else if (targettype==QuVal_Target_Creature) {
755 	if (targetnum >= 0 && targetnum < self->numtargets[1])
756 	    return self->targetlist[1][targetnum].index;
757 	return (-1);
758     }
759     else if (targettype==QuVal_Target_Corpse) {
760 	if (targetnum >= 0 && targetnum < self->numtargets[2])
761 	    return self->targetlist[2][targetnum].index;
762 	return (-1);
763     }
764     else return (-1);
765 }
766 
StuffAboutTarget(pgame,targettype,targetnum)767 int StuffAboutTarget(pgame, targettype, targetnum)
768 game *pgame;
769 int targettype, targetnum;
770 {
771     struct realgame *self = (struct realgame *)pgame;
772 
773     if (targettype==QuVal_Target_Wizard) {
774 	if (targetnum >= 0 && targetnum < self->numtargets[0])
775 	    return self->targetlist[0][targetnum].stuff;
776 	return 0;
777     }
778     else if (targettype==QuVal_Target_Creature) {
779 	if (targetnum >= 0 && targetnum < self->numtargets[1])
780 	    return self->targetlist[1][targetnum].stuff;
781 	return 0;
782     }
783     else if (targettype==QuVal_Target_Corpse) {
784 	if (targetnum >= 0 && targetnum < self->numtargets[2])
785 	    return self->targetlist[2][targetnum].stuff;
786 	return 0;
787     }
788     else return 0;
789 }
790 
791 /* -1 if dead, -2 if no corpse, surrendered, or out of bounds */
HitPointsOfBeing(pgame,targettype,indexnum)792 int HitPointsOfBeing(pgame, targettype, indexnum)
793 game *pgame;
794 int targettype, indexnum;
795 {
796     struct realgame *self = (struct realgame *)pgame;
797     int ix;
798 
799     if (targettype==QuVal_Target_Wizard) {
800 	if (indexnum < self->numplayers) {
801 	    ix = self->wiz[indexnum]->hitpoints;
802 	    if (ix<0) ix=0;
803 	    if (self->wiz[indexnum]->alive)
804 		return ix;
805 	    if (self->wiz[indexnum]->surrendered)
806 		return (-2);
807 	    else
808 		return (-1);
809 	}
810 	else
811 	    return -2;
812     }
813     else if (targettype==QuVal_Target_Creature) {
814 	if (indexnum < self->numcres) {
815 	    ix = self->cre[indexnum].hitpoints;
816 	    if (ix<0) ix=0;
817 	    if (self->cre[indexnum].alive)
818 		return ix;
819 	    if (self->cre[indexnum].nocorpse)
820 		return (-2);
821 	    else
822 		return (-1);
823 	}
824 	else
825 	    return -2;
826     }
827     else return -2;
828 }
829 
StuffAboutBeing(pgame,targettype,indexnum)830 int StuffAboutBeing(pgame, targettype, indexnum)
831 game *pgame;
832 int targettype, indexnum;
833 {
834     struct realgame *self = (struct realgame *)pgame;
835     union being *fred;
836     int res;
837 
838     if (targettype==QuVal_Target_Wizard) {
839 	if (indexnum < self->numplayers) {
840 	    fred = (union being *)self->wiz[indexnum];
841 	}
842 	else
843 	    return 0;
844     }
845     else if (targettype==QuVal_Target_Creature) {
846 	if (indexnum < self->numcres) {
847 	    fred = (union being *)&(self->cre[indexnum]);
848 	}
849 	else
850 	    return 0;
851     }
852     else return 0;
853 
854     res=0;
855     if (fred->both.resistant_heat)
856 	res |= Stuff_RESIST_HEAT;
857     if (fred->both.resistant_cold)
858 	res |= Stuff_RESIST_COLD;
859     if (fred->both.prot_from_evil)
860 	res |= Stuff_PROTECT_EVIL;
861     if (fred->both.invisibility)
862 	res |= Stuff_INVISIBLE;
863     if (fred->both.blindness)
864 	res |= Stuff_BLIND;
865     if (fred->both.poison_time != (-1))
866 	res |= Stuff_POISON;
867     if (fred->both.disease_time != (-1))
868 	res |= Stuff_DISEASE;
869 
870     return res;
871 }
872 
OwnerOfCreature(pgame,indexnum)873 int OwnerOfCreature(pgame, indexnum)
874 game *pgame;
875 int indexnum;
876 {
877     struct realgame *self = (struct realgame *)pgame;
878     int res = self->cre[indexnum].owner;
879 
880     if (res<0 || !self->wiz[res]->alive)
881 	return (-1);
882     else
883 	return res;
884 }
885 
NameOfBeing(pgame,targettype,indexnum)886 char *NameOfBeing(pgame, targettype, indexnum)
887 game *pgame;
888 int targettype, indexnum;
889 {
890     struct realgame *self = (struct realgame *)pgame;
891     int ix;
892 
893     if (targettype==QuVal_Target_Wizard) {
894 	if (indexnum < self->numplayers) {
895 	    return self->wiz[indexnum]->name;
896 	}
897 	else
898 	    return NULL;
899     }
900     else if (targettype==QuVal_Target_Creature) {
901 	if (indexnum < self->numcres) {
902 	    return self->cre[indexnum].name;
903 	}
904 	else
905 	    return NULL;
906     }
907     else return NULL;
908 }
909 
TurnType(pgame)910 int TurnType(pgame)
911 game *pgame;
912 {
913     struct realgame *self = (struct realgame *)pgame;
914 
915     return self->turntype;
916 }
917 
918 /* this is called after surrenders are killed */
setup_turnactive(self)919 static void setup_turnactive(self)
920 struct realgame *self;
921 {
922     int ix;
923 
924     for (ix=0; ix<MAXPLAYERS; ix++)
925 	self->turnactive[ix] = 0;
926 
927     switch (self->turntype) {
928 	case Turn_NORMAL:
929 	    for (ix=0; ix<self->numplayers; ix++) {
930 		self->turnactive[ix] = self->wiz[ix]->alive;
931 	    }
932 	    break;
933 	case Turn_HASTE:
934 	    for (ix=0; ix<self->numplayers; ix++) {
935 		self->turnactive[ix] = (self->wiz[ix]->alive && self->wiz[ix]->haste);
936 	    }
937 	    break;
938 	case Turn_TIMESTOP:
939 	    for (ix=0; ix<self->numplayers; ix++) {
940 		self->turnactive[ix] = (self->wiz[ix]->alive && self->wiz[ix]->timestop);
941 	    }
942 	    break;
943 	default:
944 	    PrintMsg("ERROR: Unknown turn type\n");
945 	    break;
946     }
947 }
948 
TurnPlayerActive(pgame,player)949 int TurnPlayerActive(pgame, player)
950 game *pgame;
951 int player;
952 {
953     struct realgame *self = (struct realgame *)pgame;
954 
955     return self->turnactive[player];
956 }
957 
958 /* go over wiz->foundlist and generate queries as to which spell is desired */
restrict_gestures(self,wiznum)959 static void restrict_gestures(self, wiznum)
960 struct realgame *self;
961 int wiznum;
962 {
963     int jx;
964     int lcount=0, rcount=0;
965     int *llist = self->wiz[wiznum]->llist;
966     int *rlist = self->wiz[wiznum]->rlist;
967     int *foundlist = self->wiz[wiznum]->foundlist;
968 
969     for (jx=0; jx<NUMSPELLS; jx++) {
970 	if (foundlist[jx]) {
971 	    switch (foundlist[jx]) {
972 		case MASK_LEFT:
973 		    lcount++;
974 		    llist[lcount] = jx;
975 		    break;
976 		case MASK_RIGHT:
977 		    rcount++;
978 		    rlist[rcount] = jx;
979 		    break;
980 		case MASK_LEFT|MASK_RIGHT:
981 		    lcount++;
982 		    llist[lcount] = jx;
983 		    rcount++;
984 		    rlist[rcount] = jx;
985 		    break;
986 		case MASK_TWOHAND:
987 		    lcount++;
988 		    llist[lcount] = jx | QuVal_Hand_Both;
989 		    rcount++;
990 		    rlist[rcount] = jx | QuVal_Hand_Both;
991 		    break;
992 		default:
993 		    PrintMsg("ERROR in restrict_gestures\n");
994 		    break;
995 	    }
996 	}
997     }
998     llist[0] = lcount;
999     rlist[0] = rcount;
1000 
1001     if (lcount>1) {
1002 	add_query(self, wiznum, Qu_LeftHand, (char *)llist);
1003     }
1004     if (rcount>1) {
1005 	add_query(self, wiznum, Qu_RightHand, (char *)rlist);
1006     }
1007 
1008     if (self->wiz[wiznum]->delay_bank != (-1))
1009 	add_query(self, wiznum, Qu_SetOffDelay, (char *)self->wiz[wiznum]->delay_bank);
1010 }
1011 
1012 static int spelltargetlist[NUMSPELLS] = {
1013     Qu_TargetWizard, Qu_TargetWizard, Qu_TargetBeingNone, Qu_TargetBeingNone,
1014     Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetBeingNone,
1015     Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetWizardNone, Qu_TargetRaiseDead,
1016     Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetWizardNone, Qu_TargetBeingNone,
1017     Qu_TargetBeingNone, Qu_NoQuery, Qu_TargetBeingNone, Qu_TargetBeingNone,
1018     Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetWizardNone, Qu_TargetBeingNone,
1019     Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetWizardNone, Qu_TargetWizardNone,
1020     Qu_TargetWizardNone, Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetBeingNone,
1021     Qu_NoQuery, Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetWizardNone,
1022     Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_NoQuery, Qu_TargetBeingNone,
1023     Qu_TargetBeingNone, Qu_TargetBeingNone, Qu_TargetBeingNone
1024 };
1025 
1026 /* use llist and rlist together with self->querylist answers (including time delay) to create a spell list. Then create new querylist about targets, and ask it. */
build_cast_list(self)1027 static void build_cast_list(self)
1028 struct realgame *self;
1029 {
1030     struct castspell *res, *tmp;
1031     int wiznum, jx, kx;
1032     struct query *qtmp;
1033 
1034     /* free last turn's castlist */
1035     while (self->castlist) {
1036 	tmp = self->castlist->next;
1037 	free((char *)self->castlist);
1038 	self->castlist = tmp;
1039     }
1040 
1041     for (wiznum=0; wiznum<self->numplayers; wiznum++)
1042 	if (self->turnactive[wiznum]) {
1043 	    int *llist = self->wiz[wiznum]->llist;
1044 	    int *rlist = self->wiz[wiznum]->rlist;
1045 	    int lspel, rspel;
1046 
1047 	    if (llist[0]==0)
1048 		lspel = (-1);
1049 	    else if (llist[0]==1)
1050 		lspel = llist[1];
1051 	    else {
1052 		for (jx=0; jx<self->numqueries; jx++)
1053 		    if (self->querylist[jx].player == wiznum
1054 			&& self->querylist[jx].qtype == Qu_LeftHand)
1055 			break;
1056 		lspel = llist[1 + self->querylist[jx].answer];
1057 	    }
1058 	    if (rlist[0]==0)
1059 		rspel = (-1);
1060 	    else if (rlist[0]==1)
1061 		rspel = rlist[1];
1062 	    else {
1063 		for (jx=0; jx<self->numqueries; jx++)
1064 		    if (self->querylist[jx].player == wiznum
1065 			&& self->querylist[jx].qtype == Qu_RightHand)
1066 			break;
1067 		rspel = rlist[1 + self->querylist[jx].answer];
1068 	    }
1069 
1070 	    if (lspel>=0 && (lspel & QuVal_Hand_Both)) {
1071 		if (lspel==rspel) {
1072 		    res = (struct castspell *)malloc(sizeof(struct castspell));
1073 		    res->caster = wiznum;
1074 		    res->handage = MASK_TWOHAND;
1075 		    res->spellnum = lspel & (~QuVal_Hand_Both);
1076 		    res->permanent = 0;
1077 		    res->next = self->castlist;
1078 		    self->castlist = res;
1079 		    lspel = (-1);
1080 		    rspel = (-1);
1081 		}
1082 		else
1083 		    lspel = (-1);
1084 	    }
1085 	    if (rspel>=0 && (rspel & QuVal_Hand_Both)) {
1086 		rspel = (-1);
1087 	    }
1088 	    /* only one-handed spells remain */
1089 	    if (lspel>=0) {
1090 		res = (struct castspell *)malloc(sizeof(struct castspell));
1091 		res->caster = wiznum;
1092 		res->handage = MASK_LEFT;
1093 		res->spellnum = lspel;
1094 		res->permanent = 0;
1095 		res->next = self->castlist;
1096 		self->castlist = res;
1097 	    }
1098 	    if (rspel>=0) {
1099 		res = (struct castspell *)malloc(sizeof(struct castspell));
1100 		res->caster = wiznum;
1101 		res->handage = MASK_RIGHT;
1102 		res->spellnum = rspel;
1103 		res->permanent = 0;
1104 		res->next = self->castlist;
1105 		self->castlist = res;
1106 	    }
1107 
1108 	    if (self->wiz[wiznum]->delay_bank != (-1)) {
1109 		for (jx=0; jx<self->numqueries; jx++)
1110 		    if (self->querylist[jx].player == wiznum
1111 			&& self->querylist[jx].qtype == Qu_SetOffDelay)
1112 			break;
1113 		if (self->querylist[jx].answer) {
1114 		    res = (struct castspell *)malloc(sizeof(struct castspell));
1115 		    res->caster = wiznum;
1116 		    res->handage = 0;
1117 		    res->spellnum = self->wiz[wiznum]->delay_bank;
1118 		    res->permanent = 0;
1119 		    res->next = self->castlist;
1120 		    self->castlist = res;
1121 		    self->wiz[wiznum]->delay_bank = (-1);
1122 		}
1123 	    }
1124 	}  /* end if self->turnactive[ix] */
1125 
1126     erase_queries(self);
1127 
1128     for (wiznum=0; wiznum<self->numplayers; wiznum++)
1129 	if (self->turnactive[wiznum]) {
1130 	    struct wizard *wiz = self->wiz[wiznum];
1131 
1132 	    /* DELAYED EFFECT */
1133 	    if (wiz->delay_time) {
1134 		struct castspell *dellist[10]; /* that had better be enough */
1135 		int delnum[11];
1136 
1137 		int numdel = 0;
1138 		for (tmp=self->castlist; tmp; tmp=tmp->next) {
1139 		    if (tmp->caster == wiznum
1140 			&& tmp->handage != 0 /* can't bank a banked spell */
1141 			&& tmp->spellnum != SP__STAB) {
1142 			dellist[numdel] = tmp;
1143 			delnum[numdel] = tmp->spellnum;
1144 			numdel++;
1145 		    }
1146 		}
1147 		delnum[numdel] = (-1);
1148 		if (numdel==0)
1149 		    res = NULL;
1150 		else if (numdel==1)
1151 		    res = dellist[0];
1152 		else {
1153 		    /* gack -- have to pick from the list. */
1154 		    erase_queries(self);
1155 		    add_query(self, wiznum, Qu_WhichToDelay, delnum);
1156 		    Queries(self->numqueries, self->querylist);
1157 		    res = dellist[self->querylist[0].answer];
1158 		}
1159 
1160 		if (res) {
1161 		    struct castspell **ppt;
1162 		    for (ppt = (&(self->castlist));
1163 			 (*ppt) && (*ppt)!=res;
1164 			 ppt = (&((*ppt)->next)));
1165 		    if (!(*ppt)) {
1166 			PrintMsg("ERROR: Unable to find Delayed spell.\n");
1167 		    }
1168 		    else {
1169 			*ppt = res->next;
1170 			res->next = NULL;
1171 			sprintf(bigbuf, "You cast %s; the spell is caught in the web of your Delayed Effect. It rises to hover by your head.\n", spelllist[res->spellnum].name);
1172 			sprintf(bigbuf2, "%s casts %s; the spell is caught in the web of %s Delayed Effect.\n", wiz->name, spelllist[res->spellnum].name, pro_his(wiz->gender));
1173 			PrintMsg2(wiznum, bigbuf, bigbuf2);
1174 			if (wiz->delay_bank != (-1)) {
1175 			    sprintf(bigbuf, "The %s spell that you had caught previously is lost.\n", spelllist[wiz->delay_bank].name);
1176 			    sprintf(bigbuf2, "The %s spell that %s had caught previously is lost.\n", spelllist[wiz->delay_bank].name, wiz->name);
1177 			    PrintMsg2(wiznum, bigbuf, bigbuf2);
1178 			    wiz->delay_bank = (-1);
1179 			}
1180 			wiz->delay_time = 0;
1181 			wiz->delay_bank = res->spellnum;
1182 			free((char *)res);
1183 		    }
1184 		}
1185 	    }
1186 
1187 	    /* PERMANENCY */
1188 	    if (wiz->perm_time) {
1189 		struct castspell *dellist[10]; /* that had better be enough */
1190 		int delnum[11];
1191 
1192 		int numdel = 0;
1193 		for (tmp=self->castlist; tmp; tmp=tmp->next) {
1194 		    if (tmp->caster == wiznum
1195 			&& tmp->handage != 0 /* can't perm a banked spell */
1196 			&& spelllist[tmp->spellnum].extendable) {
1197 			dellist[numdel] = tmp;
1198 			delnum[numdel] = tmp->spellnum;
1199 			numdel++;
1200 		    }
1201 		}
1202 		delnum[numdel] = (-1);
1203 		if (numdel==0)
1204 		    res = NULL;
1205 		else if (numdel==1)
1206 		    res = dellist[0];
1207 		else {
1208 		    /* gack -- have to pick from the list. */
1209 		    erase_queries(self);
1210 		    add_query(self, wiznum, Qu_WhichToPerm, delnum);
1211 		    Queries(self->numqueries, self->querylist);
1212 		    res = dellist[self->querylist[0].answer];
1213 		}
1214 
1215 		if (res) {
1216 		    res->permanent = 1;
1217 		    sprintf(bigbuf, "Your Permanency spell wraps itself around your %s spell.\n", spelllist[res->spellnum].name);
1218 		    PrintMsg2(wiznum, bigbuf, NULL);
1219 		    wiz->perm_time = 0;
1220 		}
1221 	    }
1222 	}
1223 
1224     erase_queries(self);
1225 
1226     /* add target queries for spells, in order */
1227     for (tmp=self->castlist; tmp; tmp=tmp->next) {
1228 	int orval;
1229 	if (tmp->handage==MASK_LEFT)
1230 	    orval = QuVal_Hand_Left;
1231 	else if (tmp->handage==MASK_RIGHT)
1232 	    orval = QuVal_Hand_Right;
1233 	else if (tmp->handage==0)
1234 	    orval = 0;
1235 	else
1236 	    orval = QuVal_Hand_Both;
1237 
1238 	add_query(self, tmp->caster, spelltargetlist[tmp->spellnum], tmp->spellnum | orval);
1239     }
1240     Queries(self->numqueries, self->querylist); /* "who do you want to cast X on?" queries */
1241     for (tmp=self->castlist, jx=0; tmp; tmp=tmp->next, jx++) {
1242 	if (spelltargetlist[tmp->spellnum]==Qu_NoQuery) {
1243 	    tmp->targettype = (-1);
1244 	}
1245 	else {
1246 	    int ival;
1247 	    int tart = self->querylist[jx].answer & QuVal_Target_MASK;
1248 	    if (tart==0) {
1249 		tmp->targettype = 0;
1250 	    }
1251 	    else {
1252 		kx = self->querylist[jx].answer & (~QuVal_Target_MASK);
1253 		ival = IndexOfTarget((game *)self, tart, kx);
1254 		tmp->target = ival & (~QuVal_Target_MASK);
1255 		tmp->targettype = ival & QuVal_Target_MASK;
1256 	    }
1257 	}
1258     }
1259 }
1260 
exec_unhealth(self,fred,cnum,wizflag)1261 static void exec_unhealth(self, fred, cnum, wizflag) /* no deaders */
1262 struct realgame *self;
1263 union being *fred;
1264 int cnum;
1265 int wizflag;
1266 {
1267     if (self->turntype==Turn_TIMESTOP && fred->both.timestop!=1)
1268 	return; /* the illnesses are timestopped and have no effect. */
1269 
1270     if (fred->both.disease_time != (-1)) {
1271 	fred->both.disease_time--;
1272 	switch (fred->both.disease_time) {
1273 	    case 5:
1274 		/* message already printed */
1275 		break;
1276 	    case 4:
1277 		sprintf(bigbuf, "%s starts to look hot and flushed.\n", fred->both.name);
1278 		if (wizflag)
1279 		    PrintMsg2(cnum, "You begin to feel somewhat feverish.\n", bigbuf);
1280 		else
1281 		    PrintMsg(bigbuf);
1282 		break;
1283 	    case 3:
1284 		sprintf(bigbuf, "%s looks even more flushed.\n", fred->both.name);
1285 		if (wizflag)
1286 		    PrintMsg2(cnum, "Your fever is growing worse.\n", bigbuf);
1287 		else
1288 		    PrintMsg(bigbuf);
1289 		break;
1290 	    case 2:
1291 		sprintf(bigbuf, "%s is flushed and sweating, and seems to be somewhat unsteady on %s feet.\n", fred->both.name, pro_his(fred->both.gender));
1292 		if (wizflag)
1293 		    PrintMsg2(cnum, "You are very hot and somewhat dizzy, and your bones are starting to ache.\n", bigbuf);
1294 		else
1295 		    PrintMsg(bigbuf);
1296 		break;
1297 	    case 1:
1298 		sprintf(bigbuf, "%s is both flushed and shivering violently.\n", fred->both.name);
1299 		if (wizflag)
1300 		    PrintMsg2(cnum, "You are feverish and shivering at the same time, and you ache all over.\n", bigbuf);
1301 		else
1302 		    PrintMsg(bigbuf);
1303 		break;
1304 	    case 0:
1305 		sprintf(bigbuf, "%s crumples to the ground, agony on %s sweating features.\n", fred->both.name, pro_his(fred->both.gender));
1306 		if (wizflag)
1307 		    PrintMsg2(cnum, "Your knees give way and you fall to the ground. Your head pounds unmercifully as consciousness slips away....\n", bigbuf);
1308 		else
1309 		    PrintMsg(bigbuf);
1310 		fred->both.alive = 0;
1311 		break;
1312 	}
1313     }
1314 
1315     if (fred->both.poison_time != (-1)) {
1316 	fred->both.poison_time--;
1317 	switch (fred->both.poison_time) {
1318 	    case 5:
1319 		/* message already printed */
1320 		break;
1321 	    case 4:
1322 		sprintf(bigbuf, "%s is looking pale.\n", fred->both.name);
1323 		if (wizflag)
1324 		    PrintMsg2(cnum, "Your toes suddenly feel slightly numb.\n", bigbuf);
1325 		else
1326 		    PrintMsg(bigbuf);
1327 		break;
1328 	    case 3:
1329 		sprintf(bigbuf, "%s is looking very pale and weak.\n", fred->both.name);
1330 		if (wizflag)
1331 		    PrintMsg2(cnum, "Your hands and feet are getting numb.\n", bigbuf);
1332 		else
1333 		    PrintMsg(bigbuf);
1334 		break;
1335 	    case 2:
1336 		sprintf(bigbuf, "%s is white as a sheet, and seems a little unsteady.\n", fred->both.name);
1337 		if (wizflag)
1338 		    PrintMsg2(cnum, "Your limbs are heavy, and your fingers are getting clumsy.\n", bigbuf);
1339 		else
1340 		    PrintMsg(bigbuf);
1341 		break;
1342 	    case 1:
1343 		sprintf(bigbuf, "%s is having difficulty staying on %s feet.\n", fred->both.name, pro_his(fred->both.gender));
1344 		if (wizflag)
1345 		    PrintMsg2(cnum, "You cannot feel your hands and feet, and your vision is becoming clouded.\n", bigbuf);
1346 		else
1347 		    PrintMsg(bigbuf);
1348 		break;
1349 	    case 0:
1350 		sprintf(bigbuf, "%s collapses in a heap, twitching slightly.\n", fred->both.name, pro_his(fred->both.gender));
1351 		if (wizflag)
1352 		    PrintMsg2(cnum, "You stumble and fall to your knees, vision dimming. Numbness creeps through your bones, and you cannot tell if you are still breathing....\n", bigbuf);
1353 		else
1354 		    PrintMsg(bigbuf);
1355 		fred->both.alive = 0;
1356 		break;
1357 	}
1358     }
1359 }
1360 
1361 /* let critters die, let poison/disease advance, etc */
pass_time(self)1362 static void pass_time(self)
1363 struct realgame *self;
1364 {
1365     int ix;
1366 
1367     for (ix=0; ix<self->numplayers; ix++) {
1368 	if (self->wiz[ix]->alive && self->wiz[ix]->hitpoints <= 0) {
1369 	    sprintf(bigbuf, "%s has died!\n", self->wiz[ix]->name);
1370 	    PrintMsg2(ix, "You have died!\n", bigbuf);
1371 	    self->wiz[ix]->alive = 0;
1372 	    clear_out_spells(self->wiz[ix], 1);
1373 	    write_gestures(self, self->wiz[ix], Gesture_NOTHING, Gesture_NOTHING);
1374 	    /* ### other stuff? */
1375 	}
1376 	if (self->wiz[ix]->alive) {
1377 	    exec_unhealth(self, self->wiz[ix], ix, 1);
1378 	}
1379 	if (self->wiz[ix]->alive && self->turnactive[ix]) {
1380 	    if (self->wiz[ix]->delay_time) {
1381 		self->wiz[ix]->delay_time--;
1382 		if (self->wiz[ix]->delay_time==0) {
1383 		    sprintf(bigbuf, "The Delayed Effect spell hovering around %s dies away.\n", self->wiz[ix]->name);
1384 		    PrintMsg2(ix, "The Delayed Effect spell hovering around you dies away.\n", bigbuf);
1385 		}
1386 	    }
1387 	}
1388 	if (self->wiz[ix]->alive && self->turnactive[ix]) {
1389 	    if (self->wiz[ix]->perm_time) {
1390 		self->wiz[ix]->perm_time--;
1391 		if (self->wiz[ix]->perm_time==0) {
1392 		    sprintf(bigbuf, "The Permanency spell hovering around %s dies away.\n", self->wiz[ix]->name);
1393 		    PrintMsg2(ix, "The Permanency spell hovering around you dies away.\n", bigbuf);
1394 		}
1395 	    }
1396 	}
1397     }
1398     for (ix=0; ix<self->numcres; ix++) {
1399 	if (self->cre[ix].alive && self->cre[ix].hitpoints <= 0) {
1400 	    sprintf(bigbuf, "%s has died.\n", self->cre[ix].name);
1401 	    PrintMsg(bigbuf);
1402 	    self->cre[ix].alive = 0;
1403 	    clear_out_spells(&(self->cre[ix]), 0);
1404 	    /* ### other stuff? */
1405 	}
1406 	if (self->cre[ix].alive)
1407 	    exec_unhealth(self, &self->cre[ix], ix, 0);
1408     }
1409 }
1410 
analyze_endgame(self,numlive,numdead,numsurr)1411 static int analyze_endgame(self, numlive, numdead, numsurr)
1412 struct realgame *self;
1413 int numlive, numdead, numsurr; /* these add up to self->numplayers, and numlive <= 1 */
1414 {
1415     int ix, jx;
1416 
1417     if (numlive==1) {
1418 
1419 	for (ix=0; ix<self->numplayers; ix++)
1420 	    if (self->wiz[ix]->alive && !self->wiz[ix]->surrendered)
1421 		break;
1422 
1423 	if (numsurr==0) {
1424 	    sprintf(bigbuf, "%s is the sole survivor!\n", self->wiz[ix]->name);
1425 	    PrintMsg(bigbuf);
1426 	}
1427 	else if (numsurr==1) {
1428 	    for (jx=0; jx<self->numplayers; jx++)
1429 		if (self->wiz[jx]->alive && self->wiz[jx]->surrendered)
1430 		    break;
1431 	    sprintf(bigbuf, "%s has surrendered to %s!\n", self->wiz[jx]->name, self->wiz[ix]->name);
1432 	    PrintMsg(bigbuf);
1433 	}
1434 	else {
1435 	    sprintf(bigbuf, "All of %s's opponents have surrendered!\n", self->wiz[ix]->name);
1436 	    PrintMsg(bigbuf);
1437 	}
1438 
1439 	return ix;
1440     }
1441     else {
1442 	/* nobody left alive (and unsurrendered) */
1443 	if (numsurr==0) {
1444 	    PrintMsg("Everyone is dead!\n");
1445 	    return MAXPLAYERS;
1446 	}
1447 
1448 	if (numsurr==1) {
1449 	    for (jx=0; jx<self->numplayers; jx++)
1450 		if (self->wiz[jx]->alive && self->wiz[jx]->surrendered)
1451 		    break;
1452 	    sprintf(bigbuf, "%s finds that there is nobody left to surrender to!\n", self->wiz[jx]->name);
1453 	    PrintMsg(bigbuf);
1454 	    return jx;
1455 	}
1456 
1457 	if (numdead)
1458 	    PrintMsg("The survivors have all surrendered to each other!\n");
1459 	else
1460 	    PrintMsg("Everyone has surrendered to each other!\n");
1461 	return MAXPLAYERS;
1462     }
1463 }
1464