New sound effects
[supertux.git] / src / badguy / angrystone.cpp
1 //  AngryStone - A spiked block that charges towards the player
2 //  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
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/angrystone.hpp"
18
19 #include "object/player.hpp"
20 #include "sprite/sprite.hpp"
21 #include "supertux/object_factory.hpp"
22
23 static const float CHARGE_SPEED = 240;
24
25 static const float CHARGE_TIME = .5;
26 static const float ATTACK_TIME = 1;
27 static const float RECOVER_TIME = .5;
28
29 AngryStone::AngryStone(const Reader& reader) :
30   BadGuy(reader, "images/creatures/angrystone/angrystone.sprite"),
31   attackDirection(),
32   oldWallDirection(),
33   timer(),
34   state(IDLE)
35 {
36   countMe = false;
37   physic.set_velocity_x(0);
38   physic.set_velocity_y(0);
39   physic.enable_gravity(true);
40   sprite->set_action("idle");
41 }
42
43 void
44 AngryStone::collision_solid(const CollisionHit& hit)
45 {
46   // TODO
47   (void) hit;
48 #if 0
49   if ((state == ATTACKING) &&
50       (hit.normal.x == -attackDirection.x) && (hit.normal.y == attackDirection.y)) {
51     state = IDLE;
52     sprite->set_action("idle");
53     physic.set_velocity_x(0);
54     physic.set_velocity_y(0);
55     physic.enable_gravity(true);
56     oldWallDirection.x = attackDirection.x;
57     oldWallDirection.y = attackDirection.y;
58   }
59 #endif
60 }
61
62 void
63 AngryStone::kill_fall()
64 {
65   //prevents AngryStone from getting killed by other enemies or the player
66 }
67
68 HitResponse
69 AngryStone::collision_badguy(BadGuy& badguy, const CollisionHit& )
70 {
71   if (state == ATTACKING) {
72     badguy.kill_fall();
73     return FORCE_MOVE;
74   }
75
76   return FORCE_MOVE;
77 }
78
79 void
80 AngryStone::active_update(float elapsed_time) {
81   BadGuy::active_update(elapsed_time);
82
83   if (state == IDLE) {
84     MovingObject* player = this->get_nearest_player();
85     if(player) {
86       MovingObject* badguy = this;
87       const Vector playerPos = player->get_pos();
88       const Vector badguyPos = badguy->get_pos();
89       float dx = (playerPos.x - badguyPos.x);
90       float dy = (playerPos.y - badguyPos.y);
91
92       float playerHeight = player->get_bbox().p2.y - player->get_bbox().p1.y;
93       float badguyHeight = badguy->get_bbox().p2.y - badguy->get_bbox().p1.y;
94
95       float playerWidth = player->get_bbox().p2.x - player->get_bbox().p1.x;
96       float badguyWidth = badguy->get_bbox().p2.x - badguy->get_bbox().p1.x;
97
98       if ((dx > -playerWidth) && (dx < badguyWidth)) {
99         if (dy > 0) {
100           attackDirection.x = 0;
101           attackDirection.y = 1;
102         } else {
103           attackDirection.x = 0;
104           attackDirection.y = -1;
105         }
106         if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
107           sprite->set_action("charging");
108           timer.start(CHARGE_TIME);
109           state = CHARGING;
110         }
111       } else
112         if ((dy > -playerHeight) && (dy < badguyHeight)) {
113           if (dx > 0) {
114             attackDirection.x = 1;
115             attackDirection.y = 0;
116           } else {
117             attackDirection.x = -1;
118             attackDirection.y = 0;
119           }
120           if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
121             sprite->set_action("charging");
122             timer.start(CHARGE_TIME);
123             state = CHARGING;
124           }
125         }
126
127     }
128   }
129
130   if (state == CHARGING) {
131     if (timer.check()) {
132       sprite->set_action("attacking");
133       timer.start(ATTACK_TIME);
134       state = ATTACKING;
135       physic.enable_gravity(false);
136       physic.set_velocity_x(CHARGE_SPEED * attackDirection.x);
137       physic.set_velocity_y(CHARGE_SPEED * attackDirection.y);
138       oldWallDirection.x = 0;
139       oldWallDirection.y = 0;
140     }
141   }
142
143   if (state == ATTACKING) {
144     if (timer.check()) {
145       timer.start(RECOVER_TIME);
146       state = RECOVERING;
147       sprite->set_action("idle");
148       physic.enable_gravity(true);
149       physic.set_velocity_x(0);
150       physic.set_velocity_y(0);
151     }
152   }
153
154   if (state == RECOVERING) {
155     if (timer.check()) {
156       state = IDLE;
157       sprite->set_action("idle");
158       physic.enable_gravity(true);
159       physic.set_velocity_x(0);
160       physic.set_velocity_y(0);
161     }
162   }
163
164 }
165
166 /* EOF */