/* level.h Copyright (C) 2010-2019 Amf This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define MOVE_LEFT 0 #define MOVE_UP 1 #define MOVE_RIGHT 2 #define MOVE_DOWN 3 #define MOVE_NONE 4 #define MOVE_SWAP 5 #define MOVE_SWAPPED 6 #define MOVE_UNKNOWN 7 #define MOVE_REDO 8 #define MOVER_FAST 1 #define MOVER_UNDO 2 #define MOVER_STORE 4 #define LEVELFLAG_MOVES 1 #define LEVELFLAG_STARS 2 #define LEVELFLAG_SWITCH 4 #define LEVELFLAG_EXIT 8 #define LEVELFLAG_SOLVED 16 #define LEVELFLAG_FAILED 32 #define LEVELFLAG_PAUSED 64 #define LEVELFLAG_UNDO 128 #define LEVELFLAG_TESTING 256 #define LEVELFLAG_MAP 512 #define LEVELFLAG_NOUNDO 1024 #ifdef XOR_COMPATIBILITY #define MAPPED_TOP_LEFT 1 #define MAPPED_TOP_RIGHT 2 #define MAPPED_BOTTOM_LEFT 4 #define MAPPED_BOTTOM_RIGHT 8 #endif enum { PIECE_SPACE = 0, PIECE_WALL = 1, PIECE_PLAYER_ONE = 2, PIECE_PLAYER_TWO = 3, PIECE_STAR = 4, PIECE_DOTS = 5, PIECE_DOOR = 6, PIECE_CIRCLE = 7, PIECE_ARROW_RED_LEFT = 8, /* PIECE_ARROW_RED_LEFT % 4 must = 0 */ PIECE_ARROW_RED_UP = 9, PIECE_ARROW_RED_RIGHT = 10, PIECE_ARROW_RED_DOWN = 11, PIECE_BOMB_RED_LEFT = 12, PIECE_BOMB_RED_UP = 13, PIECE_BOMB_RED_RIGHT = 14, PIECE_BOMB_RED_DOWN = 15, PIECE_ARROW_GREEN_LEFT = 16, PIECE_ARROW_GREEN_UP = 17, PIECE_ARROW_GREEN_RIGHT = 18, PIECE_ARROW_GREEN_DOWN = 19, PIECE_BOMB_GREEN_LEFT = 20, PIECE_BOMB_GREEN_UP = 21, PIECE_BOMB_GREEN_RIGHT = 22, PIECE_BOMB_GREEN_DOWN = 23, PIECE_ARROW_BLUE_LEFT = 24, PIECE_ARROW_BLUE_UP = 25, PIECE_ARROW_BLUE_RIGHT = 26, PIECE_ARROW_BLUE_DOWN = 27, PIECE_BOMB_BLUE_LEFT = 28, PIECE_BOMB_BLUE_UP = 29, PIECE_BOMB_BLUE_RIGHT = 30, PIECE_BOMB_BLUE_DOWN = 31, #ifdef ENIGMA_COMPATIBILITY PIECE_CIRCLE_DOUBLE, PIECE_DOTS_DOUBLE, #endif #ifdef XOR_COMPATIBILITY PIECE_DOTS_X, PIECE_DOTS_Y, PIECE_SWITCH, PIECE_TELEPORT, PIECE_MAP_TOP_LEFT, PIECE_MAP_TOP_RIGHT, PIECE_MAP_BOTTOM_LEFT, PIECE_MAP_BOTTOM_RIGHT, PIECE_DARKNESS, #endif PIECE_EXPLOSION_RED_LEFT, PIECE_EXPLOSION_RED_HORIZONTAL, PIECE_EXPLOSION_RED_RIGHT, PIECE_EXPLOSION_RED_TOP, PIECE_EXPLOSION_RED_VERTICAL, PIECE_EXPLOSION_RED_BOTTOM, PIECE_EXPLOSION_GREEN_LEFT, PIECE_EXPLOSION_GREEN_HORIZONTAL, PIECE_EXPLOSION_GREEN_RIGHT, PIECE_EXPLOSION_GREEN_TOP, PIECE_EXPLOSION_GREEN_VERTICAL, PIECE_EXPLOSION_GREEN_BOTTOM, PIECE_EXPLOSION_BLUE_LEFT, PIECE_EXPLOSION_BLUE_HORIZONTAL, PIECE_EXPLOSION_BLUE_RIGHT, PIECE_EXPLOSION_BLUE_TOP, PIECE_EXPLOSION_BLUE_VERTICAL, PIECE_EXPLOSION_BLUE_BOTTOM, PIECE_EXPLOSION_NEW_RED_LEFT, PIECE_EXPLOSION_NEW_RED_HORIZONTAL, PIECE_EXPLOSION_NEW_RED_RIGHT, PIECE_EXPLOSION_NEW_RED_TOP, PIECE_EXPLOSION_NEW_RED_VERTICAL, PIECE_EXPLOSION_NEW_RED_BOTTOM, PIECE_EXPLOSION_NEW_GREEN_LEFT, PIECE_EXPLOSION_NEW_GREEN_HORIZONTAL, PIECE_EXPLOSION_NEW_GREEN_RIGHT, PIECE_EXPLOSION_NEW_GREEN_TOP, PIECE_EXPLOSION_NEW_GREEN_VERTICAL, PIECE_EXPLOSION_NEW_GREEN_BOTTOM, PIECE_EXPLOSION_NEW_BLUE_LEFT, PIECE_EXPLOSION_NEW_BLUE_HORIZONTAL, PIECE_EXPLOSION_NEW_BLUE_RIGHT, PIECE_EXPLOSION_NEW_BLUE_TOP, PIECE_EXPLOSION_NEW_BLUE_VERTICAL, PIECE_EXPLOSION_NEW_BLUE_BOTTOM, PIECE_CURSOR, PIECE_GONE, PIECE_UNKNOWN }; #define PIECE_EXPLOSION_FIRST PIECE_EXPLOSION_RED_LEFT #define PIECE_EXPLOSION_LAST PIECE_EXPLOSION_BLUE_BOTTOM #define PIECE_EXPLOSION_NEW_FIRST PIECE_EXPLOSION_NEW_RED_LEFT #define PIECE_EXPLOSION_NEW_LAST PIECE_EXPLOSION_NEW_BLUE_BOTTOM #define PIECE_EXPLOSION_NEW_OFFSET (PIECE_EXPLOSION_NEW_FIRST - PIECE_EXPLOSION_FIRST) #define PIECE_MOVERS_FIRST PIECE_ARROW_RED_LEFT #define PIECE_MOVERS_LAST PIECE_BOMB_BLUE_DOWN #define PIECE_MAX PIECE_GONE #define isexplosion(x) (x >= PIECE_EXPLOSION_FIRST && x<= PIECE_EXPLOSION_LAST) #define isnewexplosion(x) (x >= PIECE_EXPLOSION_NEW_FIRST && x <= PIECE_EXPLOSION_NEW_LAST) enum { MODE_CHROMA, #ifdef XOR_COMPATIBILITY MODE_XOR, #endif #ifdef ENIGMA_COMPATIBILITY MODE_ENIGMA, #endif MODE_MAX }; struct mover { int x; int y; int direction; int piece; int piece_previous; int fast; struct mover* next; struct mover* previous; }; struct move { int count; int direction; struct move* previous; struct move* next; struct mover* mover_first; struct mover* mover_last; }; struct level { int size_x; int size_y; char *data_pieces; char *data_moving; char *data_previous; char *data_previousmoving; char *data_detonator; char *data_detonatormoving; unsigned int *data_data; struct move* move_first; struct move* move_last; struct move* move_current; struct mover* mover_first; struct mover* mover_last; struct mover* stack_first; struct mover* stack_last; int player; int player_x[3]; int player_y[3]; int view_x[3]; int view_y[3]; int alive[2]; int moves; int stars_caught; int stars_exploded; int stars_total; char *title; int flags; #ifdef XOR_COMPATIBILITY int switched; int mapped; #endif int mode; int level; int teleport_x[2]; int teleport_y[2]; int view_teleport_x[2]; int view_teleport_y[2]; }; /* level.c */ char piecetochar(int piece); int chartopiece(char c); char directiontochar(int direction); int chartodirection(char c); struct level* level_new(); struct level* level_load(char *filename, int partial); int level_save(struct level* plevel, char *filename, int partial); struct level* level_copy(struct level*); void level_addmove(struct level*, int); void level_fix(struct level*); struct level* level_create(int, int); void level_delete(struct level* plevel); char level_piece(struct level*, int, int); void level_setpiece(struct level*, int, int, char); char level_moving(struct level*, int, int); void level_setmoving(struct level*, int, int, char); char level_previous(struct level*, int, int); void level_setprevious(struct level*, int, int, char); char level_detonator(struct level*, int, int); void level_setdetonator(struct level*, int, int, char); char level_detonatormoving(struct level*, int, int); void level_setdetonatormoving(struct level*, int, int, char); char level_previousmoving(struct level*, int, int); void level_setpreviousmoving(struct level*, int, int, char); unsigned int level_data(struct level*, int, int); void level_setdata(struct level*, int, int, unsigned int); void level_settitle(struct level* plevel, char *title); /* engine.c */ int level_move(struct level*, int); int level_evolve(struct level*); int canfall(int p, int into, int d); struct mover* mover_new(struct level* plevel, int x, int y, int d, int piece, int fast); struct mover* mover_addtostack(struct level* plevel, int x, int y, int move); void level_storemovers(struct level*); int level_undo(struct level*); struct mover* mover_newundo(struct level* plevel, int x, int y, int d, int piece, int previous, int flags);