1 #include <stdio.h>
2 #include <string.h>
3
4 #include "handwave.h"
5 #include "spelllist.h"
6
7 struct maingame {
8 int ignorestuff;
9 };
10
PrintMsg(msg,gameval,rock)11 static void PrintMsg(msg, gameval, rock)
12 char *msg;
13 game *gameval;
14 struct maingame *rock;
15 {
16 if (msg) {
17 printf("*: ");
18 fputs(msg, stdout);
19 }
20 }
21
PrintMsg2(person1,msg1,msgelse,gameval,rock)22 static void PrintMsg2(person1, msg1, msgelse, gameval, rock)
23 int person1;
24 char *msg1, *msgelse;
25 game *gameval;
26 struct maingame *rock;
27 {
28 if (msg1) {
29 printf("%d: ", person1);
30 fputs(msg1, stdout);
31 }
32 if (msgelse) {
33 printf("~%d: ", person1);
34 fputs(msgelse, stdout);
35 }
36 }
37
PrintMsg3(person1,person2,msg1,msg2,msgelse,gameval,rock)38 static void PrintMsg3(person1, person2, msg1, msg2, msgelse, gameval, rock)
39 int person1, person2;
40 char *msg1, *msg2, *msgelse;
41 game *gameval;
42 struct maingame *rock;
43 {
44 if (msg1) {
45 printf("%d: ", person1);
46 fputs(msg1, stdout);
47 }
48 if (msg2) {
49 printf("%d: ", person2);
50 fputs(msg2, stdout);
51 }
52 if (msgelse) {
53 printf("~%d/~%d: ", person1, person2);
54 fputs(msgelse, stdout);
55 }
56 }
57
Queries(numqueries,qlist,gameval,rock)58 static void Queries(numqueries, qlist, gameval, rock)
59 int numqueries;
60 struct query qlist[];
61 game *gameval;
62 struct maingame *rock;
63 {
64 int ix, jx, attnum, spellnum;
65 int res;
66 char inbuf[256];
67 char outbuf[512];
68 static int targetlist[256];
69 static char *targetnamelist[256];
70 int numtargs, targnum;
71
72 int *hlist;
73 char *ques, *handage;
74
75 for (ix=0; ix<numqueries; ix++) {
76 switch (qlist[ix].qtype) {
77 case Qu_NoQuery:
78 /*printf("ERROR: got NoQuery\n");*/
79 break;
80 case Qu_SetOffDelay:
81 printf(
82 "%d: Do you want to release the %s from the Delayed Effect?\n (0:no, 1:yes): ",
83 qlist[ix].player,
84 spelllist[(int)qlist[ix].rock].name);
85 while (1) {
86 fgets(inbuf, 256, stdin);
87 res = atol(inbuf);
88 if (res!=0 && res!=1) {
89 printf(" [Please enter 0 or 1]: ");
90 }
91 else
92 break;
93 }
94 qlist[ix].answer = res;
95 break;
96 case Qu_LeftHand:
97 case Qu_RightHand:
98 if (qlist[ix].qtype==Qu_LeftHand)
99 ques = "What spell do you want to cast with your left hand?";
100 else
101 ques = "What spell do you want to cast with your right hand?";
102 hlist = (int *)qlist[ix].rock;
103 printf("%d: %s\n (", qlist[ix].player, ques);
104 for (jx=0; jx<hlist[0]; jx++) {
105 spellnum = hlist[jx+1];
106 printf("%d: %s%s%s", jx, spelllist[spellnum & (~QuVal_Hand_Both)].name,
107 ((spellnum & QuVal_Hand_Both) ? " [both hands]" : ""),
108 (jx+1==hlist[0]) ? "): " : ", ");
109 }
110 while (1) {
111 fgets(inbuf, 256, stdin);
112 res = atol(inbuf);
113 if (res<0 || res>=hlist[0]) {
114 printf(" [Please enter a number from 0 to %d]: ", hlist[0]-1);
115 }
116 else
117 break;
118 }
119 qlist[ix].answer = res;
120 break;
121 case Qu_ElementalType:
122 printf(
123 "%d: Which type of elemental do you want to summon?\n (0:fire, 1:ice): ",
124 qlist[ix].player);
125 while (1) {
126 fgets(inbuf, 256, stdin);
127 res = atol(inbuf);
128 if (res!=0 && res!=1) {
129 printf(" [Please enter 0 or 1]: ");
130 }
131 else
132 break;
133 }
134 qlist[ix].answer = res;
135 break;
136 case Qu_ParalysisHand:
137 printf(
138 "%d: Which of %s's hands do you want to paralyze?\n (0:left, 1:right): ",
139 qlist[ix].player,
140 NameOfBeing(gameval, QuVal_Target_Wizard,
141 qlist[ix].rock));
142 while (1) {
143 fgets(inbuf, 256, stdin);
144 res = atol(inbuf);
145 if (res!=0 && res!=1) {
146 printf(" [Please enter 0 or 1]: ");
147 }
148 else
149 break;
150 }
151 qlist[ix].answer = res;
152 break;
153 case Qu_CharmHand:
154 printf(
155 "%d: Which of %s's hands do you want to charm?\n (0:left, 1:right): ",
156 qlist[ix].player,
157 NameOfBeing(gameval, QuVal_Target_Wizard,
158 qlist[ix].rock));
159 while (1) {
160 fgets(inbuf, 256, stdin);
161 res = atol(inbuf);
162 if (res!=0 && res!=1) {
163 printf(" [Please enter 0 or 1]: ");
164 }
165 else
166 break;
167 }
168 qlist[ix].answer = res;
169 break;
170 case Qu_CharmGesture:
171 jx = (int)(qlist[ix].rock);
172 if (jx >= 128) {
173 spellnum = jx - 128;
174 jx = 1;
175 }
176 else {
177 spellnum = jx;
178 jx = 0;
179 }
180 printf(
181 "%d: What gesture do you want %s's %s hand to make?\n (enter a letter): ",
182 qlist[ix].player,
183 NameOfBeing(gameval, QuVal_Target_Wizard,
184 spellnum), (jx?"right":"left"));
185 while (1) {
186 fgets(inbuf, 256, stdin);
187 if (inbuf[0]=='\0' || inbuf[0]=='\n') {
188 printf(" [Please enter a letter]: ");
189 }
190 else {
191 res = cheap_translate(inbuf[0]);
192 break;
193 }
194 }
195 qlist[ix].answer = res;
196 break;
197 case Qu_MonsterTarget:
198 jx = (int)(qlist[ix].rock);
199 attnum = jx / 256;
200 spellnum = jx % 256;
201 switch (attnum) {
202 case 1:
203 sprintf(outbuf, "Whom do you want %s to attack?",
204 NameOfBeing(gameval,
205 QuVal_Target_Creature, spellnum));
206 break;
207 case 2:
208 sprintf(outbuf, "Whom do you want %s's first attack to be at?",
209 NameOfBeing(gameval,
210 QuVal_Target_Creature, spellnum));
211 break;
212 case 3:
213 sprintf(outbuf, "Whom do you want %s's second attack to be at?",
214 NameOfBeing(gameval,
215 QuVal_Target_Creature, spellnum));
216 break;
217 default:
218 sprintf(outbuf, "ERROR: Query about %d (%d)", spellnum, attnum);
219 break;
220 }
221 printf("%d: %s\n", qlist[ix].player, outbuf);
222 targnum = 0;
223 targetlist[targnum] = 0;
224 targetnamelist[targnum] = "nobody";
225 targnum++;
226 numtargs = NumberOfTargets(gameval, QuVal_Target_Wizard);
227 for (jx=0; jx<numtargs; jx++) {
228 targetlist[targnum] = jx | QuVal_Target_Wizard;
229 targetnamelist[targnum] = NameOfTarget(gameval,
230 QuVal_Target_Wizard, jx);
231 targnum++;
232 }
233 numtargs = NumberOfTargets(gameval, QuVal_Target_Creature);
234 for (jx=0; jx<numtargs; jx++) {
235 targetlist[targnum] = jx | QuVal_Target_Creature;
236 targetnamelist[targnum] = NameOfTarget(gameval,
237 QuVal_Target_Creature, jx);
238 targnum++;
239 }
240 numtargs = targnum;
241 if (numtargs==0)
242 printf("ERROR: No targets available!\n");
243 else {
244 printf(" [");
245 for (jx=0; jx<numtargs; jx++) {
246 printf("%d: %s%s", jx, targetnamelist[jx],
247 ((jx<numtargs-1)?", ":""));
248 }
249 printf("]: ");
250 while (1) {
251 fgets(inbuf, 256, stdin);
252 res = atol(inbuf);
253 if (res<0 || res>=numtargs) {
254 printf(" [Please enter a number from 0 to %d]: ",
255 numtargs-1);
256 }
257 else
258 break;
259 }
260 qlist[ix].answer = targetlist[res];
261 }
262 break;
263 case Qu_WhichToDelay:
264 case Qu_WhichToPerm:
265 if (qlist[ix].qtype == Qu_WhichToDelay)
266 printf("%d: Which spell do you want to delay?\n",
267 qlist[ix].player);
268 else
269 printf("%d: Which spell do you want to make permanent?\n",
270 qlist[ix].player);
271
272 hlist = (int *)qlist[ix].rock;
273 printf(" [");
274 for (jx=0; hlist[jx]!=(-1); jx++) {
275 printf("%s%d: %s", ((jx)?", ":""), jx, spelllist[hlist[jx]].name);
276 }
277 numtargs = jx;
278 printf("]: ");
279 while (1) {
280 fgets(inbuf, 256, stdin);
281 res = atol(inbuf);
282 if (res<0 || res>=numtargs) {
283 printf(" [Please enter a number from 0 to %d]: ", numtargs-1);
284 }
285 else
286 break;
287 }
288 qlist[ix].answer = res;
289 break;
290 case Qu_TargetBeing:
291 case Qu_TargetBeingNone:
292 case Qu_TargetWizard:
293 case Qu_TargetWizardNone:
294 case Qu_TargetRaiseDead:
295 jx = (int)(qlist[ix].rock);
296 spellnum = jx & (~QuVal_Hand_MASK);
297 if (jx & QuVal_Hand_Left)
298 handage = "with your left hand";
299 else if (jx & QuVal_Hand_Right)
300 handage = "with your right hand";
301 else if (jx & QuVal_Hand_Both)
302 handage = "with both hands";
303 else
304 handage = "from the Delayed Effect";
305 if (spellnum==SP__STAB)
306 sprintf(outbuf, "Who do you want to stab at (%s)?", handage);
307 else
308 sprintf(outbuf, "Who do you want to cast %s at (%s)?",
309 spelllist[spellnum].name, handage);
310 printf("%d: %s\n", qlist[ix].player, outbuf);
311 targnum = 0;
312 if (qlist[ix].qtype==Qu_TargetBeingNone ||
313 qlist[ix].qtype==Qu_TargetWizardNone) {
314 targetlist[targnum] = 0;
315 targetnamelist[targnum] = "nobody";
316 targnum++;
317 }
318 numtargs = NumberOfTargets(gameval, QuVal_Target_Wizard);
319 for (jx=0; jx<numtargs; jx++) {
320 targetlist[targnum] = jx | QuVal_Target_Wizard;
321 targetnamelist[targnum] = NameOfTarget(gameval,
322 QuVal_Target_Wizard, jx);
323 targnum++;
324 }
325 if (qlist[ix].qtype==Qu_TargetBeing ||
326 qlist[ix].qtype==Qu_TargetBeingNone ||
327 qlist[ix].qtype==Qu_TargetRaiseDead) {
328 numtargs = NumberOfTargets(gameval, QuVal_Target_Creature);
329 for (jx=0; jx<numtargs; jx++) {
330 targetlist[targnum] = jx | QuVal_Target_Creature;
331 targetnamelist[targnum] = NameOfTarget(gameval,
332 QuVal_Target_Creature, jx);
333 targnum++;
334 }
335 }
336 if (qlist[ix].qtype==Qu_TargetRaiseDead) {
337 numtargs = NumberOfTargets(gameval, QuVal_Target_Corpse);
338 for (jx=0; jx<numtargs; jx++) {
339 targetlist[targnum] = jx | QuVal_Target_Corpse;
340 targetnamelist[targnum] = NameOfTarget(gameval,
341 QuVal_Target_Corpse, jx);
342 targnum++;
343 }
344 }
345 numtargs = targnum;
346 if (numtargs==0)
347 printf("ERROR: No targets available!\n");
348 else {
349 printf(" [");
350 for (jx=0; jx<numtargs; jx++) {
351 printf("%d: %s%s", jx, targetnamelist[jx], ((jx<numtargs-1)?",
352 ":""));
353 }
354 printf("]: ");
355 while (1) {
356 fgets(inbuf, 256, stdin);
357 res = atol(inbuf);
358 if (res<0 || res>=numtargs) {
359 printf(" [Please enter a number from 0 to %d]: ",
360 numtargs-1);
361 }
362 else
363 break;
364 }
365 qlist[ix].answer = targetlist[res];
366 }
367 break;
368
369 default:
370 printf("ERROR: Unknown query type %d!\n", qlist[ix].qtype);
371 break;
372 }
373 }
374 }
375
cheap_translate(ch)376 int cheap_translate(ch)
377 char ch;
378 {
379 switch (ch) {
380 case 'p':
381 case 'P':
382 return Gesture_PALM;
383 case 'f':
384 case 'F':
385 return Gesture_FINGERS;
386 case 'd':
387 case 'D':
388 return Gesture_DIGIT;
389 case 's':
390 case 'S':
391 return Gesture_SNAP;
392 case 'c':
393 case 'C':
394 return Gesture_CLAPHALF;
395 case 'w':
396 case 'W':
397 return Gesture_WAVE;
398 case 'k':
399 case 'K':
400 return Gesture_KNIFE;
401 case ' ':
402 case 'n':
403 case 'N':
404 default:
405 return Gesture_NOTHING;
406 }
407 }
408
show_beings(gameval)409 void show_beings(gameval)
410 game *gameval;
411 {
412 int ix, max, hp;
413
414 printf("\n");
415 max = NumberOfBeings(gameval, QuVal_Target_Wizard);
416 for (ix=0; ix<max; ix++) {
417 hp = HitPointsOfBeing(gameval, QuVal_Target_Wizard, ix);
418 if (hp>=0)
419 printf("%s (%d); ", NameOfBeing(gameval, QuVal_Target_Wizard, ix), hp);
420 }
421 max = NumberOfBeings(gameval, QuVal_Target_Creature);
422 for (ix=0; ix<max; ix++) {
423 hp = HitPointsOfBeing(gameval, QuVal_Target_Creature, ix);
424 if (hp>=0)
425 printf("%s (%d); ", NameOfBeing(gameval, QuVal_Target_Creature, ix), hp);
426 }
427 printf("\n");
428 }
429
main(argc,argv)430 main(argc, argv)
431 int argc;
432 char *argv[];
433 {
434 struct interface procs;
435 struct maingame ignorerock;
436 game *gameval;
437 static char *namelist[MAXPLAYERS] = {"Arnold", "Barbara", "Crash"};
438 static int genderlist[MAXPLAYERS] = {Gender_MALE, Gender_FEMALE, Gender_NEUTER};
439 static int movelist[MAXPLAYERS*2];
440 static char inbuf[256];
441 int numplayers, whowon;
442 int ix, val;
443
444 procs.proc_PrintMsg = PrintMsg;
445 procs.proc_PrintMsg2 = PrintMsg2;
446 procs.proc_PrintMsg3 = PrintMsg3;
447 procs.proc_Queries = Queries;
448
449 numplayers = 2;
450 if (argc==2 && !strcmp(argv[1], "-3")) {
451 numplayers = 3;
452 }
453 else if (argc>=2) {
454 numplayers = 0;
455 for (ix=1; ix<argc; ix++) {
456 char *tmp;
457 namelist[numplayers] = argv[ix];
458 tmp = index(namelist[numplayers], ':');
459 if (!tmp)
460 genderlist[numplayers] = Gender_MALE;
461 else {
462 switch (*(tmp+1)) {
463 case 'f':
464 case 'F':
465 genderlist[numplayers] = Gender_FEMALE;
466 break;
467 case 'n':
468 case 'N':
469 genderlist[numplayers] = Gender_NEUTER;
470 break;
471 case 'x':
472 case 'X':
473 genderlist[numplayers] = Gender_NONE;
474 break;
475 case 'm':
476 case 'M':
477 default:
478 genderlist[numplayers] = Gender_MALE;
479 break;
480 }
481 *tmp = '\0';
482 }
483 numplayers++;
484 }
485 }
486
487 if (numplayers < 2) {
488 printf("You have listed only %d players!\n", numplayers);
489 exit(12);
490 }
491 if (numplayers > MAXPLAYERS) {
492 printf("There is a maximum of %d players!\n", MAXPLAYERS);
493 exit(12);
494 }
495
496 gameval = BeginGame(numplayers, namelist, genderlist, &procs, &ignorerock);
497
498 do {
499 show_beings(gameval);
500 val = 0;
501 switch (TurnType(gameval)) {
502 case Turn_HASTE:
503 printf("(hasted) ");
504 break;
505 case Turn_TIMESTOP:
506 printf("(timestopped) ");
507 break;
508 case Turn_NORMAL:
509 default:
510 break;
511 }
512 for (ix=0; ix<MAXPLAYERS; ix++)
513 if (TurnPlayerActive(gameval, ix)) {
514 val++;
515 printf("%d", ix);
516 }
517 printf(": Enter moves: ");
518 bzero(inbuf, numplayers*2);
519 fgets(inbuf, 256, stdin);
520 for (ix=0; ix<numplayers*2; ix++) {
521 movelist[ix] = cheap_translate(inbuf[ix]);
522 }
523 whowon = RunTurn(gameval, movelist);
524 } while (whowon < 0);
525
526 if (whowon==MAXPLAYERS)
527 printf("+++ the game is a draw +++\n");
528 else
529 printf("+++ %s has won +++\n", namelist[whowon]);
530
531 FreeGame(gameval);
532 }
533
534