+static void PlayerActions(struct PlayerInfo *player, byte player_action)
+{
+ static byte stored_player_action[MAX_PLAYERS];
+ static int num_stored_actions = 0;
+ static boolean save_tape_entry = FALSE;
+ boolean moved = FALSE, snapped = FALSE, bombed = FALSE;
+ int jx = player->jx, jy = player->jy;
+ 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 || player->gone || tape.pausing)
+ return;
+
+ if (player_action)
+ {
+ save_tape_entry = TRUE;
+ 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.recording && (moved || snapped || bombed))
+ {
+ if (bombed && !moved)
+ player_action &= JOY_BUTTON;
+
+ stored_player_action[player->index_nr] = player_action;
+
+#if 0
+ /* this allows cycled sequences of PlayerActions() */
+ if (num_stored_actions >= MAX_PLAYERS)
+ {
+ TapeRecordAction(stored_player_action);
+ num_stored_actions = 0;
+ }
+#endif
+
+ }
+ else if (tape.playing && snapped)
+ SnapField(player, 0,0); /* stop snapping */
+ }
+ else
+ {
+ DigField(player, 0,0, 0,0, DF_NO_PUSH);
+ SnapField(player, 0,0);
+ if (++player->frame_reset_delay > MoveSpeed)
+ player->Frame = 0;
+ }
+
+ if (tape.recording && num_stored_actions >= MAX_PLAYERS && save_tape_entry)
+ {
+ TapeRecordAction(stored_player_action);
+ num_stored_actions = 0;
+ save_tape_entry = FALSE;
+ }
+
+ if (tape.playing && !tape.pausing && !player_action &&
+ tape.counter < tape.length)
+ {
+ 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 : 10);
+
+ if (tape.delay_played + push_delay >= tape.pos[tape.counter].delay)
+ {
+ player->MovDir = next_joy;
+ player->Frame = FrameCounter % 4;
+ player->Pushing = TRUE;
+ }
+ }
+ }
+ }
+}
+