added check for custom elements being "next to" player or element
[rocksndiamonds.git] / src / editor.c
index 24590595e96d645f563ad4ee6e9c9fa375feed44..7f63d89eec53de1db4fc33587be48a05be5f7abb 100644 (file)
@@ -637,6 +637,7 @@ enum
   // checkbuttons/radiobuttons for level/element properties
 
   GADGET_ID_AUTO_COUNT_GEMS,
+  GADGET_ID_RATE_TIME_OVER_SCORE,
   GADGET_ID_USE_LEVELSET_ARTWORK,
   GADGET_ID_COPY_LEVEL_TEMPLATE,
   GADGET_ID_RANDOM_PERCENTAGE,
@@ -656,6 +657,7 @@ enum
   GADGET_ID_AUTO_EXIT_SOKOBAN,
   GADGET_ID_SOLVED_BY_ONE_PLAYER,
   GADGET_ID_FINISH_DIG_COLLECT,
+  GADGET_ID_KEEP_WALKABLE_CE,
   GADGET_ID_CONTINUOUS_SNAPPING,
   GADGET_ID_BLOCK_SNAP_FIELD,
   GADGET_ID_BLOCK_LAST_FIELD,
@@ -946,6 +948,7 @@ enum
 enum
 {
   ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS,
+  ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE,
   ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK,
   ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE,
   ED_CHECKBUTTON_ID_RANDOM_RESTRICTED,
@@ -965,6 +968,7 @@ enum
   ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN,
   ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER,
   ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT,
+  ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE,
   ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING,
   ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD,
   ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD,
@@ -1019,7 +1023,7 @@ enum
 };
 
 #define ED_CHECKBUTTON_ID_LEVEL_FIRST  ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS
-#define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS
+#define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE
 
 #define ED_CHECKBUTTON_ID_LEVELSET_FIRST ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK
 #define ED_CHECKBUTTON_ID_LEVELSET_LAST         ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE
@@ -1423,7 +1427,7 @@ static struct
     "score for time or steps left:",   NULL, NULL
   },
   {
-    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(12),
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(13),
     0,                                 9999,
     GADGET_ID_LEVEL_RANDOM_SEED_DOWN,  GADGET_ID_LEVEL_RANDOM_SEED_UP,
     GADGET_ID_LEVEL_RANDOM_SEED_TEXT,  GADGET_ID_NONE,
@@ -2005,6 +2009,9 @@ static struct ValueTextInfo options_change_direct_action[] =
   { CE_HEADLINE_SPECIAL_EVENTS,        "[mouse events]"                },
   { CE_CLICKED_BY_MOUSE,       "clicked by mouse"              },
   { CE_PRESSED_BY_MOUSE,       "pressed by mouse"              },
+  { CE_UNDEFINED,              " "                             },
+  { CE_HEADLINE_SPECIAL_EVENTS,        "[static states]"               },
+  { CE_NEXT_TO_PLAYER,         "next to player"                },
 
   { -1,                                NULL                            }
 };
@@ -2038,6 +2045,10 @@ static struct ValueTextInfo options_change_other_action[] =
   { CE_HEADLINE_SPECIAL_EVENTS,        "[mouse events]"                },
   { CE_MOUSE_CLICKED_ON_X,     "mouse clicked on"              },
   { CE_MOUSE_PRESSED_ON_X,     "mouse pressed on"              },
+  { CE_UNDEFINED,              " "                             },
+  { CE_HEADLINE_SPECIAL_EVENTS,        "[static states]"               },
+  { CE_PLAYER_NEXT_TO_X,       "player next to"                },
+  { CE_NEXT_TO_X,              "next to"                       },
 
   { -1,                                NULL                            }
 };
@@ -2510,7 +2521,7 @@ static struct
     NULL, NULL, NULL,                  "time score for 1 or 10 seconds/steps"
   },
   {
-    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(11),
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(12),
     GADGET_ID_GAME_ENGINE_TYPE,                GADGET_ID_NONE,
     -1,
     options_game_engine_type,
@@ -3025,6 +3036,13 @@ static struct
     NULL, NULL,
     "automatically count gems needed", "set counter to number of gems"
   },
+  {
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(11),
+    GADGET_ID_RATE_TIME_OVER_SCORE,    GADGET_ID_NONE,
+    &level.rate_time_over_score,
+    NULL, NULL,
+    "rate time/steps used over score", "sort high scores by playing time/steps"
+  },
   {
     ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(7),
     GADGET_ID_USE_LEVELSET_ARTWORK,    GADGET_ID_NONE,
@@ -3161,6 +3179,13 @@ static struct
     NULL, NULL,
     "CE action on finished dig/collect", "only finished dig/collect triggers CE"
   },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(4),
+    GADGET_ID_KEEP_WALKABLE_CE,                GADGET_ID_NONE,
+    &level.keep_walkable_ce,
+    NULL, NULL,
+    "keep walkable CE changed to player", "keep CE changing to player if walkable"
+  },
   {
     ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(9),
     GADGET_ID_CONTINUOUS_SNAPPING,     GADGET_ID_NONE,
@@ -8187,7 +8212,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
 
   // set "change by direct action" selectbox help value
   custom_element_change.direct_action =
-    (HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER :
+    (HAS_CHANGE_EVENT(element, CE_NEXT_TO_PLAYER) ? CE_NEXT_TO_PLAYER :
+     HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_SWITCHED_BY_PLAYER) ? CE_SWITCHED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_SNAPPED_BY_PLAYER) ? CE_SNAPPED_BY_PLAYER :
@@ -8211,7 +8237,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
 
   // set "change by other element action" selectbox help value
   custom_element_change.other_action =
-    (HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X :
+    (HAS_CHANGE_EVENT(element, CE_PLAYER_NEXT_TO_X) ? CE_PLAYER_NEXT_TO_X :
+     HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X :
      HAS_CHANGE_EVENT(element, CE_PLAYER_PRESSES_X) ? CE_PLAYER_PRESSES_X :
      HAS_CHANGE_EVENT(element, CE_PLAYER_SWITCHES_X) ? CE_PLAYER_SWITCHES_X :
      HAS_CHANGE_EVENT(element, CE_PLAYER_SNAPS_X) ? CE_PLAYER_SNAPS_X :
@@ -8221,6 +8248,7 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_PLAYER_DIGS_X) ? CE_PLAYER_DIGS_X :
      HAS_CHANGE_EVENT(element, CE_PLAYER_COLLECTS_X) ? CE_PLAYER_COLLECTS_X :
      HAS_CHANGE_EVENT(element, CE_PLAYER_DROPS_X) ? CE_PLAYER_DROPS_X :
+     HAS_CHANGE_EVENT(element, CE_NEXT_TO_X) ? CE_NEXT_TO_X :
      HAS_CHANGE_EVENT(element, CE_TOUCHING_X) ? CE_TOUCHING_X :
      HAS_CHANGE_EVENT(element, CE_HITTING_X) ? CE_HITTING_X :
      HAS_CHANGE_EVENT(element, CE_DIGGING_X) ? CE_DIGGING_X :
@@ -8247,7 +8275,7 @@ static void CopyGroupElementPropertiesToEditor(int element)
 
 static void CopyClassicElementPropertiesToEditor(int element)
 {
-  if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element))
+  if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element))
     custom_element_properties[EP_CAN_MOVE_INTO_ACID] =
       getMoveIntoAcidProperty(&level, element);
 
@@ -8349,6 +8377,7 @@ static void CopyCustomElementPropertiesToGame(int element)
   // ---------- element settings: advanced (custom elements) ------------------
 
   // set player change event from checkbox and selectbox
+  custom_element_change_events[CE_NEXT_TO_PLAYER] = FALSE;
   custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_SWITCHED_BY_PLAYER] = FALSE;
@@ -8373,6 +8402,7 @@ static void CopyCustomElementPropertiesToGame(int element)
     custom_element_change_events[CE_BY_DIRECT_ACTION];
 
   // set other element action change event from checkbox and selectbox
+  custom_element_change_events[CE_PLAYER_NEXT_TO_X] = FALSE;
   custom_element_change_events[CE_PLAYER_TOUCHES_X] = FALSE;
   custom_element_change_events[CE_PLAYER_PRESSES_X] = FALSE;
   custom_element_change_events[CE_PLAYER_SWITCHES_X] = FALSE;
@@ -8383,6 +8413,7 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_PLAYER_DIGS_X] = FALSE;
   custom_element_change_events[CE_PLAYER_COLLECTS_X] = FALSE;
   custom_element_change_events[CE_PLAYER_DROPS_X] = FALSE;
+  custom_element_change_events[CE_NEXT_TO_X] = FALSE;
   custom_element_change_events[CE_TOUCHING_X] = FALSE;
   custom_element_change_events[CE_HITTING_X] = FALSE;
   custom_element_change_events[CE_DIGGING_X] = FALSE;
@@ -8433,7 +8464,7 @@ static void CopyGroupElementPropertiesToGame(int element)
 
 static void CopyClassicElementPropertiesToGame(int element)
 {
-  if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element))
+  if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element))
     setMoveIntoAcidProperty(&level, element,
                            custom_element_properties[EP_CAN_MOVE_INTO_ACID]);
 
@@ -9103,7 +9134,7 @@ static void DrawPropertiesTabulatorGadgets(void)
   int i;
 
   // draw two config tabulators for player elements
-  if (ELEM_IS_PLAYER(properties_element))
+  if (IS_PLAYER_ELEMENT(properties_element))
     id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2;
 
   // draw two config and one "change" tabulator for custom elements
@@ -9118,7 +9149,7 @@ static void DrawPropertiesTabulatorGadgets(void)
 
     // use "config 1" and "config 2" instead of "config" for players and CEs
     if (i == ED_TEXTBUTTON_ID_PROPERTIES_CONFIG &&
-       (ELEM_IS_PLAYER(properties_element) ||
+       (IS_PLAYER_ELEMENT(properties_element) ||
         IS_CUSTOM_ELEMENT(properties_element)))
       continue;
 
@@ -9815,7 +9846,7 @@ static boolean checkPropertiesConfig(int element)
       IS_ENVELOPE(element) ||
       IS_MM_MCDUFFIN(element) ||
       IS_DF_LASER(element) ||
-      ELEM_IS_PLAYER(element) ||
+      IS_PLAYER_ELEMENT(element) ||
       HAS_EDITOR_CONTENT(element) ||
       CAN_GROW(element) ||
       COULD_MOVE_INTO_ACID(element) ||
@@ -9972,7 +10003,7 @@ static void DrawPropertiesConfig(void)
       DrawAndroidElementArea(properties_element);
   }
 
-  if (ELEM_IS_PLAYER(properties_element))
+  if (IS_PLAYER_ELEMENT(properties_element))
   {
     int player_nr = GET_PLAYER_NR(properties_element);
 
@@ -10035,6 +10066,7 @@ static void DrawPropertiesConfig(void)
       // draw checkbutton gadgets
       MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY);
       MapCheckbuttonGadget(ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT);
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE);
 
       // draw counter gadgets
       MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE);
@@ -10051,7 +10083,7 @@ static void DrawPropertiesConfig(void)
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE);
 
   if (COULD_MOVE_INTO_ACID(properties_element) &&
-      !ELEM_IS_PLAYER(properties_element) &&
+      !IS_PLAYER_ELEMENT(properties_element) &&
       (!IS_CUSTOM_ELEMENT(properties_element) ||
        edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2))
   {
@@ -10389,12 +10421,12 @@ static void DrawPropertiesWindow(void)
     edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_2;
 
   if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG &&
-      !ELEM_IS_PLAYER(properties_element) &&
+      !IS_PLAYER_ELEMENT(properties_element) &&
       !IS_CUSTOM_ELEMENT(properties_element))
     edit_mode_properties = ED_MODE_PROPERTIES_CONFIG;
 
   if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG &&
-      (ELEM_IS_PLAYER(properties_element) ||
+      (IS_PLAYER_ELEMENT(properties_element) ||
        IS_CUSTOM_ELEMENT(properties_element)))
     edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_1;
 
@@ -12302,7 +12334,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y,
        {
          int element = Tile[x][y];
 
-         if (!IS_EM_ELEMENT(element) && !ELEM_IS_PLAYER(element))
+         if (!IS_EM_ELEMENT(element) && !IS_PLAYER_ELEMENT(element))
            use_em_engine = FALSE;
 
          if (!IS_SP_ELEMENT(element))
@@ -12985,7 +13017,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
        {
          SetDrawModeHiRes(new_element);
 
-         if (ELEM_IS_PLAYER(new_element))
+         if (IS_PLAYER_ELEMENT(new_element))
          {
            // remove player at old position
            for (y = 0; y < lev_fieldy; y++)
@@ -12994,7 +13026,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
              {
                int old_element = Tile[x][y];
 
-               if (ELEM_IS_PLAYER(old_element))
+               if (IS_PLAYER_ELEMENT(old_element))
                {
                  int replaced_with_element =
                    (old_element == EL_SOKOBAN_FIELD_PLAYER &&