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 | |
22 | static const float CHARGE_SPEED = 240; |
23 | |
24 | static const float CHARGE_TIME = .5; |
25 | static const float ATTACK_TIME = 1; |
26 | static const float RECOVER_TIME = .5; |
27 | |
28 | AngryStone::AngryStone(const ReaderMapping& reader) : |
29 | BadGuy(reader, "images/creatures/angrystone/angrystone.sprite" ), |
30 | attackDirection(), |
31 | oldWallDirection(), |
32 | timer(), |
33 | state(IDLE) |
34 | { |
35 | m_countMe = false; |
36 | m_physic.set_velocity_x(0); |
37 | m_physic.set_velocity_y(0); |
38 | m_physic.enable_gravity(true); |
39 | m_sprite->set_action("idle" ); |
40 | } |
41 | |
42 | void |
43 | AngryStone::collision_solid(const CollisionHit& /*hit*/) |
44 | { |
45 | // TODO |
46 | #if 0 |
47 | if ((state == ATTACKING) && |
48 | (hit.normal.x == -attackDirection.x) && (hit.normal.y == attackDirection.y)) { |
49 | state = IDLE; |
50 | sprite->set_action("idle" ); |
51 | physic.set_velocity_x(0); |
52 | physic.set_velocity_y(0); |
53 | physic.enable_gravity(true); |
54 | oldWallDirection.x = attackDirection.x; |
55 | oldWallDirection.y = attackDirection.y; |
56 | } |
57 | #endif |
58 | } |
59 | |
60 | void |
61 | AngryStone::kill_fall() |
62 | { |
63 | //prevents AngryStone from getting killed by other enemies or the player |
64 | } |
65 | |
66 | HitResponse |
67 | AngryStone::collision_badguy(BadGuy& badguy, const CollisionHit& ) |
68 | { |
69 | if (state == ATTACKING) { |
70 | badguy.kill_fall(); |
71 | return FORCE_MOVE; |
72 | } |
73 | |
74 | return FORCE_MOVE; |
75 | } |
76 | |
77 | void |
78 | AngryStone::active_update(float dt_sec) { |
79 | BadGuy::active_update(dt_sec); |
80 | |
81 | if (m_frozen) { |
82 | return; |
83 | } |
84 | |
85 | switch (state) { |
86 | |
87 | |
88 | case IDLE: { |
89 | auto player = get_nearest_player(); |
90 | if (player) { |
91 | auto badguy = this; |
92 | const Vector& playerPos = player->get_pos(); |
93 | const Vector& badguyPos = badguy->get_pos(); |
94 | float dx = (playerPos.x - badguyPos.x); |
95 | float dy = (playerPos.y - badguyPos.y); |
96 | |
97 | float playerHeight = player->get_bbox().get_height(); |
98 | float badguyHeight = badguy->get_bbox().get_height(); |
99 | |
100 | float playerWidth = player->get_bbox().get_width(); |
101 | float badguyWidth = badguy->get_bbox().get_width(); |
102 | |
103 | if ((dx > -playerWidth) && (dx < badguyWidth)) { |
104 | if (dy > 0) { |
105 | attackDirection.x = 0; |
106 | attackDirection.y = 1; |
107 | } else { |
108 | attackDirection.x = 0; |
109 | attackDirection.y = -1; |
110 | } |
111 | if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) { |
112 | m_sprite->set_action("charging" ); |
113 | timer.start(CHARGE_TIME); |
114 | state = CHARGING; |
115 | } |
116 | } else if ((dy > -playerHeight) && (dy < badguyHeight)) { |
117 | if (dx > 0) { |
118 | attackDirection.x = 1; |
119 | attackDirection.y = 0; |
120 | } else { |
121 | attackDirection.x = -1; |
122 | attackDirection.y = 0; |
123 | } |
124 | if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) { |
125 | m_sprite->set_action("charging" ); |
126 | timer.start(CHARGE_TIME); |
127 | state = CHARGING; |
128 | } |
129 | } |
130 | } |
131 | } break; |
132 | |
133 | case CHARGING: { |
134 | if (timer.check()) { |
135 | m_sprite->set_action("attacking" ); |
136 | timer.start(ATTACK_TIME); |
137 | state = ATTACKING; |
138 | m_physic.enable_gravity(false); |
139 | m_physic.set_velocity_x(CHARGE_SPEED * attackDirection.x); |
140 | m_physic.set_velocity_y(CHARGE_SPEED * attackDirection.y); |
141 | oldWallDirection.x = 0; |
142 | oldWallDirection.y = 0; |
143 | } |
144 | } break; |
145 | |
146 | case ATTACKING: { |
147 | if (timer.check()) { |
148 | timer.start(RECOVER_TIME); |
149 | state = RECOVERING; |
150 | m_sprite->set_action("idle" ); |
151 | m_physic.enable_gravity(true); |
152 | m_physic.set_velocity_x(0); |
153 | m_physic.set_velocity_y(0); |
154 | } |
155 | } break; |
156 | |
157 | case RECOVERING: { |
158 | if (timer.check()) { |
159 | state = IDLE; |
160 | m_sprite->set_action("idle" ); |
161 | m_physic.enable_gravity(true); |
162 | m_physic.set_velocity_x(0); |
163 | m_physic.set_velocity_y(0); |
164 | } |
165 | } break; |
166 | } |
167 | |
168 | } |
169 | |
170 | bool |
171 | AngryStone::is_freezable() const |
172 | { |
173 | return state != ATTACKING; |
174 | } |
175 | |
176 | bool |
177 | AngryStone::is_flammable() const |
178 | { |
179 | return false; |
180 | } |
181 | |
182 | /* EOF */ |
183 | |