break;
case EL_EMC_MAGIC_BALL:
- if (game.ball_state)
+ if (game.ball_active)
Feld[x][y] = EL_EMC_MAGIC_BALL_ACTIVE;
break;
case EL_EMC_MAGIC_BALL_SWITCH:
- if (game.ball_state)
+ if (game.ball_active)
Feld[x][y] = EL_EMC_MAGIC_BALL_SWITCH_ACTIVE;
break;
(exit_closed ? EL_EXIT_CLOSED : EL_EXIT_OPEN);
game_panel_controls[GAME_PANEL_EMC_MAGIC_BALL].value =
- (game.ball_state ? EL_EMC_MAGIC_BALL_ACTIVE : EL_EMC_MAGIC_BALL);
+ (game.ball_active ? EL_EMC_MAGIC_BALL_ACTIVE : EL_EMC_MAGIC_BALL);
game_panel_controls[GAME_PANEL_EMC_MAGIC_BALL_SWITCH].value =
- (game.ball_state ? EL_EMC_MAGIC_BALL_SWITCH_ACTIVE :
+ (game.ball_active ? EL_EMC_MAGIC_BALL_SWITCH_ACTIVE :
EL_EMC_MAGIC_BALL_SWITCH);
game_panel_controls[GAME_PANEL_LIGHT_SWITCH].value =
// ---------- initialize graphics engine ------------------------------------
game.scroll_delay_value =
(game.forced_scroll_delay_value != -1 ? game.forced_scroll_delay_value :
+ level.game_engine_type == GAME_ENGINE_TYPE_EM &&
+ !setup.forced_scroll_delay ? 0 :
setup.scroll_delay ? setup.scroll_delay_value : 0);
game.scroll_delay_value =
MIN(MAX(MIN_SCROLL_DELAY, game.scroll_delay_value), MAX_SCROLL_DELAY);
// Supaplex levels with time limit currently unsupported -- should be added
if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
level.time = 0;
+
+ // ---------- initialize flags for handling game actions --------------------
+
+ // set flags for game actions to default values
+ game.use_key_actions = TRUE;
+ game.use_mouse_actions = FALSE;
+
+ // when using Mirror Magic game engine, handle mouse events only
+ if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ {
+ game.use_key_actions = FALSE;
+ game.use_mouse_actions = TRUE;
+ }
+
+ // check for custom elements with mouse click events
+ if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
+ {
+ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ if (HAS_CHANGE_EVENT(element, CE_CLICKED_BY_MOUSE) ||
+ HAS_CHANGE_EVENT(element, CE_PRESSED_BY_MOUSE) ||
+ HAS_CHANGE_EVENT(element, CE_MOUSE_CLICKED_ON_X) ||
+ HAS_CHANGE_EVENT(element, CE_MOUSE_PRESSED_ON_X))
+ game.use_mouse_actions = TRUE;
+ }
+ }
}
static int get_num_special_action(int element, int action_first,
InitGameEngine();
InitGameControlValues();
+ // initialize tape actions from game when recording tape
+ if (tape.recording)
+ {
+ tape.use_key_actions = game.use_key_actions;
+ tape.use_mouse_actions = game.use_mouse_actions;
+ }
+
// don't play tapes over network
network_playing = (network.enabled && !tape.playing);
game.lenses_time_left = 0;
game.magnify_time_left = 0;
- game.ball_state = level.ball_state_initial;
+ game.ball_active = level.ball_active_initial;
game.ball_content_nr = 0;
game.explosions_delayed = TRUE;
// use preferred player also in local single-player mode
if (!network.enabled && !game.team_mode)
{
- int old_index_nr = local_player->index_nr;
int new_index_nr = setup.network_player_nr;
if (new_index_nr >= 0 && new_index_nr < MAX_PLAYERS)
{
- stored_player[old_index_nr].connected_locally = FALSE;
+ for (i = 0; i < MAX_PLAYERS; i++)
+ stored_player[i].connected_locally = FALSE;
+
stored_player[new_index_nr].connected_locally = TRUE;
}
}
// ---------- player actions ---------------------------------------------
case CA_MOVE_PLAYER:
+ case CA_MOVE_PLAYER_NEW:
{
// automatically move to the next field in specified direction
for (i = 0; i < MAX_PLAYERS; i++)
if (trigger_player_bits & (1 << i))
- stored_player[i].programmed_action = action_arg_direction;
+ if (action_type == CA_MOVE_PLAYER ||
+ stored_player[i].MovPos == 0)
+ stored_player[i].programmed_action = action_arg_direction;
break;
}
if (CustomValue[x][y] == 0)
{
+ // reset change counter (else CE_VALUE_GETS_ZERO would not work)
+ ChangeCount[x][y] = 0; // allow at least one more change
+
CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_GETS_ZERO);
CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X);
}
{
int xx, yy;
+ // reset change counter (else CE_SCORE_GETS_ZERO would not work)
+ ChangeCount[x][y] = 0; // allow at least one more change
+
CheckElementChange(x, y, element, EL_UNDEFINED, CE_SCORE_GETS_ZERO);
CheckTriggeredElementChange(x, y, element, CE_SCORE_GETS_ZERO_OF_X);
static void SetMouseActionFromTapeAction(struct MouseActionInfo *mouse_action,
byte *tape_action)
{
- if (!tape.use_mouse)
+ if (!tape.use_mouse_actions)
return;
mouse_action->lx = tape_action[TAPE_ACTION_LX];
static void SetTapeActionFromMouseAction(byte *tape_action,
struct MouseActionInfo *mouse_action)
{
- if (!tape.use_mouse)
+ if (!tape.use_mouse_actions)
return;
tape_action[TAPE_ACTION_LX] = mouse_action->lx;
unsigned int game_frame_delay_value;
byte *recorded_player_action;
byte summarized_player_action = 0;
- byte tape_action[MAX_PLAYERS];
+ byte tape_action[MAX_TAPE_ACTIONS] = { 0 };
int i;
// detect endless loops, caused by custom element programming
void GameActions_RND(void)
{
+ static struct MouseActionInfo mouse_action_last = { 0 };
+ struct MouseActionInfo mouse_action = local_player->effective_mouse_action;
int magic_wall_x = 0, magic_wall_y = 0;
int i, x, y, element, graphic, last_gfx_frame;
#endif
}
+ if (mouse_action.button)
+ {
+ int new_button = (mouse_action.button && mouse_action_last.button == 0);
+
+ x = mouse_action.lx;
+ y = mouse_action.ly;
+ element = Feld[x][y];
+
+ if (new_button)
+ {
+ CheckElementChange(x, y, element, EL_UNDEFINED, CE_CLICKED_BY_MOUSE);
+ CheckTriggeredElementChange(x, y, element, CE_MOUSE_CLICKED_ON_X);
+ }
+
+ CheckElementChange(x, y, element, EL_UNDEFINED, CE_PRESSED_BY_MOUSE);
+ CheckTriggeredElementChange(x, y, element, CE_MOUSE_PRESSED_ON_X);
+ }
+
SCAN_PLAYFIELD(x, y)
{
element = Feld[x][y];
// use random number generator in every frame to make it less predictable
if (game.engine_version >= VERSION_IDENT(3,1,1,0))
RND(1);
+
+ mouse_action_last = mouse_action;
}
static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
{
int xx, yy;
- game.ball_state = !game.ball_state;
+ game.ball_active = !game.ball_active;
SCAN_PLAYFIELD(xx, yy)
{
int e = Feld[xx][yy];
- if (game.ball_state)
+ if (game.ball_active)
{
if (e == EL_EMC_MAGIC_BALL)
CreateField(xx, yy, EL_EMC_MAGIC_BALL_ACTIVE);