From 42ab1555a4ae65badec13e8ef32bf5ff71c34568 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 17 Dec 2005 04:07:38 +0100 Subject: [PATCH] rnd-20051217-2-src * added new player option "block snap field" (enabled by default) to make it possible to show a snapping animation like in Emerald Mine --- ChangeLog | 4 ++ src/conftime.h | 2 +- src/editor.c | 144 ++++++++++++++++++++++++++----------------------- src/files.c | 143 ++++++++++++++++++++++++------------------------ src/game.c | 56 +++++++++++++++++++ src/main.c | 5 ++ src/main.h | 4 +- src/tools.c | 27 ++++++++++ 8 files changed, 247 insertions(+), 138 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2718887..6859bdee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-12-17 + * added new player option "block snap field" (enabled by default) to + make it possible to show a snapping animation like in Emerald Mine + 2005-12-16 * added dynamic checkboxes to custom element action settings in editor * added "CE value" counter for custom elements (instead of "CE count") diff --git a/src/conftime.h b/src/conftime.h index 9ecbf26b..103dd7d4 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2005-12-17 00:15]" +#define COMPILE_DATE_STRING "[2005-12-17 04:05]" diff --git a/src/editor.c b/src/editor.c index d4e44e8c..14c5c353 100644 --- a/src/editor.c +++ b/src/editor.c @@ -543,41 +543,42 @@ #define GADGET_ID_USE_TIME_ORB_BUG (GADGET_ID_CHECKBUTTON_FIRST + 7) #define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 8) #define GADGET_ID_DOUBLE_SPEED (GADGET_ID_CHECKBUTTON_FIRST + 9) -#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 10) -#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 11) -#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 12) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 13) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 38) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 39) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 40) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 10) +#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 11) +#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 12) +#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 13) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 14) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 36) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 37) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 40) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 42) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 42) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 43) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -759,40 +760,41 @@ #define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 5 #define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 6 #define ED_CHECKBUTTON_ID_DOUBLE_SPEED 7 -#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 8 -#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 9 -#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 10 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 11 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 12 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 13 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 14 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 15 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 16 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 17 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 18 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 19 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 20 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 21 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 22 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 23 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 24 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 25 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 26 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 27 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 28 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 29 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 30 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 31 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 32 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 33 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 34 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 35 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 36 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 37 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 38 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 39 - -#define ED_NUM_CHECKBUTTONS 40 +#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 8 +#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 9 +#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 10 +#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 11 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 12 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 13 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 14 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 15 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 16 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 17 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 18 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 19 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 20 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 21 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 22 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 23 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 24 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 25 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 26 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 27 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 28 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 29 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 30 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 31 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 32 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 33 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 34 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 35 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 36 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 37 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 38 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 39 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 40 + +#define ED_NUM_CHECKBUTTONS 41 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_INITIAL_GRAVITY #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -2350,6 +2352,13 @@ static struct NULL, "double speed movement", "set initial movement speed of player" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, + &level.block_snap_field, + NULL, + "block snap field when snapping", "use snapping delay to show animation" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE, @@ -7347,6 +7356,7 @@ static void DrawPropertiesConfig() MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ? ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD : ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DOUBLE_SPEED); diff --git a/src/files.c b/src/files.c index 4cf2a857..0482ba8d 100644 --- a/src/files.c +++ b/src/files.c @@ -389,6 +389,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) level->can_pass_to_walkable = FALSE; level->grow_into_diggable = TRUE; + level->block_snap_field = TRUE; + level->block_last_field = FALSE; /* EM does not block by default */ level->sp_block_last_field = TRUE; /* SP blocks the last field */ @@ -2783,77 +2785,10 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) if (leveldir_current == NULL) /* only when dumping level */ return; -#if 0 - printf("::: sort_priority: %d\n", leveldir_current->sort_priority); -#endif - - /* determine correct game engine version of current level */ - if (!leveldir_current->latest_engine) + if (leveldir_current->latest_engine) { - /* For all levels which are not forced to use the latest game engine - version (normally user contributed, private and undefined levels), - use the version of the game engine the levels were created for. - - Since 2.0.1, the game engine version is now directly stored - in the level file (chunk "VERS"), so there is no need anymore - to set the game version from the file version (except for old, - pre-2.0 levels, where the game version is still taken from the - file format version used to store the level -- see above). */ - - /* player was faster than enemies in 1.0.0 and before */ - if (level->file_version == FILE_VERSION_1_0) - level->double_speed = TRUE; - - /* default behaviour for EM style gems was "slippery" only in 2.0.1 */ - if (level->game_version == VERSION_IDENT(2,0,1,0)) - level->em_slippery_gems = TRUE; - - /* springs could be pushed over pits before (pre-release version) 2.2.0 */ - if (level->game_version < VERSION_IDENT(2,2,0,0)) - level->use_spring_bug = TRUE; - - /* time orb caused limited time in endless time levels before 3.1.2 */ - if (level->game_version < VERSION_IDENT(3,1,2,0)) - level->use_time_orb_bug = TRUE; - - /* only few elements were able to actively move into acid before 3.1.0 */ - /* trigger settings did not exist before 3.1.0; set to default "any" */ - if (level->game_version < VERSION_IDENT(3,1,0,0)) - { - int i, j; - - /* correct "can move into acid" settings (all zero in old levels) */ - - level->can_move_into_acid_bits = 0; /* nothing can move into acid */ - level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */ - - setMoveIntoAcidProperty(level, EL_ROBOT, TRUE); - setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE); - setMoveIntoAcidProperty(level, EL_PENGUIN, TRUE); - setMoveIntoAcidProperty(level, EL_BALLOON, TRUE); + /* ---------- use latest game engine ----------------------------------- */ - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE); - - /* correct trigger settings (stored as zero == "none" in old levels) */ - - for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) - { - int element = EL_CUSTOM_START + i; - struct ElementInfo *ei = &element_info[element]; - - for (j = 0; j < ei->num_change_pages; j++) - { - struct ElementChangeInfo *change = &ei->change_page[j]; - - change->trigger_player = CH_PLAYER_ANY; - change->trigger_page = CH_PAGE_ANY; - } - } - } - } - else /* always use the latest game engine version */ - { /* For all levels which are forced to use the latest game engine version (normally all but user contributed, private and undefined levels), set the game engine version to the actual version; this allows for actual @@ -2873,6 +2808,76 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) if (level->file_version < FILE_VERSION_2_0) level->em_slippery_gems = TRUE; + + return; + } + + /* ---------- use game engine the level was created with ----------------- */ + + /* For all levels which are not forced to use the latest game engine + version (normally user contributed, private and undefined levels), + use the version of the game engine the levels were created for. + + Since 2.0.1, the game engine version is now directly stored + in the level file (chunk "VERS"), so there is no need anymore + to set the game version from the file version (except for old, + pre-2.0 levels, where the game version is still taken from the + file format version used to store the level -- see above). */ + + /* player was faster than enemies in 1.0.0 and before */ + if (level->file_version == FILE_VERSION_1_0) + level->double_speed = TRUE; + + /* default behaviour for EM style gems was "slippery" only in 2.0.1 */ + if (level->game_version == VERSION_IDENT(2,0,1,0)) + level->em_slippery_gems = TRUE; + + /* springs could be pushed over pits before (pre-release version) 2.2.0 */ + if (level->game_version < VERSION_IDENT(2,2,0,0)) + level->use_spring_bug = TRUE; + + /* time orb caused limited time in endless time levels before 3.1.2 */ + if (level->game_version < VERSION_IDENT(3,1,2,0)) + level->use_time_orb_bug = TRUE; + + /* default behaviour for snapping was "no snap delay" before 3.1.2 */ + if (level->game_version < VERSION_IDENT(3,1,2,0)) + level->block_snap_field = FALSE; + + /* only few elements were able to actively move into acid before 3.1.0 */ + /* trigger settings did not exist before 3.1.0; set to default "any" */ + if (level->game_version < VERSION_IDENT(3,1,0,0)) + { + int i, j; + + /* correct "can move into acid" settings (all zero in old levels) */ + + level->can_move_into_acid_bits = 0; /* nothing can move into acid */ + level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */ + + setMoveIntoAcidProperty(level, EL_ROBOT, TRUE); + setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE); + setMoveIntoAcidProperty(level, EL_PENGUIN, TRUE); + setMoveIntoAcidProperty(level, EL_BALLOON, TRUE); + + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE); + + /* correct trigger settings (stored as zero == "none" in old levels) */ + + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; + + for (j = 0; j < ei->num_change_pages; j++) + { + struct ElementChangeInfo *change = &ei->change_page[j]; + + change->trigger_player = CH_PLAYER_ANY; + change->trigger_page = CH_PAGE_ANY; + } + } } } diff --git a/src/game.c b/src/game.c index ae9c3bd2..cc4dace1 100644 --- a/src/game.c +++ b/src/game.c @@ -33,6 +33,7 @@ #define USE_NEW_ALL_SLIPPERY (USE_NEW_STUFF * 1) #define USE_NEW_PLAYER_SPEED (USE_NEW_STUFF * 1) #define USE_NEW_DELAYED_ACTION (USE_NEW_STUFF * 1) +#define USE_NEW_SNAP_DELAY (USE_NEW_STUFF * 1) /* for DigField() */ #define DF_NO_PUSH 0 @@ -7930,6 +7931,18 @@ void GameActions() RemoveField(x, y); } +#if USE_NEW_SNAP_DELAY + if (Feld[x][y] == EL_ELEMENT_SNAPPING) + { + MovDelay[x][y]--; + if (MovDelay[x][y] <= 0) + { + RemoveField(x, y); + DrawLevelField(x, y); + } + } +#endif + #if DEBUG if (ChangePage[x][y] != -1 && ChangeDelay[x][y] != 1) { @@ -8084,6 +8097,14 @@ void GameActions() CheckForDragon(x, y); else if (element == EL_EXPLOSION) ; /* drawing of correct explosion animation is handled separately */ + else if (element == EL_ELEMENT_SNAPPING) + { +#if 1 + graphic = el_act_dir2img(GfxElement[x][y], GfxAction[x][y],GfxDir[x][y]); + + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); +#endif + } else if (IS_ANIMATED(graphic) && !IS_CHANGING(x, y)) DrawLevelGraphicAnimationIfNeeded(x, y, graphic); @@ -9483,6 +9504,27 @@ void RemovePlayer(struct PlayerInfo *player) ExitY = ZY = jy; } +#if USE_NEW_SNAP_DELAY +static void setFieldForSnapping(int x, int y, int element, int direction) +{ + struct ElementInfo *ei = &element_info[element]; + int direction_bit = MV_DIR_BIT(direction); + int graphic_snapping = ei->direction_graphic[ACTION_SNAPPING][direction_bit]; + int action = (graphic_snapping != IMG_EMPTY_SPACE ? ACTION_SNAPPING : + IS_DIGGABLE(element) ? ACTION_DIGGING : ACTION_COLLECTING); + + Feld[x][y] = EL_ELEMENT_SNAPPING; + MovDelay[x][y] = MOVE_DELAY_NORMAL_SPEED + 1 - 1; + + ResetGfxAnimation(x, y); + + GfxElement[x][y] = element; + GfxAction[x][y] = action; + GfxDir[x][y] = direction; + GfxFrame[x][y] = -1; +} +#endif + /* ============================================================================= checkDiagonalPushing() @@ -9707,7 +9749,14 @@ int DigField(struct PlayerInfo *player, player->index_bit, dig_side); if (mode == DF_SNAP) + { TestIfElementTouchesCustomElement(x, y); /* for empty space */ + +#if USE_NEW_SNAP_DELAY + if (level.block_snap_field) + setFieldForSnapping(x, y, element, move_direction); +#endif + } } else if (IS_COLLECTIBLE(element)) { @@ -9797,7 +9846,14 @@ int DigField(struct PlayerInfo *player, player->index_bit, dig_side); if (mode == DF_SNAP) + { TestIfElementTouchesCustomElement(x, y); /* for empty space */ + +#if USE_NEW_SNAP_DELAY + if (level.block_snap_field) + setFieldForSnapping(x, y, element, move_direction); +#endif + } } else if (IS_PUSHABLE(element)) { diff --git a/src/main.c b/src/main.c index fbe001f8..b7f19e0d 100644 --- a/src/main.c +++ b/src/main.c @@ -3968,6 +3968,11 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "-", "-" }, + { + "element.snapping", + "-", + "-" + }, /* ----------------------------------------------------------------------- */ /* dummy elements (never used as game elements, only used as graphics) */ diff --git a/src/main.h b/src/main.h index 59b935f5..a8146357 100644 --- a/src/main.h +++ b/src/main.h @@ -1221,9 +1221,10 @@ #define EL_QUICKSAND_FILLING (EL_FIRST_RUNTIME_UNREAL + 15) #define EL_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 16) #define EL_BD_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 17) +#define EL_ELEMENT_SNAPPING (EL_FIRST_RUNTIME_UNREAL + 18) /* dummy elements (never used as game elements, only used as graphics) */ -#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 18) +#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 19) #define EL_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 0) #define EL_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 1) @@ -1804,6 +1805,7 @@ struct LevelInfo boolean can_pass_to_walkable; /* player can pass to empty or walkable tile */ boolean grow_into_diggable; /* amoeba can grow into anything diggable */ + boolean block_snap_field; /* snapping blocks field to show animation */ boolean block_last_field; /* player blocks previous field while moving */ boolean sp_block_last_field; /* player blocks previous field while moving */ diff --git a/src/tools.c b/src/tools.c index e630cd18..a2797839 100644 --- a/src/tools.c +++ b/src/tools.c @@ -976,6 +976,11 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) IS_MOVING(xx, yy)) continue; +#if 1 + if (Feld[xx][yy] == EL_ELEMENT_SNAPPING) + continue; +#endif + element = TILE_GFX_ELEMENT(xx, yy); if (!GFX_CRUMBLED(element)) @@ -988,7 +993,11 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) continue; #endif +#if 1 + graphic = el_act2crm(element, ACTION_DEFAULT); +#else graphic = el_act2crm(Feld[xx][yy], ACTION_DEFAULT); +#endif crumbled_border_size = graphic_info[graphic].border_size; getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); @@ -1023,7 +1032,20 @@ void DrawLevelFieldCrumbledSand(int x, int y) if (!IN_LEV_FIELD(x, y)) return; +#if 1 + if (Feld[x][y] == EL_ELEMENT_SNAPPING && + GFX_CRUMBLED(GfxElement[x][y])) + { + DrawLevelFieldCrumbledSandDigging(x, y, GfxDir[x][y], GfxFrame[x][y]); + return; + } +#endif + +#if 1 + graphic = el_act2crm(TILE_GFX_ELEMENT(x, y), ACTION_DEFAULT); +#else graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT); +#endif DrawLevelFieldCrumbledSandExt(x, y, graphic, 0); } @@ -1698,8 +1720,13 @@ inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic) DrawGraphicAnimation(sx, sy, graphic); +#if 1 + if (GFX_CRUMBLED(TILE_GFX_ELEMENT(x, y))) + DrawLevelFieldCrumbledSand(x, y); +#else if (GFX_CRUMBLED(Feld[x][y])) DrawLevelFieldCrumbledSand(x, y); +#endif } void DrawLevelElementAnimationIfNeeded(int x, int y, int element) -- 2.34.1