Fix bug in terrain matching
Remove (unused and unneccessary) support for wildcards in source terrain
This commit is contained in:
parent
1f42924397
commit
5a4b7663c2
3 changed files with 37 additions and 73 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue