#define USE_FIX_IMPACT_COLLISION (USE_NEW_STUFF * 1)
#define USE_FIX_CE_ACTION_WITH_PLAYER (USE_NEW_STUFF * 1)
+#define USE_PLAYER_REANIMATION (USE_NEW_STUFF * 1)
+
#define USE_GFX_RESET_WHEN_NOT_MOVING (USE_NEW_STUFF * 1)
-#define USE_DELAYED_GFX_REDRAW (USE_NEW_STUFF * 1)
+#define USE_DELAYED_GFX_REDRAW (USE_NEW_STUFF * 0)
#if USE_DELAYED_GFX_REDRAW
#define TEST_DrawLevelField(x, y) \
void TestIfFriendTouchesBadThing(int, int);
void TestIfBadThingTouchesFriend(int, int);
void TestIfBadThingTouchesOtherBadThing(int, int);
+void TestIfGoodThingGetsHitByBadThing(int, int, int);
void KillPlayer(struct PlayerInfo *);
void BuryPlayer(struct PlayerInfo *);
player->jx = player->last_jx = x;
player->jy = player->last_jy = y;
}
+
+#if USE_PLAYER_REANIMATION
+ if (!init_game)
+ {
+ int player_nr = GET_PLAYER_NR(element);
+ struct PlayerInfo *player = &stored_player[player_nr];
+
+ if (player->active)
+ player->killed = FALSE; /* if player was just killed, reanimate him */
+ }
+#endif
}
static void InitField(int x, int y, boolean init_game)
GfxElement[x][y] = EL_UNDEFINED;
GfxAction[x][y] = ACTION_DEFAULT;
GfxDir[x][y] = MV_NONE;
+#if 0
+ /* !!! this would prevent the removed tile from being redrawn !!! */
GfxRedraw[x][y] = GFX_REDRAW_NONE;
+#endif
}
void RemoveMovingField(int x, int y)
element - EL_EM_GATE_1_GRAY + EL_EM_GATE_1_GRAY_ACTIVE :
IS_EMC_GATE_GRAY(element) ?
element - EL_EMC_GATE_5_GRAY + EL_EMC_GATE_5_GRAY_ACTIVE :
+ IS_DC_GATE_GRAY(element) ?
+ EL_DC_GATE_WHITE_GRAY_ACTIVE :
element);
TEST_DrawLevelField(x, y);
}
element - EL_EM_GATE_1_GRAY_ACTIVE + EL_EM_GATE_1_GRAY :
IS_EMC_GATE_GRAY_ACTIVE(element) ?
element - EL_EMC_GATE_5_GRAY_ACTIVE + EL_EMC_GATE_5_GRAY :
+ IS_DC_GATE_GRAY_ACTIVE(element) ?
+ EL_DC_GATE_WHITE_GRAY :
element);
TEST_DrawLevelField(x, y);
}
else if (element == EL_PENGUIN)
TestIfFriendTouchesBadThing(newx, newy);
+ if (DONT_GET_HIT_BY(element))
+ {
+ TestIfGoodThingGetsHitByBadThing(newx, newy, direction);
+ }
+
/* give the player one last chance (one more frame) to move away */
if (CAN_FALL(element) && direction == MV_DOWN &&
(last_line || (!IS_FREE(x, newy + 1) &&
GfxRedraw[x][y] != GFX_REDRAW_NONE)
#endif
{
+ /* !!! PROBLEM: THIS REDRAWS THE PLAYFIELD _AFTER_ THE SCAN, BUT TILES
+ !!! MAY HAVE CHANGED AFTER BEING DRAWN DURING PLAYFIELD SCAN !!! */
+
if (GfxRedraw[x][y] & GFX_REDRAW_TILE)
DrawLevelField(x, y);
void ScrollLevel(int dx, int dy)
{
-#if 1
+#if 0
+ /* (directly solved in BlitBitmap() now) */
static Bitmap *bitmap_db_field2 = NULL;
int softscroll_offset = (setup.soft_scrolling ? TILEX : 0);
int x, y;
#else
- int i, x, y;
+ int x, y;
#endif
#if 0
return;
#endif
-#if 1
+#if 0
+ /* (directly solved in BlitBitmap() now) */
if (bitmap_db_field2 == NULL)
bitmap_db_field2 = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
/* check for change of border element */
CheckElementChangeBySide(xx, yy, border_element, center_element,
CE_TOUCHING_X, center_side);
+
+ /* (center element cannot be player, so we dont have to check this here) */
}
for (i = 0; i < NUM_DIRECTIONS; i++)
test_x = bad_x + test_xy[i][0];
test_y = bad_y + test_xy[i][1];
+
if (!IN_LEV_FIELD(test_x, test_y))
continue;
kill_x = test_x;
kill_y = test_y;
+
break;
}
else if (test_element == EL_PENGUIN)
{
kill_x = test_x;
kill_y = test_y;
+
break;
}
}
}
}
+void TestIfGoodThingGetsHitByBadThing(int bad_x, int bad_y, int bad_move_dir)
+{
+ int bad_element = Feld[bad_x][bad_y];
+ int dx = (bad_move_dir == MV_LEFT ? -1 : bad_move_dir == MV_RIGHT ? +1 : 0);
+ int dy = (bad_move_dir == MV_UP ? -1 : bad_move_dir == MV_DOWN ? +1 : 0);
+ int test_x = bad_x + dx, test_y = bad_y + dy;
+ int test_move_dir, test_element;
+ int kill_x = -1, kill_y = -1;
+
+ if (!IN_LEV_FIELD(test_x, test_y))
+ return;
+
+ test_move_dir =
+ (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NONE);
+
+ test_element = Feld[test_x][test_y];
+
+ if (test_move_dir != bad_move_dir)
+ {
+ /* good thing can be player or penguin that does not move away */
+ if (IS_PLAYER(test_x, test_y))
+ {
+ struct PlayerInfo *player = PLAYERINFO(test_x, test_y);
+
+ /* (note: in comparison to DONT_RUN_TO and DONT_TOUCH, also handle the
+ player as being hit when he is moving towards the bad thing, because
+ the "get hit by" condition would be lost after the player stops) */
+ if (player->MovPos != 0 && player->MovDir == bad_move_dir)
+ return; /* player moves away from bad thing */
+
+ kill_x = test_x;
+ kill_y = test_y;
+ }
+ else if (test_element == EL_PENGUIN)
+ {
+ kill_x = test_x;
+ kill_y = test_y;
+ }
+ }
+
+ if (kill_x != -1 || kill_y != -1)
+ {
+ if (IS_PLAYER(kill_x, kill_y))
+ {
+ struct PlayerInfo *player = PLAYERINFO(kill_x, kill_y);
+
+ if (player->shield_deadly_time_left > 0 &&
+ !IS_INDESTRUCTIBLE(bad_element))
+ Bang(bad_x, bad_y);
+ else if (!PLAYER_ENEMY_PROTECTED(kill_x, kill_y))
+ KillPlayer(player);
+ }
+ else
+ Bang(kill_x, kill_y);
+ }
+}
+
void TestIfPlayerTouchesBadThing(int x, int y)
{
TestIfGoodThingHitsBadThing(x, y, MV_NONE);
player->shield_deadly_time_left = 0;
Bang(jx, jy);
+
+#if USE_PLAYER_REANIMATION
+ if (player->killed) /* player may have been reanimated */
+ BuryPlayer(player);
+#else
BuryPlayer(player);
+#endif
}
static void KillPlayerUnlessEnemyProtected(int x, int y)