cleanup of unnecessarily convoluted function call
[rocksndiamonds.git] / src / game_bd / bd_cavedb.c
index 8fac33019f3e0ab7d410d351f564f9d3d2526025..e3290c78fb6bfc9aacc96968970941c209d3d02b 100644 (file)
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <glib.h>
-#include <glib/gi18n.h>
-
 #include "main_bd.h"
 
 
-/* some cells are created inside the game (by merging two cells from the png etc);
-   those are used only in the editor.
-   this enum is used to give each and every one a different index automatically. */
+// some cells are created inside the game (by merging two cells from the png etc);
+// those are used only in the editor.
+// this enum is used to give each and every one a different index automatically.
 enum _generated_cells_indexes
 {
-  /* the first one gets the first available index. */
-  /* the following ones will be generated by the compiler automatically. */
+  // the first one gets the first available index.
+  // the following ones will be generated by the compiler automatically.
   i_stonefly_1 = GD_NUM_OF_CELLS_X * GD_NUM_OF_CELLS_Y,
   i_stonefly_2,
   i_stonefly_3,
@@ -82,7 +79,7 @@ enum _generated_cells_indexes
   i_pre_invis_outbox,
   i_unknown,
   i_waiting_stone,
-  i_pre_outbox_frame_1,    /* this will have 8 frames. */
+  i_pre_outbox_frame_1,    // this will have 8 frames.
   i_pre_outbox_frame_2,
   i_pre_outbox_frame_3,
   i_pre_outbox_frame_4,
@@ -109,28 +106,29 @@ enum _generated_cells_indexes
   i_max_cell_num
 };
 
-/* elements description array. do not miss an index!
-   the game will check if one is missing and stop the game.
-   the identifier in the saved file might also not match, reading an "outbox" from
-   the file should store an O_PRE_OUTBOX.
-
-   images are: image in editor, image in editor - animated, game image
-   indexes which are in the png have to be given as numeric constants.
-   for generated cells (ie. guard + an arrow), use the above enum
+/*
+  elements description array. do not miss an index!
+  the game will check if one is missing and stop the game.
+  the identifier in the saved file might also not match, reading an "outbox" from
+  the file should store an O_PRE_OUTBOX.
+
+  images are: image in editor, image in editor - animated, game image
+  indexes which are in the png have to be given as numeric constants.
+  for generated cells (ie. guard + an arrow), use the above enum
 */
 GdElements gd_elements[] =
 {
-  { O_SPACE, N_("Space"), P_AMOEBA_CONSUMES, "SPACE", ' ', 0, 0, 0 },
-  { O_DIRT, N_("Dirt"), P_AMOEBA_CONSUMES|P_VISUAL_EFFECT|P_DIRT, "DIRT", '.', 2, 2, 2 },
-  { O_DIRT_SLOPED_UP_RIGHT, N_("Sloped dirt (up & right)"), P_DIRT|P_SLOPED_UP|P_SLOPED_RIGHT|P_AMOEBA_CONSUMES, "DIRTSLOPEDUPRIGHT", 0, 280, 280, 280 },
-  { O_DIRT_SLOPED_UP_LEFT, N_("Sloped dirt (up & left)"), P_DIRT|P_SLOPED_UP|P_SLOPED_LEFT|P_AMOEBA_CONSUMES, "DIRTSLOPEDUPLEFT", 0, 281, 281, 281 },
-  { O_DIRT_SLOPED_DOWN_LEFT, N_("Sloped dirt (down & left)"), P_DIRT|P_SLOPED_DOWN|P_SLOPED_LEFT|P_AMOEBA_CONSUMES, "DIRTSLOPEDDOWNLEFT", 0, 282, 282, 282 },
-  { O_DIRT_SLOPED_DOWN_RIGHT, N_("Sloped dirt (down & right)"), P_DIRT|P_SLOPED_DOWN|P_SLOPED_RIGHT|P_AMOEBA_CONSUMES, "DIRTSLOPEDDOWNRIGHT", 0, 283, 283, 283 },
-  { O_DIRT_BALL, N_("Dirt ball"), P_DIRT|P_SLOPED|P_AMOEBA_CONSUMES|P_MOVED_BY_CONVEYOR_TOP, "DIRTBALL", 0, 289, 289, 289, 120 },    /* has ckdelay */
-  { O_DIRT_BALL_F, N_("Dirt ball (falling)"), 0, "DIRTBALLf", 0, 289, 289, 289, 120 },    /* has ckdelay */
-  { O_DIRT_LOOSE, N_("Loose dirt"), P_DIRT|P_AMOEBA_CONSUMES|P_MOVED_BY_CONVEYOR_TOP, "DIRTLOOSE", 0, 352, 352, 352, 60 },    /* has ckdelay */
-  { O_DIRT_LOOSE_F, N_("Loose dirt (falling)"), 0, "DIRTLOOSEf", 0, 352, 352, 352, 60 },    /* has ckdelay */
-  { O_DIRT2, N_("Dirt 2"), P_DIRT|P_AMOEBA_CONSUMES, "DIRT2", 0, 3, 3, 3 },
+  { O_SPACE, N_("Space"), P_AMOEBA_CONSUMES | P_WALKABLE, "SPACE", ' ', 0, 0, 0 },
+  { O_DIRT, N_("Dirt"), P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE, "DIRT", '.', 2, 2, 2 },
+  { O_DIRT_SLOPED_UP_RIGHT, N_("Sloped dirt (up & right)"), P_DIRT | P_SLOPED_UP | P_SLOPED_RIGHT | P_AMOEBA_CONSUMES | P_DIGGABLE, "DIRTSLOPEDUPRIGHT", 0, 280, 280, 280 },
+  { O_DIRT_SLOPED_UP_LEFT, N_("Sloped dirt (up & left)"), P_DIRT | P_SLOPED_UP | P_SLOPED_LEFT | P_AMOEBA_CONSUMES | P_DIGGABLE, "DIRTSLOPEDUPLEFT", 0, 281, 281, 281 },
+  { O_DIRT_SLOPED_DOWN_LEFT, N_("Sloped dirt (down & left)"), P_DIRT | P_SLOPED_DOWN | P_SLOPED_LEFT | P_AMOEBA_CONSUMES | P_DIGGABLE, "DIRTSLOPEDDOWNLEFT", 0, 282, 282, 282 },
+  { O_DIRT_SLOPED_DOWN_RIGHT, N_("Sloped dirt (down & right)"), P_DIRT | P_SLOPED_DOWN | P_SLOPED_RIGHT | P_AMOEBA_CONSUMES | P_DIGGABLE, "DIRTSLOPEDDOWNRIGHT", 0, 283, 283, 283 },
+  { O_DIRT_BALL, N_("Dirt ball"), P_DIRT | P_SLOPED | P_AMOEBA_CONSUMES | P_MOVED_BY_CONVEYOR_TOP | P_DIGGABLE | P_CAN_FALL, "DIRTBALL", 0, 289, 289, 289, 120 },    // has ckdelay
+  { O_DIRT_BALL_F, N_("Dirt ball (falling)"), P_FALLING | P_DIGGABLE, "DIRTBALLf", 0, 289, 289, 289, 120 },    // has ckdelay
+  { O_DIRT_LOOSE, N_("Loose dirt"), P_DIRT | P_AMOEBA_CONSUMES | P_MOVED_BY_CONVEYOR_TOP | P_DIGGABLE | P_CAN_FALL, "DIRTLOOSE", 0, 352, 352, 352, 60 },    // has ckdelay
+  { O_DIRT_LOOSE_F, N_("Loose dirt (falling)"), P_FALLING, "DIRTLOOSEf", 0, 352, 352, 352, 60 },    // has ckdelay
+  { O_DIRT2, N_("Dirt 2"), P_DIRT | P_AMOEBA_CONSUMES | P_DIGGABLE, "DIRT2", 0, 3, 3, 3 },
   { O_BRICK, N_("Brick wall"), P_SLOPED|P_BLADDER_SLOPED|P_CAN_BE_HAMMERED, "WALL", 'w', 5, 5, 5 },
   { O_BRICK_SLOPED_UP_RIGHT, N_("Sloped brick wall (up & right)"), P_SLOPED_UP|P_SLOPED_RIGHT|P_BLADDER_SLOPED|P_CAN_BE_HAMMERED, "WALLSLOPEDUPRIGHT", 0, 276, 276, 276 },
   { O_BRICK_SLOPED_UP_LEFT, N_("Sloped brick wall (up & left)"), P_SLOPED_UP|P_SLOPED_LEFT|P_BLADDER_SLOPED|P_CAN_BE_HAMMERED, "WALLSLOPEDUPLEFT", 0, 277, 277, 277 },
@@ -148,38 +146,38 @@ GdElements gd_elements[] =
   { O_STEEL_SLOPED_DOWN_LEFT, N_("Sloped steel wall (down & left)"), P_SLOPED_DOWN|P_SLOPED_LEFT|P_NON_EXPLODABLE, "STEELWALLSLOPEDDOWNLEFT", 0, 286, 286, 286 },
   { O_STEEL_SLOPED_DOWN_RIGHT, N_("Sloped steel wall (down & right)"), P_SLOPED_DOWN|P_SLOPED_RIGHT|P_NON_EXPLODABLE, "STEELWALLSLOPEDDOWNRIGHT", 0, 287, 287, 287 },
   { O_STEEL_EXPLODABLE, N_("Explodable steel wall"), P_CAN_BE_HAMMERED, "STEELWALLDESTRUCTABLE", 'E', 72, 72, 4 },
-  { O_STEEL_EATABLE, N_("Eatable steel wall"), 0, "STEELWALLEATABLE", 0, i_steel_eatable, i_steel_eatable, 4 },
-  { O_BRICK_EATABLE, N_("Eatable brick wall"), 0, "WALLEATABLE", 0, i_brick_eatable, i_brick_eatable, 5 },
-  { O_STONE, N_("Stone"), P_SLOPED|P_MOVED_BY_CONVEYOR_TOP, "BOULDER", 'r', 1, 1, 1, 156 },    /* has ckdelay */
-  { O_STONE_F, N_("Stone, falling"), 0, "BOULDERf", 'R', i_stone_f, i_stone_f, 1, 156 },    /* has ckdelay */
-  { O_FLYING_STONE, N_("Flying stone"), P_SLOPED|P_MOVED_BY_CONVEYOR_BOTTOM, "FLYINGBOULDER", 0, 357, 357, 357, 156 },    /* has ckdelay */
-  { O_FLYING_STONE_F, N_("Flying stone, flying"), 0, "FLYINGBOULDERf", 0, i_flying_stone_f, i_flying_stone_f, 357, 156 },    /* has ckdelay */
-  { O_MEGA_STONE, N_("Mega stone"), P_SLOPED|P_MOVED_BY_CONVEYOR_TOP, "MEGABOULDER", 0, 272, 272, 272, 156 },    /* has ckdelay */
-  { O_MEGA_STONE_F, N_("Mega stone, falling"), 0, "MEGABOULDERf", 0, i_mega_stone_falling, i_mega_stone_falling, 272, 156 },    /* has ckdelay */
-  { O_DIAMOND, N_("Diamond"), P_SLOPED|P_MOVED_BY_CONVEYOR_TOP|P_COLLECTIBLE, "DIAMOND", 'd', 248, -248, -248, 156 },    /* has ckdelay */
-  { O_DIAMOND_F, N_("Diamond, falling"), 0, "DIAMONDf", 'D', i_diamond_f, i_diamond_f, -248, 156 },    /* has ckdelay */
-  { O_FLYING_DIAMOND, N_("Flying diamond"), P_SLOPED|P_MOVED_BY_CONVEYOR_BOTTOM|P_COLLECTIBLE, "FLYINGDIAMOND", 0, 344, -344, -344, 156 },    /* has ckdelay */
-  { O_FLYING_DIAMOND_F, N_("Flying diamond, flying"), 0, "FLYINGDIAMONDf", 0, i_flying_diamond_f, i_flying_diamond_f, -344, 156 },    /* has ckdelay */
-  { O_NUT, N_("Nut"), P_SLOPED|P_MOVED_BY_CONVEYOR_TOP, "NUT", 0, 358, 358, 358, 156 },    /* has ckdelay */
-  { O_NUT_F, N_("Nut, falling"), 0, "NUTf", 0, i_nut_f, i_nut_f, 358, 156 },    /* has ckdelay */
-  { O_BLADDER_SPENDER, N_("Bladder Spender"), 0, "BLADDERSPENDER", 0, 6, 6, 6, 20 },    /* has ckdelay */
+  { O_STEEL_EATABLE, N_("Eatable steel wall"), P_DIGGABLE, "STEELWALLEATABLE", 0, i_steel_eatable, i_steel_eatable, 4 },
+  { O_BRICK_EATABLE, N_("Eatable brick wall"), P_DIGGABLE, "WALLEATABLE", 0, i_brick_eatable, i_brick_eatable, 5 },
+  { O_STONE, N_("Stone"), P_SLOPED | P_MOVED_BY_CONVEYOR_TOP | P_PUSHABLE | P_CAN_FALL, "BOULDER", 'r', 1, 1, 1, 156 },    // has ckdelay
+  { O_STONE_F, N_("Stone, falling"), P_FALLING, "BOULDERf", 'R', i_stone_f, i_stone_f, 1, 156 },    // has ckdelay
+  { O_FLYING_STONE, N_("Flying stone"), P_SLOPED | P_MOVED_BY_CONVEYOR_BOTTOM | P_PUSHABLE | P_CAN_FALL, "FLYINGBOULDER", 0, 357, 357, 357, 156 },    // has ckdelay
+  { O_FLYING_STONE_F, N_("Flying stone, flying"), P_FALLING, "FLYINGBOULDERf", 0, i_flying_stone_f, i_flying_stone_f, 357, 156 },    // has ckdelay
+  { O_MEGA_STONE, N_("Mega stone"), P_SLOPED | P_MOVED_BY_CONVEYOR_TOP | P_PUSHABLE | P_CAN_FALL, "MEGABOULDER", 0, 272, 272, 272, 156 },    // has ckdelay
+  { O_MEGA_STONE_F, N_("Mega stone, falling"), P_FALLING, "MEGABOULDERf", 0, i_mega_stone_falling, i_mega_stone_falling, 272, 156 },    // has ckdelay
+  { O_DIAMOND, N_("Diamond"), P_SLOPED | P_MOVED_BY_CONVEYOR_TOP | P_COLLECTIBLE | P_CAN_FALL, "DIAMOND", 'd', 248, -248, -248, 156 },    // has ckdelay
+  { O_DIAMOND_F, N_("Diamond, falling"), P_FALLING, "DIAMONDf", 'D', i_diamond_f, i_diamond_f, -248, 156 },    // has ckdelay
+  { O_FLYING_DIAMOND, N_("Flying diamond"), P_SLOPED | P_MOVED_BY_CONVEYOR_BOTTOM | P_COLLECTIBLE | P_CAN_FALL, "FLYINGDIAMOND", 0, 344, -344, -344, 156 },    // has ckdelay
+  { O_FLYING_DIAMOND_F, N_("Flying diamond, flying"), P_FALLING, "FLYINGDIAMONDf", 0, i_flying_diamond_f, i_flying_diamond_f, -344, 156 },    // has ckdelay
+  { O_NUT, N_("Nut"), P_SLOPED | P_MOVED_BY_CONVEYOR_TOP | P_PUSHABLE | P_CAN_FALL, "NUT", 0, 358, 358, 358, 156 },    // has ckdelay
+  { O_NUT_F, N_("Nut, falling"), P_FALLING, "NUTf", 0, i_nut_f, i_nut_f, 358, 156 },    // has ckdelay
+  { O_BLADDER_SPENDER, N_("Bladder Spender"), P_PUSHABLE, "BLADDERSPENDER", 0, 6, 6, 6, 20 },    // has ckdelay
   { O_INBOX, N_("Inbox"), 0, "INBOX", 'P', 35, 35, 22 },
-  { O_H_EXPANDING_WALL, N_("Expanding wall, horizontal"), P_VISUAL_EFFECT | P_CAN_BE_HAMMERED, "HEXPANDINGWALL", 'x', i_h_expanding_wall, i_h_expanding_wall, 5, 111 },    /* has ckdelay */
-  { O_V_EXPANDING_WALL, N_("Expanding wall, vertical"), P_VISUAL_EFFECT | P_CAN_BE_HAMMERED, "VEXPANDINGWALL", 'v', i_v_expanding_wall, i_v_expanding_wall, 5, 111 },    /* has ckdelay */
-  { O_EXPANDING_WALL, N_("Expanding wall"), P_VISUAL_EFFECT | P_CAN_BE_HAMMERED, "EXPANDINGWALL", 'e', i_expanding_wall, i_expanding_wall, 5, 111 },    /* has ckdelay */
-  { O_H_EXPANDING_STEEL_WALL, N_("Expanding steel wall, horizontal"), P_NON_EXPLODABLE, "HEXPANDINGSTEELWALL", 0, i_h_expanding_steel_wall, i_h_expanding_steel_wall, 4, 111 },    /* has ckdelay */
-  { O_V_EXPANDING_STEEL_WALL, N_("Expanding steel wall, vertical"), P_NON_EXPLODABLE, "VEXPANDINGSTEELWALL", 0, i_v_expanding_steel_wall, i_v_expanding_steel_wall, 4, 111 },    /* has ckdelay */
-  { O_EXPANDING_STEEL_WALL, N_("Expanding steel wall"), P_NON_EXPLODABLE, "EXPANDINGSTEELWALL", 0, i_expanding_steel_wall, i_expanding_steel_wall, 4, 111 },    /* has ckdelay */
+  { O_H_EXPANDING_WALL, N_("Expanding wall, horizontal"), P_VISUAL_EFFECT | P_CAN_BE_HAMMERED, "HEXPANDINGWALL", 'x', i_h_expanding_wall, i_h_expanding_wall, 5, 111 },    // has ckdelay
+  { O_V_EXPANDING_WALL, N_("Expanding wall, vertical"), P_VISUAL_EFFECT | P_CAN_BE_HAMMERED, "VEXPANDINGWALL", 'v', i_v_expanding_wall, i_v_expanding_wall, 5, 111 },    // has ckdelay
+  { O_EXPANDING_WALL, N_("Expanding wall"), P_VISUAL_EFFECT | P_CAN_BE_HAMMERED, "EXPANDINGWALL", 'e', i_expanding_wall, i_expanding_wall, 5, 111 },    // has ckdelay
+  { O_H_EXPANDING_STEEL_WALL, N_("Expanding steel wall, horizontal"), P_NON_EXPLODABLE, "HEXPANDINGSTEELWALL", 0, i_h_expanding_steel_wall, i_h_expanding_steel_wall, 4, 111 },    // has ckdelay
+  { O_V_EXPANDING_STEEL_WALL, N_("Expanding steel wall, vertical"), P_NON_EXPLODABLE, "VEXPANDINGSTEELWALL", 0, i_v_expanding_steel_wall, i_v_expanding_steel_wall, 4, 111 },    // has ckdelay
+  { O_EXPANDING_STEEL_WALL, N_("Expanding steel wall"), P_NON_EXPLODABLE, "EXPANDINGSTEELWALL", 0, i_expanding_steel_wall, i_expanding_steel_wall, 4, 111 },    // has ckdelay
   { O_EXPANDING_WALL_SWITCH, N_("Expanding wall switch"), 0, "EXPANDINGWALLSWITCH", 0, 40, 40, 40 },
   { O_CREATURE_SWITCH, N_("Creature direction switch"), 0, "FIREFLYBUTTERFLYSWITCH", 0, 18, 18, 18 },
   { O_BITER_SWITCH, N_("Biter switch"), 0, "BITERSWITCH", 0, 12, 12, 12 },
   { O_REPLICATOR_SWITCH, N_("Replicator switch"), 0, "REPLICATORSWITCH", 0, 290, 290, 290 },
   { O_CONVEYOR_SWITCH, N_("Conveyor belt power switch"), 0, "CONVEYORSWITCH", 0, 356, 356, 356 },
   { O_CONVEYOR_DIR_SWITCH, N_("Conveyor belt direction switch"), 0, "CONVEYORDIRECTIONSWITCH", 0, 353, 353, 353 },
-  { O_ACID, N_("Acid"), 0, "ACID", 0, 20, 20, 20, 128 },    /* has ckdelay */
-  { O_FALLING_WALL, N_("Falling wall"), P_CAN_BE_HAMMERED, "FALLINGWALL", 0, i_falling_wall, i_falling_wall, 5, 80 },    /* has ckdelay */
-  { O_FALLING_WALL_F, N_("Falling wall, falling"), P_CAN_BE_HAMMERED, "FALLINGWALLf", 0, i_falling_wall_falling, i_falling_wall_falling, 5, 80 },    /* has ckdelay */
-  { O_BOX, N_("Box"), 0, "SOKOBANBOX", 0, 21, 21, 21 },
+  { O_ACID, N_("Acid"), 0, "ACID", 0, 20, 20, 20, 128 },    // has ckdelay
+  { O_FALLING_WALL, N_("Falling wall"), P_CAN_BE_HAMMERED | P_CAN_FALL, "FALLINGWALL", 0, i_falling_wall, i_falling_wall, 5, 80 },    // has ckdelay
+  { O_FALLING_WALL_F, N_("Falling wall, falling"), P_CAN_BE_HAMMERED | P_FALLING, "FALLINGWALLf", 0, i_falling_wall_falling, i_falling_wall_falling, 5, 80 },    // has ckdelay
+  { O_BOX, N_("Box"), P_PUSHABLE, "SOKOBANBOX", 0, 21, 21, 21 },
   { O_TIME_PENALTY, N_("Time penalty"), P_NON_EXPLODABLE, "TIMEPENALTY", 0, i_time_penalty, i_time_penalty, 9 },
   { O_GRAVESTONE, N_("Gravestone"), P_NON_EXPLODABLE, "GRAVESTONE", 'G', 9, 9, 9 },
   { O_STONE_GLUED, N_("Glued stone"), P_SLOPED, "GLUEDBOULDER", 0, i_stone_glued, i_stone_glued, 1 },
@@ -198,9 +196,9 @@ GdElements gd_elements[] =
   { O_POT, N_("Pot"), 0, "POT", 0, 63, 63, 63 },
   { O_GRAVITY_SWITCH, N_("Gravity switch"), 0, "GRAVITY_SWITCH", 0, 274, 274, 274 },
   { O_PNEUMATIC_HAMMER, N_("Pneumatic hammer"), P_COLLECTIBLE, "PNEUMATIC_HAMMER", 0, 62, 62, 62 },
-  { O_TELEPORTER, N_("Teleporter"), 0, "TELEPORTER", 0, 61, 61, 61 },
+  { O_TELEPORTER, N_("Teleporter"), P_WALKABLE, "TELEPORTER", 0, 61, 61, 61 },
   { O_SKELETON, N_("Skeleton"), 0, "SKELETON", 0, 273, 273, 273 },
-  { O_WATER, N_("Water"), 0, "WATER", 0, 96, -96, -96, 100 },    /* has ckdelay */
+  { O_WATER, N_("Water"), 0, "WATER", 0, 96, -96, -96, 100 },    // has ckdelay
   { O_WATER_1, N_("Water (1)"), 0, "WATER1", 0, 96, -96, -96 },
   { O_WATER_2, N_("Water (2)"), 0, "WATER2", 0, 96, -96, -96 },
   { O_WATER_3, N_("Water (3)"), 0, "WATER3", 0, 96, -96, -96 },
@@ -217,32 +215,32 @@ GdElements gd_elements[] =
   { O_WATER_14, N_("Water (14)"), 0, "WATER14", 0, 96, -96, -96 },
   { O_WATER_15, N_("Water (15)"), 0, "WATER15", 0, 96, -96, -96 },
   { O_WATER_16, N_("Water (16)"), 0, "WATER16", 0, 96, -96, -96 },
-  { O_COW_1, N_("Cow (left)"), P_CCW, "COWl", 0, i_cow_1, -88, -88, 384 },    /* has ckdelay */
-  { O_COW_2, N_("Cow (up)"), P_CCW, "COWu", 0, i_cow_2, -88, -88, 384 },    /* has ckdelay */
-  { O_COW_3, N_("Cow (right)"), P_CCW, "COWr", 0, i_cow_3, -88, -88, 384 },    /* has ckdelay */
-  { O_COW_4, N_("Cow (down)"), P_CCW, "COWd", 0, i_cow_4, -88, -88, 384 },    /* has ckdelay */
-  { O_COW_ENCLOSED_1, N_("Cow (enclosed, 1)"), 0, "COW_ENCLOSED1", 0, i_cow_enclosed, -88, -88, 120 },    /* has ckdelay */
-  { O_COW_ENCLOSED_2, N_("Cow (enclosed, 2)"), 0, "COW_ENCLOSED2", 0, i_cow_enclosed, -88, -88, 120 },    /* has ckdelay */
-  { O_COW_ENCLOSED_3, N_("Cow (enclosed, 3)"), 0, "COW_ENCLOSED3", 0, i_cow_enclosed, -88, -88, 120 },    /* has ckdelay */
-  { O_COW_ENCLOSED_4, N_("Cow (enclosed, 4)"), 0, "COW_ENCLOSED4", 0, i_cow_enclosed, -88, -88, 120 },    /* has ckdelay */
-  { O_COW_ENCLOSED_5, N_("Cow (enclosed, 5)"), 0, "COW_ENCLOSED5", 0, i_cow_enclosed, -88, -88, 120 },    /* has ckdelay */
-  { O_COW_ENCLOSED_6, N_("Cow (enclosed, 6)"), 0, "COW_ENCLOSED6", 0, i_cow_enclosed, -88, -88, 120 },    /* has ckdelay */
-  { O_COW_ENCLOSED_7, N_("Cow (enclosed, 7)"), 0, "COW_ENCLOSED7", 0, i_cow_enclosed, -88, -88, 120 },    /* has ckdelay */
+  { O_COW_1, N_("Cow (left)"), P_CCW | P_CAN_MOVE, "COWl", 0, i_cow_1, -88, -88, 384 },    // has ckdelay
+  { O_COW_2, N_("Cow (up)"), P_CCW | P_CAN_MOVE, "COWu", 0, i_cow_2, -88, -88, 384 },      // has ckdelay
+  { O_COW_3, N_("Cow (right)"), P_CCW | P_CAN_MOVE, "COWr", 0, i_cow_3, -88, -88, 384 },   // has ckdelay
+  { O_COW_4, N_("Cow (down)"), P_CCW | P_CAN_MOVE, "COWd", 0, i_cow_4, -88, -88, 384 },    // has ckdelay
+  { O_COW_ENCLOSED_1, N_("Cow (enclosed, 1)"), 0, "COW_ENCLOSED1", 0, i_cow_enclosed, -88, -88, 120 },    // has ckdelay
+  { O_COW_ENCLOSED_2, N_("Cow (enclosed, 2)"), 0, "COW_ENCLOSED2", 0, i_cow_enclosed, -88, -88, 120 },    // has ckdelay
+  { O_COW_ENCLOSED_3, N_("Cow (enclosed, 3)"), 0, "COW_ENCLOSED3", 0, i_cow_enclosed, -88, -88, 120 },    // has ckdelay
+  { O_COW_ENCLOSED_4, N_("Cow (enclosed, 4)"), 0, "COW_ENCLOSED4", 0, i_cow_enclosed, -88, -88, 120 },    // has ckdelay
+  { O_COW_ENCLOSED_5, N_("Cow (enclosed, 5)"), 0, "COW_ENCLOSED5", 0, i_cow_enclosed, -88, -88, 120 },    // has ckdelay
+  { O_COW_ENCLOSED_6, N_("Cow (enclosed, 6)"), 0, "COW_ENCLOSED6", 0, i_cow_enclosed, -88, -88, 120 },    // has ckdelay
+  { O_COW_ENCLOSED_7, N_("Cow (enclosed, 7)"), 0, "COW_ENCLOSED7", 0, i_cow_enclosed, -88, -88, 120 },    // has ckdelay
   { O_WALLED_DIAMOND, N_("Walled diamond"), P_CAN_BE_HAMMERED, "WALLED_DIAMOND", 0, i_walled_diamond, i_walled_diamond, 5 },
   { O_WALLED_KEY_1, N_("Walled key 1"), P_CAN_BE_HAMMERED, "WALLED_KEY1", 0, i_walled_key_1, i_walled_key_1, 5 },
   { O_WALLED_KEY_2, N_("Walled key 2"), P_CAN_BE_HAMMERED, "WALLED_KEY2", 0, i_walled_key_2, i_walled_key_2, 5 },
   { O_WALLED_KEY_3, N_("Walled key 3"), P_CAN_BE_HAMMERED, "WALLED_KEY3", 0, i_walled_key_3, i_walled_key_3, 5 },
 
-  { O_AMOEBA, N_("Amoeba"), P_BLOWS_UP_FLIES, "AMOEBA", 'a', 192, -192, -192, 260 },    /* has ckdelay */
-  { O_AMOEBA_2, N_("Amoeba 2"), P_BLOWS_UP_FLIES|P_VISUAL_EFFECT, "AMOEBA2", 0, 296, -296, -296, 260 },    /* has ckdelay */
-  { O_REPLICATOR, N_("Replicator"), P_NON_EXPLODABLE, "REPLICATOR", 0, 304, 304, 304, 210 },    /* has ckdelay */
-  { O_CONVEYOR_LEFT, N_("Conveyor belt (left)"), P_NON_EXPLODABLE, "CONVEYORLEFT", 0, i_conveyor_left, -328, -328, 256  },    /* has ckdelay */
+  { O_AMOEBA, N_("Amoeba"), P_BLOWS_UP_FLIES | P_CAN_MOVE, "AMOEBA", 'a', 192, -192, -192, 260 },    // has ckdelay
+  { O_AMOEBA_2, N_("Amoeba 2"), P_BLOWS_UP_FLIES | P_CAN_MOVE | P_VISUAL_EFFECT, "AMOEBA2", 0, 296, -296, -296, 260 },    // has ckdelay
+  { O_REPLICATOR, N_("Replicator"), P_NON_EXPLODABLE, "REPLICATOR", 0, 304, -304, -304, 210 },    // has ckdelay
+  { O_CONVEYOR_LEFT, N_("Conveyor belt (left)"), P_NON_EXPLODABLE, "CONVEYORLEFT", 0, i_conveyor_left, -328, -328, 256  },    // has ckdelay
   { O_CONVEYOR_RIGHT, N_("Conveyor belt (right)"), P_NON_EXPLODABLE, "CONVEYORRIGHT", 0, i_conveyor_right, -320, -320  },
   { O_LAVA, N_("Lava"), P_NON_EXPLODABLE, "LAVA", 0, 312, -312, -312 },
   { O_SWEET, N_("Sweet"), P_COLLECTIBLE, "SWEET", 0, 8, 8, 8 },
   { O_VOODOO, N_("Voodoo doll"), P_BLOWS_UP_FLIES, "DUMMY", 'F', 7, 7, 7 },
-  { O_SLIME, N_("Slime"), 0, "SLIME", 's', 200, -200, -200, 211 },    /* has ckdelay */
-  { O_BLADDER, N_("Bladder"), 0, "BLADDER", 0, 176, -176, -176, 267 },    /* has ckdelay */
+  { O_SLIME, N_("Slime"), 0, "SLIME", 's', 200, -200, -200, 211 },        // has ckdelay
+  { O_BLADDER, N_("Bladder"), 0, "BLADDER", 0, 176, -176, -176, 267 },    // has ckdelay
   { O_BLADDER_1, N_("Bladder (1)"), 0, "BLADDERd1", 0, 176, -176, -176 },
   { O_BLADDER_2, N_("Bladder (2)"), 0, "BLADDERd2", 0, 176, -176, -176 },
   { O_BLADDER_3, N_("Bladder (3)"), 0, "BLADDERd3", 0, 176, -176, -176 },
@@ -252,46 +250,53 @@ GdElements gd_elements[] =
   { O_BLADDER_7, N_("Bladder (7)"), 0, "BLADDERd7", 0, 176, -176, -176 },
   { O_BLADDER_8, N_("Bladder (8)"), 0, "BLADDERd8", 0, 176, -176, -176 },
 
-  { O_WAITING_STONE, N_("Waiting stone"), P_SLOPED, "WAITINGBOULDER", 0, i_waiting_stone, i_waiting_stone, 1, 176 },    /* has ckdelay */
-  { O_CHASING_STONE, N_("Chasing stone"), P_SLOPED, "CHASINGBOULDER", 0, 17, 17, 17, 269 },    /* has ckdelay */
-  { O_GHOST, N_("Ghost"), 0, "GHOST", 'g', 160, -160, -160, 50 },    /* has ckdelay */
-  { O_FIREFLY_1, N_("Guard, left"), P_EXPLODES_BY_HIT | P_CCW, "FIREFLYl", 'Q', i_guard_1, -136, -136, 384 },    /* has ckdelay */
-  { O_FIREFLY_2, N_("Guard, up"), P_EXPLODES_BY_HIT | P_CCW, "FIREFLYu", 'o', i_guard_2, -136, -136, 384 },    /* has ckdelay */
-  { O_FIREFLY_3, N_("Guard, right"), P_EXPLODES_BY_HIT | P_CCW, "FIREFLYr", 'O', i_guard_3, -136, -136, 384 },    /* has ckdelay */
-  { O_FIREFLY_4, N_("Guard, down"), P_EXPLODES_BY_HIT | P_CCW, "FIREFLYd", 'q', i_guard_4, -136, -136, 384 },    /* has ckdelay */
-  { O_ALT_FIREFLY_1, N_("Alternative guard, left"), P_EXPLODES_BY_HIT, "A_FIREFLYl", 0, i_alt_guard_1, -104, -104, 384 },    /* has ckdelay */
-  { O_ALT_FIREFLY_2, N_("Alternative guard, up"), P_EXPLODES_BY_HIT, "A_FIREFLYu", 0, i_alt_guard_2, -104, -104, 384 },    /* has ckdelay */
-  { O_ALT_FIREFLY_3, N_("Alternative guard, right"), P_EXPLODES_BY_HIT, "A_FIREFLYr", 0, i_alt_guard_3, -104, -104, 384 },    /* has ckdelay */
-  { O_ALT_FIREFLY_4, N_("Alternative guard, down"), P_EXPLODES_BY_HIT, "A_FIREFLYd", 0, i_alt_guard_4, -104, -104, 384 },    /* has ckdelay */
-  { O_BUTTER_1, N_("Butterfly, left"), P_EXPLODES_BY_HIT, "BUTTERFLYl", 'C', i_butter_1, -144, -144, 384 },    /* has ckdelay */
-  { O_BUTTER_2, N_("Butterfly, up"), P_EXPLODES_BY_HIT, "BUTTERFLYu", 'b', i_butter_2, -144, -144, 384 },    /* has ckdelay */
-  { O_BUTTER_3, N_("Butterfly, right"), P_EXPLODES_BY_HIT, "BUTTERFLYr", 'B', i_butter_3, -144, -144, 384 },    /* has ckdelay */
-  { O_BUTTER_4, N_("Butterfly, down"), P_EXPLODES_BY_HIT, "BUTTERFLYd", 'c', i_butter_4, -144, -144, 384 },    /* has ckdelay */
-  { O_ALT_BUTTER_1, N_("Alternative butterfly, left"), P_EXPLODES_BY_HIT | P_CCW, "A_BUTTERFLYl", 0, i_alt_butter_1, -112, -112, 384 },    /* has ckdelay */
-  { O_ALT_BUTTER_2, N_("Alternative butterfly, up"), P_EXPLODES_BY_HIT | P_CCW, "A_BUTTERFLYu", 0, i_alt_butter_2, -112, -112, 384 },    /* has ckdelay */
-  { O_ALT_BUTTER_3, N_("Alternative butterfly, right"), P_EXPLODES_BY_HIT | P_CCW, "A_BUTTERFLYr", 0, i_alt_butter_3, -112, -112, 384 },    /* has ckdelay */
-  { O_ALT_BUTTER_4, N_("Alternative butterfly, down"), P_EXPLODES_BY_HIT | P_CCW, "A_BUTTERFLYd", 0, i_alt_butter_4, -112, -112, 384 },    /* has ckdelay */
-  { O_STONEFLY_1, N_("Stonefly, left"), P_EXPLODES_BY_HIT, "STONEFLYl", 0, i_stonefly_1, -152, -152, 384 },    /* has ckdelay */
-  { O_STONEFLY_2, N_("Stonefly, up"), P_EXPLODES_BY_HIT, "STONEFLYu", 0, i_stonefly_2, -152, -152, 384 },    /* has ckdelay */
-  { O_STONEFLY_3, N_("Stonefly, right"), P_EXPLODES_BY_HIT, "STONEFLYr", 0, i_stonefly_3, -152, -152, 384 },    /* has ckdelay */
-  { O_STONEFLY_4, N_("Stonefly, down"), P_EXPLODES_BY_HIT, "STONEFLYd", 0, i_stonefly_4, -152, -152, 384 },    /* has ckdelay */
-  { O_BITER_1, N_("Biter, up"), 0, "BITERu", 0, i_biter_1, -168, -168, 518 },    /* has ckdelay */
-  { O_BITER_2, N_("Biter, right"), 0, "BITERr", 0, i_biter_2, -168, -168, 518 },    /* has ckdelay */
-  { O_BITER_3, N_("Biter, down"), 0, "BITERd", 0, i_biter_3, -168, -168, 518 },    /* has ckdelay */
-  { O_BITER_4, N_("Biter, left"), 0, "BITERl", 0, i_biter_4, -168, -168, 518 },    /* has ckdelay */
-  { O_DRAGONFLY_1, N_("Dragonfly, left"), P_EXPLODES_BY_HIT|P_CCW, "DRAGONFLYl", 0, i_dragonfly_1, -336, -336, 256  },    /* has ckdelay */
-  { O_DRAGONFLY_2, N_("Dragonfly, up"), P_EXPLODES_BY_HIT|P_CCW, "DRAGONFLYu", 0, i_dragonfly_2, -336, -336, 256  },    /* has ckdelay */
-  { O_DRAGONFLY_3, N_("Dragonfly, right"), P_EXPLODES_BY_HIT|P_CCW, "DRAGONFLYr", 0, i_dragonfly_3, -336, -336, 256  },    /* has ckdelay */
-  { O_DRAGONFLY_4, N_("Dragonfly, down"), P_EXPLODES_BY_HIT|P_CCW, "DRAGONFLYd", 0, i_dragonfly_4, -336, -336, 256  },    /* has ckdelay */
-
-  { O_PRE_PL_1, N_("Player birth (1)"), 0, "GUYBIRTH1", 0, 32, 32, 32 },
-  { O_PRE_PL_2, N_("Player birth (2)"), 0, "GUYBIRTH2", 0, 33, 33, 33 },
-  { 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_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_WAITING_STONE, N_("Waiting stone"), P_SLOPED | P_PUSHABLE, "WAITINGBOULDER", 0, i_waiting_stone, i_waiting_stone, 1, 176 },    // has ckdelay
+  { O_CHASING_STONE, N_("Chasing stone"), P_SLOPED | P_CAN_MOVE | P_PUSHABLE, "CHASINGBOULDER", 0, 17, 17, 17, 269 },    // has ckdelay
+  { O_GHOST, N_("Ghost"), P_CAN_MOVE, "GHOST", 'g', 160, -160, -160, 50 },    // has ckdelay
+  { O_FIREFLY_1, N_("Guard, left"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "FIREFLYl", 'Q', i_guard_1, -136, -136, 384 },    // has ckdelay
+  { O_FIREFLY_2, N_("Guard, up"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "FIREFLYu", 'o', i_guard_2, -136, -136, 384 },      // has ckdelay
+  { O_FIREFLY_3, N_("Guard, right"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "FIREFLYr", 'O', i_guard_3, -136, -136, 384 },   // has ckdelay
+  { O_FIREFLY_4, N_("Guard, down"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "FIREFLYd", 'q', i_guard_4, -136, -136, 384 },    // has ckdelay
+  { O_ALT_FIREFLY_1, N_("Alternative guard, left"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "A_FIREFLYl", 0, i_alt_guard_1, -104, -104, 384 },    // has ckdelay
+  { O_ALT_FIREFLY_2, N_("Alternative guard, up"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "A_FIREFLYu", 0, i_alt_guard_2, -104, -104, 384 },      // has ckdelay
+  { O_ALT_FIREFLY_3, N_("Alternative guard, right"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "A_FIREFLYr", 0, i_alt_guard_3, -104, -104, 384 },   // has ckdelay
+  { O_ALT_FIREFLY_4, N_("Alternative guard, down"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "A_FIREFLYd", 0, i_alt_guard_4, -104, -104, 384 },    // has ckdelay
+  { O_BUTTER_1, N_("Butterfly, left"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "BUTTERFLYl", 'C', i_butter_1, -144, -144, 384 },    // has ckdelay
+  { O_BUTTER_2, N_("Butterfly, up"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "BUTTERFLYu", 'b', i_butter_2, -144, -144, 384 },      // has ckdelay
+  { O_BUTTER_3, N_("Butterfly, right"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "BUTTERFLYr", 'B', i_butter_3, -144, -144, 384 },   // has ckdelay
+  { O_BUTTER_4, N_("Butterfly, down"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "BUTTERFLYd", 'c', i_butter_4, -144, -144, 384 },    // has ckdelay
+  { O_ALT_BUTTER_1, N_("Alternative butterfly, left"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "A_BUTTERFLYl", 0, i_alt_butter_1, -112, -112, 384 },    // has ckdelay
+  { O_ALT_BUTTER_2, N_("Alternative butterfly, up"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "A_BUTTERFLYu", 0, i_alt_butter_2, -112, -112, 384 },      // has ckdelay
+  { O_ALT_BUTTER_3, N_("Alternative butterfly, right"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "A_BUTTERFLYr", 0, i_alt_butter_3, -112, -112, 384 },   // has ckdelay
+  { O_ALT_BUTTER_4, N_("Alternative butterfly, down"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "A_BUTTERFLYd", 0, i_alt_butter_4, -112, -112, 384 },    // has ckdelay
+  { O_STONEFLY_1, N_("Stonefly, left"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "STONEFLYl", 0, i_stonefly_1, -152, -152, 384 },    // has ckdelay
+  { O_STONEFLY_2, N_("Stonefly, up"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "STONEFLYu", 0, i_stonefly_2, -152, -152, 384 },      // has ckdelay
+  { O_STONEFLY_3, N_("Stonefly, right"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "STONEFLYr", 0, i_stonefly_3, -152, -152, 384 },   // has ckdelay
+  { O_STONEFLY_4, N_("Stonefly, down"), P_EXPLODES_BY_HIT | P_CAN_MOVE, "STONEFLYd", 0, i_stonefly_4, -152, -152, 384 },    // has ckdelay
+  { O_BITER_1, N_("Biter, up"), P_CAN_MOVE, "BITERu", 0, i_biter_1, -168, -168, 518 },    // has ckdelay
+  { O_BITER_2, N_("Biter, right"), P_CAN_MOVE, "BITERr", 0, i_biter_2, -168, -168, 518 },    // has ckdelay
+  { O_BITER_3, N_("Biter, down"), P_CAN_MOVE, "BITERd", 0, i_biter_3, -168, -168, 518 },    // has ckdelay
+  { O_BITER_4, N_("Biter, left"), P_CAN_MOVE, "BITERl", 0, i_biter_4, -168, -168, 518 },    // has ckdelay
+  { O_DRAGONFLY_1, N_("Dragonfly, left"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "DRAGONFLYl", 0, i_dragonfly_1, -336, -336, 256  },    // has ckdelay
+  { O_DRAGONFLY_2, N_("Dragonfly, up"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "DRAGONFLYu", 0, i_dragonfly_2, -336, -336, 256  },      // has ckdelay
+  { O_DRAGONFLY_3, N_("Dragonfly, right"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "DRAGONFLYr", 0, i_dragonfly_3, -336, -336, 256  },   // has ckdelay
+  { O_DRAGONFLY_4, N_("Dragonfly, down"), P_EXPLODES_BY_HIT | P_CCW | P_CAN_MOVE, "DRAGONFLYd", 0, i_dragonfly_4, -336, -336, 256  },    // has ckdelay
+
+  { O_PRE_PL_1, N_("Player birth (1)"), P_GROWING, "GUYBIRTH1", 0, 32, 32, 32 },
+  { O_PRE_PL_2, N_("Player birth (2)"), P_GROWING, "GUYBIRTH2", 0, 33, 33, 33 },
+  { O_PRE_PL_3, N_("Player birth (3)"), P_GROWING, "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 },
@@ -301,52 +306,52 @@ GdElements gd_elements[] =
   { O_BOMB_TICK_6, N_("Ticking bomb (6)"), 0, "IGNITEDBOMB6", 0, 54, 54, 54 },
   { O_BOMB_TICK_7, N_("Ticking bomb (7)"), 0, "IGNITEDBOMB7", 0, 55, 55, 55 },
 
-  { O_NITRO_PACK, N_("Nitro pack"), P_SLOPED|P_EXPLODES_BY_HIT|P_MOVED_BY_CONVEYOR_TOP, "NITRO", 0, 288, 288, 288 },
-  { O_NITRO_PACK_F, N_("Nitro pack, falling"), P_EXPLODES_BY_HIT, "NITROf", 0, i_nitro_pack_f, i_nitro_pack_f, 288 },
+  { O_NITRO_PACK, N_("Nitro pack"), P_SLOPED | P_EXPLODES_BY_HIT | P_MOVED_BY_CONVEYOR_TOP | P_PUSHABLE | P_CAN_FALL, "NITRO", 0, 288, 288, 288 },
+  { O_NITRO_PACK_F, N_("Nitro pack, falling"), P_EXPLODES_BY_HIT | P_FALLING, "NITROf", 0, i_nitro_pack_f, i_nitro_pack_f, 288 },
   { O_NITRO_PACK_EXPLODE, N_("Nitro pack, triggered"), P_EXPLODES_BY_HIT, "NITROtriggered", 0, i_nitro_explode, i_nitro_explode, 288 },
 
-  { O_PRE_CLOCK_1, N_("Clock birth (1)"), P_EXPLOSION_FIRST_STAGE, "CLOCKBIRTH1", 0, 28, 28, 28, 280 },    /* has ckdelay */
-  { O_PRE_CLOCK_2, N_("Clock birth (2)"), 0, "CLOCKBIRTH2", 0, 29, 29, 29, 280 },    /* has ckdelay */
-  { O_PRE_CLOCK_3, N_("Clock birth (3)"), 0, "CLOCKBIRTH3", 0, 30, 30, 30, 280 },    /* has ckdelay */
-  { O_PRE_CLOCK_4, N_("Clock birth (4)"), 0, "CLOCKBIRTH4", 0, 31, 31, 31, 280 },    /* has ckdelay */
-  { O_PRE_DIA_1, N_("Diamond birth (1)"), P_EXPLOSION_FIRST_STAGE, "DIAMONDBIRTH1", 0, 56, 56, 56, 280 },    /* has ckdelay */
-  { O_PRE_DIA_2, N_("Diamond birth (2)"), 0, "DIAMONDBIRTH2", 0, 57, 57, 57, 280 },    /* has ckdelay */
-  { O_PRE_DIA_3, N_("Diamond birth (3)"), 0, "DIAMONDBIRTH3", 0, 58, 58, 58, 280 },    /* has ckdelay */
-  { O_PRE_DIA_4, N_("Diamond birth (4)"), 0, "DIAMONDBIRTH4", 0, 59, 59, 59, 280 },    /* has ckdelay */
-  { O_PRE_DIA_5, N_("Diamond birth (5)"), 0, "DIAMONDBIRTH5", 0, 60, 60, 60, 280 },    /* has ckdelay */
-  { O_EXPLODE_1, N_("Explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "EXPLOSION1", 0, 43, 43, 43, 280 },    /* has ckdelay */
-  { O_EXPLODE_2, N_("Explosion (2)"), P_EXPLOSION, "EXPLOSION2", 0, 44, 44, 44, 280 },    /* has ckdelay */
-  { O_EXPLODE_3, N_("Explosion (3)"), P_EXPLOSION, "EXPLOSION3", 0, 45, 45, 45, 280 },    /* has ckdelay */
-  { O_EXPLODE_4, N_("Explosion (4)"), P_EXPLOSION, "EXPLOSION4", 0, 46, 46, 46, 280 },    /* has ckdelay */
-  { O_EXPLODE_5, N_("Explosion (5)"), P_EXPLOSION, "EXPLOSION5", 0, 47, 47, 47, 280 },    /* has ckdelay */
-  { O_PRE_STONE_1, N_("Stone birth (1)"), P_EXPLOSION_FIRST_STAGE, "BOULDERBIRTH1", 0, 36, 36, 36, 280 },    /* has ckdelay */
-  { O_PRE_STONE_2, N_("Stone birth (2)"), 0, "BOULDERBIRTH2", 0, 37, 37, 37, 280 },    /* has ckdelay */
-  { O_PRE_STONE_3, N_("Stone birth (3)"), 0, "BOULDERBIRTH3", 0, 38, 38, 38, 280 },    /* has ckdelay */
-  { O_PRE_STONE_4, N_("Stone birth (4)"), 0, "BOULDERBIRTH4", 0, 39, 39, 39, 280 },    /* has ckdelay */
-  { O_PRE_STEEL_1, N_("Steel birth (1)"), P_EXPLOSION_FIRST_STAGE, "STEELWALLBIRTH1", 0, 24, 24, 24, 280 },    /* has ckdelay */
-  { O_PRE_STEEL_2, N_("Steel birth (2)"), 0, "STEELWALLBIRTH2", 0, 25, 25, 25, 280 },    /* has ckdelay */
-  { O_PRE_STEEL_3, N_("Steel birth (3)"), 0, "STEELWALLBIRTH3", 0, 26, 26, 26, 280 },    /* has ckdelay */
-  { O_PRE_STEEL_4, N_("Steel birth (4)"), 0, "STEELWALLBIRTH4", 0, 27, 27, 27, 280 },    /* has ckdelay */
-  { O_GHOST_EXPL_1, N_("Ghost explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "GHOSTEXPLOSION1", 0, 80, 80, 80, 280 },    /* has ckdelay */
-  { O_GHOST_EXPL_2, N_("Ghost explosion (2)"), P_EXPLOSION, "GHOSTEXPLOSION2", 0, 81, 81, 81, 280 },    /* has ckdelay */
-  { O_GHOST_EXPL_3, N_("Ghost explosion (3)"), P_EXPLOSION, "GHOSTEXPLOSION3", 0, 82, 82, 82, 280 },    /* has ckdelay */
-  { O_GHOST_EXPL_4, N_("Ghost explosion (4)"), P_EXPLOSION, "GHOSTEXPLOSION4", 0, 83, 83, 83, 280 },    /* has ckdelay */
-  { O_BOMB_EXPL_1, N_("Bomb explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "BOMBEXPLOSION1", 0, 84, 84, 84, 280 },    /* has ckdelay */
-  { O_BOMB_EXPL_2, N_("Bomb explosion (2)"), P_EXPLOSION, "BOMBEXPLOSION2", 0, 85, 85, 85, 280 },    /* has ckdelay */
-  { O_BOMB_EXPL_3, N_("Bomb explosion (3)"), P_EXPLOSION, "BOMBEXPLOSION3", 0, 86, 86, 86, 280 },    /* has ckdelay */
-  { O_BOMB_EXPL_4, N_("Bomb explosion (4)"), P_EXPLOSION, "BOMBEXPLOSION4", 0, 87, 87, 87, 280 },    /* has ckdelay */
-  { O_NITRO_EXPL_1, N_("Nitro pack explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "NITROEXPLOSION1", 0, 44, 44, 44, 280 },    /* has ckdelay */
-  { O_NITRO_EXPL_2, N_("Nitro pack explosion (2)"), P_EXPLOSION, "NITROEXPLOSION2", 0, 45, 45, 45, 280 },    /* has ckdelay */
-  { O_NITRO_EXPL_3, N_("Nitro pack explosion (3)"), P_EXPLOSION, "NITROEXPLOSION3", 0, 46, 46, 46, 280 },    /* has ckdelay */
-  { O_NITRO_EXPL_4, N_("Nitro pack explosion (4)"), P_EXPLOSION, "NITROEXPLOSION4", 0, 47, 47, 47, 280 },    /* has ckdelay */
-  { O_AMOEBA_2_EXPL_1, N_("Amoeba 2 explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "AMOEBA2EXPLOSION1", 0, 292, 292, 292, 280 },    /* has ckdelay */
-  { O_AMOEBA_2_EXPL_2, N_("Amoeba 2 explosion (2)"), P_EXPLOSION, "AMOEBA2EXPLOSION2", 0, 293, 293, 293, 280 },    /* has ckdelay */
-  { O_AMOEBA_2_EXPL_3, N_("Amoeba 2 explosion (3)"), P_EXPLOSION, "AMOEBA2EXPLOSION3", 0, 294, 294, 294, 280 },    /* has ckdelay */
-  { O_AMOEBA_2_EXPL_4, N_("Amoeba 2 explosion (4)"), P_EXPLOSION, "AMOEBA2EXPLOSION4", 0, 295, 295, 295, 280 },    /* has ckdelay */
-  { O_NUT_EXPL_1, N_("Nut explosion (1)"), P_SLOPED | P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "NUTEXPLOSION1", 0, 360, 360, 360, 280 },    /* has ckdelay */
+  { O_PRE_CLOCK_1, N_("Clock birth (1)"), P_GROWING | P_EXPLOSION_FIRST_STAGE, "CLOCKBIRTH1", 0, 28, 28, 28, 280 },    // has ckdelay
+  { O_PRE_CLOCK_2, N_("Clock birth (2)"), P_GROWING, "CLOCKBIRTH2", 0, 29, 29, 29, 280 },    // has ckdelay
+  { O_PRE_CLOCK_3, N_("Clock birth (3)"), P_GROWING, "CLOCKBIRTH3", 0, 30, 30, 30, 280 },    // has ckdelay
+  { O_PRE_CLOCK_4, N_("Clock birth (4)"), P_GROWING, "CLOCKBIRTH4", 0, 31, 31, 31, 280 },    // has ckdelay
+  { O_PRE_DIA_1, N_("Diamond birth (1)"), P_GROWING | P_EXPLOSION_FIRST_STAGE, "DIAMONDBIRTH1", 0, 56, 56, 56, 280 },    // has ckdelay
+  { O_PRE_DIA_2, N_("Diamond birth (2)"), P_GROWING, "DIAMONDBIRTH2", 0, 57, 57, 57, 280 },    // has ckdelay
+  { O_PRE_DIA_3, N_("Diamond birth (3)"), P_GROWING, "DIAMONDBIRTH3", 0, 58, 58, 58, 280 },    // has ckdelay
+  { O_PRE_DIA_4, N_("Diamond birth (4)"), P_GROWING, "DIAMONDBIRTH4", 0, 59, 59, 59, 280 },    // has ckdelay
+  { O_PRE_DIA_5, N_("Diamond birth (5)"), P_GROWING, "DIAMONDBIRTH5", 0, 60, 60, 60, 280 },    // has ckdelay
+  { O_EXPLODE_1, N_("Explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "EXPLOSION1", 0, 43, 43, 43, 280 },    // has ckdelay
+  { O_EXPLODE_2, N_("Explosion (2)"), P_EXPLOSION, "EXPLOSION2", 0, 44, 44, 44, 280 },    // has ckdelay
+  { O_EXPLODE_3, N_("Explosion (3)"), P_EXPLOSION, "EXPLOSION3", 0, 45, 45, 45, 280 },    // has ckdelay
+  { O_EXPLODE_4, N_("Explosion (4)"), P_EXPLOSION, "EXPLOSION4", 0, 46, 46, 46, 280 },    // has ckdelay
+  { O_EXPLODE_5, N_("Explosion (5)"), P_EXPLOSION, "EXPLOSION5", 0, 47, 47, 47, 280 },    // has ckdelay
+  { O_PRE_STONE_1, N_("Stone birth (1)"), P_GROWING | P_EXPLOSION_FIRST_STAGE, "BOULDERBIRTH1", 0, 36, 36, 36, 280 },    // has ckdelay
+  { O_PRE_STONE_2, N_("Stone birth (2)"), P_GROWING, "BOULDERBIRTH2", 0, 37, 37, 37, 280 },    // has ckdelay
+  { O_PRE_STONE_3, N_("Stone birth (3)"), P_GROWING, "BOULDERBIRTH3", 0, 38, 38, 38, 280 },    // has ckdelay
+  { O_PRE_STONE_4, N_("Stone birth (4)"), P_GROWING, "BOULDERBIRTH4", 0, 39, 39, 39, 280 },    // has ckdelay
+  { O_PRE_STEEL_1, N_("Steel birth (1)"), P_GROWING | P_EXPLOSION_FIRST_STAGE, "STEELWALLBIRTH1", 0, 24, 24, 24, 280 },    // has ckdelay
+  { O_PRE_STEEL_2, N_("Steel birth (2)"), P_GROWING, "STEELWALLBIRTH2", 0, 25, 25, 25, 280 },    // has ckdelay
+  { O_PRE_STEEL_3, N_("Steel birth (3)"), P_GROWING, "STEELWALLBIRTH3", 0, 26, 26, 26, 280 },    // has ckdelay
+  { O_PRE_STEEL_4, N_("Steel birth (4)"), P_GROWING, "STEELWALLBIRTH4", 0, 27, 27, 27, 280 },    // has ckdelay
+  { O_GHOST_EXPL_1, N_("Ghost explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "GHOSTEXPLOSION1", 0, 80, 80, 80, 280 },    // has ckdelay
+  { O_GHOST_EXPL_2, N_("Ghost explosion (2)"), P_EXPLOSION, "GHOSTEXPLOSION2", 0, 81, 81, 81, 280 },    // has ckdelay
+  { O_GHOST_EXPL_3, N_("Ghost explosion (3)"), P_EXPLOSION, "GHOSTEXPLOSION3", 0, 82, 82, 82, 280 },    // has ckdelay
+  { O_GHOST_EXPL_4, N_("Ghost explosion (4)"), P_EXPLOSION, "GHOSTEXPLOSION4", 0, 83, 83, 83, 280 },    // has ckdelay
+  { O_BOMB_EXPL_1, N_("Bomb explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "BOMBEXPLOSION1", 0, 84, 84, 84, 280 },    // has ckdelay
+  { O_BOMB_EXPL_2, N_("Bomb explosion (2)"), P_EXPLOSION, "BOMBEXPLOSION2", 0, 85, 85, 85, 280 },    // has ckdelay
+  { O_BOMB_EXPL_3, N_("Bomb explosion (3)"), P_EXPLOSION, "BOMBEXPLOSION3", 0, 86, 86, 86, 280 },    // has ckdelay
+  { O_BOMB_EXPL_4, N_("Bomb explosion (4)"), P_EXPLOSION, "BOMBEXPLOSION4", 0, 87, 87, 87, 280 },    // has ckdelay
+  { O_NITRO_EXPL_1, N_("Nitro pack explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "NITROEXPLOSION1", 0, 44, 44, 44, 280 },    // has ckdelay
+  { O_NITRO_EXPL_2, N_("Nitro pack explosion (2)"), P_EXPLOSION, "NITROEXPLOSION2", 0, 45, 45, 45, 280 },    // has ckdelay
+  { O_NITRO_EXPL_3, N_("Nitro pack explosion (3)"), P_EXPLOSION, "NITROEXPLOSION3", 0, 46, 46, 46, 280 },    // has ckdelay
+  { O_NITRO_EXPL_4, N_("Nitro pack explosion (4)"), P_EXPLOSION, "NITROEXPLOSION4", 0, 47, 47, 47, 280 },    // has ckdelay
+  { O_AMOEBA_2_EXPL_1, N_("Amoeba 2 explosion (1)"), P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "AMOEBA2EXPLOSION1", 0, 292, 292, 292, 280 },    // has ckdelay
+  { O_AMOEBA_2_EXPL_2, N_("Amoeba 2 explosion (2)"), P_EXPLOSION, "AMOEBA2EXPLOSION2", 0, 293, 293, 293, 280 },    // has ckdelay
+  { O_AMOEBA_2_EXPL_3, N_("Amoeba 2 explosion (3)"), P_EXPLOSION, "AMOEBA2EXPLOSION3", 0, 294, 294, 294, 280 },    // has ckdelay
+  { O_AMOEBA_2_EXPL_4, N_("Amoeba 2 explosion (4)"), P_EXPLOSION, "AMOEBA2EXPLOSION4", 0, 295, 295, 295, 280 },    // has ckdelay
+  { O_NUT_EXPL_1, N_("Nut explosion (1)"), P_SLOPED | P_EXPLOSION | P_EXPLOSION_FIRST_STAGE, "NUTEXPLOSION1", 0, 360, 360, 360, 280 },    // has ckdelay
   { O_NUT_EXPL_2, N_("Nut explosion (2)"), P_SLOPED | P_EXPLOSION, "NUTEXPLOSION2", 0, 361, 361, 361, 280 },    /* has ckdelay */        /* these are rounded!! */
-  { O_NUT_EXPL_3, N_("Nut explosion (3)"), P_SLOPED | P_EXPLOSION, "NUTEXPLOSION3", 0, 362, 362, 362, 280 },    /* has ckdelay */
-  { O_NUT_EXPL_4, N_("Nut explosion (4)"), P_SLOPED | P_EXPLOSION, "NUTEXPLOSION4", 0, 363, 363, 363, 280 },    /* has ckdelay */
+  { O_NUT_EXPL_3, N_("Nut explosion (3)"), P_SLOPED | P_EXPLOSION, "NUTEXPLOSION3", 0, 362, 362, 362, 280 },    // has ckdelay
+  { O_NUT_EXPL_4, N_("Nut explosion (4)"), P_SLOPED | P_EXPLOSION, "NUTEXPLOSION4", 0, 363, 363, 363, 280 },    // has ckdelay
 
   { O_PLAYER_PNEUMATIC_LEFT, NULL /* Player using hammer, left */, P_BLOWS_UP_FLIES | P_EXPLODES_BY_HIT | P_PLAYER, "GUYHAMMERl", 0, 265, 265, 265 },
   { O_PLAYER_PNEUMATIC_RIGHT, NULL /* Player using hammer, right */, P_BLOWS_UP_FLIES | P_EXPLODES_BY_HIT | P_PLAYER, "GUYHAMMERr", 0, 268, 268, 268 },
@@ -357,18 +362,25 @@ GdElements gd_elements[] =
   { O_NONE, N_("No element"), 0, "NONE", 0, 79, 79, 79 },
   { O_MAX },
 
-  /* these are just helpers, for all the element -> image index information to be in this array */
+  // these are just helpers, for all the element -> image index information to be in this array
   { O_FAKE_BONUS, NULL, 0, NULL, 0, 120, -120, -120 },
   { O_INBOX_CLOSED, NULL, 0, NULL, 0, 22, 22, 22 },
   { O_INBOX_OPEN, NULL, 0, NULL, 0, 23, 23, 23 },
-  { O_OUTBOX_CLOSED, NULL, 0, NULL, 0, 22, 22, 22 },    /* game graphics - also for imported diego effects, but don't know if it is used anywhere in original games */
+
+  // game graphics
+  // also for imported diego effects, but don't know if it is used anywhere in original games
+  { O_OUTBOX_CLOSED, NULL, 0, NULL, 0, 22, 22, 22 },
   { O_OUTBOX_OPEN, NULL, 0, NULL, 0, 23, 23, 23 },
   { O_COVERED, NULL, 0, NULL, 0, 128, -128, -128 },
   { O_PLAYER_LEFT, NULL, P_PLAYER, NULL, 0, 232, -232, -232 },
   { O_PLAYER_RIGHT, NULL, P_PLAYER, NULL, 0, 240, -240, -240 },
+  { O_PLAYER_UP, NULL, P_PLAYER, NULL, 0, 376, -376, -376 },
+  { O_PLAYER_DOWN, NULL, P_PLAYER, NULL, 0, 384, -384, -384 },
   { O_PLAYER_TAP, NULL, P_PLAYER, NULL, 0, 216, -216, -216 },
   { O_PLAYER_BLINK, NULL, P_PLAYER, NULL, 0, 208, -208, -208 },
   { O_PLAYER_TAP_BLINK, NULL, P_PLAYER, NULL, 0, 224, -224, -224 },
+  { O_PLAYER_PUSH_LEFT, N_("Player, pushing left"), P_PLAYER, NULL, 0, 392, -392, -392 },
+  { O_PLAYER_PUSH_RIGHT, N_("Player, pushing right"), P_PLAYER, NULL, 0, 400, -400, -400 },
   { O_CREATURE_SWITCH_ON, NULL, 0, NULL, 0, 19, 19, 19 },
   { O_EXPANDING_WALL_SWITCH_HORIZ, NULL, 0, NULL, 0, 40, 40, 40 },
   { O_EXPANDING_WALL_SWITCH_VERT, NULL, 0, NULL, 0, 41, 41, 41 },
@@ -401,14 +413,15 @@ GdElements gd_elements[] =
   { -1 },
 };
 
-/* entries. */
+// entries.
 /* type given for each element;
  * GD_TYPE_ELEMENT represents a combo box of gdash objects.
  * GD_TAB&LABEL represents a notebook tab or a label.
- * others are self-explanatory. */
+ * others are self-explanatory.
+ */
 const GdStructDescriptor gd_cave_properties[] =
 {
-  /* default data */
+  // default data
   {"", GD_TAB, 0, N_("Cave data")},
   {"Name", GD_TYPE_STRING, 0, N_("Name"), STRUCT_OFFSET(GdCave, name), 1, N_("Name of game")},
   {"Description", GD_TYPE_STRING, 0, N_("Description"), STRUCT_OFFSET(GdCave, description), 1, N_("Some words about the game")},
@@ -430,10 +443,10 @@ const GdStructDescriptor gd_cave_properties[] =
   {"Charset", GD_TYPE_STRING, 0, N_("Character set"), STRUCT_OFFSET(GdCave, charset), 1, N_("Theme used for displaying the game. Not used by GDash.")},
   {"Fontset", GD_TYPE_STRING, 0, N_("Font set"), STRUCT_OFFSET(GdCave, fontset), 1, N_("Font used during the game. Not used by GDash.")},
 
-  /* notes - a tab on its own */
+  // notes - a tab on its own
   {"Story", GD_TYPE_LONGSTRING, 0, N_("Story"), STRUCT_OFFSET(GdCave, story), 1, N_("Story for the cave. It will be shown when the cave is played.")},
 
-  /* remark - also a tab on its own */
+  // remark - also a tab on its own
   {"Remark", GD_TYPE_LONGSTRING, 0, N_("Remark"), STRUCT_OFFSET(GdCave, remark), 1, N_("Remark (informative). Can contain supplementary information about the design of the cave. It is not shown during the game, only when the user requests the cave info dialog, so can also contain spoilers and hints.")},
 
   {"", GD_TAB, 0, N_("Colors")},
@@ -445,7 +458,7 @@ const GdStructDescriptor gd_cave_properties[] =
   {"Colors", GD_TYPE_COLOR, GD_ALWAYS_SAVE, N_("Amoeba color"), STRUCT_OFFSET(GdCave, color4), 1, N_("Amoeba color for C64 graphics")},
   {"Colors", GD_TYPE_COLOR, GD_ALWAYS_SAVE, N_("Slime color"), STRUCT_OFFSET(GdCave, color5), 1, N_("Slime color for C64 graphics")},
 
-  /* difficulty */
+  // difficulty
   {"", GD_TAB, 0, N_("Difficulty")},
   {"", GD_LABEL, GD_SHOW_LEVEL_LABEL, N_("Diamonds")},
   {"DiamondsRequired", GD_TYPE_INT, GD_ALWAYS_SAVE, N_("Diamonds needed"), CAVE_OFFSET(level_diamonds[0]), 5, N_("Here zero means automatically count diamonds before level start. If negative, the value is subtracted from that. This is useful for totally random caves."), -100, 999},
@@ -462,7 +475,7 @@ const GdStructDescriptor gd_cave_properties[] =
   {"CaveDelay", GD_TYPE_INT, GD_ALWAYS_SAVE, N_("   Delay (C64-style)"), CAVE_OFFSET(level_ckdelay[0]), 5, N_("The length of the delay loop between game frames. Used when milliseconds-based timing is inactive, ie. some kind of C64 or Atari scheduling is selected."), 0, 32},
   {"HatchingTime", GD_TYPE_INT, 0, N_("   Hatching time (seconds)"), CAVE_OFFSET(level_hatching_delay_time[0]), 5, N_("This value sets how much the cave will move until the player enters the cave. This is used for the C64-like schedulings."), 1, 40},
 
-  /* initial fill */
+  // initial fill
   {"RandSeed", GD_TYPE_INT, GD_DONT_SHOW_IN_EDITOR, NULL /* random seed value */, CAVE_OFFSET(level_rand[0]), 5, NULL, -1, 255},
   {"InitialBorder", GD_TYPE_ELEMENT, GD_DONT_SHOW_IN_EDITOR, NULL /* Initial border */, CAVE_OFFSET(initial_border), 1, NULL},
   {"InitialFill", GD_TYPE_ELEMENT, GD_DONT_SHOW_IN_EDITOR, NULL /* Initial fill */, CAVE_OFFSET(initial_fill), 1, NULL},
@@ -475,9 +488,10 @@ const GdStructDescriptor gd_cave_properties[] =
   {"RandomFill", GD_TYPE_ELEMENT, GD_DONT_SHOW_IN_EDITOR, NULL /* Random fill 4 */, CAVE_OFFSET(random_fill[3]), 1, NULL},
   {"RandomFill", GD_TYPE_INT, GD_DONT_SHOW_IN_EDITOR, NULL /* Probability 4 */, CAVE_OFFSET(random_fill_probability[3]), 1, NULL, 0, 255},
 
-  /* PLAYER */
+  // PLAYER
   {"", GD_TAB, 0, N_("Player")},
-  /* player */
+
+  // player
   {"", GD_LABEL, 0, N_("Player movements")},
   {"DiagonalMovement", GD_TYPE_BOOLEAN, 0, N_("Diagonal movements"), CAVE_OFFSET(diagonal_movements), 1, N_("Controls if the player can move diagonally.")},
   {"ActiveGuyIsFirst", GD_TYPE_BOOLEAN, 0, N_("Uppermost player active"), CAVE_OFFSET(active_is_first_found), 1, N_("In 1stB, cave is scrolled to the uppermost and leftmost player found, whereas in the original game to the last one. Chasing stones also follow the active player.")},
@@ -486,15 +500,22 @@ 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.")},
-  /* pneumatic hammer */
+
+  // 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},
   {"PneumaticHammer.wallsreappear", GD_TYPE_BOOLEAN, 0, N_("Hammered walls reappear"), CAVE_OFFSET(hammered_walls_reappear), 1, N_("If this is set to true, walls broken with a pneumatic hammer will reappear later.")},
   {"PneumaticHammer.wallsreappearframes", GD_TYPE_INT, 0, N_("   Timer for reappear (frames)"), CAVE_OFFSET(hammered_wall_reappear_frame), 1, N_("This sets the number of game frames, after hammered walls reappear, when the above setting is true."), 1, 200},
-  /* clock */
+
+  // clock
   {"", GD_LABEL, GD_SHOW_LEVEL_LABEL, N_("Clock")},
   {"BonusTime", GD_TYPE_INT, 0, N_("Time bonus (s)"), CAVE_OFFSET(level_bonus_time), 5, N_("Bonus time when a clock is collected."), -100, 100},
-  /* voodoo */
+
+  // voodoo
   {"", GD_LABEL, 0, N_("Voodoo Doll")},
   {"DummyProperties.diamondcollector", GD_TYPE_BOOLEAN, 0, N_("Can collect diamonds"), CAVE_OFFSET(voodoo_collects_diamonds), 1, N_("Controls if a voodoo doll can collect diamonds for the player.")},
   {"DummyProperties.penalty", GD_TYPE_BOOLEAN, 0, N_("Dies if hit by a stone"), CAVE_OFFSET(voodoo_dies_by_stone), 1, N_("Controls if the voodoo doll dies if it is hit by a stone. Then the player gets a time penalty, and it is turned to a gravestone surrounded by steel wall.")},
@@ -502,11 +523,12 @@ const GdStructDescriptor gd_cave_properties[] =
   {"DummyProperties.alwayskillsplayer", GD_TYPE_BOOLEAN, 0, N_("Any way hurt, player explodes"), CAVE_OFFSET(voodoo_any_hurt_kills_player), 1, N_("If this setting is enabled, the player will explode if the voodoo is hurt in any possible way, ie. touched by a firefly, hit by a stone or an explosion.")},
   {"PenaltyTime", GD_TYPE_INT, 0, N_("Time penalty (s)"), CAVE_OFFSET(level_penalty_time), 5, N_("Penalty time when the voodoo is destroyed by a stone."), 0, 100},
 
-  /* AMOEBA */
+  // AMOEBA
   {"", GD_TAB, 0, N_("Amoeba")},
   {"AmoebaProperties.immediately", GD_TYPE_BOOLEAN, 0, N_("Timer started immediately"), CAVE_OFFSET(amoeba_timer_started_immediately), 1, N_("If this flag is enabled, the amoeba slow growth timer will start at the beginning of the cave, regardless of the amoeba being let free or not. This can make a big difference when playing the cave!")},
   {"AmoebaProperties.waitforhatching", GD_TYPE_BOOLEAN, 0, N_("Timer waits for hatching"), CAVE_OFFSET(amoeba_timer_wait_for_hatching), 1, N_("This determines if the amoeba timer starts before the player appearing. Amoeba can always be activated before that; but if this is set to true, the timer will not start. This setting is for compatiblity for some old imported caves. As the player is usually born within a few seconds, changing this setting makes not much difference. It is not advised to change it, set the slow growth time to fit your needs instead.")},
-  /* amoeba */
+
+  // amoeba
   {"", GD_LABEL, GD_SHOW_LEVEL_LABEL, N_("Amoeba")},
   {"AmoebaThreshold", GD_TYPE_RATIO, 0, N_("Threshold (cells)"), CAVE_OFFSET(level_amoeba_threshold), 5, N_("If the amoeba grows more than this fraction of the cave, it is considered too big and it converts to the element specified below."), 0, 16383},
   {"AmoebaTime", GD_TYPE_INT, 0, N_("Slow growth time (s)"), CAVE_OFFSET(level_amoeba_time), 5, N_("After this time, amoeba will grow very quickly."), 0, 999},
@@ -525,12 +547,14 @@ const GdStructDescriptor gd_cave_properties[] =
   {"AMOEBA2DIAMONDeffect", GD_TYPE_EFFECT, 0, N_("If enclosed, converts to"), CAVE_OFFSET(amoeba_2_enclosed_effect), 1, N_("Controls which element an enclosed amoeba converts to.")},
   {"AMOEBA2LOOKSLIKEeffect", GD_TYPE_EFFECT, 0, N_("Looks like"), CAVE_OFFSET(amoeba_2_looks_like), 1, N_("Amoeba 2 can look like any other element. Hint: it can also look like a normal amoeba. Or it can look like slime, and then you have two different colored amoebas!")},
 
-  /* magic wall */
+  // magic wall
   {"", GD_TAB, 0, N_("Magic Wall")},
   {"", GD_LABEL, GD_SHOW_LEVEL_LABEL, N_("Timing")},
   {"MagicWallTime", GD_TYPE_INT, 0, N_("Milling time (s)"), CAVE_OFFSET(level_magic_wall_time), 5, N_("Magic wall will stop after this time, and it cannot be activated again."), 0, 999},
+  {"MagicWallProperties.zeroisinfinite", GD_TYPE_BOOLEAN, 0, N_("Milling time 0 is infinite"), CAVE_OFFSET(magic_timer_zero_is_infinite), 1, N_("This determines if the magic wall timer 0 is interpreted as infinite.")},
   {"MagicWallProperties.waitforhatching", GD_TYPE_BOOLEAN, 0, N_("Timer waits for hatching"), CAVE_OFFSET(magic_timer_wait_for_hatching), 1, N_("This determines if the magic wall timer starts before the player appearing. Magic can always be activated before that; but if this is set to true, the timer will not start.")},
   {"MagicWallProperties.convertamoeba", GD_TYPE_BOOLEAN, 0, N_("Stops amoeba"), CAVE_OFFSET(magic_wall_stops_amoeba), 1, N_("When the magic wall is activated, it can convert amoeba into diamonds.")},
+  {"MagicWallProperties.breakscan", GD_TYPE_BOOLEAN, 0, N_("BD1 amoeba bug"), CAVE_OFFSET(magic_wall_breakscan), 1, N_("This setting emulates the BD1 bug, where a stone or a diamond falling into a magic wall sometimes caused the active amoeba to convert into a diamond. The rule is: if all amoeba cells above or left to the point where the stone or the diamond falls into the magic wall are enclosed, the amoeba is converted. The timing implications of the bug are not emulated.")},
   {"", GD_LABEL, 0, N_("Conversions")},
   {"MagicWallProperties", GD_TYPE_ELEMENT, 0, N_("Diamond to"), CAVE_OFFSET(magic_diamond_to), 1, N_("As a special effect, magic walls can convert diamonds to any other element.")},
   {"MagicWallProperties", GD_TYPE_ELEMENT, 0, N_("Stone to"), CAVE_OFFSET(magic_stone_to), 1, N_("As a special effect, magic walls can convert stones to any other element.")},
@@ -540,11 +564,12 @@ const GdStructDescriptor gd_cave_properties[] =
   {"MagicWallProperties.flyingstoneto", GD_TYPE_ELEMENT, 0, N_("Flying stone to"), CAVE_OFFSET(magic_flying_stone_to), 1, N_("If a flying stone climbs up into the magic wall, it will be turned to this element. Remember that flying stones enter the magic wall from its bottom, not from the top!")},
   {"MagicWallProperties.flyingdiamondto", GD_TYPE_ELEMENT, 0, N_("Flying diamonds to"), CAVE_OFFSET(magic_flying_diamond_to), 1, N_("If a flying diamond enters the magic wall, it will be turned to this element. Remember that flying diamonds enter the magic wall from its bottom, not from the top!")},
 
-  /* slime */
+  // slime
   {"", GD_TAB, 0, N_("Slime")},
   {"", GD_LABEL, GD_SHOW_LEVEL_LABEL, N_("Permeability")},
   {"", GD_TYPE_BOOLEAN, GD_DONT_SAVE, N_("Predictable"), CAVE_OFFSET(slime_predictable), 1, N_("Controls if the predictable random generator is used for slime. It is required for compatibility with some older caves.")},
-  /* permeabilities are "always" saved; and according to the predictability, one of them is removed. */
+
+  // permeabilities are "always" saved; and according to the predictability, one of them is removed.
   {"SlimePermeability", GD_TYPE_PROBABILITY, GD_ALWAYS_SAVE, N_("Permeability (unpredictable, %)"), CAVE_OFFSET(level_slime_permeability[0]), 5, N_("This controls the rate at which elements go through the slime. Higher values represent higher probability of passing. This one is for unpredictable slime.")},
   {"SlimePermeabilityC64", GD_TYPE_INT, GD_ALWAYS_SAVE, N_("Permeability (predictable, bits)"), CAVE_OFFSET(level_slime_permeability_c64[0]), 5, N_("This controls the rate at which elements go through the slime. This one is for predictable slime, and the value is used for a bitwise AND function. The values used by the C64 engines are 0, 128, 192, 224, 240, 248, 252, 254 and 255."), 0, 255},
   {"SlimePredictableC64.seed", GD_TYPE_INT, 0, N_("Random seed (predictable)"), CAVE_OFFSET(level_slime_seed_c64), 5, N_("The random number seed for predictable slime. Use -1 to leave on its default. Not recommended to change. Does not affect unpredictable slime."), -1, 65535},
@@ -556,41 +581,50 @@ const GdStructDescriptor gd_cave_properties[] =
   {"SlimeProperties", GD_TYPE_ELEMENT, 0, N_("Eats this..."), CAVE_OFFSET(slime_eats_3), 1, N_("Slime can let other elements than stone and diamond go through. It always lets a waiting or a chasing stone pass, though. Also, flying diamonds and stones, as well as bladders are always passed.")},
   {"SlimeProperties", GD_TYPE_ELEMENT, 0, N_("  ... and converts to"), CAVE_OFFSET(slime_converts_3), 1, N_("Slime can let other elements than stone and diamond go through. It always lets a waiting or a chasing stone pass, though. Also, flying diamonds and stones, as well as bladders are always passed.")},
 
-  /* ACTIVE 2 */
+  // ACTIVE 2
   {"", GD_TAB, 0, N_("Other elements")},
-  /* acid */
+
+  // acid
   {"", GD_LABEL, 0, N_("Acid")},
   {"AcidProperties", GD_TYPE_ELEMENT, 0, N_("Eats this element"), CAVE_OFFSET(acid_eats_this), 1, N_("The element which acid eats. If it cannot find any, it simply disappears.")},
   {"AcidProperties", GD_TYPE_PROBABILITY, 0, N_("Spread ratio (%)"), CAVE_OFFSET(acid_spread_ratio), 1, N_("The probability at which an acid will explode and eat neighbouring elements.")},
   {"ACIDEffect", GD_TYPE_EFFECT, 0, N_("Leaves this behind"), CAVE_OFFSET(acid_turns_to), 1, N_("If acid converts to an explosion puff on spreading or any other element.")},
-  /* biter */
+
+  // biter
   {"", GD_LABEL, 0, N_("Biter")},
   {"BiterProperties", GD_TYPE_INT, 0, N_("Delay (frame)"), CAVE_OFFSET(biter_delay_frame), 1, N_("Number of frames biters wait between movements."), 0, 3},
   {"BiterProperties", GD_TYPE_ELEMENT, 0, N_("Eats this"), CAVE_OFFSET(biter_eat), 1, N_("Biters eat this element. (They always eat dirt.)")},
-  /* bladder */
+
+  // bladder
   {"", GD_LABEL, 0, N_("Bladder")},
   {"BladderProperties", GD_TYPE_ELEMENT, 0, N_("Converts to clock by touching"), CAVE_OFFSET(bladder_converts_by), 1, NULL},
-  /* expanding wall */
+
+  // expanding wall
   {"", GD_LABEL, 0, N_("Expanding wall")},
   {"ExpandingWallDirection.changed", GD_TYPE_BOOLEAN, 0, N_("Direction changed"), CAVE_OFFSET(expanding_wall_changed), 1, N_("If this option is enabled, the direction of growing for the horizontal and vertical expanding wall is switched. As you can use both horizontal and vertical expanding walls in a cave, it is not recommended to change this setting, as it might be confusing. You should rather select the type with the correct direction from the element box when drawing the cave.")},
-  /* replicator */
+
+  // replicator
   {"", GD_LABEL, 0, N_("Replicator")},
   {"ReplicatorActive", GD_TYPE_BOOLEAN, 0, N_("Active at start"), CAVE_OFFSET(replicators_active), 1, N_("Whether the replicators are turned on or off at the cave start.")},
   {"ReplicatorDelayFrame", GD_TYPE_INT, 0, N_("Delay (frame)"), CAVE_OFFSET(replicator_delay_frame), 1, N_("Number of frames to wait between replicating elements."), 0, 100},
-  /* conveyor belt */
+
+  // conveyor belt
   {"", GD_LABEL, 0, N_("Conveyor belt")},
   {"ConveyorBeltActive", GD_TYPE_BOOLEAN, 0, N_("Active at start"), CAVE_OFFSET(conveyor_belts_active), 1, N_("Whether the conveyor belts are moving when the cave starts.")},
   {"ConveyorBeltDirection.changed", GD_TYPE_BOOLEAN, 0, N_("Direction changed"), CAVE_OFFSET(conveyor_belts_direction_changed), 1, N_("If the conveyor belts' movement is changed, ie. they are running in the opposite direction. As you can freely use left and right going versions of the conveyor belt in a cave, it is not recommended to change this setting, rather you should select the correct one from the element box when drawing.")},
-  /* water */
+
+  // water
   {"", GD_LABEL, 0, N_("Water")},
   {"WaterProperties.doesnotflowdown", GD_TYPE_BOOLEAN, 0, N_("Does not flow downwards"), CAVE_OFFSET(water_does_not_flow_down), 1, N_("In CrDr, the water element had the odd property that it did not flow downwards, only in other directions. This flag emulates this behaviour.")},
-  /* nut */
+
+  // nut
   {"", GD_LABEL, 0, N_("Nut")},
   {"Nut.whencrushed", GD_TYPE_ELEMENT, 0, N_("Turns to when crushed"), CAVE_OFFSET(nut_turns_to_when_crushed), 1, N_("Normally, a nut contains a diamond. If you crush it with a stone, the diamond will appear after the usual nut explosion sequence. This setting can be used to change the element the nut contains.")},
 
-  /* EFFECTS 1 */
+  // EFFECTS 1
   {"", GD_TAB, 0, N_("Effects")},
-  /* cave effects */
+
+  // cave effects
   {"", GD_LABEL, 0, N_("Stone and diamond effects")},
   {"BOULDERfallingeffect", GD_TYPE_EFFECT, 0, N_("Falling stones convert to"), CAVE_OFFSET(stone_falling_effect), 1, N_("When a stone begins falling, it converts to this element.")},
   {"BOULDERbouncingeffect", GD_TYPE_EFFECT, 0, N_("Bouncing stones convert to"), CAVE_OFFSET(stone_bouncing_effect), 1, N_("When a stone stops falling and rolling, it converts to this element.")},
@@ -611,26 +645,28 @@ const GdStructDescriptor gd_cave_properties[] =
   {"BOMBEXPLOSIONeffect", GD_TYPE_EFFECT, 0, N_("Bombs explosions end in"), CAVE_OFFSET(bomb_explosion_effect), 1, N_("Use this setting to select the element the exploding bomb creates.")},
   {"NITROEXPLOSIONeffect", GD_TYPE_EFFECT, 0, N_("Nitro explosions end in"), CAVE_OFFSET(nitro_explosion_effect), 1, N_("The nitro explosions can create some element other than space.")},
 
-  /* EFFECTS 2 */
+  // EFFECTS 2
   {"", GD_TAB, 0, N_("More effects")},
-  /* visual effects */
+
+  // visual effects
   {"", GD_LABEL, 0, N_("Visual effects")},
   {"EXPANDINGWALLLOOKSLIKEeffect", GD_TYPE_EFFECT, 0, N_("Expanding wall looks like"), CAVE_OFFSET(expanding_wall_looks_like), 1, N_("This is a compatibility setting for old caves. If you need an expanding wall which looks like steel, you should rather choose the expanding steel wall from the element box.")},
   {"DIRTLOOKSLIKEeffect", GD_TYPE_EFFECT, 0, N_("Dirt looks like"), CAVE_OFFSET(dirt_looks_like), 1, N_("Compatibility setting. Use it wisely! Anything other than Dirt 2 (which can be used to emulate the Dirt Mod) is not recommended.")},
 
-  /* creature effects */
+  // creature effects
   {"", GD_LABEL, 0, N_("Creature movement")},
   {"EnemyDirectionProperties.startbackwards", GD_TYPE_BOOLEAN, 0, N_("Start backwards"), CAVE_OFFSET(creatures_backwards), 1, N_("Whether the direction creatures travel will already be switched at the cave start.")},
   {"EnemyDirectionProperties.time", GD_TYPE_INT, 0, N_("Automatically turn (s)"), CAVE_OFFSET(creatures_direction_auto_change_time), 1, N_("If this is greater than zero, creatures will automatically change direction in every x seconds."), 0, 999},
   {"EnemyDirectionProperties.changeathatching", GD_TYPE_BOOLEAN, 0, N_("Auto turn on hatching"), CAVE_OFFSET(creatures_direction_auto_change_on_start), 1, N_("If this is set to true, creatures also turn at the start signal. If false, the first change in direction occurs only later.")},
-  /* gravity */
+
+  // gravity
   {"", GD_LABEL, 0, N_("Gravitation change")},
   {"Gravitation", GD_TYPE_DIRECTION, 0, N_("Direction"), CAVE_OFFSET(gravity), 1, N_("The direction where stones and diamonds fall.")},
   {"GravitationSwitchActive", GD_TYPE_BOOLEAN, 0, N_("Switch active at start"), CAVE_OFFSET(gravity_switch_active), 1, N_("If set to true, the gravitation switch will be already activated, when the cave is started, as if a pot has already been collected.")},
   {"SkeletonsForPot", GD_TYPE_INT, 0, N_("Skeletons needed for pot"), CAVE_OFFSET(skeletons_needed_for_pot), 1, N_("The number of skeletons to be collected to be able to use a pot."), 0, 50},
   {"GravitationChangeDelay", GD_TYPE_INT, 0, N_("Gravitation switch delay"), CAVE_OFFSET(gravity_change_time), 1, N_("The gravitation changes after a while using the gravitation switch. This option sets the number of seconds to wait."), 1, 60},
 
-  /* SOUND */
+  // SOUND
   {"", GD_TAB, 0, N_("Sound")},
   {"", GD_LABEL, 0, N_("Sound for elements")},
   {"Diamond.sound", GD_TYPE_BOOLEAN, 0, N_("Diamond"), CAVE_OFFSET(diamond_sound), 1, N_("If true, falling diamonds will have sound.")},
@@ -655,7 +691,7 @@ const GdStructDescriptor gd_cave_properties[] =
   {"GravityChange.sound", GD_TYPE_BOOLEAN, 0, N_("Gravity change"), CAVE_OFFSET(gravity_change_sound), 1, N_("If true, the gravity changing will make sound.")},
   {"EnemyDirectionProperties.sound", GD_TYPE_BOOLEAN, 0, N_("Creature direction change"), CAVE_OFFSET(creature_direction_auto_change_sound), 1, N_("If this is set to true, creatures changing direction will be signaled by a sound.")},
 
-  /* COMPATIBILITY */
+  // COMPATIBILITY
   {"", GD_TAB, 0, N_("Compatibility")},
   {"", GD_LABEL, 0, N_("Skeleton")},
   {"SkeletonsWorthDiamonds", GD_TYPE_INT, GD_COMPATIBILITY_SETTING, N_("Skeletons worth diamonds"), CAVE_OFFSET(skeletons_worth_diamonds), 1, N_("The number of diamonds each skeleton is worth. Normally skeletons are used for letting the player use the pot! They are not intended to be used as a second kind of diamond."), 0, 10},
@@ -667,18 +703,19 @@ const GdStructDescriptor gd_cave_properties[] =
   {"ShortExplosions", GD_TYPE_BOOLEAN, 0, N_("Short explosions"), CAVE_OFFSET(short_explosions), 1, N_("In 1stB and newer engines, explosions were longer, they took five cave frames to complete, as opposed to four frames in the original.")},
   {"GravityAffectsAll", GD_TYPE_BOOLEAN, 0, N_("Gravity change affects everything"), CAVE_OFFSET(gravity_affects_all), 1, N_("If this is enabled, changing the gravity will also affect bladders (moving and pushing), bladder spenders, falling walls and waiting stones. Otherwise, those elements behave as gravity was always pointing downwards. This is a compatibility setting which is not recommended to change. It is intended for imported caves.")},
 
-  {NULL}  /* end of array */
+  {NULL}  // end of array
 };
 
-/* entries. */
-/* type given for each element */
+// entries.
+// type given for each element
 const GdStructDescriptor gd_replay_properties[] =
 {
-  /* default data */
+  // default data
   {"", GD_TAB, 0, N_("Replay")},
   {"Level", GD_TYPE_INT, 0, NULL, STRUCT_OFFSET(GdReplay, level), 1, NULL},
   {"RandomSeed", GD_TYPE_INT, 0, NULL, STRUCT_OFFSET(GdReplay, seed), 1, NULL},
-  //    {"Saved", GD_TYPE_BOOLEAN, 0, NULL, STRUCT_OFFSET(GdReplay, saved), 1, NULL},        /* no need to state in bdcff, as saved replays are saved ones :) */
+  // {"Saved", GD_TYPE_BOOLEAN, 0, NULL, STRUCT_OFFSET(GdReplay, saved), 1, NULL},
+  // no need to state in bdcff, as saved replays are saved ones :)
   {"Player", GD_TYPE_STRING, 0, NULL, STRUCT_OFFSET(GdReplay, player_name), 1, NULL},
   {"Date", GD_TYPE_STRING, 0, NULL, STRUCT_OFFSET(GdReplay, date), 1, NULL},
   {"Comment", GD_TYPE_LONGSTRING, 0, NULL, STRUCT_OFFSET(GdReplay, comment), 1, NULL},
@@ -688,12 +725,12 @@ const GdStructDescriptor gd_replay_properties[] =
   {"Success", GD_TYPE_BOOLEAN, 0, NULL, STRUCT_OFFSET(GdReplay, success), 1, NULL},
   {"Checksum", GD_TYPE_INT, 0, NULL, STRUCT_OFFSET(GdReplay, checksum), 1, NULL},
 
-  {NULL}  /* end of array */
+  {NULL}  // end of array
 };
 
 GdPropertyDefault gd_cave_defaults_gdash[] =
 {
-  /* default data */
+  // default data
   {CAVE_OFFSET(selectable), TRUE},
   {CAVE_OFFSET(intermission), FALSE},
   {CAVE_OFFSET(intermission_instantlife), FALSE},
@@ -712,7 +749,7 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(color4), 5},
   {CAVE_OFFSET(color5), 6},
 
-  /* difficulty */
+  // difficulty
   {CAVE_OFFSET(level_diamonds[0]), 10},
   {CAVE_OFFSET(diamond_value), 0},
   {CAVE_OFFSET(extra_diamond_value), 0},
@@ -727,7 +764,7 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(level_hatching_delay_frame[0]), 21},
   {CAVE_OFFSET(level_rand[0]), 0},
 
-  /* initial fill */
+  // initial fill
   {CAVE_OFFSET(initial_border), O_STEEL},
   {CAVE_OFFSET(initial_fill), O_DIRT},
   {CAVE_OFFSET(random_fill[0]), O_DIRT},
@@ -739,7 +776,7 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(random_fill[3]), O_DIRT},
   {CAVE_OFFSET(random_fill_probability[3]), 0},
 
-  /* PLAYER */
+  // PLAYER
   {CAVE_OFFSET(diagonal_movements), FALSE},
   {CAVE_OFFSET(active_is_first_found), TRUE},
   {CAVE_OFFSET(snap_element), O_SPACE},
@@ -755,7 +792,7 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(voodoo_any_hurt_kills_player), FALSE},
   {CAVE_OFFSET(level_penalty_time), 30},
 
-  /* magic wall */
+  // magic wall
   {CAVE_OFFSET(level_magic_wall_time), 999},
   {CAVE_OFFSET(magic_diamond_to), O_STONE_F},
   {CAVE_OFFSET(magic_stone_to), O_DIAMOND_F},
@@ -765,8 +802,10 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(magic_flying_stone_to), O_FLYING_DIAMOND_F},
   {CAVE_OFFSET(magic_flying_diamond_to), O_FLYING_STONE_F},
   {CAVE_OFFSET(magic_wall_stops_amoeba), TRUE},
+  {CAVE_OFFSET(magic_timer_zero_is_infinite), TRUE},
   {CAVE_OFFSET(magic_timer_wait_for_hatching), FALSE},
-  /* amoeba */
+
+  // amoeba
   {CAVE_OFFSET(amoeba_timer_started_immediately), TRUE},
   {CAVE_OFFSET(amoeba_timer_wait_for_hatching), FALSE},
 
@@ -778,7 +817,8 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(amoeba_timer_wait_for_hatching), FALSE},
   {CAVE_OFFSET(amoeba_too_big_effect), O_STONE},
   {CAVE_OFFSET(amoeba_enclosed_effect), O_DIAMOND},
-  /* amoeba */
+
+  // amoeba
   {CAVE_OFFSET(level_amoeba_2_threshold), 200},
   {CAVE_OFFSET(amoeba_2_growth_prob), 31250},
   {CAVE_OFFSET(amoeba_2_fast_growth_prob), 250000},
@@ -789,20 +829,21 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(amoeba_2_looks_like), O_AMOEBA_2},
   {CAVE_OFFSET(amoeba_2_explosion_effect), O_SPACE},
 
-  /* water */
+  // water
   {CAVE_OFFSET(water_does_not_flow_down), FALSE},
 
-  /* nut */
+  // nut
   {CAVE_OFFSET(nut_turns_to_when_crushed), O_NUT_EXPL_1},
-  /* replicator */
+
+  // replicator
   {CAVE_OFFSET(replicator_delay_frame), 4},
   {CAVE_OFFSET(replicators_active), TRUE},
 
-  /* conveyor belt */
+  // conveyor belt
   {CAVE_OFFSET(conveyor_belts_active), TRUE},
   {CAVE_OFFSET(conveyor_belts_direction_changed), FALSE},
 
-  /* slime */
+  // slime
   {CAVE_OFFSET(slime_predictable), TRUE},
   {CAVE_OFFSET(level_slime_seed_c64), -1},
   {CAVE_OFFSET(level_slime_permeability_c64), 0},
@@ -814,19 +855,19 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(slime_eats_3), O_NUT},
   {CAVE_OFFSET(slime_converts_3), O_NUT_F},
 
-  /* acid */
+  // acid
   {CAVE_OFFSET(acid_eats_this), O_DIRT},
   {CAVE_OFFSET(acid_spread_ratio), 31250},
   {CAVE_OFFSET(acid_turns_to), O_EXPLODE_3},
 
-  /* biter */
+  // biter
   {CAVE_OFFSET(biter_delay_frame), 0},
   {CAVE_OFFSET(biter_eat), O_DIAMOND},
 
-  /* bladder */
+  // bladder
   {CAVE_OFFSET(bladder_converts_by), O_VOODOO},
 
-  /* SOUND */
+  // SOUND
   {CAVE_OFFSET(amoeba_sound), TRUE},
   {CAVE_OFFSET(magic_wall_sound), TRUE},
   {CAVE_OFFSET(slime_sound), TRUE},
@@ -848,11 +889,12 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(gravity_change_sound), TRUE},
   {CAVE_OFFSET(creature_direction_auto_change_sound), TRUE},
 
-  /* creature effects */
+  // creature effects
   {CAVE_OFFSET(creatures_backwards), FALSE},
   {CAVE_OFFSET(creatures_direction_auto_change_time), 0},
   {CAVE_OFFSET(creatures_direction_auto_change_on_start), FALSE},
-  /* cave effects */
+
+  // cave effects
   {CAVE_OFFSET(explosion_effect), O_SPACE},
   {CAVE_OFFSET(diamond_birth_effect), O_DIAMOND},
   {CAVE_OFFSET(bomb_explosion_effect), O_BRICK},
@@ -868,16 +910,18 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {CAVE_OFFSET(stone_bouncing_effect), O_STONE},
   {CAVE_OFFSET(diamond_falling_effect), O_DIAMOND_F},
   {CAVE_OFFSET(diamond_bouncing_effect), O_DIAMOND},
-  /* visual effects */
+
+  // visual effects
   {CAVE_OFFSET(expanding_wall_looks_like), O_BRICK},
   {CAVE_OFFSET(dirt_looks_like), O_DIRT},
-  /* gravity */
+
+  // gravity
   {CAVE_OFFSET(gravity), GD_MV_DOWN},
   {CAVE_OFFSET(gravity_switch_active), FALSE},
   {CAVE_OFFSET(skeletons_needed_for_pot), 5},
   {CAVE_OFFSET(gravity_change_time), 10},
 
-  /* COMPATIBILITY */
+  // COMPATIBILITY
   {CAVE_OFFSET(border_scan_first_and_last), TRUE},
   {CAVE_OFFSET(lineshift), FALSE},
   {CAVE_OFFSET(wraparound_objects), FALSE},
@@ -888,13 +932,13 @@ GdPropertyDefault gd_cave_defaults_gdash[] =
   {-1},
 };
 
-/* return new element, which appears after elem is hammered. */
-/* returns o_none, if elem is invalid for hammering. */
+// return new element, which appears after elem is hammered.
+// returns o_none, if elem is invalid for hammering.
 GdElement gd_element_get_hammered(GdElement elem)
 {
   switch (elem)
   {
-    /* what is under the pneumatic hammer? */
+    // what is under the pneumatic hammer?
     case O_WALLED_KEY_1:
       return O_KEY_1;
 
@@ -933,40 +977,40 @@ void gd_cave_db_init(void)
   HashTable *pointers;
   boolean lowercase_names = TRUE;
 
-  /* TRANSLATORS: some languages (for example, german) do not have lowercase nouns. */
-  /* When gdash generates the list of lowercase element names, this has to be */
-  /* taken into account. Therefore we have a string, which must be changed */
-  /* by the translator to select the behavior. */
-  /* For example, the name of the element is "Brick wall", as in a button, it has to be */
-  /* written with an uppercase initial. But if "Line of brick wall", the B is changed to b. */
-  /* However, this is not allowed in some languages, for example, German. */
-  /* So one writes "Ziegelmauer", and "Linie aus Ziegelmauer", the Z is not changed to z. */
-  /* Set the translated string to "lowercase-element-names-yes", if your language */
-  /* allows writing nouns with lowercase initials. Set it to "lowercase-element-names-no", */
-  /* if not: for example, german. Do not translate the string, but set the behavior! */
+  // TRANSLATORS: some languages (for example, german) do not have lowercase nouns.
+  // When gdash generates the list of lowercase element names, this has to be
+  // taken into account. Therefore we have a string, which must be changed
+  // by the translator to select the behavior.
+  // For example, the name of the element is "Brick wall", as in a button, it has to be
+  // written with an uppercase initial. But if "Line of brick wall", the B is changed to b.
+  // However, this is not allowed in some languages, for example, German.
+  // So one writes "Ziegelmauer", and "Linie aus Ziegelmauer", the Z is not changed to z.
+  // Set the translated string to "lowercase-element-names-yes", if your language
+  // allows writing nouns with lowercase initials. Set it to "lowercase-element-names-no",
+  // if not: for example, german. Do not translate the string, but set the behavior!
 
   if (strEqual(_("lowercase-element-names-yes"), "lowercase-element-names-no"))
     lowercase_names = FALSE;
 
-  /* check element database for faults. */
+  // check element database for faults.
   for (i = 0; gd_elements[i].element != -1; i++)
   {
     if (gd_elements[i].element != i)
       Error("element: i:0x%x != 0x%x", i, gd_elements[i].element);
 
-    /* if it has a name, create a lowercase name (of the translated one).
-       will be used by the editor */
+    // if it has a name, create a lowercase name (of the translated one).
+    // will be used by the editor
     if (gd_elements[i].name)
     {
       if (lowercase_names)
-       /* the function allocates a new string, but it is needed as long as the app is running */
-       gd_elements[i].lowercase_name = g_utf8_strdown(gettext(gd_elements[i].name), -1);
+       // the function allocates a new string, but it is needed as long as the app is running
+       gd_elements[i].lowercase_name = getStringToLower(gettext(gd_elements[i].name));
       else
-       /* only translate, no lowercase. */
+       // only translate, no lowercase.
        gd_elements[i].lowercase_name = gettext(gd_elements[i].name);
     }
 
-    /* we do not like generated pixbufs for games. only those that are in the png. */
+    // we do not like generated pixbufs for games. only those that are in the png.
     if (ABS(gd_elements[i].image_game) > GD_NUM_OF_CELLS_X * GD_NUM_OF_CELLS_Y)
       Error("game pixbuf for element %x (%s) bigger than png size", i, gd_elements[i].name);
 
@@ -977,8 +1021,10 @@ void gd_cave_db_init(void)
       Error("element %x (%s) can be hammered, but get_hammered_element does not define another one", i, gd_elements[i].name);
   }
 
-  /* NOT REALLY NEEDED ANYMORE, as the enum takes care of it.
-     maybe to show that there is an unnecessary one. */
+  /*
+    NOT REALLY NEEDED ANYMORE, as the enum takes care of it.
+    maybe to show that there is an unnecessary one.
+  */
   /*
     g_print("Free pixbuf indexes: ");
     for (i = GD_NUM_OF_CELLS_X*GD_NUM_OF_CELLS_Y; i<GD_NUM_OF_CELLS; i++)
@@ -989,7 +1035,7 @@ void gd_cave_db_init(void)
     g_print("\n");
   */
 
-  /* uncomment this, to show free element->character characters. */
+  // uncomment this, to show free element->character characters.
   /*
     gd_create_char_to_element_table();
     g_print("Free characters: ");
@@ -999,7 +1045,7 @@ void gd_cave_db_init(void)
     g_print("\n");
   */
 
-  /* check the cave property database for faults. */
+  // check the cave property database for faults.
   pointers = create_hashtable(get_hash_from_integer, hash_key_integers_are_equal, NULL, NULL);
 
   for (i = 0; gd_cave_properties[i].identifier != NULL; i++)
@@ -1010,8 +1056,7 @@ void gd_cave_db_init(void)
     {
       case GD_LABEL:
       case GD_TAB:
-       /* some lines are used for the user interface. these should not have
-          an identifier. */
+       // some lines are used for the user interface. these should not have an identifier.
        if (strcmp(gd_cave_properties[i].identifier, "") != 0)
        {
          Error ("ui lines in cave properties should not have identifiers: %s",
@@ -1020,9 +1065,9 @@ void gd_cave_db_init(void)
        break;
 
       case GD_TYPE_STRING:
-       /* check if any of the properties are designated as string arrays.
-          they are not supported in
-        * file read/write and operations, also they do not even make any sense! */
+       // check if any of the properties are designated as string arrays.
+       // they are not supported in file read/write and operations,
+       // also they do not even make any sense!
        if (gd_cave_properties[i].count != 1)
        {
          Error ("string arrays have no sense in cave properties: %s",
@@ -1039,7 +1084,7 @@ void gd_cave_db_init(void)
        break;
 
       case GD_TYPE_EFFECT:
-       /* the same applies for effects. */
+       // the same applies for effects.
        if (gd_cave_properties[i].count != 1)
        {
          Error ("effect arrays not supported in cave properties: %s",
@@ -1048,7 +1093,7 @@ void gd_cave_db_init(void)
        break;
 
       case GD_TYPE_COLOR:
-       /* the same applies for effects. */
+       // the same applies for effects.
        if (gd_cave_properties[i].count != 1)
        {
          Error ("color arrays not supported in cave properties: %s",
@@ -1069,9 +1114,9 @@ void gd_cave_db_init(void)
     {
       const char *another_prop;
 
-      /* other types */
-      /* check if its pointer is not the same as another one's */
-      /* +1 is added so it is never zero */
+      // other types
+      // check if its pointer is not the same as another one's
+      // +1 is added so it is never zero
       if (!(gd_cave_properties[i].flags & GD_DONT_SAVE) && strcmp(gd_cave_properties[i].identifier, "") == 0)
       {
        Error ("property should have a bdcff identifier: line %d, name %s",
@@ -1087,7 +1132,7 @@ void gd_cave_db_init(void)
       }
       else
       {
-       /* value is the identifier, so we can report the OLD one if the check fails */
+       // value is the identifier, so we can report the OLD one if the check fails
        hashtable_insert(pointers, INT_TO_PTR(gd_cave_properties[i].offset + 1),
                         gd_cave_properties[i].identifier);
       }