switch (Feld[x][y])
{
case EL_SPIELFIGUR:
+ case EL_SP_MURPHY:
if (init_game)
Feld[x][y] = EL_SPIELER1;
/* no break! */
case EL_MAMPFER2:
case EL_ROBOT:
case EL_PACMAN:
+ case EL_SP_SNIKSNAK:
+ case EL_SP_ELECTRON:
InitMovDir(x, y);
break;
MovDir[x][y] = 1 << RND(4);
break;
+ case EL_SP_EMPTY:
+ Feld[x][y] = EL_LEERRAUM;
+ break;
+
default:
break;
}
ScreenMovPos = 0;
ScreenGfxPos = 0;
- AllPlayersGone = SiebAktiv = FALSE;
+ if (level.high_speed)
+ {
+ MoveSpeed = 4;
+ ScrollStepSize = TILEX/4;
+ }
+ else
+ {
+ MoveSpeed = 8;
+ ScrollStepSize = TILEX/8;
+ }
+
+ AllPlayersGone = FALSE;
+ SiebAktiv = FALSE;
+ SiebCount = 0;
for (i=0; i<MAX_NUM_AMOEBA; i++)
AmoebaCnt[i] = AmoebaCnt2[i] = 0;
if (element != EL_KAEFER &&
element != EL_FLIEGER &&
element != EL_BUTTERFLY &&
- element != EL_FIREFLY)
+ element != EL_FIREFLY &&
+ element != EL_SP_SNIKSNAK &&
+ element != EL_SP_ELECTRON)
break;
for (i=0; i<4; i++)
MovDir[x][y] = direction[0][i];
break;
}
- else if (element == EL_FLIEGER || element == EL_FIREFLY)
+ else if (element == EL_FLIEGER || element == EL_FIREFLY ||
+ element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
{
MovDir[x][y] = direction[1][i];
break;
return;
}
- if (element == EL_BOMBE && (lastline || object_hit)) /* element is bomb */
+ if ((element == EL_BOMBE || element == EL_SP_DISK_ORANGE) &&
+ (lastline || object_hit)) /* element is bomb */
{
Bang(x, y);
return;
if (!lastline && object_hit) /* check which object was hit */
{
if (CAN_CHANGE(element) &&
- (smashed == EL_SIEB_LEER || smashed == EL_SIEB2_LEER) && !SiebAktiv)
- SiebAktiv = level.dauer_sieb * FRAMES_PER_SECOND;
+ (smashed == EL_SIEB_INAKTIV || smashed == EL_SIEB2_INAKTIV))
+ {
+ int x, y;
+ int activated_magic_wall =
+ (smashed == EL_SIEB_INAKTIV ? EL_SIEB_LEER : EL_SIEB2_LEER);
+
+ /* activate magic wall / mill */
+
+ for (y=0; y<lev_fieldy; y++)
+ for (x=0; x<lev_fieldx; x++)
+ if (Feld[x][y] == smashed)
+ Feld[x][y] = activated_magic_wall;
+
+ SiebCount = level.dauer_sieb * FRAMES_PER_SECOND;
+ SiebAktiv = TRUE;
+ }
if (IS_PLAYER(x, y+1))
{
}
else if (element == EL_FELSBROCKEN)
{
- if (IS_ENEMY(smashed) || smashed == EL_BOMBE || smashed == EL_SONDE ||
- smashed == EL_SCHWEIN || smashed == EL_DRACHE)
+ if (IS_ENEMY(smashed) ||
+ smashed == EL_BOMBE || smashed == EL_SP_DISK_ORANGE ||
+ smashed == EL_SONDE || smashed == EL_SCHWEIN || smashed == EL_DRACHE)
{
Bang(x, y+1);
return;
else if (element == EL_BUTTERFLY) /* && MovDir[x][y] == left_dir) */
MovDelay[x][y] = 1;
}
- else if (element == EL_FLIEGER || element == EL_FIREFLY)
+ else if (element == EL_FLIEGER || element == EL_FIREFLY ||
+ element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
{
TestIfBadThingHitsOtherBadThing(x, y);
!IS_FREE_OR_PLAYER(move_x, move_y))
MovDir[x][y] = right_dir;
- if (element == EL_FLIEGER && MovDir[x][y] != old_move_dir)
+ if ((element == EL_FLIEGER ||
+ element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
+ && MovDir[x][y] != old_move_dir)
MovDelay[x][y] = 9;
else if (element == EL_FIREFLY) /* && MovDir[x][y] == right_dir) */
MovDelay[x][y] = 1;
Store2[x][y] = 0;
}
}
- else if (SiebAktiv && CAN_CHANGE(element) &&
+ else if (CAN_CHANGE(element) &&
(Feld[x][y+1] == EL_SIEB_LEER || Feld[x][y+1] == EL_SIEB2_LEER))
{
InitMovingField(x, y, MV_DOWN);
if (element!=EL_MAMPFER && element!=EL_MAMPFER2 && element!=EL_PACMAN)
{
TurnRound(x, y);
- if (MovDelay[x][y] && (element == EL_KAEFER || element == EL_FLIEGER))
+ if (MovDelay[x][y] && (element == EL_KAEFER || element == EL_FLIEGER ||
+ element == EL_SP_SNIKSNAK ||
+ element == EL_SP_ELECTRON))
DrawLevelField(x, y);
}
}
TurnRound(x, y);
- if (element == EL_KAEFER || element == EL_FLIEGER)
+ if (element == EL_KAEFER || element == EL_FLIEGER ||
+ element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
DrawLevelField(x, y);
else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
DrawGraphicAnimation(x, y, el2gfx(element), 2, 4, ANIM_NORMAL);
int newx = x + dx, newy = y + dy;
int step = (horiz_move ? dx : dy) * TILEX/8;
- if (CAN_FALL(element) && horiz_move)
+ if (CAN_FALL(element) && horiz_move && !IS_SP_ELEMENT(element))
step*=2;
else if (element == EL_TROPFEN)
step/=2;
if (newax == ax && neway == ay) /* amoeba cannot grow */
{
- if (i == 4 && !waiting_for_player)
+ if (i == 4 && (!waiting_for_player || game_emulation == EMU_BOULDERDASH))
{
Feld[ax][ay] = EL_AMOEBE_TOT;
DrawLevelField(ax, ay);
void SiebAktivieren(int x, int y, int typ)
{
- if (!(SiebAktiv % 4) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y),
- (typ == 1 ? GFX_SIEB_VOLL :
- GFX_SIEB2_VOLL) + 3 - (SiebAktiv % 16) / 4);
+ int graphic = (typ == 1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL) + 3;
+
+ DrawGraphicAnimation(x, y, graphic, 4, 4, ANIM_REVERSE);
}
void AusgangstuerPruefen(int x, int y)
if (SiebAktiv)
{
- if (!(SiebAktiv%4))
+ if (!(SiebCount % 4))
PlaySoundLevel(sieb_x, sieb_y, SND_MIEP);
- SiebAktiv--;
- if (!SiebAktiv)
+
+ if (SiebCount > 0)
{
- for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+ SiebCount--;
+ if (!SiebCount)
{
- element = Feld[x][y];
- if (element == EL_SIEB_LEER || element == EL_SIEB_VOLL)
- {
- Feld[x][y] = EL_SIEB_TOT;
- DrawLevelField(x, y);
- }
- else if (element == EL_SIEB2_LEER || element == EL_SIEB2_VOLL)
+ for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
{
- Feld[x][y] = EL_SIEB2_TOT;
- DrawLevelField(x, y);
+ element = Feld[x][y];
+ if (element == EL_SIEB_LEER || element == EL_SIEB_VOLL)
+ {
+ Feld[x][y] = EL_SIEB_TOT;
+ DrawLevelField(x, y);
+ }
+ else if (element == EL_SIEB2_LEER || element == EL_SIEB2_VOLL)
+ {
+ Feld[x][y] = EL_SIEB2_TOT;
+ DrawLevelField(x, y);
+ }
}
+
+ SiebAktiv = FALSE;
}
}
}
- if (TimeLeft>0 && TimeFrames>=(1000/GameFrameDelay) && !tape.pausing)
+ if (TimeLeft > 0 && TimeFrames >= (1000 / GameFrameDelay) && !tape.pausing)
{
TimeFrames = 0;
TimeLeft--;
jy = player->jy = new_jy;
StorePlayer[jx][jy] = player->element_nr;
- player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * 7*TILEX/8;
+ player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / MoveSpeed);
ScrollFigure(player, SCROLL_INIT);
/* should only happen if pre-1.2 tape recordings are played */
/* this is only for backward compatibility */
+ int old_move_speed = MoveSpeed;
+
#if DEBUG
printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES.\n");
#endif
+ /* scroll remaining steps with finest movement resolution */
+ MoveSpeed = 8;
+
while (player->MovPos)
{
ScrollFigure(player, SCROLL_GO_ON);
DrawAllPlayers();
BackToFront();
}
+
+ MoveSpeed = old_move_speed;
}
if (player->last_move_dir & (MV_LEFT | MV_RIGHT))
else if (!FrameReached(&player->actual_frame_counter, 1))
return;
- player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX/8;
+ player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX / MoveSpeed;
player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize);
if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING)
if (ScreenMovPos)
{
- ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX/8;
+ ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX / MoveSpeed;
ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize);
redraw_mask |= REDRAW_FIELD;
}
PlaySoundLevel(x, y, SND_PONG);
break;
+ case EL_SPEED_PILL:
+ RemoveField(x, y);
+ MoveSpeed = 4;
+ ScrollStepSize = TILEX/4;
+ PlaySoundLevel(x, y, SND_PONG);
+ break;
+
case EL_DYNAMIT_AUS:
+ case EL_SP_DISK_RED:
RemoveField(x, y);
player->dynamite++;
RaiseScoreElement(EL_DYNAMIT);
return MF_ACTION;
break;
+ case EL_SP_TERMINAL:
+ {
+ int xx, yy;
+
+ for (yy=0; yy<lev_fieldy; yy++)
+ for (xx=0; xx<lev_fieldx; xx++)
+ if (Feld[xx][yy] == EL_SP_DISK_YELLOW)
+ Bang(xx, yy);
+
+ Feld[x][y] = EL_SP_TERMINAL_ACTIVE;
+ DrawLevelField(x, y);
+ return MF_ACTION;
+ }
+ break;
+
+ case EL_SP_EXIT:
+ if (local_player->gems_still_needed > 0)
+ return MF_NO_ACTION;
+
+ player->LevelSolved = player->GameOver = TRUE;
+ PlaySoundLevel(x, y, SND_BUING);
+ break;
+
case EL_FELSBROCKEN:
case EL_BOMBE:
case EL_KOKOSNUSS:
case EL_ZEIT_LEER:
+ case EL_SP_ZONK:
+ case EL_SP_DISK_ORANGE:
if (dy || mode == DF_SNAP)
return MF_NO_ACTION;
return MF_NO_ACTION;
break;
+ case EL_SP_PORT1_LEFT:
+ case EL_SP_PORT2_LEFT:
+ case EL_SP_PORT1_RIGHT:
+ case EL_SP_PORT2_RIGHT:
+ case EL_SP_PORT1_UP:
+ case EL_SP_PORT2_UP:
+ case EL_SP_PORT1_DOWN:
+ case EL_SP_PORT2_DOWN:
+ case EL_SP_PORT_X:
+ case EL_SP_PORT_Y:
+ case EL_SP_PORT_XY:
+ if ((dx == -1 &&
+ element != EL_SP_PORT1_LEFT &&
+ element != EL_SP_PORT2_LEFT &&
+ element != EL_SP_PORT_X &&
+ element != EL_SP_PORT_XY) ||
+ (dx == +1 &&
+ element != EL_SP_PORT1_RIGHT &&
+ element != EL_SP_PORT2_RIGHT &&
+ element != EL_SP_PORT_X &&
+ element != EL_SP_PORT_XY) ||
+ (dy == -1 &&
+ element != EL_SP_PORT1_UP &&
+ element != EL_SP_PORT2_UP &&
+ element != EL_SP_PORT_Y &&
+ element != EL_SP_PORT_XY) ||
+ (dy == +1 &&
+ element != EL_SP_PORT1_DOWN &&
+ element != EL_SP_PORT2_DOWN &&
+ element != EL_SP_PORT_Y &&
+ element != EL_SP_PORT_XY) ||
+ !IN_LEV_FIELD(x + dx, y + dy) ||
+ !IS_FREE(x + dx, y + dy))
+ return MF_NO_ACTION;
+ break;
+
case EL_AUSGANG_ZU:
case EL_AUSGANG_ACT:
/* door is not (yet) open */
case EL_SOKOBAN_FELD_VOLL:
case EL_SOKOBAN_OBJEKT:
case EL_SONDE:
+ case EL_SP_DISK_YELLOW:
if (mode == DF_SNAP)
return MF_NO_ACTION;