1 | // SuperTux - "Will-O-Wisp" Badguy |
2 | // Copyright (C) 2007 Matthias Braun |
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/treewillowisp.hpp" |
18 | |
19 | #include <math.h> |
20 | |
21 | #include "audio/sound_manager.hpp" |
22 | #include "audio/sound_source.hpp" |
23 | #include "badguy/ghosttree.hpp" |
24 | #include "math/util.hpp" |
25 | #include "object/lantern.hpp" |
26 | #include "object/player.hpp" |
27 | #include "sprite/sprite.hpp" |
28 | |
29 | static const std::string TREEWILLOSOUND = "sounds/willowisp.wav" ; |
30 | |
31 | TreeWillOWisp::TreeWillOWisp(GhostTree* tree_, const Vector& pos, |
32 | float radius_, float speed_) : |
33 | BadGuy(tree_->get_pos() + pos, "images/creatures/willowisp/willowisp.sprite" , |
34 | LAYER_OBJECTS - 20), |
35 | was_sucked(false), |
36 | mystate(STATE_DEFAULT), |
37 | color(), |
38 | angle(0), |
39 | radius(radius_), |
40 | speed(speed_), |
41 | sound_source(), |
42 | tree(tree_), |
43 | suck_target() |
44 | { |
45 | SoundManager::current()->preload(TREEWILLOSOUND); |
46 | set_colgroup_active(COLGROUP_MOVING); |
47 | } |
48 | |
49 | TreeWillOWisp::~TreeWillOWisp() |
50 | { |
51 | } |
52 | |
53 | void |
54 | TreeWillOWisp::activate() |
55 | { |
56 | sound_source = SoundManager::current()->create_sound_source(TREEWILLOSOUND); |
57 | sound_source->set_position(get_pos()); |
58 | sound_source->set_looping(true); |
59 | sound_source->set_gain(1.0f); |
60 | sound_source->set_reference_distance(32); |
61 | sound_source->play(); |
62 | } |
63 | |
64 | void |
65 | TreeWillOWisp::vanish() |
66 | { |
67 | mystate = STATE_VANISHING; |
68 | m_sprite->set_action("vanishing" , 1); |
69 | set_colgroup_active(COLGROUP_DISABLED); |
70 | } |
71 | |
72 | void |
73 | TreeWillOWisp::start_sucking(const Vector& suck_target_) |
74 | { |
75 | mystate = STATE_SUCKED; |
76 | suck_target = suck_target_; |
77 | was_sucked = true; |
78 | } |
79 | |
80 | HitResponse |
81 | TreeWillOWisp::collision_player(Player& player, const CollisionHit& hit) |
82 | { |
83 | //TODO: basically a no-op. Remove if this doesn't change. |
84 | return BadGuy::collision_player(player, hit); |
85 | } |
86 | |
87 | bool |
88 | TreeWillOWisp::collides(GameObject& other, const CollisionHit& ) const |
89 | { |
90 | auto lantern = dynamic_cast<Lantern*>(&other); |
91 | if (lantern && lantern->is_open()) |
92 | return true; |
93 | if (dynamic_cast<Player*>(&other)) |
94 | return true; |
95 | |
96 | return false; |
97 | } |
98 | |
99 | void |
100 | TreeWillOWisp::draw(DrawingContext& context) |
101 | { |
102 | m_sprite->draw(context.color(), get_pos(), m_layer); |
103 | m_sprite->draw(context.light(), get_pos(), m_layer); |
104 | } |
105 | |
106 | void |
107 | TreeWillOWisp::active_update(float dt_sec) |
108 | { |
109 | // remove TreeWillOWisp if it has completely vanished |
110 | if (mystate == STATE_VANISHING) { |
111 | if (m_sprite->animation_done()) { |
112 | remove_me(); |
113 | tree->willowisp_died(this); |
114 | } |
115 | return; |
116 | } |
117 | |
118 | if (mystate == STATE_SUCKED) { |
119 | Vector dir_ = suck_target - get_pos(); |
120 | if (dir_.norm() < 5) { |
121 | vanish(); |
122 | return; |
123 | } |
124 | Vector newpos = get_pos() + dir_ * dt_sec; |
125 | m_col.m_movement = newpos - get_pos(); |
126 | return; |
127 | } |
128 | |
129 | angle = fmodf(angle + dt_sec * speed, math::TAU); |
130 | Vector newpos(m_start_position + Vector(sinf(angle) * radius, 0)); |
131 | m_col.m_movement = newpos - get_pos(); |
132 | float sizemod = cosf(angle) * 0.8f; |
133 | /* TODO: modify sprite size */ |
134 | |
135 | sound_source->set_position(get_pos()); |
136 | |
137 | if (sizemod < 0) { |
138 | m_layer = LAYER_OBJECTS + 5; |
139 | } else { |
140 | m_layer = LAYER_OBJECTS - 20; |
141 | } |
142 | } |
143 | |
144 | void |
145 | TreeWillOWisp::set_color(const Color& color_) |
146 | { |
147 | color = color_; |
148 | m_sprite->set_color(color_); |
149 | } |
150 | |
151 | Color |
152 | TreeWillOWisp::get_color() const |
153 | { |
154 | return color; |
155 | } |
156 | |
157 | void TreeWillOWisp::stop_looping_sounds() |
158 | { |
159 | if (sound_source) { |
160 | sound_source->stop(); |
161 | } |
162 | } |
163 | |
164 | void TreeWillOWisp::play_looping_sounds() |
165 | { |
166 | if (sound_source) { |
167 | sound_source->play(); |
168 | } |
169 | } |
170 | |
171 | /* EOF */ |
172 | |