rnd-20040218-1-src
authorHolger Schemel <info@artsoft.org>
Wed, 18 Feb 2004 02:22:59 +0000 (03:22 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:45:53 +0000 (10:45 +0200)
* fixed bug which caused all CE change pages to be ignored which had
  the same change event, but used a different element side
  (reported by Simon Forsberg)
* fixed bug which caused elements that can move and fall and that are
  transported by a conveyor belt to continue moving into that direction
  after leaving the conveyor belt, regardless of their own movement
  type; only elements which can not move are transported now
  (reported by Simon Forsberg)
* fixed bug which could cause an array overflow in RelocatePlayer()
  (reported by Niko Böhm)
* changed Emerald Mine style "passable / over" elements to "protected"
  (fixing unsolvable level 10 of "Bondmine 9" with bug beside gate)
* added new option to select from which side a "walkable/passable"
  element can be entered
* added explosion and ignition delay for elements that can explode
* fixed bug which caused player not being protected against enemies
  when a CE was "walkable / inside" and was not "indestructible"
* added "walkable/passable" fields to be "protected/unprotected"
  against enemies, even if not accessible "inside" but "over/under"

CHANGES
ChangeLog
src/conf_e2g.c
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/init.c

diff --git a/CHANGES b/CHANGES
index cb2335dbc03aa6d811dce5564bd73e15d09fa948..e949e68f1c1e2fc6233450a7309ffabdc2b74530 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-Release Version 3.0.9 [?? ??? ????]
+Release Version 3.1.0 [?? ??? ????]
 -----------------------------------
 
 Release Version 3.0.8 [14 DEC 2003]
index 6e0badccbc6efecafbc29fbe5b1bcae9212ae20a..e2a771a293bcae1070b795cda5689e1125437c9c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2004-02-17
+       * fixed bug which caused all CE change pages to be ignored which had
+         the same change event, but used a different element side
+         (reported by Simon Forsberg)
+
+       * fixed bug which caused elements that can move and fall and that are
+         transported by a conveyor belt to continue moving into that direction
+         after leaving the conveyor belt, regardless of their own movement
+         type; only elements which can not move are transported now
+         (reported by Simon Forsberg)
+
+       * fixed bug which could cause an array overflow in RelocatePlayer()
+         (reported by Niko Böhm)
+
+       * changed Emerald Mine style "passable / over" elements to "protected"
+         (fixing unsolvable level 10 of "Bondmine 9" with bug beside gate)
+
+       * added new option to select from which side a "walkable/passable"
+         element can be entered
+
+2004-02-16
+       * added explosion and ignition delay for elements that can explode
+
+2004-02-05
+       * fixed bug which caused player not being protected against enemies
+         when a CE was "walkable / inside" and was not "indestructible"
+       * added "walkable/passable" fields to be "protected/unprotected"
+         against enemies, even if not accessible "inside" but "over/under"
+
 2004-02-04
        * corrected move pattern to 32 bit and initial move direction to 8 bit
 
@@ -6,6 +35,7 @@
 
 2004-02-02
        * added some special EMC mappings to Emerald Mine level loader
+         (also covering previously unknown element in level 0 of "Bondmine 8")
 
 2004-01-30
        * added option to block last field when player is moving (for Supaplex)
index 583c2c3eeabb3ec0b343f8f4ecfc5006a4274017..1bbae6db31acf28f735353521a7d43778511b922 100644 (file)
@@ -2525,6 +2525,38 @@ element_to_graphic[] =
     EL_UNKNOWN,                                -1, -1, FALSE,
     IMG_UNKNOWN
   },
+  {
+    EL_BD_BUTTERFLY_DOWN,              -1, -1, FALSE,
+    IMG_BD_BUTTERFLY
+  },
+  {
+    EL_BD_BUTTERFLY_LEFT,              -1, -1, FALSE,
+    IMG_BD_BUTTERFLY
+  },
+  {
+    EL_BD_BUTTERFLY_RIGHT,             -1, -1, FALSE,
+    IMG_BD_BUTTERFLY
+  },
+  {
+    EL_BD_BUTTERFLY_UP,                        -1, -1, FALSE,
+    IMG_BD_BUTTERFLY
+  },
+  {
+    EL_BD_FIREFLY_DOWN,                        -1, -1, FALSE,
+    IMG_BD_FIREFLY
+  },
+  {
+    EL_BD_FIREFLY_LEFT,                        -1, -1, FALSE,
+    IMG_BD_FIREFLY
+  },
+  {
+    EL_BD_FIREFLY_RIGHT,               -1, -1, FALSE,
+    IMG_BD_FIREFLY
+  },
+  {
+    EL_BD_FIREFLY_UP,                  -1, -1, FALSE,
+    IMG_BD_FIREFLY
+  },
   {
     EL_DOOR_WHITE,                     -1, -1, FALSE,
     IMG_CHAR_QUESTION
index 527570809876d4efa61065a5946de98179a9b485..3a1d4df0c716347846d1757526bab0361e21dc57 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-02-17 19:34]"
+#define COMPILE_DATE_STRING "[2004-02-18 02:49]"
index 51c842b9d32b146c3a081e51bd99dbac54be3276..9cd163a506eb7891c9f726b2606432424f655804 100644 (file)
 
 /* values for element content drawing areas */
 /* amoeba content */
-#define ED_AREA_ELEM_CONTENT_XPOS      ( 2 * MINI_TILEX)
-#define ED_AREA_ELEM_CONTENT_YPOS      (22 * MINI_TILEY)
+#define ED_AREA_AMOEBA_CONTENT_XPOS    ED_SETTINGS_XPOS(0)
+#define ED_AREA_AMOEBA_CONTENT_YPOS    (ED_SETTINGS_YPOS(2) + \
+                                        ED_GADGET_DISTANCE)
 
 /* yamyam content */
-#define ED_AREA_YAMYAM_CONTENT_XPOS(n) (ED_AREA_ELEM_CONTENT_XPOS + \
+#define ED_AREA_YAMYAM_CONTENT_XPOS(n) (2 * MINI_TILEX + \
                                         5 * (n % 4) * MINI_TILEX)
-#define ED_AREA_YAMYAM_CONTENT_YPOS(n) (ED_AREA_ELEM_CONTENT_YPOS + \
+#define ED_AREA_YAMYAM_CONTENT_YPOS(n) (22 * MINI_TILEY + \
                                         6 * (n / 4) * MINI_TILEY)
 
 /* custom change target */
@@ -1785,21 +1786,21 @@ static struct
   /* ---------- element settings: configure (various elements) ------------- */
 
   {
-    ED_SETTINGS_XPOS(0),               0,      /* set at runtime */
+    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(0),
     GADGET_ID_STICK_ELEMENT,           GADGET_ID_NONE,
     &stick_element_properties_window,
     NULL,
     "stick this screen to edit content","stick this screen to edit content"
   },
   {
-    ED_SETTINGS_XPOS(0),               ED_COUNTER_YPOS(4),
+    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(1),
     GADGET_ID_EM_SLIPPERY_GEMS,                GADGET_ID_NONE,
     &level.em_slippery_gems,
     NULL,
     "slip down from certain flat walls","use EM style slipping behaviour"
   },
   {
-    ED_SETTINGS_XPOS(0),               ED_COUNTER_YPOS(4),
+    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(0),
     GADGET_ID_BLOCK_LAST_FIELD,                GADGET_ID_NONE,
     &level.block_last_field,
     NULL,
@@ -2021,10 +2022,10 @@ static struct
   /* ---------- amoeba content --------------------------------------------- */
 
   {
-    ED_AREA_ELEM_CONTENT_XPOS,         ED_AREA_ELEM_CONTENT_YPOS,
+    ED_AREA_AMOEBA_CONTENT_XPOS,       ED_AREA_AMOEBA_CONTENT_YPOS,
     1, 1,
     GADGET_ID_AMOEBA_CONTENT,          GADGET_ID_NONE,
-    NULL, "content of amoeba",         NULL
+    "content:", NULL,                  NULL
   },
 
   /* ---------- custom graphic --------------------------------------------- */
@@ -4835,8 +4836,10 @@ void FreeLevelEditorGadgets()
 static void MapCounterButtons(int id)
 {
   int gadget_id_down = counterbutton_info[id].gadget_id_down;
+  int gadget_id_text = counterbutton_info[id].gadget_id_text;
   int gadget_id_up   = counterbutton_info[id].gadget_id_up;
   struct GadgetInfo *gi_down = level_editor_gadget[gadget_id_down];
+  struct GadgetInfo *gi_text = level_editor_gadget[gadget_id_text];
   struct GadgetInfo *gi_up   = level_editor_gadget[gadget_id_up];
 #if 0
   char infotext[MAX_OUTPUT_LINESIZE + 1];
@@ -4857,6 +4860,17 @@ static void MapCounterButtons(int id)
   int y = gi_up->y + yoffset;
 #endif
 
+#if 1
+  /* special case needed for "score" counter gadget */
+  if (id == ED_COUNTER_ID_ELEMENT_SCORE)
+  {
+    ModifyGadget(gi_down, GDI_Y, SY + counterbutton_info[id].y, GDI_END);
+    ModifyGadget(gi_text, GDI_Y, SY + counterbutton_info[id].y, GDI_END);
+    ModifyGadget(gi_up,   GDI_Y, SY + counterbutton_info[id].y, GDI_END);
+    y = gi_up->y + yoffset;
+  }
+#endif
+
   if (counterbutton_info[id].text_above)
     DrawText(x, y_above, counterbutton_info[id].text_above, FONT_TEXT_1);
 
@@ -4868,9 +4882,9 @@ static void MapCounterButtons(int id)
 
   ModifyEditorCounter(id, *counterbutton_info[id].value);
 
-  MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_down]);
-  MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_text]);
-  MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_up]);
+  MapGadget(gi_down);
+  MapGadget(gi_text);
+  MapGadget(gi_up);
 }
 
 static void MapControlButtons()
@@ -6644,8 +6658,14 @@ static void DrawPropertiesConfig()
     {
       int counter_id = ED_COUNTER_ID_ELEMENT_SCORE;
 
+      if (HAS_CONTENT(properties_element))     /* needs stickybutton */
+       counterbutton_info[counter_id].y = ED_SETTINGS_YPOS(1);
+      else
+       counterbutton_info[counter_id].y = ED_SETTINGS_YPOS(0);
+
       counterbutton_info[counter_id].value = elements_with_counter[i].value;
       counterbutton_info[counter_id].text_right= elements_with_counter[i].text;
+
       MapCounterButtons(counter_id);
 
       break;
@@ -6655,9 +6675,7 @@ static void DrawPropertiesConfig()
   if (HAS_CONTENT(properties_element))
   {
     /* draw stickybutton gadget */
-    i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
-    checkbutton_info[i].y = ED_COUNTER_YPOS(4);
-    MapCheckbuttonGadget(i);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT);
 
     if (IS_AMOEBOID(properties_element))
       MapDrawingArea(ED_DRAWING_ID_AMOEBA_CONTENT);
@@ -6692,9 +6710,7 @@ static void DrawPropertiesConfig()
   if (IS_CUSTOM_ELEMENT(properties_element))
   {
     /* draw stickybutton gadget */
-    i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
-    checkbutton_info[i].y = ED_SETTINGS_YPOS(0);
-    MapCheckbuttonGadget(i);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT);
 
     if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_1)
     {
@@ -6748,9 +6764,7 @@ static void DrawPropertiesConfig()
   else if (IS_GROUP_ELEMENT(properties_element))
   {
     /* draw stickybutton gadget */
-    i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
-    checkbutton_info[i].y = ED_SETTINGS_YPOS(0);
-    MapCheckbuttonGadget(i);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT);
 
     /* draw checkbutton gadgets */
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC);
@@ -6794,9 +6808,7 @@ static void DrawPropertiesChange()
   int i;
 
   /* draw stickybutton gadget */
-  i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
-  checkbutton_info[i].y = ED_SETTINGS_YPOS(0);
-  MapCheckbuttonGadget(i);
+  MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT);
 
   /* draw checkbutton gadgets */
   for (i =  ED_CHECKBUTTON_ID_CHANGE_FIRST;
index c7af57d1ed923d0b4daec8c864b9b47a09e3221f..356d8a4b11dca6581e77f39a6b118acbf1391978 100644 (file)
@@ -1011,8 +1011,13 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
   /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */
   ei->move_pattern |= (getFile16BitBE(file) << 16);
 
+  ei->access_direction = getFile8Bit(file);
+
+  ei->explosion_delay = getFile8Bit(file);
+  ei->ignition_delay = getFile8Bit(file);
+
   /* some free bytes for future custom property values and padding */
-  ReadUnusedBytesFromFile(file, 5);
+  ReadUnusedBytesFromFile(file, 2);
 
   /* read change property values */
 
@@ -2582,8 +2587,13 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */
   putFile16BitBE(file, (ei->move_pattern >> 16) & 0xffff);
 
+  putFile8Bit(file, ei->access_direction);
+
+  putFile8Bit(file, ei->explosion_delay);
+  putFile8Bit(file, ei->ignition_delay);
+
   /* some free bytes for future custom property values and padding */
-  WriteUnusedBytesToFile(file, 5);
+  WriteUnusedBytesToFile(file, 2);
 
   /* write change property values */
 
index 572758d93ba61a642c4c8414f9de9ec7fede4278..77df179d6664144f52f88ecdaf4de9710dab5d46 100644 (file)
@@ -497,6 +497,28 @@ collect_count_list[] =
   { EL_UNDEFINED,              0 },
 };
 
+struct
+{
+  int element;
+  int direction;
+}
+tube_access[] =
+{
+  { EL_TUBE_ANY,               MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+  { EL_TUBE_VERTICAL,                               MV_UP | MV_DOWN },
+  { EL_TUBE_HORIZONTAL,                MV_LEFT | MV_RIGHT                   },
+  { EL_TUBE_VERTICAL_LEFT,     MV_LEFT |            MV_UP | MV_DOWN },
+  { EL_TUBE_VERTICAL_RIGHT,              MV_RIGHT | MV_UP | MV_DOWN },
+  { EL_TUBE_HORIZONTAL_UP,     MV_LEFT | MV_RIGHT | MV_UP           },
+  { EL_TUBE_HORIZONTAL_DOWN,   MV_LEFT | MV_RIGHT |         MV_DOWN },
+  { EL_TUBE_LEFT_UP,           MV_LEFT |            MV_UP           },
+  { EL_TUBE_LEFT_DOWN,         MV_LEFT |                    MV_DOWN },
+  { EL_TUBE_RIGHT_UP,                    MV_RIGHT | MV_UP           },
+  { EL_TUBE_RIGHT_DOWN,                          MV_RIGHT |         MV_DOWN },
+
+  { EL_UNDEFINED,              0                                    }
+};
+
 static unsigned long trigger_events[MAX_NUM_ELEMENTS];
 
 #define IS_AUTO_CHANGING(e)    (element_info[e].change_events & \
@@ -1157,6 +1179,18 @@ static void InitGameEngine()
   for (i = 0; collect_count_list[i].element != EL_UNDEFINED; i++)
     element_info[collect_count_list[i].element].collect_count =
       collect_count_list[i].count;
+
+  /* ---------- initialize access direction -------------------------------- */
+
+  /* initialize access direction values to default */
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+    if (!IS_CUSTOM_ELEMENT(i))
+      element_info[i].access_direction = MV_ALL_DIRECTIONS;
+
+  /* set access direction value for certain elements from pre-defined list */
+  for (i = 0; tube_access[i].element != EL_UNDEFINED; i++)
+    element_info[tube_access[i].element].access_direction =
+      tube_access[i].direction;
 }
 
 
@@ -2731,8 +2765,10 @@ void Explode(int ex, int ey, int phase, int mode)
       KillHeroUnlessExplosionProtected(x, y);
       border_explosion = TRUE;
 
+#if 0
       if (phase == last_phase)
        printf("::: IS_PLAYER\n");
+#endif
     }
     else if (CAN_EXPLODE_BY_EXPLOSION(border_element))
     {
@@ -2741,8 +2777,10 @@ void Explode(int ex, int ey, int phase, int mode)
       Bang(x, y);
       border_explosion = TRUE;
 
+#if 0
       if (phase == last_phase)
        printf("::: CAN_EXPLODE_BY_EXPLOSION\n");
+#endif
     }
     else if (border_element == EL_AMOEBA_TO_DIAMOND)
     {
@@ -2750,11 +2788,13 @@ void Explode(int ex, int ey, int phase, int mode)
       Store2[x][y] = 0;
       border_explosion = TRUE;
 
+#if 0
       if (phase == last_phase)
        printf("::: EL_AMOEBA_TO_DIAMOND [%d, %d] [%d]\n",
               element_info[border_element].explosion_delay,
               element_info[border_element].ignition_delay,
               phase);
+#endif
     }
 
 #if 1
@@ -7773,9 +7813,14 @@ static void CheckGravityMovement(struct PlayerInfo *player)
         canEnterSupaplexPort(new_jx, new_jy, dx, dy))));
     /* !!! extend EL_SAND to anything diggable !!! */
 
+    boolean player_is_standing_on_valid_field =
+      (IS_WALKABLE_INSIDE(Feld[jx][jy]) ||
+       (IS_WALKABLE(Feld[jx][jy]) &&
+       !(element_info[Feld[jx][jy]].access_direction & MV_DOWN)));
+
     if (field_under_player_is_free &&
-       !player_is_moving_to_valid_field &&
-       !IS_WALKABLE_INSIDE(Feld[jx][jy]))
+       !player_is_standing_on_valid_field &&
+       !player_is_moving_to_valid_field)
       player->programmed_action = MV_DOWN;
   }
 }
@@ -8901,6 +8946,7 @@ int DigField(struct PlayerInfo *player,
                        dy == +1 ? MV_DOWN : MV_NO_MOVING);
   int opposite_direction = MV_DIR_OPPOSITE(move_direction);
   int dig_side = change_sides[MV_DIR_BIT(move_direction)];
+  int old_element = Feld[jx][jy];
   int element;
 
   if (player->MovPos == 0)
@@ -8923,6 +8969,8 @@ int DigField(struct PlayerInfo *player,
   if (IS_MOVING(x, y) || IS_PLAYER(x, y))
     return MF_NO_ACTION;
 
+#if 0
+
 #if 0
   if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy]))
 #else
@@ -8959,8 +9007,15 @@ int DigField(struct PlayerInfo *player,
       return MF_NO_ACTION;     /* tube has no opening in this direction */
   }
 
-  if (IS_CUSTOM_ELEMENT(Feld[jx][jy]) && IS_WALKABLE(Feld[jx][jy]) &&
-      !(element_info[Feld[jx][jy]].access_direction & move_direction))
+#else
+
+  if (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0))
+    old_element = Back[jx][jy];
+
+#endif
+
+  if (IS_WALKABLE(old_element) &&
+      !(element_info[old_element].access_direction & move_direction))
     return MF_NO_ACTION;       /* field has no opening in this direction */
 
   element = Feld[x][y];
@@ -9035,6 +9090,7 @@ int DigField(struct PlayerInfo *player,
       PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING);
       break;
 
+#if 0
     case EL_TUBE_ANY:
     case EL_TUBE_VERTICAL:
     case EL_TUBE_HORIZONTAL:
@@ -9077,6 +9133,7 @@ int DigField(struct PlayerInfo *player,
        PlayLevelSound(x, y, SND_CLASS_TUBE_WALKING);
       }
       break;
+#endif
 
     default:
 
@@ -9084,8 +9141,7 @@ int DigField(struct PlayerInfo *player,
       {
        int sound_action = ACTION_WALKING;
 
-       if (IS_CUSTOM_ELEMENT(element) &&
-           !(element_info[element].access_direction & opposite_direction))
+       if (!(element_info[element].access_direction & opposite_direction))
          return MF_NO_ACTION;  /* field not accessible from this direction */
 
        if (element >= EL_GATE_1 && element <= EL_GATE_4)
index cfb271b1c04d8bc360357718ccee1a04931c64d6..142c21bc6bdfc63dbff6c31f1382dfa8cc152480 100644 (file)
@@ -2089,6 +2089,16 @@ void InitElementPropertiesStatic()
 
   static int ep_protected[] =
   {
+    EL_EM_GATE_1,
+    EL_EM_GATE_2,
+    EL_EM_GATE_3,
+    EL_EM_GATE_4,
+    EL_EM_GATE_1_GRAY,
+    EL_EM_GATE_2_GRAY,
+    EL_EM_GATE_3_GRAY,
+    EL_EM_GATE_4_GRAY,
+    EL_SWITCHGATE_OPEN,
+    EL_TIMEGATE_OPEN,
     -1
   };
 
@@ -3242,6 +3252,18 @@ void InitElementPropertiesEngine(int engine_version)
     if (element_info[element].push_delay_random == -1)
       element_info[element].push_delay_random = game.default_push_delay_random;
   }
+
+  /* set some other uninitialized values of custom elements in older levels */
+  if (engine_version < VERSION_IDENT(3,0,9,0))
+  {
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+    {
+      int element = EL_CUSTOM_START + i;
+
+      element_info[element].explosion_delay = 18;
+      element_info[element].ignition_delay = 8;
+    }
+  }
 #endif
 
   /* this is needed because some graphics depend on element properties */