00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.hpp"
00016
00017 #include "config.hpp"
00018 #include "gettext.hpp"
00019 #include "log.hpp"
00020 #include "util.hpp"
00021 #include "terrain.hpp"
00022 #include "serialization/string_utils.hpp"
00023 #include "tstring.hpp"
00024 #include "wml_exception.hpp"
00025
00026 #include <algorithm>
00027 #include <cstdlib>
00028 #include <iostream>
00029
00030
00031 terrain_type::terrain_type() :
00032 minimap_image_("void"),
00033 minimap_image_overlay_("void"),
00034 editor_image_("void"),
00035 id_(),
00036 name_(),
00037 number_(t_translation::VOID_TERRAIN),
00038 mvt_type_(1, t_translation::VOID_TERRAIN),
00039 def_type_(1, t_translation::VOID_TERRAIN),
00040 union_type_(1, t_translation::VOID_TERRAIN),
00041 height_adjust_(0),
00042 submerge_(0.0),
00043 light_modification_(0),
00044 heals_(0),
00045 income_description_(),
00046 income_description_ally_(),
00047 income_description_enemy_(),
00048 income_description_own_(),
00049 editor_group_(),
00050 village_(false),
00051 castle_(false),
00052 keep_(false),
00053 overlay_(false),
00054 combined_(false),
00055 editor_default_base_(t_translation::VOID_TERRAIN)
00056 {}
00057
00058 terrain_type::terrain_type(const config& cfg) :
00059 minimap_image_(cfg["symbol_image"]),
00060 minimap_image_overlay_("void"),
00061 editor_image_(cfg["editor_image"]),
00062 id_(cfg["id"]),
00063 name_(cfg["name"]),
00064 number_(t_translation::read_terrain_code(cfg["string"])),
00065 mvt_type_(),
00066 def_type_(),
00067 union_type_(),
00068 height_adjust_(atoi(cfg["unit_height_adjust"].c_str())),
00069 submerge_(atof(cfg["submerge"].c_str())),
00070 light_modification_(atoi(cfg["light"].c_str())),
00071 heals_(lexical_cast_default<int>(cfg["heals"], 0)),
00072 income_description_(),
00073 income_description_ally_(),
00074 income_description_enemy_(),
00075 income_description_own_(),
00076 editor_group_(cfg["editor_group"]),
00077 village_(utils::string_bool(cfg["gives_income"])),
00078 castle_(utils::string_bool(cfg["recruit_onto"])),
00079 keep_(utils::string_bool(cfg["recruit_from"])),
00080 editor_default_base_(t_translation::read_terrain_code(cfg["default_base"]))
00081 {
00082
00083
00084
00085
00086 #if 0
00087 VALIDATE(number_ != t_translation::NONE_TERRAIN,
00088 missing_mandatory_wml_key("terrain", "string"));
00089 VALIDATE(!minimap_image_.empty(),
00090 missing_mandatory_wml_key("terrain", "symbol_image", "string",
00091 t_translation::write_terrain_code(number_)));
00092 VALIDATE(!name_.empty(),
00093 missing_mandatory_wml_key("terrain", "name", "string",
00094 t_translation::write_terrain_code(number_)));
00095 #endif
00096
00097 if(editor_image_.empty()) {
00098 editor_image_ = minimap_image_;
00099 }
00100
00101 combined_ = false;
00102 overlay_ = (number_.base == t_translation::NO_LAYER) ? true : false;
00103
00104 mvt_type_.push_back(number_);
00105 def_type_.push_back(number_);
00106 const t_translation::t_list& alias = t_translation::read_list(cfg["aliasof"]);
00107 if(!alias.empty()) {
00108 mvt_type_ = alias;
00109 def_type_ = alias;
00110 }
00111
00112 const t_translation::t_list& mvt_alias = t_translation::read_list(cfg["mvt_alias"]);
00113 if(!mvt_alias.empty()) {
00114 mvt_type_ = mvt_alias;
00115 }
00116
00117 const t_translation::t_list& def_alias = t_translation::read_list(cfg["def_alias"]);
00118 if(!def_alias.empty()) {
00119 def_type_ = def_alias;
00120 }
00121 union_type_ = mvt_type_;
00122 union_type_.insert( union_type_.end(), def_type_.begin(), def_type_.end() );
00123
00124
00125 union_type_.erase(std::remove(union_type_.begin(), union_type_.end(),
00126 t_translation::MINUS), union_type_.end());
00127
00128 union_type_.erase(std::remove(union_type_.begin(), union_type_.end(),
00129 t_translation::PLUS), union_type_.end());
00130
00131
00132 std::sort(union_type_.begin(),union_type_.end());
00133 union_type_.erase(std::unique(union_type_.begin(), union_type_.end()), union_type_.end());
00134
00135 #ifdef USE_TINY_GUI
00136 height_adjust_ /= 2;
00137 #endif
00138
00139
00140
00141 if(village_) {
00142 income_description_ = cfg["income_description"];
00143 if(income_description_ == "") {
00144 income_description_ = _("Village");
00145 }
00146
00147 income_description_ally_ = cfg["income_description_ally"];
00148 if(income_description_ally_ == "") {
00149 income_description_ally_ = _("Allied village");
00150 }
00151
00152 income_description_enemy_ = cfg["income_description_enemy"];
00153 if(income_description_enemy_ == "") {
00154 income_description_enemy_ = _("Enemy village");
00155 }
00156
00157 income_description_own_ = cfg["income_description_own"];
00158 if(income_description_own_ == "") {
00159 income_description_own_ = _("Owned village");
00160 }
00161 }
00162 }
00163
00164 terrain_type::terrain_type(const terrain_type& base, const terrain_type& overlay) :
00165 overlay_(false),
00166 combined_(true)
00167 {
00168 number_ = t_translation::t_terrain(base.number_.base, overlay.number_.overlay);
00169
00170 minimap_image_ = base.minimap_image_;
00171 minimap_image_overlay_ = overlay.minimap_image_;
00172 editor_image_ = overlay.editor_image_;
00173
00174 name_ = overlay.name_;
00175 id_ = base.id_+"^"+overlay.id_;
00176
00177 mvt_type_ = overlay.mvt_type_;
00178 def_type_ = overlay.def_type_;
00179
00180 merge_alias_lists(mvt_type_, base.mvt_type_);
00181 merge_alias_lists(def_type_, base.def_type_);
00182
00183 union_type_ = mvt_type_;
00184 union_type_.insert( union_type_.end(), def_type_.begin(), def_type_.end() );
00185
00186
00187 union_type_.erase(std::remove(union_type_.begin(), union_type_.end(),
00188 t_translation::MINUS), union_type_.end());
00189
00190 union_type_.erase(std::remove(union_type_.begin(), union_type_.end(),
00191 t_translation::PLUS), union_type_.end());
00192
00193
00194 std::sort(union_type_.begin(),union_type_.end());
00195 union_type_.erase(std::unique(union_type_.begin(), union_type_.end()), union_type_.end());
00196
00197
00198 height_adjust_ = overlay.height_adjust_;
00199 submerge_ = overlay.submerge_;
00200 light_modification_ = base.light_modification_ + overlay.light_modification_;
00201
00202 heals_ = maximum<int>(base.heals_, overlay.heals_);
00203
00204 village_ = base.village_ | overlay.village_;
00205 castle_ = base.castle_ | overlay.castle_;
00206 keep_ = base.keep_ | overlay.keep_;
00207
00208
00209 if(base.village_) {
00210 income_description_ = base.income_description_;
00211 income_description_ally_ = base.income_description_ally_;
00212 income_description_enemy_ = base.income_description_enemy_;
00213 income_description_own_ = base.income_description_own_;
00214 }
00215 else if (overlay.village_) {
00216 income_description_ = overlay.income_description_;
00217 income_description_ally_ = overlay.income_description_ally_;
00218 income_description_enemy_ = overlay.income_description_enemy_;
00219 income_description_own_ = overlay.income_description_own_;
00220 }
00221
00222 editor_group_ = "";
00223
00224 }
00225
00226 t_translation::t_terrain terrain_type::terrain_with_default_base() const {
00227 if(overlay_ && editor_default_base_ != t_translation::NONE_TERRAIN) {
00228 return t_translation::t_terrain(editor_default_base_.base, number_.overlay);
00229 }
00230 return number_;
00231 }
00232
00233 void create_terrain_maps(const std::vector<config*>& cfgs,
00234 t_translation::t_list& terrain_list,
00235 std::map<t_translation::t_terrain, terrain_type>& letter_to_terrain)
00236 {
00237 for(std::vector<config*>::const_iterator i = cfgs.begin();
00238 i != cfgs.end(); ++i) {
00239 terrain_type terrain(**i);
00240 terrain_list.push_back(terrain.number());
00241 letter_to_terrain.insert(std::pair<t_translation::t_terrain, terrain_type>(
00242 terrain.number(),terrain));
00243 }
00244 }
00245
00246 void merge_alias_lists(t_translation::t_list& first, const t_translation::t_list& second)
00247 {
00248
00249
00250 bool revert = (first.front() == t_translation::MINUS ? true : false);
00251 t_translation::t_list::iterator i;
00252
00253 for(i = first.begin(); i != first.end(); i++) {
00254 if(*i == t_translation::PLUS) {
00255 revert = false;
00256 continue;
00257 } else if(*i == t_translation::MINUS) {
00258 revert = true;
00259 continue;
00260 }
00261
00262 if(*i == t_translation::BASE) {
00263 t_translation::t_list::iterator insert_it = first.erase(i);
00264
00265
00266 if(revert) {
00267 insert_it = first.insert(insert_it, t_translation::PLUS);
00268 insert_it++;
00269 insert_it = first.insert(insert_it, t_translation::MINUS);
00270 }
00271 else {
00272
00273 insert_it = first.insert(insert_it, t_translation::PLUS);
00274 }
00275
00276 first.insert(insert_it, second.begin(), second.end());
00277
00278 break;
00279 }
00280 }
00281
00282 }