Merged changes from branches/supertux-milestone2-grumbel/ to trunk/supertux/
[supertux.git] / src / supertux / moving_object.hpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #ifndef HEADER_SUPERTUX_SUPERTUX_MOVING_OBJECT_HPP
18 #define HEADER_SUPERTUX_SUPERTUX_MOVING_OBJECT_HPP
19
20 #include <stdint.h>
21
22 #include "math/rect.hpp"
23 #include "supertux/collision_hit.hpp"
24 #include "supertux/game_object.hpp"
25
26 class Sector;
27 class CollisionGrid;
28
29 enum CollisionGroup {
30   /** Objects in DISABLED group are not tested for collisions */
31   COLGROUP_DISABLED = 0,
32
33   /** "default" is moving object. MovingObjects get tested against all
34       other objects and against other movingobjects */
35   COLGROUP_MOVING,
36
37   /** a Moving object, that is not tested against other MovingObjects
38       (or other MovingOnlyStatic objects), but is tested against all
39       other objects. */
40   COLGROUP_MOVING_ONLY_STATIC,
41
42   /** TODO write docu :-/ */
43   COLGROUP_MOVING_STATIC,
44
45   /** 
46    * Doesn't move and isn't explicitly checked for collisions with
47    * other objects (but other objects might check with this) The
48    * difference to COLGROUP_TOUCHABLE is that we can do multiple
49    * collision response tests in a row which is needed for static object
50    * that tux walks on. The results for collisions with STATIC objects
51    * are also sorted by time (so that the first hit gets handled first).
52    * 
53    * Use this for static obstacles 
54    */
55   COLGROUP_STATIC,
56
57   /** Isn't explicitly checked for collisions with other objects. But
58       other objects might check with this object.  Difference to
59       COLGROUP_STATIC is that collisions with this object are only
60       tested once and collision response is typically not handled
61    
62       Use this for touchable things like spikes/areas or collectibles
63       like coins */
64   COLGROUP_TOUCHABLE,
65
66   /** Should be used for tilemaps */
67   COLGROUP_TILEMAP
68 };
69
70 /** Base class for all dynamic/moving game objects. This class
71     contains things for handling the bounding boxes and collision
72     feedback. */
73 class MovingObject : public GameObject
74 {
75 public:
76   MovingObject();
77   virtual ~MovingObject();
78
79   /** this function is called when the object collided with something solid */
80   virtual void collision_solid(const CollisionHit& hit)
81   {
82     (void) hit;
83   }
84
85   /** when 2 objects collided, we will first call the
86       pre_collision_check functions of both objects that can decide on
87       how to react to the collision. */
88   virtual bool collides(GameObject& other, const CollisionHit& hit)
89   {
90     (void) other;
91     (void) hit;
92     return true;
93   }
94
95   /** this function is called when the object collided with any other object */
96   virtual HitResponse collision(GameObject& other, const CollisionHit& hit) = 0;
97
98   /** called when tiles with special attributes have been touched */
99   virtual void collision_tile(uint32_t tile_attributes)
100   {
101     (void) tile_attributes;
102   }
103
104   const Vector& get_pos() const
105   {
106     return bbox.p1;
107   }
108
109   /** returns the bounding box of the Object */
110   const Rect& get_bbox() const
111   {
112     return bbox;
113   }
114
115   const Vector& get_movement() const
116   {
117     return movement;
118   }
119
120   /** places the moving object at a specific position. Be careful when
121       using this function. There are no collision detection checks
122       performed here so bad things could happen. */
123   virtual void set_pos(const Vector& pos)
124   {
125     dest.move(pos-get_pos());
126     bbox.set_pos(pos);
127   }
128
129   /** sets the moving object's bbox to a specific width. Be careful
130       when using this function. There are no collision detection
131       checks performed here so bad things could happen. */
132   virtual void set_width(float w)
133   {
134     dest.set_width(w);
135     bbox.set_width(w);
136   }
137
138   /** sets the moving object's bbox to a specific size. Be careful
139       when using this function. There are no collision detection
140       checks performed here so bad things could happen. */
141   virtual void set_size(float w, float h)
142   {
143     dest.set_size(w, h);
144     bbox.set_size(w, h);
145   }
146
147   CollisionGroup get_group() const
148   {
149     return group;
150   }
151
152 protected:
153   friend class Sector;
154   friend class CollisionGrid;
155   friend class Platform;
156
157   void set_group(CollisionGroup group)
158   {
159     this->group = group;
160   }
161
162   /** The bounding box of the object (as used for collision detection,
163       this isn't necessarily the bounding box for graphics) */
164   Rect bbox;
165
166   /** The movement that will happen till next frame */
167   Vector movement;
168
169   /** The collision group */
170   CollisionGroup group;
171
172 private:
173   /** this is only here for internal collision detection use (don't touch this
174       from outside collision detection code)
175       
176       This field holds the currently anticipated destination of the object
177       during collision detection */
178   Rect dest;
179 };
180
181 #endif
182
183 /* EOF */