Clean up the array copying for the new high scores list. It was way
[attac-man.git] / player.c
blob3f0791e0f17464ccaeb12900a4904d3df35b8d19
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: player.c,v 1.27 2003/11/30 17:43:55 nsubtil Exp $";
23 #ifdef _WIN32
24 #include <windows.h>
25 #endif
27 #include <GL/gl.h>
28 #include <GL/glu.h>
29 #include <SDL.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
34 #include "object.h"
35 #include "audio.h"
36 #include "m_math.h"
37 #include "gfx.h"
38 #include "game.h"
39 #include "map.h"
40 #include "screen.h"
41 #include "render.h"
42 #include "shot.h"
43 #include "bomb.h"
44 #include "input.h"
46 #include "player.h"
47 #include "ghost.h"
49 GLfloat pacman_colors[2][4] = {
50 {PACMAN_YELLOW}, {PACMAN_BLUE}
52 int num_pacman_colors = 2;
54 void player_reset(struct game *game)
56 if(game->players)
57 free(game->players);
59 game->players = NULL;
60 game->n_players = 0;
63 void player_add_new(struct game *game)
65 struct player *new;
67 game->players = realloc(game->players, sizeof(struct player) * (game->n_players + 1));
68 new = &game->players[game->n_players];
69 game->n_players++;
71 new->state = PLAYER_STATE_STOPPED;
72 new->pill_time = 0;
74 new->position[X] = 0.0;
75 new->position[Y] = -0.5;
76 new->position[Z] = 0.0;
78 new->direction = DIRECTION_UP;
80 /* XXX - tudo isto não é suposto */
81 new->model_moving = object_read_file("gfx/pacman-moving.3d", &new->frames_moving);
82 new->model_stopped = object_read_file("gfx/pacman-stopped.3d", &new->frames_stopped);
83 new->model_dying = object_read_file("gfx/pacman-dying.3d", &new->frames_dying);
84 new->model_won = object_read_file("gfx/pacman-jumping.3d", &new->frames_won);
86 new->current_frame = 0.0;
88 /* XXX - ugly ? UGLY! */
89 if(game->n_players == 1)
91 new->keys[KEY_UP] = SDLK_UP;
92 new->keys[KEY_DOWN] = SDLK_DOWN;
93 new->keys[KEY_LEFT] = SDLK_LEFT;
94 new->keys[KEY_RIGHT] = SDLK_RIGHT;
95 new->keys[KEY_FIRE] = SDLK_SPACE;
96 new->keys[KEY_BOMB] = SDLK_b;
97 } else {
98 new->keys[KEY_UP] = SDLK_w;
99 new->keys[KEY_DOWN] = SDLK_s;
100 new->keys[KEY_LEFT] = SDLK_a;
101 new->keys[KEY_RIGHT] = SDLK_d;
102 new->keys[KEY_FIRE] = SDLK_f;
103 new->keys[KEY_BOMB] = SDLK_g;
106 new->speed = 4.0;
107 new->lives = PLAYER_START_LIVES;
108 new->score = 0;
109 new->multiplier = 0;
111 new->color = pacman_colors[(game->n_players - 1) % num_pacman_colors];
112 new->camera = (struct camera *)malloc(sizeof(struct camera));
113 new->camera->type = CAMERA_TYPE_LOOSE_TRAIL;
116 void player_update(struct game *game, int player_no, float delta)
118 float new_position[3], vec[2];
119 float dest_x, dest_z, frac_x, frac_z;
120 int nx, ny;
121 int keep_moving = 0, verify = 0, update_map = 0;
122 struct player *p = &game->players[player_no];
123 struct map *map = game->map;
125 if(p->state == PLAYER_STATE_DEAD)
127 if(p->current_frame >= (float)(p->frames_dying - 1))
129 p->lives--;
131 if(p->lives != 0)
133 /* colocar no jogo */
134 p->state = PLAYER_STATE_STOPPED;
135 p->position[X] = p->start_position[X];
136 p->position[Y] = p->start_position[Y];
137 p->position[Z] = p->start_position[Z];
138 p->direction = DIRECTION_UP;
139 p->pill_time = 0.0;
140 p->speed = 4.0;
141 p->current_frame = 0.0;
144 return;
147 /* actualizar frames */
148 p->current_frame += delta * ANIM_FPS;
149 return;
152 new_position[X] = p->position[X];
153 new_position[Y] = p->position[Y];
154 new_position[Z] = p->position[Z];
156 if(p->state == PLAYER_STATE_MOVING)
158 frac_x = p->position[X] - (float)((int)p->position[X]);
159 frac_z = p->position[Z] - (float)((int)p->position[Z]);
161 dest_x = (int)p->position[X] + 0.5;
162 dest_z = (int)p->position[Z] + 0.5;
164 switch(p->direction)
166 case DIRECTION_UP:
167 new_position[Z] += MIN(delta * p->speed, 0.5);
169 if(frac_z > 0.5)
170 dest_z += 1.0;
172 if(input_kstate(p->keys[KEY_UP]))
173 keep_moving = 1;
175 if(new_position[Z] > dest_z)
177 update_map = 1;
179 if(keep_moving)
181 p->position[X] = new_position[X];
182 p->position[Z] = new_position[Z];
183 } else {
184 p->position[X] = dest_x;
185 p->position[Z] = dest_z;
186 p->state = PLAYER_STATE_STOPPED;
188 } else {
189 if(MAP_CAN_ENTER(map, (int)dest_x, (int)dest_z))
191 p->position[X] = new_position[X];
192 p->position[Z] = new_position[Z];
193 } else {
194 p->position[X] = dest_x;
195 p->position[Z] = dest_z - 1.0;
196 p->state = PLAYER_STATE_STOPPED;
200 break;
202 case DIRECTION_DOWN:
203 new_position[Z] -= MIN(delta * p->speed, 0.5);
205 if(frac_z < 0.5)
206 dest_z -= 1.0;
208 if(p->camera->type == CAMERA_TYPE_TOMB_RAIDER)
210 if(input_kstate(p->keys[KEY_UP]))
211 keep_moving = 1;
212 } else {
213 if(input_kstate(p->keys[KEY_DOWN]))
214 keep_moving = 1;
217 if(new_position[Z] < dest_z)
219 update_map = 1;
221 if(keep_moving)
223 p->position[X] = new_position[X];
224 p->position[Z] = new_position[Z];
225 } else {
226 p->position[X] = dest_x;
227 p->position[Z] = dest_z;
228 p->state = PLAYER_STATE_STOPPED;
230 } else {
231 if(MAP_CAN_ENTER(map, (int)dest_x, (int)dest_z))
233 p->position[X] = new_position[X];
234 p->position[Z] = new_position[Z];
235 } else {
236 p->position[X] = dest_x;
237 p->position[Z] = dest_z + 1.0;
238 p->state = PLAYER_STATE_STOPPED;
242 break;
244 case DIRECTION_LEFT:
245 new_position[X] -= MIN(delta * p->speed, 0.5);
247 if(frac_x < 0.5)
248 dest_x -= 1.0;
250 if(p->camera->type == CAMERA_TYPE_TOMB_RAIDER)
252 if(input_kstate(p->keys[KEY_UP]))
253 keep_moving = 1;
254 } else {
255 if(input_kstate(p->keys[KEY_LEFT]))
256 keep_moving = 1;
259 if(new_position[X] < dest_x)
261 update_map = 1;
263 if(keep_moving)
265 p->position[X] = new_position[X];
266 p->position[Z] = new_position[Z];
267 } else {
268 p->position[X] = dest_x;
269 p->position[Z] = dest_z;
270 p->state = PLAYER_STATE_STOPPED;
272 } else {
273 if(MAP_CAN_ENTER(map, (int)dest_x, (int)dest_z))
275 p->position[X] = new_position[X];
276 p->position[Z] = new_position[Z];
277 } else {
278 p->position[X] = dest_x + 1.0;
279 p->position[Z] = dest_z;
280 p->state = PLAYER_STATE_STOPPED;
284 break;
286 case DIRECTION_RIGHT:
287 new_position[X] += MIN(delta * p->speed, 0.5);
289 if(frac_x > 0.5)
290 dest_x += 1.0;
292 if(p->camera->type == CAMERA_TYPE_TOMB_RAIDER)
294 if(input_kstate(p->keys[KEY_UP]))
295 keep_moving = 1;
296 } else {
297 if(input_kstate(p->keys[KEY_RIGHT]))
298 keep_moving = 1;
301 if(new_position[X] > dest_x)
303 update_map = 1;
305 if(keep_moving)
307 p->position[X] = new_position[X];
308 p->position[Z] = new_position[Z];
309 } else {
310 p->position[X] = dest_x;
311 p->position[Z] = dest_z;
312 p->state = PLAYER_STATE_STOPPED;
314 } else {
315 if(MAP_CAN_ENTER(map, (int)dest_x, (int)dest_z))
317 p->position[X] = new_position[X];
318 p->position[Z] = new_position[Z];
319 } else {
320 p->position[X] = dest_x - 1.0;
321 p->position[Z] = dest_z;
322 p->state = PLAYER_STATE_STOPPED;
327 break;
331 /* mapa */
332 vec[X] = p->position[X] - (float)((int)p->position[X]) + 0.5;
333 vec[Y] = p->position[Z] - (float)((int)p->position[Z]) + 0.5;
335 if(update_map || math_norm_vec2(vec) < 0.1)
337 switch(MAP(map, (int)p->position[X], (int)p->position[Z]).content)
339 case MAP_CONTENT_FOOD:
340 if(MAP(map, (int)p->position[X], (int)p->position[Z]).c_data.food.status == FOOD_STATUS_ACTIVE)
342 MAP(map, (int)p->position[X], (int)p->position[Z]).c_data.food.status = FOOD_STATUS_EATEN;
343 audio_play_sample("sfx/chomp.wav");
345 p->score += 10;
346 break;
348 case MAP_CONTENT_PILL:
349 if(MAP(map, (int)p->position[X], (int)p->position[Z]).c_data.pill.status == PILL_STATUS_ACTIVE)
351 MAP(map, (int)p->position[X], (int)p->position[Z]).c_data.pill.status = PILL_STATUS_EATEN;
352 audio_play_sample("sfx/glomp.wav");
353 p->pill_time = 10.0;
354 p->score += 50;
355 if (p->multiplier == 0) {
356 /* 200 / 400 / 800 / 1600 */
357 p->multiplier = 2;
359 ghost_taint_all(game);
362 break;
364 case MAP_CONTENT_TELEPORT:
365 game_teleport_player(game, player_no);
366 break;
369 case '0':
370 if(p->direction == DIRECTION_LEFT)
371 game_teleport_player(p, MAP_POS(game_map, (int)p->position[X],
372 (int)p->position[Z]));
373 break;
375 case '1':
376 if(p->direction == DIRECTION_RIGHT)
377 game_teleport_player(p, MAP_POS(game_map, (int)p->position[X],
378 (int)p->position[Z]));
380 break;
385 /* teclas */
386 if(p->camera->type == CAMERA_TYPE_TOMB_RAIDER)
388 /* change direction */
389 switch(p->direction)
391 case DIRECTION_UP:
392 /* left turns pacman left */
393 if(input_kstate(p->keys[KEY_LEFT]))
395 p->direction = DIRECTION_LEFT;
396 p->state = PLAYER_STATE_STOPPED;
397 input_kclear(p->keys[KEY_LEFT]);
400 /* right turns pacman right */
401 if(input_kstate(p->keys[KEY_RIGHT]))
403 p->direction = DIRECTION_RIGHT;
404 p->state = PLAYER_STATE_STOPPED;
405 input_kclear(p->keys[KEY_RIGHT]);
408 /* down turns pacman down */
409 if(input_kstate(p->keys[KEY_DOWN]))
411 p->direction = DIRECTION_DOWN;
412 p->state = PLAYER_STATE_STOPPED;
413 input_kclear(p->keys[KEY_DOWN]);
416 break;
418 case DIRECTION_DOWN:
419 /* left turns pacman right */
420 if(input_kstate(p->keys[KEY_LEFT]))
422 p->direction = DIRECTION_RIGHT;
423 p->state = PLAYER_STATE_STOPPED;
424 input_kclear(p->keys[KEY_LEFT]);
427 /* right turns pacman left */
428 if(input_kstate(p->keys[KEY_RIGHT]))
430 p->direction = DIRECTION_LEFT;
431 p->state = PLAYER_STATE_STOPPED;
432 input_kclear(p->keys[KEY_RIGHT]);
435 /* down turns pacman up */
436 if(input_kstate(p->keys[KEY_DOWN]))
438 p->direction = DIRECTION_UP;
439 p->state = PLAYER_STATE_STOPPED;
440 input_kclear(p->keys[KEY_DOWN]);
443 break;
445 case DIRECTION_LEFT:
446 /* left turns pacman down */
447 if(input_kstate(p->keys[KEY_LEFT]))
449 p->direction = DIRECTION_DOWN;
450 p->state = PLAYER_STATE_STOPPED;
451 input_kclear(p->keys[KEY_LEFT]);
454 /* right turns pacman up */
455 if(input_kstate(p->keys[KEY_RIGHT]))
457 p->direction = DIRECTION_UP;
458 p->state = PLAYER_STATE_STOPPED;
459 input_kclear(p->keys[KEY_RIGHT]);
462 /* down turns pacman right */
463 if(input_kstate(p->keys[KEY_DOWN]))
465 p->direction = DIRECTION_RIGHT;
466 p->state = PLAYER_STATE_STOPPED;
467 input_kclear(p->keys[KEY_DOWN]);
470 break;
472 case DIRECTION_RIGHT:
473 /* left turns pacman up */
474 if(input_kstate(p->keys[KEY_LEFT]))
476 p->direction = DIRECTION_UP;
477 p->state = PLAYER_STATE_STOPPED;
478 input_kclear(p->keys[KEY_LEFT]);
481 /* right turns pacman down */
482 if(input_kstate(p->keys[KEY_RIGHT]))
484 p->direction = DIRECTION_DOWN;
485 p->state = PLAYER_STATE_STOPPED;
486 input_kclear(p->keys[KEY_RIGHT]);
489 /* down turns pacman left */
490 if(input_kstate(p->keys[KEY_DOWN]))
492 p->direction = DIRECTION_LEFT;
493 p->state = PLAYER_STATE_STOPPED;
494 input_kclear(p->keys[KEY_DOWN]);
497 break;
500 /* move */
501 switch(p->direction)
503 case DIRECTION_UP:
504 /* up moves pacman up */
505 if(input_kstate(p->keys[KEY_UP]))
507 p->direction = DIRECTION_UP;
508 if(p->state == PLAYER_STATE_STOPPED)
510 p->state = PLAYER_STATE_MOVING;
511 verify = 1;
515 break;
517 case DIRECTION_DOWN:
518 /* up moves pacman down */
519 if(input_kstate(p->keys[KEY_UP]))
521 p->direction = DIRECTION_DOWN;
522 if(p->state == PLAYER_STATE_STOPPED)
524 p->state = PLAYER_STATE_MOVING;
525 verify = 1;
529 break;
531 case DIRECTION_LEFT:
532 /* up moves pacman left */
533 if(input_kstate(p->keys[KEY_UP]))
535 p->direction = DIRECTION_LEFT;
536 if(p->state == PLAYER_STATE_STOPPED)
538 p->state = PLAYER_STATE_MOVING;
539 verify = 1;
543 break;
545 case DIRECTION_RIGHT:
546 /* up moves pacman right */
547 if(input_kstate(p->keys[KEY_UP]))
549 p->direction = DIRECTION_RIGHT;
550 if(p->state == PLAYER_STATE_STOPPED)
552 p->state = PLAYER_STATE_MOVING;
553 verify = 1;
557 break;
559 } else {
560 if(input_kstate(p->keys[KEY_UP]) &&
561 (p->state == PLAYER_STATE_STOPPED ||
562 p->direction == DIRECTION_DOWN))
564 p->direction = DIRECTION_UP;
565 p->state = PLAYER_STATE_MOVING;
566 verify = 1;
567 } else
568 if(input_kstate(p->keys[KEY_LEFT]) &&
569 (p->state == PLAYER_STATE_STOPPED ||
570 p->direction == DIRECTION_RIGHT))
572 p->direction = DIRECTION_LEFT;
573 p->state = PLAYER_STATE_MOVING;
574 verify = 1;
575 } else
576 if(input_kstate(p->keys[KEY_RIGHT]) &&
577 (p->state == PLAYER_STATE_STOPPED ||
578 p->direction == DIRECTION_LEFT))
580 p->direction = DIRECTION_RIGHT;
581 p->state = PLAYER_STATE_MOVING;
582 verify = 1;
583 } else
584 if(input_kstate(p->keys[KEY_DOWN]) &&
585 (p->state == PLAYER_STATE_STOPPED ||
586 p->direction == DIRECTION_UP))
588 p->direction = DIRECTION_DOWN;
589 p->state = PLAYER_STATE_MOVING;
590 verify = 1;
594 if(input_kstate(p->keys[KEY_FIRE]))
596 shot_new(game, player_no, SHOT_TYPE_ROCKET, p->speed);
597 input_kclear(p->keys[KEY_FIRE]);
600 if(input_kstate(p->keys[KEY_BOMB]))
602 if((MAP(game->map, (int)p->position[X], (int)p->position[Z]).flags &
603 MAP_FLAG_BOMB) == 0)
604 bomb_new(game, player_no, 4.0);
606 input_kclear(p->keys[KEY_BOMB]);
609 if(verify)
611 /* validar nova direcção */
612 nx = (int)p->position[X];
613 ny = (int)p->position[Z];
615 switch(p->direction)
617 case DIRECTION_UP:
618 ny++;
619 break;
621 case DIRECTION_DOWN:
622 ny--;
623 break;
625 case DIRECTION_LEFT:
626 nx--;
627 break;
629 case DIRECTION_RIGHT:
630 nx++;
631 break;
634 if(!MAP_CAN_ENTER(map, nx, ny))
635 p->state = PLAYER_STATE_STOPPED;
637 /* align pacman with tile center */
638 p->position[X] = (float)((int)p->position[X]) + 0.5;
639 p->position[Z] = (float)((int)p->position[Z]) + 0.5;
642 /* frame da animação */
643 switch(p->state)
645 case PLAYER_STATE_MOVING:
646 if(p->direction == DIRECTION_LEFT || p->direction == DIRECTION_RIGHT)
647 p->current_frame =
648 (p->position[X] - (float)((int)p->position[X])) *
649 p->frames_moving;
650 else
651 p->current_frame = (p->position[Z] - (float)((int)p->position[Z])) *
652 p->frames_moving;
654 break;
656 case PLAYER_STATE_STOPPED:
657 p->current_frame += delta * ANIM_FPS;
658 break;
661 /* pill time! */
662 if(p->pill_time != 0.0)
664 p->pill_time -= delta;
665 if(p->pill_time <= 0.0)
667 p->multiplier = 0;
668 p->pill_time = 0.0;
669 ghost_untaint_all(game);
674 void player_kill(struct game *game, int player_no)
676 struct player *player;
678 player = &game->players[player_no];
679 player->state = PLAYER_STATE_DEAD;
680 player->current_frame = 0.0;
681 audio_play_sample("sfx/pacman-die.wav");