added option to rotate newly created gray ball content for MM engine
[rocksndiamonds.git] / src / editor.c
index 631c57f6e32fb32671231433ddf9cc6ccdbb3a40..c0fc04466e000ece5d8a5de2f9a75314f08214c7 100644 (file)
@@ -459,6 +459,9 @@ enum
   GADGET_ID_INVENTORY_SIZE_DOWN,
   GADGET_ID_INVENTORY_SIZE_TEXT,
   GADGET_ID_INVENTORY_SIZE_UP,
+  GADGET_ID_MM_BALL_CONTENT_DOWN,
+  GADGET_ID_MM_BALL_CONTENT_TEXT,
+  GADGET_ID_MM_BALL_CONTENT_UP,
   GADGET_ID_CUSTOM_SCORE_DOWN,
   GADGET_ID_CUSTOM_SCORE_TEXT,
   GADGET_ID_CUSTOM_SCORE_UP,
@@ -539,6 +542,7 @@ enum
   GADGET_ID_ARTWORK_ELEMENT,
   GADGET_ID_EXPLOSION_ELEMENT,
   GADGET_ID_INVENTORY_CONTENT,
+  GADGET_ID_MM_BALL_CONTENT,
   GADGET_ID_CUSTOM_GRAPHIC,
   GADGET_ID_CUSTOM_CONTENT,
   GADGET_ID_CUSTOM_MOVE_ENTER,
@@ -570,6 +574,7 @@ enum
   GADGET_ID_LEVELSET_SAVE_MODE,
   GADGET_ID_WIND_DIRECTION,
   GADGET_ID_PLAYER_SPEED,
+  GADGET_ID_MM_BALL_CHOICE_MODE,
   GADGET_ID_CUSTOM_WALK_TO_ACTION,
   GADGET_ID_CUSTOM_EXPLOSION_TYPE,
   GADGET_ID_CUSTOM_DEADLINESS,
@@ -682,6 +687,7 @@ enum
   GADGET_ID_DF_LASER_RED,
   GADGET_ID_DF_LASER_GREEN,
   GADGET_ID_DF_LASER_BLUE,
+  GADGET_ID_ROTATE_MM_BALL_CONTENT,
   GADGET_ID_CUSTOM_INDESTRUCTIBLE,
   GADGET_ID_CUSTOM_CAN_EXPLODE,
   GADGET_ID_CUSTOM_EXPLODE_FIRE,
@@ -750,6 +756,7 @@ enum
   ED_COUNTER_ID_ENVELOPE_XSIZE,
   ED_COUNTER_ID_ENVELOPE_YSIZE,
   ED_COUNTER_ID_INVENTORY_SIZE,
+  ED_COUNTER_ID_MM_BALL_CONTENT,
   ED_COUNTER_ID_CUSTOM_SCORE,
   ED_COUNTER_ID_CUSTOM_GEMCOUNT,
   ED_COUNTER_ID_CUSTOM_VALUE_FIX,
@@ -856,6 +863,7 @@ enum
   ED_SELECTBOX_ID_LEVELSET_SAVE_MODE,
   ED_SELECTBOX_ID_WIND_DIRECTION,
   ED_SELECTBOX_ID_PLAYER_SPEED,
+  ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE,
   ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE,
   ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER,
   ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED,
@@ -993,6 +1001,7 @@ enum
   ED_CHECKBUTTON_ID_DF_LASER_RED,
   ED_CHECKBUTTON_ID_DF_LASER_GREEN,
   ED_CHECKBUTTON_ID_DF_LASER_BLUE,
+  ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT,
   ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC,
   ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1,
   ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE,
@@ -1079,6 +1088,7 @@ enum
   ED_DRAWING_ID_ARTWORK_ELEMENT,
   ED_DRAWING_ID_EXPLOSION_ELEMENT,
   ED_DRAWING_ID_INVENTORY_CONTENT,
+  ED_DRAWING_ID_MM_BALL_CONTENT,
   ED_DRAWING_ID_CUSTOM_GRAPHIC,
   ED_DRAWING_ID_CUSTOM_CONTENT,
   ED_DRAWING_ID_CUSTOM_MOVE_ENTER,
@@ -1533,6 +1543,14 @@ static struct
     &level.initial_inventory_size[0],
     NULL,                              NULL, "number of inventory elements"
   },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(3),
+    MIN_ELEMENTS_IN_GROUP,             MAX_MM_BALL_CONTENTS,
+    GADGET_ID_MM_BALL_CONTENT_DOWN,    GADGET_ID_MM_BALL_CONTENT_UP,
+    GADGET_ID_MM_BALL_CONTENT_TEXT,    GADGET_ID_NONE,
+    &level.num_mm_ball_contents,
+    NULL,                              NULL, "number of content elements"
+  },
 
   // ---------- element settings: configure 1 (custom elements) ---------------
 
@@ -1743,7 +1761,7 @@ static struct
   int gadget_id;
   int xsize, ysize;
   char *value;
-  char *text_above, *infotext;
+  char *text_above, *text_above_cropped, *infotext;
 } textarea_info[ED_NUM_TEXTAREAS] =
 {
   {
@@ -1751,7 +1769,7 @@ static struct
     GADGET_ID_ENVELOPE_INFO,
     MAX_ENVELOPE_XSIZE, MAX_ENVELOPE_YSIZE,
     NULL,
-    "Envelope Content:", "Envelope Content"
+    "Envelope Content:", "Envelope Content (cropped):", "Envelope Content"
   }
 };
 
@@ -2555,6 +2573,14 @@ static struct
     &level.initial_player_stepsize[0],
     NULL, "initial player speed:", NULL,       "initial player speed"
   },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(4),
+    GADGET_ID_MM_BALL_CHOICE_MODE,     GADGET_ID_NONE,
+    -1,
+    options_group_choice_mode,
+    &level.mm_ball_choice_mode,
+    NULL, "choice type:", NULL,                "type of content choice"
+  },
 
   // ---------- element settings: configure 1 (custom elements) ---------------
 
@@ -3354,6 +3380,13 @@ static struct
     NULL, NULL,
     "blue",                            "use blue color components in laser"
   },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(5),
+    GADGET_ID_ROTATE_MM_BALL_CONTENT,  GADGET_ID_NONE,
+    &level.rotate_mm_ball_content,
+    NULL, NULL,
+    "randomly rotate created content", "randomly rotate newly created content"
+  },
 
   // ---------- element settings: configure 1 (custom elements) ---------------
 
@@ -3740,6 +3773,16 @@ static struct
     NULL, NULL, NULL, NULL,            "content for initial inventory"
   },
 
+  // ---------- gray ball content -----------------------------------------
+
+  {
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(2),
+    ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
+    GADGET_ID_MM_BALL_CONTENT,         GADGET_ID_NONE,
+    &level.mm_ball_content[0],         MAX_MM_BALL_CONTENTS, 1,
+    "content:", NULL, NULL, NULL,      "content for gray ball"
+  },
+
   // ---------- element settings: configure 1 (custom elements) ---------------
 
   // ---------- custom graphic ------------------------------------------------
@@ -4610,7 +4653,12 @@ static int editor_el_mirror_magic[] =
   EL_MM_WOODEN_GRID_FIXED_1,
   EL_MM_WOODEN_GRID_FIXED_2,
   EL_MM_WOODEN_GRID_FIXED_3,
-  EL_MM_WOODEN_GRID_FIXED_4
+  EL_MM_WOODEN_GRID_FIXED_4,
+
+  EL_MM_ENVELOPE_1,
+  EL_MM_ENVELOPE_2,
+  EL_MM_ENVELOPE_3,
+  EL_MM_ENVELOPE_4
 };
 static int *editor_hl_mirror_magic_ptr = editor_hl_mirror_magic;
 static int *editor_el_mirror_magic_ptr = editor_el_mirror_magic;
@@ -7276,6 +7324,8 @@ void CreateLevelEditorGadgets(void)
 
   use_permanent_palette = !editor.palette.show_as_separate_screen;
 
+  InitGadgetScreenBorders(-1, INFOTEXT_YPOS);
+
   ReinitializeElementList();
 
   CreateControlButtons();
@@ -7468,9 +7518,13 @@ static void MapTextAreaGadget(int id)
   int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE;
   int x_above = ED_SETTINGS_X(textarea_info[id].x);
   int y_above = ED_SETTINGS_Y(textarea_info[id].y) - yoffset_above;
+  char *text_above = textarea_info[id].text_above;
 
-  if (textarea_info[id].text_above)
-    DrawTextS(x_above, y_above, font_nr, textarea_info[id].text_above);
+  if (gi->textarea.cropped && textarea_info[id].text_above_cropped)
+    text_above = textarea_info[id].text_above_cropped;
+
+  if (text_above)
+    DrawTextS(x_above, y_above, font_nr, text_above);
 
   ModifyGadget(gi, GDI_TEXT_VALUE, textarea_info[id].value, GDI_END);
 
@@ -9492,7 +9546,7 @@ static void DrawMagicBallContentAreas(void)
   DrawText(x, y + 2 * tilesize, "active",    font_nr);
 }
 
-static void DrawAndroidElementArea(int element)
+static void DrawAndroidElementArea(void)
 {
   int id = ED_DRAWING_ID_ANDROID_CONTENT;
   int num_elements = level.num_android_clone_elements;
@@ -9520,7 +9574,7 @@ static void DrawAndroidElementArea(int element)
   MapDrawingArea(id);
 }
 
-static void DrawGroupElementArea(int element)
+static void DrawGroupElementArea(void)
 {
   int id = ED_DRAWING_ID_GROUP_CONTENT;
   int num_elements = group_element_info.num_elements;
@@ -9577,13 +9631,40 @@ static void DrawPlayerInitialInventoryArea(int element)
   MapDrawingArea(id);
 }
 
+static void DrawMMBallContentArea(void)
+{
+  int id = ED_DRAWING_ID_MM_BALL_CONTENT;
+  int num_elements = level.num_mm_ball_contents;
+  int border_size = ED_DRAWINGAREA_BORDER_SIZE;
+  int sx = SX + ED_AREA_SETTINGS_X(drawingarea_info[id]) - border_size;
+  int sy = SY + ED_AREA_SETTINGS_Y(drawingarea_info[id]) - border_size;
+  int xsize = MAX_MM_BALL_CONTENTS;
+  int ysize = 1;
+
+  if (drawingarea_info[id].text_left != NULL)
+    sx += getTextWidthForDrawingArea(drawingarea_info[id].text_left);
+
+  UnmapDrawingArea(id);
+
+  ModifyEditorDrawingArea(id, num_elements, 1);
+
+  // delete content areas in case of reducing number of them
+  DrawBackground(sx, sy,
+                xsize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size,
+                ysize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size);
+
+  MapDrawingArea(id);
+}
+
 static void DrawEnvelopeTextArea(int envelope_nr)
 {
   int id = ED_TEXTAREA_ID_ENVELOPE_INFO;
   struct GadgetInfo *gi = level_editor_gadget[textarea_info[id].gadget_id];
 
   UnmapGadget(gi);
-  DrawBackground(gi->x, gi->y, gi->width, gi->height);
+
+  DrawBackground(gi->x, gi->y,
+                gi->textarea.crop_width, gi->textarea.crop_height);
 
   if (envelope_nr != -1)
     textarea_info[id].value = level.envelope[envelope_nr].text;
@@ -9903,6 +9984,7 @@ static boolean checkPropertiesConfig(int element)
       IS_EMPTY_ELEMENT(element) ||
       IS_BALLOON_ELEMENT(element) ||
       IS_ENVELOPE(element) ||
+      IS_MM_ENVELOPE(element) ||
       IS_MM_MCDUFFIN(element) ||
       IS_DF_LASER(element) ||
       IS_PLAYER_ELEMENT(element) ||
@@ -10059,7 +10141,15 @@ static void DrawPropertiesConfig(void)
       MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE);
     }
     else if (properties_element == EL_EMC_ANDROID)
-      DrawAndroidElementArea(properties_element);
+      DrawAndroidElementArea();
+    else if (properties_element == EL_MM_GRAY_BALL)
+    {
+      MapCounterButtons(ED_COUNTER_ID_MM_BALL_CONTENT);
+      MapSelectboxGadget(ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE);
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT);
+
+      DrawMMBallContentArea();
+    }
   }
 
   if (IS_PLAYER_ELEMENT(properties_element))
@@ -10200,13 +10290,14 @@ static void DrawPropertiesConfig(void)
   if (IS_BALLOON_ELEMENT(properties_element))
     MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION);
 
-  if (IS_ENVELOPE(properties_element))
+  if (IS_ENVELOPE(properties_element) ||
+      IS_MM_ENVELOPE(properties_element))
   {
     int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE;
     int counter2_id = ED_COUNTER_ID_ENVELOPE_YSIZE;
     int button1_id = ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP;
     int button2_id = ED_CHECKBUTTON_ID_ENVELOPE_CENTERED;
-    int envelope_nr = properties_element - EL_ENVELOPE_1;
+    int envelope_nr = ENVELOPE_NR(properties_element);
 
     counterbutton_info[counter1_id].value = &level.envelope[envelope_nr].xsize;
     counterbutton_info[counter2_id].value = &level.envelope[envelope_nr].ysize;
@@ -10314,7 +10405,7 @@ static void DrawPropertiesConfig(void)
     MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1);
 
     // draw drawing area gadgets
-    DrawGroupElementArea(properties_element);
+    DrawGroupElementArea();
 
     // draw text input gadgets
     MapTextInputGadget(ED_TEXTINPUT_ID_ELEMENT_NAME);
@@ -13313,11 +13404,11 @@ static void HandleCounterButtons(struct GadgetInfo *gi)
       break;
 
     case ED_COUNTER_ID_ANDROID_CONTENT:
-      DrawAndroidElementArea(properties_element);
+      DrawAndroidElementArea();
       break;
 
     case ED_COUNTER_ID_GROUP_CONTENT:
-      DrawGroupElementArea(properties_element);
+      DrawGroupElementArea();
       CopyGroupElementPropertiesToGame(properties_element);
       break;
 
@@ -13325,6 +13416,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi)
       DrawPlayerInitialInventoryArea(properties_element);
       break;
 
+    case ED_COUNTER_ID_MM_BALL_CONTENT:
+      DrawMMBallContentArea();
+      break;
+
     case ED_COUNTER_ID_ENVELOPE_XSIZE:
     case ED_COUNTER_ID_ENVELOPE_YSIZE:
       DrawEnvelopeTextArea(-1);
@@ -14219,7 +14314,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
          id <= GADGET_ID_ELEMENTLIST_LAST)
       {
        int element_position = id - GADGET_ID_ELEMENTLIST_FIRST;
-       int new_element = editor_elements[element_position + element_shift];
+
+       new_element = editor_elements[element_position + element_shift];
 
        if (IS_EDITOR_CASCADE(new_element))
        {
@@ -14513,7 +14609,6 @@ static void ClearEditorGadgetInfoText(void)
 void PrintEditorGadgetInfoText(struct GadgetInfo *gi)
 {
   char infotext[MAX_OUTPUT_LINESIZE + 1];
-  char shortcut[MAX_OUTPUT_LINESIZE + 1];
   int max_infotext_len = getMaxInfoTextLength();
 
   if (gi == NULL || strlen(gi->info_text) == 0)
@@ -14528,6 +14623,8 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi)
 
     if (key)
     {
+      char shortcut[MAX_OUTPUT_LINESIZE + 1];
+
       if (gi->custom_id == GADGET_ID_SINGLE_ITEMS)
        sprintf(shortcut, " ('.' or '%c')", key);
       else if (gi->custom_id == GADGET_ID_PICK_ELEMENT)
@@ -14571,7 +14668,6 @@ void HandleEditorGadgetInfoText(void *ptr)
 
 static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
 {
-  static int start_lx, start_ly;
   int id = gi->custom_id;
   int type_id = gi->custom_type_id;
   int sx = gi->event.x;
@@ -14584,7 +14680,6 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
   int actual_drawing_function = drawing_function;
   int max_infotext_len = getMaxInfoTextLength();
   char infotext[MAX_OUTPUT_LINESIZE + 1];
-  char *text;
 
   infotext[0] = '\0';          // start with empty info text
 
@@ -14625,6 +14720,10 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
     {
       if (button_status)       // if (gi->state == GD_BUTTON_PRESSED)
       {
+       static int start_lx = 0;
+       static int start_ly = 0;
+       char *text;
+
        if (gi->event.type == GD_EVENT_PRESSED)
        {
          start_lx = lx;