1 | // SuperTux |
2 | // Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de> |
3 | // Copyright (C) 2006 Matthias Braun <matze@braunis.de> |
4 | // Copyright (C) 2010 Florian Forster <supertux at octo.it> |
5 | // |
6 | // This program is free software: you can redistribute it and/or modify |
7 | // it under the terms of the GNU General Public License as published by |
8 | // the Free Software Foundation, either version 3 of the License, or |
9 | // (at your option) any later version. |
10 | // |
11 | // This program is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | // |
16 | // You should have received a copy of the GNU General Public License |
17 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | |
19 | #ifndef HEADER_SUPERTUX_SUPERTUX_TILE_HPP |
20 | #define |
21 | |
22 | #include <vector> |
23 | #include <stdint.h> |
24 | |
25 | #include "math/rectf.hpp" |
26 | #include "video/color.hpp" |
27 | #include "video/surface_ptr.hpp" |
28 | |
29 | class Canvas; |
30 | class DrawingContext; |
31 | |
32 | class Tile final |
33 | { |
34 | public: |
35 | static bool draw_editor_images; |
36 | |
37 | public: |
38 | /** bitset for tile attributes */ |
39 | enum { |
40 | /** solid tile that is indestructible by Tux */ |
41 | SOLID = 0x0001, |
42 | /** uni-directional solid tile */ |
43 | UNISOLID = 0x0002, |
44 | /** a brick that can be destroyed by jumping under it */ |
45 | BRICK = 0x0004, //Marked for removal, DO NOT USE! |
46 | /** the level should be finished when touching a goaltile. |
47 | * if data is 0 then the endsequence should be triggered, if data is 1 |
48 | * then we can finish the level instantly. |
49 | */ |
50 | GOAL = 0x0008, //Marked for removal, DO NOT USE! |
51 | /** slope tile */ |
52 | SLOPE = 0x0010, |
53 | /** Bonusbox, content is stored in \a data */ |
54 | FULLBOX = 0x0020, //Marked for removal, DO NOT USE! |
55 | /** Tile is a coin */ |
56 | COIN = 0x0040, //Marked for removal, DO NOT USE! |
57 | |
58 | /* interesting flags (the following are passed to gameobjects) */ |
59 | FIRST_INTERESTING_FLAG = 0x0100, |
60 | |
61 | /** an ice brick that makes tux sliding more than usual */ |
62 | ICE = 0x0100, |
63 | /** a water tile in which tux starts to swim */ |
64 | WATER = 0x0200, |
65 | /** a tile that hurts Tux if he touches it */ |
66 | HURTS = 0x0400, |
67 | /** for lava: WATER, HURTS, FIRE */ |
68 | FIRE = 0x0800 |
69 | }; |
70 | |
71 | /** worldmap flags */ |
72 | enum { |
73 | WORLDMAP_NORTH = 0x0001, |
74 | WORLDMAP_SOUTH = 0x0002, |
75 | WORLDMAP_EAST = 0x0004, |
76 | WORLDMAP_WEST = 0x0008, |
77 | WORLDMAP_DIR_MASK = 0x000f, |
78 | |
79 | WORLDMAP_STOP = 0x0010, |
80 | |
81 | // convenience values ("C" stands for crossroads) |
82 | WORLDMAP_CNSE = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST, |
83 | WORLDMAP_CNSW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_WEST, |
84 | WORLDMAP_CNEW = WORLDMAP_NORTH | WORLDMAP_EAST | WORLDMAP_WEST, |
85 | WORLDMAP_CSEW = WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST, |
86 | WORLDMAP_CNSEW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST |
87 | }; |
88 | |
89 | enum |
90 | { |
91 | UNI_DIR_NORTH = 0, |
92 | UNI_DIR_SOUTH = 1, |
93 | UNI_DIR_WEST = 2, |
94 | UNI_DIR_EAST = 3, |
95 | UNI_DIR_MASK = 3 |
96 | }; |
97 | |
98 | public: |
99 | Tile(); |
100 | Tile(const std::vector<SurfacePtr>& images, |
101 | const std::vector<SurfacePtr>& editor_images, |
102 | uint32_t attributes, uint32_t data, float fps, |
103 | const std::string& obj_name = "" , const std::string& obj_data = "" , |
104 | bool deprecated = false); |
105 | |
106 | /** Draw a tile on the screen */ |
107 | void draw(Canvas& canvas, const Vector& pos, int z_pos, const Color& color = Color(1, 1, 1)) const; |
108 | void draw_debug(Canvas& canvas, const Vector& pos, int z_pos, const Color& color = Color(1.0f, 0.f, 1.0f, 0.5f)) const; |
109 | |
110 | SurfacePtr get_current_surface() const; |
111 | SurfacePtr get_current_editor_surface() const; |
112 | |
113 | uint32_t get_attributes() const { return m_attributes; } |
114 | int get_data() const { return m_data; } |
115 | |
116 | /** Checks the SLOPE attribute. Returns "true" if set, "false" otherwise. */ |
117 | bool is_slope() const { return (m_attributes & SLOPE) != 0; } |
118 | |
119 | /** Determine the solidity of a tile. This version behaves correctly |
120 | for unisolid tiles by taking position and movement of the object |
121 | in question into account. Because creating the arguments for |
122 | this function can be expensive, you should handle trivial cases |
123 | using the "is_solid()" and "is_unisolid()" methods first. */ |
124 | bool is_solid (const Rectf& tile_bbox, const Rectf& position, const Vector& movement) const; |
125 | |
126 | /** This version only checks the SOLID flag to determine the |
127 | solidity of a tile. This means it will always return "true" for |
128 | unisolid tiles. To determine the *current* solidity of unisolid |
129 | tiles, use the "is_solid" method that takes position and |
130 | movement into account (see above). */ |
131 | bool is_solid() const { return (m_attributes & SOLID) != 0; } |
132 | |
133 | /** Determines whether the tile's attributes are important to |
134 | calculate the collisions. The tile may be unisolid and therefore |
135 | the collision with that tile don't matter.*/ |
136 | bool is_collisionful(const Rectf& tile_bbox, const Rectf& position, const Vector& movement) const; |
137 | |
138 | /** Checks the UNISOLID attribute. Returns "true" if set, "false" otherwise. */ |
139 | bool is_unisolid() const { return (m_attributes & UNISOLID) != 0; } |
140 | |
141 | bool is_deprecated() const { return m_deprecated; } |
142 | |
143 | const std::string& get_object_name() const { return m_object_name; } |
144 | const std::string& get_object_data() const { return m_object_data; } |
145 | |
146 | private: |
147 | /** Returns zero if a unisolid tile is non-solid due to the movement |
148 | direction, non-zero if the tile is solid due to direction. */ |
149 | bool check_movement_unisolid (const Vector& movement) const; |
150 | |
151 | /** Returns zero if a unisolid tile is non-solid due to the position |
152 | of the tile and the object, non-zero if the tile is solid. */ |
153 | bool check_position_unisolid (const Rectf& obj_bbox, |
154 | const Rectf& tile_bbox) const; |
155 | |
156 | private: |
157 | std::vector<SurfacePtr> m_images; |
158 | std::vector<SurfacePtr> m_editor_images; |
159 | |
160 | /** tile attributes */ |
161 | uint32_t m_attributes; |
162 | |
163 | /** General purpose data attached to a tile (content of a box, type of coin)*/ |
164 | int m_data; |
165 | |
166 | float m_fps; |
167 | |
168 | std::string m_object_name; |
169 | std::string m_object_data; |
170 | |
171 | /** Discourage use of this tile by not making it available in the editor */ |
172 | bool m_deprecated; |
173 | |
174 | private: |
175 | Tile(const Tile&) = delete; |
176 | Tile& operator=(const Tile&) = delete; |
177 | }; |
178 | |
179 | #endif |
180 | |
181 | /* EOF */ |
182 | |