From 1d0dd12b2e33fafd21a206058ac736feb7f13977 Mon Sep 17 00:00:00 2001 From: gmueller Date: Tue, 18 Jan 2011 21:52:05 +0100 Subject: [PATCH] move game to c++ --- src/client/Client.cpp | 6 +- src/client/Client.h | 1 - src/common/Application.cpp | 8 +- src/common/Application.h | 6 +- src/common/CMakeLists.txt | 2 +- src/common/Game.cpp | 386 ++++++++++++++++++++++++++++++++++++ src/common/Game.h | 81 ++++++++ src/common/Network.cpp | 22 +-- src/common/Network.h | 6 +- src/common/game.cpp | 387 ------------------------------------- src/common/game.h | 76 -------- 11 files changed, 492 insertions(+), 489 deletions(-) create mode 100644 src/common/Game.cpp create mode 100644 src/common/Game.h delete mode 100644 src/common/game.cpp delete mode 100644 src/common/game.h diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 2f2961e..7ed7395 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -364,7 +364,7 @@ void Client::initialize(Arguments &arg) { exit(EXIT_FAILURE); } - game_setup_explosion_callback(&game, explosion_callback, 0); + game.setup_explosion_callback(explosion_callback, 0); setup_opengl(); setup_explosion(); quadratic = gluNewQuadric(); @@ -372,8 +372,8 @@ void Client::initialize(Arguments &arg) { gluQuadricTexture(quadratic, GL_TRUE); if (isMaster()) { - team_t *team = game_team(&game, 0); - game.local_player = game_spawn_player(&game, team); + team_t *team = game.getTeam(0); + game.local_player = game.spawn_player(team); } size_t i; diff --git a/src/client/Client.h b/src/client/Client.h index bab01b5..a438efb 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -11,7 +11,6 @@ #include "Application.h" #include "Schedule.h" #include "oglfont.h" -#include "game.h" class Client: public Application { public: diff --git a/src/common/Application.cpp b/src/common/Application.cpp index ea06466..3ff5e6d 100644 --- a/src/common/Application.cpp +++ b/src/common/Application.cpp @@ -42,8 +42,8 @@ void Application::initialize(Arguments &arg) { time = PerformanceTimer::get(); // setup game - game_setup(&game); - game_reset(&game); + game.setup(); + game.reset(); // setup schedules gameUpdateSchudule.setExact(true); @@ -77,7 +77,7 @@ void Application::update() { // network stuff network.service(master ? 1 : 0); - game_update(&game, dt); + game.update(dt); if (master && gameUpdateSchudule.next(time)) { network.sendGameUpdates(); } @@ -87,5 +87,5 @@ void Application::setMaster(bool master) { std::cout << "[Application] setMaster = " << master << std::endl; this->master = master; - game_set_master(&game, master ? 1 : 0); + game.set_master(master ? 1 : 0); } diff --git a/src/common/Application.h b/src/common/Application.h index 75b77e5..a2b5dde 100644 --- a/src/common/Application.h +++ b/src/common/Application.h @@ -8,7 +8,7 @@ #ifndef APPLICATION_H_ #define APPLICATION_H_ -#include "game.h" +#include "Game.h" #include "Schedule.h" #include "Arguments.h" @@ -31,7 +31,7 @@ public: } void setMaster(bool master); - inline game_t *getGame() { + inline Game *getGame() { return &game; } @@ -42,7 +42,7 @@ private: bool master; protected: - game_t game; + Game game; Network network; double dt; double time; diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 4dabd07..d922ee0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -3,7 +3,7 @@ include_directories (${GREMLIN_SOURCE_DIR}/src) add_library( common Application - game + Game Time Network ) diff --git a/src/common/Game.cpp b/src/common/Game.cpp new file mode 100644 index 0000000..cf95293 --- /dev/null +++ b/src/common/Game.cpp @@ -0,0 +1,386 @@ +#include "Game.h" + +#include +#include +#include + +double rand2() { + float u = (float) rand() / (float) RAND_MAX; + return 2.0 * (u - 0.5); +} + +void reset_team(team_t *team) { + team->points = 0; +} + +void reset_player(player_t *player) { + if (player->team) { + player->x = player->team->x + 100; + player->y = player->team->y; + player->z = player->team->z; + } else { + player->x = 0; + player->y = 0; + player->z = 0; + } + player->vx = 0.; + player->vy = 0.; + player->vz = 0.; +} + +void reset_point(point_t *point) { + point->status = 1; + point->x = 1000 + 500.0 * rand2(); + point->y = 500.0 * rand2(); + point->z = 500.0 * rand2(); +} + +void setup_team(team_t *team, uint8_t id) { + team->id = id; + team->color[0] = .5f + .5f * (id & (1 << 0)); + team->color[1] = .5f + .5f * (id & (1 << 1)); + team->color[2] = .5f + .5f * (id & (1 << 2)); + team->color[3] = 1.0f; + + team->x = 2000.0 * (id & (1 << 0)); + team->y = 2000.0 * (id & (1 << 1)); + team->z = 2000.0 * (id & (1 << 2)); + + team->points = 0; + team->wins = 0; +} + +void setup_player(player_t *player) { + player->id = 0; + player->status = 0; + player->team = NULL; + player->x = 0.0; + player->y = 0.0; + player->z = 0.0; + player->vx = 0.0; + player->vy = 0.0; + player->vz = 0.0; +} + +void setup_point(point_t *point) { + point->status = 0; + point->x = 0.0; + point->y = 0.0; + point->z = 0.0; +} + +void setup_bomb(bomb_t *bomb) { + bomb->status = 0; + bomb->x = 0.0; + bomb->y = 0.0; + bomb->z = 0.0; +} + +void Game::setup() { + size_t i; + + for (i = 0; i < GAME_TEAM_COUNT; i++) + setup_team(&team[i], i); + + for (i = 0; i < GAME_BOMB_COUNT; i++) + setup_bomb(&bomb[i]); + + for (i = 0; i < GAME_PLAYER_COUNT; i++) + setup_player(&player[i]); + + for (i = 0; i < GAME_POINT_COUNT; i++) + setup_point(&point[i]); + + max_player_id = 0; + master = 0; + updateTime = 0.0; + explosion_callback = 0; + local_player = 0; +} + +void Game::reset() { + size_t i; + + for (i = 0; i < GAME_TEAM_COUNT; i++) + reset_team(&team[i]); + + for (i = 0; i < GAME_BOMB_COUNT; i++) + setup_bomb(&bomb[i]); + + for (i = 0; i < GAME_PLAYER_COUNT; i++) + reset_player(&player[i]); + + for (i = 0; i < GAME_POINT_COUNT; i++) + reset_point(&point[i]); +} + +player_t *Game::getFreePlayer() { + size_t i; + for (i = 0; i < GAME_PLAYER_COUNT; i++) { + if (player[i].status == 0) + return &player[i]; + } + return NULL; +} + +player_t *Game::spawn_player(team_t *team) { + player_t *player = getFreePlayer(); + player->team = team; + player->status = 1; + player->id = max_player_id++; + reset_player(player); + return player; +} + +player_t *Game::spawn_player_id(team_t *team, uint16_t id) { + player_t *player = getFreePlayer(); + player->team = team; + player->id = id; + if (max_player_id < id) + max_player_id = id; + player->status = 1; + player->x = team->x + 100; + player->y = team->y; + player->z = team->z; + player->vx = 0.; + player->vy = 0.; + player->vz = 0.; + return player; +} + +void Game::update_players(double dt) { + size_t i; + for (i = 0; i < GAME_PLAYER_COUNT; i++) { + player_t *p = &player[i]; + if (p->status == 0) + return; + if (p->vx > 1000.0) + p->vx = 1000.0; + if (p->vy > 1000.0) + p->vy = 1000.0; + if (p->vz > 1000.0) + p->vz = 1000.0; + p->x += p->vx * dt; + p->y += p->vy * dt; + p->z += p->vz * dt; + + double distance2 = pow(p->x - p->team->x, 2) + + pow(p->y - p->team->y, 2) + pow(p->z - p->team->z, 2); + if (distance2 < 10000) { + p->team->points += p->points; + p->points = 0; + } + + if (p->x < (-1000 + 10)) { + p->x = (-1000 + 10); + p->vx *= -1; + } else if (p->x > (5000 - 10)) { + p->x = (5000 - 10); + p->vx *= -1; + } + + if (p->y < (-3000 + 10)) { + p->y = (-3000 + 10); + p->vy *= -1; + } else if (p->y > (3000 - 10)) { + p->y = (3000 - 10); + p->vy *= -1; + } + + if (p->z < (-3000 + 10)) { + p->z = (-3000 + 10); + p->vz *= -1; + } else if (p->z > (3000 - 10)) { + p->z = (3000 - 10); + p->vz *= -1; + } + } +} + +void Game::explode_bomb(bomb_t *bomb) { + size_t i, j; + for (i = 0; i < GAME_PLAYER_COUNT; i++) { + player_t *p = &player[i]; + if (p->status == 0) + continue; + double distance2 = pow(p->x - bomb->x, 2) + pow(p->y - bomb->y, 2) + + pow(p->z - bomb->z, 2); + if (distance2 < pow(150., 2.)) { + if (explosion_callback) + explosion_callback(p->x, p->y, p->z, explosion_callback_data); + p->x = p->team->x + 100; + p->y = p->team->y; + p->z = p->team->z; + p->vx = 0.; + p->vy = 0.; + p->vz = 0.; + for (j = 0; j < p->points; j++) { + point_t *point = spawn_point(); + point->x = p->x + 20.0 * rand2(); + point->y = p->x + 20.0 * rand2(); + point->z = p->x + 20.0 * rand2(); + } + p->points = 0; + } + } +} + +void Game::update_bombs(double dt) { + size_t i; + for (i = 0; i < GAME_BOMB_COUNT; i++) { + bomb_t *b = &bomb[i]; + if (b->status == 0) + continue; + b->x += b->vx * dt; + b->y += b->vy * dt; + b->z += b->vz * dt; + b->ttl -= dt; + + if (b->x < (-1000 + 10)) { + b->x = (-1000 + 10); + b->ttl = -0.1; + } else if (b->x > (5000 - 10)) { + b->x = (5000 - 10); + b->ttl = -0.1; + } else if (b->y < (-3000 + 10)) { + b->y = (-3000 + 10); + b->ttl = -0.1; + } else if (b->y > (3000 - 10)) { + b->y = (3000 - 10); + b->ttl = -0.1; + } else if (b->z < (-3000 + 10)) { + b->z = (-3000 + 10); + b->ttl = -0.1; + } else if (b->z > (3000 - 10)) { + b->z = (3000 - 10); + b->ttl = -0.1; + } + + if (b->ttl < 0) { + if (b->status == 1) { + if (explosion_callback) + explosion_callback(b->x, b->y, b->z, + explosion_callback_data); + b->status = 2; + } else if (b->ttl < -0.2) { + if (master) { + explode_bomb(b); + } + b->status = 0; + } + } + } +} + +void Game::update_point(point_t *point) { + size_t i; + for (i = 0; i < GAME_PLAYER_COUNT; i++) { + player_t *P = &player[i]; + if (P->status == 0) + continue; + double distance2 = pow(P->x - point->x, 2) + pow(P->y - point->y, 2) + + pow(P->z - point->z, 2); + if (distance2 > 1000.0) + continue; + point->status = 0; + P->points += 1; + } + +} + +void Game::update_points(double dt) { + size_t i; + for (i = 0; i < GAME_POINT_COUNT; i++) { + point_t *p = &point[i]; + if (p->status == 0) + continue; + update_point(p); + } +} + +void Game::update(double dt) { + const double delta = 1. / 120.; + updateTime += dt; + while (updateTime > delta) { + Game::update_players(delta); + Game::update_bombs(delta); + Game::update_points(delta); + updateTime -= delta; + } +} + +size_t Game::active_team_players(team_t *team) { + size_t i, count = 0; + for (i = 0; i < GAME_PLAYER_COUNT; i++) { + if (player[i].status == 0) + continue; + if (player[i].team == team) + count++; + } + return count; +} + +team_t *Game::team_with_least_players() { + size_t i, count = -1; + team_t *t = NULL; + for (i = 0; i < GAME_TEAM_COUNT; i++) { + size_t players = active_team_players(&team[i]); + if (players < count) { + count = players; + t = &team[i]; + } + } + return t; +} + +team_t *Game::getTeam(uint16_t id) { + size_t i; + for (i = 0; i < GAME_TEAM_COUNT; i++) { + if (team[i].id == id) { + return &team[i]; + } + } + return NULL; +} + +player_t *Game::getPlayer(uint16_t id) { + size_t i; + for (i = 0; i < GAME_PLAYER_COUNT; i++) { + if (player[i].id == id) { + return &player[i]; + } + } + return NULL; +} + +bomb_t *Game::spawn_bomb() { + size_t i; + for (i = 0; i < GAME_BOMB_COUNT; i++) { + if (bomb[i].status == 0) { + bomb[i].status = 1; + return &bomb[i]; + } + } + return NULL; +} + +point_t *Game::spawn_point() { + size_t i; + for (i = 0; i < GAME_POINT_COUNT; i++) { + if (point[i].status == 0) { + point[i].status = 1; + return &point[i]; + } + } + return NULL; +} + +void Game::setup_explosion_callback(void(*explosion_callback)(double x, + double y, double z, void *data), void *data) { + this->explosion_callback = explosion_callback; + explosion_callback_data = data; +} + +void Game::set_master(int master) { + this->master = master; +} diff --git a/src/common/Game.h b/src/common/Game.h new file mode 100644 index 0000000..d0f1d4c --- /dev/null +++ b/src/common/Game.h @@ -0,0 +1,81 @@ +#ifndef GREMLIN_GAME_H +#define GREMLIN_GAME_H + +#include "common.h" + +typedef struct team_t team_t; +typedef struct player_t player_t; +class Game; + +#define GAME_TEAM_COUNT 2 +#define GAME_PLAYER_COUNT 64 +#define GAME_BOMB_COUNT (GAME_PLAYER_COUNT * 5) +#define GAME_POINT_COUNT 50 + +struct player_t { + uint16_t id; + uint16_t status; + double x, y, z; + double rx, ry, rz, rw; + double vx, vy, vz; + team_t *team; + uint16_t points; +}; + +struct bomb_t { + uint8_t status; + double x, y, z; + double vx, vy, vz; + double ttl; +}; + +struct point_t { + uint8_t status; + double x, y, z; +}; + +struct team_t { + uint16_t id; + double x, y, z; + float color[4]; + uint16_t points; + uint16_t wins; +}; + +class Game { +public: + team_t team[GAME_TEAM_COUNT]; + player_t player[GAME_PLAYER_COUNT]; + bomb_t bomb[GAME_BOMB_COUNT]; + point_t point[GAME_POINT_COUNT]; + int16_t max_player_id; + int master; + double updateTime; + player_t *local_player; + void(*explosion_callback)(double x, double y, double z, void *data); + void *explosion_callback_data; + + void setup(); + void reset(); + team_t *team_with_least_players(); + player_t *spawn_player(team_t *team); + player_t *spawn_player_id(team_t *team, uint16_t id); + team_t *getTeam(uint16_t id); + player_t *getPlayer(uint16_t id); + bomb_t *getBomb(uint16_t index); + void update_players(double dt); + bomb_t *spawn_bomb(); + point_t *spawn_point(); + void update_bombs(double dt); + void update_points(double dt); + void update(double dt); + void setup_explosion_callback(void(*explosion_callback)(double x, double y, + double z, void *data), void *data); + void set_master(int master); + player_t *getFreePlayer(); + void explode_bomb(bomb_t *bomb); + void update_point(point_t *point); + size_t active_team_players(team_t *team); +}; + +#endif diff --git a/src/common/Network.cpp b/src/common/Network.cpp index 0080f4a..1b25053 100644 --- a/src/common/Network.cpp +++ b/src/common/Network.cpp @@ -10,7 +10,7 @@ #include #include -Network::Network(game_t *game) : +Network::Network(Game *game) : game(game), client_peer(0) { } @@ -108,25 +108,25 @@ void Network::dispatch(enet_uint8 *data, size_t length) { switch (msg->msg_id) { case MESSAGE_PLAYER_SPAWN: { player_spawn_message_t *sm = (player_spawn_message_t *) data; - team_t *team = game_team(game, sm->team_id); - player_t *player = game_spawn_player_id(game, team, sm->player_id); + team_t *team = game->getTeam(sm->team_id); + player_t *player = game->spawn_player_id(team, sm->player_id); break; } case MESSAGE_PLAYER_KILL: { player_kill_message_t *sm = (player_kill_message_t *) data; - player_t *player = game_player(game, sm->player_id); + player_t *player = game->getPlayer(sm->player_id); player->status = 0; player->team = 0; break; } case MESSAGE_ACCEPT: { accept_message_t *am = (accept_message_t *) data; - game->local_player = game_player(game, am->player_id); + game->local_player = game->getPlayer(am->player_id); break; } case MESSAGE_PLAYER_UPDATE: { player_update_message_t *um = (player_update_message_t *) data; - player_t *player = game_player(game, um->player_id); + player_t *player = game->getPlayer(um->player_id); if (player != game->local_player) { player->x = um->x + um->vx * 0.0001; player->y = um->y + um->vy * 0.0001; @@ -168,7 +168,7 @@ void Network::dispatch(enet_uint8 *data, size_t length) { } case MESSAGE_PLAYER_ACCELERATE: { player_accelerate_message_t *um = (player_accelerate_message_t *) data; - player_t *player = game_player(game, um->player_id); + player_t *player = game->getPlayer(um->player_id); player->vx += um->x; player->vy += um->y; player->vz += um->z; @@ -176,7 +176,7 @@ void Network::dispatch(enet_uint8 *data, size_t length) { } case MESSAGE_BOMB_DROP: { bomb_drop_meesage_t *m = (bomb_drop_meesage_t *) data; - bomb_t *bomb = game_spawn_bomb(game); + bomb_t *bomb = game->spawn_bomb(); if (bomb == NULL) return; bomb->x = m->x + m->vx * 0.0001; @@ -195,7 +195,7 @@ void Network::dispatch(enet_uint8 *data, size_t length) { } case MESSAGE_TEAM_UPDATE: { team_update_message_t *m = (team_update_message_t *) data; - team_t *team = game_team(game, m->team_id); + team_t *team = game->getTeam(m->team_id); if (team == NULL) return; team->points = m->points; @@ -249,8 +249,8 @@ void Network::service(uint32_t timeout) { enet_peer_send(event.peer, 0, packet); } - team_t *team = game_team_with_least_players(game); - player_t *player = game_spawn_player(game, team); + team_t *team = game->team_with_least_players(); + player_t *player = game->spawn_player(team); event.peer->data = player; // send player spawn message diff --git a/src/common/Network.h b/src/common/Network.h index 06f40d0..2c7ce7c 100644 --- a/src/common/Network.h +++ b/src/common/Network.h @@ -8,7 +8,7 @@ #ifndef NETWORK_H_ #define NETWORK_H_ -#include "game.h" +#include "Game.h" #include "common.h" #include @@ -91,7 +91,7 @@ struct team_update_message_t { class Network { public: - Network(game_t *game); + Network(Game* game); void initialize(const std::string &host); void shutdown(); void dispatch(uint8_t *data, size_t length); @@ -99,7 +99,7 @@ public: void sendGameUpdates(); void sendMessage(uint8_t *data, size_t length); protected: - game_t *game; + Game *game; ENetHost *host; ENetPeer *client_peer; }; diff --git a/src/common/game.cpp b/src/common/game.cpp deleted file mode 100644 index 9e5ef01..0000000 --- a/src/common/game.cpp +++ /dev/null @@ -1,387 +0,0 @@ -#include "game.h" - -#include -#include -#include - -double rand2() { - float u = (float) rand() / (float) RAND_MAX; - return 2.0 * (u - 0.5); -} - -void game_reset_team(team_t *team) { - team->points = 0; -} - -void game_reset_player(player_t *player) { - if (player->team) { - player->x = player->team->x + 100; - player->y = player->team->y; - player->z = player->team->z; - } else { - player->x = 0; - player->y = 0; - player->z = 0; - } - player->vx = 0.; - player->vy = 0.; - player->vz = 0.; -} - -void game_reset_point(point_t *point) { - point->status = 1; - point->x = 1000 + 500.0 * rand2(); - point->y = 500.0 * rand2(); - point->z = 500.0 * rand2(); -} - -void game_setup_team(team_t *team, uint8_t id) { - team->id = id; - team->color[0] = .5f + .5f * (id & (1 << 0)); - team->color[1] = .5f + .5f * (id & (1 << 1)); - team->color[2] = .5f + .5f * (id & (1 << 2)); - team->color[3] = 1.0f; - - team->x = 2000.0 * (id & (1 << 0)); - team->y = 2000.0 * (id & (1 << 1)); - team->z = 2000.0 * (id & (1 << 2)); - - team->points = 0; - team->wins = 0; -} - -void game_setup_player(player_t *player) { - player->id = 0; - player->status = 0; - player->team = NULL; - player->x = 0.0; - player->y = 0.0; - player->z = 0.0; - player->vx = 0.0; - player->vy = 0.0; - player->vz = 0.0; -} - -void game_setup_point(point_t *point) { - point->status = 0; - point->x = 0.0; - point->y = 0.0; - point->z = 0.0; -} - -void game_setup_bomb(bomb_t *bomb) { - bomb->status = 0; - bomb->x = 0.0; - bomb->y = 0.0; - bomb->z = 0.0; -} - -void game_setup(game_t *game) { - size_t i; - - for (i = 0; i < GAME_TEAM_COUNT; i++) - game_setup_team(&game->team[i], i); - - for (i = 0; i < GAME_BOMB_COUNT; i++) - game_setup_bomb(&game->bomb[i]); - - for (i = 0; i < GAME_PLAYER_COUNT; i++) - game_setup_player(&game->player[i]); - - for (i = 0; i < GAME_POINT_COUNT; i++) - game_setup_point(&game->point[i]); - - game->max_player_id = 0; - game->master = 0; - game->updateTime = 0.0; - game->explosion_callback = 0; - game->local_player = 0; -} - -void game_reset(game_t *game) { - size_t i; - - for (i = 0; i < GAME_TEAM_COUNT; i++) - game_reset_team(&game->team[i]); - - for (i = 0; i < GAME_BOMB_COUNT; i++) - game_setup_bomb(&game->bomb[i]); - - for (i = 0; i < GAME_PLAYER_COUNT; i++) - game_reset_player(&game->player[i]); - - for (i = 0; i < GAME_POINT_COUNT; i++) - game_reset_point(&game->point[i]); -} - -player_t *_game_free_player(game_t *game) { - size_t i; - for (i = 0; i < GAME_PLAYER_COUNT; i++) { - if (game->player[i].status == 0) - return &game->player[i]; - } - return NULL; -} - -player_t *game_spawn_player(game_t *game, team_t *team) { - player_t *player = _game_free_player(game); - player->team = team; - player->status = 1; - player->id = game->max_player_id++; - game_reset_player(player); - return player; -} - -player_t *game_spawn_player_id(game_t *game, team_t *team, uint16_t id) { - player_t *player = _game_free_player(game); - player->team = team; - player->id = id; - if (game->max_player_id < id) - game->max_player_id = id; - player->status = 1; - player->x = team->x + 100; - player->y = team->y; - player->z = team->z; - player->vx = 0.; - player->vy = 0.; - player->vz = 0.; - return player; -} - -void game_update_players(game_t *game, double dt) { - size_t i; - for (i = 0; i < GAME_PLAYER_COUNT; i++) { - player_t *player = &game->player[i]; - if (player->status == 0) - return; - if (player->vx > 1000.0) - player->vx = 1000.0; - if (player->vy > 1000.0) - player->vy = 1000.0; - if (player->vz > 1000.0) - player->vz = 1000.0; - player->x += player->vx * dt; - player->y += player->vy * dt; - player->z += player->vz * dt; - - double distance2 = pow(player->x - player->team->x, 2) + pow(player->y - - player->team->y, 2) + pow(player->z - player->team->z, 2); - if (distance2 < 10000) { - player->team->points += player->points; - player->points = 0; - } - - if (player->x < (-1000 + 10)) { - player->x = (-1000 + 10); - player->vx *= -1; - } else if (player->x > (5000 - 10)) { - player->x = (5000 - 10); - player->vx *= -1; - } - - if (player->y < (-3000 + 10)) { - player->y = (-3000 + 10); - player->vy *= -1; - } else if (player->y > (3000 - 10)) { - player->y = (3000 - 10); - player->vy *= -1; - } - - if (player->z < (-3000 + 10)) { - player->z = (-3000 + 10); - player->vz *= -1; - } else if (player->z > (3000 - 10)) { - player->z = (3000 - 10); - player->vz *= -1; - } - } -} - -void _explode_bomb(game_t *game, bomb_t *bomb) { - size_t i, j; - for (i = 0; i < GAME_PLAYER_COUNT; i++) { - player_t *player = &game->player[i]; - if (player->status == 0) - continue; - double distance2 = pow(player->x - bomb->x, 2) + pow(player->y - - bomb->y, 2) + pow(player->z - bomb->z, 2); - if (distance2 < pow(150., 2.)) { - if (game->explosion_callback) - game->explosion_callback(player->x, player->y, player->z, - game->explosion_callback_data); - player->x = player->team->x + 100; - player->y = player->team->y; - player->z = player->team->z; - player->vx = 0.; - player->vy = 0.; - player->vz = 0.; - for (j = 0; j < player->points; j++) { - point_t *point = game_spawn_point(game); - point->x = player->x + 20.0 * rand2(); - point->y = player->x + 20.0 * rand2(); - point->z = player->x + 20.0 * rand2(); - } - player->points = 0; - } - } -} - -void game_update_bombs(game_t *game, double dt) { - size_t i; - for (i = 0; i < GAME_BOMB_COUNT; i++) { - bomb_t *bomb = &game->bomb[i]; - if (bomb->status == 0) - continue; - bomb->x += bomb->vx * dt; - bomb->y += bomb->vy * dt; - bomb->z += bomb->vz * dt; - bomb->ttl -= dt; - - if (bomb->x < (-1000 + 10)) { - bomb->x = (-1000 + 10); - bomb->ttl = -0.1; - } else if (bomb->x > (5000 - 10)) { - bomb->x = (5000 - 10); - bomb->ttl = -0.1; - } else if (bomb->y < (-3000 + 10)) { - bomb->y = (-3000 + 10); - bomb->ttl = -0.1; - } else if (bomb->y > (3000 - 10)) { - bomb->y = (3000 - 10); - bomb->ttl = -0.1; - } else if (bomb->z < (-3000 + 10)) { - bomb->z = (-3000 + 10); - bomb->ttl = -0.1; - } else if (bomb->z > (3000 - 10)) { - bomb->z = (3000 - 10); - bomb->ttl = -0.1; - } - - if (bomb->ttl < 0) { - if (bomb->status == 1) { - if (game->explosion_callback) - game->explosion_callback(bomb->x, bomb->y, bomb->z, - game->explosion_callback_data); - bomb->status = 2; - } else if (bomb->ttl < -0.2) { - if (game->master) { - _explode_bomb(game, bomb); - } - bomb->status = 0; - } - } - } -} - -void _update_point(game_t *game, point_t *point) { - size_t i; - for (i = 0; i < GAME_PLAYER_COUNT; i++) { - player_t *player = &game->player[i]; - if (player->status == 0) - continue; - double distance2 = pow(player->x - point->x, 2) + pow(player->y - - point->y, 2) + pow(player->z - point->z, 2); - if (distance2 > 1000.0) - continue; - point->status = 0; - player->points += 1; - } - -} - -void game_update_points(game_t *game, double dt) { - size_t i; - for (i = 0; i < GAME_POINT_COUNT; i++) { - point_t *point = &game->point[i]; - if (point->status == 0) - continue; - _update_point(game, point); - } -} - -void game_update(game_t *game, double dt) { - const double delta = 1. / 120.; - game->updateTime += dt; - while (game->updateTime > delta) { - game_update_players(game, delta); - game_update_bombs(game, delta); - game_update_points(game, delta); - game->updateTime -= delta; - } -} - -size_t game_active_team_players(game_t *game, team_t *team) { - size_t i, count = 0; - for (i = 0; i < GAME_PLAYER_COUNT; i++) { - if (game->player[i].status == 0) - continue; - if (game->player[i].team == team) - count++; - } - return count; -} - -team_t *game_team_with_least_players(game_t *game) { - size_t i, count = -1; - team_t *team = NULL; - for (i = 0; i < GAME_TEAM_COUNT; i++) { - size_t players = game_active_team_players(game, &game->team[i]); - if (players < count) { - count = players; - team = &game->team[i]; - } - } - return team; -} - -team_t *game_team(game_t *game, uint16_t id) { - size_t i; - for (i = 0; i < GAME_TEAM_COUNT; i++) { - if (game->team[i].id == id) { - return &game->team[i]; - } - } - return NULL; -} - -player_t *game_player(game_t *game, uint16_t id) { - size_t i; - for (i = 0; i < GAME_PLAYER_COUNT; i++) { - if (game->player[i].id == id) { - return &game->player[i]; - } - } - return NULL; -} - -bomb_t *game_spawn_bomb(game_t *game) { - size_t i; - for (i = 0; i < GAME_BOMB_COUNT; i++) { - if (game->bomb[i].status == 0) { - game->bomb[i].status = 1; - return &game->bomb[i]; - } - } - return NULL; -} - -point_t *game_spawn_point(game_t *game) { - size_t i; - for (i = 0; i < GAME_POINT_COUNT; i++) { - if (game->point[i].status == 0) { - game->point[i].status = 1; - return &game->point[i]; - } - } - return NULL; -} - -void game_setup_explosion_callback(game_t *game, void(*explosion_callback)( - double x, double y, double z, void *data), void *data) { - game->explosion_callback = explosion_callback; - game->explosion_callback_data = data; -} - -void game_set_master(game_t *game, int master) { - game->master = master; -} diff --git a/src/common/game.h b/src/common/game.h deleted file mode 100644 index a73727b..0000000 --- a/src/common/game.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef GREMLIN_GAME_H -#define GREMLIN_GAME_H - -#include "common.h" - -typedef struct team_t team_t; -typedef struct player_t player_t; -typedef struct game_t game_t; - -#define GAME_TEAM_COUNT 2 -#define GAME_PLAYER_COUNT 64 -#define GAME_BOMB_COUNT (GAME_PLAYER_COUNT * 5) -#define GAME_POINT_COUNT 50 - -struct player_t { - uint16_t id; - uint16_t status; - double x, y, z; - double rx, ry, rz, rw; - double vx, vy, vz; - team_t *team; - uint16_t points; -}; - -struct bomb_t { - uint8_t status; - double x, y, z; - double vx, vy, vz; - double ttl; -}; - -struct point_t { - uint8_t status; - double x, y, z; -}; - -struct team_t { - uint16_t id; - double x, y, z; - float color[4]; - uint16_t points; - uint16_t wins; -}; - -struct game_t { - team_t team[GAME_TEAM_COUNT]; - player_t player[GAME_PLAYER_COUNT]; - bomb_t bomb[GAME_BOMB_COUNT]; - point_t point[GAME_POINT_COUNT]; - int16_t max_player_id; - int master; - double updateTime; - player_t *local_player; - void(*explosion_callback)(double x, double y, double z, void *data); - void *explosion_callback_data; -}; - -extern void game_setup(game_t *game); -extern void game_reset(game_t *game); -extern team_t *game_team_with_least_players(game_t *game); -extern player_t *game_spawn_player(game_t *game, team_t *team); -extern player_t *game_spawn_player_id(game_t *game, team_t *team, uint16_t id); -extern team_t *game_team(game_t *game, uint16_t id); -extern player_t *game_player(game_t *game, uint16_t id); -extern bomb_t *game_bomb(game_t *game, uint16_t index); -extern void game_update_players(game_t *game, double dt); -extern bomb_t *game_spawn_bomb(game_t *game); -extern point_t *game_spawn_point(game_t *game); -extern void game_update_bombs(game_t *game, double dt); -extern void game_update_points(game_t *game, double dt); -extern void game_update(game_t *game, double dt); -extern void game_setup_explosion_callback(game_t *game, - void(*explosion_callback)(double x, double y, double z, void *data), - void *data); -extern void game_set_master(game_t *game, int master); -#endif