mail[Wesnoth-commits] r20096 - in /trunk: changelog src/terrain_filter.cpp src/unit.cpp


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

Header


Content

Posted by patrick_X99 on September 04, 2007 - 05:40:
Author: sapient
Date: Tue Sep  4 05:39:48 2007
New Revision: 20096

URL: http://svn.gna.org/viewcvs/wesnoth?rev=20096&view=rev
Log:
* now [filter_adjacent] is supported in SLF
* clean up the [filter_adjacent] code in SUF

Modified:
    trunk/changelog
    trunk/src/terrain_filter.cpp
    trunk/src/unit.cpp

Modified: trunk/changelog
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=20096&r1=20095&r2=20096&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Tue Sep  4 05:39:48 2007
@@ -16,6 +16,7 @@
    * show observer team chat messages in the 'Chat Log' window
  * WML engine:
    * now tag [filter_adjacent] is supported in the Standard Unit Filter
+   * now tag [filter_adjacent] is supported in the Standard Location Filter
    * remove the unused [neighbour_unit_filter] animation filter, now that SUF
      does it for us (and better)
    * a minus sign in front of a cardinal direction now reverses it ("-s"="n")

Modified: trunk/src/terrain_filter.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/terrain_filter.cpp?rev=20096&r1=20095&r2=20096&view=diff
==============================================================================
--- trunk/src/terrain_filter.cpp (original)
+++ trunk/src/terrain_filter.cpp Tue Sep  4 05:39:48 2007
@@ -20,6 +20,7 @@
 #include "log.hpp"
 #include "map.hpp"
 #include "pathfind.hpp"
+#include "terrain_filter.hpp"
 #include "util.hpp"
 #include "variable.hpp"
 #include "wassert.hpp"
@@ -33,19 +34,37 @@
 #define ERR_CF LOG_STREAM(err, config)
 #define LOG_G LOG_STREAM(info, general)
 
+namespace {
+       struct terrain_filter_cache {
+               terrain_filter_cache() : parsed_terrain(NULL), 
adjacent_matches(NULL) {}
+               ~terrain_filter_cache() { 
+                       delete parsed_terrain;
+                       delete adjacent_matches;
+               }
+               t_translation::t_match *parsed_terrain;
+               std::vector< std::set<gamemap::location> > *adjacent_matches;
+               std::vector< std::map<gamemap::location,bool> > 
adjacent_match_cache;
+       };
+
+       struct cfg_isor {
+               bool operator() (std::pair<const std::string*,const config*> 
val) {
+                       return *(val.first) == "or";
+               }
+       };
+} //end anonymous namespace
 
 static bool terrain_matches_internal(const gamemap& map, const 
gamemap::location& loc, const vconfig& cfg,
                const gamestatus& game_status, const unit_map& units, const 
bool flat_tod,
-               const bool ignore_xy, t_translation::t_match*& parsed_terrain)
+               const bool ignore_xy, terrain_filter_cache& cache)
 {
 
        if(cfg.has_attribute("terrain")) {
-               if(parsed_terrain == NULL) {
-                       parsed_terrain = new 
t_translation::t_match(cfg["terrain"]);
-               }
-               if(!parsed_terrain->is_empty) {
+               if(cache.parsed_terrain == NULL) {
+                       cache.parsed_terrain = new 
t_translation::t_match(cfg["terrain"]);
+               }
+               if(!cache.parsed_terrain->is_empty) {
                        const t_translation::t_letter letter = 
map.get_terrain_info(loc).number();
-                       if(!t_translation::terrain_matches(letter, 
*parsed_terrain)) {
+                       if(!t_translation::terrain_matches(letter, 
*cache.parsed_terrain)) {
                                return false;
                        }
                }
@@ -84,6 +103,57 @@
                const unit_map::const_iterator u = units.find(loc);
                if (u == units.end() || 
!u->second.matches_filter(unit_filter, loc, flat_tod))
                        return false;
+       }
+
+       //Allow filtering on adjacent locations
+       if(cfg.has_child("filter_adjacent")) {
+               gamemap::location adjacent[6];
+               get_adjacent_tiles(loc, adjacent);
+               const vconfig::child_list& adj_filt = 
cfg.get_children("filter_adjacent");
+               vconfig::child_list::const_iterator i, i_end, i_begin = 
adj_filt.begin();
+               for (i = i_begin, i_end = adj_filt.end(); i != i_end; ++i) {
+                       int match_count=0;
+                       std::string adj_dirs = (*i).has_attribute("adjacent") 
? (*i)["adjacent"]
+                               : "n,ne,se,s,sw,nw";
+                       static std::vector<gamemap::location::DIRECTION> 
default_dirs
+                               = 
gamemap::location::parse_directions("n,ne,se,s,sw,nw");
+                       std::vector<gamemap::location::DIRECTION> dirs = 
(*i).has_attribute("adjacent")
+                               ? 
gamemap::location::parse_directions((*i)["adjacent"]) : default_dirs;
+                       
std::vector<gamemap::location::DIRECTION>::const_iterator j, j_end = 
dirs.end();
+                       for (j = dirs.begin(); j != j_end; ++j) {
+                               gamemap::location &adj = adjacent[*j];
+                               if(map.on_board(adj)) {
+                                       if(cache.adjacent_matches == NULL) {
+                                               
std::map<gamemap::location,bool>::iterator lookup = 
cache.adjacent_match_cache[i-i_begin].find(adj);
+                                               if(lookup == 
cache.adjacent_match_cache[i-i_begin].end()) {
+                                                       
if(terrain_matches_filter(map,adj,*i,game_status,units,flat_tod)) {
+                                                               
cache.adjacent_match_cache[i-i_begin][adj] = true;
+                                                               ++match_count;
+                                                       } else {
+                                                               
cache.adjacent_match_cache[i-i_begin][adj] = false;
+                                                       }
+                                               } else if(lookup->second) {
+                                                       ++match_count;
+                                               }
+                                       } else 
if((*cache.adjacent_matches)[i-i_begin].find(adj) != 
(*cache.adjacent_matches)[i-i_begin].end()) {
+                                               ++match_count;
+                                       }
+                               }
+                       }
+                       static std::vector<std::pair<int,int> > 
default_counts = utils::parse_ranges("1-6");
+                       std::vector<std::pair<int,int> > counts = 
(*i).has_attribute("count") 
+                               ? utils::parse_ranges((*i)["count"]) : 
default_counts;
+                       std::vector<std::pair<int,int> >::const_iterator 
count, count_end = counts.end();
+                       bool count_matches = false;
+                       for (count = counts.begin(); count != count_end && 
!count_matches; ++count) {
+                               if(count->first <= match_count && match_count 
<= count->second) {
+                                       count_matches = true;
+                               }
+                       }
+                       if(!count_matches) {
+                               return false;
+                       }
+               }
        }
 
        const t_string& t_tod_type = cfg["time_of_day"];
@@ -145,27 +215,15 @@
 }
 
 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";
-               }
-       };
-
        //terrain predicate, returns true if a terrain matches the predicate
-       class terrain_pred : public xy_pred, protected terrain_cache_manager {
+       class terrain_pred : public xy_pred, protected terrain_filter_cache {
        public:
                terrain_pred(const gamemap& map, const vconfig& cfg, const 
gamestatus& game_status,
                        const unit_map& units, const bool flat_tod) : 
map_(map), cfg_(cfg),
                        status_(game_status), units_(units), flat_(flat_tod) 
{}
 
                virtual bool operator()(const gamemap::location& loc) {
-                       return terrain_matches_internal(map_, loc, cfg_, 
status_, units_, flat_, false, ptr);
+                       return terrain_matches_internal(map_, loc, cfg_, 
status_, units_, flat_, false, *this);
                }
        private:
                const gamemap& map_;
@@ -197,9 +255,9 @@
 
                size_t loop_count = 0;
                std::set<gamemap::location>::const_iterator i;
-               terrain_cache_manager tcm;
+               terrain_filter_cache tfc;
                for(i = hexes.begin(); i != hexes.end() && loop_count <= 
max_loop && !matches; ++i) {
-                       matches = terrain_matches_internal(map, *i, cfg, 
game_status, units, flat_tod, false, tcm.ptr);
+                       matches = terrain_matches_internal(map, *i, cfg, 
game_status, units, flat_tod, false, tfc);
                        ++loop_count;
                }
        } else if(cfg["x"] == "recall" && cfg["y"] == "recall"
@@ -283,10 +341,19 @@
        }
 
        //handle location filter
-       terrain_cache_manager tcm;
+       terrain_filter_cache tfc;
+       if(filter.has_child("filter_adjacent")) {
+               tfc.adjacent_matches = new 
std::vector<std::set<gamemap::location> >();
+               const vconfig::child_list& adj_filt = 
filter.get_children("filter_adjacent");
+               for (int i = 0; i < adj_filt.size() && i <= max_loop; ++i) {
+                       std::set<gamemap::location> adj_set;
+                       get_locations(map, adj_set, adj_filt[i], game_status, 
units, flat_tod, max_loop);
+                       tfc.adjacent_matches->push_back(adj_set);
+               }
+       }
        std::vector<gamemap::location>::iterator loc_itor = xy_locs.begin();
        while(loc_itor != xy_locs.end()) {
-               if(terrain_matches_internal(map, *loc_itor, filter, 
game_status, units, flat_tod, true, tcm.ptr)) {
+               if(terrain_matches_internal(map, *loc_itor, filter, 
game_status, units, flat_tod, true, tfc)) {
                        ++loc_itor;
                } else {
                        loc_itor = xy_locs.erase(loc_itor);
@@ -354,6 +421,7 @@
                ++cond;
        }
 
+       /*      
        //restrict the potential number of locations to be returned
        if(locs.size() > max_loop + 1) {
                std::set<gamemap::location>::iterator erase_itor = 
locs.begin();
@@ -362,6 +430,7 @@
                }
                locs.erase(erase_itor, locs.end());
        }
+       */
 }
 
 

Modified: trunk/src/unit.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit.cpp?rev=20096&r1=20095&r2=20096&view=diff
==============================================================================
--- trunk/src/unit.cpp (original)
+++ trunk/src/unit.cpp Tue Sep  4 05:39:48 2007
@@ -989,32 +989,29 @@
                const vconfig::child_list& adj_filt = 
cfg.get_children("filter_adjacent");
                for (i = adj_filt.begin(), i_end = adj_filt.end(); i != 
i_end; ++i) {
                        int match_count=0;
-                       std::string adj_dirs = (*i).has_attribute("adjacent") 
? (*i)["adjacent"]
-                               : "n,ne,se,s,sw,nw";
-                       std::vector<std::string> dirs = 
utils::split(adj_dirs);
-                       std::vector<std::string>::const_iterator j, j_end = 
dirs.end();
+                       static std::vector<gamemap::location::DIRECTION> 
default_dirs
+                               = 
gamemap::location::parse_directions("n,ne,se,s,sw,nw");
+                       std::vector<gamemap::location::DIRECTION> dirs = 
(*i).has_attribute("adjacent")
+                               ? 
gamemap::location::parse_directions((*i)["adjacent"]) : default_dirs;
+                       
std::vector<gamemap::location::DIRECTION>::const_iterator j, j_end = 
dirs.end();
                        for (j = dirs.begin(); j != j_end; ++j) {
-                               gamemap::location::DIRECTION index =
-                                       
gamemap::location::parse_direction(*j);
-                               if (index == gamemap::location::NDIRECTIONS)
+                               unit_map::const_iterator unit_itor = 
units_->find(adjacent[*j]);
+                               if (unit_itor == units_->end() 
+                               || !unit_itor->second.matches_filter(*i, 
unit_itor->first, use_flat_tod)) {
                                        continue;
-                               unit_map::const_iterator unit_itor = 
units_->find(adjacent[index]);
-                               if (unit_itor == units_->end())
-                                       continue;
-                               if (unit_itor->second.matches_filter(*i, 
unit_itor->first, use_flat_tod)
-                               && (!(*i).has_attribute("is_enemy") || 
utils::string_bool((*i)["is_enemy"])
-                               == 
(*gamestatus_->teams)[this->side()-1].is_enemy(unit_itor->second.side()))) {
+                               }
+                               if (!(*i).has_attribute("is_enemy")
+                               || utils::string_bool((*i)["is_enemy"]) == 
(*gamestatus_->teams)[this->side()-1].is_enemy(unit_itor->second.side())) {
                                        ++match_count;
                                }
                        }
-                       std::string count_str = (*i).has_attribute("count") ? 
(*i)["count"]
-                               : "1-6";
-                       std::vector<std::string> counts = 
utils::split(count_str);
-                       j_end = counts.end();
+                       static std::vector<std::pair<int,int> > 
default_counts = utils::parse_ranges("1-6");
+                       std::vector<std::pair<int,int> > counts = 
(*i).has_attribute("count") 
+                               ? utils::parse_ranges((*i)["count"]) : 
default_counts;
+                       std::vector<std::pair<int,int> >::const_iterator 
count, count_end = counts.end();
                        bool count_matches = false;
-                       for (j = counts.begin(); j != j_end && 
!count_matches; ++j) {
-                               std::pair<int,int> count_range = 
utils::parse_range(*j);
-                               if(count_range.first <= match_count && 
match_count <= count_range.second) {
+                       for (count = counts.begin(); count != count_end && 
!count_matches; ++count) {
+                               if(count->first <= match_count && match_count 
<= count->second) {
                                        count_matches = true;
                                }
                        }




Related Messages


Powered by MHonArc, Updated Tue Sep 04 06:20:23 2007