static void PlayLevelSoundNearest(int, int, int);
static void PlayLevelSoundAction(int, int, int);
static void PlayLevelSoundElementAction(int, int, int, int);
+static void PlayLevelSoundElementActionIfLoop(int, int, int, int);
static void PlayLevelSoundActionIfLoop(int, int, int);
static void StopLevelSoundActionIfLoop(int, int, int);
static void PlayLevelMusic();
boolean emulate_bd = TRUE; /* unless non-BOULDERDASH elements found */
boolean emulate_sb = TRUE; /* unless non-SOKOBAN elements found */
boolean emulate_sp = TRUE; /* unless non-SUPAPLEX elements found */
- int i, j, x, y;
+ int i, j, k, x, y;
InitGameEngine();
/* don't play tapes over network */
network_playing = (options.network && !tape.playing);
- for (i=0; i<MAX_PLAYERS; i++)
+ for (i=0; i < MAX_PLAYERS; i++)
{
struct PlayerInfo *player = &stored_player[i];
player->lights_still_needed = 0;
player->friends_still_needed = 0;
- for (j=0; j<4; j++)
+ for (j=0; j < 4; j++)
player->key[j] = FALSE;
player->dynabomb_count = 0;
player->is_pushing = FALSE;
player->is_switching = FALSE;
+ player->is_bored = FALSE;
+ player->is_sleeping = FALSE;
+
+ player->frame_counter_bored = -1;
+ player->frame_counter_sleeping = -1;
+
+ player->anim_delay_counter = 0;
+ player->post_delay_counter = 0;
+
+ player->special_action_bored = ACTION_DEFAULT;
+ player->special_action_sleeping = ACTION_DEFAULT;
+
+ player->num_special_action_bored = 0;
+ player->num_special_action_sleeping = 0;
+
+ /* determine number of special actions for bored and sleeping animation */
+ for (j=ACTION_BORING_1; j <= ACTION_BORING_LAST; j++)
+ {
+ boolean found = FALSE;
+
+ for (k=0; k < NUM_DIRECTIONS; k++)
+ if (el_act_dir2img(player->element_nr, j, k) !=
+ el_act_dir2img(player->element_nr, ACTION_DEFAULT, k))
+ found = TRUE;
+
+ if (found)
+ player->num_special_action_bored++;
+ else
+ break;
+ }
+ for (j=ACTION_SLEEPING_1; j <= ACTION_SLEEPING_LAST; j++)
+ {
+ boolean found = FALSE;
+
+ for (k=0; k < NUM_DIRECTIONS; k++)
+ if (el_act_dir2img(player->element_nr, j, k) !=
+ el_act_dir2img(player->element_nr, ACTION_DEFAULT, k))
+ found = TRUE;
+
+ if (found)
+ player->num_special_action_sleeping++;
+ else
+ break;
+ }
+
player->switch_x = -1;
player->switch_y = -1;
return CheckElementSideChange(x, y, element, CH_SIDE_ANY, trigger_event, -1);
}
+static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting)
+{
+ int jx = player->jx, jy = player->jy;
+ int element = player->element_nr;
+ boolean was_waiting = player->is_waiting;
+
+ if (is_waiting)
+ {
+ int action;
+
+ if (!was_waiting) /* not waiting -> waiting */
+ {
+ player->is_waiting = TRUE;
+
+ player->frame_counter_bored =
+ FrameCounter +
+ game.player_boring_delay_fixed +
+ SimpleRND(game.player_boring_delay_random);
+ player->frame_counter_sleeping =
+ FrameCounter +
+ game.player_sleeping_delay_fixed +
+ SimpleRND(game.player_sleeping_delay_random);
+
+ InitPlayerGfxAnimation(player, ACTION_WAITING, player->MovDir);
+ }
+
+ if (game.player_sleeping_delay_fixed != -1 &&
+ game.player_sleeping_delay_random != -1 &&
+ player->anim_delay_counter == 0 &&
+ player->post_delay_counter == 0 &&
+ FrameCounter >= player->frame_counter_sleeping)
+ player->is_sleeping = TRUE;
+ else if (game.player_boring_delay_fixed != -1 &&
+ game.player_boring_delay_random != -1 &&
+ FrameCounter >= player->frame_counter_bored)
+ player->is_bored = TRUE;
+
+ action = (player->is_sleeping ? ACTION_SLEEPING :
+ player->is_bored ? ACTION_BORING : ACTION_WAITING);
+
+ if (!was_waiting)
+ PlayLevelSoundElementAction(jx, jy, element, action);
+ else
+ PlayLevelSoundElementActionIfLoop(jx, jy, element, action);
+ }
+ else if (was_waiting) /* waiting -> not waiting */
+ {
+ if (player->is_sleeping)
+ PlayLevelSoundElementAction(jx, jy, element, ACTION_AWAKENING);
+
+ player->is_waiting = FALSE;
+ player->is_bored = FALSE;
+ player->is_sleeping = FALSE;
+
+ player->frame_counter_bored = -1;
+ player->frame_counter_sleeping = -1;
+
+ player->anim_delay_counter = 0;
+ player->post_delay_counter = 0;
+
+ player->special_action_bored = ACTION_DEFAULT;
+ player->special_action_sleeping = ACTION_DEFAULT;
+ }
+}
+
#if 1
static byte PlayerActions(struct PlayerInfo *player, byte player_action)
{
}
}
+ SetPlayerWaiting(player, FALSE);
+
#if 1
return player_action;
#else
CheckGravityMovement(player);
if (player->MovPos == 0)
- InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir);
+ SetPlayerWaiting(player, TRUE);
if (player->MovPos == 0) /* needed for tape.playing */
player->is_moving = FALSE;
tape_action[i] = PlayerActions(&stored_player[i], actual_player_action);
+ if (tape.recording && tape_action[i] && !tape.player_participates[i])
+ tape.player_participates[i] = TRUE; /* player just appeared from CE */
+
ScrollPlayer(&stored_player[i], SCROLL_GO_ON);
}
PlayLevelSound(x, y, sound_effect);
}
+static void PlayLevelSoundElementActionIfLoop(int x, int y, int element,
+ int action)
+{
+ int sound_effect = element_info[element].sound[action];
+
+ if (sound_effect != SND_UNDEFINED && IS_LOOP_SOUND(sound_effect))
+ PlayLevelSound(x, y, sound_effect);
+}
+
static void PlayLevelSoundActionIfLoop(int x, int y, int action)
{
int sound_effect = element_info[Feld[x][y]].sound[action];