1// SuperTux
2// Copyright (C) 2010 Florian Forster <supertux at octo.it>
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/skydive.hpp"
18
19#include "object/explosion.hpp"
20#include "object/player.hpp"
21#include "supertux/constants.hpp"
22#include "supertux/sector.hpp"
23#include "supertux/tile.hpp"
24
25SkyDive::SkyDive(const ReaderMapping& reader) :
26 BadGuy(reader, "images/creatures/skydive/skydive.sprite")
27{
28}
29
30void
31SkyDive::collision_solid(const CollisionHit& hit)
32{
33 if (hit.bottom) {
34 explode ();
35 return;
36 }
37
38 if (hit.left || hit.right)
39 m_physic.set_velocity_x (0.0);
40}
41
42HitResponse
43SkyDive::collision_badguy(BadGuy&, const CollisionHit& hit)
44{
45 if (hit.bottom) {
46 explode();
47 return ABORT_MOVE;
48 }
49
50 return FORCE_MOVE;
51}
52
53void
54SkyDive::grab(MovingObject& object, const Vector& pos, Direction dir_)
55{
56 Portable::grab(object, pos, dir_);
57 m_col.m_movement = pos - get_pos();
58 m_dir = dir_;
59
60 m_physic.set_velocity_x(m_col.m_movement.x * LOGICAL_FPS);
61 m_physic.set_velocity_y(0.0);
62 m_physic.set_acceleration_y(0.0);
63 m_physic.enable_gravity(false);
64 set_colgroup_active(COLGROUP_DISABLED);
65}
66
67void
68SkyDive::ungrab(MovingObject& object, Direction dir_)
69{
70 m_physic.set_velocity_y(0);
71 m_physic.set_acceleration_y(0);
72 m_physic.enable_gravity(true);
73 set_colgroup_active(COLGROUP_MOVING);
74 Portable::ungrab(object, dir_);
75}
76
77HitResponse
78SkyDive::collision_player(Player&, const CollisionHit& hit)
79{
80 if (hit.bottom) {
81 explode();
82 return ABORT_MOVE;
83 }
84
85 return FORCE_MOVE;
86}
87
88bool
89SkyDive::collision_squished(GameObject& obj)
90{
91 auto player = dynamic_cast<Player *>(&obj);
92 if (player) {
93 player->bounce(*this);
94 return false;
95 }
96
97 explode();
98 return false;
99}
100
101void
102SkyDive::collision_tile(uint32_t tile_attributes)
103{
104 if (tile_attributes & Tile::HURTS)
105 {
106 explode();
107 }
108}
109
110void
111SkyDive::active_update(float dt_sec)
112{
113 if (!is_grabbed())
114 m_col.m_movement = m_physic.get_movement(dt_sec);
115}
116
117void
118SkyDive::explode()
119{
120 if (!is_valid())
121 return;
122
123 auto& explosion = Sector::get().add<Explosion>(get_anchor_pos(m_col.m_bbox, ANCHOR_BOTTOM));
124
125 explosion.hurts(true);
126 explosion.pushes(false);
127
128 remove_me();
129}
130
131/* EOF */
132