+static void CheckBuggyBase(int x, int y)
+{
+ int element = Feld[x][y];
+
+ if (element == EL_SP_BUG)
+ {
+ if (!MovDelay[x][y]) /* wait some time before activating base */
+ MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
+
+ if (MovDelay[x][y])
+ {
+ MovDelay[x][y]--;
+ if (MovDelay[x][y] < 5 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ DrawGraphic(SCREENX(x), SCREENY(y), GFX_SP_BUG_WARNING);
+ if (MovDelay[x][y])
+ return;
+
+ Feld[x][y] = EL_SP_BUG_ACTIVE;
+ }
+ }
+ else if (element == EL_SP_BUG_ACTIVE)
+ {
+ if (!MovDelay[x][y]) /* start activating buggy base */
+ MovDelay[x][y] = 1 * FRAMES_PER_SECOND + RND(1 * FRAMES_PER_SECOND);
+
+ if (MovDelay[x][y])
+ {
+ MovDelay[x][y]--;
+ if (MovDelay[x][y])
+ {
+ int i;
+ static int xy[4][2] =
+ {
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
+
+ if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ DrawGraphic(SCREENX(x),SCREENY(y), GFX_SP_BUG_ACTIVE + SimpleRND(4));
+
+ for (i=0; i<4; i++)
+ {
+ int xx = x + xy[i][0], yy = y + xy[i][1];
+
+ if (IS_PLAYER(xx, yy))
+ {
+ PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_ACTIVATING);
+ break;
+ }
+ }
+
+ return;
+ }
+
+ Feld[x][y] = EL_SP_BUG;
+ DrawLevelField(x, y);
+ }
+ }
+}
+
+static void CheckTrap(int x, int y)
+{
+ int element = Feld[x][y];
+
+ if (element == EL_TRAP_INACTIVE)
+ {
+ if (!MovDelay[x][y]) /* wait some time before activating trap */
+ MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
+
+ if (MovDelay[x][y])
+ {
+ MovDelay[x][y]--;
+ if (MovDelay[x][y])
+ return;
+
+ Feld[x][y] = EL_TRAP_ACTIVE;
+ PlaySoundLevel(x, y, SND_TRAP_ACTIVATING);
+ }
+ }
+ else if (element == EL_TRAP_ACTIVE)
+ {
+ int delay = 4;
+ int num_frames = 8;
+
+ if (!MovDelay[x][y]) /* start activating trap */
+ MovDelay[x][y] = num_frames * delay;
+
+ if (MovDelay[x][y])
+ {
+ MovDelay[x][y]--;
+
+ if (MovDelay[x][y])
+ {
+ if (!(MovDelay[x][y] % delay))
+ {
+ int phase = MovDelay[x][y]/delay;
+
+ if (phase >= num_frames/2)
+ phase = num_frames - phase;
+
+ if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ {
+ DrawGraphic(SCREENX(x),SCREENY(y), GFX_TRAP_INACTIVE + phase - 1);
+ ErdreichAnbroeckeln(SCREENX(x), SCREENY(y));
+ }
+ }
+
+ return;
+ }
+
+ Feld[x][y] = EL_TRAP_INACTIVE;
+ DrawLevelField(x, y);
+ }
+ }
+}
+
+static void DrawBeltAnimation(int x, int y, int element)
+{
+ int belt_nr = getBeltNrFromElement(element);
+ int belt_dir = game.belt_dir[belt_nr];
+
+ if (belt_dir != MV_NO_MOVING)
+ {
+ int delay = 2;
+ int mode = (belt_dir == MV_LEFT ? ANIM_NORMAL : ANIM_REVERSE);
+ int graphic = el2gfx(element) + (belt_dir == MV_LEFT ? 0 : 7);
+
+ DrawGraphicAnimation(x, y, graphic, 8, delay, mode);
+
+ if (!(FrameCounter % 2))
+ PlaySoundLevel(x, y, SND_CONVEYOR_BELT_RUNNING);
+ }
+}
+
+static void PlayerActions(struct PlayerInfo *player, byte player_action)
+{
+ static byte stored_player_action[MAX_PLAYERS];
+ static int num_stored_actions = 0;
+#if 0
+ static boolean save_tape_entry = FALSE;
+#endif
+ boolean moved = FALSE, snapped = FALSE, bombed = FALSE;
+ int left = player_action & JOY_LEFT;
+ int right = player_action & JOY_RIGHT;
+ int up = player_action & JOY_UP;
+ int down = player_action & JOY_DOWN;
+ int button1 = player_action & JOY_BUTTON_1;
+ int button2 = player_action & JOY_BUTTON_2;
+ int dx = (left ? -1 : right ? 1 : 0);
+ int dy = (up ? -1 : down ? 1 : 0);
+
+ stored_player_action[player->index_nr] = 0;
+ num_stored_actions++;
+
+ if (!player->active || tape.pausing)
+ return;
+
+ if (player_action)
+ {
+#if 0
+ save_tape_entry = TRUE;
+#endif
+ player->frame_reset_delay = 0;
+
+ if (button1)
+ snapped = SnapField(player, dx, dy);
+ else
+ {
+ if (button2)
+ bombed = PlaceBomb(player);
+ moved = MoveFigure(player, dx, dy);
+ }
+
+ if (tape.single_step && tape.recording && !tape.pausing)
+ {
+ if (button1 || (bombed && !moved))
+ {
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+ SnapField(player, 0, 0); /* stop snapping */
+ }
+ }
+
+#if 0
+ if (tape.recording && (moved || snapped || bombed))
+ {
+ if (bombed && !moved)
+ player_action &= JOY_BUTTON;
+
+ stored_player_action[player->index_nr] = player_action;
+ save_tape_entry = TRUE;
+ }
+ else if (tape.playing && snapped)
+ SnapField(player, 0, 0); /* stop snapping */
+#else
+ stored_player_action[player->index_nr] = player_action;
+#endif
+ }
+ else
+ {
+ /* no actions for this player (no input at player's configured device) */
+
+ DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
+ SnapField(player, 0, 0);
+ CheckGravityMovement(player);
+
+#if 1
+ if (player->MovPos == 0) /* needed for tape.playing */
+ player->is_moving = FALSE;
+#endif
+#if 0
+ if (player->MovPos == 0) /* needed for tape.playing */
+ player->last_move_dir = MV_NO_MOVING;
+
+ /* !!! CHECK THIS AGAIN !!!
+ (Seems to be needed for some EL_ROBOT stuff, but breaks
+ tapes when walking through pipes!)
+ */
+
+ /* it seems that "player->last_move_dir" is misused as some sort of
+ "player->is_just_moving_in_this_moment", which is needed for the
+ robot stuff (robots don't kill players when they are moving)
+ */
+#endif
+
+ if (++player->frame_reset_delay > player->move_delay_value)
+ player->Frame = 0;
+ }
+
+#if 0
+ if (tape.recording && num_stored_actions >= MAX_PLAYERS && save_tape_entry)
+ {
+ TapeRecordAction(stored_player_action);
+ num_stored_actions = 0;
+ save_tape_entry = FALSE;
+ }
+#else
+ if (tape.recording && num_stored_actions >= MAX_PLAYERS)
+ {
+ TapeRecordAction(stored_player_action);
+ num_stored_actions = 0;
+ }
+#endif
+
+#if 0
+ if (tape.playing && !tape.pausing && !player_action &&
+ tape.counter < tape.length)
+ {
+ int jx = player->jx, jy = player->jy;
+ int next_joy =
+ tape.pos[tape.counter].action[player->index_nr] & (JOY_LEFT|JOY_RIGHT);
+
+ if ((next_joy == JOY_LEFT || next_joy == JOY_RIGHT) &&
+ (player->MovDir != JOY_UP && player->MovDir != JOY_DOWN))
+ {
+ int dx = (next_joy == JOY_LEFT ? -1 : +1);
+
+ if (IN_LEV_FIELD(jx+dx, jy) && IS_PUSHABLE(Feld[jx+dx][jy]))
+ {
+ int el = Feld[jx+dx][jy];
+ int push_delay = (IS_SB_ELEMENT(el) || el == EL_SONDE ? 2 :
+ (el == EL_BALLOON || el == EL_SPRING) ? 0 : 10);
+
+ if (tape.delay_played + push_delay >= tape.pos[tape.counter].delay)
+ {
+ player->MovDir = next_joy;
+ player->Frame = FrameCounter % 4;
+ player->Pushing = TRUE;
+ }
+ }
+ }
+ }
+#endif
+}
+