1 /* Tornado - Two player weather action game
2  *
3  * Copyright (C) 2000-2002  Oliver Feiler (kiza@gmx.net)
4  *
5  * main.c
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 
23 
24 #include <ncurses.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <time.h>
29 #include <string.h>
30 
31 #ifdef LOCALEPATH
32 #  include <libintl.h>
33 #  include <locale.h>
34 #endif
35 
36 #include "draw.h"
37 #include "version.h"
38 #include "erwin.h"
39 #include "network.h"
40 #include "scores.h"
41 //#include "house.h"
42 
43 #define SERVER_PORT 3000	/* Port that the server should run on. */
44 
45 #ifdef LOCALEPATH
46 #  define _(String) gettext (String)
47 #else
48 #  define _(String) (String)
49 #endif
50 
51 
52 char player1[21];		/* name for player 1 */
53 char player2[21];		/* guess what */
54 int current_player = 1;		/* just what it says */
55 int cloud_x;			/* horizontal cloud position */
56 int networkplay = 0;		/* indicates whether the game runs in
57 				 * network mode or not:
58 				 * 0 = nope
59 				 * 1 = server
60 				 * 2 = client */
61 int login = 0;			/* logged in at the tornado website? */
62 char side = '0';        	/* the side (client/server) that quit the game
63                                  * 0 = we did; 1 = other side */
64 
65 void main_network_readint(int *i);
66 void main_network_writeint(int i);
67 
68 /**
69  * Return a random integer between (and including) 0 and max.
70  **/
71 
main_rand(int max)72 int main_rand(int max) {
73   return (float)rand() / (float)RAND_MAX * max;
74 }
75 
76 
77 /* Ask for the player names and put them into player1 and player2. */
78 
get_player_names(void)79 void get_player_names(void) {
80   draw_dialog(_("Please enter your name Player 1"), player1, sizeof(player1)-1);
81   draw_dialog(_("Please enter your name Player 2"), player2, sizeof(player2)-1);
82 }
83 
84 /* Init the curses library, clear the screen and hide the cursor. */
85 
init_curses(void)86 void init_curses(void) {
87 	initscr();
88 	start_color();
89 	cbreak();
90 	noecho();
91 	clear();
92 	curs_set(0);
93 	refresh();
94 
95 	/* White text on black bg. Set WA_BOLD to get pure white. */
96 	init_pair (1, COLOR_WHITE, COLOR_BLACK);
97 
98 	/* Brown on black, set WA_BOLD to get yellow. */
99 	init_pair (2, COLOR_YELLOW, COLOR_BLACK);
100 
101 	init_pair (3, COLOR_RED, COLOR_BLACK);
102 
103 	init_pair (4, COLOR_CYAN, COLOR_BLACK);
104 
105 	init_pair (5, COLOR_GREEN, COLOR_BLACK);
106 
107 	init_pair (6, COLOR_BLUE, COLOR_BLACK);;
108 
109 	/* "Clear" screen with new background color. */
110 	bkgdset(' '|COLOR_PAIR(1));
111 	clrtobot();
112   	/*
113 	if (has_colors())
114 		mvprintw (0,0,"%d colours available in %d pairs", COLORS, COLOR_PAIRS);
115 
116 	attron (COLOR_PAIR(1));
117 	attron(WA_BOLD);
118 	mvaddstr (2,0,"white on black");
119 
120 	attroff(WA_BOLD);
121 	attroff (COLOR_PAIR(1));
122 
123 	attron (COLOR_PAIR(2));
124 	attron(WA_BOLD);
125 	mvaddstr (3,0,"yellow on black");
126 	attroff(WA_BOLD);
127 	attroff(COLOR_PAIR(2));
128 
129 	attron(COLOR_PAIR(3));
130 	mvaddstr(4,0,"red on black");
131 	attroff(COLOR_PAIR(3));
132 
133 	attron(COLOR_PAIR(4));
134 	mvaddstr(5,0,"cyan on black");
135 	attroff(COLOR_PAIR(4));
136 
137 	refresh();
138 	getch();
139 	endwin();
140 	exit(1);
141 	*/
142 }
143 /* Clear the screen, deinitialize ncurses and quit. */
144 
main_quit(void)145 void main_quit(void) {
146   clear();
147   refresh();
148   endwin();
149 
150   if (networkplay) {
151     if (side == '1') {
152       if (current_player == 1)
153 	printf(_("%s quit the game.\n"), player1);
154       if (current_player == 2)
155 	printf(_("%s quit the game.\n"), player2);
156     } else if (side == '0')
157       printf(_("You quit the game.\n"));
158   }
159   printf(_("Thanks for playing Tornado!\n"));
160 
161   network_close();
162   exit(0);
163 }
164 
165 /* main_network_function (the following 5 functions):
166  * These functions are used for error checking rather than checking for
167  * errors inside the main program. If a function in network.c
168  * returns an error (-1) the program aborts and prints an error message
169  * to stderr. */
170 
main_network_read(char * buf,int size)171 void main_network_read(char *buf, int size){
172   int result;
173   result = network_read(buf, size);
174   if (result == -1) {
175     perror(_("Error reading from network: "));
176     main_quit();
177   }
178 }
179 
main_network_write(char * buf)180 void main_network_write(char *buf) {
181   int result;
182   result = network_write(buf);
183   if (result == -1) {
184     perror(_("Error writing to network: "));
185     main_quit();
186   }
187 }
188 
main_network_readint(int * i)189 void main_network_readint(int *i) {
190   int result;
191   result = network_readint(i);
192   if (result == -1) {
193     perror(_("Error reading from network: "));
194     main_quit();
195   }
196 }
197 
main_network_writeint(int i)198 void main_network_writeint(int i) {
199   int result;
200   result = network_writeint(i);
201   if (result == -1) {
202     perror(_("Error writing to network: "));
203     main_quit();
204   }
205 }
206 
main_network_writech(char ch)207 void main_network_writech(char ch) {
208   int result;
209   result = network_writech(ch);
210   if (result == -1) {
211     perror(_("Error writing to network: "));
212     main_quit();
213   }
214 }
215 
main_network_readch(char * ch)216 void main_network_readch(char *ch) {
217   int result;
218   result = network_readch(ch);
219   if (result == -1) {
220     perror(_("Error reading network: "));
221     main_quit();
222   }
223 }
224 
225 /*
226  * main function
227  *
228  * Setup everything and enter the main program loop.
229  */
230 
main(int argc,char * argv[])231 int main(int argc, char *argv[]) {
232   char input;			/* used for various keyboard inputs */
233   char input_net[81];		/* var read from network */
234   char statusline[81];		/* holds statusline text */
235   char windspeed_str[23];	/* input buffer for aim */
236   int windspeed = 0;		/* randomly generated windspeed */
237   int userinput = 0;		/* atoi'd version of windspeed_str */
238   //  int current_player = 1;	/* just what it says */
239   int auto_mode = 0;		/* if 1, play in demo mode */
240   //  int erwin_destroy_count = 0;	/* how much did the AI destroy yet? */
241   //  int self_destroyed = 0;	/* how much of my house is destroyed? */
242   int score_player1 = 0;	/* --- player --- */
243   int score_player2 = 0;	/* --- scores --- */
244   int score_tmp = 0;		/*  */
245   char version_check[100];	/* var for comparing client/server version */
246   int rand_pos;			/* random cloud position */
247   char yesno;			/* used for the winning dialog */
248   char tmp1[80], tmp2[80], ch;
249   /*  char *split_ptr, *split_name, *split_ip, *split_time; */
250   int net_connect_error;
251   /*  FILE *wget; */
252 
253   /* Builds the house inside the array */
254   /************************************************
255    * THIS IS THE NEW ARRAY HOUSE GENERATION STUFF *
256    ************************************************/
257   //  char house[17][10] = 0;	/* array holding the house state */
258   //  generate_house(0);		/* call the generator function */
259 
260 #ifdef LOCALEPATH
261   setlocale (LC_ALL, "");
262   bindtextdomain ("tornado", LOCALEPATH);
263   textdomain ("tornado");
264 #endif
265 
266   /* Check for arguments */
267 
268   if (argc > 1) {
269     if (strcmp(argv[1], "--demo") == 0)
270       auto_mode = 1;
271 
272 
273     /*
274     if (strcmp(argv[1], "--get-players") == 0) {
275       printf("\n");
276       printf("Name                   | IP              | Login time\n");
277       printf("-----------------------+-----------------+-----------\n");
278       wget = popen("wget -q -O - http://spot.local/~kiza/linux/tornado/online-players", "r");
279       while (!feof(wget)) {
280 
281 	if (fgets(tmp1, sizeof(tmp1), wget)) {
282 
283 
284 
285           split_name = tmp1;
286 
287 	  split_ptr = strchr(split_name, ':');
288 	  if (!split_ptr)
289 	    continue;
290 	  *split_ptr = '\0';
291 
292 	  split_ip = split_ptr + 1;
293 
294 	  split_ptr = strchr(split_ip, ':');
295 	  if (!split_ptr)
296 	    continue;
297 	  *split_ptr = '\0';
298 
299 	  split_time = split_ptr + 1;
300 
301 	  printf("%-22.22s   %-16.16s  %-9.9s\n", split_name, split_ip, split_time);
302 
303 	}
304 
305       }
306 
307       fclose(wget);
308       printf("\n");
309       exit(0);
310     }
311     */
312 
313     /* If "--login" is specified execute login code and change argv[1] to
314        "--server". */
315     /*
316     if (strcmp(argv[1], "--login") == 0) {
317       printf("debug: --login\n");
318       argv[1] = "--server";
319       login = 1;
320     }
321     */
322 
323 
324 
325     /* The game will act as server, open a socket and liste on port
326      * SERVER_PORT for a connecting client. If opening the socket fails
327      * the program aborts.
328      * If everything is fine, server and client program version are checked.
329      * If they match, go on, if they don't match print out a warning
330      * message. */
331     if (strcmp(argv[1], "--server") == 0) {
332       networkplay = 1;			   /* Set server mode. */
333       printf(_("Waiting for connection on port %d...\n"), SERVER_PORT);
334       if (network_listen(SERVER_PORT) == -1) {
335 	perror(_("Could not initialize Network"));
336 	printf(_("Exiting.\n"));
337 	exit (1);
338       } else {
339 	printf(_("Client from %s connected at port %d.\n\n"),
340 	       network_get_remote_name(), SERVER_PORT);
341 	main_network_write(NETVERSION);
342 	main_network_read(version_check, sizeof(version_check)-1);
343 	if (strcmp(version_check, NETVERSION) != 0) {
344 	  printf(_("Program versions mismatch! You are running version %s, "
345 		 "client is %s.\nYou can play, but the game will get out of sync and probably crash.\n\n"),
346 		 NETVERSION, version_check);
347 	  sleep(3);
348 	}
349       }
350 
351     }
352     /* The game will act a client and connect to the specified IP at port
353      * SERVER_PORT. If the connection fails, the program exits.
354      * See comment for section "--server" above. */
355     if (strcmp(argv[1], "--connect") == 0 ) {
356       networkplay = 2;			   /* Set client mode. */
357       if (argc != 3) {			   /* Check of the user has given enough
358 					    * arguments. If not, quit instead of segfault.*/
359 	printf(_("No hostname specified. Exiting...\n"));
360 	exit(1);
361       }
362       printf(_("Connecting to server %s on port %d...\n"), argv[2], SERVER_PORT);
363       net_connect_error = network_connect(argv[2], SERVER_PORT);
364       if (net_connect_error == -1) {
365 	perror(_("Could not connect to server"));
366 	printf(_("Exiting.\n"));
367 	exit (1);
368       } else if (net_connect_error == -2) {
369 	printf(_("Could not connect to server: hostname lookup failure\n"));
370 	printf(_("Exiting.\n"));
371 	exit (1);
372       } else {
373 	printf(_("Connection to server %s established.\n\n"), argv[2]);
374 	main_network_write(NETVERSION);
375 	main_network_read(version_check, sizeof(version_check)-1);
376 	if (strcmp(version_check, NETVERSION) != 0) {
377 	  printf(_("Program versions mismatch! Your are running version %s, "
378 		 "server is %s.\nYou can play, but the game will get out of sync and probably crash.\n\n"),
379 		 NETVERSION, version_check);
380 	  sleep(3);
381 	}
382       }
383     }
384 
385     if (strcmp(argv[1], "--version") == 0) {
386       printf(_("Tornado version %s\n"), VERSION);
387       return(1);
388     }
389 
390     /* Print usage summary for every unknown command line. */
391     if (strcmp(argv[1], "--help") == 0 || (strcmp(argv[1], "--connect") != 0
392 					   && strcmp(argv[1], "--demo") != 0
393 					   && strcmp(argv[1], "--server") != 0
394 					   && strcmp(argv[1], "--version") != 0
395 					   && strcmp(argv[1], "--get-players") != 0)) {
396       printf(_("Tornado %s\n\n"), VERSION);
397       printf(_("usage: [--connect IP|--demo|--help|--server]\n\n"));
398       printf(_("\t--connect [IP]\tConnect to IP/host for network play.\n"));
399       printf(_("\t--demo\t\tRun in demo mode.\n"));
400       /*      printf("\t--get-players\tGet list of online players from online players webpage.\n");*/
401       printf(_("\t--help\t\tPrint this help message.\n"));
402       /*      printf("\t--login\t\tLogin on the online players webpage.\n"*/
403       /*	     "\t\t\tThis also activates \"--server\". (see manpage)\n");*/
404       printf(_("\t--server\tRun as server so others can connect.\n"));
405       printf(_("\t--version\tPrint version number and exit.\n"));
406       return(1);
407     }
408   }
409 
410   srand(time(0));			      /* initializes the random number generator */
411 
412   /* init ncurses and draw the startup screen */
413 
414   init_curses();
415   draw_house(5,14);
416   draw_house(59,14);
417   draw_cloud(10,0);
418 
419   /* if started with --demo use default player names.
420    * Player who has server will be assigned to Player #1;
421    * client will be assigned Player #2
422    * Otherwise ask both players */
423 
424   if (networkplay == 1) {
425     draw_dialog(_("Please enter your name"), player1, sizeof(player1)-1);
426     main_network_write(player1);
427     draw_window("", _("Waiting for other player..."), "", "");
428     main_network_read(player2, sizeof(player2)-1);
429     draw_window_delete();
430   } else if (networkplay == 2) {
431     draw_dialog(_("Please enter your name"), player2, sizeof(player2)-1);
432     main_network_write(player2);
433     draw_window("", _("Waiting for other player..."), "", "");
434     main_network_read(player1, sizeof(player1)-1);
435     draw_window_delete();
436   } else if (auto_mode == 0) {
437     get_player_names();
438     if (strcmp(player1, "") == 0)
439       strcpy(player1, "Computer");
440     if (strcmp(player2, "") == 0)
441       strcpy(player2, "Computer");
442   } else {
443     strcpy(player1, "Computer");
444     strcpy(player2, "Computer");
445   }
446 
447   /**                      **/
448   /* The main program loop. */
449   /**                      **/
450 
451   while (1) {
452 
453     /* Check if one of the houses is destroyed and draw the winning screen
454      * for the winning player. Aaaand restart the game if necessary. */
455 
456     /* The new count_destroyed if-loop doesn't count snow as part of
457      * house. count_destroyed + count_snow */
458     //    if ((count_destroyed(5, 14, 17, 10)-32) == 138) {
459     //      score_player2 *= (100-((count_destroyed(59, 14, 17, 10)-32) / 138.0 * 100.0));
460     if (((count_destroyed(5, 14, 17, 10)-32)+ (count_snow(5, 14, 17, 10))) == 138) {
461       score_player2 *= (100-((count_destroyed(59, 14, 17, 10)-32) / 138.0 * 100.0));
462       highscore_add(player2, score_player2);
463       yesno = draw_win(2, score_player2, networkplay, player2);
464 
465       if (networkplay == 1)
466 	main_network_writech(yesno);
467       else if (networkplay == 2)
468 	main_network_readch(&yesno);
469 
470       if (yesno == 'y') {
471 	clear();
472 	draw_house(5,14);
473 	draw_house(59,14);
474 	score_player1 = 0;
475 	score_player2 = 0;
476       } else {
477 	main_quit();
478       }
479     }
480 
481 //    else if ((count_destroyed(59, 14, 17, 10)-32) == 138) {
482 //      score_player1 *= (100-((count_destroyed(5, 14, 17, 10)-32) / 138.0 * 100.0));
483     else if (((count_destroyed(59, 14, 17, 10)-32) + (count_snow(59, 14, 17, 10))) == 138) {
484       score_player1 *= (100-((count_destroyed(5, 14, 17, 10)-32) / 138.0 * 100.0));
485       highscore_add(player1, score_player1);
486       yesno = draw_win(1, score_player1, networkplay, player1);
487 
488       if (networkplay == 1)
489 	main_network_writech(yesno);
490       else if (networkplay == 2)
491 	main_network_readch(&yesno);
492 
493       if (yesno == 'y') {
494 	clear();		/* make sure everything is cleared - 1.0.4*/
495 	draw_house(5,14);
496 	draw_house(59,14);
497 	score_player1 = 0;
498 	score_player2 = 0;
499       } else {
500 	main_quit();
501       }
502     }
503 
504     /* Clear the sky after each round and set the
505      * windspeed to a random value */
506 
507     draw_clear_sky();
508     windspeed = (main_rand(10) - 5);
509 
510     /* Send the windspeed to the other side if we are server or
511      * wait until we received it if we're client. */
512 
513     if (networkplay == 1) {
514       sprintf(input_net, "%d", windspeed);
515       main_network_write(input_net);
516     } else if (networkplay == 2) {
517       main_network_read(input_net, sizeof(input_net));
518       windspeed = atoi(input_net);
519     }
520 
521     /* Sprintf the statusline... */
522 
523     sprintf(statusline, _("%c%-23s  %3.0f%% | Windspeed: %2d | %3.0f%%   %23s%c"),
524 	    (current_player == 1) ? '*' : ' ',
525 	    player1,
526 	    //	    100-((count_destroyed(5, 14, 17, 10)-32) / 138.0 * 100.0),
527 	    100-(((count_destroyed(5, 14, 17, 10)-32) + (count_snow(5, 14, 17, 10))) / 138.0 * 100.0),
528 	    windspeed,
529 	    //	    100-((count_destroyed(59, 14, 17, 10)-32) / 138.0 * 100.0),
530 	    100-(((count_destroyed(59, 14, 17, 10)-32) + (count_snow(59, 14, 17, 10))) / 138.0 * 100.0),
531 	    player2,
532 	    (current_player == 2) ? '*' : ' ');
533 
534     /* ... and display it. */
535 
536     draw_statusline(statusline);
537 
538     /* Get a random value for the cloud position. */
539 
540     cloud_x = main_rand(80 - 29);
541 
542     /* Send it over the network if we are server or recieve it, if
543      * we are client. */
544 
545     if (networkplay == 1) {		 sprintf(input_net, "%d", cloud_x);
546     main_network_write(input_net);
547     } else if (networkplay == 2) {
548       main_network_read(input_net, sizeof(input_net));
549       cloud_x = atoi(input_net);
550     }
551 
552     /* Now draw the cloud. */
553 
554     draw_cloud(cloud_x,0);
555 
556     /**                                         **
557      * if: get a weather and an aim from the AI; *
558      * else: ask the player for his choice.      *
559      **                                         **/
560 
561     if (((current_player == 1) && (strcmp(player1, "Computer") == 0))
562 	|| ((current_player == 2) && (strcmp(player2, "Computer") == 0))) {
563 
564       /* Get a weather and an aim from the AI */
565 
566       /*
567       if (current_player == 2) {
568 	erwin_destroy_count = (count_destroyed(5, 14, 17, 10)-32);
569 	self_destroyed = (count_destroyed(59, 14, 17, 10)-32);
570       }
571       if (current_player == 1) {
572 	erwin_destroy_count = (count_destroyed(59, 14, 17, 10)-32);
573 	self_destroyed = (count_destroyed(5, 14, 17, 10)-32);
574 	}
575       */
576 
577 //      input = erwin_choice(erwin_destroy_count, self_destroyed, cloud_x, current_player);
578 //      userinput = erwin_aim(input, windspeed, cloud_x, current_player);
579       input = erwin_choice_new(cloud_x, current_player);
580       userinput = erwin_aim_new(input, windspeed, cloud_x, current_player);
581 
582       switch (input) {
583       case 'l':					   /* lightning */
584 	score_tmp = draw_lightning(cloud_x - 6 + main_rand(27), current_player);
585 	break;
586       case 'r':					   /* rain */
587 	score_tmp = draw_weather(cloud_x + main_rand(14), windspeed + userinput, '/', 1);
588 	break;
589       case 's':					   /* snow */
590 	/*	score_tmp = draw_weather(cloud_x + main_rand(14), windspeed + userinput, '*', 1);*/
591 	score_tmp = draw_snow(cloud_x + main_rand(14), windspeed + userinput, '*');
592 	break;
593       case 'h':					   /* hail */
594 	score_tmp = draw_weather(cloud_x + main_rand(14), windspeed + userinput, ':', 2);
595 	break;
596       case 't':					   /* tornado */
597 	draw_tornado_cloud();
598 	score_tmp = draw_tornado(cloud_x, 1, windspeed + userinput, current_player);
599 	break;
600       }
601     } else {
602 
603     input_here:
604 
605       /* If we are playing a network game, draw a little window to let
606        * the player know what's going on and wait until we got the
607        * data from the other player over the network. */
608       if ((networkplay == 1) && (current_player == 2)) {
609 	draw_window("", _("Waiting for other player..."), "", "");
610 	main_network_read(input_net, sizeof(input_net));
611 	draw_window_delete();
612 	input = input_net[0];
613       } else if ((networkplay == 2) && (current_player == 1)) {
614 	draw_window("", _("Waiting for other player..."), "", "");
615 	main_network_read(input_net, sizeof(input_net));
616 	draw_window_delete();
617 	input = input_net[0];
618       } else {
619 
620 	/* If there is no network game running, proceed normally
621 	 * and draw the user interface. */
622 	input = draw_user_interface();
623 
624 	/* If we are the current player in network mode,
625 	 * send the data to the other side when we entered it. */
626 	if ((input != 'o') && (input != 'c') && (networkplay))
627 	  network_writech(input);
628       }
629 
630 
631       switch (input) {
632       case 'q':					   /* program quit */
633 	if (input_net[0] == 'q')
634 	  side = '1';
635 	main_quit();
636 	break;
637       case 'o':					   /* draw the highscores table */
638 	draw_highscores();
639 	goto input_here;
640 	break;
641       case 'c':
642 	sprintf(tmp1, _("%d points"), score_player1);
643 	sprintf(tmp2, _("%d points"), score_player2);
644 	draw_window(player1, tmp1, player2, tmp2);
645 	ch = getch();
646 	draw_window_delete();
647 	goto input_here;
648 	break;
649       case 'r':					   /* rain */
650 	rand_pos = main_rand(14);
651 
652 	/* If we are not the current player in network mode get the values
653 	 * over the network. */
654 	if (((networkplay == 1) && (current_player == 2)) ||
655 	    ((networkplay == 2) && (current_player == 1))) {
656 	  main_network_read(windspeed_str, sizeof(windspeed_str));
657 	  main_network_readint(&rand_pos);
658 	} else {				   /* If we're not in network mode, */
659 	  do {					   /* ask the player for his aim. */
660 	    draw_dialog("Aim?", windspeed_str, sizeof(windspeed_str)-1);
661 	  } while (strlen(windspeed_str) == 0);
662 
663 	  /* If we are current player in network mode
664 	   * write the values we entered to the network. */
665 	  if (networkplay) {
666 	    main_network_write(windspeed_str);
667 	    main_network_writeint(rand_pos);
668 	  }
669 	}
670 
671 	/* Pass all variables to the draw_weather() funtion. */
672 	userinput = atoi(windspeed_str);
673 	score_tmp = draw_weather(cloud_x + rand_pos, windspeed + userinput, '/', 1);
674 	break;
675       case 's':					   /* snow */
676 	rand_pos = main_rand(14);
677 	if (((networkplay == 1) && (current_player == 2)) ||
678 	    ((networkplay == 2) && (current_player == 1))) {
679 	  main_network_read(windspeed_str, sizeof(windspeed_str));
680 	  main_network_readint(&rand_pos);
681 	}
682 	else {
683 	  do {
684 	    draw_dialog(_("Aim?"), windspeed_str, sizeof(windspeed_str)-1);
685 	  } while (strlen(windspeed_str) == 0);
686 	  if (networkplay) {
687 	    main_network_write(windspeed_str);
688 	    main_network_writeint(rand_pos);
689 	  }
690 	}
691 	userinput = atoi(windspeed_str);
692 	score_tmp = draw_snow(cloud_x + rand_pos, windspeed + userinput, '*');
693 	break;
694       case 'h':					   /* hail */
695 	rand_pos = main_rand(14);
696 	if (((networkplay == 1) && (current_player == 2)) ||
697 	    ((networkplay == 2) && (current_player == 1))) {
698 	  main_network_read(windspeed_str, sizeof(windspeed_str));
699 	  main_network_readint(&rand_pos);
700 	}
701 	else {
702 	  do {
703 	    draw_dialog(_("Aim?"), windspeed_str, sizeof(windspeed_str)-1);
704 	  } while (strlen(windspeed_str) == 0);
705 	  if (networkplay) {
706 	    main_network_write(windspeed_str);
707 	    main_network_writeint(rand_pos);
708 	  }
709 	}
710 	userinput = atoi(windspeed_str);
711 	score_tmp = draw_weather(cloud_x + rand_pos, windspeed + userinput, ':', 2);
712 	break;
713       case 'l':					   /* lightning */
714 	rand_pos = main_rand(27);
715 	if (((networkplay == 1) && (current_player == 2)) ||
716 	    ((networkplay == 2) && (current_player == 1)))
717 	  main_network_readint(&rand_pos);
718 	else if (networkplay)
719 	  main_network_writeint(rand_pos);
720 	score_tmp = draw_lightning(cloud_x - 6 + rand_pos, current_player);
721 	break;
722       case 't':					   /* tornado */
723 	draw_tornado_cloud();
724 	if (((networkplay == 1) && (current_player == 2)) ||
725 	    ((networkplay == 2) && (current_player == 1)))
726 	  main_network_read(windspeed_str, sizeof(windspeed_str));
727 	else {
728 	  do {
729 	    draw_dialog(_("Aim?"), windspeed_str, sizeof(windspeed_str)-1);
730 	  } while (strlen(windspeed_str) == 0);
731 	  if (networkplay)
732 	    main_network_write(windspeed_str);
733 	}
734 	userinput = atoi(windspeed_str);
735 	score_tmp = draw_tornado(cloud_x, 1, windspeed + userinput, current_player);
736 	break;
737       default:
738 	beep();
739 	goto input_here;
740       }
741     }
742 
743     /* Cycle players */
744 
745     if (current_player == 1) {
746       current_player = 2;
747       score_player1 = score_player1 + (score_tmp * score_tmp);
748     } else if (current_player == 2) {
749       current_player = 1;
750       score_player2 = score_player2 + (score_tmp * score_tmp);
751     }
752   }
753 
754   main_quit();
755   return 0;
756 }
757