rnd-20031231-1-src
authorHolger Schemel <info@artsoft.org>
Wed, 31 Dec 2003 00:15:08 +0000 (01:15 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:45:10 +0000 (10:45 +0200)
src/conftime.h
src/editor.c
src/events.c
src/files.c
src/game.c
src/init.c
src/main.h

index b09b190caf8593da63020d36b549577acbbee70a..a4b8f9239c57c190f9494836bc10c7538432a3cb 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2003-12-28 03:38]"
+#define COMPILE_DATE_STRING "[2003-12-31 01:13]"
index 5c9ab31734b3f5afe89f8640420f1862bc9a35c0..c9f86cc35d1a65df60761f3f4e50d211ba29127d 100644 (file)
@@ -1134,6 +1134,7 @@ static struct ValueTextInfo options_deadliness[] =
 static struct ValueTextInfo options_consistency[] =
 {
   { EP_CAN_EXPLODE_3X3,                "can explode 3x3"               },
+  { EP_CAN_EXPLODE_DYNA,       "can explode 3+3"               },
   { EP_CAN_EXPLODE_1X1,                "can explode 1x1"               },
   { EP_INDESTRUCTIBLE,         "indestructible"                },
   { -1,                                NULL                            }
@@ -1155,11 +1156,11 @@ static struct ValueTextInfo options_change_direct_action[] =
   { CE_LEFT_BY_PLAYER,         "left by player ..."            },
   { CE_DROPPED_BY_PLAYER,      "dropped by player"             },
   { CE_SWITCHED,               "switched ..."                  },
-#if 0
-  { CE_COLLISION_ACTIVE,       "hitting something ..."         },
-  { CE_COLLISION_PASSIVE,      "hit by something ..."          },
+#if 1
+  { CE_HITTING_SOMETHING,      "hitting something ..."         },
+  { CE_HIT_BY_SOMETHING,       "hit by something ..."          },
 #else
-  { CE_COLLISION_ACTIVE,       "collision ..."                 },
+  { CE_HITTING_SOMETHING,      "collision ..."                 },
 #endif
   { CE_IMPACT,                 "impact (on something)"         },
   { CE_SMASHED,                        "smashed (from above)"          },
@@ -1177,9 +1178,9 @@ static struct ValueTextInfo options_change_other_action[] =
   { CE_OTHER_GETS_COLLECTED,   "player collects"               },
   { CE_OTHER_GETS_DROPPED,     "player drops"                  },
   { CE_OTHER_IS_TOUCHING,      "touching ..."                  },
-#if 0
-  { CE_OTHER_IS_COLL_ACTIVE,   "hitting ..."                   },
-  { CE_OTHER_IS_COLL_PASSIVE,  "hit by ..."                    },
+#if 1
+  { CE_OTHER_IS_HITTING,       "hitting ..."                   },
+  { CE_OTHER_GETS_HIT,         "hit by ..."                    },
 #endif
   { CE_OTHER_IS_SWITCHING,     "switch of ..."                 },
   { CE_OTHER_IS_CHANGING,      "change of"                     },
@@ -4963,11 +4964,13 @@ static void CopyCustomElementPropertiesToEditor(int element)
     (IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE :
      CAN_EXPLODE_1X1(element) ? EP_CAN_EXPLODE_1X1 :
      CAN_EXPLODE_3X3(element) ? EP_CAN_EXPLODE_3X3 :
+     CAN_EXPLODE_DYNA(element) ? EP_CAN_EXPLODE_DYNA :
      custom_element.consistency);
   custom_element_properties[EP_EXPLODE_RESULT] =
     (IS_INDESTRUCTIBLE(element) ||
      CAN_EXPLODE_1X1(element) ||
-     CAN_EXPLODE_3X3(element));
+     CAN_EXPLODE_3X3(element) ||
+     CAN_EXPLODE_DYNA(element));
 
   /* special case: sub-settings dependent from main setting */
   if (CAN_EXPLODE_BY_FIRE(element))
@@ -4988,8 +4991,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_LEFT_BY_PLAYER) ? CE_LEFT_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_DROPPED_BY_PLAYER) ? CE_DROPPED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_SWITCHED) ? CE_SWITCHED :
-     HAS_CHANGE_EVENT(element, CE_COLLISION_ACTIVE) ? CE_COLLISION_ACTIVE :
-     HAS_CHANGE_EVENT(element, CE_COLLISION_PASSIVE) ? CE_COLLISION_PASSIVE :
+     HAS_CHANGE_EVENT(element, CE_HITTING_SOMETHING) ? CE_HITTING_SOMETHING :
+     HAS_CHANGE_EVENT(element, CE_HIT_BY_SOMETHING) ? CE_HIT_BY_SOMETHING :
      HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
      HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED :
      custom_element_change.direct_action);
@@ -5005,8 +5008,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED :
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DROPPED) ? CE_OTHER_GETS_DROPPED :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING :
-     HAS_CHANGE_EVENT(element, CE_OTHER_IS_COLL_ACTIVE) ? CE_OTHER_IS_COLL_ACTIVE :
-     HAS_CHANGE_EVENT(element, CE_OTHER_IS_COLL_PASSIVE) ? CE_OTHER_IS_COLL_PASSIVE :
+     HAS_CHANGE_EVENT(element, CE_OTHER_IS_HITTING) ? CE_OTHER_IS_HITTING :
+     HAS_CHANGE_EVENT(element, CE_OTHER_GETS_HIT) ? CE_OTHER_GETS_HIT :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_SWITCHING) ? CE_OTHER_IS_SWITCHING :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING :
@@ -5081,6 +5084,7 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_properties[EP_INDESTRUCTIBLE] = FALSE;
   custom_element_properties[EP_CAN_EXPLODE_1X1] = FALSE;
   custom_element_properties[EP_CAN_EXPLODE_3X3] = FALSE;
+  custom_element_properties[EP_CAN_EXPLODE_DYNA] = FALSE;
   custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE;
   custom_element_properties[EP_CAN_EXPLODE_SMASHED] = FALSE;
   custom_element_properties[EP_CAN_EXPLODE_IMPACT] = FALSE;
@@ -5088,8 +5092,9 @@ static void CopyCustomElementPropertiesToGame(int element)
     custom_element_properties[EP_EXPLODE_RESULT];
 
   /* special case: sub-settings dependent from main setting */
-  if (custom_element_properties[EP_CAN_EXPLODE_3X3] ||
-      custom_element_properties[EP_CAN_EXPLODE_1X1])
+  if (custom_element_properties[EP_CAN_EXPLODE_1X1] ||
+      custom_element_properties[EP_CAN_EXPLODE_3X3] ||
+      custom_element_properties[EP_CAN_EXPLODE_DYNA])
   {
     custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] =
       custom_element.can_explode_by_fire;
@@ -5109,8 +5114,8 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_LEFT_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_DROPPED_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_SWITCHED] = FALSE;
-  custom_element_change_events[CE_COLLISION_ACTIVE] = FALSE;
-  custom_element_change_events[CE_COLLISION_PASSIVE] = FALSE;
+  custom_element_change_events[CE_HITTING_SOMETHING] = FALSE;
+  custom_element_change_events[CE_HIT_BY_SOMETHING] = FALSE;
   custom_element_change_events[CE_IMPACT] = FALSE;
   custom_element_change_events[CE_SMASHED] = FALSE;
   custom_element_change_events[custom_element_change.direct_action] =
@@ -5126,8 +5131,8 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_DROPPED] = FALSE;
   custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE;
-  custom_element_change_events[CE_OTHER_IS_COLL_ACTIVE] = FALSE;
-  custom_element_change_events[CE_OTHER_IS_COLL_PASSIVE] = FALSE;
+  custom_element_change_events[CE_OTHER_IS_HITTING] = FALSE;
+  custom_element_change_events[CE_OTHER_GETS_HIT] = FALSE;
   custom_element_change_events[CE_OTHER_IS_SWITCHING] = FALSE;
   custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE;
   custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE;
index facafec6be76761e2afcf20dd9e7656d550fefda..f86d9ed39727bdbe0fd9fbd4a148ece77131b7db 100644 (file)
@@ -488,7 +488,7 @@ static void HandleKeysCheating(Key key)
 #endif
 
 #if 1
-  if (is_string_suffix(cheat_input, ":insert solution tape"))
+  if (is_string_suffix(cheat_input, ":insert-solution-tape"))
     InsertSolutionTape();
 #else
   if (is_string_suffix(cheat_input, ":ist"))
@@ -496,7 +496,7 @@ static void HandleKeysCheating(Key key)
 #endif
 
 #ifdef DEBUG
-  else if (is_string_suffix(cheat_input, ":dump tape"))
+  else if (is_string_suffix(cheat_input, ":dump-tape"))
     DumpTape(&tape);
   else if (is_string_suffix(cheat_input, ".q"))
     for (i = 0; i < MAX_INVENTORY_SIZE; i++)
index 5bd23127cfad804b325401f89502815b9c82e2c2..811b4200dfd790b18c932298f0760f95235117d1 100644 (file)
@@ -1042,7 +1042,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
       }
 
       /* order of checking and copying events to be mapped is important */
-      for (j = CE_OTHER_GETS_COLLECTED; j >= CE_COLLISION_ACTIVE; j--)
+      for (j = CE_OTHER_GETS_COLLECTED; j >= CE_HITTING_SOMETHING; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 1))
        {
index af65d866d449ce9a7b4537fd7efe451832546e1f..7ce333bc84e20af17e4d4e5226960c82a694203e 100644 (file)
@@ -184,6 +184,7 @@ static void KillHeroUnlessProtected(int, int);
 
 static void TestIfPlayerTouchesCustomElement(int, int);
 static void TestIfElementTouchesCustomElement(int, int);
+static void TestIfElementHitsCustomElement(int, int, int);
 
 static void ChangeElement(int, int, int);
 static boolean CheckTriggeredElementSideChange(int, int, int, int, int);
@@ -673,6 +674,11 @@ static void InitField(int x, int y, boolean init_game)
       break;
 
     case EL_DYNAMITE_ACTIVE:
+    case EL_SP_DISK_RED_ACTIVE:
+    case EL_DYNABOMB_PLAYER_1_ACTIVE:
+    case EL_DYNABOMB_PLAYER_2_ACTIVE:
+    case EL_DYNABOMB_PLAYER_3_ACTIVE:
+    case EL_DYNABOMB_PLAYER_4_ACTIVE:
       MovDelay[x][y] = 96;
       break;
 
@@ -2565,6 +2571,7 @@ void Explode(int ex, int ey, int phase, int mode)
 void DynaExplode(int ex, int ey)
 {
   int i, j;
+  int dynabomb_element = Feld[ex][ey];
   int dynabomb_size = 1;
   boolean dynabomb_xl = FALSE;
   struct PlayerInfo *player;
@@ -2576,9 +2583,9 @@ void DynaExplode(int ex, int ey)
     { 0, +1 }
   };
 
-  if (IS_ACTIVE_BOMB(Feld[ex][ey]))
+  if (IS_ACTIVE_BOMB(dynabomb_element))
   {
-    player = &stored_player[Feld[ex][ey] - EL_DYNABOMB_PLAYER_1_ACTIVE];
+    player = &stored_player[dynabomb_element - EL_DYNABOMB_PLAYER_1_ACTIVE];
     dynabomb_size = player->dynabomb_size;
     dynabomb_xl = player->dynabomb_xl;
     player->dynabombs_left++;
@@ -2683,7 +2690,9 @@ void Bang(int x, int y)
        Explode(x, y, EX_PHASE_START, EX_CENTER);
       break;
     default:
-      if (CAN_EXPLODE_1X1(element))
+      if (CAN_EXPLODE_DYNA(element))
+       DynaExplode(x, y);
+      else if (CAN_EXPLODE_1X1(element))
        Explode(x, y, EX_PHASE_START, EX_CENTER);
       else
        Explode(x, y, EX_PHASE_START, EX_NORMAL);
@@ -4257,6 +4266,8 @@ void StartMoving(int x, int y)
     int move_pattern = element_info[element].move_pattern;
     int newx, newy;
 
+    Moving2Blocked(x, y, &newx, &newy);
+
 #if 1
     if (IS_PUSHABLE(element) && JustBeingPushed(x, y))
       return;
@@ -4268,6 +4279,28 @@ void StartMoving(int x, int y)
       return;
 #endif
 
+#if 1
+    if (game.engine_version >= VERSION_IDENT(3,0,9,0) &&
+       WasJustMoving[x][y] && IN_LEV_FIELD(newx, newy) &&
+       (Feld[newx][newy] == EL_BLOCKED || IS_PLAYER(newx, newy)))
+    {
+#if 0
+      printf("::: element %d '%s' WasJustMoving %d [%d, %d, %d, %d]\n",
+            element, element_info[element].token_name,
+            WasJustMoving[x][y],
+            HAS_ANY_CHANGE_EVENT(element, CE_HITTING_SOMETHING),
+            HAS_ANY_CHANGE_EVENT(element, CE_HIT_BY_SOMETHING),
+            HAS_ANY_CHANGE_EVENT(element, CE_OTHER_IS_HITTING),
+            HAS_ANY_CHANGE_EVENT(element, CE_OTHER_GETS_HIT));
+#endif
+
+      TestIfElementHitsCustomElement(x, y, MovDir[x][y]);
+
+      if (Feld[x][y] != element)       /* element has changed */
+       return;
+    }
+#endif
+
 #if 0
 #if 0
     if (element == EL_SPRING && MovDir[x][y] == MV_DOWN)
@@ -4739,7 +4772,9 @@ void ContinueMoving(int x, int y)
   int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
   int dy = (direction == MV_UP   ? -1 : direction == MV_DOWN  ? +1 : 0);
   int newx = x + dx, newy = y + dy;
+#if 0
   int nextx = newx + dx, nexty = newy + dy;
+#endif
   boolean pushed = Pushed[x][y];
 
   MovPos[x][y] += getElementMoveStepsize(x, y);
@@ -4916,13 +4951,19 @@ void ContinueMoving(int x, int y)
     ChangeElement(newx, newy, ChangePage[newx][newy]);
 #endif
 
+#if 1
+
+  TestIfElementHitsCustomElement(newx, newy, direction);
+
+#else
+
   if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty))
   {
     int hitting_element = Feld[newx][newy];
 
     /* !!! fix side (direction) orientation here and elsewhere !!! */
     CheckElementSideChange(newx, newy, hitting_element,
-                          direction, CE_COLLISION_ACTIVE, -1);
+                          direction, CE_HITTING_SOMETHING, -1);
 
 #if 0
     if (IN_LEV_FIELD(nextx, nexty))
@@ -4948,10 +4989,10 @@ void ContinueMoving(int x, int y)
        int i;
 
        CheckElementSideChange(nextx, nexty, touched_element,
-                              opposite_direction, CE_COLLISION_PASSIVE, -1);
+                              opposite_direction, CE_HIT_BY_SOMETHING, -1);
 
        if (IS_CUSTOM_ELEMENT(hitting_element) &&
-           HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_COLL_ACTIVE))
+           HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING))
        {
          for (i = 0; i < element_info[hitting_element].num_change_pages; i++)
          {
@@ -4959,19 +5000,19 @@ void ContinueMoving(int x, int y)
              &element_info[hitting_element].change_page[i];
 
            if (change->can_change &&
-               change->events & CH_EVENT_BIT(CE_OTHER_IS_COLL_ACTIVE) &&
+               change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) &&
                change->sides & touched_side &&
                change->trigger_element == touched_element)
            {
              CheckElementSideChange(newx, newy, hitting_element,
-                                    CH_SIDE_ANY, CE_OTHER_IS_COLL_ACTIVE, i);
+                                    CH_SIDE_ANY, CE_OTHER_IS_HITTING, i);
              break;
            }
          }
        }
 
        if (IS_CUSTOM_ELEMENT(touched_element) &&
-           HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_IS_COLL_PASSIVE))
+           HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_GETS_HIT))
        {
          for (i = 0; i < element_info[touched_element].num_change_pages; i++)
          {
@@ -4979,12 +5020,12 @@ void ContinueMoving(int x, int y)
              &element_info[touched_element].change_page[i];
 
            if (change->can_change &&
-               change->events & CH_EVENT_BIT(CE_OTHER_IS_COLL_PASSIVE) &&
+               change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) &&
                change->sides & hitting_side &&
                change->trigger_element == hitting_element)
            {
              CheckElementSideChange(nextx, nexty, touched_element,
-                                    CH_SIDE_ANY, CE_OTHER_IS_COLL_PASSIVE, i);
+                                    CH_SIDE_ANY, CE_OTHER_GETS_HIT, i);
              break;
            }
          }
@@ -4993,6 +5034,7 @@ void ContinueMoving(int x, int y)
     }
 #endif
   }
+#endif
 
   TestIfPlayerTouchesCustomElement(newx, newy);
   TestIfElementTouchesCustomElement(newx, newy);
@@ -7867,6 +7909,89 @@ void TestIfElementTouchesCustomElement(int x, int y)
                           CE_OTHER_IS_TOUCHING, center_element_change_page);
 }
 
+void TestIfElementHitsCustomElement(int x, int y, int direction)
+{
+  int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
+  int dy = (direction == MV_UP   ? -1 : direction == MV_DOWN  ? +1 : 0);
+  int hitx = x + dx, hity = y + dy;
+  int hitting_element = Feld[x][y];
+
+  if (IN_LEV_FIELD(hitx, hity) && IS_FREE(hitx, hity))
+    return;
+
+  CheckElementSideChange(x, y, hitting_element,
+                        direction, CE_HITTING_SOMETHING, -1);
+
+  if (IN_LEV_FIELD(hitx, hity))
+  {
+    static int opposite_directions[] =
+    {
+      MV_RIGHT,
+      MV_LEFT,
+      MV_DOWN,
+      MV_UP
+    };
+    int move_dir_bit = MV_DIR_BIT(direction);
+    int opposite_direction = opposite_directions[move_dir_bit];
+    int hitting_side = direction;
+    int touched_side = opposite_direction;
+    int touched_element = MovingOrBlocked2Element(hitx, hity);
+    boolean object_hit = (!IS_MOVING(hitx, hity) ||
+                         MovDir[hitx][hity] != direction ||
+                         ABS(MovPos[hitx][hity]) <= TILEY / 2);
+
+    object_hit = TRUE;
+
+    if (object_hit)
+    {
+      int i;
+
+      CheckElementSideChange(hitx, hity, touched_element,
+                            opposite_direction, CE_HIT_BY_SOMETHING, -1);
+
+      if (IS_CUSTOM_ELEMENT(hitting_element) &&
+         HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING))
+      {
+       for (i = 0; i < element_info[hitting_element].num_change_pages; i++)
+       {
+         struct ElementChangeInfo *change =
+           &element_info[hitting_element].change_page[i];
+
+         if (change->can_change &&
+             change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) &&
+             change->sides & touched_side &&
+             change->trigger_element == touched_element)
+         {
+           CheckElementSideChange(x, y, hitting_element,
+                                  CH_SIDE_ANY, CE_OTHER_IS_HITTING, i);
+           break;
+         }
+       }
+      }
+
+      if (IS_CUSTOM_ELEMENT(touched_element) &&
+         HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_GETS_HIT))
+      {
+       for (i = 0; i < element_info[touched_element].num_change_pages; i++)
+       {
+         struct ElementChangeInfo *change =
+           &element_info[touched_element].change_page[i];
+
+         if (change->can_change &&
+             change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) &&
+             change->sides & hitting_side &&
+             change->trigger_element == hitting_element)
+         {
+           CheckElementSideChange(hitx, hity, touched_element,
+                                  CH_SIDE_ANY, CE_OTHER_GETS_HIT, i);
+           break;
+         }
+       }
+      }
+    }
+  }
+}
+
 void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir)
 {
   int i, kill_x = -1, kill_y = -1;
@@ -8890,14 +9015,13 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
 boolean DropElement(struct PlayerInfo *player)
 {
   int jx = player->jx, jy = player->jy;
-  int old_element;
+  int old_element = Feld[jx][jy];
   int new_element;
 
+  /* check if player is active, not moving and ready to drop */
   if (!player->active || player->MovPos || player->drop_delay > 0)
     return FALSE;
 
-  old_element = Feld[jx][jy];
-
   /* check if player has anything that can be dropped */
   if (player->inventory_size == 0 && player->dynabombs_left == 0)
     return FALSE;
@@ -8915,28 +9039,20 @@ boolean DropElement(struct PlayerInfo *player)
   if (old_element != EL_EMPTY)
     Back[jx][jy] = old_element;                /* store old element on this field */
 
-
-
-  /* !!! CHANGE !!! CHANGE !!! */
-
-#if 0
-  MovDelay[jx][jy] = 96;
-#endif
-
-  /* !!! CHANGE !!! CHANGE !!! */
-
-
-
   ResetGfxAnimation(jx, jy);
   ResetRandomAnimationValue(jx, jy);
 
   if (player->inventory_size > 0)
   {
-    new_element = player->inventory_element[--player->inventory_size];
+    player->inventory_size--;
+    new_element = player->inventory_element[player->inventory_size];
 
-    Feld[jx][jy] = (new_element == EL_DYNAMITE ? EL_DYNAMITE_ACTIVE :
-                   new_element == EL_SP_DISK_RED ? EL_SP_DISK_RED_ACTIVE :
-                   new_element);
+    if (new_element == EL_DYNAMITE)
+      new_element = EL_DYNAMITE_ACTIVE;
+    else if (new_element == EL_SP_DISK_RED)
+      new_element = EL_SP_DISK_RED_ACTIVE;
+
+    Feld[jx][jy] = new_element;
 
     DrawText(DX_DYNAMITE, DY_DYNAMITE,
             int2str(local_player->inventory_size, 3), FONT_TEXT_2);
@@ -8954,30 +9070,33 @@ boolean DropElement(struct PlayerInfo *player)
   else         /* player is dropping a dyna bomb */
   {
     player->dynabombs_left--;
+    new_element = EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr;
 
-    Feld[jx][jy] =
-      EL_DYNABOMB_PLAYER_1_ACTIVE + (player->element_nr - EL_PLAYER_1);
+    Feld[jx][jy] = new_element;
 
     if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
       DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
 
     PlayLevelSoundAction(jx, jy, ACTION_DROPPING);
-
-    MovDelay[jx][jy] = 96;
   }
 
 
 
 #if 1
-  InitField(jx, jy, FALSE);
-  if (CAN_MOVE(Feld[jx][jy]))
-    InitMovDir(jx, jy);
+
+  if (Feld[jx][jy] == new_element)     /* uninitialized unless CE change */
+  {
+    InitField(jx, jy, FALSE);
+    if (CAN_MOVE(Feld[jx][jy]))
+      InitMovDir(jx, jy);
+  }
 
   new_element = Feld[jx][jy];
 
   if (IS_CUSTOM_ELEMENT(new_element) && CAN_MOVE(new_element) &&
       element_info[new_element].move_pattern == MV_PROJECTILE)
   {
+    int move_stepsize = element_info[new_element].move_stepsize;
     int direction, dx, dy, nextx, nexty;
 
     if (element_info[new_element].move_direction_initial == MV_NO_MOVING)
@@ -8991,20 +9110,33 @@ boolean DropElement(struct PlayerInfo *player)
 
     if (IN_LEV_FIELD(nextx, nexty) && IS_FREE(nextx, nexty))
     {
-      InitMovingField(jx, jy, MovDir[jx][jy]);
+#if 0
+      WasJustMoving[jx][jy] = 3;
+#else
+      InitMovingField(jx, jy, direction);
       ContinueMoving(jx, jy);
+#endif
     }
     else
     {
       Changed[jx][jy] = 0;            /* allow another change */
+
+#if 1
+      TestIfElementHitsCustomElement(jx, jy, direction);
+#else
       CheckElementSideChange(jx, jy, new_element,
-                            direction, CE_COLLISION_ACTIVE, -1);
+                            direction, CE_HITTING_SOMETHING, -1);
+#endif
     }
+
+    player->drop_delay = 2 * TILEX / move_stepsize + 1;
   }
 
+#if 0
+  player->drop_delay = 8 + 8 + 8;
 #endif
 
-  player->drop_delay = 8 + 8 + 8;
+#endif
 
 
 
index 205524ca5228ea7585d30dec09cddeb5b5af2682..864d0b3b6395753964fb40a791ac7403ab269247 100644 (file)
@@ -644,6 +644,15 @@ void InitElementGraphicInfo()
       if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].crumbled[act] != -1)
        default_action_crumbled = element_info[EL_SB_DEFAULT].crumbled[act];
 
+#if 1
+      /* !!! make this better !!! */
+      if (i == EL_EMPTY_SPACE)
+      {
+       default_action_graphic = element_info[EL_DEFAULT].graphic[act];
+       default_action_crumbled = element_info[EL_DEFAULT].crumbled[act];
+      }
+#endif
+
       if (default_action_graphic == -1)
        default_action_graphic = default_graphic;
       if (default_action_crumbled == -1)
@@ -2071,6 +2080,11 @@ void InitElementPropertiesStatic()
     -1
   };
 
+  static int ep_can_explode_dyna[] =
+  {
+    -1
+  };
+
   static int ep_player[] =
   {
     EL_PLAYER_1,
@@ -2842,6 +2856,7 @@ void InitElementPropertiesStatic()
     { ep_droppable,            EP_DROPPABLE            },
     { ep_can_explode_1x1,      EP_CAN_EXPLODE_1X1      },
     { ep_pushable,             EP_PUSHABLE             },
+    { ep_can_explode_dyna,     EP_CAN_EXPLODE_DYNA     },
 
     { ep_player,               EP_PLAYER               },
     { ep_can_pass_magic_wall,  EP_CAN_PASS_MAGIC_WALL  },
@@ -3103,7 +3118,16 @@ void InitElementPropertiesEngine(int engine_version)
 
     /* ---------- CAN_EXPLODE_3X3 ------------------------------------------ */
     SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (CAN_EXPLODE(i) &&
-                                        !CAN_EXPLODE_1X1(i)));
+                                        !CAN_EXPLODE_1X1(i) &&
+                                        !CAN_EXPLODE_DYNA(i)));
+#if 0
+    if (i == EL_CUSTOM_START + 253)
+      printf("::: %d, %d, %d -> %d\n",
+            CAN_EXPLODE_1X1(i),
+            CAN_EXPLODE_3X3(i),
+            CAN_EXPLODE_DYNA(i),
+            CAN_EXPLODE(i));
+#endif
 
     /* ---------- CAN_CHANGE ----------------------------------------------- */
     SET_PROPERTY(i, EP_CAN_CHANGE, FALSE);     /* default: cannot change */
index bb85b0ccf017add7642edf2bd93f9c4b01bbb98a..83442acf799f7f8ae9d51745b9f37166767d61be 100644 (file)
@@ -86,6 +86,7 @@
 #define EP_DROPPABLE           22
 #define EP_CAN_EXPLODE_1X1     23
 #define EP_PUSHABLE            24
+#define EP_CAN_EXPLODE_DYNA    25
 
 /* values for pre-defined properties */
 #define EP_PLAYER              32
 #define CE_PRESSED_BY_PLAYER   2
 #define CE_PUSHED_BY_PLAYER    3
 #define CE_DROPPED_BY_PLAYER   4
-#define CE_COLLISION_ACTIVE    5
+#define CE_HITTING_SOMETHING   5
 #define CE_IMPACT              6
 #define CE_SMASHED             7
 #define CE_OTHER_IS_TOUCHING   8
 #define CE_OTHER_GETS_LEFT     24
 #define CE_SWITCHED            25
 #define CE_OTHER_IS_SWITCHING  26
-#define CE_COLLISION_PASSIVE   27
-#define CE_OTHER_IS_COLL_ACTIVE        28
-#define CE_OTHER_IS_COLL_PASSIVE 29
+#define CE_HIT_BY_SOMETHING    27
+#define CE_OTHER_IS_HITTING    28
+#define CE_OTHER_GETS_HIT      29
 
 #define NUM_CHANGE_EVENTS      30
 
 #define IS_DROPPABLE(e)                HAS_PROPERTY(e, EP_DROPPABLE)
 #define CAN_EXPLODE_1X1(e)     HAS_PROPERTY(e, EP_CAN_EXPLODE_1X1)
 #define IS_PUSHABLE(e)         HAS_PROPERTY(e, EP_PUSHABLE)
+#define CAN_EXPLODE_DYNA(e)    HAS_PROPERTY(e, EP_CAN_EXPLODE_DYNA)
 
 /* macros for special configurable properties */
 #define IS_EM_SLIPPERY_WALL(e) HAS_PROPERTY(e, EP_EM_SLIPPERY_WALL)