fix cr/lfs and remove trailing whitespaces...
[supertux.git] / src / object / trampoline.cpp
1 //  $Id$
2 //
3 //  SuperTux - Trampoline
4 //  Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 #include <config.h>
21
22 #include "trampoline.hpp"
23 #include "object_factory.hpp"
24 #include "player.hpp"
25 #include "audio/sound_manager.hpp"
26 #include "sprite/sprite_manager.hpp"
27
28 /* Trampoline will accelerate player to to VY_INITIAL, if
29  * he jumps on it to VY_MIN. */
30 namespace {
31   const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
32   const float VY_MIN = -900; //negative, upwards
33   const float VY_INITIAL = -500;
34 }
35
36 Trampoline::Trampoline(const lisp::Lisp& lisp)
37         : MovingSprite(lisp, "images/objects/trampoline/trampoline.sprite" )
38 {
39   sound_manager->preload( TRAMPOLINE_SOUND );
40   flags |= FLAG_PORTABLE;
41   physic.set_velocity(0, 0);
42   physic.enable_gravity(true);
43   on_ground = false;
44
45   bool portable = true;
46   //Check if this trampoline is not portable
47   if( lisp.get( "portable", portable ) ){
48     if( !portable ){
49         flags ^= FLAG_PORTABLE;
50         //we need another sprite
51         sprite_name = "images/objects/trampoline/trampoline_fix.sprite";
52         sprite = sprite_manager->create( sprite_name );
53         sprite->set_action("normal");
54     }
55   }
56 }
57
58 void
59 Trampoline::update( float elapsed_time ){
60     if( !on_ground ){
61         movement = physic.get_movement(elapsed_time);
62     }
63     if(sprite->animation_done()) {
64       sprite->set_action("normal");
65     }
66 }
67
68 HitResponse
69 Trampoline::collision(GameObject& other, const CollisionHit& hit )
70 {
71   //Tramponine has to be on ground to work.
72   if( !on_ground ){
73       return FORCE_MOVE;
74   }
75   Player* player = dynamic_cast<Player*> (&other);
76   if ( player ) {
77     float vy = player->physic.get_velocity_y();
78     //player is falling down on trampoline
79     if(hit.top && vy > 0) {
80       if(player->get_controller()->hold(Controller::JUMP)) {
81         vy = VY_MIN;
82       } else {
83         vy = VY_INITIAL;
84       }
85       player->physic.set_velocity_y( vy );
86       sound_manager->play( TRAMPOLINE_SOUND );
87       sprite->set_action("swinging", 1);
88       return FORCE_MOVE;
89     }
90   }
91   //Fake being solid for moving_object.
92   MovingObject* moving_object = dynamic_cast<MovingObject*> (&other);
93   if( moving_object ){
94       if( hit.top ){
95         float inside = moving_object->get_bbox().get_bottom() - get_bbox().get_top();
96         if( inside > 0 ){
97           Vector pos = moving_object->get_pos();
98           pos.y -= inside;
99           moving_object->set_pos( pos );
100         }
101       }
102       CollisionHit hit_other = hit;
103       std::swap(hit_other.left, hit_other.right);
104       std::swap(hit_other.top, hit_other.bottom);
105       moving_object->collision_solid( hit_other );
106   }
107   return FORCE_MOVE;
108 }
109
110 void
111 Trampoline::collision_solid( const CollisionHit& hit ){
112   if( hit.bottom ){
113      on_ground = true;
114   }
115 }
116
117 void
118 Trampoline::grab( MovingObject&, const Vector& pos, Direction ){
119   movement = pos - get_pos();
120   set_group( COLGROUP_DISABLED );
121   on_ground = true;
122   sprite->set_animation_loops( 0 );
123 }
124
125 void
126 Trampoline::ungrab(MovingObject& , Direction ){
127   set_group( COLGROUP_MOVING );
128   on_ground = false;
129   physic.set_velocity(0, 0);
130 }
131
132
133 IMPLEMENT_FACTORY(Trampoline, "trampoline");