Bibi/src/monsters.c

353 lines
6.7 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "SDL.h"
#include "SDL_image.h"
#include "../include/game.h"
struct s_monster {
int x,y,portee_monstre;
SDL_Surface * directed_img[4];
enum e_way current_way;
t_monster nxt;
};
static void monster_load_img(t_monster monster, enum e_way way,
const char *filename) {
monster->directed_img[way] = IMG_Load(filename);
if (!monster->directed_img[way])
error("IMG_Load: %s\n", IMG_GetError());
}
t_monster monster_init(t_monster list_monsters, int x, int y, int portee_monstre) {
t_monster monster = malloc(sizeof(*monster));
if (!monster)
error("Memory error");
monster_load_img(monster, LEFT, IMG_MONSTER_LEFT);
monster_load_img(monster, RIGHT, IMG_MONSTER_RIGHT);
monster_load_img(monster, UP, IMG_MONSTER_UP);
monster_load_img(monster, DOWN, IMG_MONSTER_DOWN);
monster->current_way = DOWN;
monster->x=x;
monster->y=y;
monster->portee_monstre=portee_monstre;
monster->nxt=NULL;
if( list_monsters== NULL)
{
return monster;
}
else
{
t_monster temp=list_monsters;
while(temp->nxt != NULL)
{
temp = temp->nxt;
}
temp->nxt = monster;
return list_monsters;
}
}
void monster_free(t_monster monster) {
if (monster != NULL){
assert(monster);
int i;
for (i = 0; i < 4; i++)
SDL_FreeSurface(monster->directed_img[i]);
free(monster);
}
}
t_monster get_next_monster(t_monster monster){
return monster->nxt;
}
void set_next_monster(t_monster monster, t_monster nxt_monster){
monster->nxt=nxt_monster;
}
int monster_get_x(t_monster monster) {
assert(monster != NULL);
return monster->x;
}
int monster_get_y(t_monster monster) {
assert(monster != NULL);
return monster->y;
}
int monster_portee(t_monster monster) {
assert(monster != NULL);
return monster->portee_monstre;
}
enum e_way monster_get_current_way(t_monster monster) {
assert(monster);
return(monster->current_way);
}
void monster_set_current_way(t_monster monster, enum e_way way) {
assert(monster);
monster->current_way = way;
}
void monster_increase_portee(t_monster monster) {
assert(monster);
if (monster->portee_monstre <BOMB_RANGE_MAX)
monster->portee_monstre++;
}
void monster_decrease_portee(t_monster monster) {
assert(monster);
if (monster->portee_monstre >1)
monster->portee_monstre--;
}
static int monster_move_aux(t_monster monster, t_player player, t_player player2, int nb_joueur, t_map map, int x1, int y1, int x2,
int y2) {
t_cell_type type;
if (!map_is_inside(map, x1, y1))
return 0;
type=map_get_cell_type(map, x1, y1);
switch (type & 0x0f) {
case CELL_WALL:
return 0;
break;
case CELL_BOMB:
return 0;
break;
case CELL_PLAYER:
if ( nb_joueur==1){
player_decrease_lives(player);
}
else{
if (player_get_x(player)==x1 && player_get_y(player)==y1) {
player_decrease_lives(player);
}
if (player_get_x(player2)==x1 && player_get_y(player2)==y1) {
player_decrease_lives(player2);
}
}
break;
case CELL_FLAMME:
return 0;;
break;
case CELL_MENU_EMPTY:
return 0;
break;
case CELL_MENU_LIVES:
return 0;
break;
case CELL_MENU_BOMBS:
return 0;
break;
case CELL_MENU_RANGE:
return 0;
break;
case CELL_BONUS:
switch ((type & 0xf0) >> 4) {
case BONUS_BOMB_RANGE_INC:
monster_increase_portee(monster);
break;
case BONUS_BOMB_RANGE_DEC:
monster_decrease_portee(monster);
break;
default:
break;
}
break;
case CELL_BOX:
if (!map_is_inside(map, x2, y2))
return 0;
switch (map_get_cell_type(map,x2,y2)& 0x0f){
case CELL_WALL:
return 0;
break;
case CELL_BOX:
return 0;
break;
case CELL_GOAL:
return 0;
break;
case CELL_MONSTER:
return 0;
break;
case CELL_PLAYER:
return 0;
break;
case CELL_PLAYER_2:
return 0;
break;
case CELL_BOMB:
return 0;
break;
case CELL_MENU_EMPTY:
return 0;
break;
case CELL_MENU_LIVES:
return 0;
break;
case CELL_MENU_BOMBS:
return 0;
break;
case CELL_MENU_RANGE:
return 0;
break;
case CELL_MENU_PLAYER_1:
return 0;
break;
case CELL_MENU_PLAYER_2:
return 0;
break;
default:
break;
}
map_set_cell_type(map, x1, y1, CELL_EMPTY);
switch ((type & 0xf0) >> 4) {
case BONUS_BOMB_RANGE_INC:
map_set_cell_type(map, x2, y2, CELL_BOX | (BONUS_BOMB_RANGE_INC << 4));
break;
case BONUS_BOMB_RANGE_DEC:
map_set_cell_type(map, x2, y2, CELL_BOX | (BONUS_BOMB_RANGE_DEC << 4));
break;
case BONUS_BOMB_NB_INC:
map_set_cell_type(map, x2, y2, CELL_BOX | (BONUS_BOMB_NB_INC << 4));
break;
case BONUS_BOMB_NB_DEC:
map_set_cell_type(map, x2, y2, CELL_BOX | (BONUS_BOMB_NB_DEC << 4));
break;
case BONUS_MONSTER:
map_set_cell_type(map, x2, y2, CELL_BOX | (BONUS_MONSTER << 4));
break;
case BONUS_LIFE_INC:
map_set_cell_type(map, x2, y2, CELL_BOX | (BONUS_LIFE_INC << 4));
break;
case NO_BONUS:
map_set_cell_type(map, x2, y2, CELL_BOX | (NO_BONUS << 4));
break;
default:
break;
}
return 1;
break;
case CELL_GOAL:
return 0;
break;
case CELL_MONSTER:
return 0;
break;
case CELL_MENU_PLAYER_1:
return 0;
break;
case CELL_MENU_PLAYER_2:
return 0;
break;
default:
break;
}
// monster has moved
return 1;
}
int monster_move(t_monster monster, t_map map, t_player player, t_player player2, int nb_joueur) {
int x = monster->x;
int y = monster->y;
int move = 0;
switch (monster->current_way) {
case UP:
if (monster_move_aux(monster, player, player2,nb_joueur, map, x, y - 1, x, y - 2)) {
monster->y--;
move = 1;
}
break;
case DOWN:
if (monster_move_aux(monster, player, player2, nb_joueur, map, x, y + 1, x, y + 2)) {
monster->y++;
move = 1;
}
break;
case LEFT:
if (monster_move_aux(monster, player, player2, nb_joueur, map, x - 1, y, x - 2, y)) {
monster->x--;
move = 1;
}
break;
case RIGHT:
if (monster_move_aux(monster, player, player2, nb_joueur, map, x + 1, y, x + 2, y)) {
monster->x++;
move = 1;
}
break;
}
if (move) {
map_set_cell_type(map, x, y, CELL_EMPTY);
map_set_cell_type(map, monster->x, monster->y, CELL_MONSTER);
}
return move;
}
void monster_display(t_monster monster, SDL_Surface *screen) {
assert(monster);
assert(monster->directed_img[monster->current_way]);
assert(screen);
SDL_Rect place;
place.x = monster->x * SIZE_BLOC;
place.y = monster->y * SIZE_BLOC;
SDL_BlitSurface(monster->directed_img[monster->current_way], NULL, screen,
&place);
}