1 /***********************************************************
2 *                      K O U L E S                         *
3 *----------------------------------------------------------*
4 *  C1995 JAHUSOFT                                          *
5 *        Jan Hubicka                                       *
6 *        Dukelskych bojovniku 1944                         *
7 *        390 03 Tabor                                      *
8 *        Czech Republic                                    *
9 *        Phone: 0041-361-32613                             *
10 *        eMail: hubicka@limax.paru.cas.cz                  *
11 *----------------------------------------------------------*
12 *    Copyright(c)1995,1996 by Jan Hubicka.See README for   *
13 *                    licence details.                      *
14 *----------------------------------------------------------*
15 *  gameplan.c scores,levels......                          *
16 ***********************************************************/
17 /* Changes for OS/2 Warp with Dive.                        *
18  *  Copyright(c)1996 by Thomas A. K. Kjaer                 *
19  ***********************************************************/
20 
21 #include "koules.h"
22 #include "server.h"
23 #define HOLELEVEL 5
24 #define BBALLLEVEL (nrockets==1?12:10)
25 #define EHOLELEVEL 20
26 #define SPRINGLEVEL 30
27 #define THIEFLEVEL 40
28 #define FINDERLEVEL 50
29 #define TTOOLLEVEL 60
30 #define INSPECTORLEVEL 70
31 #define BBBALLLEVEL 90
32 #define LUNATICLEVEL 80
33 
34 static int      level = 0;
35 static int      gtime;
36 static int      nos;
37 static int      ktime = 0;
38 static int      kmode = 0;
39 static int      secondpart;
40 void
gameplan_init()41 gameplan_init ()
42 {
43 #ifdef DEBUG
44   level = 98;
45 #else
46   level = lastlevel;
47 #endif
48 }
49 void
effect(int so)50 effect (int so)
51 {
52   char            s[20];
53   if (gamemode == GAME)
54     {
55       if (!so)
56 	Effect (S_START, 0);
57       else
58 	Effect (S_END, 0);
59     }
60   if (gameplan == COOPERATIVE)
61     {
62 #ifdef SOUND
63 #endif
64       gamemode = MENU;
65 #ifndef DEBUG
66       if (!so && level == 0)
67 #endif
68 	intro_intro ();
69 #ifndef DEBUG
70       if (!so && level == HOLELEVEL + 1)
71 #endif
72 	hole_intro ();
73 #ifndef DEBUG
74       if (!so && level == INSPECTORLEVEL)
75 #endif
76 	inspector_intro ();
77 #ifndef DEBUG
78       if (!so && level == BBALLLEVEL + 1)
79 #endif
80 	bball_intro ();
81 #ifndef DEBUG
82       if (!so && level == BBBALLLEVEL)
83 #endif
84 	bbball_intro ();
85 #ifndef DEBUG
86       if (!so && level == EHOLELEVEL)
87 #endif
88 	maghole_intro ();
89 #ifndef DEBUG
90       if (!so && level == SPRINGLEVEL + 1)
91 #endif
92 	spring_intro ();
93 #ifndef DEBUG
94       if (!so && level == THIEFLEVEL)
95 #endif
96 	thief_intro ();
97 #ifndef DEBUG
98       if (!so && level == FINDERLEVEL)
99 #endif
100 	finder_intro ();
101 #ifndef DEBUG
102       if (!so && level == TTOOLLEVEL)
103 #endif
104 	ttool_intro ();
105 #ifndef DEBUG
106       if (!so && level == LUNATICLEVEL)
107 #endif
108 	lunatic_intro ();
109       if (!so && level == 99)
110 	outro1 ();
111     }
112   gamemode = GAME;
113   SetScreen (backscreen);
114   ClearScreen ();
115   tbreak = 1;
116   if (gameplan == COOPERATIVE)
117     sprintf (s, "SECTOR %i", level + 1);
118   else
119     sprintf (s, "GET READY");
120 #ifdef XSUPPORT
121   DrawWhiteMaskedText (MAPWIDTH / 2 - 32, MAPHEIGHT / 2 - 4, s);
122 #else
123   DrawText (MAPWIDTH / 2 - 32, MAPHEIGHT / 2 - 4, s);
124 #endif
125   CopyToScreen (backscreen);
126   fadein ();
127 #ifdef XSUPPORT
128   XFlush (dp);
129 #endif
130 #ifdef OS2DIVE
131   forceBlitting ();
132 #endif
133   fflush (stdout);
134   usleep (1000000);
135 }
136 /*
137  * level creation routines
138  */
139 static void
init_objects1()140 init_objects1 ()
141 {
142   int             i, nholes;
143   dosprings = 0;
144   lastlevel = level;
145   if (maxlevel < level)
146     maxlevel = level;
147   save_rc ();
148   if (gamemode != GAME)
149     {
150       nobjects = 0;
151       return;
152     }
153   switch (gameplan)
154     {
155     case DEATHMATCH:
156       dosprings = 1;		/* enable spring in death match */
157       randsprings = 40;
158       if (nrockets != 1)
159 	{
160 	  nobjects = nrockets * 3 * GAMEWIDTH / 640 * GAMEHEIGHT / 460 + 3;
161 	  for (i = 0; i < nobjects; i++)
162 	    object[i].live = 0;
163 	  for (i = 0; i < nobjects; i++)
164 	    {
165 	      object[i].live = 1;
166 	      object[i].lineto = -1;
167 	      object[i].live1 = 1;
168 	      object[i].thief = 0;
169 	      object[i].time = (i < nrockets ? 99 : 0);
170 	      object[i].fx = 0;
171 	      object[i].fy = 0;
172 	      object[i].rotation = 0;
173 	      object[i].type = (i < nrockets ? ROCKET : BALL);
174 	      if (!find_possition (&object[i].x, &object[i].y, radius (object[i].type)))
175 		return;
176 	      object[i].M = M (object[i].type);
177 	      object[i].radius = radius (object[i].type);
178 	      object[i].accel = ROCKET_SPEED;
179 	      object[i].letter = ' ';
180 	      secondpart = 0;
181 	    }
182 	  nholes = nrockets / 3 + 1;
183 	  for (i = 0; i < nholes; i++)
184 	    creator (HOLE);
185 	  creator (INSPECTOR);
186 	  creator (EHOLE);
187 	}
188       else
189 	{
190 	  nobjects = 2;
191 	  for (i = 0; i < nobjects; i++)
192 	    object[i].live = 0;
193 	  for (i = 0; i < nobjects; i++)
194 	    {
195 	      object[i].live = 1;
196 	      object[i].lineto = -1;
197 	      if (i != 0)
198 		object[i].lineto = 0;
199 	      object[i].live1 = 1;
200 	      object[i].thief = 0;
201 	      object[i].time = (i < nrockets ? 99 : 0);
202 	      object[i].fx = 0;
203 	      object[i].fy = 0;
204 	      object[i].rotation = 0;
205 	      object[i].type = (i < nrockets ? ROCKET : LUNATIC);
206 	      if (!find_possition (&object[i].x, &object[i].y, radius (object[i].type)))
207 		return;
208 	      object[i].M = M (object[i].type);
209 	      object[i].radius = radius (object[i].type);
210 	      object[i].accel = ROCKET_SPEED;
211 	      object[i].letter = ' ';
212 	      secondpart = 0;
213 	    }
214 	}
215       break;
216     case COOPERATIVE:
217       if (level != 99)
218 	{
219 	  int             nbballs;
220 	  if (level > SPRINGLEVEL)
221 	    dosprings = 1;
222 	  randsprings = 40 - level / 3;
223 	  nobjects = 3 + sqrt (level) * ((nrockets + 1) / 2) + 2 * nrockets;
224 	  nobjects = (float) nobjects *(GAMEWIDTH / 640 * GAMEHEIGHT / 460 + 2) / 3;
225 	  if (nobjects > 30)
226 	    nobjects = 30;
227 	  for (i = 0; i < nobjects; i++)
228 	    object[i].live = 0;
229 	  nbballs = nrockets + level / BBBALLLEVEL;
230 	  gtime = 100 + 1000 / (level + 1);
231 	  for (i = 0; i < nobjects; i++)
232 	    {
233 	      object[i].live = (i < nrockets ? 5 : 1);
234 	      object[i].live1 = (i < nrockets ? 5 : 1);
235 	      object[i].lineto = -1;
236 	      object[i].thief = 0;
237 	      object[i].time = (i < nrockets ? 100 : 0);
238 	      object[i].fx = 0;
239 	      object[i].fy = 0;
240 	      object[i].rotation = 0;
241 	      object[i].type = (i < nrockets ? ROCKET : (i < nbballs ? BBALL : BALL));
242 	      object[i].M = M (object[i].type);
243 	      if (i < nrockets)
244 		{
245 		  if (level < 5)
246 		    object[i].M *= 1.0 + (5.0 - level) / 15.0;
247 		  if (level < 25)
248 		    object[i].M *= 1.0 + (level) / 120.0;
249 		}
250 	      object[i].radius = radius (object[i].type);
251 	      object[i].accel = ROCKET_SPEED;
252 	      if (!find_possition (&object[i].x, &object[i].y, radius (object[i].type)))
253 		return;
254 	      object[i].letter = ' ';
255 	    }
256 	}
257       else
258 	{
259 	  nobjects = nrockets + 10;
260 	  for (i = 0; i < nobjects; i++)
261 	    object[i].live = 0;
262 	  object[nrockets].type = APPLE;
263 	  object[nrockets].M = APPLEM;
264 	  object[nrockets].lineto = -1;
265 	  object[nrockets].thief = 0;
266 	  object[nrockets].radius = APPLE_RADIUS;
267 	  object[nrockets].live = (i < nrockets ? 5 : 1);
268 	  object[nrockets].fx = 0;
269 	  object[nrockets].fy = 0;
270 	  object[nrockets].x = GAMEWIDTH / 2;
271 	  object[nrockets].y = GAMEHEIGHT / 2;
272 	  for (i = 0; i < nrockets; i++)
273 	    {
274 	      object[i].live = 5;
275 	      object[i].live1 = 5;
276 	      object[i].time = 100;
277 	      object[i].thief = 0;
278 	      object[i].lineto = -1;
279 	      object[i].fx = 0;
280 	      object[i].fy = 0;
281 	      object[i].rotation = 0;
282 	      object[i].type = ROCKET;
283 	      object[i].accel = ROCKET_SPEED;
284 	      object[i].M = M (object[i].type);
285 	      object[i].radius = radius (object[i].type);
286 	      object[i].letter = ' ';
287 	      object[i].x = GAMEWIDTH / 2 + sin (i * RAD (360) / nrockets) * GAMEHEIGHT / 3;
288 	      object[i].x = GAMEHEIGHT / 2 + cos (i * RAD (360) / nrockets) * GAMEHEIGHT / 3;
289 	    }
290 	  for (i = nrockets + 1; i < nobjects; i++)
291 	    {
292 	      object[i].live = 1;
293 	      object[i].live1 = 1;
294 	      object[i].lineto = -1;
295 	      object[i].time = 0;
296 	      object[i].thief = 0;
297 	      object[i].fx = 0;
298 	      object[i].fy = 0;
299 	      object[i].rotation = 0;
300 	      object[i].type = BALL;
301 	      object[i].accel = BALL_SPEED;
302 	      object[i].M = M (object[i].type);
303 	      object[i].radius = radius (object[i].type);
304 	      object[i].letter = ' ';
305 	      if (!find_possition (&object[i].x, &object[i].y, radius (object[i].type)))
306 		return;
307 	    }
308 	}
309     }
310   ktime = 0;
311 }
312 void
init_objects()313 init_objects ()
314 {
315   switch (difficulty)
316     {
317     case 0:
318       ROCKET_SPEED = 0.8;
319       BALL_SPEED = 1.2;
320       BBALL_SPEED = 1.2;
321       SLOWDOWN = 0.9;
322       GUMM = 20;
323 
324 
325       BALLM = 3;
326       LBALLM = 3;
327       BBALLM = 8;
328       APPLEM = 40;
329       ROCKETM = 2;
330       break;
331     case 1:
332       ROCKET_SPEED = 1.0;
333       BALL_SPEED = 1.2;
334       BBALL_SPEED = 1.2;
335       SLOWDOWN = 0.9;
336       GUMM = 20;
337 
338 
339       BALLM = 3;
340       LBALLM = 3;
341       BBALLM = 8;
342       APPLEM = 40;
343       ROCKETM = 4;
344 
345       break;
346     case 2:
347       ROCKET_SPEED = 1.2;
348       BALL_SPEED = 1.2;
349       BBALL_SPEED = 1.2;
350       SLOWDOWN = 0.8;
351       GUMM = 20;
352 
353 
354       APPLEM = 34;
355       BALLM = 3;
356       LBALLM = 3;
357       BBALLM = 8;
358       ROCKETM = 4;
359       break;
360     case 3:
361       ROCKET_SPEED = 2.0;
362       BALL_SPEED = 1.2;
363       BBALL_SPEED = 1.2;
364       SLOWDOWN = 0.8;
365       GUMM = 20;
366 
367 
368       BALLM = 3;
369       LBALLM = 3;
370       APPLEM = 24;
371       BBALLM = 8;
372       ROCKETM = 5;
373       break;
374     case 4:
375       ROCKET_SPEED = 2.0;
376       BALL_SPEED = 1.2;
377       BBALL_SPEED = 1.2;
378       SLOWDOWN = 0.8;
379       GUMM = 15;
380 
381 
382       BALLM = 3;
383       LBALLM = 3;
384       APPLEM = 24;
385       BBALLM = 8;
386       ROCKETM = 7;
387 
388 
389     }
390 #ifdef NETSUPPORT
391   if (!server)
392 #endif
393     clearpoints ();
394 #ifdef NETSUPPORT
395   if (!client)
396 #endif
397     init_objects1 ();
398   if (!server)
399     effect (nos);
400 #ifdef NETSUPPORT
401   else
402     {
403       if (server)
404 	SEffect (lastlevel, nos);
405     }
406 #endif
407 
408 }
409 
410 int
allow_finder()411 allow_finder ()
412 {
413   if (level > FINDERLEVEL || gameplan == DEATHMATCH)
414     return 1;
415   return 0;
416 }
417 int
create_letter()418 create_letter ()
419 {
420   int             tirage, chance, letter;
421   int             i;
422   if (gameplan == COOPERATIVE)
423     {
424       i = rand () % 4;
425       if (i < 3)
426 	return (i);
427       if (level > THIEFLEVEL && rand () % 400 < level - THIEFLEVEL + 40)
428 	return (3);
429       if (level > TTOOLLEVEL && rand () % 600 < level - TTOOLLEVEL + 40)
430 	return (5);
431       if (level > FINDERLEVEL && gtime < 0 && rand () % 700 < level - FINDERLEVEL + 40)
432 	return (4);
433       return (0);
434     }
435   chance = rand () % 100;
436   if (chance < 80)
437     {				/* create letter : = 1 rand / 2 */
438       tirage = rand () % 100;
439       if (tirage < 30)
440 	letter = 1;
441       else if (tirage < 60)
442 	letter = 2;
443       else if (tirage < 70)
444 	letter = 5;
445       else if (tirage < 80)
446 	letter = 3;
447       else
448 	letter = 4;
449       return (letter);
450     }
451   else
452     return (0);
453 
454 }
455 void
update_game()456 update_game ()
457 {
458   int             i;
459   if (gamemode == GAME)
460     {
461       if (ktime)
462 	{
463 	  ktime--;
464 	  if (ktime == 0)
465 	    switch (kmode)
466 	      {
467 	      case 1:
468 		init_objects ();
469 		break;
470 	      case 2:
471 		lastlevel = 0;
472 		level = 1, gamemode = MENU;
473 #ifdef NETSUPPORT
474 		if (server)
475 		  Outro ();
476 		else
477 #endif
478 		  outro2 ();
479 		break;
480 	      case 3:
481 		if (a_balls || a_bballs || a_inspectors || a_lunatics)
482 		  break;
483 		for (i = 0; i < nrockets; i++)
484 		  if (object[i].type == ROCKET && object[i].live)
485 		    object[i].score += object[i].live * 20;
486 		level++, init_objects ();
487 		break;
488 	      case 4:
489 		for (i = 0; i < nrockets; i++)
490 		  if (object[i].type == ROCKET)
491 		    object[i].score -= 100;
492 		nos = 1;
493 		init_objects ();
494 		nos = 0;
495 		break;
496 	      }
497 	}
498       else
499 	switch (gameplan)
500 	  {
501 
502 
503 	  case DEATHMATCH:
504 	    if (nrockets == 1)
505 	      {
506 		if (!(rand () % 60))
507 		  creator (HOLE);
508 		if (a_rockets == 0)
509 		  {
510 		    ktime = 50;
511 		    kmode = 1;
512 		    object[0].score -= 100;
513 		  }
514 		if (a_lunatics == 0)
515 		  {
516 		    ktime = 50;
517 		    kmode = 1;
518 		    object[0].score += 100;
519 		  }
520 		break;
521 	      }
522 	    if (a_balls == 0)
523 	      secondpart = 1;
524 	    if (a_lunatics < nrockets && !(rand () % 150))
525 	      creator (LUNATIC);
526 	    if (secondpart)
527 	      {
528 		if (!(rand () % 100))
529 		  creator (BBALL);
530 		if (!(rand () % 60))
531 		  creator (HOLE);
532 		if (!(rand () % 400))
533 		  creator (BBALL);
534 		if (!(rand () % 400))
535 		  creator (INSPECTOR);
536 		if (!(rand () % 600))
537 		  creator (EHOLE);
538 	      }
539 
540 	    if (a_rockets <= 1)
541 	      {
542 		ktime = 50;
543 		kmode = 1;
544 	      }
545 	    break;
546 
547 
548 
549 	  case COOPERATIVE:
550 	    if (level == 99)
551 	      {
552 		if (!a_apples)
553 		  ktime = 50, kmode = 2;
554 		if (a_balls < 15)
555 		  if (!(rand () % 40))
556 		    creator (BALL);
557 		/*if (a_lunatics < 3)
558 		   if (!(rand () % 90))
559 		   creator (LUNATIC); */
560 		if (a_bballs < 3)
561 		  if (!(rand () % 3000))
562 		    creator (BBALL);
563 	      }
564 	    else
565 	      {
566 		gtime--;
567 		if (a_balls == 0 && a_bballs == 0 && a_inspectors == 0 && a_lunatics == 0)
568 		  {
569 		    ktime = 50, kmode = 3;
570 		  }
571 		if (a_balls < 4 * level && gtime < 0)
572 		  if (!(rand () % ((nrockets == 1 ? 200 : 150) + (110 - level))))
573 		    creator (BALL);
574 		if (a_lunatics < (level - LUNATICLEVEL) && a_lunatics < 3 && gtime < 0)
575 		  if (!(rand () % ((nrockets == 1 ? 800 : 450) + (110 - level))))
576 		    creator (LUNATIC);
577 
578 		if (a_holes < 4 * (level - HOLELEVEL) && gtime < 0)
579 		  if (!(rand () % (412 + 512 / level)))
580 		    creator (HOLE);
581 		if (a_bballs < 4 * (level - BBALLLEVEL) && gtime < 0)
582 		  if (!(rand () % ((nrockets == 1 ? 700 : 500) + 1 * (110 - level) / 3 + 2024 / level)))
583 		    creator (BBALL);
584 		if (a_inspectors < level / (INSPECTORLEVEL) && gtime < 0)
585 		  if (!(rand () % (1500 + 10 * (110 - level))))
586 		    creator (INSPECTOR);
587 		if (a_eholes < level / EHOLELEVEL + 1 && gtime < 0 && level >= EHOLELEVEL)
588 		  if (!(rand () % (500 + 1000 / level)))
589 		    creator (EHOLE);
590 	      }
591 	    if (a_rockets == 0)
592 	      {
593 		ktime = 50;
594 		kmode = 4;
595 	      }
596 	  }
597     }
598   else
599     {
600       if (a_balls < 5 && !(rand () % (50)))
601 	creator (BALL);
602       if (a_lunatics < 5 && !(rand () % (50)))
603 	creator (LUNATIC);
604       if (a_bballs < 4 && !(rand () % (200)))
605 	creator (BBALL);
606     }
607 }
608