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 $";
49 GLfloat pacman_colors
[2][4] = {
50 {PACMAN_YELLOW
}, {PACMAN_BLUE
}
52 int num_pacman_colors
= 2;
54 void player_reset(struct game
*game
)
63 void player_add_new(struct game
*game
)
67 game
->players
= realloc(game
->players
, sizeof(struct player
) * (game
->n_players
+ 1));
68 new = &game
->players
[game
->n_players
];
71 new->state
= PLAYER_STATE_STOPPED
;
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
;
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
;
107 new->lives
= PLAYER_START_LIVES
;
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_dead(struct game
*game
, int player_no
, float delta
)
118 struct player
*p
= &game
->players
[player_no
];
120 if(p
->current_frame
>= (float)(p
->frames_dying
- 1)) {
124 /* colocar no jogo */
125 p
->state
= PLAYER_STATE_MOVING
;
126 p
->position
[X
] = p
->start_position
[X
];
127 p
->position
[Y
] = p
->start_position
[Y
];
128 p
->position
[Z
] = p
->start_position
[Z
];
129 p
->direction
= DIRECTION_LEFT
;
132 p
->current_frame
= 0.0;
137 /* actualizar frames */
138 p
->current_frame
+= delta
* ANIM_FPS
;
143 * In TOMB_RAIDER, the camera always follows behind the player. So, as long
144 * as the forward (up, in this case) key is depressed, keep going in the
147 #define LEFT (p->camera->type == CAMERA_TYPE_TOMB_RAIDER ? KEY_UP : KEY_LEFT)
148 #define RIGHT (p->camera->type == CAMERA_TYPE_TOMB_RAIDER ? KEY_UP : KEY_RIGHT)
150 #define DOWN (p->camera->type == CAMERA_TYPE_TOMB_RAIDER ? KEY_UP : KEY_DOWN)
152 * return 1 if we need to update the map
154 static int update_player_position(struct player
*p
, struct map
*map
, float delta
)
157 int dest_reached
= 0, keep_moving
= 0;
158 float dest_x
, dest_z
, frac_x
, frac_z
;
159 float new_position
[3];
160 /* x,z modifier, for lack of a better word. */
161 float x_mod
= 0.0, z_mod
= 0.0;
163 new_position
[X
] = p
->position
[X
];
164 new_position
[Y
] = p
->position
[Y
];
165 new_position
[Z
] = p
->position
[Z
];
167 if (p
->state
!= PLAYER_STATE_MOVING
)
170 frac_x
= p
->position
[X
] - (float)((int)p
->position
[X
]);
171 frac_z
= p
->position
[Z
] - (float)((int)p
->position
[Z
]);
173 dest_x
= (int)p
->position
[X
] + 0.5;
174 dest_z
= (int)p
->position
[Z
] + 0.5;
176 switch(p
->direction
) {
178 new_position
[Z
] += MIN(delta
* p
->speed
, 0.5);
181 dest_reached
= new_position
[Z
] > dest_z
;
184 keep_moving
= input_kstate(p
->keys
[UP
]);
187 new_position
[Z
] -= MIN(delta
* p
->speed
, 0.5);
190 dest_reached
= new_position
[Z
] < dest_z
;
193 keep_moving
= input_kstate(p
->keys
[DOWN
]);
196 new_position
[X
] -= MIN(delta
* p
->speed
, 0.5);
199 dest_reached
= new_position
[X
] < dest_x
;
202 keep_moving
= input_kstate(p
->keys
[LEFT
]);
204 case DIRECTION_RIGHT
:
205 new_position
[X
] += MIN(delta
* p
->speed
, 0.5);
208 dest_reached
= new_position
[X
] > dest_x
;
211 keep_moving
= input_kstate(p
->keys
[RIGHT
]);
221 p
->position
[X
] = new_position
[X
];
222 p
->position
[Z
] = new_position
[Z
];
224 p
->position
[X
] = dest_x
;
225 p
->position
[Z
] = dest_z
;
226 p
->state
= PLAYER_STATE_STOPPED
;
229 if(MAP_CAN_ENTER(map
,(int)dest_x
,(int)dest_z
)) {
230 p
->position
[X
] = new_position
[X
];
231 p
->position
[Z
] = new_position
[Z
];
233 p
->position
[X
] = dest_x
+ x_mod
;
234 p
->position
[Z
] = dest_z
+ z_mod
;
235 p
->state
= PLAYER_STATE_STOPPED
;
242 int food_status_active(struct map
*map
, struct player
*p
)
244 struct pacman_food
*food
;
246 food
= &MAP_FOOD(map
, (int)p
->position
[X
], (int)p
->position
[Z
]);
247 return food
->status
== FOOD_STATUS_ACTIVE
;
250 void eat_food(struct map
*map
, struct player
*p
)
252 struct pacman_food
*food
;
254 food
= &MAP_FOOD(map
, (int)p
->position
[X
], (int)p
->position
[Z
]);
255 food
->status
= FOOD_STATUS_EATEN
;
256 audio_play_sample("sfx/chomp.wav");
260 int pill_status_active(struct map
*map
, struct player
*p
)
262 struct pacman_pill
*pill
;
264 pill
= &MAP_PILL(map
, (int)p
->position
[X
], (int)p
->position
[Z
]);
265 return pill
->status
== PILL_STATUS_ACTIVE
;
268 void eat_pill(struct map
*map
, struct player
*p
)
270 struct pacman_pill
*pill
;
272 pill
= &MAP_PILL(map
, (int)p
->position
[X
], (int)p
->position
[Z
]);
273 pill
->status
= PILL_STATUS_EATEN
;
274 audio_play_sample("sfx/glomp.wav");
277 if (p
->multiplier
== 0) {
278 /* 200 / 400 / 800 / 1600 */
283 void player_update(struct game
*game
, int player_no
, float delta
)
287 int verify
= 0, update_map
= 0;
288 struct player
*p
= &game
->players
[player_no
];
289 struct map
*map
= game
->map
;
291 if(p
->state
== PLAYER_STATE_DEAD
) {
292 player_update_dead(game
, player_no
, delta
);
296 /* update p->position */
297 update_map
= update_player_position(p
, map
, delta
);
300 vec
[X
] = p
->position
[X
] - (float)((int)p
->position
[X
]) + 0.5;
301 vec
[Y
] = p
->position
[Z
] - (float)((int)p
->position
[Z
]) + 0.5;
303 if(update_map
|| math_norm_vec2(vec
) < 0.1) {
304 switch(MAP(map
, (int)p
->position
[X
], (int)p
->position
[Z
]).content
) {
305 case MAP_CONTENT_FOOD
:
306 if (food_status_active(map
, p
))
310 case MAP_CONTENT_PILL
:
311 if (pill_status_active(map
, p
)) {
313 ghost_taint_all(game
);
317 case MAP_CONTENT_TELEPORT
:
318 game_teleport_player(game
, player_no
);
324 if(p
->camera
->type
== CAMERA_TYPE_TOMB_RAIDER
) {
325 /* change direction */
329 /* left turns pacman left */
330 if(input_kstate(p
->keys
[KEY_LEFT
]))
332 p
->direction
= DIRECTION_LEFT
;
333 p
->state
= PLAYER_STATE_STOPPED
;
334 input_kclear(p
->keys
[KEY_LEFT
]);
337 /* right turns pacman right */
338 if(input_kstate(p
->keys
[KEY_RIGHT
]))
340 p
->direction
= DIRECTION_RIGHT
;
341 p
->state
= PLAYER_STATE_STOPPED
;
342 input_kclear(p
->keys
[KEY_RIGHT
]);
345 /* down turns pacman down */
346 if(input_kstate(p
->keys
[KEY_DOWN
]))
348 p
->direction
= DIRECTION_DOWN
;
349 p
->state
= PLAYER_STATE_STOPPED
;
350 input_kclear(p
->keys
[KEY_DOWN
]);
356 /* left turns pacman right */
357 if(input_kstate(p
->keys
[KEY_LEFT
]))
359 p
->direction
= DIRECTION_RIGHT
;
360 p
->state
= PLAYER_STATE_STOPPED
;
361 input_kclear(p
->keys
[KEY_LEFT
]);
364 /* right turns pacman left */
365 if(input_kstate(p
->keys
[KEY_RIGHT
]))
367 p
->direction
= DIRECTION_LEFT
;
368 p
->state
= PLAYER_STATE_STOPPED
;
369 input_kclear(p
->keys
[KEY_RIGHT
]);
372 /* down turns pacman up */
373 if(input_kstate(p
->keys
[KEY_DOWN
]))
375 p
->direction
= DIRECTION_UP
;
376 p
->state
= PLAYER_STATE_STOPPED
;
377 input_kclear(p
->keys
[KEY_DOWN
]);
383 /* left turns pacman down */
384 if(input_kstate(p
->keys
[KEY_LEFT
]))
386 p
->direction
= DIRECTION_DOWN
;
387 p
->state
= PLAYER_STATE_STOPPED
;
388 input_kclear(p
->keys
[KEY_LEFT
]);
391 /* right turns pacman up */
392 if(input_kstate(p
->keys
[KEY_RIGHT
]))
394 p
->direction
= DIRECTION_UP
;
395 p
->state
= PLAYER_STATE_STOPPED
;
396 input_kclear(p
->keys
[KEY_RIGHT
]);
399 /* down turns pacman right */
400 if(input_kstate(p
->keys
[KEY_DOWN
]))
402 p
->direction
= DIRECTION_RIGHT
;
403 p
->state
= PLAYER_STATE_STOPPED
;
404 input_kclear(p
->keys
[KEY_DOWN
]);
409 case DIRECTION_RIGHT
:
410 /* left turns pacman up */
411 if(input_kstate(p
->keys
[KEY_LEFT
]))
413 p
->direction
= DIRECTION_UP
;
414 p
->state
= PLAYER_STATE_STOPPED
;
415 input_kclear(p
->keys
[KEY_LEFT
]);
418 /* right turns pacman down */
419 if(input_kstate(p
->keys
[KEY_RIGHT
]))
421 p
->direction
= DIRECTION_DOWN
;
422 p
->state
= PLAYER_STATE_STOPPED
;
423 input_kclear(p
->keys
[KEY_RIGHT
]);
426 /* down turns pacman left */
427 if(input_kstate(p
->keys
[KEY_DOWN
]))
429 p
->direction
= DIRECTION_LEFT
;
430 p
->state
= PLAYER_STATE_STOPPED
;
431 input_kclear(p
->keys
[KEY_DOWN
]);
441 /* up moves pacman up */
442 if(input_kstate(p
->keys
[KEY_UP
]))
444 p
->direction
= DIRECTION_UP
;
445 if(p
->state
== PLAYER_STATE_STOPPED
)
447 p
->state
= PLAYER_STATE_MOVING
;
455 /* up moves pacman down */
456 if(input_kstate(p
->keys
[KEY_UP
]))
458 p
->direction
= DIRECTION_DOWN
;
459 if(p
->state
== PLAYER_STATE_STOPPED
)
461 p
->state
= PLAYER_STATE_MOVING
;
469 /* up moves pacman left */
470 if(input_kstate(p
->keys
[KEY_UP
]))
472 p
->direction
= DIRECTION_LEFT
;
473 if(p
->state
== PLAYER_STATE_STOPPED
)
475 p
->state
= PLAYER_STATE_MOVING
;
482 case DIRECTION_RIGHT
:
483 /* up moves pacman right */
484 if(input_kstate(p
->keys
[KEY_UP
]))
486 p
->direction
= DIRECTION_RIGHT
;
487 if(p
->state
== PLAYER_STATE_STOPPED
)
489 p
->state
= PLAYER_STATE_MOVING
;
497 if(input_kstate(p
->keys
[KEY_UP
]) &&
498 (p
->state
== PLAYER_STATE_STOPPED
||
499 p
->direction
== DIRECTION_DOWN
))
501 p
->direction
= DIRECTION_UP
;
502 p
->state
= PLAYER_STATE_MOVING
;
505 if(input_kstate(p
->keys
[KEY_LEFT
]) &&
506 (p
->state
== PLAYER_STATE_STOPPED
||
507 p
->direction
== DIRECTION_RIGHT
))
509 p
->direction
= DIRECTION_LEFT
;
510 p
->state
= PLAYER_STATE_MOVING
;
513 if(input_kstate(p
->keys
[KEY_RIGHT
]) &&
514 (p
->state
== PLAYER_STATE_STOPPED
||
515 p
->direction
== DIRECTION_LEFT
))
517 p
->direction
= DIRECTION_RIGHT
;
518 p
->state
= PLAYER_STATE_MOVING
;
521 if(input_kstate(p
->keys
[KEY_DOWN
]) &&
522 (p
->state
== PLAYER_STATE_STOPPED
||
523 p
->direction
== DIRECTION_UP
))
525 p
->direction
= DIRECTION_DOWN
;
526 p
->state
= PLAYER_STATE_MOVING
;
531 if(input_kstate(p
->keys
[KEY_FIRE
]))
533 shot_new(game
, player_no
, SHOT_TYPE_ROCKET
, p
->speed
);
534 input_kclear(p
->keys
[KEY_FIRE
]);
537 if(input_kstate(p
->keys
[KEY_BOMB
]))
539 if((MAP(game
->map
, (int)p
->position
[X
], (int)p
->position
[Z
]).flags
&
541 bomb_new(game
, player_no
, 4.0);
543 input_kclear(p
->keys
[KEY_BOMB
]);
548 /* validar nova direcção */
549 nx
= (int)p
->position
[X
];
550 ny
= (int)p
->position
[Z
];
566 case DIRECTION_RIGHT
:
571 if(!MAP_CAN_ENTER(map
, nx
, ny
))
572 p
->state
= PLAYER_STATE_STOPPED
;
574 /* align pacman with tile center */
575 p
->position
[X
] = (float)((int)p
->position
[X
]) + 0.5;
576 p
->position
[Z
] = (float)((int)p
->position
[Z
]) + 0.5;
579 /* frame da animação */
582 case PLAYER_STATE_MOVING
:
583 if(p
->direction
== DIRECTION_LEFT
|| p
->direction
== DIRECTION_RIGHT
)
585 (p
->position
[X
] - (float)((int)p
->position
[X
])) *
588 p
->current_frame
= (p
->position
[Z
] - (float)((int)p
->position
[Z
])) *
593 case PLAYER_STATE_STOPPED
:
594 p
->current_frame
+= delta
* ANIM_FPS
;
599 if(p
->pill_time
!= 0.0)
601 p
->pill_time
-= delta
;
602 if(p
->pill_time
<= 0.0)
606 ghost_untaint_all(game
);
611 void player_kill(struct game
*game
, int player_no
)
613 struct player
*player
;
615 player
= &game
->players
[player_no
];
616 player
->state
= PLAYER_STATE_DEAD
;
617 player
->current_frame
= 0.0;
618 audio_play_sample("sfx/pacman-die.wav");