Fixed trailing whitespaces in all(?) source files of supertux, also fixed some svn...
[supertux.git] / src / sector.hpp
index 05d5af4..487f4a2 100644 (file)
@@ -1,7 +1,7 @@
 //  $Id$
 //
 //  SuperTux -  A Jump'n Run
-//  Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
 
 #include <string>
 #include <vector>
+#include <list>
+#include <memory>
+#include <squirrel.h>
 
 #include "direction.hpp"
 #include "math/vector.hpp"
 #include "video/drawing_context.hpp"
+#include "script_interface.hpp"
+#include "scripting/ssector.hpp"
 
 namespace lisp {
 class Lisp;
 class Writer;
 }
+namespace collision {
+class Constraints;
+}
 
 class Rect;
 class Sprite;
@@ -38,26 +46,32 @@ class Player;
 class Camera;
 class TileMap;
 class Bullet;
-class CollisionGrid;
 class ScriptInterpreter;
 class SpawnPoint;
 class MovingObject;
 class CollisionHit;
+class Level;
+class Portable;
 
 enum MusicType {
   LEVEL_MUSIC,
-  HERRING_MUSIC
+  HERRING_MUSIC,
+  HERRING_WARNING_MUSIC
 };
 
-/** This class holds a sector (a part of a level) and all the game objects
- * (badguys, player, background, tilemap, ...)
+/**
+ * This class holds a sector (a part of a level) and all the game objects in
+ * the sector
  */
-class Sector
+class Sector : public Scripting::SSector
 {
 public:
-  Sector();
+  Sector(Level* parent);
   ~Sector();
 
+  /// get parent level
+  Level* get_level();
+
   /// read sector from lisp file
   void parse(const lisp::Lisp& lisp);
   void parse_old_format(const lisp::Lisp& lisp);
@@ -67,12 +81,19 @@ public:
   /// activates this sector (change music, intialize player class, ...)
   void activate(const std::string& spawnpoint);
   void activate(const Vector& player_pos);
+  void deactivate();
 
   void update(float elapsed_time);
   void update_game_objects();
 
   void draw(DrawingContext& context);
 
+  /**
+   * runs a script in the context of the sector (sector_table will be the
+   * roottable of this squirrel VM)
+   */
+  HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
+
   /// adds a gameobject
   void add_object(GameObject* object);
 
@@ -81,21 +102,18 @@ public:
   const std::string& get_name() const
   { return name; }
 
-  /// tests if a given rectangle is inside the sector
+  /**
+   * tests if a given rectangle is inside the sector
+   * (a rectangle that is on top of the sector is considered inside)
+   */
   bool inside(const Rect& rectangle) const;
 
   void play_music(MusicType musictype);
   MusicType get_music_type();
-  
-  /** Checks for all possible collisions. And calls the
-      collision_handlers, which the collision_objects provide for this
-      case (or not). */
-  void handle_collisions();
 
   bool add_bullet(const Vector& pos, float xm, Direction dir);
   bool add_smoke_cloud(const Vector& pos);
-  void add_floating_text(const Vector& pos, const std::string& text);
-                                                                                
+
   /** get currently activated sector. */
   static Sector* current()
   { return _current; }
@@ -103,13 +121,38 @@ public:
   /** Get total number of badguys */
   int get_total_badguys();
 
-  void collision_tilemap(MovingObject* object, CollisionHit& hit) const;
-  uint32_t collision_tile_attributes(MovingObject* object) const;
+  /** Get total number of GameObjects of given type */
+  template<class T> int get_total_count()
+  {
+    int total = 0;
+    for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+      if (dynamic_cast<T*>(*i)) total++;
+    }
+    return total;
+  }
+
+  void collision_tilemap(collision::Constraints* constraints,
+      const Vector& movement, const Rect& dest) const;
 
-  /** Checks if at the specified rectangle are gameobjects with STATIC flag set
-   * (or solid tiles from the tilemap)
+  /**
+   * Checks if the specified rectangle is free of (solid) tiles.
+   * Note that this does not include static objects, e.g. bonus blocks.
+   */
+  bool is_free_of_tiles(const Rect& rect) const;
+  /**
+   * Checks if the specified rectangle is free of both
+   * 1.) solid tiles and
+   * 2.) MovingObjects in COLGROUP_STATIC.
+   * Note that this does not include badguys or players.
    */
-  bool is_free_space(const Rect& rect) const;
+  bool is_free_of_statics(const Rect& rect, const MovingObject* ignore_object = 0) const;
+  /**
+   * Checks if the specified rectangle is free of both
+   * 1.) solid tiles and
+   * 2.) MovingObjects in COLGROUP_STATIC, COLGROUP_MOVINGSTATIC or COLGROUP_MOVING.
+   * This includes badguys and players.
+   */
+  bool is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object = 0) const;
 
   /**
    * returns a list of players currently in the sector
@@ -118,48 +161,116 @@ public:
     return std::vector<Player*>(1, this->player);
   }
 
-private:
-  void collision_object(MovingObject* object1, MovingObject* object2) const;
-  GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);
-  
-  static Sector* _current;
-  
-  std::string name;
+  Rect get_active_region();
 
-public:
-  std::string music;
-  float gravity;
+  /**
+   * returns the width (in px) of a sector)
+   */
+  float get_width() const;
 
-  // some special objects, where we need direct access
-  Player* player;
-  TileMap* solids;
-  Camera* camera;
-  
-private:
-  std::vector<Bullet*> bullets;
+  /**
+   * returns the height (in px) of a sector)
+   */
+  float get_height() const;
 
-  std::string init_script;
+  /**
+   * globally changes solid tilemaps' tile ids
+   */
+  void change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id);
 
-public: // TODO make this private again
   typedef std::vector<GameObject*> GameObjects;
-  GameObjects gameobjects;
   typedef std::vector<MovingObject*> MovingObjects;
-  MovingObjects moving_objects;
   typedef std::vector<SpawnPoint*> SpawnPoints;
-  SpawnPoints spawnpoints;                       
+  typedef std::vector<Portable*> Portables;
 
-  Rect get_active_region();
+  // --- Scripting ---
+  /**
+   *  get/set color of ambient light
+   */
+  void set_ambient_light(float red, float green, float blue);
+  float get_ambient_red();
+  float get_ambient_green();
+  float get_ambient_blue();
 
 private:
+  Level* level; /**< Parent level containing this sector */
+  uint32_t collision_tile_attributes(const Rect& dest) const;
+
+  void before_object_remove(GameObject* object);
+  bool before_object_add(GameObject* object);
+
+  void try_expose(GameObject* object);
+  void try_unexpose(GameObject* object);
+  void try_expose_me();
+  void try_unexpose_me();
+
+  /** Checks for all possible collisions. And calls the
+      collision_handlers, which the collision_objects provide for this
+      case (or not). */
+  void handle_collisions();
+
+  /**
+   * Does collision detection between 2 objects and does instant
+   * collision response handling in case of a collision
+   */
+  void collision_object(MovingObject* object1, MovingObject* object2) const;
+
+  /**
+   * Does collision detection of an object against all other static
+   * objects (and the tilemap) in the level. Collision response is done
+   * for the first hit in time. (other hits get ignored, the function
+   * should be called repeatedly to resolve those)
+   *
+   * returns true if the collision detection should be aborted for this object
+   * (because of ABORT_MOVE in the collision response or no collisions)
+   */
+  void collision_static(collision::Constraints* constraints,
+      const Vector& movement, const Rect& dest, GameObject& object);
+
+  void collision_static_constrains(MovingObject& object);
+
+  GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);
+
   void fix_old_tiles();
-  
+
+  static Sector* _current;
+
+  std::string name;
+
+  std::vector<Bullet*> bullets;
+
+  std::string init_script;
+
   /// container for newly created objects, they'll be added in Sector::update
   GameObjects gameobjects_new;
+
   MusicType currentmusic;
 
-  CollisionGrid* grid;
+  HSQOBJECT sector_table;
+  /// sector scripts
+  typedef std::vector<HSQOBJECT> ScriptList;
+  ScriptList scripts;
+
+  Color ambient_light;
+
+public: // TODO make this private again
+  /// show collision rectangles of moving objects (for debugging)
+  static bool show_collrects;
+  static bool draw_solids_only;
+
+  GameObjects gameobjects;
+  MovingObjects moving_objects;
+  SpawnPoints spawnpoints;
+  Portables portables;
+
+  std::string music;
+  float gravity;
+
+  // some special objects, where we need direct access
+  // (try to avoid accessing them directly)
+  Player* player;
+  std::list<TileMap*> solid_tilemaps;
+  Camera* camera;
 };
 
 #endif
-