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 "editor/editor.hpp" |
21 | #include "object/player.hpp" |
22 | #include "object/sprite_particle.hpp" |
23 | #include "sprite/sprite.hpp" |
24 | #include "supertux/sector.hpp" |
25 | |
26 | LiveFire::LiveFire(const ReaderMapping& reader) : |
27 | WalkingBadguy(reader, "images/creatures/livefire/livefire.sprite" , "left" , "right" ), |
28 | death_sound("sounds/fall.wav" ), |
29 | state(STATE_WALKING) |
30 | { |
31 | walk_speed = 80; |
32 | max_drop_height = 20; |
33 | m_lightsprite->set_color(Color(1.0f, 1.0f, 1.0f)); |
34 | m_glowing = true; |
35 | } |
36 | |
37 | void |
38 | LiveFire::collision_solid(const CollisionHit& hit) |
39 | { |
40 | if (state != STATE_WALKING) { |
41 | BadGuy::collision_solid(hit); |
42 | return; |
43 | } |
44 | WalkingBadguy::collision_solid(hit); |
45 | } |
46 | |
47 | HitResponse |
48 | LiveFire::collision_badguy(BadGuy& badguy, const CollisionHit& hit) |
49 | { |
50 | if (state != STATE_WALKING) { |
51 | return BadGuy::collision_badguy(badguy, hit); |
52 | } |
53 | return WalkingBadguy::collision_badguy(badguy, hit); |
54 | } |
55 | |
56 | void |
57 | LiveFire::active_update(float dt_sec) { |
58 | |
59 | // Remove when extinguish animation is done |
60 | if ((m_sprite->get_action() == "extinguish-left" || m_sprite->get_action() == "extinguish-right" ) |
61 | && m_sprite->animation_done()) remove_me(); |
62 | |
63 | if (state == STATE_WALKING) { |
64 | WalkingBadguy::active_update(dt_sec); |
65 | return; |
66 | } |
67 | |
68 | if (state == STATE_SLEEPING && m_col.get_group() == COLGROUP_MOVING) { |
69 | |
70 | auto player = get_nearest_player(); |
71 | if (player) { |
72 | Rectf pb = player->get_bbox(); |
73 | |
74 | bool inReach_left = (pb.get_right() >= m_col.m_bbox.get_right()-((m_dir == Direction::LEFT) ? 256 : 0)); |
75 | bool inReach_right = (pb.get_left() <= m_col.m_bbox.get_left()+((m_dir == Direction::RIGHT) ? 256 : 0)); |
76 | bool inReach_top = (pb.get_bottom() >= m_col.m_bbox.get_top()); |
77 | bool inReach_bottom = (pb.get_top() <= m_col.m_bbox.get_bottom()); |
78 | |
79 | if (inReach_left && inReach_right && inReach_top && inReach_bottom) { |
80 | // wake up |
81 | m_sprite->set_action(m_dir == Direction::LEFT ? "waking-left" : "waking-right" , 1); |
82 | state = STATE_WAKING; |
83 | } |
84 | } |
85 | } |
86 | else if (state == STATE_WAKING) { |
87 | if (m_sprite->animation_done()) { |
88 | // start walking |
89 | state = STATE_WALKING; |
90 | WalkingBadguy::initialize(); |
91 | } |
92 | } |
93 | |
94 | BadGuy::active_update(dt_sec); |
95 | } |
96 | |
97 | void |
98 | LiveFire::freeze() |
99 | { |
100 | // attempting to freeze a flame causes it to go out |
101 | death_sound = "sounds/sizzle.ogg" ; |
102 | kill_fall(); |
103 | } |
104 | |
105 | bool |
106 | LiveFire::is_freezable() const |
107 | { |
108 | return true; |
109 | } |
110 | |
111 | bool |
112 | LiveFire::is_flammable() const |
113 | { |
114 | return false; |
115 | } |
116 | |
117 | void |
118 | LiveFire::kill_fall() |
119 | { |
120 | SoundManager::current()->play(death_sound, get_pos()); |
121 | // throw a puff of smoke |
122 | Vector ppos = m_col.m_bbox.get_middle(); |
123 | Vector pspeed = Vector(0, -150); |
124 | Vector paccel = Vector(0,0); |
125 | Sector::get().add<SpriteParticle>("images/objects/particles/smoke.sprite" , |
126 | "default" , ppos, ANCHOR_MIDDLE, |
127 | pspeed, paccel, |
128 | LAYER_BACKGROUNDTILES+2); |
129 | // extinguish the flame |
130 | m_sprite->set_action(m_dir == Direction::LEFT ? "extinguish-left" : "extinguish-right" , 1); |
131 | m_physic.set_velocity_y(0); |
132 | m_physic.set_acceleration_y(0); |
133 | m_physic.enable_gravity(false); |
134 | m_lightsprite->set_blend(Blend::ADD); |
135 | m_lightsprite->set_color(Color(1.0f, 0.9f, 0.8f)); |
136 | set_group(COLGROUP_DISABLED); |
137 | |
138 | // start dead-script |
139 | run_dead_script(); |
140 | } |
141 | |
142 | /* The following defines a sleeping version */ |
143 | |
144 | LiveFireAsleep::LiveFireAsleep(const ReaderMapping& reader) : |
145 | LiveFire(reader) |
146 | { |
147 | state = STATE_SLEEPING; |
148 | } |
149 | |
150 | void |
151 | LiveFireAsleep::draw(DrawingContext& context) |
152 | { |
153 | if (Editor::is_active()) { |
154 | m_sprite->set_action(m_dir == Direction::LEFT ? "sleeping-left" : "sleeping-right" ); |
155 | BadGuy::draw(context); |
156 | } else { |
157 | LiveFire::draw(context); |
158 | } |
159 | } |
160 | |
161 | void |
162 | LiveFireAsleep::initialize() |
163 | { |
164 | m_physic.set_velocity_x(0); |
165 | m_sprite->set_action(m_dir == Direction::LEFT ? "sleeping-left" : "sleeping-right" ); |
166 | } |
167 | |
168 | /* The following defines a dormant version that never wakes */ |
169 | LiveFireDormant::LiveFireDormant(const ReaderMapping& reader) : |
170 | LiveFire(reader) |
171 | { |
172 | walk_speed = 0; |
173 | state = STATE_DORMANT; |
174 | } |
175 | |
176 | void |
177 | LiveFireDormant::draw(DrawingContext& context) |
178 | { |
179 | if (Editor::is_active()) { |
180 | m_sprite->set_action(m_dir == Direction::LEFT ? "sleeping-left" : "sleeping-right" ); |
181 | BadGuy::draw(context); |
182 | } else { |
183 | LiveFire::draw(context); |
184 | } |
185 | } |
186 | |
187 | void |
188 | LiveFireDormant::initialize() |
189 | { |
190 | m_physic.set_velocity_x(0); |
191 | m_sprite->set_action(m_dir == Direction::LEFT ? "sleeping-left" : "sleeping-right" ); |
192 | } |
193 | |
194 | /* EOF */ |
195 | |