moved flag for mouse click events from level to game structure
[rocksndiamonds.git] / src / game.c
index fbe34cc7a6eeef5328fc8bb5b85bef4a62c741fb..5d9e473b0d412d0cd976ff55ec44ece8308d33c5 100644 (file)
@@ -1963,12 +1963,12 @@ static void InitField(int x, int y, boolean init_game)
       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;
 
@@ -2228,14 +2228,14 @@ static void UpdateGameControlValues(void)
               game_mm.score :
               game.score);
   int gems = (level.game_engine_type == GAME_ENGINE_TYPE_EM ?
-             game_em.lev->required :
+             game_em.lev->gems_needed :
              level.game_engine_type == GAME_ENGINE_TYPE_SP ?
              game_sp.infotrons_still_needed :
              level.game_engine_type == GAME_ENGINE_TYPE_MM ?
              game_mm.kettles_still_needed :
              game.gems_still_needed);
   int exit_closed = (level.game_engine_type == GAME_ENGINE_TYPE_EM ?
-                    game_em.lev->required > 0 :
+                    game_em.lev->gems_needed > 0 :
                     level.game_engine_type == GAME_ENGINE_TYPE_SP ?
                     game_sp.infotrons_still_needed > 0 :
                     level.game_engine_type == GAME_ENGINE_TYPE_MM ?
@@ -2366,9 +2366,9 @@ static void UpdateGameControlValues(void)
     (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 =
@@ -2906,12 +2906,17 @@ static void InitGameEngine(void)
   game.use_block_last_field_bug =
     (game.engine_version < VERSION_IDENT(3,1,1,0));
 
+  /* various special flags and settings for native Emerald Mine game engine */
+
   game_em.use_single_button =
     (game.engine_version > VERSION_IDENT(4,0,0,2));
 
   game_em.use_snap_key_bug =
     (game.engine_version < VERSION_IDENT(4,0,1,0));
 
+  game_em.use_old_explosions =
+    (game.engine_version < VERSION_IDENT(4,1,4,2));
+
   // --------------------------------------------------------------------------
 
   // set maximal allowed number of custom element changes per game frame
@@ -3250,6 +3255,8 @@ static void InitGameEngine(void)
   // ---------- 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);
@@ -3272,6 +3279,23 @@ static void InitGameEngine(void)
   // Supaplex levels with time limit currently unsupported -- should be added
   if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
     level.time = 0;
+
+  // ----------initialize flag for handling mouse events ---------------------
+
+  // set flag to default value: do not handle mouse events
+  game.use_mouse_events = FALSE;
+
+  // now check for custom elements which have mouse click events defined
+  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_events = TRUE;
+  }
 }
 
 static int get_num_special_action(int element, int action_first,
@@ -3612,7 +3636,7 @@ void InitGame(void)
   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;
@@ -3746,12 +3770,13 @@ void InitGame(void)
   // 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;
     }
   }
@@ -3933,7 +3958,7 @@ void InitGame(void)
   game.centered_player_nr = (network_playing ? local_player->index_nr : -1);
   game.centered_player_nr_next = game.centered_player_nr;
   game.set_centered_player = FALSE;
-  game.set_centered_player_fast = FALSE;
+  game.set_centered_player_wrap = FALSE;
 
   if (network_playing && tape.recording)
   {
@@ -9872,11 +9897,14 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
     // ---------- 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;
     }
@@ -10152,6 +10180,9 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
 
        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);
        }
@@ -10175,6 +10206,9 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
        {
          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);
 
@@ -11673,6 +11707,8 @@ void GameActions_RND_Main(void)
 
 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;
 
@@ -11859,6 +11895,24 @@ void GameActions_RND(void)
 #endif
   }
 
+  if (mouse_action.button)
+  {
+    int new_button = (mouse_action.button && mouse_action_last.button == 0);
+
+    x = local_player->mouse_action.lx;
+    y = local_player->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];
@@ -12200,6 +12254,8 @@ void GameActions_RND(void)
   // 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)
@@ -14218,13 +14274,13 @@ static int DigField(struct PlayerInfo *player,
     {
       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);
@@ -14701,7 +14757,7 @@ static void PlayLevelMusic(void)
 
 void PlayLevelSound_EM(int xx, int yy, int element_em, int sample)
 {
-  int element = (element_em > -1 ? map_element_EM_to_RND(element_em) : 0);
+  int element = (element_em > -1 ? map_element_EM_to_RND_game(element_em) : 0);
   int offset = (BorderElement == EL_STEELWALL ? 1 : 0);
   int x = xx - 1 - offset;
   int y = yy - 1 - offset;