rnd-20040222-1-src
authorHolger Schemel <info@artsoft.org>
Sun, 22 Feb 2004 11:22:32 +0000 (12:22 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:45:58 +0000 (10:45 +0200)
* added option "can move into acid" for all movable elements
* fixed graphical bug for elements moving into acid
* changed event handling to handle all pending events before going on

ChangeLog
src/conftime.h
src/editor.c
src/events.c
src/files.c
src/game.c
src/init.c
src/tools.c
src/tools.h

index 7824af79cf8d711b9c1d38448e7e61485274d8b9..d7d1674991003f4ba9594a97ec36827409a285a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,9 @@
        * "spring push bug" reintroduced as configurable element property
        * fixed bug with missing properties for "mole"
        * fixed bug that showed up when fixing the above "mole" properties bug
+       * added option "can move into acid" for all movable elements
+       * fixed graphical bug for elements moving into acid
+       * changed event handling to handle all pending events before going on
 
 2004-02-17
        * fixed bug which caused all CE change pages to be ignored which had
index 59869ce1ec0c0a56b713ece11732e52c3c21a619..531e29685dfa3394c400eccc347677c72332b406 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-02-21 21:18]"
+#define COMPILE_DATE_STRING "[2004-02-22 02:42]"
index cc05c9d24f91bdd4cad9c9274344761d25fef4ca..199da58e31b098767a660ab174bf4f8556c26283 100644 (file)
@@ -5843,6 +5843,7 @@ static void CopyClassicElementPropertiesToGame(int element)
   if (COULD_MOVE_INTO_ACID(element))
     setMoveIntoAcidProperty(&level, element,
                            custom_element_properties[EP_CAN_MOVE_INTO_ACID]);
+
 #else
 
   if (COULD_MOVE_INTO_ACID(element))
index e76026e17bfc68c3c468eedc59421fcdc08a1ff3..b123c86d7f6667632eda8bfe7385da81ddbe2825 100644 (file)
@@ -85,7 +85,7 @@ void EventLoop(void)
     {
       Event event;
 
-      if (NextValidEvent(&event))
+      while (NextValidEvent(&event))
       {
        switch(event.type)
        {
@@ -411,36 +411,8 @@ void HandleButton(int mx, int my, int button)
 
     case GAME_MODE_PLAYING:
 #ifdef DEBUG
-      if (button == MB_RELEASED)
-      {
-       if (IN_GFX_SCREEN(mx, my))
-       {
-         int sx = (mx - SX) / TILEX;
-         int sy = (my - SY) / TILEY;
-         int x = LEVELX(sx);
-         int y = LEVELY(sy);
-
-         printf("INFO: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y);
-
-         if (!IN_LEV_FIELD(x, y))
-           break;
-
-         printf("      Feld[%d][%d] == %d ('%s')\n", x,y, Feld[x][y],
-                element_info[Feld[x][y]].token_name);
-         printf("      Back[%d][%d] == %d\n", x,y, Back[x][y]);
-         printf("      Store[%d][%d] == %d\n", x,y, Store[x][y]);
-         printf("      Store2[%d][%d] == %d\n", x,y, Store2[x][y]);
-         printf("      StorePlayer[%d][%d] == %d\n", x,y, StorePlayer[x][y]);
-         printf("      MovPos[%d][%d] == %d\n", x,y, MovPos[x][y]);
-         printf("      MovDir[%d][%d] == %d\n", x,y, MovDir[x][y]);
-         printf("      MovDelay[%d][%d] == %d\n", x,y, MovDelay[x][y]);
-         printf("      ChangeDelay[%d][%d] == %d\n", x,y, ChangeDelay[x][y]);
-         printf("      GfxElement[%d][%d] == %d\n", x,y, GfxElement[x][y]);
-         printf("      GfxAction[%d][%d] == %d\n", x,y, GfxAction[x][y]);
-         printf("      GfxFrame[%d][%d] == %d\n", x,y, GfxFrame[x][y]);
-         printf("\n");
-       }
-      }
+      if (button == MB_PRESSED && !motion_status && IN_GFX_SCREEN(mx, my))
+       DumpTile(LEVELX((mx - SX) / TILEX), LEVELY((my - SY) / TILEY));
 #endif
       break;
 
index 34e3d3acebb9f2f3af0d013718574c7eae867e39..c8580105cfcef25a13b193902a9c8fa8d0732c9c 100644 (file)
@@ -2158,6 +2158,15 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
+  /* correct field access direction (for old levels without this option) */
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+  {
+    int element = EL_CUSTOM_START + i;
+
+    if (element_info[element].access_direction == MV_NO_MOVING)
+      element_info[element].access_direction = MV_ALL_DIRECTIONS;
+  }
+
 #if 0
   /* set default push delay values (corrected since version 3.0.7-1) */
   if (level->game_version < VERSION_IDENT(3,0,7,1))
index 75508923566c856c7708a3ab612ab9006189a287..f8289cc9138937767facf986edaa3b21fa908628 100644 (file)
 #define GET_MAX_MOVE_DELAY(e)  (   (element_info[e].move_delay_fixed) + \
                                    (element_info[e].move_delay_random))
 
+#define ELEMENT_CAN_ENTER_FIELD_BASE(e, x, y, condition)               \
+               (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) ||                \
+                                       (CAN_MOVE_INTO_ACID(e) &&       \
+                                        Feld[x][y] == EL_ACID) ||      \
+                                       (condition)))
+
+#if 0
 #define ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, condition)            \
                (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) ||                \
                                        (condition) ||                  \
                                        (DONT_COLLIDE_WITH(e) &&        \
                                         IS_PLAYER(x, y) &&             \
                                         !PLAYER_ENEMY_PROTECTED(x, y))))
-
-#define ELEMENT_CAN_ENTER_FIELD_GENERIC_X(e, x, y, condition)          \
+#else
+#define ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, condition)            \
                (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) ||                \
                                        (condition) ||                  \
                                        (CAN_MOVE_INTO_ACID(e) &&       \
                                        (DONT_COLLIDE_WITH(e) &&        \
                                         IS_PLAYER(x, y) &&             \
                                         !PLAYER_ENEMY_PROTECTED(x, y))))
+#endif
 
 #define ELEMENT_CAN_ENTER_FIELD_GENERIC_2(x, y, condition)             \
                (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) ||                \
 #define ELEMENT_CAN_ENTER_FIELD_OR_ACID_2(x, y)                                \
        ELEMENT_CAN_ENTER_FIELD_GENERIC_2(x, y, (Feld[x][y] == EL_ACID))
 
-#define ENEMY_CAN_ENTER_FIELD(x, y) (IN_LEV_FIELD(x, y) && IS_FREE(x, y))
+#if 0
+#define ENEMY_CAN_ENTER_FIELD(e, x, y) (IN_LEV_FIELD(x, y) && IS_FREE(x, y))
+#else
+#define ENEMY_CAN_ENTER_FIELD(e, x, y) ELEMENT_CAN_ENTER_FIELD_BASE(e, x, y, 0)
+#endif
 
 #define YAMYAM_CAN_ENTER_FIELD(x, y)                                   \
                (IN_LEV_FIELD(x, y) && (IS_FREE_OR_PLAYER(x, y) ||      \
 #define IS_EQUAL_OR_IN_GROUP(e, ge)                                    \
        (IS_GROUP_ELEMENT(ge) ? IS_IN_GROUP(e, GROUP_NR(ge)) : (e) == (ge))
 
+#if 0
 #define CE_ENTER_FIELD_COND(e, x, y)                                   \
                (!IS_PLAYER(x, y) &&                                    \
                 (Feld[x][y] == EL_ACID ||                              \
                  IS_EQUAL_OR_IN_GROUP(Feld[x][y], MOVE_ENTER_EL(e))))
-
-#define CE_ENTER_FIELD_COND_X(e, x, y)                                 \
+#else
+#define CE_ENTER_FIELD_COND(e, x, y)                                   \
                (!IS_PLAYER(x, y) &&                                    \
                 IS_EQUAL_OR_IN_GROUP(Feld[x][y], MOVE_ENTER_EL(e)))
+#endif
 
 #define CUSTOM_ELEMENT_CAN_ENTER_FIELD(e, x, y)                                \
-       ELEMENT_CAN_ENTER_FIELD_GENERIC_X(e, x, y, CE_ENTER_FIELD_COND_X(e, x, y))
+       ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, CE_ENTER_FIELD_COND(e, x, y))
 
 #define MOLE_CAN_ENTER_FIELD(x, y, condition)                          \
                (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || (condition)))
@@ -2321,8 +2335,25 @@ void RemoveMovingField(int x, int y)
   if (IS_MOVING(x, y))
   {
     Moving2Blocked(x, y, &newx, &newy);
+#if 0
     if (Feld[newx][newy] != EL_BLOCKED)
       return;
+#else
+    if (Feld[newx][newy] != EL_BLOCKED)
+    {
+      /* element is moving, but target field is not free (blocked), but
+        already occupied by something different (example: acid pool);
+        in this case, only remove the moving field, but not the target */
+
+      RemoveField(oldx, oldy);
+
+      Store[oldx][oldy] = Store2[oldx][oldy] = 0;
+
+      DrawLevelField(oldx, oldy);
+
+      return;
+    }
+#endif
   }
   else if (element == EL_BLOCKED)
   {
@@ -3086,23 +3117,42 @@ void Bang(int x, int y)
 
 void SplashAcid(int x, int y)
 {
+#if 1
+  if (IN_LEV_FIELD(x - 1, y - 1) && IS_FREE(x - 1, y - 1) &&
+      (!IN_LEV_FIELD(x - 1, y - 2) ||
+       !CAN_FALL(MovingOrBlocked2Element(x - 1, y - 2))))
+    Feld[x - 1][y - 1] = EL_ACID_SPLASH_LEFT;
+
+  if (IN_LEV_FIELD(x + 1, y - 1) && IS_FREE(x + 1, y - 1) &&
+      (!IN_LEV_FIELD(x + 1, y - 2) ||
+       !CAN_FALL(MovingOrBlocked2Element(x + 1, y - 2))))
+    Feld[x + 1][y - 1] = EL_ACID_SPLASH_RIGHT;
+
+  PlayLevelSound(x, y, SND_ACID_SPLASHING);
+#else
+  /* input: position of element entering acid (obsolete) */
+
   int element = Feld[x][y];
 
+  if (!IN_LEV_FIELD(x, y + 1) || Feld[x][y + 1] != EL_ACID)
+    return;
+
   if (element != EL_ACID_SPLASH_LEFT &&
       element != EL_ACID_SPLASH_RIGHT)
   {
     PlayLevelSound(x, y, SND_ACID_SPLASHING);
 
-    if (IN_LEV_FIELD(x-1, y) && IS_FREE(x-1, y) &&
-       (!IN_LEV_FIELD(x-1, y-1) ||
-        !CAN_FALL(MovingOrBlocked2Element(x-1, y-1))))
-      Feld[x-1][y] = EL_ACID_SPLASH_LEFT;
+    if (IN_LEV_FIELD(x - 1, y) && IS_FREE(x - 1, y) &&
+       (!IN_LEV_FIELD(x - 1, y - 1) ||
+        !CAN_FALL(MovingOrBlocked2Element(x - 1, y - 1))))
+      Feld[x - 1][y] = EL_ACID_SPLASH_LEFT;
 
-    if (IN_LEV_FIELD(x+1, y) && IS_FREE(x+1, y) &&
-       (!IN_LEV_FIELD(x+1, y-1) ||
-        !CAN_FALL(MovingOrBlocked2Element(x+1, y-1))))
-      Feld[x+1][y] = EL_ACID_SPLASH_RIGHT;
+    if (IN_LEV_FIELD(x + 1, y) && IS_FREE(x + 1, y) &&
+       (!IN_LEV_FIELD(x + 1, y - 1) ||
+        !CAN_FALL(MovingOrBlocked2Element(x + 1, y - 1))))
+      Feld[x + 1][y] = EL_ACID_SPLASH_RIGHT;
   }
+#endif
 }
 
 static void InitBeltMovement()
@@ -3479,7 +3529,7 @@ void Impact(int x, int y)
 
   if (!lastline && smashed == EL_ACID) /* element falls into acid */
   {
-    SplashAcid(x, y);
+    SplashAcid(x, y + 1);
     return;
   }
 
@@ -3730,9 +3780,9 @@ inline static void TurnRoundExt(int x, int y)
   {
     TestIfBadThingTouchesOtherBadThing(x, y);
 
-    if (ENEMY_CAN_ENTER_FIELD(right_x, right_y))
+    if (ENEMY_CAN_ENTER_FIELD(element, right_x, right_y))
       MovDir[x][y] = right_dir;
-    else if (!ENEMY_CAN_ENTER_FIELD(move_x, move_y))
+    else if (!ENEMY_CAN_ENTER_FIELD(element, move_x, move_y))
       MovDir[x][y] = left_dir;
 
     if (element == EL_BUG && MovDir[x][y] != old_move_dir)
@@ -3745,9 +3795,9 @@ inline static void TurnRoundExt(int x, int y)
   {
     TestIfBadThingTouchesOtherBadThing(x, y);
 
-    if (ENEMY_CAN_ENTER_FIELD(left_x, left_y))
+    if (ENEMY_CAN_ENTER_FIELD(element, left_x, left_y))
       MovDir[x][y] = left_dir;
-    else if (!ENEMY_CAN_ENTER_FIELD(move_x, move_y))
+    else if (!ENEMY_CAN_ENTER_FIELD(element, move_x, move_y))
       MovDir[x][y] = right_dir;
 
     if ((element == EL_SPACESHIP ||
@@ -4523,7 +4573,7 @@ void StartMoving(int x, int y)
     else if (CAN_FALL(element) && Feld[x][y + 1] == EL_ACID)
 #endif
     {
-      SplashAcid(x, y);
+      SplashAcid(x, y + 1);
 
       InitMovingField(x, y, MV_DOWN);
       started_moving = TRUE;
@@ -4929,9 +4979,15 @@ void StartMoving(int x, int y)
 
     }
 #if 1
+#if 1
+    else if (CAN_MOVE_INTO_ACID(element) &&
+            IN_LEV_FIELD(newx, newy) && Feld[newx][newy] == EL_ACID &&
+            (MovDir[x][y] == MV_DOWN ||
+             game.engine_version > VERSION_IDENT(3,0,8,0)))
+#else
     else if (CAN_MOVE_INTO_ACID(element) && MovDir[x][y] == MV_DOWN &&
             IN_LEV_FIELD(newx, newy) && Feld[newx][newy] == EL_ACID)
-
+#endif
 #else
 
     else if ((element == EL_PENGUIN ||
@@ -4943,7 +4999,7 @@ void StartMoving(int x, int y)
             MovDir[x][y] == MV_DOWN && Feld[newx][newy] == EL_ACID)
 #endif
     {
-      SplashAcid(x, y);
+      SplashAcid(newx, newy);
       Store[x][y] = EL_ACID;
     }
     else if (element == EL_PENGUIN && IN_LEV_FIELD(newx, newy))
@@ -5158,8 +5214,15 @@ void StartMoving(int x, int y)
          AmoebaCnt[AmoebaNr[newx][newy]]--;
       }
 
+#if 0
+      /* !!! test !!! */
+      if (IS_MOVING(newx, newy) || IS_BLOCKED(newx, newy))
+#else
       if (IS_MOVING(newx, newy))
+#endif
+      {
        RemoveMovingField(newx, newy);
+      }
       else
       {
        Feld[newx][newy] = EL_EMPTY;
@@ -7972,7 +8035,7 @@ boolean MovePlayerOneStep(struct PlayerInfo *player,
   {
     if (element == EL_ACID && dx == 0 && dy == 1)
     {
-      SplashAcid(jx, jy);
+      SplashAcid(new_jx, new_jy);
       Feld[jx][jy] = EL_PLAYER_1;
       InitMovingField(jx, jy, MV_DOWN);
       Store[jx][jy] = EL_ACID;
index b7ea2825020ffc76aafe7e857ad5f41acc5d7668..40b6417a04d32f6218f0c8efb5862833196ddeb6 100644 (file)
@@ -3122,6 +3122,12 @@ void InitElementPropertiesEngine(int engine_version)
   InitElementPropertiesStatic();
 #endif
 
+  /* important: after initialization in InitElementPropertiesStatic(), the
+     elements are not again initialized to a default value; therefore all
+     changes have to make sure that they leave the element with a defined
+     property (which means that conditional property changes must be set to
+     a reliable default value before) */
+
   /* set all special, combined or engine dependent element properties */
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
@@ -3131,8 +3137,7 @@ void InitElementPropertiesEngine(int engine_version)
 #endif
 
     /* ---------- INACTIVE ------------------------------------------------- */
-    if (i >= EL_CHAR_START && i <= EL_CHAR_END)
-      SET_PROPERTY(i, EP_INACTIVE, TRUE);
+    SET_PROPERTY(i, EP_INACTIVE, (i >= EL_CHAR_START && i <= EL_CHAR_END));
 
     /* ---------- WALKABLE, PASSABLE, ACCESSIBLE --------------------------- */
     SET_PROPERTY(i, EP_WALKABLE, (IS_WALKABLE_OVER(i) ||
@@ -3184,9 +3189,11 @@ void InitElementPropertiesEngine(int engine_version)
                                             !IS_DIGGABLE(i) &&
                                             !IS_COLLECTIBLE(i)));
 
+#if 1
     /* ---------- PROTECTED ------------------------------------------------ */
     if (IS_ACCESSIBLE_INSIDE(i))
       SET_PROPERTY(i, EP_PROTECTED, TRUE);
+#endif
 
     /* ---------- DRAGONFIRE_PROOF ----------------------------------------- */
 
@@ -3219,6 +3226,8 @@ void InitElementPropertiesEngine(int engine_version)
 
     if (IS_CUSTOM_ELEMENT(i))
     {
+      /* these are additional properties which are initially false when set */
+
       /* ---------- DONT_COLLIDE_WITH / DONT_RUN_INTO ---------------------- */
       if (DONT_TOUCH(i))
        SET_PROPERTY(i, EP_DONT_COLLIDE_WITH, TRUE);
@@ -3259,8 +3268,8 @@ void InitElementPropertiesEngine(int engine_version)
                                              IS_CUSTOM_ELEMENT(i)));
 
     /* ---------- CAN_MOVE_INTO_ACID --------------------------------------- */
-    if (getMoveIntoAcidProperty(&level, i))
-      SET_PROPERTY(i, EP_CAN_MOVE_INTO_ACID, TRUE);
+    if (!IS_CUSTOM_ELEMENT(i))
+      SET_PROPERTY(i, EP_CAN_MOVE_INTO_ACID,getMoveIntoAcidProperty(&level,i));
 
     /* ---------- SP_PORT -------------------------------------------------- */
     SET_PROPERTY(i, EP_SP_PORT, (IS_SP_ELEMENT(i) &&
index b69aff20581093b7d74ba9fb09917d2b5a5074ac..8f3798a41f6e23541994274f933a96315c85808a 100644 (file)
@@ -40,6 +40,39 @@ static int el_act2crm(int, int);
 static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
 static int request_gadget_id = -1;
 
+void DumpTile(int x, int y)
+{
+  int sx = SCREENX(x);
+  int sy = SCREENX(y);
+
+  printf_line("-", 79);
+  printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y);
+  printf_line("-", 79);
+
+  if (!IN_LEV_FIELD(x, y))
+  {
+    printf("(not in level field)\n");
+    printf("\n");
+
+    return;
+  }
+
+  printf("  Feld:        %d ['%s']\n", Feld[x][y],
+        element_info[Feld[x][y]].token_name);
+  printf("  Back:        %d\n", Back[x][y]);
+  printf("  Store:       %d\n", Store[x][y]);
+  printf("  Store2:      %d\n", Store2[x][y]);
+  printf("  StorePlayer: %d\n", StorePlayer[x][y]);
+  printf("  MovPos:      %d\n", MovPos[x][y]);
+  printf("  MovDir:      %d\n", MovDir[x][y]);
+  printf("  MovDelay:    %d\n", MovDelay[x][y]);
+  printf("  ChangeDelay: %d\n", ChangeDelay[x][y]);
+  printf("  GfxElement:  %d\n", GfxElement[x][y]);
+  printf("  GfxAction:   %d\n", GfxAction[x][y]);
+  printf("  GfxFrame:    %d\n", GfxFrame[x][y]);
+  printf("\n");
+}
+
 void SetDrawtoField(int mode)
 {
   if (mode == DRAW_BUFFERED && setup.soft_scrolling)
@@ -1485,7 +1518,13 @@ void DrawScreenField(int x, int y)
       DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], content, cut_mode);
 
     if (content == EL_ACID)
-      DrawLevelElementThruMask(lx, ly + 1, EL_ACID);
+    {
+      int dir = MovDir[lx][ly];
+      int newlx = lx + (dir == MV_LEFT ? -1 : dir == MV_RIGHT ? +1 : 0);
+      int newly = ly + (dir == MV_UP   ? -1 : dir == MV_DOWN  ? +1 : 0);
+
+      DrawLevelElementThruMask(newlx, newly, EL_ACID);
+    }
   }
   else if (IS_BLOCKED(lx, ly))
   {
index f226a9cfd09a40ae8e2a1c83e1104d0a8728bb15..d5170c776e922b66b4aac5d06eacfb9e7d8f6743 100644 (file)
@@ -58,6 +58,8 @@
 
 #define REQUEST_WAIT_FOR       (REQ_ASK | REQ_CONFIRM | REQ_PLAYER)
 
+void DumpTile(int, int);
+
 void SetDrawtoField(int);
 void RedrawPlayfield(boolean, int, int, int, int);
 void BackToFront();