added option to explode gray ball instead of melting for MM engine
authorHolger Schemel <info@artsoft.org>
Thu, 23 Feb 2023 18:06:59 +0000 (19:06 +0100)
committerHolger Schemel <info@artsoft.org>
Thu, 23 Feb 2023 18:06:59 +0000 (19:06 +0100)
src/editor.c
src/files.c
src/game_mm/export.h
src/game_mm/mm_game.c
src/main.h

index 8d8d9c629d2e3aaeb72d231f45ed0ca00c02d171..10ff5a7f8463771253829dbd90443f7f2d468010 100644 (file)
@@ -688,6 +688,7 @@ enum
   GADGET_ID_DF_LASER_GREEN,
   GADGET_ID_DF_LASER_BLUE,
   GADGET_ID_ROTATE_MM_BALL_CONTENT,
+  GADGET_ID_EXPLODE_MM_BALL,
   GADGET_ID_CUSTOM_INDESTRUCTIBLE,
   GADGET_ID_CUSTOM_CAN_EXPLODE,
   GADGET_ID_CUSTOM_EXPLODE_FIRE,
@@ -1002,6 +1003,7 @@ enum
   ED_CHECKBUTTON_ID_DF_LASER_GREEN,
   ED_CHECKBUTTON_ID_DF_LASER_BLUE,
   ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT,
+  ED_CHECKBUTTON_ID_EXPLODE_MM_BALL,
   ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC,
   ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1,
   ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE,
@@ -3387,6 +3389,13 @@ static struct
     NULL, NULL,
     "randomly rotate created content", "randomly rotate newly created content"
   },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(6),
+    GADGET_ID_EXPLODE_MM_BALL,         GADGET_ID_NONE,
+    &level.explode_mm_ball,
+    NULL, NULL,
+    "explode ball instead of melting", "use explosion to release ball content"
+  },
 
   // ---------- element settings: configure 1 (custom elements) ---------------
 
@@ -10148,6 +10157,7 @@ static void DrawPropertiesConfig(void)
       MapCounterButtons(ED_COUNTER_ID_MM_BALL_CONTENT);
       MapSelectboxGadget(ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE);
       MapCheckbuttonGadget(ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT);
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EXPLODE_MM_BALL);
 
       DrawMMBallContentArea();
     }
index bd631a46fb31f38fb395d7d83246f33da60932c0..6a4c5f62623e4654fcd5441204bae12b8afc3771 100644 (file)
@@ -926,6 +926,11 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
     &li.rotate_mm_ball_content,                TRUE
   },
+  {
+    EL_MM_GRAY_BALL,                   -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.explode_mm_ball,               FALSE
+  },
 
   {
     EL_MM_STEEL_BLOCK,                 -1,
@@ -4192,6 +4197,7 @@ static void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
   level_mm->num_ball_contents = level->num_mm_ball_contents;
   level_mm->ball_choice_mode = level->mm_ball_choice_mode;
   level_mm->rotate_ball_content = level->rotate_mm_ball_content;
+  level_mm->explode_ball = level->explode_mm_ball;
 
   for (i = 0; i < level->num_mm_ball_contents; i++)
     level_mm->ball_content[i] =
@@ -4244,6 +4250,7 @@ static void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
   level->num_mm_ball_contents = level_mm->num_ball_contents;
   level->mm_ball_choice_mode = level_mm->ball_choice_mode;
   level->rotate_mm_ball_content = level_mm->rotate_ball_content;
+  level->explode_mm_ball = level_mm->explode_ball;
 
   for (i = 0; i < level->num_mm_ball_contents; i++)
     level->mm_ball_content[i] =
index 7f31d68cdb2eeb741e6b8b06d5c166049997a12e..1cbf0b6a1f4e067ba2cb6431e2f85362109d3ae7 100644 (file)
@@ -180,6 +180,7 @@ struct LevelInfo_MM
   int ball_choice_mode;
   int ball_content[MM_MAX_BALL_CONTENTS];
   boolean rotate_ball_content;
+  boolean explode_ball;
 
   short field[MAX_PLAYFIELD_WIDTH][MAX_PLAYFIELD_HEIGHT];
 };
index cda5e6aee9db15eba2061ac419ba873fe2125ae9..78f0f954b802fa246733bee85a6ec434f6eeb3ca 100644 (file)
@@ -2727,12 +2727,14 @@ static void Explode_MM(int x, int y, int phase, int mode)
       Tile[x][y] = center_element;
     }
 
-    Store[x][y] = EL_EMPTY;
+    if (center_element != EL_GRAY_BALL_ACTIVE)
+      Store[x][y] = EL_EMPTY;
     Store2[x][y] = center_element;
 
     Tile[x][y] = EL_EXPLODING_OPAQUE;
 
     GfxElement[x][y] = (center_element == EL_BOMB_ACTIVE ? EL_BOMB :
+                       center_element == EL_GRAY_BALL_ACTIVE ? EL_GRAY_BALL :
                        IS_MCDUFFIN(center_element) ? EL_MCDUFFIN :
                        center_element);
 
@@ -2783,6 +2785,9 @@ static void Explode_MM(int x, int y, int phase, int mode)
 
     InitField(x, y, FALSE);
     DrawField_MM(x, y);
+
+    if (center_element == EL_GRAY_BALL_ACTIVE)
+      ScanLaser_FromLastMirror();
   }
   else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
   {
@@ -3497,9 +3502,12 @@ static void GameActions_MM_Ext(void)
       Store2[ELX][ELY] = TRUE;
     }
 
-    Tile[ELX][ELY] = EL_GRAY_BALL_OPENING;
+    if (native_mm_level.explode_ball)
+      Bang_MM(ELX, ELY);
+    else
+      Tile[ELX][ELY] = EL_GRAY_BALL_OPENING;
 
-    laser.dest_element_last = Tile[ELX][ELY];
+    laser.dest_element = laser.dest_element_last = Tile[ELX][ELY];
 
     return;
   }
index 26e0570ad0bdc3c62abc727ae35dd98b39372f12..bd672e761804526e148f6ffcc0201baad76df192 100644 (file)
@@ -3312,6 +3312,7 @@ struct LevelInfo
   int mm_ball_choice_mode;
   int mm_ball_content[MAX_MM_BALL_CONTENTS];
   boolean rotate_mm_ball_content;
+  boolean explode_mm_ball;
 
   // ('int' instead of 'boolean' because used as selectbox value in editor)
   int use_step_counter;                // count steps instead of seconds for level