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