1 // SuperTux badguy - walking flame that glows
2 // Copyright (C) 2013 LMH <lmh.0013@gmail.com>
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.
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.
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/>.
17 #include "badguy/walkingflame.hpp"
19 #include "audio/sound_manager.hpp"
20 #include "object/player.hpp"
21 #include "object/sprite_particle.hpp"
22 #include "sprite/sprite.hpp"
23 #include "supertux/object_factory.hpp"
24 #include "supertux/sector.hpp"
26 static const float WALKSPEED = 80;
27 static const float MAXDROPHEIGHT = 20;
29 WalkingFlame::WalkingFlame(const Reader& reader) :
30 WalkingBadguy(reader, "images/creatures/walkingflame/walkingflame.sprite", "left", "right"),
31 lightsprite(sprite_manager->create("images/objects/lightmap_light/lightmap_light-medium.sprite"))
33 walk_speed = WALKSPEED;
34 max_drop_height = MAXDROPHEIGHT;
35 lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
36 lightsprite->set_color(Color(1.0f, 0.9f, 0.8f));
40 WalkingFlame::draw(DrawingContext& context)
43 sprite->draw(context, get_pos(), LAYER_OBJECTS);
45 context.push_target();
46 context.set_target(DrawingContext::LIGHTMAP);
47 lightsprite->draw(context, get_bbox().get_middle(), 0);
52 WalkingFlame::freeze()
54 // attempting to freeze a flame causes it to go out
59 WalkingFlame::is_freezable() const
65 WalkingFlame::is_flammable() const
71 WalkingFlame::kill_fall()
73 //TODO: get unique sound for ice-fire encounters
74 sound_manager->play("sounds/fall.wav", get_pos());
75 // throw a puff of smoke
76 Vector ppos = bbox.get_middle();
77 Vector pspeed = Vector(0, -150);
78 Vector paccel = Vector(0,0);
79 Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_BACKGROUNDTILES+2));
80 // extinguish the flame
81 sprite->set_action(dir == LEFT ? "extinguish-left" : "extinguish-right");
82 physic.set_velocity_y(0);
83 physic.set_acceleration_y(0);
84 physic.enable_gravity(false);
85 set_state(STATE_SQUISHED); // used to nullify any threat and remove
91 /* The following handles a sleeping version */
93 SWalkingFlame::SWalkingFlame(const Reader& reader) :
94 WalkingBadguy(reader, "images/creatures/walkingflame/walkingflame.sprite", "left", "right"), state(STATE_SLEEPING),
95 lightsprite(sprite_manager->create("images/objects/lightmap_light/lightmap_light-medium.sprite"))
97 walk_speed = WALKSPEED;
98 max_drop_height = MAXDROPHEIGHT;
99 lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
100 lightsprite->set_color(Color(1.0f, 0.9f, 0.8f));
104 SWalkingFlame::initialize()
106 state = STATE_SLEEPING;
107 physic.set_velocity_x(0);
108 sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right");
112 SWalkingFlame::collision_solid(const CollisionHit& hit)
114 if(state != STATE_WALKING) {
115 BadGuy::collision_solid(hit);
118 WalkingBadguy::collision_solid(hit);
122 SWalkingFlame::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
124 if(state != STATE_WALKING) {
125 return BadGuy::collision_badguy(badguy, hit);
127 return WalkingBadguy::collision_badguy(badguy, hit);
131 SWalkingFlame::active_update(float elapsed_time) {
133 if(state == STATE_WALKING) {
134 WalkingBadguy::active_update(elapsed_time);
138 if(state == STATE_SLEEPING) {
140 Player* player = this->get_nearest_player();
142 Rectf mb = this->get_bbox();
143 Rectf pb = player->get_bbox();
145 bool inReach_left = (pb.p2.x >= mb.p2.x-((dir == LEFT) ? 256 : 0));
146 bool inReach_right = (pb.p1.x <= mb.p1.x+((dir == RIGHT) ? 256 : 0));
147 bool inReach_top = (pb.p2.y >= mb.p1.y);
148 bool inReach_bottom = (pb.p1.y <= mb.p2.y);
150 if (inReach_left && inReach_right && inReach_top && inReach_bottom) {
152 sprite->set_action(dir == LEFT ? "waking-left" : "waking-right", 1);
153 state = STATE_WAKING;
157 BadGuy::active_update(elapsed_time);
160 if(state == STATE_WAKING) {
161 if(sprite->animation_done()) {
163 state = STATE_WALKING;
164 WalkingBadguy::initialize();
167 BadGuy::active_update(elapsed_time);
172 SWalkingFlame::draw(DrawingContext& context)
175 sprite->draw(context, get_pos(), LAYER_OBJECTS);
177 context.push_target();
178 context.set_target(DrawingContext::LIGHTMAP);
179 lightsprite->draw(context, get_bbox().get_middle(), 0);
180 context.pop_target();
184 SWalkingFlame::freeze()
186 // attempting to freeze a flame causes it to go out
191 SWalkingFlame::is_freezable() const
197 SWalkingFlame::is_flammable() const
203 SWalkingFlame::kill_fall()
205 //TODO: get unique sound for ice-fire encounters
206 sound_manager->play("sounds/fall.wav", get_pos());
207 // throw a puff of smoke
208 Vector ppos = bbox.get_middle();
209 Vector pspeed = Vector(0, -150);
210 Vector paccel = Vector(0,0);
211 Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_BACKGROUNDTILES+2));
212 // extinguish the flame
213 sprite->set_action(dir == LEFT ? "extinguish-left" : "extinguish-right");
214 physic.set_velocity_y(0);
215 physic.set_acceleration_y(0);
216 physic.enable_gravity(false);
217 set_state(STATE_SQUISHED); // used to nullify any threat and remove