void terrain_builder::apply_rule(const terrain_builder::building_rule &rule, const map_location &loc)
{
	for(constraint_set::const_iterator constraint = rule.constraints.begin();
			constraint != rule.constraints.end(); ++constraint) {

		rule_imagelist::const_iterator img;
		const map_location tloc = loc.legacy_sum(constraint->second.loc);
		if(!tile_map_.on_map(tloc)) {
			return;
		}

		tile& btile = tile_map_[tloc];

		// We want to order the images by layer first and base-y second,
		// so we sort by layer*BASE_Y_INTERVAL + BASE_Y_INTERVAL/2 + basey
		// Thus, allowed values for basey are from -50000 to 49999
		for(img = constraint->second.images.begin(); img != constraint->second.images.end(); ++img) {
			btile.images.insert(std::pair<int, const rule_image*>(
									img->layer*BASE_Y_INTERVAL + BASE_Y_INTERVAL/2 + img->basey, &*img));
		}

		// Sets flags
		for(std::vector<std::string>::const_iterator itor = constraint->second.set_flag.begin();
				itor != constraint->second.set_flag.end(); ++itor) {
			btile.flags.insert(*itor);
		}

	}
}
bool terrain_builder::rule_matches(const terrain_builder::building_rule &rule,
		const map_location &loc, const int rule_index, const constraint_set::const_iterator type_checked) const
{
	if(rule.location_constraints.valid() && rule.location_constraints != loc) {
		return false;
	}

	if(rule.probability != -1) {
		unsigned int a = (loc.x + 92872973) ^ 918273;
		unsigned int b = (loc.y + 1672517) ^ 128123;
		unsigned int c = (rule_index + 127390) ^ 13923787;
		unsigned int abc = a*b*c + a*b + b*c + a*c + a + b + c;
		unsigned int random = (abc*abc) % 100;

		if(random > static_cast<unsigned int>(rule.probability)) {
			return false;
		}
	}

	for(constraint_set::const_iterator cons = rule.constraints.begin();
			cons != rule.constraints.end(); ++cons) {

		// Translated location
		const map_location tloc = loc.legacy_sum(cons->second.loc);

		if(!tile_map_.on_map(tloc)) {
			return false;
		}

		//std::cout << "testing..." << builder_letter(map().get_terrain(tloc))

		// check if terrain matches except if we already know that it does
		if(cons != type_checked &&
				!terrain_matches(map().get_terrain(tloc), cons->second.terrain_types_match)) {
			return false;
		}

		const tile& btile = tile_map_[tloc];

		std::vector<std::string>::const_iterator itor;
		for(itor = cons->second.no_flag.begin(); itor != cons->second.no_flag.end(); ++itor) {

			// If a flag listed in "no_flag" is present, the rule does not match
			if(btile.flags.find(*itor) != btile.flags.end()) {
				return false;
			}
		}
		for(itor = cons->second.has_flag.begin(); itor != cons->second.has_flag.end(); ++itor) {

			// If a flag listed in "has_flag" is not present, this rule does not match
			if(btile.flags.find(*itor) == btile.flags.end()) {
				return false;
			}
		}
	}

	return true;
}