added support for rocket launcher in BD engine
authorHolger Schemel <info@artsoft.org>
Mon, 1 Apr 2024 21:56:50 +0000 (23:56 +0200)
committerHolger Schemel <info@artsoft.org>
Mon, 1 Apr 2024 21:56:50 +0000 (23:56 +0200)
14 files changed:
docs/elements/bd_rocket.txt [new file with mode: 0644]
docs/elements/bd_rocket_launcher.txt [new file with mode: 0644]
graphics/gfx_classic/boulder_rush.png
src/conf_gfx.c
src/editor.c
src/files.c
src/game_bd/bd_cave.c
src/game_bd/bd_cave.h
src/game_bd/bd_cavedb.c
src/game_bd/bd_caveengine.c
src/game_bd/bd_elements.h
src/main.c
src/main.h
src/tools.c

diff --git a/docs/elements/bd_rocket.txt b/docs/elements/bd_rocket.txt
new file mode 100644 (file)
index 0000000..d2bcca2
--- /dev/null
@@ -0,0 +1 @@
+A rocket that can be fired using the rocket launcher.
diff --git a/docs/elements/bd_rocket_launcher.txt b/docs/elements/bd_rocket_launcher.txt
new file mode 100644 (file)
index 0000000..92c4822
--- /dev/null
@@ -0,0 +1,3 @@
+If you find a rocket launcher, you can pick it up, and fire rockets.
+To use it, press fire and a direction key. Be careful not to make an
+explosion which is too close to the player.
index d01e4ba20f74b8ba9ae0ae6321b8a7798ef10ea7..618f146298655c2efc7519b08422a30d1f022392 100644 (file)
Binary files a/graphics/gfx_classic/boulder_rush.png and b/graphics/gfx_classic/boulder_rush.png differ
index c99b77162d38bde31cb4c574ce974759305901bb..127d38a42e4f28b61e57a5c4e539729f3817d561 100644 (file)
@@ -168,6 +168,12 @@ struct ConfigInfo image_config[] =
   { "bd_player_with_bomb.frames",                      "1"                             },
   { "bd_player_with_bomb.scale_up_factor",             "2"                             },
 
+  { "bd_player_with_rocket_launcher",                  "boulder_rush.png"              },
+  { "bd_player_with_rocket_launcher.xpos",             "1"                             },
+  { "bd_player_with_rocket_launcher.ypos",             "46"                            },
+  { "bd_player_with_rocket_launcher.frames",           "1"                             },
+  { "bd_player_with_rocket_launcher.scale_up_factor",  "2"                             },
+
   { "bd_player_stirring",                              "boulder_rush.png"              },
   { "bd_player_stirring.xpos",                         "3"                             },
   { "bd_player_stirring.ypos",                         "4"                             },
@@ -1222,6 +1228,38 @@ struct ConfigInfo image_config[] =
   { "bd_bomb.frames",                                  "1"                             },
   { "bd_bomb.scale_up_factor",                         "2"                             },
 
+  { "bd_rocket_launcher",                              "boulder_rush.png"              },
+  { "bd_rocket_launcher.xpos",                         "0"                             },
+  { "bd_rocket_launcher.ypos",                         "46"                            },
+  { "bd_rocket_launcher.frames",                       "1"                             },
+  { "bd_rocket_launcher.scale_up_factor",              "2"                             },
+
+  { "bd_rocket",                                       "boulder_rush.png"              },
+  { "bd_rocket.xpos",                                  "5"                             },
+  { "bd_rocket.ypos",                                  "45"                            },
+  { "bd_rocket.frames",                                        "1"                             },
+  { "bd_rocket.scale_up_factor",                       "2"                             },
+  { "bd_rocket.right",                                 "boulder_rush.png"              },
+  { "bd_rocket.right.xpos",                            "4"                             },
+  { "bd_rocket.right.ypos",                            "45"                            },
+  { "bd_rocket.right.frames",                          "1"                             },
+  { "bd_rocket.right.scale_up_factor",                 "2"                             },
+  { "bd_rocket.up",                                    "boulder_rush.png"              },
+  { "bd_rocket.up.xpos",                               "5"                             },
+  { "bd_rocket.up.ypos",                               "45"                            },
+  { "bd_rocket.up.frames",                             "1"                             },
+  { "bd_rocket.up.scale_up_factor",                    "2"                             },
+  { "bd_rocket.left",                                  "boulder_rush.png"              },
+  { "bd_rocket.left.xpos",                             "6"                             },
+  { "bd_rocket.left.ypos",                             "45"                            },
+  { "bd_rocket.left.frames",                           "1"                             },
+  { "bd_rocket.left.scale_up_factor",                  "2"                             },
+  { "bd_rocket.down",                                  "boulder_rush.png"              },
+  { "bd_rocket.down.xpos",                             "7"                             },
+  { "bd_rocket.down.ypos",                             "45"                            },
+  { "bd_rocket.down.frames",                           "1"                             },
+  { "bd_rocket.down.scale_up_factor",                  "2"                             },
+
   { "bd_nitro_pack",                                   "RocksBD.png"                   },
   { "bd_nitro_pack.xpos",                              "3"                             },
   { "bd_nitro_pack.ypos",                              "4"                             },
index 40b1f51f0375ffa6341cfeeecfe5f7d9885b4a2c..a4762db74a1e5930155e93937a5c4f588e1e478f 100644 (file)
@@ -765,6 +765,7 @@ enum
   GADGET_ID_BD_CONVEYOR_BELTS_CHANGED,
   GADGET_ID_BD_WATER_CANNOT_FLOW_DOWN,
   GADGET_ID_BD_HAMMER_WALLS_REAPPEAR,
+  GADGET_ID_BD_INFINITE_ROCKETS,
   GADGET_ID_BD_CREATURES_START_BACKWARDS,
   GADGET_ID_BD_CREATURES_TURN_ON_HATCHING,
   GADGET_ID_BD_GRAVITY_SWITCH_ACTIVE,
@@ -1120,6 +1121,7 @@ enum
   ED_CHECKBUTTON_ID_BD_CONVEYOR_BELTS_CHANGED,
   ED_CHECKBUTTON_ID_BD_WATER_CANNOT_FLOW_DOWN,
   ED_CHECKBUTTON_ID_BD_HAMMER_WALLS_REAPPEAR,
+  ED_CHECKBUTTON_ID_BD_INFINITE_ROCKETS,
   ED_CHECKBUTTON_ID_BD_CREATURES_START_BACKWARDS,
   ED_CHECKBUTTON_ID_BD_CREATURES_TURN_ON_HATCHING,
   ED_CHECKBUTTON_ID_BD_GRAVITY_SWITCH_ACTIVE,
@@ -3949,6 +3951,14 @@ static struct
     NULL, NULL,
     "Hammered walls reappear",                 "Hammered walls reappear after delay"
   },
+  {
+    ED_CHECKBUTTON_ID_BD_INFINITE_ROCKETS,
+    ED_ELEMENT_SETTINGS_XPOS(0),               ED_ELEMENT_SETTINGS_YPOS(0),
+    GADGET_ID_BD_INFINITE_ROCKETS,             GADGET_ID_NONE,
+    &level.bd_infinite_rockets,
+    NULL, NULL,
+    "Infinite rockets",                                "Rocket launcher has infinite rockets"
+  },
   {
     ED_CHECKBUTTON_ID_BD_CREATURES_START_BACKWARDS,
     ED_ELEMENT_SETTINGS_XPOS(0),               ED_ELEMENT_SETTINGS_YPOS(0),
@@ -5281,8 +5291,13 @@ static int editor_el_boulderdash_native[] =
 
   EL_BD_PLAYER,
   EL_BD_PLAYER_WITH_BOMB,
+  EL_BD_PLAYER_WITH_ROCKET_LAUNCHER,
+  EL_BD_ROCKET_LAUNCHER,
+
   EL_BD_PLAYER_GLUED,
   EL_BD_PLAYER_STIRRING,
+  EL_EMPTY,
+  EL_EMPTY,
 };
 static int *editor_hl_boulderdash_native_ptr = editor_hl_boulderdash_native;
 static int *editor_el_boulderdash_native_ptr = editor_el_boulderdash_native;
@@ -11734,6 +11749,7 @@ static boolean checkPropertiesConfig(int element)
       element == EL_BD_ROCK ||
       element == EL_BD_MEGA_ROCK ||
       element == EL_BD_BOMB ||
+      element == EL_BD_ROCKET_LAUNCHER ||
       element == EL_BD_NITRO_PACK ||
       element == EL_BD_SWEET ||
       element == EL_BD_VOODOO_DOLL ||
@@ -12216,6 +12232,11 @@ static void DrawPropertiesConfig(void)
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_HAMMER_WALLS_REAPPEAR);
   }
 
+  if (properties_element == EL_BD_ROCKET_LAUNCHER)
+  {
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_INFINITE_ROCKETS);
+  }
+
   if (properties_element == EL_BD_CREATURE_SWITCH)
   {
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_CREATURES_START_BACKWARDS);
index a0c0564cb99a1e2215169e8ec59b2a23186a8c00..157564d824603e3cdac3a0cfbc8d1823735fb368 100644 (file)
@@ -950,6 +950,12 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     &li.bd_hammer_walls_reappear_delay,        100
   },
 
+  {
+    EL_BD_ROCKET_LAUNCHER,             -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_infinite_rockets,           FALSE
+  },
+
   {
     EL_BD_SKELETON,                    -1,
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
@@ -4326,6 +4332,8 @@ static void CopyNativeLevel_RND_to_BD(struct LevelInfo *level)
   cave->hammered_walls_reappear                = level->bd_hammer_walls_reappear;
   cave->hammered_wall_reappear_frame   = level->bd_hammer_walls_reappear_delay;
 
+  cave->infinite_rockets               = level->bd_infinite_rockets;
+
   cave->skeletons_needed_for_pot       = level->bd_num_skeletons_needed_for_pot;
   cave->skeletons_worth_diamonds       = level->bd_skeleton_worth_num_diamonds;
 
@@ -4487,6 +4495,8 @@ static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level)
   level->bd_hammer_walls_reappear      = cave->hammered_walls_reappear;
   level->bd_hammer_walls_reappear_delay        = cave->hammered_wall_reappear_frame;
 
+  level->bd_infinite_rockets           = cave->infinite_rockets;
+
   level->bd_num_skeletons_needed_for_pot= cave->skeletons_needed_for_pot;
   level->bd_skeleton_worth_num_diamonds        = cave->skeletons_worth_diamonds;
 
index ea56d6da706c612ed61196792269e7db2e70f538..88fa93299f57d61f39ce44e38802ab87f576978c 100644 (file)
@@ -1314,12 +1314,15 @@ void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer
   elemdrawing[O_PLAYER] = draw;
   elemdrawing[O_PLAYER_GLUED] = draw;
 
-  // player with bomb does not blink or tap - no graphics drawn for that.
-  // running is drawn using w/o bomb cells */
+  // player with bomb/rocketlauncher does not blink or tap - no graphics drawn for that.
+  // running is drawn using w/o bomb/rocketlauncher cells */
   if (cave->last_direction != GD_MV_STILL)
   {
     elemmapping[O_PLAYER_BOMB] = map;
     elemdrawing[O_PLAYER_BOMB] = draw;
+
+    elemmapping[O_PLAYER_ROCKET_LAUNCHER] = map;
+    elemdrawing[O_PLAYER_ROCKET_LAUNCHER] = draw;
   }
 
   elemmapping[O_INBOX] = (cave->inbox_flash_toggle ? O_INBOX_OPEN : O_INBOX_CLOSED);
index 67eed046d9acb48c6dbfddf80a62f6a43d4df46d..b1ec47f398f0b38334c09812b7b7012682038245 100644 (file)
@@ -82,7 +82,7 @@ void gd_struct_set_defaults_from_array(void *str, const GdStructDescriptor *prop
 
 // these define the number of the cells in the png file
 #define GD_NUM_OF_CELLS_X      8
-#define GD_NUM_OF_CELLS_Y      46
+#define GD_NUM_OF_CELLS_Y      47
 
 // +80: placeholder for cells which are rendered by the game;
 // for example diamond + arrow = falling diamond
@@ -530,6 +530,9 @@ typedef struct _gd_cave
   int hammered_wall_reappear_frame;
   boolean pneumatic_hammer_sound;
 
+  boolean infinite_rockets;             // if true, the player which got a rocket launcher will be
+                                        // able to launch an infinite number of rockets
+
   // internal variables, used during the game. private data :)
 
   // returns range corrected x/y position (points to perfect or line shifting get function)
index 0952e68bbcf7683454d165afa5d8858545d65a6e..34084767e5d4610cdb8401473480229212c824af 100644 (file)
@@ -287,9 +287,16 @@ GdElements gd_elements[] =
   { O_PRE_PL_3, N_("Player birth (3)"), 0, "GUYBIRTH3", 0, 34, 34, 34 },
   { O_PLAYER, N_("Player"), P_BLOWS_UP_FLIES | P_EXPLODES_BY_HIT | P_PLAYER, "GUY", 0, i_player, i_player, 35, 32 },    // has ckdelay
   { O_PLAYER_BOMB, N_("Player with bomb"), P_BLOWS_UP_FLIES | P_EXPLODES_BY_HIT | P_PLAYER, "GUYBOMB", 0, 42, 42, 42, 25 },    // has ckdelay
+  { O_PLAYER_ROCKET_LAUNCHER, N_("Player with rocket launcher"), P_BLOWS_UP_FLIES | P_EXPLODES_BY_HIT | P_PLAYER, "GUYROCKETLAUNCER", 0, 369, 369, 369, 25 },    // has ckdelay
   { O_PLAYER_GLUED, N_("Glued player"), P_BLOWS_UP_FLIES | P_EXPLODES_BY_HIT, "GUYGLUED", 0, i_player_glued, i_player_glued, 35 },    // is not a real player! so active x, y will not find it. no P_PLAYER bit!
   { O_PLAYER_STIRRING, N_("Player stirring"), P_BLOWS_UP_FLIES | P_EXPLODES_BY_HIT | P_PLAYER, "GUYSTIRRING", 0, 256, -256, -256 },
 
+  { O_ROCKET_LAUNCHER, N_("Rocket launcher"), 0, "ROCKET_LAUNCHER", 0, 368, 368, 368 },
+  { O_ROCKET_1, N_("Rocket (right)"), 0, "ROCKETr", 0, 364, 364, 364, 40 },    // has ckdelay
+  { O_ROCKET_2, N_("Rocket (up)"), 0, "ROCKETu", 0, 365, 365, 365, 40 },    // has ckdelay
+  { O_ROCKET_3, N_("Rocket (left)"), 0, "ROCKETl", 0, 366, 366, 366, 40 },    // has ckdelay
+  { O_ROCKET_4, N_("Rocket (down)"), 0, "ROCKETd", 0, 367, 367, 367, 40 },    // has ckdelay
+
   { O_BOMB, N_("Bomb"), P_COLLECTIBLE, "BOMB", 0, 48, 48, 48 },
   { O_BOMB_TICK_1, N_("Ticking bomb (1)"), P_EXPLOSION_FIRST_STAGE, "IGNITEDBOMB1", 0, 49, 49, 49 },
   { O_BOMB_TICK_2, N_("Ticking bomb (2)"), 0, "IGNITEDBOMB2", 0, 50, 50, 50 },
@@ -489,6 +496,11 @@ const GdStructDescriptor gd_cave_properties[] =
   {"", GD_LABEL, 0, N_("Sweet")},
   {"PushingBoulderProb", GD_TYPE_PROBABILITY, 0, N_("Probability of pushing (%)"), CAVE_OFFSET(pushing_stone_prob_sweet), 1, N_("Chance of player managing to push a stone, every game cycle he tries. This is used after eating sweet.")},
   {"PushingMegaStonesAfterSweet", GD_TYPE_BOOLEAN, 0, N_("Mega stones pushable"), CAVE_OFFSET(mega_stones_pushable_with_sweet), 1, N_("If it is true, mega stones can be pushed after eating sweet.")},
+
+  // rocket launcher
+  {"", GD_LABEL, 0, N_("Rocket launcher")},
+  {"RocketLauncher.infinite", GD_TYPE_BOOLEAN, 0, N_("Infinite rockets"), CAVE_OFFSET(infinite_rockets), 1, N_("If it is true, the player is able to launch an infinite number of rockets. Otherwise every rocket launcher contains only a single rocket.")},
+
   // pneumatic hammer
   {"", GD_LABEL, 0, N_("Pneumatic hammer")},
   {"PneumaticHammer.frames", GD_TYPE_INT, 0, N_("Time for hammer (frames)"), CAVE_OFFSET(pneumatic_hammer_frame), 1, N_("This is the number of game frames, a pneumatic hammer is required to break a wall."), 1, 100},
index 03722b801ca1e62f9943f583685a8ea07d2745ea..e95236ce6b73c8a5994635adf1d08ee76fc82ebf 100644 (file)
@@ -748,6 +748,13 @@ static void explode(GdCave *cave, int x, int y)
       creature_explode(cave, x, y, O_EXPLODE_1);
       break;
 
+    case O_ROCKET_1:
+    case O_ROCKET_2:
+    case O_ROCKET_3:
+    case O_ROCKET_4:
+      creature_explode(cave, x, y, O_EXPLODE_1);
+      break;
+
     case O_BUTTER_1:
     case O_BUTTER_2:
     case O_BUTTER_3:
@@ -780,6 +787,7 @@ static void explode(GdCave *cave, int x, int y)
     case O_PLAYER_BOMB:
     case O_PLAYER_GLUED:
     case O_PLAYER_STIRRING:
+    case O_PLAYER_ROCKET_LAUNCHER:
     case O_PLAYER_PNEUMATIC_LEFT:
     case O_PLAYER_PNEUMATIC_RIGHT:
       creature_explode(cave, x, y, O_EXPLODE_1);
@@ -1747,6 +1755,19 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire,
                    move(cave, x, y, player_move, O_PLAYER_BOMB);
                  break;
 
+               case O_ROCKET_LAUNCHER:
+                 // if its a rocket launcher, remember he now has one.
+                 // we do not change the "remains" and "what" variables,
+                 // so that part of the code will be ineffective
+                 gd_sound_play(cave, GD_S_BOMB_COLLECTING, what, x, y);
+                 store_dir(cave, x, y, player_move, O_SPACE);
+
+                 if (player_fire)
+                   store(cave, x, y, O_PLAYER_ROCKET_LAUNCHER);
+                 else
+                   move(cave, x, y, player_move, O_PLAYER_ROCKET_LAUNCHER);
+                 break;
+
                case O_POT:
                  // we do not change the "remains" and "what" variables,
                  // so that part of the code will be ineffective
@@ -1888,6 +1909,98 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire,
          }
          break;
 
+       case O_PLAYER_ROCKET_LAUNCHER:
+         // much simpler; cannot snap-push stones
+         if (cave->kill_player)
+         {
+           explode(cave, x, y);
+           break;
+         }
+
+         cave->player_seen_ago = 0;
+         // bd4 intermission caves have many players. so if one of them has exited,
+         // do not change the flag anymore. so this if () is needed
+         if (cave->player_state != GD_PL_EXITED)
+           cave->player_state = GD_PL_LIVING;
+
+         // firing a rocket?
+         if (player_move != GD_MV_STILL)
+         {
+           // if the player does not move, nothing to do
+           GdElement what = get_dir(cave, x, y, player_move);
+           GdElement remains = what;
+
+           // to fire a rocket, diagonal movement should not be allowed.
+           // so either x or y must be zero
+           if (player_fire)
+           {
+             // placing a rocket into empty space
+             if (is_space_dir(cave, x, y, player_move))
+             {
+               switch (player_move)
+               {
+                 case GD_MV_RIGHT:
+                   store_dir(cave, x, y, player_move, O_ROCKET_1);
+                   if (!cave->infinite_rockets)
+                     store(cave, x, y, O_PLAYER);
+                   break;
+
+                 case GD_MV_UP:
+                   store_dir(cave, x, y, player_move, O_ROCKET_2);
+                   if (!cave->infinite_rockets)
+                     store(cave, x, y, O_PLAYER);
+                   break;
+
+                 case GD_MV_LEFT:
+                   store_dir(cave, x, y, player_move, O_ROCKET_3);
+                   if (!cave->infinite_rockets)
+                     store(cave, x, y, O_PLAYER);
+                   break;
+
+                 case GD_MV_DOWN:
+                   store_dir(cave, x, y, player_move, O_ROCKET_4);
+                   if (!cave->infinite_rockets)
+                     store(cave, x, y, O_PLAYER);
+                   break;
+
+                 default:
+                   // cannot fire in other directions
+                   break;
+               }
+
+               gd_sound_play(cave, GD_S_BOMB_PLACING, O_BOMB, x, y);
+             }
+
+             // a player with rocket launcher cannot snap elements, so stop here
+             break;
+           }
+
+           // pushing and collecting
+           // if we are 'eating' a teleporter, and the function returns true
+           // (teleporting worked), break here
+           if (what == O_TELEPORTER && do_teleporter(cave, x, y, player_move))
+             break;
+
+           // player fire is false...
+           if (do_push(cave, x, y, player_move, FALSE))
+           {
+             remains = O_SPACE;
+           }
+           else
+           {
+             // get element. if cannot get, player_get_element will return the same
+             remains = player_get_element(cave, what, x, y);
+           }
+
+           // if something changed, OR there is space, move.
+           if (remains != what || remains == O_SPACE)
+           {
+             // if anything changed, apply the change.
+             move(cave, x, y, player_move, O_PLAYER_ROCKET_LAUNCHER);
+           }
+         }
+         break;
+
        case O_PLAYER_STIRRING:
          if (cave->kill_player)
          {
@@ -3169,6 +3282,38 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire,
          }
          break;
 
+         // ============================================================================
+         //    R O C K E T S
+         // ============================================================================
+
+       case O_ROCKET_1:
+         if (is_space_dir(cave, x, y, GD_MV_RIGHT))
+           move(cave, x, y, GD_MV_RIGHT, O_ROCKET_1);
+         else
+           explode(cave, x, y);
+         break;
+
+       case O_ROCKET_2:
+         if (is_space_dir(cave, x, y, GD_MV_UP))
+           move(cave, x, y, GD_MV_UP, O_ROCKET_2);
+         else
+           explode(cave, x, y);
+         break;
+
+       case O_ROCKET_3:
+         if (is_space_dir(cave, x, y, GD_MV_LEFT))
+           move(cave, x, y, GD_MV_LEFT, O_ROCKET_3);
+         else
+           explode(cave, x, y);
+         break;
+
+       case O_ROCKET_4:
+         if (is_space_dir(cave, x, y, GD_MV_DOWN))
+           move(cave, x, y, GD_MV_DOWN, O_ROCKET_4);
+         else
+           explode(cave, x, y);
+         break;
+
          // ============================================================================
          //    S I M P L E   C H A N G I N G;   E X P L O S I O N S
          // ============================================================================
index ab5d5fc5800163eeb2f38da4d454357b504931fa..de04d23aa6de5d875beb012412633e570a8af5a2 100644 (file)
@@ -190,9 +190,16 @@ typedef enum _element
   O_PRE_PL_3,
   O_PLAYER,
   O_PLAYER_BOMB,
+  O_PLAYER_ROCKET_LAUNCHER,
   O_PLAYER_GLUED,
   O_PLAYER_STIRRING,
 
+  O_ROCKET_LAUNCHER,
+  O_ROCKET_1,
+  O_ROCKET_2,
+  O_ROCKET_3,
+  O_ROCKET_4,
+
   O_BOMB,
   O_BOMB_TICK_1,
   O_BOMB_TICK_2,
index bff898d02db9059997c48d966b91fd4c6fcf7f7e..b278a0df17172e77dd264d7da67bfcd6bb3b4259 100644 (file)
@@ -7107,6 +7107,11 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "bd_player",
     "Player with bomb",
   },
+  {
+    "bd_player_with_rocket_launcher",
+    "bd_player",
+    "Player with rocket launcher",
+  },
   {
     "bd_player_glued",
     "bd_player",
@@ -7117,6 +7122,36 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "bd_player",
     "Stirring player"
   },
+  {
+    "bd_rocket_launcher",
+    "bd_rocket_launcher",
+    "Rocket launcher",
+  },
+  {
+    "bd_rocket",
+    "bd_rocket",
+    "Rocket",
+  },
+  {
+    "bd_rocket.right",
+    "bd_rocket",
+    "Rocket (starts moving right)"
+  },
+  {
+    "bd_rocket.up",
+    "bd_rocket",
+    "Rocket (starts moving up)"
+  },
+  {
+    "bd_rocket.left",
+    "bd_rocket",
+    "Rocket (starts moving left)"
+  },
+  {
+    "bd_rocket.down",
+    "bd_rocket",
+    "Rocket (starts moving down)"
+  },
   {
     "bd_fake_bonus",
     "bd_fake_bonus",
index 2a630a1e887614d9b5d7cbffa8422f3aa453dae7..04b6021aed78e26600ff8c9b6a2ccd01c342a1c0 100644 (file)
 #define EL_BD_NITRO_PACK                       1379
 #define EL_BD_PLAYER                           1380
 #define EL_BD_PLAYER_WITH_BOMB                 1381
-#define EL_BD_PLAYER_GLUED                     1382
-#define EL_BD_PLAYER_STIRRING                  1383
-#define EL_BD_FAKE_BONUS                       1384
-#define EL_BD_COVERED                          1385
+#define EL_BD_PLAYER_WITH_ROCKET_LAUNCHER      1382
+#define EL_BD_PLAYER_GLUED                     1383
+#define EL_BD_PLAYER_STIRRING                  1384
+#define EL_BD_ROCKET_LAUNCHER                  1385
+#define EL_BD_ROCKET                           1386
+#define EL_BD_ROCKET_RIGHT                     1387
+#define EL_BD_ROCKET_UP                                1388
+#define EL_BD_ROCKET_LEFT                      1389
+#define EL_BD_ROCKET_DOWN                      1390
+#define EL_BD_FAKE_BONUS                       1391
+#define EL_BD_COVERED                          1392
 
 // BD style elements ("effects"; mostly runtime elements, but can also be stored in level file)
-#define EL_BD_SAND_BALL_FALLING                        1386
-#define EL_BD_SAND_LOOSE_FALLING               1387
-#define EL_BD_ROCK_FALLING                     1388
-#define EL_BD_FLYING_ROCK_FLYING               1389
-#define EL_BD_MEGA_ROCK_FALLING                        1390
-#define EL_BD_DIAMOND_FALLING                  1391
-#define EL_BD_FLYING_DIAMOND_FLYING            1392
-#define EL_BD_NUT_FALLING                      1393
-#define EL_BD_FALLING_WALL_FALLING             1394
-#define EL_BD_NITRO_PACK_FALLING               1395
-#define EL_BD_WATER_1                          1396
-#define EL_BD_WATER_2                          1397
-#define EL_BD_WATER_3                          1398
-#define EL_BD_WATER_4                          1399
-#define EL_BD_WATER_5                          1400
-#define EL_BD_WATER_6                          1401
-#define EL_BD_WATER_7                          1402
-#define EL_BD_WATER_8                          1403
-#define EL_BD_WATER_9                          1404
-#define EL_BD_WATER_10                         1405
-#define EL_BD_WATER_11                         1406
-#define EL_BD_WATER_12                         1407
-#define EL_BD_WATER_13                         1408
-#define EL_BD_WATER_14                         1409
-#define EL_BD_WATER_15                         1410
-#define EL_BD_WATER_16                         1411
-#define EL_BD_COW_ENCLOSED_1                   1412
-#define EL_BD_COW_ENCLOSED_2                   1413
-#define EL_BD_COW_ENCLOSED_3                   1414
-#define EL_BD_COW_ENCLOSED_4                   1415
-#define EL_BD_COW_ENCLOSED_5                   1416
-#define EL_BD_COW_ENCLOSED_6                   1417
-#define EL_BD_COW_ENCLOSED_7                   1418
-#define EL_BD_BLADDER_1                                1419
-#define EL_BD_BLADDER_2                                1420
-#define EL_BD_BLADDER_3                                1421
-#define EL_BD_BLADDER_4                                1422
-#define EL_BD_BLADDER_5                                1423
-#define EL_BD_BLADDER_6                                1424
-#define EL_BD_BLADDER_7                                1425
-#define EL_BD_BLADDER_8                                1426
-#define EL_BD_PLAYER_GROWING_1                 1427
-#define EL_BD_PLAYER_GROWING_2                 1428
-#define EL_BD_PLAYER_GROWING_3                 1429
-#define EL_BD_BOMB_TICKING_1                   1430
-#define EL_BD_BOMB_TICKING_2                   1431
-#define EL_BD_BOMB_TICKING_3                   1432
-#define EL_BD_BOMB_TICKING_4                   1433
-#define EL_BD_BOMB_TICKING_5                   1434
-#define EL_BD_BOMB_TICKING_6                   1435
-#define EL_BD_BOMB_TICKING_7                   1436
-#define EL_BD_CLOCK_GROWING_1                  1437
-#define EL_BD_CLOCK_GROWING_2                  1438
-#define EL_BD_CLOCK_GROWING_3                  1439
-#define EL_BD_CLOCK_GROWING_4                  1440
-#define EL_BD_DIAMOND_GROWING_1                        1441
-#define EL_BD_DIAMOND_GROWING_2                        1442
-#define EL_BD_DIAMOND_GROWING_3                        1443
-#define EL_BD_DIAMOND_GROWING_4                        1444
-#define EL_BD_DIAMOND_GROWING_5                        1445
-#define EL_BD_EXPLODING_1                      1446
-#define EL_BD_EXPLODING_2                      1447
-#define EL_BD_EXPLODING_3                      1448
-#define EL_BD_EXPLODING_4                      1449
-#define EL_BD_EXPLODING_5                      1450
-#define EL_BD_ROCK_GROWING_1                   1451
-#define EL_BD_ROCK_GROWING_2                   1452
-#define EL_BD_ROCK_GROWING_3                   1453
-#define EL_BD_ROCK_GROWING_4                   1454
-#define EL_BD_STEELWALL_GROWING_1              1455
-#define EL_BD_STEELWALL_GROWING_2              1456
-#define EL_BD_STEELWALL_GROWING_3              1457
-#define EL_BD_STEELWALL_GROWING_4              1458
-#define EL_BD_GHOST_EXPLODING_1                        1459
-#define EL_BD_GHOST_EXPLODING_2                        1460
-#define EL_BD_GHOST_EXPLODING_3                        1461
-#define EL_BD_GHOST_EXPLODING_4                        1462
-#define EL_BD_BOMB_EXPLODING_1                 1463
-#define EL_BD_BOMB_EXPLODING_2                 1464
-#define EL_BD_BOMB_EXPLODING_3                 1465
-#define EL_BD_BOMB_EXPLODING_4                 1466
-#define EL_BD_NITRO_PACK_EXPLODING             1467
-#define EL_BD_NITRO_PACK_EXPLODING_1           1468
-#define EL_BD_NITRO_PACK_EXPLODING_2           1469
-#define EL_BD_NITRO_PACK_EXPLODING_3           1470
-#define EL_BD_NITRO_PACK_EXPLODING_4           1471
-#define EL_BD_AMOEBA_2_EXPLODING_1             1472
-#define EL_BD_AMOEBA_2_EXPLODING_2             1473
-#define EL_BD_AMOEBA_2_EXPLODING_3             1474
-#define EL_BD_AMOEBA_2_EXPLODING_4             1475
-#define EL_BD_NUT_BREAKING_1                   1476
-#define EL_BD_NUT_BREAKING_2                   1477
-#define EL_BD_NUT_BREAKING_3                   1478
-#define EL_BD_NUT_BREAKING_4                   1479
-
-#define NUM_FILE_ELEMENTS                      1480
+#define EL_BD_SAND_BALL_FALLING                        1393
+#define EL_BD_SAND_LOOSE_FALLING               1394
+#define EL_BD_ROCK_FALLING                     1395
+#define EL_BD_FLYING_ROCK_FLYING               1396
+#define EL_BD_MEGA_ROCK_FALLING                        1397
+#define EL_BD_DIAMOND_FALLING                  1398
+#define EL_BD_FLYING_DIAMOND_FLYING            1399
+#define EL_BD_NUT_FALLING                      1400
+#define EL_BD_FALLING_WALL_FALLING             1401
+#define EL_BD_NITRO_PACK_FALLING               1402
+#define EL_BD_WATER_1                          1403
+#define EL_BD_WATER_2                          1404
+#define EL_BD_WATER_3                          1405
+#define EL_BD_WATER_4                          1406
+#define EL_BD_WATER_5                          1407
+#define EL_BD_WATER_6                          1408
+#define EL_BD_WATER_7                          1409
+#define EL_BD_WATER_8                          1410
+#define EL_BD_WATER_9                          1411
+#define EL_BD_WATER_10                         1412
+#define EL_BD_WATER_11                         1413
+#define EL_BD_WATER_12                         1414
+#define EL_BD_WATER_13                         1415
+#define EL_BD_WATER_14                         1416
+#define EL_BD_WATER_15                         1417
+#define EL_BD_WATER_16                         1418
+#define EL_BD_COW_ENCLOSED_1                   1419
+#define EL_BD_COW_ENCLOSED_2                   1420
+#define EL_BD_COW_ENCLOSED_3                   1421
+#define EL_BD_COW_ENCLOSED_4                   1422
+#define EL_BD_COW_ENCLOSED_5                   1423
+#define EL_BD_COW_ENCLOSED_6                   1424
+#define EL_BD_COW_ENCLOSED_7                   1425
+#define EL_BD_BLADDER_1                                1426
+#define EL_BD_BLADDER_2                                1427
+#define EL_BD_BLADDER_3                                1428
+#define EL_BD_BLADDER_4                                1429
+#define EL_BD_BLADDER_5                                1430
+#define EL_BD_BLADDER_6                                1431
+#define EL_BD_BLADDER_7                                1432
+#define EL_BD_BLADDER_8                                1433
+#define EL_BD_PLAYER_GROWING_1                 1434
+#define EL_BD_PLAYER_GROWING_2                 1435
+#define EL_BD_PLAYER_GROWING_3                 1436
+#define EL_BD_BOMB_TICKING_1                   1437
+#define EL_BD_BOMB_TICKING_2                   1438
+#define EL_BD_BOMB_TICKING_3                   1439
+#define EL_BD_BOMB_TICKING_4                   1440
+#define EL_BD_BOMB_TICKING_5                   1441
+#define EL_BD_BOMB_TICKING_6                   1442
+#define EL_BD_BOMB_TICKING_7                   1443
+#define EL_BD_CLOCK_GROWING_1                  1444
+#define EL_BD_CLOCK_GROWING_2                  1445
+#define EL_BD_CLOCK_GROWING_3                  1446
+#define EL_BD_CLOCK_GROWING_4                  1447
+#define EL_BD_DIAMOND_GROWING_1                        1448
+#define EL_BD_DIAMOND_GROWING_2                        1449
+#define EL_BD_DIAMOND_GROWING_3                        1450
+#define EL_BD_DIAMOND_GROWING_4                        1451
+#define EL_BD_DIAMOND_GROWING_5                        1452
+#define EL_BD_EXPLODING_1                      1453
+#define EL_BD_EXPLODING_2                      1454
+#define EL_BD_EXPLODING_3                      1455
+#define EL_BD_EXPLODING_4                      1456
+#define EL_BD_EXPLODING_5                      1457
+#define EL_BD_ROCK_GROWING_1                   1458
+#define EL_BD_ROCK_GROWING_2                   1459
+#define EL_BD_ROCK_GROWING_3                   1460
+#define EL_BD_ROCK_GROWING_4                   1461
+#define EL_BD_STEELWALL_GROWING_1              1462
+#define EL_BD_STEELWALL_GROWING_2              1463
+#define EL_BD_STEELWALL_GROWING_3              1464
+#define EL_BD_STEELWALL_GROWING_4              1465
+#define EL_BD_GHOST_EXPLODING_1                        1466
+#define EL_BD_GHOST_EXPLODING_2                        1467
+#define EL_BD_GHOST_EXPLODING_3                        1468
+#define EL_BD_GHOST_EXPLODING_4                        1469
+#define EL_BD_BOMB_EXPLODING_1                 1470
+#define EL_BD_BOMB_EXPLODING_2                 1471
+#define EL_BD_BOMB_EXPLODING_3                 1472
+#define EL_BD_BOMB_EXPLODING_4                 1473
+#define EL_BD_NITRO_PACK_EXPLODING             1474
+#define EL_BD_NITRO_PACK_EXPLODING_1           1475
+#define EL_BD_NITRO_PACK_EXPLODING_2           1476
+#define EL_BD_NITRO_PACK_EXPLODING_3           1477
+#define EL_BD_NITRO_PACK_EXPLODING_4           1478
+#define EL_BD_AMOEBA_2_EXPLODING_1             1479
+#define EL_BD_AMOEBA_2_EXPLODING_2             1480
+#define EL_BD_AMOEBA_2_EXPLODING_3             1481
+#define EL_BD_AMOEBA_2_EXPLODING_4             1482
+#define EL_BD_NUT_BREAKING_1                   1483
+#define EL_BD_NUT_BREAKING_2                   1484
+#define EL_BD_NUT_BREAKING_3                   1485
+#define EL_BD_NUT_BREAKING_4                   1486
+
+#define NUM_FILE_ELEMENTS                      1487
 
 
 // "real" (and therefore drawable) runtime elements
@@ -3715,6 +3722,7 @@ struct LevelInfo
   int bd_hammer_walls_break_delay;     // BD hammer time for breaking walls (in BD frames)
   boolean bd_hammer_walls_reappear;    // BD hammered walls are reappearing after some delay
   int bd_hammer_walls_reappear_delay;  // BD hammer time for reappearing walls (in BD frames)
+  boolean bd_infinite_rockets;         // BD rocket launcher has infinite number of rockets
   int bd_num_skeletons_needed_for_pot; // BD skeletons amount must be collected to use a pot
   int bd_skeleton_worth_num_diamonds;  // BD skeleton collected is worth this number of diamonds
   int bd_expanding_wall_looks_like;    // BD expanding wall looks like this other game element
index 36fc6e153d20ed04708a385fd259c591f430c413..e05a197392679a7f1f0a2df6683dbdfa88d63b63 100644 (file)
@@ -6894,6 +6894,10 @@ bd_object_mapping_list[] =
     O_PLAYER_BOMB,                             TRUE,
     EL_BD_PLAYER_WITH_BOMB,                    -1, -1
   },
+  {
+    O_PLAYER_ROCKET_LAUNCHER,                  TRUE,
+    EL_BD_PLAYER_WITH_ROCKET_LAUNCHER,         -1, -1
+  },
   {
     O_PLAYER_GLUED,                            TRUE,
     EL_BD_PLAYER_GLUED,                                -1, -1
@@ -6902,6 +6906,26 @@ bd_object_mapping_list[] =
     O_PLAYER_STIRRING,                         TRUE,
     EL_BD_PLAYER_STIRRING,                     -1, -1
   },
+  {
+    O_ROCKET_LAUNCHER,                         TRUE,
+    EL_BD_ROCKET_LAUNCHER,                     -1, -1
+  },
+  {
+    O_ROCKET_1,                                        TRUE,
+    EL_BD_ROCKET_RIGHT,                                -1, -1
+  },
+  {
+    O_ROCKET_2,                                        TRUE,
+    EL_BD_ROCKET_UP,                           -1, -1
+  },
+  {
+    O_ROCKET_3,                                        TRUE,
+    EL_BD_ROCKET_LEFT,                         -1, -1
+  },
+  {
+    O_ROCKET_4,                                        TRUE,
+    EL_BD_ROCKET_DOWN,                         -1, -1
+  },
   {
     O_BOMB,                                    TRUE,
     EL_BD_BOMB,                                        -1, -1