mail[Wesnoth-commits] r44699 - /trunk/src/game_events.cpp


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by guillaume . melquiond on July 26, 2010 - 11:52:
Author: silene
Date: Mon Jul 26 11:52:33 2010
New Revision: 44699

URL: http://svn.gna.org/viewcvs/wesnoth?rev=44699&view=rev
Log:
Generalized user synchronization to arbitrary config objects.

Modified:
    trunk/src/game_events.cpp

Modified: trunk/src/game_events.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_events.cpp?rev=44699&r1=44698&r2=44699&view=diff
==============================================================================
--- trunk/src/game_events.cpp (original)
+++ trunk/src/game_events.cpp Mon Jul 26 11:52:33 2010
@@ -377,48 +377,6 @@
 }
 
 /**
- * Saves a choice from an arbitrary source for the replay so that it can
- * be shared between clients. It must not be used for choices made via a
- * synchronized RNG. It must only be used for choices from the LOCAL_MASTER
- * context.
- */
-static void send_local_master_choice(int value)
-{
-       config cfg;
-       cfg["value"] = value;
-       recorder.user_input("choose", cfg);
-}
-
-/**
- * Gets the same choice as was made in the replay.
- * It must be used in for choices in the REMOTE_MASTER context.
- * @return the integer value of the choice made.
- */
-static int retrieve_remote_master_choice()
-{
-       int active_side = resources::controller->current_side();
-       do_replay_handle(active_side, "choose");
-       const config* action = get_replay_source().get_next_action();
-       if (!action || !*(action = &action->child("choose"))) {
-               replay::process_error("\"choose\" expected but none found\n");
-               return 0;
-       }
-
-       return (*action)["value"];
-}
-
-/**
- * Makes a choice in the SYNCED context, when neither the user nor a replay
- * can be consulted.
- * @param num_options the number of possible options.
- * @return the integer value of the choice made.
-  */
-static int synchronized_choice(int num_options)
-{
-       return resources::state_of_game->rng().get_next_random() % 
num_options;
-}
-
-/**
  * Provides a string name for the choice enum.
  * @return a constant string for that type.
  */
@@ -439,37 +397,49 @@
 /**
  * Function class for local choices.
  */
-struct int_choice
-{
-       int nb_options;
-       int_choice(int o): nb_options(o) {}
-       virtual ~int_choice() {}
-       virtual int operator()() const = 0;
+struct user_choice
+{
+       virtual ~user_choice() {}
+       virtual config query_user() const = 0;
+       virtual config random_choice(rand_rng::simple_rng &) const = 0;
 };
 
 /**
  * Performs a choice and calls the function object if local.
  */
-int get_int_choice(const int_choice &fch)
-{
-       int selected = 0;
+config get_user_choice(const std::string &name, const user_choice &uch)
+{
        CHOICE choice = classify_interactive_choice();
-
        DBG_NG << "MP choice has type " << choice_string(choice) << '\n';
 
        switch(choice) {
        case LOCAL_MASTER:
-               selected = fch();
-               send_local_master_choice(selected);
-               break;
+       {
+               /* Query the user and store the result in the replay,
+                  so that it can be shared between clients. */
+               config cfg = uch.query_user();
+               recorder.user_input(name, cfg);
+               return cfg;
+       }
        case REMOTE_MASTER:
-               selected = retrieve_remote_master_choice();
-               break;
+       {
+               // Get the choice from the replay.
+               int active_side = resources::controller->current_side();
+               do_replay_handle(active_side, name);
+               const config *action = get_replay_source().get_next_action();
+               if (!action || !*(action = &action->child(name))) {
+                       replay::process_error("[" + name + "] expected but 
none found\n");
+                       break;
+               }
+               return *action;
+       }
        case SYNCED:
-               selected = synchronized_choice(fch.nb_options);
-               break;
-       }
-       return 0;
+               /* Neither the user nor a replay can be consulted.
+                  The result is not stored in the replay, since the
+                  other clients have already taken the same decision. */
+               return uch.random_choice(resources::state_of_game->rng());
+       }
+       return config();
 }
 
 }
@@ -2275,22 +2245,36 @@
        }
 }
 
-struct unstore_unit_advance_choice: mp_sync::int_choice
-{
+struct unstore_unit_advance_choice: mp_sync::user_choice
+{
+       int nb_options;
        map_location loc;
        bool use_dialog;
+
        unstore_unit_advance_choice(int o, const map_location &l, bool d)
-               : int_choice(o), loc(l), use_dialog(d)
+               : nb_options(o), loc(l), use_dialog(d)
        {}
-       virtual int operator()() const
-       {
+
+       virtual config query_user() const
+       {
+               int selected;
                if (use_dialog) {
                        DBG_NG << "dialog requested\n";
-                       return dialogs::advance_unit_dialog(loc);
+                       selected = dialogs::advance_unit_dialog(loc);
                } else {
                        // VITAL this is NOT done using the synced RNG
-                       return rand() % nb_options;
-               }
+                       selected = rand() % nb_options;
+               }
+               config cfg;
+               cfg["value"] = selected;
+               return cfg;
+       }
+
+       virtual config random_choice(rand_rng::simple_rng &rng) const
+       {
+               config cfg;
+               cfg["value"] = rng.get_next_random() % nb_options;
+               return cfg;
        }
 };
 
@@ -2334,11 +2318,12 @@
                        if (utils::string_bool(cfg["advance"], true) &&
                            
unit_helper::will_certainly_advance(resources::units->find(loc)))
                        {
-                               int total_advancement_options = 
unit_helper::number_of_possible_advances(u);
+                               int total_opt = 
unit_helper::number_of_possible_advances(u);
                                bool use_dialog = side == u.side() &&
                                        (*resources::teams)[side - 
1].is_human();
-                               int selected = 
mp_sync::get_int_choice(unstore_unit_advance_choice(total_advancement_options,
 loc, use_dialog));
-                               dialogs::animate_unit_advancement(loc, 
selected);
+                               config selected = 
mp_sync::get_user_choice("choose",
+                                       
unstore_unit_advance_choice(total_opt, loc, use_dialog));
+                               dialogs::animate_unit_advancement(loc, 
selected["value"]);
                        }
                } else {
                        team& t = (*resources::teams)[u.side()-1];




Related Messages


Powered by MHonArc, Updated Mon Jul 26 12:00:20 2010