Author: thonsew
Date: Fri Aug 19 12:54:44 2011
New Revision: 50853

URL: http://svn.gna.org/viewcvs/wesnoth?rev=50853&view=rev
Log:
Added patch by Brilliand for bug #2851 Ghast and Necrophage double feeding
  1. Added event ids to prevent duplicates
  2. Added event deletion via ids.

Modified:
    trunk/changelog
    trunk/data/core/about.cfg
    trunk/data/core/macros/abilities.cfg
    trunk/src/game_events.cpp

Modified: trunk/changelog
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=50853&r1=50852&r2=50853&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Fri Aug 19 12:54:44 2011
@@ -99,6 +99,8 @@
      * Increased the swamp defense from 10% to 20%
      * Decreased the hill defense from 60% to 50%
  * WML engine:
+   * Added [event]id= support (to protect against duplicates)
+   * Added [event]delete=true support (to remove events that have an id set)
    * Implemented sub= and divide= for abilities and weapon specials
      (patch #2857)
    * new attribute replay_save= in [end_level]. Defaults to yes, allows

Modified: trunk/data/core/about.cfg
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/data/core/about.cfg?rev=50853&r1=50852&r2=50853&view=diff
==============================================================================
--- trunk/data/core/about.cfg (original)
+++ trunk/data/core/about.cfg Fri Aug 19 12:54:44 2011
@@ -894,6 +894,9 @@
         name = "Ben Anderman (crimson_penguin)"
         comment = "unit list"
     [/entry]
+     [entry]
+        name = "Brilliand"
+    [/entry]
     [entry]
         name = "Burkay Özdemir (Velory)"
         comment = "Poisoning improvement for Formula AI"

Modified: trunk/data/core/macros/abilities.cfg
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/data/core/macros/abilities.cfg?rev=50853&r1=50852&r2=50853&view=diff
==============================================================================
--- trunk/data/core/macros/abilities.cfg (original)
+++ trunk/data/core/macros/abilities.cfg Fri Aug 19 12:54:44 2011
@@ -527,18 +527,9 @@
 This unit gains 1 hitpoint added to its maximum whenever it kills a living 
unit."
     [/dummy] # a hack to please wmlxgettext (using a bug in wmlxgettext!): 
dummy tag start: [abilities]
 [/abilities]
-
-# NOTE: the purpose of the unit.variables.killed_by_feeding variable is to
-# prevent multiple instances of feeding stacking with each other: the first
-# event will not trigger for units marked as already having been killed by
-# feeding on this turn. The turn number is included in the variable value in
-# order to decrease the chances of feeding not working on a unit as a result of
-# a scenario event storing it upon death and bringing it back later, in which
-# case the variable could still be intact. However, this doesn't work in every
-# imaginable situation and therefore a better fix is still needed eventually.
-
 [event]
-    name=last breath
+       id=ability_feeding_die
+    name=die
     first_time_only=no
 
     [filter]
@@ -548,27 +539,12 @@
                     not_living="yes"
                 [/status]
             [/filter_wml]
-
-            [or]
-                [filter_wml]
-                    [variables]
-                        killed_by_feeding="on_turn_$turn_number"
-                    [/variables]
-                [/filter_wml]
-            [/or]
         [/not]
     [/filter]
 
     [filter_second]
         ability=feeding
     [/filter_second]
-
-    {VARIABLE unit.variables.killed_by_feeding "on_turn_$turn_number"}
-
-    [unstore_unit]
-        variable=unit
-        find_vacant=no
-    [/unstore_unit]
 
     [unstore_unit]
         variable=second_unit
@@ -591,25 +567,6 @@
             increase=1
         [/effect]
     [/object]
-[/event]
-[event]
-    name=die
-    first_time_only=no
-
-    [filter]
-        [filter_wml]
-            [variables]
-                killed_by_feeding="on_turn_$turn_number"
-            [/variables]
-        [/filter_wml]
-    [/filter]
-
-    {CLEAR_VARIABLE unit.variables.killed_by_feeding}
-
-    [unstore_unit]
-        variable=unit
-        find_vacant=no
-    [/unstore_unit]
 [/event]
 [+abilities] # a hack to please wmlxgettext (using a bug in wmlxgettext!): 
dummy tag end: [/abilities]
 #enddef

Modified: trunk/src/game_events.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_events.cpp?rev=50853&r1=50852&r2=50853&view=diff
==============================================================================
--- trunk/src/game_events.cpp (original)
+++ trunk/src/game_events.cpp Fri Aug 19 12:54:44 2011
@@ -123,7 +123,6 @@
        bool manager_running = false;
        int floating_label = 0;
 
-       std::vector< game_events::event_handler > new_handlers;
        typedef std::pair< std::string, config* > wmi_command_change;
        std::vector< wmi_command_change > wmi_command_changes;
 
@@ -570,7 +569,92 @@
 
 namespace {
 
-       std::vector<game_events::event_handler> event_handlers;
+       class t_event_handlers : public std::vector<game_events::event_handler> 
{
+       private:
+               std::vector<game_events::event_handler> insert_buffer;
+               std::set<std::string> remove_buffer;
+               bool buffering;
+
+       public:
+               /**
+                * Adds an event handler.  An event with a nonempty ID will not
+                * be added if an event with that ID already exists.  This 
method
+                * respects this class's buffering functionality.
+                */
+               void add_event_handler(game_events::event_handler const & 
new_handler) {
+                       if(buffering) {
+                               insert_buffer.push_back(new_handler);
+                       } else {
+                               const config & cfg = new_handler.get_config();
+                               std::string id = cfg["id"];
+                               if(id != "") {
+                                       
for(std::vector<game_events::event_handler>::iterator i = begin(); i < end(); 
i++) {
+                                               const config & temp_config = 
(*i).get_config();
+                                               if(id == temp_config["id"])
+                                                       return;
+                                       }
+                               }
+                               this->push_back(new_handler);
+                       }
+               }
+
+               /**
+                * Removes an event handler, identified by its ID.  Events with
+                * empty IDs cannot be removed.  This method respects this 
class's
+                * buffering functionality.
+                */
+               void remove_event_handler(std::string const & id) {
+                       if(id == "")
+                               return;
+
+                       if(buffering)
+                               remove_buffer.insert(id);
+
+                       std::vector<game_events::event_handler> &temp = 
buffering ? insert_buffer : *this;
+
+                       std::vector<game_events::event_handler>::iterator i = 
temp.begin();
+                       while(i < temp.end()) {
+                               const config & temp_config = (*i).get_config();
+                               std::string event_id = temp_config["id"];
+                               if(event_id != "" && event_id == id)
+                                       i = temp.erase(i);
+                               else
+                                       i++;
+                       }
+               }
+
+               /**
+                * Starts buffering.  While buffering, any calls to 
add_event_handler
+                * and remove_event_handler will not take effect until 
commit_buffer
+                * is called.  This function is idempotent - starting a buffer
+                * when already buffering will not start a second buffer.
+                */
+               void start_buffer() {
+                       buffering = true;
+               }
+
+               /**
+                * Stops buffering and commits all changes.
+                */
+               void commit_buffer() {
+                       if(!buffering)
+                               return;
+
+                       buffering = false;
+
+                       // Commit any event removals
+                       for(std::set<std::string>::iterator i = 
remove_buffer.begin(); i != remove_buffer.end(); i++)
+                               remove_event_handler(*i);
+                       remove_buffer.clear();
+
+                       // Commit any spawned events-within-events
+                       for(std::vector<game_events::event_handler>::iterator i 
= insert_buffer.begin(); i != insert_buffer.end(); i++)
+                               add_event_handler(*i);
+                       insert_buffer.clear();
+               }
+       };
+
+       t_event_handlers event_handlers;
 
 } // end anonymous namespace (4)
 
@@ -2693,10 +2777,12 @@
 // Adding new events
 WML_HANDLER_FUNCTION(event, /*event_info*/, cfg)
 {
-       if (!cfg["delayed_variable_substitution"].to_bool(true)) {
-               
new_handlers.push_back(game_events::event_handler(cfg.get_parsed_config()));
+       if (cfg["remove"].to_bool(false)) {
+               event_handlers.remove_event_handler(cfg["id"]);
+       } else if (!cfg["delayed_variable_substitution"].to_bool(true)) {
+               
event_handlers.add_event_handler(game_events::event_handler(cfg.get_parsed_config()));
        } else {
-               
new_handlers.push_back(game_events::event_handler(cfg.get_config()));
+               
event_handlers.add_event_handler(game_events::event_handler(cfg.get_config()));
        }
 }
 
@@ -2767,10 +2853,7 @@
 
 static void commit_new_handlers() {
        // Commit any spawned events-within-events
-       while(new_handlers.size() > 0) {
-               event_handlers.push_back(new_handlers.back());
-               new_handlers.pop_back();
-       }
+       event_handlers.commit_buffer();
 }
 static void commit_wmi_commands() {
        // Commit WML Menu Item command changes
@@ -2797,7 +2880,7 @@
                        }
                } else if(!is_empty_command) {
                        LOG_NG << "setting command for " << mref->name << " 
to:\n" << *wcc.second;
-                       
event_handlers.push_back(game_events::event_handler(mref->command, true));
+                       
event_handlers.add_event_handler(game_events::event_handler(mref->command, 
true));
                }
 
                delete wcc.second;
@@ -3068,7 +3151,7 @@
        {
                assert(!manager_running);
                foreach (const config &ev, cfg.child_range("event")) {
-                       
event_handlers.push_back(game_events::event_handler(ev));
+                       
event_handlers.add_event_handler(game_events::event_handler(ev));
                }
                foreach (const std::string &id, 
utils::split(cfg["unit_wml_ids"])) {
                        unit_wml_ids.insert(id);
@@ -3092,7 +3175,7 @@
                typedef std::pair<std::string, wml_menu_item *> item;
                foreach (const item &itor, 
resources::state_of_game->wml_menu_items) {
                        if (!itor.second->command.empty()) {
-                               
event_handlers.push_back(game_events::event_handler(itor.second->command, 
true));
+                               
event_handlers.add_event_handler(game_events::event_handler(itor.second->command,
 true));
                        }
                        ++wmi_count;
                }
@@ -3176,8 +3259,7 @@
                if(std::find(unit_wml_ids.begin(),unit_wml_ids.end(),id) == 
unit_wml_ids.end()) {
                        unit_wml_ids.insert(id);
                        foreach (const config &new_ev, cfgs) {
-                               std::vector<game_events::event_handler> &temp = 
(pump_manager::count()) ? new_handlers : event_handlers;
-                               
temp.push_back(game_events::event_handler(new_ev));
+                               
event_handlers.add_event_handler(game_events::event_handler(new_ev));
                        }
                }
        }
@@ -3207,6 +3289,8 @@
                                << "recursion level would exceed maximum " << 
game_config::max_loop << '\n';
                        return false;
                }
+
+               event_handlers.start_buffer();
 
                bool result = false;
                while(events_queue.empty() == false) {


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to