New sound effects
[supertux.git] / src / badguy / livefire.cpp
1 //  SuperTux badguy - walking flame that glows
2 //  Copyright (C) 2013 LMH <lmh.0013@gmail.com>
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 #include "badguy/livefire.hpp"
18
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"
25
26 LiveFire::LiveFire(const Reader& reader) :
27   WalkingBadguy(reader, "images/creatures/livefire/livefire.sprite", "left", "right"),
28   lightsprite(SpriteManager::current()->create("images/objects/lightmap_light/lightmap_light-medium.sprite")),
29   death_sound("sounds/fall.wav"),
30   state(STATE_WALKING)
31 {
32   walk_speed = 80;
33   max_drop_height = 20;
34   lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
35   lightsprite->set_color(Color(1.0f, 0.9f, 0.8f));
36 }
37
38 void
39 LiveFire::collision_solid(const CollisionHit& hit)
40 {
41   if(state != STATE_WALKING) {
42     BadGuy::collision_solid(hit);
43     return;
44   }
45   WalkingBadguy::collision_solid(hit);
46 }
47
48 HitResponse
49 LiveFire::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
50 {
51   if(state != STATE_WALKING) {
52     return BadGuy::collision_badguy(badguy, hit);
53   }
54   return WalkingBadguy::collision_badguy(badguy, hit);
55 }
56
57 void
58 LiveFire::active_update(float elapsed_time) {
59
60   // Remove when extinguish animation is done
61   if((sprite->get_action() == "extinguish-left" || sprite->get_action() == "extinguish-right" )
62     && sprite->animation_done()) remove_me();
63
64   if(state == STATE_WALKING) {
65     WalkingBadguy::active_update(elapsed_time);
66     return;
67   }
68
69   if(state == STATE_SLEEPING && get_group() == COLGROUP_MOVING) {
70
71     Player* player = this->get_nearest_player();
72     if (player) {
73       Rectf mb = this->get_bbox();
74       Rectf pb = player->get_bbox();
75
76       bool inReach_left = (pb.p2.x >= mb.p2.x-((dir == LEFT) ? 256 : 0));
77       bool inReach_right = (pb.p1.x <= mb.p1.x+((dir == RIGHT) ? 256 : 0));
78       bool inReach_top = (pb.p2.y >= mb.p1.y);
79       bool inReach_bottom = (pb.p1.y <= mb.p2.y);
80
81       if (inReach_left && inReach_right && inReach_top && inReach_bottom) {
82         // wake up
83         sprite->set_action(dir == LEFT ? "waking-left" : "waking-right", 1);
84         state = STATE_WAKING;
85       }
86     }
87   }
88   else if(state == STATE_WAKING) {
89     if(sprite->animation_done()) {
90       // start walking
91       state = STATE_WALKING;
92       WalkingBadguy::initialize();
93     }
94   }
95
96   BadGuy::active_update(elapsed_time);
97 }
98
99 void
100 LiveFire::draw(DrawingContext& context)
101 {
102   //Draw the Sprite.
103   sprite->draw(context, get_pos(), LAYER_OBJECTS);
104   //Draw the light
105   context.push_target();
106   context.set_target(DrawingContext::LIGHTMAP);
107   lightsprite->draw(context, get_bbox().get_middle(), 0);
108   context.pop_target();
109 }
110
111 void
112 LiveFire::freeze()
113 {
114   // attempting to freeze a flame causes it to go out
115   death_sound = "sounds/sizzle.ogg";
116   kill_fall();
117 }
118
119 bool
120 LiveFire::is_freezable() const
121 {
122   return true;
123 }
124
125 bool
126 LiveFire::is_flammable() const
127 {
128   return false;
129 }
130
131 void
132 LiveFire::kill_fall()
133 {
134   SoundManager::current()->play(death_sound, get_pos());
135   // throw a puff of smoke
136   Vector ppos = bbox.get_middle();
137   Vector pspeed = Vector(0, -150);
138   Vector paccel = Vector(0,0);
139   Sector::current()->add_object(std::make_shared<SpriteParticle>("images/objects/particles/smoke.sprite",
140                                                                  "default", ppos, ANCHOR_MIDDLE,
141                                                                  pspeed, paccel,
142                                                                  LAYER_BACKGROUNDTILES+2));
143   // extinguish the flame
144   sprite->set_action(dir == LEFT ? "extinguish-left" : "extinguish-right", 1);
145   physic.set_velocity_y(0);
146   physic.set_acceleration_y(0);
147   physic.enable_gravity(false);
148   lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
149   lightsprite->set_color(Color(0.5f, 0.4f, 0.3f));
150   set_group(COLGROUP_DISABLED);
151
152   // start dead-script
153   run_dead_script();
154 }
155
156 /* The following defines a sleeping version */
157
158 LiveFireAsleep::LiveFireAsleep(const Reader& reader) :
159   LiveFire(reader)
160 {
161   state = STATE_SLEEPING;
162 }
163
164 void
165 LiveFireAsleep::initialize()
166 {
167   physic.set_velocity_x(0);
168   sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right");
169 }
170
171 /* The following defines a dormant version that never wakes */
172 LiveFireDormant::LiveFireDormant(const Reader& reader) :
173   LiveFire(reader)
174 {
175   walk_speed = 0;
176   state = STATE_DORMANT;
177 }
178
179 void
180 LiveFireDormant::initialize()
181 {
182   physic.set_velocity_x(0);
183   sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right");
184 }
185
186 /* EOF */