rnd-20030210-1-src
[rocksndiamonds.git] / src / editor.c
index 15a3b692ddc8b9464bdf84bf3417a1f9ec8b0385..633a5586256d065d67ddffdf4e666e20eda4c762 100644 (file)
 #define GADGET_ID_EM_SLIPPERY_GEMS     77
 #define GADGET_ID_CUSTOM_INDESTRUCTIBLE        78
 #define GADGET_ID_CUSTOM_CAN_FALL      79
-#define GADGET_ID_CUSTOM_SLIPPERY      80
+#define GADGET_ID_CUSTOM_CAN_SMASH     80
+#define GADGET_ID_CUSTOM_PUSHABLE      81
+#define GADGET_ID_CUSTOM_SLIPPERY      82
 
 /* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST    81
-#define GADGET_ID_ELEMENTLIST_LAST     (81 + ED_NUM_ELEMENTLIST_BUTTONS - 1)
+#define GADGET_ID_ELEMENTLIST_FIRST    83
+#define GADGET_ID_ELEMENTLIST_LAST     (GADGET_ID_ELEMENTLIST_FIRST +  \
+                                       ED_NUM_ELEMENTLIST_BUTTONS - 1)
 
 #define NUM_EDITOR_GADGETS             (GADGET_ID_ELEMENTLIST_LAST + 1)
 
 #define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS     4
 #define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE        5
 #define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      6
-#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      7
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     7
+#define ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE      8
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      9
 
-#define ED_NUM_CHECKBUTTONS                    8
+#define ED_NUM_CHECKBUTTONS                    10
 
 #define ED_CHECKBUTTON_ID_LEVEL_FIRST  ED_CHECKBUTTON_ID_DOUBLE_SPEED
 #define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
 
+#define ED_CHECKBUTTON_ID_CUSTOM_FIRST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE
+#define ED_CHECKBUTTON_ID_CUSTOM_LAST  ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY
+
 /* values for radiobutton gadgets */
 #define ED_RADIOBUTTON_ID_PERCENTAGE   0
 #define ED_RADIOBUTTON_ID_QUANTITY     1
@@ -432,6 +440,8 @@ static struct
 {
   boolean indestructible;
   boolean can_fall;
+  boolean can_smash;
+  boolean pushable;
   boolean slippery;
 } custom_element_properties[NUM_CUSTOM_ELEMENTS];
 
@@ -704,6 +714,18 @@ static struct
   },
   {
     ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(6),
+    GADGET_ID_CUSTOM_CAN_SMASH,
+    &custom_element_properties[0].can_smash,
+    "can smash",                       "element can smash other elements"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(7),
+    GADGET_ID_CUSTOM_PUSHABLE,
+    &custom_element_properties[0].pushable,
+    "pushable",                                "element can be pushed"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS(8),
     GADGET_ID_CUSTOM_SLIPPERY,
     &custom_element_properties[0].slippery,
     "slippery",                                "other elements can fall down from it"
@@ -2449,6 +2471,79 @@ static boolean LevelContainsPlayer()
   return player_found;
 }
 
+static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
+                         short dst[MAX_LEV_FIELDX][MAX_LEV_FIELDY])
+{
+  int x, y;
+
+  for(x=0; x<lev_fieldx; x++)
+    for(y=0; y<lev_fieldy; y++) 
+      dst[x][y] = src[x][y];
+}
+
+static void CopyCustomElementPropertiesToEditor()
+{
+  int i;
+
+  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  {
+    int element = EL_CUSTOM_START + i;
+    int properties = Properties1[element];
+
+    custom_element_properties[i].indestructible =
+      ((properties & EP_BIT_MASSIVE) != 0 ? TRUE : FALSE);
+
+    custom_element_properties[i].can_fall =
+      ((properties & EP_BIT_CAN_FALL) != 0 ? TRUE : FALSE);
+
+    custom_element_properties[i].can_smash =
+      ((properties & EP_BIT_CAN_SMASH) != 0 ? TRUE : FALSE);
+
+    custom_element_properties[i].pushable =
+      ((properties & EP_BIT_PUSHABLE) != 0 ? TRUE : FALSE);
+
+    custom_element_properties[i].slippery =
+      ((properties & EP_BIT_SLIPPERY) != 0 ? TRUE : FALSE);
+  }
+}
+
+static void CopyCustomElementPropertiesToGame()
+{
+  int i;
+
+  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  {
+    int element = EL_CUSTOM_START + i;
+
+    Properties1[element] = EP_BITMASK_DEFAULT;
+
+    if (custom_element_properties[i].indestructible)
+      Properties1[element] |= EP_BIT_MASSIVE;
+    else
+      Properties1[element] &= ~EP_BIT_MASSIVE;
+
+    if (custom_element_properties[i].can_fall)
+      Properties1[element] |= EP_BIT_CAN_FALL;
+    else
+      Properties1[element] &= ~EP_BIT_CAN_FALL;
+
+    if (custom_element_properties[i].can_smash)
+      Properties1[element] |= EP_BIT_CAN_SMASH;
+    else
+      Properties1[element] &= ~EP_BIT_CAN_SMASH;
+
+    if (custom_element_properties[i].pushable)
+      Properties1[element] |= EP_BIT_PUSHABLE;
+    else
+      Properties1[element] &= ~EP_BIT_PUSHABLE;
+
+    if (custom_element_properties[i].slippery)
+      Properties1[element] |= EP_BIT_SLIPPERY;
+    else
+      Properties1[element] &= ~EP_BIT_SLIPPERY;
+  }
+}
+
 void DrawLevelEd()
 {
   CloseDoor(DOOR_CLOSE_ALL);
@@ -2456,15 +2551,8 @@ void DrawLevelEd()
 
   if (level_editor_test_game)
   {
-    int x, y;
-
-    for(x=0; x<lev_fieldx; x++)
-      for(y=0; y<lev_fieldy; y++)
-       Feld[x][y] = Ur[x][y];
-
-    for(x=0; x<lev_fieldx; x++)
-      for(y=0; y<lev_fieldy; y++)
-       Ur[x][y] = FieldBackup[x][y];
+    CopyPlayfield(Ur, Feld);
+    CopyPlayfield(FieldBackup, Ur);
 
     level_editor_test_game = FALSE;
   }
@@ -2963,7 +3051,7 @@ static void DrawPropertiesWindow()
     { EL_PACMAN_LEFT,  &level.score[SC_PACMAN],        TEXT_SMASHING },
     { EL_PACMAN_DOWN,  &level.score[SC_PACMAN],        TEXT_SMASHING },
     { EL_NUT,          &level.score[SC_KOKOSNUSS],     TEXT_CRACKING },
-    { EL_DYNAMITE      ,&level.score[SC_DYNAMIT],      TEXT_COLLECTING },
+    { EL_DYNAMITE,     &level.score[SC_DYNAMIT],       TEXT_COLLECTING },
     { EL_KEY1,         &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
     { EL_KEY2,         &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
     { EL_KEY3,         &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
@@ -3064,6 +3152,8 @@ static void DrawPropertiesWindow()
   {
     int nr = properties_element - EL_CUSTOM_START;
 
+    CopyCustomElementPropertiesToEditor();
+
     /* draw checkbutton gadget */
     i = ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE;
     x = checkbutton_info[i].x + xoffset_right2;
@@ -3088,6 +3178,30 @@ static void DrawPropertiesWindow()
                 GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
     MapCheckbuttonGadget(i);
 
+    /* draw checkbutton gadget */
+    i = ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH;
+    x = checkbutton_info[i].x + xoffset_right2;
+    y = checkbutton_info[i].y + yoffset_right2;
+
+    checkbutton_info[i].value = &custom_element_properties[nr].can_smash;
+
+    DrawTextF(x, y, font_color, checkbutton_info[i].text);
+    ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
+                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+    MapCheckbuttonGadget(i);
+
+    /* draw checkbutton gadget */
+    i = ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE;
+    x = checkbutton_info[i].x + xoffset_right2;
+    y = checkbutton_info[i].y + yoffset_right2;
+
+    checkbutton_info[i].value = &custom_element_properties[nr].pushable;
+
+    DrawTextF(x, y, font_color, checkbutton_info[i].text);
+    ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
+                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+    MapCheckbuttonGadget(i);
+
     /* draw checkbutton gadget */
     i = ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY;
     x = checkbutton_info[i].x + xoffset_right2;
@@ -4011,7 +4125,13 @@ static void HandleRadiobuttons(struct GadgetInfo *gi)
 
 static void HandleCheckbuttons(struct GadgetInfo *gi)
 {
-  *checkbutton_info[gi->custom_type_id].value ^= TRUE;
+  int type_id = gi->custom_type_id;
+
+  *checkbutton_info[type_id].value ^= TRUE;
+
+  if (type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST &&
+      type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST)
+    CopyCustomElementPropertiesToGame();
 }
 
 static void HandleControlButtons(struct GadgetInfo *gi)
@@ -4255,9 +4375,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
       {
        if (Request("Save this level and kill the old ?", REQ_ASK))
        {
-         for(x=0; x<lev_fieldx; x++)
-           for(y=0; y<lev_fieldy; y++) 
-             Ur[x][y] = Feld[x][y];
+         CopyPlayfield(Feld, Ur);
+
          SaveLevel(level_nr);
        }
       }
@@ -4271,37 +4390,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
        if (LevelChanged())
          level.game_version = GAME_VERSION_ACTUAL;
 
-       for(x=0; x<lev_fieldx; x++)
-         for(y=0; y<lev_fieldy; y++)
-           FieldBackup[x][y] = Ur[x][y];
-
-       for(x=0; x<lev_fieldx; x++)
-         for(y=0; y<lev_fieldy; y++)
-           Ur[x][y] = Feld[x][y];
-
-       /* !!! ---------- ---------- ---------- ---------- ---------- */
-
-       for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
-       {
-         int element = EL_CUSTOM_START + i;
-
-         if (custom_element_properties[i].indestructible)
-           Properties1[element] |= EP_BIT_MASSIVE;
-         else
-           Properties1[element] &= ~EP_BIT_MASSIVE;
-
-         if (custom_element_properties[i].can_fall)
-           Properties1[element] |= EP_BIT_CAN_FALL;
-         else
-           Properties1[element] &= ~EP_BIT_CAN_FALL;
-
-         if (custom_element_properties[i].slippery)
-           Properties1[element] |= EP_BIT_SLIPPERY;
-         else
-           Properties1[element] &= ~EP_BIT_SLIPPERY;
-       }
-
-       /* !!! ---------- ---------- ---------- ---------- ---------- */
+       CopyPlayfield(Ur, FieldBackup);
+       CopyPlayfield(Feld, Ur);
 
        UnmapLevelEditorGadgets();
        UndrawSpecialEditorDoor();