added checkbox to player settings in editor if first player solves level
authorHolger Schemel <info@artsoft.org>
Mon, 17 Sep 2018 16:57:54 +0000 (18:57 +0200)
committerHolger Schemel <info@artsoft.org>
Mon, 17 Sep 2018 17:10:46 +0000 (19:10 +0200)
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
src/files.c
src/game.c
src/main.h

index 7ba41621be34cda75b0e381688d46c4ec284def9..06420ebcf2a18632a9856b30f1e129e22f8304c2 100644 (file)
 #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)
 
 #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);
index 79c7787936dc2ab8cc8cee8ed272c911a90f73f7..eb9d37e304878de634d0df8f435989f73d730d3d 100644 (file)
@@ -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)
index d9ac07ace8b24b7aa528880e7bc7858f76f589e7..e0f9c8781c8f199311028141fe57aee066ad09b1 100644 (file)
@@ -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)
index 3c6e492ce8f6b5f8002e5ceb78828f3c41a3e1e2..27441310edc93e27b1708d917ba62aa58abf03f9 100644 (file)
@@ -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 */