Author: sapient
Date: Sun May  6 01:09:03 2007
New Revision: 17351

URL: http://svn.gna.org/viewcvs/wesnoth?rev=17351&view=rev
Log:
finish the support for [and] and [or] in SLF.

Modified:
    trunk/changelog
    trunk/src/map.cpp

Modified: trunk/changelog
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=17351&r1=17350&r2=17351&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Sun May  6 01:09:03 2007
@@ -23,6 +23,7 @@
    * replace [own_village] with macro {OWN_VILLAGE X Y SIDE}
    * new conditional tag [have_location], tests true if any location passes
      the standard location filter provided inside the tag
+   * now the standard location filter supports [and] and [or] tags
  * user interface:
    * fixed incorrect active flag in the satus bar when using custom flag
    * restore a lost feature : if acceleration is on, pressing shift uses 
normal speed

Modified: trunk/src/map.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/map.cpp?rev=17351&r1=17350&r2=17351&view=diff
==============================================================================
--- trunk/src/map.cpp (original)
+++ trunk/src/map.cpp Sun May  6 01:09:03 2007
@@ -563,11 +563,19 @@
 }
 
 namespace {
+
        struct terrain_cache_manager {
                terrain_cache_manager() : ptr(NULL) {}
                ~terrain_cache_manager() { delete ptr; }
                t_translation::t_match *ptr;
        };
+
+       struct cfg_isor {
+               bool operator() (std::pair<const std::string*,const config*> 
&val) {
+                       return *(val.first) == "or";
+               }
+       };
+
 } //end anonymous namespace
 
 bool gamemap::terrain_matches_filter(const gamemap::location& loc, const 
vconfig& cfg, 
@@ -589,16 +597,45 @@
                matches = terrain_matches_internal(*i, cfg, game_status, units, 
flat_tod, false, tcm.ptr);
                ++loop_count;
        }
-       if(!matches) return false;
-
-       //handle [not]
-       const vconfig::child_list& nots = cfg.get_children("not");
-       for(vconfig::child_list::const_iterator j = nots.begin(); j != 
nots.end(); ++j) {
-               if(terrain_matches_filter(loc, *j, game_status, units, 
flat_tod, max_loop)) {
+
+       //handle [and], [or], and [not] with in-order precedence
+       config::all_children_iterator cond = cfg.get_config().ordered_begin();
+       config::all_children_iterator cond_end = cfg.get_config().ordered_end();
+       int ors_left = std::count_if(cond, cond_end, cfg_isor());
+       while(cond != cond_end)
+       {
+               //if there are no matches or [or] conditions left, go ahead and 
return false
+               if(!matches && ors_left <= 0) {
                        return false;
                }
-       }
-       return true;
+
+               const std::string& cond_name = *((*cond).first);
+               const vconfig cond_filter(&(*((*cond).second)));
+
+               //handle [and]
+               if(cond_name == "and")
+               {
+                       matches = matches &&
+                               terrain_matches_filter(loc, cond_filter, 
game_status, units, flat_tod, max_loop);
+               }
+               //handle [or]
+               else if(cond_name == "or")
+               {
+                       matches = matches ||
+                               terrain_matches_filter(loc, cond_filter, 
game_status, units, flat_tod, max_loop);
+                       --ors_left;
+               }
+               //handle [not]
+               else if(cond_name == "not")
+               {
+                       matches = matches &&
+                               !terrain_matches_filter(loc, cond_filter, 
game_status, units, flat_tod, max_loop);
+               }
+
+               ++cond;
+       }
+
+       return matches;
 }
 
 bool gamemap::terrain_matches_internal(const gamemap::location& loc, const 
vconfig& cfg, 
@@ -779,13 +816,7 @@
 
        return terrainFrequencyCache_;
 }
-namespace {
-       struct cfg_isor {
-               bool operator() (std::pair<const std::string*,const config*> 
&val) {
-                       return *(val.first) == "or";
-               }
-       };
-}
+
 void gamemap::get_locations(std::set<gamemap::location>& locs, const vconfig& 
filter,
                const gamestatus& game_status, const unit_map& units, const 
bool flat_tod,
                const size_t max_loop) const
@@ -833,7 +864,7 @@
                //handle [and]
                if(cond_name == "and") {
                        std::set<gamemap::location> intersect_hexes;
-                       get_locations(intersect_hexes, cond_filter, 
game_status, units, flat_tod);
+                       get_locations(intersect_hexes, cond_filter, 
game_status, units, flat_tod, max_loop);
                        std::set<gamemap::location>::iterator intersect_itor = 
locs.begin();
                        while(intersect_itor != locs.end()) {
                                if(intersect_hexes.find(*intersect_itor) == 
locs.end()) {
@@ -857,7 +888,7 @@
                //handle [not]
                else if(cond_name == "not") {
                        std::set<gamemap::location> removal_hexes;
-                       get_locations(removal_hexes, cond_filter, game_status, 
units, flat_tod);
+                       get_locations(removal_hexes, cond_filter, game_status, 
units, flat_tod, max_loop);
                        std::set<gamemap::location>::iterator erase_itor = 
removal_hexes.begin();
                        while(erase_itor != removal_hexes.end()) {
                                locs.erase(*erase_itor++);


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

Reply via email to