/* forward declaration for internal use */
static void CheckGravityMovement(struct PlayerInfo *);
+static void KillHeroUnlessForceField(struct PlayerInfo *);
static void MapGameButtons();
static void HandleGameButtons(struct GadgetInfo *);
player->last_jx = player->last_jy = 0;
player->jx = player->jy = 0;
+ player->force_field_passive_time_left = 0;
+ player->force_field_active_time_left = 0;
+
DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
SnapField(player, 0, 0);
if (IS_MASSIVE(element) || element == EL_BURNING)
continue;
+ if (IS_PLAYER(x, y) && FORCE_FIELD_ON(PLAYERINFO(x, y)))
+ {
+ if (IS_ACTIVE_BOMB(element))
+ {
+ /* re-activate things under the bomb like gate or penguin */
+ Feld[x][y] = (Store[x][y] ? Store[x][y] : EL_LEERRAUM);
+ Store[x][y] = 0;
+ }
+
+ continue;
+ }
+
if (element == EL_EXPLODING)
element = Store2[x][y];
- if (IS_PLAYER(ex, ey))
+ if (IS_PLAYER(ex, ey) && !FORCE_FIELD_ON(PLAYERINFO(ex, ey)))
{
switch(StorePlayer[ex][ey])
{
int element = Store2[x][y];
if (IS_PLAYER(x, y))
- KillHero(PLAYERINFO(x, y));
+ KillHeroUnlessForceField(PLAYERINFO(x, y));
else if (IS_EXPLOSIVE(element))
{
Feld[x][y] = Store2[x][y];
else
PlaySoundLevel(x, y, SND_ROAAAR);
+#if 0
if (IS_PLAYER(x, y)) /* remove objects that might cause smaller explosion */
element = EL_LEERRAUM;
+#endif
switch(element)
{
case EL_PINGUIN:
case EL_BIRNE_AUS:
case EL_BIRNE_EIN:
- Explode(x, y, EX_PHASE_START, EX_CENTER);
+ if (IS_PLAYER(x, y))
+ Explode(x, y, EX_PHASE_START, EX_NORMAL);
+ else
+ Explode(x, y, EX_PHASE_START, EX_CENTER);
break;
default:
Explode(x, y, EX_PHASE_START, EX_NORMAL);
if (element == EL_TROPFEN && (lastline || object_hit)) /* acid drop */
{
if (object_hit && IS_PLAYER(x, y+1))
- KillHero(PLAYERINFO(x, y+1));
+ KillHeroUnlessForceField(PLAYERINFO(x, y+1));
else if (object_hit && (smashed == EL_MAULWURF || smashed == EL_PINGUIN))
Bang(x, y+1);
else
if (IS_PLAYER(x, y+1))
{
- KillHero(PLAYERINFO(x, y+1));
+ KillHeroUnlessForceField(PLAYERINFO(x, y+1));
return;
}
else if (smashed == EL_MAULWURF || smashed == EL_PINGUIN)
TestIfBadThingHitsOtherBadThing(x, y);
if (IN_LEV_FIELD(right_x, right_y) &&
- IS_FREE_OR_PLAYER(right_x, right_y))
+ IS_FREE(right_x, right_y))
MovDir[x][y] = right_dir;
else if (!IN_LEV_FIELD(move_x, move_y) ||
- !IS_FREE_OR_PLAYER(move_x, move_y))
+ !IS_FREE(move_x, move_y))
MovDir[x][y] = left_dir;
if (element == EL_KAEFER && MovDir[x][y] != old_move_dir)
TestIfBadThingHitsOtherBadThing(x, y);
if (IN_LEV_FIELD(left_x, left_y) &&
- IS_FREE_OR_PLAYER(left_x, left_y))
+ IS_FREE(left_x, left_y))
MovDir[x][y] = left_dir;
else if (!IN_LEV_FIELD(move_x, move_y) ||
- !IS_FREE_OR_PLAYER(move_x, move_y))
+ !IS_FREE(move_x, move_y))
MovDir[x][y] = right_dir;
if ((element == EL_FLIEGER ||
Moving2Blocked(x, y, &newx, &newy); /* get next screen position */
- if (IS_ENEMY(element) && IS_PLAYER(newx, newy))
+ if (IS_ENEMY(element) && IS_PLAYER(newx, newy) &&
+ !FORCE_FIELD_ON(PLAYERINFO(newx, newy)))
{
+
+#if 1
+ TestIfBadThingHitsHero(x, y);
+ return;
+#else
/* enemy got the player */
MovDir[x][y] = 0;
KillHero(PLAYERINFO(newx, newy));
return;
+#endif
+
}
else if ((element == EL_MAULWURF || element == EL_PINGUIN ||
element == EL_ROBOT || element == EL_SONDE) &&
CloseSwitchgate(x, y);
else if (element == EL_EXTRA_TIME)
DrawGraphicAnimation(x, y, GFX_EXTRA_TIME, 6, 4, ANIM_NORMAL);
- else if (element == EL_FORCE_FIELD)
- DrawGraphicAnimation(x, y, GFX_FORCE_FIELD, 6, 4, ANIM_NORMAL);
+ else if (element == EL_FORCE_FIELD_PASSIVE)
+ DrawGraphicAnimation(x, y, GFX_FORCE_FIELD_PASSIVE, 6, 4, ANIM_NORMAL);
+ else if (element == EL_FORCE_FIELD_ACTIVE)
+ DrawGraphicAnimation(x, y, GFX_FORCE_FIELD_ACTIVE, 6, 4, ANIM_NORMAL);
if (game.magic_wall_active)
{
}
}
- if (TimeFrames >= (1000 / GameFrameDelay) && !tape.pausing)
+ if (TimeFrames >= (1000 / GameFrameDelay))
{
TimeFrames = 0;
TimePlayed++;
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ if (FORCE_FIELD_ON(&stored_player[i]))
+ {
+ stored_player[i].force_field_passive_time_left--;
+
+ if (stored_player[i].force_field_active_time_left > 0)
+ stored_player[i].force_field_active_time_left--;
+ }
+ }
+
if (tape.recording || tape.playing)
DrawVideoDisplay(VIDEO_STATE_TIME_ON, TimePlayed);
BuryHero(player);
}
else
- KillHero(player);
+ {
+#if 1
+ TestIfBadThingHitsHero(new_jx, new_jy);
+#else
+ if (player->force_field_time_left == 0)
+ KillHero(player);
+#endif
+ }
return MF_MOVING;
}
if (killx != goodx || killy != goody)
{
if (IS_PLAYER(goodx, goody))
- KillHero(PLAYERINFO(goodx, goody));
+ {
+ struct PlayerInfo *player = PLAYERINFO(goodx, goody);
+
+ if (player->force_field_active_time_left > 0)
+ Bang(killx, killy);
+ else if (player->force_field_passive_time_left == 0)
+ KillHero(player);
+ }
else
Bang(goodx, goody);
}
if (killx != badx || killy != bady)
{
if (IS_PLAYER(killx, killy))
- KillHero(PLAYERINFO(killx, killy));
+ {
+ struct PlayerInfo *player = PLAYERINFO(killx, killy);
+
+ if (player->force_field_active_time_left > 0)
+ Bang(badx, bady);
+ else if (player->force_field_passive_time_left == 0)
+ KillHero(player);
+ }
else
Bang(killx, killy);
}
if (IS_PFORTE(Feld[jx][jy]))
Feld[jx][jy] = EL_LEERRAUM;
+ /* deactivate force field (else Bang()/Explode() would not work right) */
+ player->force_field_passive_time_left = 0;
+ player->force_field_active_time_left = 0;
+
Bang(jx, jy);
BuryHero(player);
}
+static void KillHeroUnlessForceField(struct PlayerInfo *player)
+{
+ if (!FORCE_FIELD_ON(player))
+ KillHero(player);
+}
+
void BuryHero(struct PlayerInfo *player)
{
int jx = player->jx, jy = player->jy;
PlaySoundStereo(SND_GONG, PSND_MAX_RIGHT);
break;
- case EL_FORCE_FIELD:
+ case EL_FORCE_FIELD_PASSIVE:
+ RemoveField(x, y);
+ player->force_field_passive_time_left += 10;
+ PlaySoundLevel(x, y, SND_PONG);
+ break;
+
+ case EL_FORCE_FIELD_ACTIVE:
RemoveField(x, y);
+ player->force_field_passive_time_left += 10;
+ player->force_field_active_time_left += 10;
PlaySoundLevel(x, y, SND_PONG);
break;
#define TAPE_IS_STOPPED(x) (!(x).recording && !(x).playing &&!(x).pausing)
#define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_SPIELER1])
+#define FORCE_FIELD_ON(p) ((p)->force_field_passive_time_left > 0)
/* Pixmaps with graphic file */
#define PIX_BACK 0
int key[4];
int dynamite;
int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
+ int force_field_passive_time_left;
+ int force_field_active_time_left;
};
struct LevelInfo
#define EL_DOOR_WHITE 260
#define EL_DOOR_WHITE_GRAY 261
#define EL_KEY_WHITE 262
-#define EL_FORCE_FIELD 263
+#define EL_FORCE_FIELD_PASSIVE 263
#define EL_EXTRA_TIME 264
#define EL_SWITCHGATE_OPEN 265
#define EL_SWITCHGATE_CLOSED 266
#define EL_MOLE_DOWN 314
#define EL_STEEL_SLANTED 315
#define EL_SAND_INVISIBLE 316
+#define EL_DX_UNKNOWN_15 317
+#define EL_DX_UNKNOWN_42 318
+#define EL_DX_UNKNOWN_229 319
+#define EL_DX_UNKNOWN_233 320
+#define EL_FORCE_FIELD_ACTIVE 321
/* "real" (and therefore drawable) runtime elements */
#define EL_SIEB_LEER 500
#define GFX_STEEL_SLANTED (GFX_START_ROCKSDC + 15 * DC_PER_LINE + 5)
#define GFX_EXTRA_TIME (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 8)
-#define GFX_FORCE_FIELD (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 8)
+#define GFX_FORCE_FIELD_PASSIVE (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 8)
+#define GFX_FORCE_FIELD_ACTIVE (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 8)
/* graphics from "RocksFont" */
#define GFX_CHAR_START (GFX_START_ROCKSFONT)
#define GFX_MOLE_RIGHT GFX_CHAR_FRAGE
#define GFX_MOLE_UP GFX_CHAR_FRAGE
#define GFX_MOLE_DOWN GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_15 GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_42 GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_229 GFX_CHAR_FRAGE
+#define GFX_DX_UNKNOWN_233 GFX_CHAR_FRAGE
/* the names of the sounds */
#define SND_ALCHEMY 0
/* forward declaration for internal use */
static int getGraphicAnimationPhase(int, int, int);
+static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
+ int, int, int);
static void UnmapToolButtons();
static void HandleToolButtons(struct GadgetInfo *);
DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
+ if (FORCE_FIELD_ON(player))
+ DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, GFX_FUNKELN_BLAU,
+ 3, 8, ANIM_OSCILLATE);
+
if (player->Pushing && player->GfxPos)
{
int px = SCREENX(next_jx), py = SCREENY(next_jy);
DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
}
+static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
+ int sxx, int syy,
+ int graphic,
+ int frames, int delay,
+ int mode)
+{
+ int phase = getGraphicAnimationPhase(frames, delay, mode);
+
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
+}
+
void getGraphicSource(int graphic, int *pixmap_nr, int *x, int *y)
{
if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
case EL_KEY_WHITE: return GFX_KEY_WHITE;
- case EL_FORCE_FIELD: return GFX_FORCE_FIELD;
+ case EL_FORCE_FIELD_PASSIVE:return GFX_FORCE_FIELD_PASSIVE;
+ case EL_FORCE_FIELD_ACTIVE: return GFX_FORCE_FIELD_ACTIVE;
case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
+ case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
+ case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
+ case EL_DX_UNKNOWN_229: return GFX_DX_UNKNOWN_229;
+ case EL_DX_UNKNOWN_233: return GFX_DX_UNKNOWN_233;
default:
{