From 41831f337ebfff25c7138785efe20af5c2b0a2a8 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 17 Sep 2018 18:57:54 +0200 Subject: [PATCH] added checkbox to player settings in editor if first player solves level A recently made change (commits 2bf392f1 and 6999c82d) added checking if all players in a level entered an exit before the level is treated as being successfully solved, changing the previous behaviour where a level was solved by the first player entering an exit, which differs from the behaviour in the EM/EMC game engine, where team-mode levels require all players to enter an exit before the level is solved. However, this change broke at least one existing level that was based on the previous behaviour (level 032 of level set "rnd_falk_sobe"), so a checkbox in the player settings of the level editor was added to be able to select the desired behaviour, using the "new" behaviour (all players must enter an exit) as the default setting. --- src/editor.c | 216 +++++++++++++++++++++++++++------------------------ src/files.c | 10 +++ src/game.c | 6 +- src/main.h | 1 + 4 files changed, 129 insertions(+), 104 deletions(-) diff --git a/src/editor.c b/src/editor.c index 7ba41621..06420ebc 100644 --- a/src/editor.c +++ b/src/editor.c @@ -654,60 +654,61 @@ #define GADGET_ID_INITIAL_BALL_STATE (GADGET_ID_CHECKBUTTON_FIRST + 12) #define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 13) #define GADGET_ID_AUTO_EXIT_SOKOBAN (GADGET_ID_CHECKBUTTON_FIRST + 14) -#define GADGET_ID_CONTINUOUS_SNAPPING (GADGET_ID_CHECKBUTTON_FIRST + 15) -#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 16) -#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 17) -#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_SHIFTED_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_LAZY_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_USE_INITIAL_INVENTORY (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_MM_LASER_RED (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_MM_LASER_GREEN (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_MM_LASER_BLUE (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_DF_LASER_RED (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_DF_LASER_GREEN (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_DF_LASER_BLUE (GADGET_ID_CHECKBUTTON_FIRST + 38) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 39) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 40) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 41) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 42) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 43) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 44) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 45) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 46) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 47) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 48) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 49) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 50) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 51) -#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 52) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 53) -#define GADGET_ID_CUSTOM_USE_TEMPLATE_1 (GADGET_ID_CHECKBUTTON_FIRST + 54) -#define GADGET_ID_CUSTOM_USE_TEMPLATE_2 (GADGET_ID_CHECKBUTTON_FIRST + 55) -#define GADGET_ID_CUSTOM_USE_TEMPLATE_3 (GADGET_ID_CHECKBUTTON_FIRST + 56) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 57) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 58) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 59) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 60) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 61) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 62) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 63) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 64) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 65) +#define GADGET_ID_SOLVED_BY_ONE_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 15) +#define GADGET_ID_CONTINUOUS_SNAPPING (GADGET_ID_CHECKBUTTON_FIRST + 16) +#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 17) +#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 18) +#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 19) +#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 20) +#define GADGET_ID_SHIFTED_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 21) +#define GADGET_ID_LAZY_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 22) +#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 23) +#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 24) +#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 25) +#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 26) +#define GADGET_ID_USE_INITIAL_INVENTORY (GADGET_ID_CHECKBUTTON_FIRST + 27) +#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 28) +#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 29) +#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 30) +#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 31) +#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 32) +#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 33) +#define GADGET_ID_MM_LASER_RED (GADGET_ID_CHECKBUTTON_FIRST + 34) +#define GADGET_ID_MM_LASER_GREEN (GADGET_ID_CHECKBUTTON_FIRST + 35) +#define GADGET_ID_MM_LASER_BLUE (GADGET_ID_CHECKBUTTON_FIRST + 36) +#define GADGET_ID_DF_LASER_RED (GADGET_ID_CHECKBUTTON_FIRST + 37) +#define GADGET_ID_DF_LASER_GREEN (GADGET_ID_CHECKBUTTON_FIRST + 38) +#define GADGET_ID_DF_LASER_BLUE (GADGET_ID_CHECKBUTTON_FIRST + 39) +#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 40) +#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 41) +#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 42) +#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 43) +#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 44) +#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 47) +#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 48) +#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 49) +#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 50) +#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 51) +#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 52) +#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 53) +#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 54) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_1 (GADGET_ID_CHECKBUTTON_FIRST + 55) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_2 (GADGET_ID_CHECKBUTTON_FIRST + 56) +#define GADGET_ID_CUSTOM_USE_TEMPLATE_3 (GADGET_ID_CHECKBUTTON_FIRST + 57) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 58) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 59) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 60) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 61) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 62) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 63) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 64) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 65) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 66) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 66) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 67) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -923,57 +924,58 @@ #define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 12 #define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 13 #define ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN 14 -#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 15 -#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 16 -#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 17 -#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 18 -#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 19 -#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 20 -#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 21 -#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 22 -#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 23 -#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 24 -#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 25 -#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 26 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 27 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 28 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 29 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 30 -#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 31 -#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 32 -#define ED_CHECKBUTTON_ID_MM_LASER_RED 33 -#define ED_CHECKBUTTON_ID_MM_LASER_GREEN 34 -#define ED_CHECKBUTTON_ID_MM_LASER_BLUE 35 -#define ED_CHECKBUTTON_ID_DF_LASER_RED 36 -#define ED_CHECKBUTTON_ID_DF_LASER_GREEN 37 -#define ED_CHECKBUTTON_ID_DF_LASER_BLUE 38 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 39 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 40 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 41 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 42 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 43 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 44 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 45 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 46 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 47 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 48 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 49 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 50 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 51 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 52 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 53 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 54 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 55 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 56 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 57 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 58 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 59 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 60 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 61 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 62 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 63 - -#define ED_NUM_CHECKBUTTONS 64 +#define ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER 15 +#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 16 +#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 17 +#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 18 +#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 19 +#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 20 +#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 21 +#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 22 +#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 23 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 24 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 25 +#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 26 +#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 27 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 28 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 29 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 30 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 31 +#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 32 +#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 33 +#define ED_CHECKBUTTON_ID_MM_LASER_RED 34 +#define ED_CHECKBUTTON_ID_MM_LASER_GREEN 35 +#define ED_CHECKBUTTON_ID_MM_LASER_BLUE 36 +#define ED_CHECKBUTTON_ID_DF_LASER_RED 37 +#define ED_CHECKBUTTON_ID_DF_LASER_GREEN 38 +#define ED_CHECKBUTTON_ID_DF_LASER_BLUE 39 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 40 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 41 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 42 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 43 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 44 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 45 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 46 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 47 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 48 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 49 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 50 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 51 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 52 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 53 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 54 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 55 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 56 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 57 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 58 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 59 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 60 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 61 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 62 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 63 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 64 + +#define ED_NUM_CHECKBUTTONS 65 #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS #define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS @@ -3039,6 +3041,13 @@ static struct NULL, NULL, "exit level if all fields solved", "automatically finish Sokoban levels" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_SOLVED_BY_ONE_PLAYER, GADGET_ID_NONE, + &level.solved_by_one_player, + NULL, NULL, + "only one player must enter exit", "level solved by first player in exit" + }, { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, @@ -9819,6 +9828,7 @@ static void DrawPropertiesConfig() MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_GRAVITY); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER); MapDrawingArea(ED_DRAWING_ID_START_ELEMENT); MapDrawingArea(ED_DRAWING_ID_ARTWORK_ELEMENT); diff --git a/src/files.c b/src/files.c index 79c77879..eb9d37e3 100644 --- a/src/files.c +++ b/src/files.c @@ -251,6 +251,12 @@ static struct LevelFileConfigInfo chunk_config_INFO[] = &li.auto_count_gems, FALSE }, + { + -1, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(11), + &li.solved_by_one_player, FALSE + }, + { -1, -1, -1, -1, @@ -6395,6 +6401,10 @@ static void LoadLevel_InitVersion(struct LevelInfo *level) /* EM style elements always chain-exploded in R'n'D engine before 3.2.6 */ if (level->game_version < VERSION_IDENT(3,2,6,0)) level->em_explodes_by_fire = TRUE; + + /* levels were solved by the first player entering an exit up to 4.1.0.0 */ + if (level->game_version <= VERSION_IDENT(4,1,0,0)) + level->solved_by_one_player = TRUE; } static void LoadLevel_InitStandardElements(struct LevelInfo *level) diff --git a/src/game.c b/src/game.c index d9ac07ac..e0f9c878 100644 --- a/src/game.c +++ b/src/game.c @@ -3956,6 +3956,9 @@ void InitGame() if (stored_player[i].active) local_player->players_still_needed++; + if (level.solved_by_one_player) + local_player->players_still_needed = 1; + /* when recording the game, store which players take part in the game */ if (tape.recording) { @@ -13425,7 +13428,8 @@ void ExitPlayer(struct PlayerInfo *player) DrawPlayer(player); /* needed here only to cleanup last field */ RemovePlayer(player); - local_player->players_still_needed--; + if (local_player->players_still_needed > 0) + local_player->players_still_needed--; } static void setFieldForSnapping(int x, int y, int element, int direction) diff --git a/src/main.h b/src/main.h index 3c6e492c..27441310 100644 --- a/src/main.h +++ b/src/main.h @@ -3094,6 +3094,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 auto_exit_sokoban; /* automatically finish solved Sokoban levels */ + boolean solved_by_one_player; /* level is solved if one player enters exit */ boolean continuous_snapping; /* repeated snapping without releasing key */ boolean block_snap_field; /* snapping blocks field to show animation */ -- 2.34.1