console: Format tabs semi-intelligently
[attac-man.git] / bomb.c
blob6348ab3942e9f7d2b53c369250ccb891cde8b465
1 /*
2 Pacman Arena
3 Copyright (C) 2003 Nuno Subtil
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 static const char cvsid[] =
21 "$Id: bomb.c,v 1.6 2003/11/22 17:32:09 nsubtil Exp $";
23 #ifdef _WIN32
24 #include <windows.h>
25 #endif
27 #include <GL/gl.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
32 #include "game.h"
33 #include "player.h"
34 #include "ghost.h"
35 #include "map.h"
36 #include "render.h"
37 #include "m_math.h"
38 #include "object.h"
39 #include "particle.h"
40 #include "audio.h"
42 #include "bomb.h"
44 void bomb_new(struct game *game, int player_no, float radius)
46 struct bomb *new;
47 struct player *p;
49 game->bombs = realloc(game->bombs, sizeof(struct bomb) * (game->n_bombs + 1));
50 new = &game->bombs[game->n_bombs];
51 game->n_bombs++;
53 new->owner = player_no;
54 p = &game->players[player_no];
56 MAP(game->map, (int)p->position[X], (int)p->position[Z]).flags |= MAP_FLAG_BOMB;
57 MATH_COPY_VEC3(new->position, p->position);
59 new->time = 0.0;
60 new->countdown = 1.0;
61 new->state = BOMB_STATE_COUNTDOWN;
62 new->radius = radius;
64 new->trail_left = NULL;
65 new->trail_right = NULL;
66 new->trail_up = NULL;
67 new->trail_down = NULL;
68 new->explosion = NULL;
70 new->model = object_read_file("gfx/bomb.3d", &new->n_frames);
73 void bomb_explode(struct game *game, int bomb_no)
75 struct bomb *b;
76 float emission[3], speed[3];
77 float color[3] = { 1.0, 0.8, 0.7 };
79 b = &game->bombs[bomb_no];
81 /*
82 V0 = 2 * radius / BOMB_FLAME_TIME
83 a = -2 * radius / BOMB_FLAME_TIME^2
86 MATH_SET_VEC3(emission, -1.0, 0.0, 0.0);
87 MATH_SET_VEC3(speed, -2.0 * b->radius / BOMB_FLAME_TIME, 0.0, 0.0);
88 b->trail_left = particle_new_src(BOMB_PARTICLE_LIFE,
89 BOMB_PARTICLE_FADE,
90 BOMB_PARTICLE_RATE,
91 BOMB_PARTICLE_SIZE,
92 b->position,
93 emission,
94 speed,
95 BOMB_PARTICLE_SPREAD,
96 BOMB_PARTICLE_SPEED,
97 BOMB_PARTICLE_SPEED_SPREAD,
98 BOMB_PARTICLE_GRAVITY,
99 color);
101 MATH_SET_VEC3(emission, 1.0, 0.0, 0.0);
102 MATH_SET_VEC3(speed, 2.0 * b->radius / BOMB_FLAME_TIME, 0.0, 0.0);
103 b->trail_right = particle_new_src(BOMB_PARTICLE_LIFE,
104 BOMB_PARTICLE_FADE,
105 BOMB_PARTICLE_RATE,
106 BOMB_PARTICLE_SIZE,
107 b->position,
108 emission,
109 speed,
110 BOMB_PARTICLE_SPREAD,
111 BOMB_PARTICLE_SPEED,
112 BOMB_PARTICLE_SPEED_SPREAD,
113 BOMB_PARTICLE_GRAVITY,
114 color);
116 MATH_SET_VEC3(emission, 0.0, 0.0, 1.0);
117 MATH_SET_VEC3(speed, 0.0, 0.0, 2.0 * b->radius / BOMB_FLAME_TIME);
118 b->trail_up = particle_new_src(BOMB_PARTICLE_LIFE,
119 BOMB_PARTICLE_FADE,
120 BOMB_PARTICLE_RATE,
121 BOMB_PARTICLE_SIZE,
122 b->position,
123 emission,
124 speed,
125 BOMB_PARTICLE_SPREAD,
126 BOMB_PARTICLE_SPEED,
127 BOMB_PARTICLE_SPEED_SPREAD,
128 BOMB_PARTICLE_GRAVITY,
129 color);
131 MATH_SET_VEC3(emission, 0.0, 0.0, -1.0);
132 MATH_SET_VEC3(speed, 0.0, 0.0, -2.0 * b->radius / BOMB_FLAME_TIME);
133 b->trail_down = particle_new_src(BOMB_PARTICLE_LIFE,
134 BOMB_PARTICLE_FADE,
135 BOMB_PARTICLE_RATE,
136 BOMB_PARTICLE_SIZE,
137 b->position,
138 emission,
139 speed,
140 BOMB_PARTICLE_SPREAD,
141 BOMB_PARTICLE_SPEED,
142 BOMB_PARTICLE_SPEED_SPREAD,
143 BOMB_PARTICLE_GRAVITY,
144 color);
146 MATH_SET_VEC3(emission, 0.0, 0.0, 0.0);
147 MATH_SET_VEC3(speed, 0.0, 0.0, 0.0);
148 b->explosion = particle_new_src(0.5,
149 1.2,
150 0.0,
151 1.0,
152 b->position,
153 emission,
154 speed,
155 0.5,
156 0.02,
157 0.005,
158 0.05,
159 color);
160 particle_src_explode(b->explosion, 300, 10.0);
162 b->state = BOMB_STATE_EXPLOSION;
163 b->time = 0.0;
165 audio_play_sample("sfx/rocket-launch.wav");
166 audio_play_sample("sfx/explosion.wav");
169 void bomb_update(struct game *game, int bomb_no, float delta)
171 struct bomb *b;
172 int c;
174 b = &game->bombs[bomb_no];
176 switch(b->state)
178 case BOMB_STATE_COUNTDOWN:
179 b->time += delta;
180 if(b->time >= b->countdown)
182 float new_delta;
184 new_delta = b->time - b->countdown;
185 bomb_explode(game, bomb_no);
186 bomb_update(game, bomb_no, new_delta);
187 return;
190 break;
192 case BOMB_STATE_EXPLOSION:
194 V0 = 2 * radius / BOMB_FLAME_TIME
195 a = -2 * radius / BOMB_FLAME_TIME^2
197 V = V0 + a * t
200 b->time += delta;
202 particle_src_update(game, b->trail_left, delta);
203 math_len_vec3(b->trail_left->src_speed,
204 b->trail_left->src_speed,
205 2.0 * b->radius / BOMB_FLAME_TIME +
206 (-2.0 * b->radius / BOMB_FLAME_TIME_SQ) * b->time);
207 b->trail_left->speed = 0.0;
208 b->trail_left->particle_rate -= BOMB_PARTICLE_RATE / BOMB_FLAME_TIME * delta;
210 particle_src_update(game, b->trail_right, delta);
211 math_len_vec3(b->trail_right->src_speed,
212 b->trail_right->src_speed,
213 2.0 * b->radius / BOMB_FLAME_TIME +
214 (-2.0 * b->radius / BOMB_FLAME_TIME_SQ) * b->time);
215 b->trail_right->speed = 0.0;
216 b->trail_right->particle_rate -= BOMB_PARTICLE_RATE / BOMB_FLAME_TIME * delta;
218 particle_src_update(game, b->trail_up, delta);
219 math_len_vec3(b->trail_up->src_speed,
220 b->trail_up->src_speed,
221 2.0 * b->radius / BOMB_FLAME_TIME +
222 (-2.0 * b->radius / BOMB_FLAME_TIME_SQ) * b->time);
223 b->trail_up->speed = 0.0;
224 b->trail_up->particle_rate -= BOMB_PARTICLE_RATE / BOMB_FLAME_TIME * delta;
226 particle_src_update(game, b->trail_down, delta);
227 math_len_vec3(b->trail_down->src_speed,
228 b->trail_down->src_speed,
229 2.0 * b->radius / BOMB_FLAME_TIME +
230 (-2.0 * b->radius / BOMB_FLAME_TIME_SQ) * b->time);
231 b->trail_down->speed = 0.0;
232 b->trail_down->particle_rate -= BOMB_PARTICLE_RATE / BOMB_FLAME_TIME * delta;
234 particle_src_update(game, b->explosion, delta);
236 if(particle_src_all_dead(b->trail_left) &&
237 particle_src_all_dead(b->trail_right) &&
238 particle_src_all_dead(b->trail_up) &&
239 particle_src_all_dead(b->trail_down) &&
240 particle_src_all_dead(b->explosion))
242 bomb_remove(game, bomb_no);
243 return;
246 /* collisions with ghosts */
247 for(c = 0; c < game->n_ghosts; c++)
249 float vec[3];
251 math_sub_vec3(vec, game->ghosts[c].position, b->trail_left->position);
252 if(math_norm_vec3(vec) < 0.7)
254 /* hit ghost c */
255 if(game->ghosts[c].state == GHOST_STATE_ACTIVE)
257 ghost_kill(game, &game->ghosts[c]);
258 MATH_COPY_VEC3(b->trail_left->position,
259 game->ghosts[c].position);
263 math_sub_vec3(vec, game->ghosts[c].position, b->trail_right->position);
264 if(math_norm_vec3(vec) < 0.7)
266 /* hit ghost c */
267 if(game->ghosts[c].state == GHOST_STATE_ACTIVE)
269 ghost_kill(game, &game->ghosts[c]);
270 MATH_COPY_VEC3(b->trail_right->position,
271 game->ghosts[c].position);
275 math_sub_vec3(vec, game->ghosts[c].position, b->trail_up->position);
276 if(math_norm_vec3(vec) < 0.7)
278 /* hit ghost c */
279 if(game->ghosts[c].state == GHOST_STATE_ACTIVE)
281 ghost_kill(game, &game->ghosts[c]);
282 MATH_COPY_VEC3(b->trail_up->position,
283 game->ghosts[c].position);
287 math_sub_vec3(vec, game->ghosts[c].position, b->trail_down->position);
288 if(math_norm_vec3(vec) < 0.7)
290 /* hit ghost c */
291 if(game->ghosts[c].state == GHOST_STATE_ACTIVE)
293 ghost_kill(game, &game->ghosts[c]);
294 MATH_COPY_VEC3(b->trail_down->position,
295 game->ghosts[c].position);
300 break;
304 void bomb_remove(struct game *game, int bomb_no)
306 struct bomb *b;
308 b = &game->bombs[bomb_no];
310 MAP(game->map, (int)b->position[X], (int)b->position[Z]).flags &= ~MAP_FLAG_BOMB;
312 particle_free_src(b->trail_left);
313 particle_free_src(b->trail_right);
314 particle_free_src(b->trail_up);
315 particle_free_src(b->trail_down);
316 particle_free_src(b->explosion);
318 memmove(&game->bombs[bomb_no], &game->bombs[bomb_no + 1],
319 (game->n_bombs - bomb_no) * sizeof(struct bomb));
320 game->n_bombs--;
321 game->bombs = realloc(game->bombs, game->n_bombs * sizeof(struct bomb));