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. */
29namespace {
30const std::string BOUNCE_SOUND = "sounds/trampoline.wav";
31const float VY_TRIGGER = -900; //negative, upwards
32const float VY_BOUNCE = -500;
33}
34
35RustyTrampoline::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
45void
46RustyTrampoline::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
60ObjectSettings
61RustyTrampoline::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
73HitResponse
74RustyTrampoline::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
124void
125RustyTrampoline::collision_solid(const CollisionHit& hit) {
126 Rock::collision_solid(hit);
127}
128
129void
130RustyTrampoline::grab(MovingObject& object, const Vector& pos, Direction dir) {
131 Rock::grab(object, pos, dir);
132}
133
134void
135RustyTrampoline::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
141bool
142RustyTrampoline::is_portable() const
143{
144 return Rock::is_portable() && portable;
145}
146
147/* EOF */
148