From adb5af2f532f105ee670e4805b47252eb5bcfdf1 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 25 Mar 2004 10:01:43 +0100 Subject: [PATCH] rnd-20040325-1-src * fixed bug with movable elements not moving after left behind by CEs --- ChangeLog | 5 ++- src/conftime.h | 2 +- src/editor.c | 112 +++++++++++++++++++++++++++---------------------- src/files.c | 5 ++- src/game.c | 93 ++++++++++++++++++++++++++++++++++++---- src/main.h | 8 ++++ 6 files changed, 163 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ebfd875..dcea920b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ +2004-03-24 + * fixed bug with movable elements not moving after left behind by CEs + 2004-03-23 - * bug fixed with movable elements not moving anymore after falling down + * fixed bug with movable elements not moving anymore after falling down 2004-03-22 * fixed another bug with custom elements digging and leaving elements diff --git a/src/conftime.h b/src/conftime.h index 1565dc42..999c4b9f 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2004-03-24 11:12]" +#define COMPILE_DATE_STRING "[2004-03-25 03:08]" diff --git a/src/editor.c b/src/editor.c index 60e64be0..97904719 100644 --- a/src/editor.c +++ b/src/editor.c @@ -502,33 +502,34 @@ #define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 8) #define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 9) #define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 10) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 11) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 12) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 13) -#define GADGET_ID_CUSTOM_EXPLODE_RESULT (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 13) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 14) +#define GADGET_ID_CUSTOM_EXPLODE_RESULT (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 35) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 36) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -701,32 +702,33 @@ #define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 6 #define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 7 #define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 8 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 9 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 10 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 11 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 12 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 13 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 14 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 15 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 16 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 17 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 18 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 19 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 20 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT 21 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 22 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 23 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 24 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 25 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 26 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 27 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 28 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 29 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 30 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 31 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 32 - -#define ED_NUM_CHECKBUTTONS 33 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 9 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 10 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 11 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 12 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 13 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 14 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 15 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 16 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 17 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 18 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 19 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 20 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 21 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT 22 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 23 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 24 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 25 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 26 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 27 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 28 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 29 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 30 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 31 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 32 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 33 + +#define ED_NUM_CHECKBUTTONS 34 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -1980,6 +1982,13 @@ static struct NULL, "no scrolling when relocating", "player gets relocated without delay" }, + { + ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(3), + GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE, + &level.can_pass_to_walkable, + NULL, + "can pass to walkable element", "player can pass to empty or walkable" + }, { ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0), GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_NONE, @@ -6997,6 +7006,7 @@ static void DrawPropertiesConfig() ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD : ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE); } if (IS_GEM(properties_element)) diff --git a/src/files.c b/src/files.c index cfce89f8..f44c2ca3 100644 --- a/src/files.c +++ b/src/files.c @@ -29,7 +29,7 @@ #define CHUNK_SIZE_NONE -1 /* do not write chunk size */ #define FILE_VERS_CHUNK_SIZE 8 /* size of file version chunk */ #define LEVEL_HEADER_SIZE 80 /* size of level file header */ -#define LEVEL_HEADER_UNUSED 3 /* unused level header bytes */ +#define LEVEL_HEADER_UNUSED 2 /* unused level header bytes */ #define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */ #define LEVEL_CHUNK_CNT2_UNUSED 11 /* unused CNT2 chunk bytes */ #define LEVEL_CHUNK_CNT3_HEADER 16 /* size of level CNT3 header */ @@ -162,6 +162,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) level->block_last_field = FALSE; level->sp_block_last_field = TRUE; level->instant_relocation = FALSE; + level->can_pass_to_walkable = FALSE; level->can_move_into_acid_bits = ~0; /* everything can move into acid */ level->dont_collide_with_bits = ~0; /* always deadly when colliding */ @@ -703,6 +704,7 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) level->use_step_counter = (getFile8Bit(file) == 1 ? TRUE : FALSE); level->instant_relocation = (getFile8Bit(file) == 1 ? TRUE : FALSE); + level->can_pass_to_walkable = (getFile8Bit(file) == 1 ? TRUE : FALSE); ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED); @@ -2441,6 +2443,7 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) putFile8Bit(file, (level->use_step_counter ? 1 : 0)); putFile8Bit(file, (level->instant_relocation ? 1 : 0)); + putFile8Bit(file, (level->can_pass_to_walkable ? 1 : 0)); WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED); } diff --git a/src/game.c b/src/game.c index 6e8c99af..05460294 100644 --- a/src/game.c +++ b/src/game.c @@ -1486,6 +1486,7 @@ void InitGame() player->is_waiting = FALSE; player->is_moving = FALSE; + player->is_auto_moving = FALSE; player->is_digging = FALSE; player->is_snapping = FALSE; player->is_collecting = FALSE; @@ -5800,6 +5801,7 @@ void StartMoving(int x, int y) void ContinueMoving(int x, int y) { int element = Feld[x][y]; + int stored = Store[x][y]; struct ElementInfo *ei = &element_info[element]; int direction = MovDir[x][y]; int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0); @@ -5904,7 +5906,7 @@ void ContinueMoving(int x, int y) { element = Feld[newx][newy] = EL_ACID; } -#if 1 +#if 0 else if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) && ei->move_leave_element != EL_EMPTY && (ei->move_leave_type == LEAVE_TYPE_UNLIMITED || @@ -5948,6 +5950,22 @@ void ContinueMoving(int x, int y) ResetGfxAnimation(x, y); /* reset animation values for old field */ +#if 1 + if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) && + ei->move_leave_element != EL_EMPTY && + (ei->move_leave_type == LEAVE_TYPE_UNLIMITED || + stored != EL_EMPTY)) + { + /* some elements can leave other elements behind after moving */ + + Feld[x][y] = ei->move_leave_element; + InitField(x, y, FALSE); + + if (GFX_CRUMBLED(Feld[x][y])) + DrawLevelFieldCrumbledSandNeighbours(x, y); + } +#endif + #if 0 /* some elements can leave other elements behind after moving */ if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) && @@ -8617,6 +8635,33 @@ static boolean canEnterSupaplexPort(int x, int y, int dx, int dy) } #endif +static boolean canFallDown(struct PlayerInfo *player) +{ + int jx = player->jx, jy = player->jy; + + return (IN_LEV_FIELD(jx, jy + 1) && + (IS_FREE(jx, jy + 1) || + (Feld[jx][jy + 1] == EL_ACID && player->can_fall_into_acid)) && + IS_WALKABLE_FROM(Feld[jx][jy], MV_DOWN) && + !IS_WALKABLE_INSIDE(Feld[jx][jy])); +} + +static boolean canPassField(int x, int y, int move_dir) +{ + int opposite_dir = MV_DIR_OPPOSITE(move_dir); + int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0); + int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0); + int nextx = x + dx; + int nexty = y + dy; + int element = Feld[x][y]; + + return (IS_PASSABLE_FROM(element, opposite_dir) && + !CAN_MOVE(element) && + IN_LEV_FIELD(nextx, nexty) && !IS_PLAYER(nextx, nexty) && + IS_WALKABLE_FROM(Feld[nextx][nexty], move_dir) && + (level.can_pass_to_walkable || IS_FREE(nextx, nexty))); +} + static boolean canMoveToValidFieldWithGravity(int x, int y, int move_dir) { int opposite_dir = MV_DIR_OPPOSITE(move_dir); @@ -8624,10 +8669,17 @@ static boolean canMoveToValidFieldWithGravity(int x, int y, int move_dir) int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0); int newx = x + dx; int newy = y + dy; +#if 0 int nextx = newx + dx; int nexty = newy + dy; - boolean next_field_must_be_free = TRUE; +#endif +#if 1 + return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) && + (IS_DIGGABLE(Feld[newx][newy]) || + IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) || + canPassField(newx, newy, move_dir))); +#else return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) && (IS_DIGGABLE(Feld[newx][newy]) || IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) || @@ -8635,7 +8687,8 @@ static boolean canMoveToValidFieldWithGravity(int x, int y, int move_dir) !CAN_MOVE(Feld[newx][newy]) && IN_LEV_FIELD(nextx, nexty) && !IS_PLAYER(nextx, nexty) && IS_WALKABLE_FROM(Feld[nextx][nexty], move_dir) && - !(next_field_must_be_free && !IS_FREE(nextx, nexty))))); + (level.can_pass_to_walkable || IS_FREE(nextx, nexty))))); +#endif } static void CheckGravityMovement(struct PlayerInfo *player) @@ -8657,7 +8710,6 @@ static void CheckGravityMovement(struct PlayerInfo *player) int jx = player->jx, jy = player->jy; - boolean player_is_moving_to_valid_field = (!player_is_snapping && (canMoveToValidFieldWithGravity(jx, jy, move_dir_horizontal) || @@ -8679,10 +8731,16 @@ static void CheckGravityMovement(struct PlayerInfo *player) #endif #if 1 + +#if 1 + boolean player_can_fall_down = canFallDown(player); +#else boolean player_can_fall_down = (IN_LEV_FIELD(jx, jy + 1) && (IS_FREE(jx, jy + 1) || (Feld[jx][jy + 1] == EL_ACID && player->can_fall_into_acid))); +#endif + #else boolean player_can_fall_down = (IN_LEV_FIELD(jx, jy + 1) && @@ -8713,9 +8771,11 @@ static void CheckGravityMovement(struct PlayerInfo *player) ); #endif +#if 0 boolean player_is_standing_on_valid_field = (IS_WALKABLE_INSIDE(Feld[jx][jy]) || (IS_WALKABLE(Feld[jx][jy]) && !ACCESS_FROM(Feld[jx][jy], MV_DOWN))); +#endif #if 0 printf("::: checking gravity NOW [%d, %d, %d] [%d] [%d / %d] ...\n", @@ -8728,7 +8788,9 @@ static void CheckGravityMovement(struct PlayerInfo *player) #endif if (player_can_fall_down && +#if 0 !player_is_standing_on_valid_field && +#endif !player_is_moving_to_valid_field) { #if 0 @@ -8923,6 +8985,9 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) #endif + /* store if player is automatically moved to next field */ + player->is_auto_moving = (player->programmed_action != MV_NO_MOVING); + /* remove the last programmed player action */ player->programmed_action = 0; @@ -10308,6 +10373,13 @@ int DigField(struct PlayerInfo *player, if (!ACCESS_FROM(element, opposite_direction)) return MF_NO_ACTION; /* field not accessible from this direction */ +#if 1 + if (element == EL_EMPTY_SPACE && + game.gravity && !player->is_auto_moving && + canFallDown(player) && move_direction != MV_DOWN) + return MF_NO_ACTION; /* player cannot walk here due to gravity */ +#endif + if (element >= EL_GATE_1 && element <= EL_GATE_4) { if (!player->key[element - EL_GATE_1]) @@ -10339,12 +10411,15 @@ int DigField(struct PlayerInfo *player, } else if (IS_PASSABLE(element)) { - boolean next_field_must_be_free = TRUE; +#if 1 + if (!canPassField(x, y, move_direction)) + return MF_NO_ACTION; +#else #if 1 if (!IN_LEV_FIELD(nextx, nexty) || IS_PLAYER(nextx, nexty) || !IS_WALKABLE_FROM(Feld[nextx][nexty], move_direction) || - (next_field_must_be_free && !IS_FREE(nextx, nexty))) + (!level.can_pass_to_walkable && !IS_FREE(nextx, nexty))) return MF_NO_ACTION; #else if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty)) @@ -10365,12 +10440,14 @@ int DigField(struct PlayerInfo *player, return MF_NO_ACTION; #endif - if (element >= EL_EM_GATE_1 && element <= EL_EM_GATE_4) +#endif + + if (IS_EM_GATE(element)) { if (!player->key[element - EL_EM_GATE_1]) return MF_NO_ACTION; } - else if (element >= EL_EM_GATE_1_GRAY && element <= EL_EM_GATE_4_GRAY) + else if (IS_EM_GATE_GRAY(element)) { if (!player->key[element - EL_EM_GATE_1_GRAY]) return MF_NO_ACTION; diff --git a/src/main.h b/src/main.h index f2e076fa..c58dbfbe 100644 --- a/src/main.h +++ b/src/main.h @@ -401,6 +401,12 @@ #define IS_ENVELOPE(e) ((e) >= EL_ENVELOPE_1 && \ (e) <= EL_ENVELOPE_4) +#define IS_EM_GATE(e) ((e) >= EL_EM_GATE_1 && \ + (e) <= EL_EM_GATE_4) + +#define IS_EM_GATE_GRAY(e) ((e) >= EL_EM_GATE_1_GRAY && \ + (e) <= EL_EM_GATE_4_GRAY) + #define GFX_ELEMENT(e) (element_info[e].use_gfx_element ? \ element_info[e].gfx_element : e) @@ -1340,6 +1346,7 @@ struct PlayerInfo boolean is_waiting; boolean is_moving; + boolean is_auto_moving; boolean is_digging; boolean is_snapping; boolean is_collecting; @@ -1453,6 +1460,7 @@ struct LevelInfo boolean sp_block_last_field; /* player blocks previous field while moving */ boolean use_spring_bug; /* for compatibility with old levels */ boolean instant_relocation; /* no visual delay when relocating player */ + boolean can_pass_to_walkable; /* player can pass to empty or walkable tile */ /* ('int' instead of 'boolean' because used as selectbox value in editor) */ int use_step_counter; /* count steps instead of seconds for level */ -- 2.34.1