1 // SuperTux - Rusty Trampoline
2 // Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
3 // Copyright (C) 2011 Jonas Kuemmerlin <rgcjonas@googlemail.com>
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 #include "object/rusty_trampoline.hpp"
19
20 #include "audio/sound_manager.hpp"
21 #include "badguy/walking_badguy.hpp"
22 #include "control/controller.hpp"
23 #include "object/player.hpp"
24 #include "sprite/sprite.hpp"
25 #include "util/reader_mapping.hpp"
26
27 /* Trampoline will accelerate Tux to to VY_BOUNCE, if
28 * he jumps on it to VY_TRIGGER. */
29 namespace {
30 const std::string BOUNCE_SOUND = "sounds/trampoline.wav";
31 const float VY_TRIGGER = -900; //negative, upwards
32 const float VY_BOUNCE = -500;
33 }
34
RustyTrampoline(const ReaderMapping & mapping)35 RustyTrampoline::RustyTrampoline(const ReaderMapping& mapping) :
36 Rock(mapping, "images/objects/rusty-trampoline/rusty-trampoline.sprite"),
37 portable(true), counter(3)
38 {
39 SoundManager::current()->preload(BOUNCE_SOUND);
40
41 mapping.get("counter", counter);
42 mapping.get("portable", portable); //do we really need this?
43 }
44
45 void
update(float dt_sec)46 RustyTrampoline::update(float dt_sec)
47 {
48 if (m_sprite->animation_done()) {
49 if (counter < 1) {
50 remove_me();
51 } else {
52 m_sprite->set_action("normal");
53 }
54
55 }
56
57 Rock::update(dt_sec);
58 }
59
60 ObjectSettings
get_settings()61 RustyTrampoline::get_settings()
62 {
63 ObjectSettings result = Rock::get_settings();
64
65 result.add_int(_("Counter"), &counter, "counter", 3);
66 result.add_bool(_("Portable"), &portable, "portable", true);
67
68 result.reorder({"counter", "x", "y"});
69
70 return result;
71 }
72
73 HitResponse
collision(GameObject & other,const CollisionHit & hit)74 RustyTrampoline::collision(GameObject& other, const CollisionHit& hit)
75 {
76 //Trampoline has to be on ground to work.
77 if (on_ground) {
78 auto player = dynamic_cast<Player*> (&other);
79 //Trampoline works for player
80 if (player) {
81 float vy = player->get_physic().get_velocity_y();
82 //player is falling down on trampoline
83 if (hit.top && vy >= 0) {
84 if (player->get_controller().hold(Control::JUMP)) {
85 vy = VY_TRIGGER;
86 } else {
87 vy = VY_BOUNCE;
88 }
89 player->get_physic().set_velocity_y(vy);
90 SoundManager::current()->play(BOUNCE_SOUND);
91 counter--;
92 if (counter > 0) {
93 m_sprite->set_action("swinging", 1);
94 } else {
95 m_sprite->set_action("breaking", 1);
96 }
97
98 return FORCE_MOVE;
99 }
100 }
101 auto walking_badguy = dynamic_cast<WalkingBadguy*> (&other);
102 //Trampoline also works for WalkingBadguy
103 if (walking_badguy) {
104 float vy = walking_badguy->get_velocity_y();
105 //walking_badguy is falling down on trampoline
106 if (hit.top && vy >= 0) {
107 vy = VY_BOUNCE;
108 walking_badguy->set_velocity_y(vy);
109 SoundManager::current()->play(BOUNCE_SOUND);
110 counter--;
111 if (counter > 0) {
112 m_sprite->set_action("swinging", 1);
113 } else {
114 m_sprite->set_action("breaking", 1);
115 }
116 return FORCE_MOVE;
117 }
118 }
119 }
120
121 return Rock::collision(other, hit);
122 }
123
124 void
collision_solid(const CollisionHit & hit)125 RustyTrampoline::collision_solid(const CollisionHit& hit) {
126 Rock::collision_solid(hit);
127 }
128
129 void
grab(MovingObject & object,const Vector & pos,Direction dir)130 RustyTrampoline::grab(MovingObject& object, const Vector& pos, Direction dir) {
131 Rock::grab(object, pos, dir);
132 }
133
134 void
ungrab(MovingObject & object,Direction dir)135 RustyTrampoline::ungrab(MovingObject& object, Direction dir) {
136 Rock::ungrab(object, dir);
137 m_sprite->set_action("breaking", 1);
138 counter = 0; //remove in update()
139 }
140
141 bool
is_portable() const142 RustyTrampoline::is_portable() const
143 {
144 return Rock::is_portable() && portable;
145 }
146
147 /* EOF */
148