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(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
;
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))
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
;
141 p
->current_frame
= 0.0;
147 /* actualizar frames */
148 p
->current_frame
+= delta
* ANIM_FPS
;
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;
167 new_position
[Z
] += MIN(delta
* p
->speed
, 0.5);
172 if(input_kstate(p
->keys
[KEY_UP
]))
175 if(new_position
[Z
] > dest_z
)
181 p
->position
[X
] = new_position
[X
];
182 p
->position
[Z
] = new_position
[Z
];
184 p
->position
[X
] = dest_x
;
185 p
->position
[Z
] = dest_z
;
186 p
->state
= PLAYER_STATE_STOPPED
;
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
];
194 p
->position
[X
] = dest_x
;
195 p
->position
[Z
] = dest_z
- 1.0;
196 p
->state
= PLAYER_STATE_STOPPED
;
203 new_position
[Z
] -= MIN(delta
* p
->speed
, 0.5);
208 if(p
->camera
->type
== CAMERA_TYPE_TOMB_RAIDER
)
210 if(input_kstate(p
->keys
[KEY_UP
]))
213 if(input_kstate(p
->keys
[KEY_DOWN
]))
217 if(new_position
[Z
] < dest_z
)
223 p
->position
[X
] = new_position
[X
];
224 p
->position
[Z
] = new_position
[Z
];
226 p
->position
[X
] = dest_x
;
227 p
->position
[Z
] = dest_z
;
228 p
->state
= PLAYER_STATE_STOPPED
;
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
];
236 p
->position
[X
] = dest_x
;
237 p
->position
[Z
] = dest_z
+ 1.0;
238 p
->state
= PLAYER_STATE_STOPPED
;
245 new_position
[X
] -= MIN(delta
* p
->speed
, 0.5);
250 if(p
->camera
->type
== CAMERA_TYPE_TOMB_RAIDER
)
252 if(input_kstate(p
->keys
[KEY_UP
]))
255 if(input_kstate(p
->keys
[KEY_LEFT
]))
259 if(new_position
[X
] < dest_x
)
265 p
->position
[X
] = new_position
[X
];
266 p
->position
[Z
] = new_position
[Z
];
268 p
->position
[X
] = dest_x
;
269 p
->position
[Z
] = dest_z
;
270 p
->state
= PLAYER_STATE_STOPPED
;
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
];
278 p
->position
[X
] = dest_x
+ 1.0;
279 p
->position
[Z
] = dest_z
;
280 p
->state
= PLAYER_STATE_STOPPED
;
286 case DIRECTION_RIGHT
:
287 new_position
[X
] += MIN(delta
* p
->speed
, 0.5);
292 if(p
->camera
->type
== CAMERA_TYPE_TOMB_RAIDER
)
294 if(input_kstate(p
->keys
[KEY_UP
]))
297 if(input_kstate(p
->keys
[KEY_RIGHT
]))
301 if(new_position
[X
] > dest_x
)
307 p
->position
[X
] = new_position
[X
];
308 p
->position
[Z
] = new_position
[Z
];
310 p
->position
[X
] = dest_x
;
311 p
->position
[Z
] = dest_z
;
312 p
->state
= PLAYER_STATE_STOPPED
;
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
];
320 p
->position
[X
] = dest_x
- 1.0;
321 p
->position
[Z
] = dest_z
;
322 p
->state
= PLAYER_STATE_STOPPED
;
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");
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");
355 if (p
->multiplier
== 0) {
356 /* 200 / 400 / 800 / 1600 */
359 ghost_taint_all(game
);
364 case MAP_CONTENT_TELEPORT
:
365 game_teleport_player(game
, player_no
);
370 if(p->direction == DIRECTION_LEFT)
371 game_teleport_player(p, MAP_POS(game_map, (int)p->position[X],
372 (int)p->position[Z]));
376 if(p->direction == DIRECTION_RIGHT)
377 game_teleport_player(p, MAP_POS(game_map, (int)p->position[X],
378 (int)p->position[Z]));
386 if(p
->camera
->type
== CAMERA_TYPE_TOMB_RAIDER
)
388 /* change direction */
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
]);
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
]);
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
]);
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
]);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
&
604 bomb_new(game
, player_no
, 4.0);
606 input_kclear(p
->keys
[KEY_BOMB
]);
611 /* validar nova direcção */
612 nx
= (int)p
->position
[X
];
613 ny
= (int)p
->position
[Z
];
629 case DIRECTION_RIGHT
:
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 */
645 case PLAYER_STATE_MOVING
:
646 if(p
->direction
== DIRECTION_LEFT
|| p
->direction
== DIRECTION_RIGHT
)
648 (p
->position
[X
] - (float)((int)p
->position
[X
])) *
651 p
->current_frame
= (p
->position
[Z
] - (float)((int)p
->position
[Z
])) *
656 case PLAYER_STATE_STOPPED
:
657 p
->current_frame
+= delta
* ANIM_FPS
;
662 if(p
->pill_time
!= 0.0)
664 p
->pill_time
-= delta
;
665 if(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");