Skip to content
This repository
Newer
Older
100644 335 lines (284 sloc) 7.903 kb
847b6cf9 »
2008-06-26 initial checkin
1 #include <iostream>
2
3 #include "custom_object.hpp"
4 #include "entity.hpp"
03e7cbf8 »
2009-08-28 refactoring to split out logic to control the player
5 #include "foreach.hpp"
55609c60 »
2009-08-29 made playable objects work. :-)
6 #include "playable_custom_object.hpp"
a9e669a4 »
2008-09-11 added option to show collision boxes
7 #include "preferences.hpp"
8 #include "raster.hpp"
2f69da5e »
2009-10-05 added initial implementation of new collision detection to object fro…
9 #include "solid_map.hpp"
847b6cf9 »
2008-06-26 initial checkin
10 #include "wml_node.hpp"
11 #include "wml_utils.hpp"
12
13 entity::entity(wml::const_node_ptr node)
764d91f4 »
2009-03-20 made it so objects that ignore collisions have their movement tracked…
14 : x_(wml::get_int(node, "x")*100),
15 y_(wml::get_int(node, "y")*100),
3143f56d »
2009-10-11 made platforms work properly
16 prev_feet_x_(INT_MIN), prev_feet_y_(INT_MIN),
847b6cf9 »
2008-06-26 initial checkin
17 face_right_(wml::get_bool(node, "face_right")),
e9bf626b »
2009-05-23 added upside down field to objects, and made it so retracting spikes …
18 upside_down_(wml::get_bool(node, "upside_down", false)),
8a5827e0 »
2008-07-30 added brambles
19 group_(wml::get_int(node, "group", -1)),
ddff1a9a »
2009-10-24 added solid dimensions and made pato have solid area
20 id_(-1), respawn_(wml::get_bool(node, "respawn", true)),
65d5ffba »
2010-05-22 made the concept of 'weak' dimensions
21 solid_dimensions_(0), collide_dimensions_(0),
5334389a »
2010-10-01 made conveyor belt move you when you're on it
22 weak_solid_dimensions_(0), weak_collide_dimensions_(0),
23 platform_motion_x_(wml::get_int(node, "platform_motion_x"))
847b6cf9 »
2008-06-26 initial checkin
24 {
03e7cbf8 »
2009-08-28 refactoring to split out logic to control the player
25 foreach(bool& b, controls_) {
26 b = false;
27 }
847b6cf9 »
2008-06-26 initial checkin
28 }
29
30 entity::entity(int x, int y, bool face_right)
65d5ffba »
2010-05-22 made the concept of 'weak' dimensions
31 : x_(x*100), y_(y*100), prev_feet_x_(INT_MIN), prev_feet_y_(INT_MIN),
32 face_right_(face_right), upside_down_(false), group_(-1), id_(-1),
33 solid_dimensions_(0), collide_dimensions_(0),
5334389a »
2010-10-01 made conveyor belt move you when you're on it
34 weak_solid_dimensions_(0), weak_collide_dimensions_(0),
35 platform_motion_x_(0)
847b6cf9 »
2008-06-26 initial checkin
36 {
03e7cbf8 »
2009-08-28 refactoring to split out logic to control the player
37 foreach(bool& b, controls_) {
38 b = false;
39 }
847b6cf9 »
2008-06-26 initial checkin
40 }
41
42 entity_ptr entity::build(wml::const_node_ptr node)
43 {
44 if(node->has_attr("is_human")) {
57612a64 »
2009-10-23 RIP to characters, items, fluids, and all those things that seemed li…
45 return entity_ptr(new playable_custom_object(node));
847b6cf9 »
2008-06-26 initial checkin
46 } else {
57612a64 »
2009-10-23 RIP to characters, items, fluids, and all those things that seemed li…
47 return entity_ptr(new custom_object(node));
847b6cf9 »
2008-06-26 initial checkin
48 }
49 }
50
3143f56d »
2009-10-11 made platforms work properly
51 bool entity::has_feet() const
52 {
53 return solid();
54 }
55
847b6cf9 »
2008-06-26 initial checkin
56 int entity::feet_x() const
57 {
52f6b591 »
2010-04-07 optimizations to calculation of entity feet positions
58 if(solid_) {
59 const int diff = solid_->area().x() + solid_->area().w()/2;
2b42ec61 »
2009-10-13 fixed solid collisions working properly in reverse
60 return face_right() ? x() + diff : x() + current_frame().width() - diff;
2f69da5e »
2009-10-05 added initial implementation of new collision detection to object fro…
61 }
847b6cf9 »
2008-06-26 initial checkin
62 return face_right() ? x() + current_frame().feet_x() : x() + current_frame().width() - current_frame().feet_x();
63 }
64
65 int entity::feet_y() const
66 {
52f6b591 »
2010-04-07 optimizations to calculation of entity feet positions
67 if(solid_) {
68 return y() + solid_->area().y() + solid_->area().h();
2f69da5e »
2009-10-05 added initial implementation of new collision detection to object fro…
69 }
847b6cf9 »
2008-06-26 initial checkin
70 return y() + current_frame().feet_y();
71 }
72
3143f56d »
2009-10-11 made platforms work properly
73 int entity::last_move_x() const
74 {
75 if(prev_feet_x_ == INT_MIN) {
76 return 0;
77 }
78
79 return feet_x() - prev_feet_x_;
80 }
81
82 int entity::last_move_y() const
83 {
84 if(prev_feet_y_ == INT_MIN) {
85 return 0;
86 }
87
88 return feet_y() - prev_feet_y_;
89 }
90
5334389a »
2010-10-01 made conveyor belt move you when you're on it
91 void entity::set_platform_motion_x(int value)
92 {
93 platform_motion_x_ = value;
94 }
95
96 int entity::platform_motion_x() const
97 {
98 return platform_motion_x_;
99 }
100
3143f56d »
2009-10-11 made platforms work properly
101 void entity::process(level& lvl)
102 {
103 prev_feet_x_ = feet_x();
104 prev_feet_y_ = feet_y();
105 }
106
847b6cf9 »
2008-06-26 initial checkin
107 void entity::set_face_right(bool facing)
108 {
109 if(facing == face_right_) {
110 return;
111 }
112 const int start_x = feet_x();
113 face_right_ = facing;
114 const int delta_x = feet_x() - start_x;
2b42ec61 »
2009-10-13 fixed solid collisions working properly in reverse
115 x_ -= delta_x*100;
116 assert(feet_x() == start_x);
959029c5 »
2009-12-25 some optimization of collision processing
117
118 calculate_solid_rect();
847b6cf9 »
2008-06-26 initial checkin
119 }
120
e9bf626b »
2009-05-23 added upside down field to objects, and made it so retracting spikes …
121 void entity::set_upside_down(bool facing)
122 {
123 upside_down_ = facing;
124 }
125
959029c5 »
2009-12-25 some optimization of collision processing
126 void entity::calculate_solid_rect()
9ebb8bb6 »
2009-10-09 fixed multi tile patterns
127 {
2daaeb1b »
2009-12-26 some optimizations to collisions and fixed walking while on a moving …
128 const frame& f = current_frame();
129
130 frame_rect_ = rect(x(), y(), f.width(), f.height());
131
28c4bd28 »
2009-12-28 optimizations to solid calculations
132 solid_ = calculate_solid();
133 if(solid_) {
134 const rect& area = solid_->area();
2b42ec61 »
2009-10-13 fixed solid collisions working properly in reverse
135
136 if(face_right()) {
959029c5 »
2009-12-25 some optimization of collision processing
137 solid_rect_ = rect(x() + area.x(), y() + area.y(), area.w(), area.h());
2b42ec61 »
2009-10-13 fixed solid collisions working properly in reverse
138 } else {
959029c5 »
2009-12-25 some optimization of collision processing
139 solid_rect_ = rect(x() + f.width() - area.x() - area.w(), y() + area.y(), area.w(), area.h());
2b42ec61 »
2009-10-13 fixed solid collisions working properly in reverse
140 }
9ebb8bb6 »
2009-10-09 fixed multi tile patterns
141 } else {
959029c5 »
2009-12-25 some optimization of collision processing
142 solid_rect_ = rect();
9ebb8bb6 »
2009-10-09 fixed multi tile patterns
143 }
144
28c4bd28 »
2009-12-28 optimizations to solid calculations
145 platform_ = calculate_platform();
146 if(platform_) {
3143f56d »
2009-10-11 made platforms work properly
147 const int delta_y = last_move_y();
28c4bd28 »
2009-12-28 optimizations to solid calculations
148 const rect& area = platform_->area();
3143f56d »
2009-10-11 made platforms work properly
149
150 if(area.empty()) {
2daaeb1b »
2009-12-26 some optimizations to collisions and fixed walking while on a moving …
151 platform_rect_ = rect();
7554ecd1 »
2009-10-20 fixed problem with falling through platforms
152 } else {
2daaeb1b »
2009-12-26 some optimizations to collisions and fixed walking while on a moving …
153 if(delta_y < 0) {
154 platform_rect_ = rect(x() + area.x(), y() + area.y(), area.w(), area.h() - delta_y);
155 } else {
156 platform_rect_ = rect(x() + area.x(), y() + area.y(), area.w(), area.h());
157 }
3143f56d »
2009-10-11 made platforms work properly
158 }
159 } else {
2daaeb1b »
2009-12-26 some optimizations to collisions and fixed walking while on a moving …
160 platform_rect_ = rect();
3143f56d »
2009-10-11 made platforms work properly
161 }
162 }
163
847b6cf9 »
2008-06-26 initial checkin
164 rect entity::body_rect() const
165 {
166 const frame& f = current_frame();
e9bf626b »
2009-05-23 added upside down field to objects, and made it so retracting spikes …
167
168 const int ypos = y() + (upside_down() ? (f.height() - (f.collide_y() + f.collide_h())) : f.collide_y());
169 return rect(face_right() ? x() + f.collide_x() : x() + f.width() - f.collide_x() - f.collide_w(),
170 ypos, f.collide_w(), f.collide_h());
847b6cf9 »
2008-06-26 initial checkin
171 }
172
173 rect entity::hit_rect() const
174 {
175 const frame& f = current_frame();
fcb303d9 »
2010-05-21 make it so when --show_hitboxes is used, red rectangles will be shown…
176 const std::vector<frame::collision_area>& areas = f.collision_areas();
177 foreach(const frame::collision_area& a, areas) {
178 if(a.name == "attack") {
179 const rect& r = a.area;
180 return rect(face_right() ? x() + r.x() : x() + f.width() - r.x() - r.w(), y() + r.y(), r.w(), r.h());
181 }
847b6cf9 »
2008-06-26 initial checkin
182 }
fcb303d9 »
2010-05-21 make it so when --show_hitboxes is used, red rectangles will be shown…
183
184 return rect();
847b6cf9 »
2008-06-26 initial checkin
185 }
a9e669a4 »
2008-09-11 added option to show collision boxes
186
03e7cbf8 »
2009-08-28 refactoring to split out logic to control the player
187 point entity::midpoint() const
188 {
a87a153a »
2009-11-22 optimized loading of levels
189 if(solid()) {
190 const rect r = solid_rect();
191 return point(r.x() + r.w()/2, r.y() + r.h()/2);
192 }
193
194 const frame& f = current_frame();
195 return point(x() + f.width()/2, y() + f.height()/2);
03e7cbf8 »
2009-08-28 refactoring to split out logic to control the player
196 }
197
7c283e9b »
2009-02-14 made it so that in properties mode you can drag objects around to cha…
198 bool entity::is_alpha(int xpos, int ypos) const
199 {
200 return current_frame().is_alpha(xpos - x(), ypos - y(), time_in_frame(), face_right());
201 }
202
a9e669a4 »
2008-09-11 added option to show collision boxes
203 void entity::draw_debug_rects() const
204 {
205 if(preferences::show_debug_hitboxes() == false) {
206 return;
207 }
208
c8baf152 »
2009-11-24 made show_hitboxes work for objects
209 const rect& body = solid_rect();
a9e669a4 »
2008-09-11 added option to show collision boxes
210 if(body.w() > 0 && body.h() > 0) {
211 const SDL_Rect rect = { body.x(), body.y(), body.w(), body.h() };
212 graphics::draw_rect(rect, graphics::color_black(), 0xAA);
213 }
214
215 const rect& hit = hit_rect();
216 if(hit.w() > 0 && hit.h() > 0) {
217 const SDL_Rect rect = { hit.x(), hit.y(), hit.w(), hit.h() };
218 graphics::draw_rect(rect, graphics::color_red(), 0xAA);
219 }
220
221 const SDL_Rect rect = { feet_x() - 1, feet_y() - 1, 3, 3 };
222 graphics::draw_rect(rect, graphics::color_white(), 0xFF);
223 }
7d7f3446 »
2009-05-23 made silver frogatto repel projectiles
224
225 void entity::generate_current(const entity& target, int* velocity_x, int* velocity_y) const
226 {
227 if(current_generator_) {
228 const rect& my_rect = body_rect();
229 const rect& target_rect = target.body_rect();
230 current_generator_->generate(my_rect.mid_x(), my_rect.mid_y(),
867acce4 »
2009-06-11 currents: version 2
231 target_rect.mid_x(), target_rect.mid_y(), target.mass(),
7d7f3446 »
2009-05-23 made silver frogatto repel projectiles
232 velocity_x, velocity_y);
233 }
234 }
235
d3ae4152 »
2009-08-02 added an interface for multiplayer
236 void entity::add_scheduled_command(int cycle, variant cmd)
237 {
238 scheduled_commands_.push_back(ScheduledCommand(cycle, cmd));
239 std::sort(scheduled_commands_.begin(), scheduled_commands_.end());
240 }
241
242 variant entity::get_scheduled_command(int cycle)
243 {
244 if(scheduled_commands_.empty() == false && cycle >= scheduled_commands_.front().first) {
245 variant result = scheduled_commands_.front().second;
246 scheduled_commands_.erase(scheduled_commands_.begin());
247 return result;
248 }
249
250 return variant();
251 }
252
03e7cbf8 »
2009-08-28 refactoring to split out logic to control the player
253 namespace {
254 std::vector<const_powerup_ptr> empty_powerup_vector;
255 }
256
257 const std::vector<const_powerup_ptr>& entity::powerups() const
258 {
259 return empty_powerup_vector;
260 }
261
262 const std::vector<const_powerup_ptr>& entity::abilities() const
263 {
264 return empty_powerup_vector;
265 }
266
7d7f3446 »
2009-05-23 made silver frogatto repel projectiles
267 void entity::set_current_generator(current_generator* generator)
268 {
269 current_generator_ = current_generator_ptr(generator);
270 }
9a8f08a3 »
2009-06-12 fixed doors up in the editor
271
79161c47 »
2009-12-05 changes to make swallowing work much more nicely
272 void entity::set_attached_objects(const std::vector<entity_ptr>& v)
273 {
274 if(v != attached_objects_) {
275 attached_objects_ = v;
276 }
277 }
278
959029c5 »
2009-12-25 some optimization of collision processing
279 bool entity::move_centipixels(int dx, int dy)
280 {
281 int start_x = x();
282 int start_y = y();
283 x_ += dx;
284 y_ += dy;
285 if(x() != start_x || y() != start_y) {
286 calculate_solid_rect();
287 return true;
288 } else {
289 return false;
290 }
291 }
292
9a8f08a3 »
2009-06-12 fixed doors up in the editor
293 void entity::set_distinct_label()
294 {
295 //generate a random label for the object
296 char buf[64];
297 sprintf(buf, "_%x", rand());
298 set_label(buf);
299 }
03e7cbf8 »
2009-08-28 refactoring to split out logic to control the player
300
301 void entity::set_control_status(const std::string& key, bool value)
302 {
303 static const std::string keys[] = { "up", "down", "left", "right", "attack", "jump" };
304 const std::string* k = std::find(keys, keys + controls::NUM_CONTROLS, key);
305 if(k == keys + controls::NUM_CONTROLS) {
306 return;
307 }
308
309 const int index = k - keys;
310 controls_[index] = value;
311 }
312
313 void entity::read_controls(int cycle)
314 {
315 player_info* info = get_player_info();
316 if(info) {
317 info->read_controls(cycle);
318 }
319 }
ca355244 »
2010-10-22 added support for objects to be parented to other objects
320
321 point entity::pivot(const std::string& name) const
322 {
323 const frame& f = current_frame();
d31635fd »
2011-05-07 fixes to relative positions when changing facing
324 if(name == "") {
325 return midpoint();
326 }
327
ca355244 »
2010-10-22 added support for objects to be parented to other objects
328 const point pos = f.pivot(name, time_in_frame());
329 if(face_right()) {
330 return point(x() + pos.x, y() + pos.y);
331 } else {
332 return point(x() + f.width() - pos.x, y() + pos.y);
333 }
334 }
Something went wrong with that request. Please try again.