#include "input_manager.h" extern int defeat; extern int win; //return 1 if the value given in parameter is in the list. int in_list(int value, int *list, int len){ for (int i = 0; i<len; i++){ if (list[i]==value){ return 1; } } return 0; } // apply the movement from (y,x) and to direction d1 first then d2 if possible. void make_move(monsters* mon, map* m, int y, int x, direction d1, direction d2){ int y1=y, x1=x; switch (d1) { case DIR_UP: y1 = y - 1; break; case DIR_DOWN: y1 = y + 1; break; case DIR_RIGHT: x1 = x + 1; break; case DIR_LEFT: x1 = x - 1; break; default: break; } int y2=y1, x2=x1; switch (d2){ case DIR_UP: y2 = y1-1; break; case DIR_DOWN: y2 = y1+1; break; case DIR_RIGHT: x2 = x1+1; break; case DIR_LEFT: x2 = x1-1; break; default : break; } update_monster(mon,m,y,x,y1,x1); //apply_events(game); if (d2 != DIR_UNKNOWN){ update_monster(mon,m,y1,x1,y2,x2); } } // verify if a move is possible and apply it if so int ok_move(monsters* mon, map* m, int y, int x, direction d1, direction d2){ int y1 = y, x1 = x; switch (d1){ case DIR_UP: y1 = y-1; break; case DIR_DOWN: y1 = y+1; break; case DIR_RIGHT: x1 = x+1; break; case DIR_LEFT: x1 = x-1; break; default : break; } int y2=y1, x2=x1; switch (d2){ case DIR_UP: y2 = y1-1; break; case DIR_DOWN: y2 = y1+1; break; case DIR_RIGHT: x2 = x1+1; break; case DIR_LEFT: x2 = x1-1; break; default : break; } if (d2 == DIR_UNKNOWN){ if (!is_obstacle(m->tiles[y1][x1])){ make_move(mon,m,y,x,d1,d2); return 1; } } else if (!is_obstacle(m->tiles[y1][x1]) && !is_obstacle(m->tiles[y2][x2])){ make_move(mon,m,y,x,d1,d2); return 1; } else if (!is_obstacle(m->tiles[y1][x1])){ make_move(mon,m,y,x,d1,DIR_UNKNOWN); return 1; } return 0; } // move the monster to the right or the left depending on the player's position int move_up_or_down(monsters* mon, map* m, int y_monster, int x_monster, int y_player){ if (y_monster > y_player) return ok_move(mon, m, y_monster,x_monster, DIR_UP, DIR_UP); else if (y_monster < y_player) return ok_move(mon, m, y_monster,x_monster, DIR_DOWN, DIR_DOWN); return 0; } // move the monster to the right or the left depending on the player's position int move_left_or_right(monsters* mon, map* m, int y_monster, int x_monster, int x_player){ if (x_monster > x_player) return ok_move(mon, m, y_monster,x_monster, DIR_LEFT, DIR_LEFT); else if (x_monster < x_player) return ok_move(mon, m, y_monster,x_monster, DIR_RIGHT, DIR_RIGHT); return 0; } // move the monster to one of the four corners int move_to_corner(monsters* mon, map* m, int y_monster, int x_monster, int y_player, int x_player){ if (x_monster > x_player && y_monster > y_player) return ok_move(mon, m, y_monster,x_monster, DIR_UP, DIR_LEFT) || ok_move(mon, m, y_monster,x_monster, DIR_LEFT, DIR_UP); else if (x_monster > x_player && x_monster < y_player) return ok_move(mon, m, y_monster,y_player, DIR_DOWN, DIR_LEFT) || ok_move(mon, m, y_monster,x_monster, DIR_LEFT, DIR_DOWN); else if (x_monster < x_player && y_monster > y_player) return ok_move(mon, m, y_monster,x_monster, DIR_RIGHT, DIR_UP) || ok_move(mon, m, y_monster,x_monster, DIR_UP, DIR_RIGHT); else if (x_monster < x_player && y_monster < y_player) return ok_move(mon, m, y_monster,x_monster, DIR_RIGHT, DIR_DOWN) || ok_move(mon, m, y_monster,x_monster, DIR_DOWN, DIR_RIGHT); return 0; } int follow_player(monsters* mon, map* m, int * y, int * x){ int y_monster = *y; int x_monster = *x; int y_player = m->player_y, x_player = m->player_x; if (x_player == x_monster){ // same column return move_up_or_down(mon, m, y_monster, x_monster, y_player); } else if (y_monster==y_player){ // same line return move_left_or_right(mon, m, y_monster, x_monster, x_player); } else if ((x_player==x_monster+1 || x_player==x_monster-1) && (y_player==y_monster+1 || y_player==y_monster-1)){ // corners return move_to_corner(mon, m, y_monster, x_monster, y_player, x_player); } else if (x_player==x_monster+1 || x_player==x_monster-1){ // one tile to the left or the right #ifdef line_first return move_up_or_down(mon, m, y_monster, x_monster, x_player) || move_to_corner(mon, m, y_monster, x_monster, y_player, x_player); #else return move_to_corner(mon, m, y_monster, x_monster, y_player, x_player) || move_up_or_down(mon, m, y_monster, x_monster, y_player); #endif } else if (y_player==y_monster+1 || y_player==y_monster-1){ // one tile upper or lower #ifdef line_first return move_left_or_right(mon, m, y_monster, x_monster, x_player) || move_to_corner(mon, m, y_monster, x_monster, y_player, x_player); #else return move_to_corner(mon, m, y_monster, x_monster, y_player, x_player) || move_left_or_right(mon, m, y_monster, x_monster, x_player); #endif } else { #ifdef line_first return move_left_or_right(mon, m, y_monster, x_monster, x_player) || move_up_or_down(mon, m, y_monster, x_monster, y_player) || move_to_corner(mon, m, y_monster, x_monster, y_player, x_player); #else #endif return move_to_corner(mon, m, y_monster, x_monster, y_player, x_player) || move_up_or_down(mon, m, y_monster, x_monster, y_player) || move_left_or_right(mon, m, y_monster, x_monster, x_player); } } void circle(monsters* mon, map* m, int y, int x) { if (y == 6 && x != 6 && m->tiles[y][x-1] != 'M') update_monster(mon,m,y,x,y,x-1); // left else if (y == 4 && x!=10 && m->tiles[y][x+1] != 'M') update_monster(mon,m,y,x,y,x+1); //right else if(x == 6 && y!=4 && m->tiles[y-1][x] != 'M') update_monster(mon,m,y,x,y-1,x); //up else if(x == 10 && y!=6 && m->tiles[y+1][x] != 'M') update_monster(mon,m,y,x,y+1,x); //down } int search_monster(monsters* mon, map* m, int y, int x) { for (int i = 0; i < mon->length; i++) { if (mon->info[i].x == x && mon->info[i].y == y) return i; } return -1; } void come_and_go(monsters* mon, map * m, int y, int x){ int monster_id = search_monster(mon, m, y, x); if (monster_id == -1) return; int dir = mon->info[monster_id].dir; if(x==m->width-2 || m->tiles[y][x+1] == '@' || m->tiles[y][x+1] == 'M') { mon->info[monster_id].dir = DIR_LEFT; update_monster(mon,m,y,x,y,x-1); } else if (x == 2 || m->tiles[y][x-1] == 'M') { mon->info[monster_id].dir = DIR_RIGHT; update_monster(mon,m,y,x,y,x+1); } else if (dir == DIR_RIGHT) update_monster(mon,m,y,x,y,x+1); else if (dir == DIR_LEFT) update_monster(mon,m,y,x,y,x-1); else if (dir == DIR_DOWN) { mon->info[monster_id].dir = DIR_LEFT; update_monster(mon,m,y,x,y,x-1); } } // verify if the player is seen by the monster void is_player_seen(monsters* mon, map * m, int y, int x){ int monster_id = search_monster(mon, m, y, x); if (monster_id == -1) return; int dir = mon->info[monster_id].dir; #ifndef BUG if (dir == DIR_RIGHT && m->player_x > x && m->player_y == y) #else if (dir == DIR_RIGHT && m->player_y == y) #endif mon->info[monster_id].player_seen = true; #ifndef BUG else if (dir == DIR_LEFT && m->player_x < x && m->player_y == y) #else else if (dir == DIR_LEFT && m->player_y == y) #endif mon->info[monster_id].player_seen = true; #ifndef BUG else if (dir == DIR_UP && m->player_y < y && m->player_x == x) #else else if (dir == DIR_UP && m->player_x == x) #endif mon->info[monster_id].player_seen = true; } // move the monster to the player's position void catch_player(monsters* mon, map * m, int y, int x){ int monster_id = search_monster(mon, m, y, x); if (y < m->player_y && !is_obstacle(m->tiles[y+1][x]) && m->tiles[y+1][x] != 'M' && m->tiles[y+1][x] != '@') { mon->info[monster_id].dir = DIR_DOWN; update_monster(mon,m,y,x,y+1,x); } else if (y > m->player_y && !is_obstacle(m->tiles[y-1][x]) && m->tiles[y-1][x] != 'M' && m->tiles[y-1][x] != '@') { mon->info[monster_id].dir = DIR_UP; update_monster(mon,m,y,x,y-1,x); } else if (x < m->player_x && !is_obstacle(m->tiles[y][x+1]) && m->tiles[y][x+1] != 'M' && m->tiles[y][x+1] != '@') { mon->info[monster_id].dir = DIR_RIGHT; update_monster(mon,m,y,x,y,x+1); } else if (x > m->player_x && !is_obstacle(m->tiles[y][x-1]) && m->tiles[y][x-1] != 'M' && m->tiles[y][x-1] != '@') { mon->info[monster_id].dir = DIR_LEFT; update_monster(mon,m,y,x,y,x-1); } } // move the monster once and verify to not move twice a monster. void move_monsters(monsters* mon, map * m){ int done[8], len = 0; for (int y = 0; y < m->height; y++){ for (int x = 0; x < m->width; x++){ if (m->tiles[y][x] == 'M'){ int id = search_monster(mon, m, y, x); if (id != -1 && !in_list(id, done, len)){ if (strcmp(m->name, "third_room") != 0) is_player_seen(mon,m,y,x); if (mon->info[id].player_seen && strcmp(m->name, "third_room") != 0) catch_player(mon,m,y,x); else if (!strcmp(m->name, "first_room")) come_and_go(mon,m,y,x); else if (!strcmp(m->name, "second_room")) circle(mon,m,y,x); else if (!strcmp(m->name, "third_room")) follow_player(mon,m,&y,&x); done[len] = id; len++; } } } } }