1 /***************************************************************************
2                           gamedefs.h  -  description
3                              -------------------
4     begin                : Thu Sep 6 2001
5     copyright            : (C) 2001 by Michael Speck
6     email                : kulkanie@gmx.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef __GAMEDEFS_H
19 #define __GAMEDEFS_H
20 
21 enum {
22 	/* game/level types */
23 	GT_LOCAL = 0,
24 	GT_NETWORK,
25 	LT_NORMAL = 0,
26 	LT_PINGPONG,
27 
28 	/* playing field */
29 	MAP_WIDTH = 16,
30 	MAP_HEIGHT = 24,
31 	EDIT_WIDTH = 14,
32 	EDIT_HEIGHT = 18,
33 
34 	/* extras */
35 	EX_NONE = -1,
36 	EX_SCORE200 = 0,
37 	EX_SCORE500,
38 	EX_SCORE1000,
39 	EX_SCORE2000,
40 	EX_SCORE5000,
41 	EX_SCORE10000,
42 	EX_GOLDSHOWER,
43 	EX_SHORTEN,
44 	EX_LENGTHEN,
45 	EX_LIFE,
46 	EX_SLIME,
47 	EX_METAL,
48 	EX_BALL,
49 	EX_WALL,
50 	EX_FROZEN,
51 	EX_WEAPON,
52 	EX_RANDOM,
53 	EX_FAST,
54 	EX_SLOW,
55 	EX_JOKER,
56 	EX_DARKNESS,
57 	EX_CHAOS,
58 	EX_GHOST_PADDLE,
59 	EX_DISABLE,
60 	EX_TIME_ADD,
61 	EX_EXPL_BALL,
62 	EX_BONUS_MAGNET,
63 	EX_MALUS_MAGNET,
64 	EX_WEAK_BALL,
65 	EX_NUMBER,
66 	TIME_WALL   = 10000,
67 	TIME_METAL  =  5000,
68 	TIME_WEAPON =  5000,
69 	TIME_FROZEN =  1000,
70 	TIME_SLIME  = 20000,
71 	TIME_FAST   = 20000,
72 	TIME_SLOW   = 20000,
73 	TIME_GOLDSHOWER   = 20000,
74 	TIME_DARKNESS     = 20000,
75 	TIME_CHAOS        = 10000,
76 	TIME_GHOST_PADDLE = 20000,
77 	TIME_EXPL_BALL    = 10000,
78 	TIME_BONUS_MAGNET = 20000,
79 	TIME_MALUS_MAGNET = 20000,
80 	TIME_WEAK_BALL    = 10000,
81 
82 	/* unused */
83 	TIME_SPIN_RIGHT   = 20000,
84 	TIME_SPIN_LEFT    = 20000,
85 
86 	/* paddle */
87 	PADDLE_INVIS_DELAY = 200,
88 	WEAPON_FIRE_RATE = 150,
89 	BALL_FIRE_RATE = 500,
90 	BALL_RESPAWN_TIME = 5000, /* in normal multiplayer levelsets a user may bring
91 				    a new ball to game after this time penalty */
92 	ATTRACT_NONE = 0,
93 	ATTRACT_BONUS,
94 	ATTRACT_MALUS,
95 	PADDLE_BOTTOM = 0,
96 	PADDLE_TOP,
97 	PADDLE_WEAPON_AMMO = 100,
98 
99 	/* bricks */
100 	INVIS_BRICK_ID = 6,	/* id of invisible brick */
101 	BRICK_EXP_TIME = 150, 	/* delay until explosion */
102 	BRICK_COUNT = 26, 	/* various brick types */
103 	BRICK_COUNT_REGULAR = 20, /* number of available bricks for edit */
104 	BRICK_GROW_FIRST = 12, 	/* only bricks within this range may grow randomly */
105 	BRICK_GROW_LAST = 17,
106 	GROW_BRICK_ID = 19,
107 	BRICK_HEAL_TIME = 4000,	/* after this time duration is increased */
108 	EXTRA_STACK_LIMIT = 20,
109 
110 	MAP_EMPTY = 0,		/* no brick */
111 	MAP_WALL,       	/* can't be destroyed at all */
112 	MAP_BRICK,      	/* may be destroyed if duration is not -1 */
113 	MAP_BRICK_EXP, 		/* explodes neighbors if destroyed */
114 	MAP_BRICK_GROW,	 	/* grow neighbors if destroyed */
115 	MAP_BRICK_HEAL, 	/* heals itself when hit */
116 	MAP_BRICK_CHAOS,	/* chaotic reflection by this brick */
117 
118 	BRICK_WIDTH = 40,
119 	BRICK_HEIGHT = 20,
120 	BRICK_SCORE = 100,
121 
122 	/* hit types */
123 	HT_HIT = 0,	/* decrease duration */
124 	HT_HEAL,	/* negative hit: regeneration */
125 	HT_REMOVE,	/* remove brick completely */
126 	HT_GROW,	/* create brick with random color */
127 	HT_REMOVE_NO_SOUND, /* is mapped to HT_REMOVE and no_sound=1 */
128 
129 	/* balls */
130 	BALL_NORMAL = 0,
131 	BALL_METAL,
132 	BALL_EXPL,
133 	BALL_WEAK,
134 	BALLS_IDLE_LIMIT=10000,
135 	BALL_NO_ENTROPY = 0,
136 	BALL_ADD_ENTROPY,
137 
138 	/* particles */
139 	SHR_BY_NORMAL_BALL = 0,
140 	SHR_BY_ENERGY_BALL,
141 	SHR_BY_SHOT,
142 	SHR_BY_EXPL,
143 	SHR_BY_EXPL_WITH_EXPL, /* shrapnells as from explosion and draw an explosion */
144 	SHR_BY_DELAYED_EXPL, /* no explosion animation except for a expl brick */
145 
146 	/* modifications, beyond this count they are dropped */
147 	MAX_MODS = 256,
148 
149 	/* difficulty */
150 	DIFF_COUNT = 4,
151 
152 	/* players */
153 	MAX_PLAYERS = 4,
154 
155 	/* credits */
156 	HIDE_CREDIT = 0,
157 	SHOW_CREDIT,
158 
159 	/* levels */
160 	MAX_LEVELS = 40,
161 
162 	/* bonus level types (start at 2) */
163 	LT_JUMPING_JACK = 2,
164     LT_OUTBREAK,
165     LT_BARRIER,
166     LT_SITTING_DUCKS,
167     LT_HUNTER,
168 	LT_DEFENDER,
169     LT_LAST
170 };
171 
172 /* small helper to identify grown bricks by char */
173 #define IS_GROWN_BRICK_CHAR(ch) ((ch) >= 'F' && (ch) <= 'K')
174 
175 typedef struct Level {
176   char 	author[32], name[32];
177   /* extras and bricks are saved by their specific character and
178      interpreted by bricks_create later */
179   char 	bricks[EDIT_WIDTH][EDIT_HEIGHT];
180   char 	extras[EDIT_WIDTH][EDIT_HEIGHT];
181   int   normal_brick_count;
182   int   type; /* normal or type of bonus level */
183 } Level;
184 typedef struct {
185 	char	name[20];
186 	int 	count;
187 	int	version, update;
188 	int	cur_level; /* id of current level */
189 	Level	**levels;
190 } LevelSet;
191 
192 typedef struct {
193     float   x, y;
194 } Vector;
195 typedef Vector Coord;
196 
197 typedef struct {
198 	int     exists; /* is there a target */
199 	int     mx, my; /* position in map */
200 	float   x, y; /* reset position of ball */
201 	int     time; /* time till contact */
202 	int     cur_tm; /* current time */
203 	Vector  perp_vector; /* reflection vector */
204 	int     side; /* side/corner of brick hit */
205 } Target;
206 
207 typedef struct {
208 	int	total_score; /* or frags */
209 
210 	int	balls_reflected;
211 	int	balls_lost;
212 	int	bricks_cleared;
213 	int	total_brick_count;
214 	int	extras_collected;
215 	int	total_extra_count;
216 
217 	int	wins, losses, draws;
218 	int	played_rounds;
219 } GameStats;
220 
221 typedef struct {
222 	char		name[32]; 	/* name */
223 	int		lives;		/* lives remaining (single player) */
224 	GameStats	stats; 		/* total score and stuff */
225 	int		paddle_id;	/* index of paddle in game::paddles */
226 	int 		level_id;	/* index in levelset the player is currently in.
227 					   to initiate a level the snapshot is used
228 					   as the player modifies the level data which
229 					   must be saved for alternating games */
230 	Level		snapshot; 	/* if player switches in alternating game a
231 					   snapshot is kept of the players progress
232 					   in this level. when it is its turn again
233 					   it starts with this leveldata */
234 	int		next_level_received;
235 	int		next_paddle_id; /* whether level has been received */
236 } Player;
237 
238 /* if this is not defined paddle has no velocity balls are reflected by convex surface */
239 #define PADDLE_FRICTION
240 
241 typedef struct {
242 	int	score; /* score/frags gained by this paddle */
243 	int     type; /* either top or bottom */
244 	float   cur_x;
245 	int     x, y;
246 	int     w, h; /* actual geometry */
247 #ifdef PADDLE_FRICTION
248 	float   v_x;
249 #endif
250 	int	wanted_w; /* resize until w == wanted_w */
251 	int     len; /* how many middle components ? */
252 	int	start_len;
253 	int     min_len, max_len; /* limits */
254 	float   friction; /* how much relative speed is given to balls ? */
255 	int     friction_delay; /* its hard to exactly hit the moment when the ball touches the paddle
256 				   so while this is >0 friction is applied */
257 	int     frozen; /* paddle frozen? */
258 	int     slime; /* paddle covered with sticky slime */
259 	int     attract; /* true if paddle attracts balls */
260 	Delay   resize_delay; /* every delay ms the paddle size is adjusted about two pixels */
261 	int     invis; /* is paddle invisible? */
262 	int     invis_delay; /* as long as this isn't timed out the paddle is seen.
263 			     	will be reset by movement */
264 
265 	/* FIRE STATE - updated by paddle_handle_events() & comm_update_remote_paddle() */
266 	int	fire_left;
267 	int	fire_right;	/* wether player presses fire buttons */
268 	int	ball_return_key_pressed; /* wether player wants to return idle balls */
269 
270 	/* WEAPON - handled by paddle_update() */
271 	double  weapon_cur;
272 	int     weapon_inst;  /* is weapon installed? */
273 	int     weapon_fire_delay; /* if >0 and either fire_left or fire_right is True checked
274 				 against milliseconds wether it drops <=0 in which
275 				 case it is reset to WEAPON_FIRE_RATE and a shot is fired */
276 	int     weapon_ammo;  /* number of shots available */
277 
278 	/* BALLS - handled by balls_update() !!! */
279 	int	ball_fire_delay; 	/* analogue to weapon_fire_delay */
280 	int	ball_ammo;		/* number of balls player may bring to game */
281 	int	start_ball_ammo;	/* initial ammount as ball ammo is modified while playing */
282 	int	last_ball_contact;	/* in NormMP player may fire a new ball when this
283 					   time is longer ago than BALL_RESPAWN_TIME and no
284 					   balls are attached. Then a new ball is created and
285 					   attached to paddle. */
286 	int     attached_ball_count;	/* number of attached balls */
287 	int	ball_ammo_disp_y; /* icons are drawn centered at y */
288         int     maxballspeed_request;
289         int     maxballspeed_request_old; /* when middle mouse button is pressed the balls
290                                              are accelerated to max speed if old state was
291                                              zero and vice versa to slow down again */
292 
293 	/* EXTRAS */
294 	int    	extra_active[EX_NUMBER];
295 	int     extra_time[EX_NUMBER]; 	/* paddle specific extras */
296 	int     wall_y; 		/* position where wall is drawn */
297 	double  wall_alpha;
298 
299 	/* STATISTICS */
300 	int	balls_reflected;	/* how many times successfully reflected a ball */
301 	int	balls_lost;		/* how many balls lost? */
302 	int	extras_collected;	/* number of collected extras. the total number is
303 					   extra_count in struct game */
304 	int	bricks_cleared;		/* again the total number is brick_count in game */
305 
306 	/* used by client */
307 	Player		*player;
308 	int		pic_x_offset;
309 	int		pic_y_offset;
310 	SDL_Rect	update_rect; /* screen update region */
311 
312     /* used for dummy paddles */
313     float   bot_vx; /* paddle velocity in pix/msec */
314 } Paddle;
315 
316 typedef struct {
317     Coord   cur; /* current position */
318     int     x, y;
319     Vector  vel; /* velocity components */
320     int	    angle; /* angle 0-180 of vector */
321     int     attached; /* attached to paddle ? */
322     Paddle  *paddle; /* last paddle the ball had contact with */
323     int     moving_back; /* ball moves back to paddle as there was no
324                             brick/paddle contact within the last
325                             20 secs */
326     int     idle_time; /* time passed since last brick/paddle contact */
327     int     return_allowed; /* if this is set returning by click is allowed */
328     Target  target; /* target in map */
329     int     get_target; /* if this is true balls_update() will compute the target
330                            and clear this flag */
331 } Ball;
332 
333 typedef struct {
334     float   x, y;
335     Target  target;
336     int     next_too; /* destroys right brick, too */
337     Paddle *paddle; /* paddle that initiated the shot */
338     int     dir; /* direction of shot depending on paddle */
339     int     get_target; /* if this is true shots_update() will compute the target
340                            and clear this flag */
341 
342     /* used by client */
343     float	cur_fr;
344     SDL_Rect	update_rect; /* screen update region */
345 } Shot;
346 
347 typedef struct {
348 	int type;	/* any of the old MAP_XXX types above */
349 	int id; 	/* picture id -- if -1 no brick -- if 0 it's indestructible */
350 	int dur; 	/* durability - if -1 & type != MAP_WALL it's only destructible
351 			   by energy ball */
352 	int extra; 	/* extra released when destroyed */
353 	int score; 	/* score you get when desctroying this brick */
354 	int exp_time;	/* -1 means inexplosive; value is set by a nearby explosion brick */
355 	Paddle *exp_paddle; /* paddle that initiated the explosion */
356 	int heal_time; 	/* if not -1 counted down and when 0 brick heals one duration
357 			   (until fully healed) */
358 	int mx, my; 	/* position of brick in map */
359 	char brick_c;	/* original character when saved to file */
360 	char extra_c;	/* original character or 0 */
361 } Brick;
362 
363 typedef struct {
364   int x,y;	/* position */
365   int type;	/* destruction, hit, regeneration, growth */
366   int dest_type;/* shot, normal, energy, explosion */
367   /* if brick will grow: */
368   int brick_id; /* brick id */
369   /* if brick was destroyed: */
370   int paddle; 	/* 0 bottom, 1 top */
371   int gold_shower;/* goldshower extra released? */
372   int draw_explosion;  /* draw an explosion on destruction */
373   int no_sound; /* play no sound on destruction */
374   int degrees; 	/* 0 to 180. *2 degree of normal animation movement */
375 } BrickHit;
376 
377 typedef struct {
378 	float       x, y;
379 	float       alpha;
380 	int         type;
381 	int         offset; 	/* offset in extra pic */
382 	int         dir; 	/* extra will move to this direction: 1 or -1 */
383 	SDL_Rect    update_rect; /* screen update region */
384 } Extra;
385 
386 typedef struct {
387     int type;
388     int px, py;
389     int dir;
390 } Stack_Extra; /* pushed extra in bricks.c which is popped in extra.c */
391 
392 typedef struct {
393 	int     lives, max_lives;
394 	int	paddle_min_size; /* minimum middle size */
395 	int     paddle_size; /* paddle's starting size */
396 	int     paddle_max_size; /* max size */
397 	int     score_mod; /* 10: 100% �1: �10% */
398 	float   v_start;
399 	float 	v_add; /* change per speedup level */
400 	float	v_max; /* velocity for this difficulty */
401 	int	v_delay; /* delay between speedups */
402 	int	allow_maluses; /* boolean */
403 	int	time_mod; /* multiplier for bonus/regeneration time */
404 } GameDiff;
405 
406 typedef struct {
407 	int 		collected_extras[2][MAX_MODS];
408 	int 		collected_extra_count[2];
409 	BrickHit 	brick_hits[MAX_MODS];
410 	int 		brick_hit_count;
411 	int 		fired_shot_count;
412 	int		attached_ball_count;
413 	int		paddle_reflected_ball_count;
414 	int		brick_reflected_ball_count;
415 } GameMod;
416 
417 typedef struct {
418 	int id;      /* brick id */
419 	int x, y;    /* position */
420 	Delay delay; /* move delay */
421 } Invader;
422 
423 typedef struct {
424 	int		game_type;
425         GameDiff	*diff; /* difficulty level */
426 	int		rel_warp_limit;
427 
428 	/* level data */
429 	int		level_type;
430 	char		author[32], title[32];
431 	Brick 		bricks[MAP_WIDTH][MAP_HEIGHT];
432 	int		brick_count; /* is not changed as it is needed for stats */
433 	int		bricks_left; /* is decreased. when 0 game is over */
434 	int		warp_limit; /* if bricks_left <= warp_limit, warp is allowed */
435 	int		extra_count; /* initial number of extras */
436 	int		extra_active[EX_NUMBER]; /* wether extra is active */
437 	int 		extra_time[EX_NUMBER]; /* time in milliseconds when extra expires */
438 	double		ball_v, ball_v_min, ball_v_max; /* ball velocity */
439 	Delay		speedup_delay;
440 	int		speedup_level; /* number of speedups */
441 	int		paddle_is_convex;
442 	int		balls_return_by_click;
443 	int		balls_use_random_angle;
444         float           accelerated_ball_speed;
445 	int		frag_limit; /* number of points a player must gain to win a
446 				       pingpong level */
447 	int		level_over; /* wether level is finished */
448 	int		winner;    /* 0 - BOTTOM won
449 				       1 - TOP won
450 				       -1 - draw */
451 
452 	/* game objects */
453 	Paddle		*paddles[2];
454 	int		paddle_count;
455 	List		*balls;
456 	List		*extras;
457 	List		*shots;
458 	List		*heal_bricks, *exp_bricks;
459 
460 	/* code red modifications from update() */
461 	GameMod		mod;
462 
463   /* bonus level information */
464   int isBonusLevel;         /* whether we are in a bonus level */
465   int blRefreshBricks;      /* copy all bricks from local to client since brick positions have
466                                changed and redraw; keep anything else */
467   int localServerGame;      /* this is the local_game context, actually handling the game */
468   int totalBonusLevelScore; /* bonus levels are all about gaining extra score so we count it */
469   int blNumCompletedRuns;   /* number of successful runs (how often score was added) */
470   double blRatioSum;        /* some of all ratios; devided by blNumCompletedRuns we get an average */
471   int blActionTime;         /* e.g.,brick dies/grows after that time */
472   Delay blDelay;            /* e.g., new brick after this times out or barrier moves down */
473   int blMaxScore;           /* maximum score for current run */
474   int bl_jj_mx, bl_jj_my;   /* position of current jumping jack */
475   int blCancerCount;        /* number of bricks grown so far, must not exceed bl_cancer_limit */
476   int blCancerLimit;        /* game over if this many bricks sprung into existence */
477   int blBarrierLevel;       /* size of barrier */
478   int blBarrierMoves;       /* how often barrier has moved in this run */
479   int blBarrierMaxMoves;    /* max number of possible moves before game over */
480   int blTotalNumDucks;      /* total number of ducks */
481   int blNumDucks;           /* number of active ducks */
482   int *blDuckPositions;     /* position of ducks */
483   int blBallAttached;       /* ball waits at ceiling */
484   int blCurrentDuck;        /* id in duck positions [id*2,id*2+1] */
485   int blDuckBaseScore;      /* maxScore is reset to this if miss */
486   int blHunterAreaX1;
487   int blHunterAreaY1;       /* left upper corner of playingfield frame */
488   int blHunterAreaX2;
489   int blHunterAreaY2;       /* right lower corner of playingfield frame */
490   int blHunterUpId;
491   int blHunterDownId;
492   int blHunterRightId;
493   int blHunterLeftId;       /* ids of brick types for control */
494   int blHunterId;
495   int blHunterPreyId;
496   int blHunterX,blHunterY;  /* position of hunter */
497   int blHunterPreyX;
498   int blHunterPreyY;        /* position of pray */
499   int blHunterTimeLeft;
500   int blInvaderLimit;       /* max number of invaders */
501   int blNumInvaders;        /* current number of invaders */
502   int blNumKilledInvaders;  /* already destroyed in this wave */
503   int blTotalNumKilledInvaders;  /* already destroyed total */
504   int blInvadersWaveOver;
505   int blInvaderTime;        /* within a wave invaders will speed up too */
506   int blInvaderScore;       /* score per invader kill */
507   Invader *blInvaders;      /* current positions */
508 } Game;
509 
510 #define SETBIT( data, bit ) data |= (1L << bit )
511 #define GETBIT( data, bit ) ((data >> bit) & 1)
512 
513 #endif
514