Fix bug in terrain matching

Remove (unused and unneccessary) support for wildcards in source terrain
This commit is contained in:
Moritz Göbelbecker 2007-07-23 21:08:54 +00:00
parent 1f42924397
commit 5a4b7663c2
3 changed files with 37 additions and 73 deletions

View file

@ -43,23 +43,6 @@ static const int UNITPOS = 36 + 18;
*/
static const int BASE_Y_INTERVAL = 100000;
static t_translation::t_letter builder_letter(const t_translation::t_letter& letter)
{
t_translation::t_letter result(letter);
if(result == t_translation::STAR || result == t_translation::NOT) {
return result;
}
if(result.overlay == t_translation::NO_LAYER &&
result.base != t_translation::WILDCARD) {
result.overlay = t_translation::WILDCARD;
}
return result;
}
terrain_builder::rule_image::rule_image(int layer, int x, int y, bool global_image) :
layer(layer), basex(x), basey(y), global_image(global_image)
{}
@ -611,7 +594,7 @@ void terrain_builder::parse_mapstring(const std::string &mapstring,
} else if (terrain.overlay != 0 ) {
anchors.insert(std::pair<int, gamemap::location>(terrain.overlay, gamemap::location(x, y)));
} else if (terrain.base == t_translation::TB_STAR) {
add_constraints(br.constraints, gamemap::location(x, y), builder_letter(t_translation::STAR), global_images);
add_constraints(br.constraints, gamemap::location(x, y), t_translation::STAR, global_images);
} else {
ERR_NG << "Invalid terrain (" << t_translation::write_letter(terrain) << ") in builder map\n";
wassert(false);
@ -789,8 +772,8 @@ bool terrain_builder::rule_matches(const terrain_builder::building_rule &rule,
if(!tile_map_.on_map(tloc)) {
return false;
}
if(!terrain_matches(builder_letter(map_.get_terrain(tloc)), cons->second.terrain_types_match)) {
//std::cout << "testing..." << builder_letter(map_.get_terrain(tloc))
if(!terrain_matches(map_.get_terrain(tloc), cons->second.terrain_types_match)) {
return false;
}
}
@ -893,10 +876,10 @@ int terrain_builder::get_constraint_size(const building_rule& rule, const terrai
if(types.empty()) {
return INT_MAX;
}
if(types.front() == builder_letter(t_translation::NOT)) {
if(types.front() == t_translation::NOT) {
return INT_MAX;
}
if(std::find(types.begin(), types.end(), builder_letter(t_translation::STAR)) != types.end()) {
if(std::find(types.begin(), types.end(), t_translation::STAR) != types.end()) {
return INT_MAX;
}
// as soon as the list has 1 wildcard we bail out
@ -954,7 +937,7 @@ void terrain_builder::build_terrains()
for(int x = -1; x <= map_.x(); ++x) {
for(int y = -1; y <= map_.y(); ++y) {
const gamemap::location loc(x,y);
const t_translation::t_letter t = builder_letter(map_.get_terrain(loc));
const t_translation::t_letter t = map_.get_terrain(loc);
terrain_by_type_[t].push_back(loc);
gamemap::location adj[6];
@ -966,10 +949,10 @@ void terrain_builder::build_terrains()
tile_map_[loc].adjacents[0] = t;
for(i = 0; i < 6; ++i) {
//updates the list of adjacents for this tile
tile_map_[loc].adjacents[i+1] = builder_letter(map_.get_terrain(adj[i]));
tile_map_[loc].adjacents[i+1] = map_.get_terrain(adj[i]);
//determines if this tile is a border tile
if(builder_letter(map_.get_terrain(adj[i])) != t) {
if(map_.get_terrain(adj[i]) != t) {
border = true;
}

View file

@ -389,10 +389,6 @@ bool terrain_matches(const t_letter& src, const t_list& dest)
return false;
}
const t_letter src_mask = get_mask_(src);
const t_letter masked_src = (src & src_mask);
const bool src_has_wildcard = has_wildcard(src);
#if 0
std::cerr << std::hex << "src = " << src.base << "^" << src.overlay << "\t"
<< src_mask.base << "^" << src_mask.overlay << "\t"
@ -422,13 +418,6 @@ bool terrain_matches(const t_letter& src, const t_list& dest)
return result;
}
// does the source wildcard match
if(src_has_wildcard &&
(itor->base & src_mask.base) == masked_src.base &&
(itor->overlay & src_mask.overlay) == masked_src.overlay) {
return result;
}
// does the destination wildcard match
const t_letter dest_mask = get_mask_(*itor);
const t_letter masked_dest = (*itor & dest_mask);
@ -446,9 +435,9 @@ bool terrain_matches(const t_letter& src, const t_list& dest)
return result;
}
if(src_has_wildcard && src.overlay == 0 && itor->overlay == NO_LAYER &&
((itor->base & src_mask.base) == masked_src.base )) {
return result;
// Special case for NO_LAYER
if(itor->overlay == 0 && src.overlay == NO_LAYER && src.base == itor->base) {
return result;
}
if(dest_has_wildcard && itor->overlay == 0 && src.overlay == NO_LAYER &&
@ -487,10 +476,6 @@ bool terrain_matches(const t_letter& src, const t_match& dest)
return false;
}
const t_letter src_mask = get_mask_(src);
const t_letter masked_src = (src & src_mask);
const bool src_has_wildcard = has_wildcard(src);
bool result = true;
// try to match the terrains if matched jump out of the loop.
@ -518,26 +503,17 @@ bool terrain_matches(const t_letter& src, const t_match& dest)
if(*terrain_itor == src) {
return result;
}
// does the source wildcard match
if(src_has_wildcard &&
(terrain_itor->base & src_mask.base) == masked_src.base &&
(terrain_itor->overlay & src_mask.overlay) == masked_src.overlay) {
return result;
}
// does the destination wildcard match
if(dest.has_wildcard &&
(src.base & dest.mask[i].base) == dest.masked_terrain[i].base &&
(src.overlay & dest.mask[i].overlay) == dest.masked_terrain[i].overlay) {
return result;
}
// does the source have a wildcard and an empty overlay and the destination
// no overlay, we need to check the part base for a match
if(src_has_wildcard && src.overlay == 0 && terrain_itor->overlay == NO_LAYER &&
((terrain_itor->base & src_mask.base) == masked_src.base )) {
return result;
// Special case for NO_LAYER
if(terrain_itor->overlay == 0 && src.overlay == NO_LAYER && src.base == terrain_itor->base) {
return result;
}
// does the desination have a wildcard and an empty overlay and the source

View file

@ -238,53 +238,58 @@ namespace t_translation {
std::string write_game_map(const t_map& map, std::map<int, coordinate> starting_positions = std::map<int, coordinate>());
/**
* Tests whether a certain terrain matches a list of terrains the terrains can
* Tests whether a specific terrain matches a list of expressions. The list can
* use wildcard matching with *. It also has an inversion function. When a !
* is found the result of the match is inverted. The matching stops at the
* first match (regardless of the ! found) the data is match from start to end.
*
* Example:
* W*, Ww does match and returns true
* W*, {!, Ww} does match and returns false (due to the !)
* Ww, WW doesn't match and return false
* Ww, W* does match and returns true
* Ww, {!, W*} does match and returns false (due to the !)
* WW, Ww doesn't match and return false
*
* Multilayer rules:
* If a terrain has multiple layers a wildcard on the first layer also
* matches the following layer unless a caret is used, in this case
* there is no need to put anything behind the caret
* If a terrain has multiple layers, each layer will be matched seperately,
* returning true only if both layers match.
*
* Example:
* A* matches Abcd but also Abcd^Abcd
* A*^* matches Abcd but also Abcd^Abcd
* A*^ matches Abcd but *not* Abcd^Abcd
* A*^Abcd does not match Abcd but matches Abcd^Abcd
*
* @param src the value to match (may also contain the wildcard)
* @param dest the list of values to match against
* Note: If an expression doesn't specify a second layer (i.e. it contains no
* caret) the second layer will be filled in with a default value (See read_letter
* and read_list).
*
* In the terrain building code, the second layer will default to the wildcard, so
* both A* and A*^* will match Abcd^Abcd
*
* @param src the value to match (may not contain wildcards)
* @param dest the list of expressions to match against
*
* @returns the result of the match (depending on the !'s)
*/
bool terrain_matches(const t_letter& src, const t_list& dest);
/**
* Tests whether a certain terrain matches another terrain, for matching
* Tests whether a specific terrain matches an expression, for matching
* rules see above.
*
* @param src the value to match (may also contain the wildcard)
* @param dest the value to match against
* @param src the value to match (may not contain wildcards)
* @param dest the expression to match against
*
* @returns the result of the match (depending on the !'s)
*/
bool terrain_matches(const t_letter& src, const t_letter& dest);
/**
* Tests whether a certain terrain matches another terrain, for matching
* Tests whether a certain terrain matches a list of expressions, for matching
* rules see above. The matching requires some bit mask which impose a
* certain overhead. This version uses a cache to cache the masks so if
* a list needs to be matched often this version is preferred.
*
* @param src the value to match (may also contain the wildcard)
* @param dest the value to match against
* @param src the value to match (may not contain wildcards)
* @param dest the cached list of expressions to match against
*
* @returns the result of the match (depending on the !'s)
*/