Make default_base work also for fill/new map/resize.

Cleaned up some of the terrain merging code while on it.
This commit is contained in:
Moritz Göbelbecker 2008-05-18 12:53:14 +00:00
parent d434b8d2ce
commit 770b3dd989
5 changed files with 57 additions and 78 deletions

View file

@ -582,8 +582,11 @@ void map_editor::edit_set_start_pos() {
}
void map_editor::perform_flood_fill(const t_translation::t_terrain fill_with) {
t_translation::t_terrain fill_with_final = map_.get_terrain_info(fill_with).terrain_with_default_base();
terrain_log log;
flood_fill(map_, selected_hex_, fill_with, &log);
flood_fill(map_, selected_hex_, fill_with_final, &log);
map_undo_action action;
for (terrain_log::iterator it = log.begin(); it != log.end(); it++) {
action.add_terrain((*it).second, palette_.selected_fg_terrain(),
@ -607,7 +610,9 @@ void map_editor::edit_quit() {
}
void map_editor::edit_new_map() {
const std::string map = new_map_dialog(gui_, palette_.selected_bg_terrain(),
t_translation::t_terrain bg_fill = map_.get_terrain_info(palette_.selected_bg_terrain()).terrain_with_default_base();
const std::string map = new_map_dialog(gui_, bg_fill,
changed_since_save(), game_config_);
if (map != "") {
num_operations_since_save_ = 0;
@ -732,9 +737,10 @@ void map_editor::edit_resize() {
// before the map gets modified.
const std::string old_data = map_.write();
t_translation::t_terrain bg_fill = map_.get_terrain_info(palette_.selected_bg_terrain()).terrain_with_default_base();
const std::string resized_map =
resize_map(map_, width, height, x_offset, y_offset,
do_expand, palette_.selected_bg_terrain());
do_expand, bg_fill);
if (resized_map != "") {
map_undo_action action;
@ -1215,26 +1221,24 @@ void map_editor::draw_terrain(const t_translation::t_terrain terrain,
const std::vector<gamemap::location> &hexes, const bool one_layer_only)
{
map_undo_action undo_action;
t_translation::t_terrain final_terrain = terrain;
if(!one_layer_only) {
final_terrain = map_.get_terrain_info(terrain).terrain_with_default_base();
}
for(std::vector<gamemap::location>::const_iterator it = hexes.begin();
it != hexes.end(); ++it) {
const t_translation::t_terrain old_terrain = map_.get_terrain(*it);
if(terrain != old_terrain) {
undo_action.add_terrain(old_terrain, terrain, *it);
if (terrain.base == t_translation::NO_LAYER) {
map_.set_overlay(*it, terrain);
const terrain_type& t_info = map_.get_terrain_info(terrain);
if (!one_layer_only && t_info.default_base() != t_translation::NONE_TERRAIN) {
map_.set_base(*it, t_info.default_base());
}
if(final_terrain != old_terrain) {
undo_action.add_terrain(old_terrain, final_terrain, *it);
if (final_terrain.base == t_translation::NO_LAYER) {
map_.set_overlay(*it, final_terrain);
}
else if (one_layer_only) {
map_.set_base(*it, terrain);
map_.set_base(*it, final_terrain);
}
else {
map_.set_terrain(*it, terrain);
map_.set_terrain(*it, final_terrain);
}
// always rebuild localy to show the drawing progress

View file

@ -412,22 +412,11 @@ void gamemap::read(const std::string& data)
// Is the terrain valid?
if(tcodeToTerrain_.count(tiles_[x][y]) == 0) {
const std::map<t_translation::t_terrain, terrain_type>::const_iterator base_iter =
tcodeToTerrain_.find(t_translation::t_terrain(tiles_[x][y].base, t_translation::NO_LAYER));
const std::map<t_translation::t_terrain, terrain_type>::const_iterator overlay_iter =
tcodeToTerrain_.find(t_translation::t_terrain(t_translation::NO_LAYER, tiles_[x][y].overlay));
if(base_iter == tcodeToTerrain_.end() || overlay_iter == tcodeToTerrain_.end()) {
if(!try_merge_terrains(tiles_[x][y])) {
ERR_CF << "Illegal character in map: (" << t_translation::write_terrain_code(tiles_[x][y])
<< ") '" << tiles_[x][y] << "'\n";
throw incorrect_format_exception("Illegal character found in map. The scenario cannot be loaded.");
}
terrain_type new_terrain(base_iter->second, overlay_iter->second);
terrainList_.push_back(new_terrain.number());
tcodeToTerrain_.insert(std::pair<t_translation::t_terrain, terrain_type>(
new_terrain.number(), new_terrain));
}
// Is it a village?
@ -733,6 +722,10 @@ void gamemap::set_terrain(const gamemap::location& loc, const t_translation::t_t
return;
}
if(!try_merge_terrains(terrain)) {
return;
}
if(on_board(loc, false)) {
const bool old_village = is_village(loc);
const bool new_village = is_village(terrain);
@ -762,32 +755,7 @@ void gamemap::set_overlay(const gamemap::location& loc, const t_translation::t_t
return;
}
//check if base only is a valid terrain
const std::map<t_translation::t_terrain, terrain_type>::const_iterator base_iter =
tcodeToTerrain_.find(t_translation::t_terrain(tiles_[loc.x + border_size_][loc.y + border_size_].base, t_translation::NO_LAYER));
//check if overlay only is a valid terrain
const std::map<t_translation::t_terrain, terrain_type>::const_iterator overlay_iter =
tcodeToTerrain_.find(t_translation::t_terrain(t_translation::NO_LAYER, terrain.overlay));
//check if base^overlay is already a valid terrain
const std::map<t_translation::t_terrain, terrain_type>::const_iterator all_iter =
tcodeToTerrain_.find(t_translation::t_terrain(tiles_[loc.x + border_size_][loc.y + border_size_].base, terrain.overlay));
// if neither, return
if((base_iter == tcodeToTerrain_.end() || overlay_iter == tcodeToTerrain_.end())
&& all_iter == tcodeToTerrain_.end()) {
return;
}
//Create new terrain
if (all_iter == tcodeToTerrain_.end()) {
terrain_type new_terrain(base_iter->second, overlay_iter->second);
terrainList_.push_back(new_terrain.number());
tcodeToTerrain_.insert(std::pair<t_translation::t_terrain, terrain_type>(
new_terrain.number(), new_terrain));
}
set_terrain(loc, t_translation::t_terrain(tiles_[loc.x + border_size_][loc.y + border_size_].base, terrain.overlay));
}
void gamemap::set_base(const gamemap::location& loc, const t_translation::t_terrain terrain)
@ -797,32 +765,7 @@ void gamemap::set_base(const gamemap::location& loc, const t_translation::t_terr
return;
}
//check if base only is a valid terrain
const std::map<t_translation::t_terrain, terrain_type>::const_iterator base_iter =
tcodeToTerrain_.find(t_translation::t_terrain(terrain.base, t_translation::NO_LAYER));
//check if overlay only is a valid terrain
const std::map<t_translation::t_terrain, terrain_type>::const_iterator overlay_iter =
tcodeToTerrain_.find(t_translation::t_terrain(t_translation::NO_LAYER, tiles_[loc.x + border_size_][loc.y + border_size_].overlay));
//check if base^overlay is already a valid terrain
const std::map<t_translation::t_terrain, terrain_type>::const_iterator all_iter =
tcodeToTerrain_.find(t_translation::t_terrain(terrain.base, tiles_[loc.x + border_size_][loc.y + border_size_].overlay));
// if neither, return
if((base_iter == tcodeToTerrain_.end() || overlay_iter == tcodeToTerrain_.end())
&& all_iter == tcodeToTerrain_.end()) {
return;
}
//Create new terrain
if (all_iter == tcodeToTerrain_.end()) {
terrain_type new_terrain(base_iter->second, overlay_iter->second);
terrainList_.push_back(new_terrain.number());
tcodeToTerrain_.insert(std::pair<t_translation::t_terrain, terrain_type>(
new_terrain.number(), new_terrain));
}
set_terrain(loc, t_translation::t_terrain(terrain.base, tiles_[loc.x + border_size_][loc.y + border_size_].overlay));
}
@ -889,3 +832,24 @@ const std::map<t_translation::t_terrain, size_t>& gamemap::get_weighted_terrain_
return terrainFrequencyCache_;
}
bool gamemap::try_merge_terrains(const t_translation::t_terrain terrain) {
if(tcodeToTerrain_.count(terrain) == 0) {
const std::map<t_translation::t_terrain, terrain_type>::const_iterator base_iter =
tcodeToTerrain_.find(t_translation::t_terrain(terrain.base, t_translation::NO_LAYER));
const std::map<t_translation::t_terrain, terrain_type>::const_iterator overlay_iter =
tcodeToTerrain_.find(t_translation::t_terrain(t_translation::NO_LAYER, terrain.overlay));
if(base_iter == tcodeToTerrain_.end() || overlay_iter == tcodeToTerrain_.end()) {
return false;
}
terrain_type new_terrain(base_iter->second, overlay_iter->second);
terrainList_.push_back(new_terrain.number());
tcodeToTerrain_.insert(std::pair<t_translation::t_terrain, terrain_type>(
new_terrain.number(), new_terrain));
return true;
}
return true; // Terrain already exists, nothing to do
}

View file

@ -269,6 +269,10 @@ private:
const t_translation::t_list operator[](int index) const
{ return tiles_[index + border_size_]; }
//! Tries to find out if "terrain" can be created by combining two existing terrains
//! Will add the resulting terrain to the terrain list if successfull
bool try_merge_terrains(const t_translation::t_terrain terrain);
t_translation::t_list terrainList_;
std::map<t_translation::t_terrain, terrain_type> tcodeToTerrain_;
std::vector<location> villages_;

View file

@ -223,6 +223,12 @@ terrain_type::terrain_type(const terrain_type& base, const terrain_type& overlay
}
t_translation::t_terrain terrain_type::terrain_with_default_base() const {
if(overlay_ && editor_default_base_ != t_translation::NONE_TERRAIN) {
return t_translation::t_terrain(editor_default_base_.base, number_.overlay);
}
return number_;
}
void create_terrain_maps(const std::vector<config*>& cfgs,
t_translation::t_list& terrain_list,

View file

@ -69,6 +69,7 @@ public:
bool is_combined() const { return combined_; }
t_translation::t_terrain default_base() const { return editor_default_base_; }
t_translation::t_terrain terrain_with_default_base() const;
private:
//! The image used in the minimap