rnd-20070310-1-src
[rocksndiamonds.git] / src / editor.c
index 4c6393974ea0e399dad7f265d2059d418824182d..009297ae66122de238e2126ce7312d66015739e3 100644 (file)
 
 /* values for elements with score for certain actions */
 #define MIN_SCORE                      0
-#define MAX_SCORE                      255
+#define MAX_SCORE                      999
 
 /* values for elements with count for collecting */
 #define MIN_COLLECT_COUNT              0
-#define MAX_COLLECT_COUNT              255
+#define MAX_COLLECT_COUNT              999
 
 /* values for random placement */
 #define RANDOM_USE_PERCENTAGE          0
@@ -1047,7 +1047,7 @@ static struct
   },
   {
     ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(9),
-    0,                                 255,
+    0,                                 999,
     GADGET_ID_LEVEL_TIMESCORE_DOWN,    GADGET_ID_LEVEL_TIMESCORE_UP,
     GADGET_ID_LEVEL_TIMESCORE_TEXT,    GADGET_ID_NONE,
     &level.score[SC_TIME_BONUS],
@@ -1173,7 +1173,7 @@ static struct
   },
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(7),
-    0,                                 255,
+    0,                                 999,
     GADGET_ID_PUSH_DELAY_FIX_DOWN,     GADGET_ID_PUSH_DELAY_FIX_UP,
     GADGET_ID_PUSH_DELAY_FIX_TEXT,     GADGET_ID_NONE,
     &custom_element.push_delay_fixed,
@@ -1181,7 +1181,7 @@ static struct
   },
   {
     -1,                                        ED_ELEMENT_SETTINGS_YPOS(7),
-    0,                                 255,
+    0,                                 999,
     GADGET_ID_PUSH_DELAY_RND_DOWN,     GADGET_ID_PUSH_DELAY_RND_UP,
     GADGET_ID_PUSH_DELAY_RND_TEXT,     GADGET_ID_PUSH_DELAY_FIX_UP,
     &custom_element.push_delay_random,
@@ -1189,7 +1189,7 @@ static struct
   },
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(8),
-    0,                                 255,
+    0,                                 999,
     GADGET_ID_DROP_DELAY_FIX_DOWN,     GADGET_ID_DROP_DELAY_FIX_UP,
     GADGET_ID_DROP_DELAY_FIX_TEXT,     GADGET_ID_NONE,
     &custom_element.drop_delay_fixed,
@@ -1197,7 +1197,7 @@ static struct
   },
   {
     -1,                                        ED_ELEMENT_SETTINGS_YPOS(8),
-    0,                                 255,
+    0,                                 999,
     GADGET_ID_DROP_DELAY_RND_DOWN,     GADGET_ID_DROP_DELAY_RND_UP,
     GADGET_ID_DROP_DELAY_RND_TEXT,     GADGET_ID_DROP_DELAY_FIX_UP,
     &custom_element.drop_delay_random,
@@ -1224,7 +1224,7 @@ static struct
   },
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(12),
-    0,                                 255,
+    0,                                 999,
     GADGET_ID_EXPLOSION_DELAY_DOWN,    GADGET_ID_EXPLOSION_DELAY_UP,
     GADGET_ID_EXPLOSION_DELAY_TEXT,    GADGET_ID_NONE,
     &custom_element.explosion_delay,
@@ -1232,7 +1232,7 @@ static struct
   },
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(13),
-    0,                                 255,
+    0,                                 999,
     GADGET_ID_IGNITION_DELAY_DOWN,     GADGET_ID_IGNITION_DELAY_UP,
     GADGET_ID_IGNITION_DELAY_TEXT,     GADGET_ID_NONE,
     &custom_element.ignition_delay,
@@ -8813,7 +8813,7 @@ static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1,
 }
 
 static void SetElementIntelliDraw(int x, int y, int new_element,
-                                 boolean change_level)
+                                 boolean change_level, int button)
 {
   static int xy[4][2] =
   {
@@ -9091,6 +9091,26 @@ static void SetElementIntelliDraw(int x, int y, int new_element,
     new_element = (nr == 0 ? EL_SP_HARDWARE_GREEN :
                   nr == 1 ? EL_SP_HARDWARE_BLUE : EL_SP_HARDWARE_RED);
   }
+  else if (IS_GROUP_ELEMENT(new_element))
+  {
+    boolean connected_drawing = FALSE;
+    int i;
+
+    for (i = 0; i < NUM_DIRECTIONS; i++)
+    {
+      int xx = x + xy[i][0];
+      int yy = y + xy[i][1];
+
+      if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
+         IS_IN_GROUP_EL(IntelliDrawBuffer[last_x][last_y], new_element))
+       connected_drawing = TRUE;
+    }
+
+    if (!connected_drawing)
+      ResolveGroupElement(new_element);
+
+    new_element = GetElementFromGroupElement(new_element);
+  }
   else if (IS_BELT_SWITCH(old_element))
   {
     int belt_nr = getBeltNrFromBeltSwitchElement(old_element);
@@ -9148,7 +9168,107 @@ static void SetElementIntelliDraw(int x, int y, int new_element,
 
       { -1,                            -1                              },
     };
-    int i;
+    static int rotatable_elements[][4] =
+    {
+      {
+       EL_BUG_UP,
+       EL_BUG_RIGHT,
+       EL_BUG_DOWN,
+       EL_BUG_LEFT
+      },
+
+      {
+       EL_SPACESHIP_UP,
+       EL_SPACESHIP_RIGHT,
+       EL_SPACESHIP_DOWN,
+       EL_SPACESHIP_LEFT
+      },
+
+      {
+       EL_BD_BUTTERFLY_UP,
+       EL_BD_BUTTERFLY_RIGHT,
+       EL_BD_BUTTERFLY_DOWN,
+       EL_BD_BUTTERFLY_LEFT
+      },
+
+      {
+       EL_BD_FIREFLY_UP,
+       EL_BD_FIREFLY_RIGHT,
+       EL_BD_FIREFLY_DOWN,
+       EL_BD_FIREFLY_LEFT
+      },
+
+      {
+       EL_PACMAN_UP,
+       EL_PACMAN_RIGHT,
+       EL_PACMAN_DOWN,
+       EL_PACMAN_LEFT
+      },
+
+      {
+       EL_YAMYAM_UP,
+       EL_YAMYAM_RIGHT,
+       EL_YAMYAM_DOWN,
+       EL_YAMYAM_LEFT
+      },
+
+      {
+       EL_ARROW_UP,
+       EL_ARROW_RIGHT,
+       EL_ARROW_DOWN,
+       EL_ARROW_LEFT
+      },
+
+      {
+       EL_SP_PORT_UP,
+       EL_SP_PORT_RIGHT,
+       EL_SP_PORT_DOWN,
+       EL_SP_PORT_LEFT
+      },
+
+      {
+       EL_SP_GRAVITY_PORT_UP,
+       EL_SP_GRAVITY_PORT_RIGHT,
+       EL_SP_GRAVITY_PORT_DOWN,
+       EL_SP_GRAVITY_PORT_LEFT
+      },
+
+      {
+       EL_MOLE_UP,
+       EL_MOLE_RIGHT,
+       EL_MOLE_DOWN,
+       EL_MOLE_LEFT
+      },
+
+      {
+       EL_BALLOON_SWITCH_UP,
+       EL_BALLOON_SWITCH_RIGHT,
+       EL_BALLOON_SWITCH_DOWN,
+       EL_BALLOON_SWITCH_LEFT
+      },
+
+      {
+       EL_SP_GRAVITY_ON_PORT_UP,
+       EL_SP_GRAVITY_ON_PORT_RIGHT,
+       EL_SP_GRAVITY_ON_PORT_DOWN,
+       EL_SP_GRAVITY_ON_PORT_LEFT
+      },
+
+      {
+       EL_SP_GRAVITY_OFF_PORT_UP,
+       EL_SP_GRAVITY_OFF_PORT_RIGHT,
+       EL_SP_GRAVITY_OFF_PORT_DOWN,
+       EL_SP_GRAVITY_OFF_PORT_LEFT
+      },
+
+      {
+       -1,
+       -1,
+       -1,
+       -1,
+      },
+    };
+    int i, j;
 
     for (i = 0; swappable_elements[i][0] != -1; i++)
     {
@@ -9158,6 +9278,20 @@ static void SetElementIntelliDraw(int x, int y, int new_element,
       if (old_element == element1 || old_element == element2)
        new_element = (old_element == element1 ? element2 : element1);
     }
+
+    for (i = 0; rotatable_elements[i][0] != -1; i++)
+    {
+      for (j = 0; j < 4; j++)
+      {
+       int element = rotatable_elements[i][j];
+
+       if (old_element == element)
+         new_element = (button == 1 ? rotatable_elements[i][(j + 3) % 4] :
+                        button == 2 ? rotatable_elements[i][0]           :
+                        button == 3 ? rotatable_elements[i][(j + 1) % 4] :
+                        old_element);
+      }
+    }
   }
 
   SetElementSimple(x, y, new_element, change_level);
@@ -9174,22 +9308,28 @@ static void ResetIntelliDraw()
     for (y = 0; y < lev_fieldy; y++)
       IntelliDrawBuffer[x][y] = Feld[x][y];
 
-  SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE);
+  SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1);
 }
 
-static void SetElementExt(int x, int y, int element, boolean change_level)
+static void SetElementExt(int x, int y, int element, boolean change_level,
+                         int button)
 {
   if (element < 0)
     SetElementSimple(x, y, Feld[x][y], change_level);
   else if (GetKeyModState() & KMOD_Shift)
-    SetElementIntelliDraw(x, y, element, change_level);
+    SetElementIntelliDraw(x, y, element, change_level, button);
   else
     SetElementSimple(x, y, element, change_level);
 }
 
 static void SetElement(int x, int y, int element)
 {
-  SetElementExt(x, y, element, TRUE);
+  SetElementExt(x, y, element, TRUE, -1);
+}
+
+static void SetElementButton(int x, int y, int element, int button)
+{
+  SetElementExt(x, y, element, TRUE, button);
 }
 
 static void DrawLineElement(int sx, int sy, int element, boolean change_level)
@@ -9197,7 +9337,7 @@ static void DrawLineElement(int sx, int sy, int element, boolean change_level)
   int lx = sx + level_xpos;
   int ly = sy + level_ypos;
 
-  SetElementExt(lx, ly, element, change_level);
+  SetElementExt(lx, ly, element, change_level, -1);
 }
 
 static void DrawLine(int from_x, int from_y, int to_x, int to_y,
@@ -9742,6 +9882,10 @@ static void RandomPlacement(int new_element)
   int num_percentage, num_elements;
   int x, y;
 
+#if 1
+  ResetIntelliDraw();
+#endif
+
   /* determine number of free positions for randomly placing the new element */
   for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++)
   {
@@ -9765,7 +9909,11 @@ static void RandomPlacement(int new_element)
     for (x = 0; x < lev_fieldx; x++)
       for (y = 0; y < lev_fieldy; y++)
        if (free_position[x][y])
+#if 1
+         SetElement(x, y, new_element);
+#else
          Feld[x][y] = new_element;
+#endif
   }
   else
   {
@@ -9778,7 +9926,11 @@ static void RandomPlacement(int new_element)
       if (free_position[x][y])
       {
        free_position[x][y] = FALSE;
+#if 1
+       SetElement(x, y, new_element);
+#else
        Feld[x][y] = new_element;
+#endif
        num_elements--;
       }
     }
@@ -9947,7 +10099,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
          }
 
 #if 1
-         SetElement(lx, ly, new_element);
+         SetElementButton(lx, ly, new_element, button);
 #else
          Feld[lx][ly] = new_element;
          DrawMiniElement(sx, sy, new_element);