add code to debug collision rectangles
[supertux.git] / src / object / scripted_object.cpp
1 #include <config.h>
2
3 #include <stdexcept>
4 #include <math.h>
5
6 #include "scripted_object.hpp"
7 #include "video/drawing_context.hpp"
8 #include "sprite/sprite_manager.hpp"
9 #include "scripting/wrapper_util.hpp"
10 #include "resources.hpp"
11 #include "object_factory.hpp"
12 #include "math/vector.hpp"
13
14 ScriptedObject::ScriptedObject(const lisp::Lisp& lisp)
15   : solid(true), physic_enabled(true), visible(true), new_vel_set(false),
16     layer(LAYER_OBJECTS)
17 {
18   lisp.get("name", name);
19   if(name == "")
20     throw std::runtime_error("Scripted object must have a name specified");
21   
22   std::string spritename;
23   lisp.get("sprite", spritename);
24   if(spritename == "")
25     throw std::runtime_error("Scripted object must have a sprite name specified");
26   sprite = sprite_manager->create(spritename);
27
28   lisp.get("x", bbox.p1.x);
29   lisp.get("y", bbox.p1.y);
30   float width = sprite->get_width();
31   float height = sprite->get_height();
32   lisp.get("width", width);
33   lisp.get("height", height);
34   bbox.set_size(width, height);
35
36   lisp.get("solid", solid);
37   lisp.get("physic-enabled", physic_enabled);
38   lisp.get("visible", visible);
39   lisp.get("layer", layer);
40   if(solid)
41     flags |= FLAG_SOLID;
42 }
43
44 ScriptedObject::~ScriptedObject()
45 {
46   delete sprite;
47 }
48
49 void
50 ScriptedObject::expose(HSQUIRRELVM vm, int table_idx)
51 {
52   Scripting::ScriptedObject* interface = static_cast<Scripting::ScriptedObject*> (this);
53   expose_object(vm, table_idx, interface, name, false);
54 }
55
56 void
57 ScriptedObject::unexpose(HSQUIRRELVM vm, int table_idx)
58 {
59   Scripting::unexpose_object(vm, table_idx, name);
60 }
61
62 void
63 ScriptedObject::move(float x, float y)
64 {
65   bbox.move(Vector(x, y));
66 }
67
68 void
69 ScriptedObject::set_pos(float x, float y)
70 {
71   bbox.set_pos(Vector(x, y));
72 }
73
74 float
75 ScriptedObject::get_pos_x()
76 {
77   return get_pos().x;
78 }
79
80 float
81 ScriptedObject::get_pos_y()
82 {
83   return get_pos().y;
84 }
85
86 void
87 ScriptedObject::set_velocity(float x, float y)
88 {
89   new_vel = Vector(x, y);
90   new_vel_set = true;
91 }
92
93 float
94 ScriptedObject::get_velocity_x()
95 {
96   return physic.get_velocity_x();
97 }
98
99 float
100 ScriptedObject::get_velocity_y()
101 {
102   return physic.get_velocity_y();
103 }
104
105 void
106 ScriptedObject::set_visible(bool visible)
107 {
108   this->visible = visible;
109 }
110
111 bool
112 ScriptedObject::is_visible()
113 {
114   return visible;
115 }
116
117 void
118 ScriptedObject::set_action(const std::string& animation)
119 {
120   sprite->set_action(animation);
121 }
122
123 std::string
124 ScriptedObject::get_action()
125 {
126   return sprite->get_action_name();
127 }
128
129 std::string
130 ScriptedObject::get_name()
131 {
132   return name;
133 }
134
135 void
136 ScriptedObject::update(float elapsed_time)
137 {
138   if(!physic_enabled)
139     return;
140
141   if(new_vel_set) {
142     physic.set_velocity(new_vel.x, new_vel.y);
143     new_vel_set = false;
144   }
145   movement = physic.get_movement(elapsed_time);
146 }
147
148 void
149 ScriptedObject::draw(DrawingContext& context)
150 {
151   if(!visible)
152     return;
153
154   sprite->draw(context, get_pos(), layer);
155 }
156
157 HitResponse
158 ScriptedObject::collision(GameObject& other, const CollisionHit& hit)
159 {
160   if(!physic_enabled)
161     return FORCE_MOVE;
162
163   if(!(other.get_flags() & FLAG_SOLID))
164     return FORCE_MOVE;
165
166   if(other.get_flags() & FLAG_SOLID) {
167     if(hit.normal.y < 0) { // landed on floor
168       if(physic.get_velocity_y() < 0)
169         physic.set_velocity_y(0);
170     } else if(hit.normal.y > 0) { // bumped against roof
171       physic.set_velocity_y(.1);
172     }
173
174     if(fabsf(hit.normal.x) > .9) { // hit on side?
175       physic.set_velocity_x(0);
176     }
177         
178     return CONTINUE;
179   }
180
181   return FORCE_MOVE;
182 }
183
184 IMPLEMENT_FACTORY(ScriptedObject, "scriptedobject");