/***************************************************************************
gamedefs.h - description
-------------------
begin : Thu Sep 6 2001
copyright : (C) 2001 by Michael Speck
email : kulkanie@gmx.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef __GAMEDEFS_H
#define __GAMEDEFS_H
enum {
/* game/level types */
GT_LOCAL = 0,
GT_NETWORK,
LT_NORMAL = 0,
LT_PINGPONG,
/* playing field */
MAP_WIDTH = 16,
MAP_HEIGHT = 24,
EDIT_WIDTH = 14,
EDIT_HEIGHT = 18,
/* extras */
EX_NONE = -1,
EX_SCORE200 = 0,
EX_SCORE500,
EX_SCORE1000,
EX_SCORE2000,
EX_SCORE5000,
EX_SCORE10000,
EX_GOLDSHOWER,
EX_SHORTEN,
EX_LENGTHEN,
EX_LIFE,
EX_SLIME,
EX_METAL,
EX_BALL,
EX_WALL,
EX_FROZEN,
EX_WEAPON,
EX_RANDOM,
EX_FAST,
EX_SLOW,
EX_JOKER,
EX_DARKNESS,
EX_CHAOS,
EX_GHOST_PADDLE,
EX_DISABLE,
EX_TIME_ADD,
EX_EXPL_BALL,
EX_BONUS_MAGNET,
EX_MALUS_MAGNET,
EX_WEAK_BALL,
EX_NUMBER,
TIME_WALL = 10000,
TIME_METAL = 5000,
TIME_WEAPON = 5000,
TIME_FROZEN = 1000,
TIME_SLIME = 20000,
TIME_FAST = 20000,
TIME_SLOW = 20000,
TIME_GOLDSHOWER = 20000,
TIME_DARKNESS = 20000,
TIME_CHAOS = 10000,
TIME_GHOST_PADDLE = 20000,
TIME_EXPL_BALL = 10000,
TIME_BONUS_MAGNET = 20000,
TIME_MALUS_MAGNET = 20000,
TIME_WEAK_BALL = 10000,
/* unused */
TIME_SPIN_RIGHT = 20000,
TIME_SPIN_LEFT = 20000,
/* paddle */
PADDLE_INVIS_DELAY = 200,
WEAPON_FIRE_RATE = 150,
BALL_FIRE_RATE = 500,
BALL_RESPAWN_TIME = 5000, /* in normal multiplayer levelsets a user may bring
a new ball to game after this time penalty */
ATTRACT_NONE = 0,
ATTRACT_BONUS,
ATTRACT_MALUS,
PADDLE_BOTTOM = 0,
PADDLE_TOP,
PADDLE_WEAPON_AMMO = 100,
/* bricks */
INVIS_BRICK_ID = 6, /* id of invisible brick */
BRICK_EXP_TIME = 150, /* delay until explosion */
BRICK_COUNT = 26, /* various brick types */
BRICK_COUNT_REGULAR = 20, /* number of available bricks for edit */
BRICK_GROW_FIRST = 12, /* only bricks within this range may grow randomly */
BRICK_GROW_LAST = 17,
GROW_BRICK_ID = 19,
BRICK_HEAL_TIME = 4000, /* after this time duration is increased */
EXTRA_STACK_LIMIT = 20,
MAP_EMPTY = 0, /* no brick */
MAP_WALL, /* can't be destroyed at all */
MAP_BRICK, /* may be destroyed if duration is not -1 */
MAP_BRICK_EXP, /* explodes neighbors if destroyed */
MAP_BRICK_GROW, /* grow neighbors if destroyed */
MAP_BRICK_HEAL, /* heals itself when hit */
MAP_BRICK_CHAOS, /* chaotic reflection by this brick */
BRICK_WIDTH = 40,
BRICK_HEIGHT = 20,
BRICK_SCORE = 100,
/* hit types */
HT_HIT = 0, /* decrease duration */
HT_HEAL, /* negative hit: regeneration */
HT_REMOVE, /* remove brick completely */
HT_GROW, /* create brick with random color */
HT_REMOVE_NO_SOUND, /* is mapped to HT_REMOVE and no_sound=1 */
/* balls */
BALL_NORMAL = 0,
BALL_METAL,
BALL_EXPL,
BALL_WEAK,
BALLS_IDLE_LIMIT=10000,
BALL_NO_ENTROPY = 0,
BALL_ADD_ENTROPY,
/* particles */
SHR_BY_NORMAL_BALL = 0,
SHR_BY_ENERGY_BALL,
SHR_BY_SHOT,
SHR_BY_EXPL,
SHR_BY_EXPL_WITH_EXPL, /* shrapnells as from explosion and draw an explosion */
SHR_BY_DELAYED_EXPL, /* no explosion animation except for a expl brick */
/* modifications, beyond this count they are dropped */
MAX_MODS = 256,
/* difficulty */
DIFF_COUNT = 4,
/* players */
MAX_PLAYERS = 4,
/* credits */
HIDE_CREDIT = 0,
SHOW_CREDIT,
/* levels */
MAX_LEVELS = 40,
/* bonus level types (start at 2) */
LT_JUMPING_JACK = 2,
LT_OUTBREAK,
LT_BARRIER,
LT_SITTING_DUCKS,
LT_HUNTER,
LT_DEFENDER,
LT_LAST
};
/* small helper to identify grown bricks by char */
#define IS_GROWN_BRICK_CHAR(ch) ((ch) >= 'F' && (ch) <= 'K')
typedef struct Level {
char author[32], name[32];
/* extras and bricks are saved by their specific character and
interpreted by bricks_create later */
char bricks[EDIT_WIDTH][EDIT_HEIGHT];
char extras[EDIT_WIDTH][EDIT_HEIGHT];
int normal_brick_count;
int type; /* normal or type of bonus level */
} Level;
typedef struct {
char name[20];
int count;
int version, update;
int cur_level; /* id of current level */
Level **levels;
} LevelSet;
typedef struct {
float x, y;
} Vector;
typedef Vector Coord;
typedef struct {
int exists; /* is there a target */
int mx, my; /* position in map */
float x, y; /* reset position of ball */
int time; /* time till contact */
int cur_tm; /* current time */
Vector perp_vector; /* reflection vector */
int side; /* side/corner of brick hit */
} Target;
typedef struct {
int total_score; /* or frags */
int balls_reflected;
int balls_lost;
int bricks_cleared;
int total_brick_count;
int extras_collected;
int total_extra_count;
int wins, losses, draws;
int played_rounds;
} GameStats;
typedef struct {
char name[32]; /* name */
int lives; /* lives remaining (single player) */
GameStats stats; /* total score and stuff */
int paddle_id; /* index of paddle in game::paddles */
int level_id; /* index in levelset the player is currently in.
to initiate a level the snapshot is used
as the player modifies the level data which
must be saved for alternating games */
Level snapshot; /* if player switches in alternating game a
snapshot is kept of the players progress
in this level. when it is its turn again
it starts with this leveldata */
int next_level_received;
int next_paddle_id; /* whether level has been received */
} Player;
/* if this is not defined paddle has no velocity balls are reflected by convex surface */
#define PADDLE_FRICTION
typedef struct {
int score; /* score/frags gained by this paddle */
int type; /* either top or bottom */
float cur_x;
int x, y;
int w, h; /* actual geometry */
#ifdef PADDLE_FRICTION
float v_x;
#endif
int wanted_w; /* resize until w == wanted_w */
int len; /* how many middle components ? */
int start_len;
int min_len, max_len; /* limits */
float friction; /* how much relative speed is given to balls ? */
int friction_delay; /* its hard to exactly hit the moment when the ball touches the paddle
so while this is >0 friction is applied */
int frozen; /* paddle frozen? */
int slime; /* paddle covered with sticky slime */
int attract; /* true if paddle attracts balls */
Delay resize_delay; /* every delay ms the paddle size is adjusted about two pixels */
int invis; /* is paddle invisible? */
int invis_delay; /* as long as this isn't timed out the paddle is seen.
will be reset by movement */
/* FIRE STATE - updated by paddle_handle_events() & comm_update_remote_paddle() */
int fire_left;
int fire_right; /* wether player presses fire buttons */
int ball_return_key_pressed; /* wether player wants to return idle balls */
/* WEAPON - handled by paddle_update() */
double weapon_cur;
int weapon_inst; /* is weapon installed? */
int weapon_fire_delay; /* if >0 and either fire_left or fire_right is True checked
against milliseconds wether it drops <=0 in which
case it is reset to WEAPON_FIRE_RATE and a shot is fired */
int weapon_ammo; /* number of shots available */
/* BALLS - handled by balls_update() !!! */
int ball_fire_delay; /* analogue to weapon_fire_delay */
int ball_ammo; /* number of balls player may bring to game */
int start_ball_ammo; /* initial ammount as ball ammo is modified while playing */
int last_ball_contact; /* in NormMP player may fire a new ball when this
time is longer ago than BALL_RESPAWN_TIME and no
balls are attached. Then a new ball is created and
attached to paddle. */
int attached_ball_count; /* number of attached balls */
int ball_ammo_disp_y; /* icons are drawn centered at y */
int maxballspeed_request;
int maxballspeed_request_old; /* when middle mouse button is pressed the balls
are accelerated to max speed if old state was
zero and vice versa to slow down again */
/* EXTRAS */
int extra_active[EX_NUMBER];
int extra_time[EX_NUMBER]; /* paddle specific extras */
int wall_y; /* position where wall is drawn */
double wall_alpha;
/* STATISTICS */
int balls_reflected; /* how many times successfully reflected a ball */
int balls_lost; /* how many balls lost? */
int extras_collected; /* number of collected extras. the total number is
extra_count in struct game */
int bricks_cleared; /* again the total number is brick_count in game */
/* used by client */
Player *player;
int pic_x_offset;
int pic_y_offset;
SDL_Rect update_rect; /* screen update region */
/* used for dummy paddles */
float bot_vx; /* paddle velocity in pix/msec */
} Paddle;
typedef struct {
Coord cur; /* current position */
int x, y;
Vector vel; /* velocity components */
int angle; /* angle 0-180 of vector */
int attached; /* attached to paddle ? */
Paddle *paddle; /* last paddle the ball had contact with */
int moving_back; /* ball moves back to paddle as there was no
brick/paddle contact within the last
20 secs */
int idle_time; /* time passed since last brick/paddle contact */
int return_allowed; /* if this is set returning by click is allowed */
Target target; /* target in map */
int get_target; /* if this is true balls_update() will compute the target
and clear this flag */
} Ball;
typedef struct {
float x, y;
Target target;
int next_too; /* destroys right brick, too */
Paddle *paddle; /* paddle that initiated the shot */
int dir; /* direction of shot depending on paddle */
int get_target; /* if this is true shots_update() will compute the target
and clear this flag */
/* used by client */
float cur_fr;
SDL_Rect update_rect; /* screen update region */
} Shot;
typedef struct {
int type; /* any of the old MAP_XXX types above */
int id; /* picture id -- if -1 no brick -- if 0 it's indestructible */
int dur; /* durability - if -1 & type != MAP_WALL it's only destructible
by energy ball */
int extra; /* extra released when destroyed */
int score; /* score you get when desctroying this brick */
int exp_time; /* -1 means inexplosive; value is set by a nearby explosion brick */
Paddle *exp_paddle; /* paddle that initiated the explosion */
int heal_time; /* if not -1 counted down and when 0 brick heals one duration
(until fully healed) */
int mx, my; /* position of brick in map */
char brick_c; /* original character when saved to file */
char extra_c; /* original character or 0 */
} Brick;
typedef struct {
int x,y; /* position */
int type; /* destruction, hit, regeneration, growth */
int dest_type;/* shot, normal, energy, explosion */
/* if brick will grow: */
int brick_id; /* brick id */
/* if brick was destroyed: */
int paddle; /* 0 bottom, 1 top */
int gold_shower;/* goldshower extra released? */
int draw_explosion; /* draw an explosion on destruction */
int no_sound; /* play no sound on destruction */
int degrees; /* 0 to 180. *2 degree of normal animation movement */
} BrickHit;
typedef struct {
float x, y;
float alpha;
int type;
int offset; /* offset in extra pic */
int dir; /* extra will move to this direction: 1 or -1 */
SDL_Rect update_rect; /* screen update region */
} Extra;
typedef struct {
int type;
int px, py;
int dir;
} Stack_Extra; /* pushed extra in bricks.c which is popped in extra.c */
typedef struct {
int lives, max_lives;
int paddle_min_size; /* minimum middle size */
int paddle_size; /* paddle's starting size */
int paddle_max_size; /* max size */
int score_mod; /* 10: 100% ±1: ±10% */
float v_start;
float v_add; /* change per speedup level */
float v_max; /* velocity for this difficulty */
int v_delay; /* delay between speedups */
int allow_maluses; /* boolean */
int time_mod; /* multiplier for bonus/regeneration time */
} GameDiff;
typedef struct {
int collected_extras[2][MAX_MODS];
int collected_extra_count[2];
BrickHit brick_hits[MAX_MODS];
int brick_hit_count;
int fired_shot_count;
int attached_ball_count;
int paddle_reflected_ball_count;
int brick_reflected_ball_count;
} GameMod;
typedef struct {
int id; /* brick id */
int x, y; /* position */
Delay delay; /* move delay */
} Invader;
typedef struct {
int game_type;
GameDiff *diff; /* difficulty level */
int rel_warp_limit;
/* level data */
int level_type;
char author[32], title[32];
Brick bricks[MAP_WIDTH][MAP_HEIGHT];
int brick_count; /* is not changed as it is needed for stats */
int bricks_left; /* is decreased. when 0 game is over */
int warp_limit; /* if bricks_left <= warp_limit, warp is allowed */
int extra_count; /* initial number of extras */
int extra_active[EX_NUMBER]; /* wether extra is active */
int extra_time[EX_NUMBER]; /* time in milliseconds when extra expires */
double ball_v, ball_v_min, ball_v_max; /* ball velocity */
Delay speedup_delay;
int speedup_level; /* number of speedups */
int paddle_is_convex;
int balls_return_by_click;
int balls_use_random_angle;
float accelerated_ball_speed;
int frag_limit; /* number of points a player must gain to win a
pingpong level */
int level_over; /* wether level is finished */
int winner; /* 0 - BOTTOM won
1 - TOP won
-1 - draw */
/* game objects */
Paddle *paddles[2];
int paddle_count;
List *balls;
List *extras;
List *shots;
List *heal_bricks, *exp_bricks;
/* code red modifications from update() */
GameMod mod;
/* bonus level information */
int isBonusLevel; /* whether we are in a bonus level */
int blRefreshBricks; /* copy all bricks from local to client since brick positions have
changed and redraw; keep anything else */
int localServerGame; /* this is the local_game context, actually handling the game */
int totalBonusLevelScore; /* bonus levels are all about gaining extra score so we count it */
int blNumCompletedRuns; /* number of successful runs (how often score was added) */
double blRatioSum; /* some of all ratios; devided by blNumCompletedRuns we get an average */
int blActionTime; /* e.g.,brick dies/grows after that time */
Delay blDelay; /* e.g., new brick after this times out or barrier moves down */
int blMaxScore; /* maximum score for current run */
int bl_jj_mx, bl_jj_my; /* position of current jumping jack */
int blCancerCount; /* number of bricks grown so far, must not exceed bl_cancer_limit */
int blCancerLimit; /* game over if this many bricks sprung into existence */
int blBarrierLevel; /* size of barrier */
int blBarrierMoves; /* how often barrier has moved in this run */
int blBarrierMaxMoves; /* max number of possible moves before game over */
int blTotalNumDucks; /* total number of ducks */
int blNumDucks; /* number of active ducks */
int *blDuckPositions; /* position of ducks */
int blBallAttached; /* ball waits at ceiling */
int blCurrentDuck; /* id in duck positions [id*2,id*2+1] */
int blDuckBaseScore; /* maxScore is reset to this if miss */
int blHunterAreaX1;
int blHunterAreaY1; /* left upper corner of playingfield frame */
int blHunterAreaX2;
int blHunterAreaY2; /* right lower corner of playingfield frame */
int blHunterUpId;
int blHunterDownId;
int blHunterRightId;
int blHunterLeftId; /* ids of brick types for control */
int blHunterId;
int blHunterPreyId;
int blHunterX,blHunterY; /* position of hunter */
int blHunterPreyX;
int blHunterPreyY; /* position of pray */
int blHunterTimeLeft;
int blInvaderLimit; /* max number of invaders */
int blNumInvaders; /* current number of invaders */
int blNumKilledInvaders; /* already destroyed in this wave */
int blTotalNumKilledInvaders; /* already destroyed total */
int blInvadersWaveOver;
int blInvaderTime; /* within a wave invaders will speed up too */
int blInvaderScore; /* score per invader kill */
Invader *blInvaders; /* current positions */
} Game;
#define SETBIT( data, bit ) data |= (1L << bit )
#define GETBIT( data, bit ) ((data >> bit) & 1)
#endif