/* arena.h - Copyright (C) 2006 Mark boyd 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. This program is distributed in the hope that it will be fun to play, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef ARENA_H #define ARENA_H #include #include #include #include //for Uint32 :( #define ARENA(x,y) x, enum arena_t { #include "arena_table.h" }; #undef ARENA enum damage_type { HURT_ENEMIES=1, HURT_PLAYER=2, }; class mover; class ball; struct SDL_Surface; //The arena is the place where the action occurs //It contains the stationary blocks(defined in arena_table.h), and also the movers //It implements the "laws of physics" (mostly, that's the "apply forces" function) //It implements fun special effects (like AOE_Force) //It detects collisions, but responding to the collision is up to the mover(s) involved //(except in the special case of balls, which are dealt with by the arena (and is a bit of a hack, really)) class arena { public: arena(); ~arena(); void set_size(int x, int y); //Also destroys all sprites etc. void set(int x, int y, arena_t); void set_player_spawn(int x, int y) {m_player_spawn_x=x;m_player_spawn_y=y;} void connect(int cause_x, int cause_y, int effect_x, int effect_y); //activate() must be called once after all calls of set() for those set()s to have any effect //activate() creates the player ship void activate(); //Used when creating levels to allow things to start in non-default states. void apply_effect(int effect_x, int effect_y); void add_mover(mover *m); void create_tractor(mover *from, mover* to); void destroy_tractor(mover *from); arena_t get(int x, int y) const; int width() const {return m_scenery.size();} int height() const {return m_scenery.size()?m_scenery[0].size():0;} SDL_Surface *bitmap() const {return m_background;} Uint8 getalpha(int x, int y) const; mover *get_nearest_tractor_target(float x, float y); mover *get_player_target(); void do_stuff(float time_interval); //calls do_stuff on all active movers void apply_forces(float time_interval); void move_stuff_and_do_collisions(float time_interval); //Possibly this function shouldn't exist?? const std::deque &movers() const; // bool arena_collision(SDL_Surface *p, int x, int y, arena_t *obstacle=0, int *tile_x=0, int *tile_y=0, int *pic_x=0, int *pic_y=0) const; int get_player_x() const {return m_player_x;} int get_player_y() const {return m_player_y;} bool level_complete() const; bool player_is_dead() const; void AOE_damage(float x, float y, float radius, int dam_centre, int dam_edge, damage_type dt); void AOE_force(float x, float y, float radius, float dam_centre, float dam_edge); //destroys all void open_exit(); private: void move_stuff(float time_interval); void do_collisions(); std::map m_bitmaps; std::vector > m_scenery; //Large images are cut up into standard-sized tiles for convenience. //m_extra_bmps stores extra bitmaps generated in this way //m_orig_bitmap gets the original bitmap index back (from a generated index) struct extra_bmps { int m_nx,m_ny; std::vector > m_bmps; }; std::map m_extra_bmps; std::map m_orig_bitmap; SDL_Surface *m_background; //movers! std::deque m_waiting_room; //newly created movers start here std::deque m_movers; //m_player_x, and m_player_y are stored outside the player so that we still //have them when the player dies. int m_player_x, m_player_y; int m_player_spawn_x, m_player_spawn_y; bool m_player_alive; int m_player_respawn; //Special places where balls are generated struct ball_src { int x; int y; ball* b; }; std::deque m_ball_srcs; //tractor beams! struct tractor { mover* from; mover* to; std::vector indicators; }; std::deque m_tractors; //Used to model powerful explosions which can push stuff around. struct force_ball { float x; float y; float radius; float force_centre; float force_edge; }; std::deque m_force_balls; //Some special tiles can perform animations- //e.g. swithes, opening/closing doors //This is notionally a single tile, oversized bitmaps work struct animation { int x; int y; std::deque frames; int current; }; std::deque m_animations; //Generally connects switches to doors struct connection { int cause_x; int cause_y; int effect_x; int effect_y; }; std::deque m_connections; void update_stuff(); void handle_collision(mover *m, arena_t obstacle, int x, int y); void untractor(mover *m); void apply_forces(mover &m, float time_interval); void add_animation(int x, int y, const std::deque &frames); void do_causality(int cause_x, int cause_y); void destroy_everything(); }; #endif