00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef UNIT_TYPES_H_INCLUDED
00015 #define UNIT_TYPES_H_INCLUDED
00016
00017 #include "unit_animation.hpp"
00018 #include "config.hpp"
00019 #include "map.hpp"
00020 #include "race.hpp"
00021 #include "util.hpp"
00022
00023 #include <string>
00024 #include <vector>
00025
00026
00027 class unit_type;
00028 class unit;
00029 class unit_ability_list;
00030 class unit_type_data;
00031 class gamestatus;
00032 class team;
00033
00034
00035
00036 class attack_type
00037 {
00038 public:
00039
00040 attack_type(const config& cfg);
00041 const t_string& name() const { return description_; }
00042 const std::string& id() const { return id_; }
00043 const std::string& type() const { return type_; }
00044 const std::string& icon() const { return icon_; }
00045 const std::string& range() const { return range_; }
00046 std::string accuracy_parry_description() const;
00047 int accuracy() const { return accuracy_; }
00048 int parry() const { return parry_; }
00049 int damage() const { return damage_; }
00050 int num_attacks() const { return num_attacks_; }
00051 double attack_weight() const { return attack_weight_; }
00052 double defense_weight() const { return defense_weight_; }
00053
00054 bool get_special_bool(const std::string& special,bool force=false) const;
00055 unit_ability_list get_specials(const std::string& special) const;
00056 std::vector<std::string> special_tooltips(bool force=false) const;
00057 std::string weapon_specials(bool force=false) const;
00058 void set_specials_context(const gamemap::location& aloc,const gamemap::location& dloc,
00059 const unit_map* unitmap,
00060 const gamemap* map, const gamestatus* game_status,
00061 const std::vector<team>* teams,bool attacker,const attack_type* other_attack) const;
00062 void set_specials_context(const gamemap::location& loc,const gamemap::location& dloc, const unit& un, bool attacker =true) const;
00063
00064 bool has_special_by_id(const std::string& special) const;
00065
00066
00067
00068 bool matches_filter(const config& cfg,bool self=false) const;
00069 bool apply_modification(const config& cfg,std::string* description);
00070 bool describe_modification(const config& cfg,std::string* description);
00071
00072 int movement_used() const { return cfg_["movement_used"] == "" ? 100000 : lexical_cast_default<int>(cfg_["movement_used"]); }
00073
00074 config& get_cfg() { return cfg_; }
00075 const config& get_cfg() const { return cfg_; }
00076 mutable gamemap::location aloc_,dloc_;
00077 mutable bool attacker_;
00078 mutable const unit_map* unitmap_;
00079 mutable const gamemap* map_;
00080 mutable const gamestatus* game_status_;
00081 mutable const std::vector<team>* teams_;
00082 mutable const attack_type* other_attack_;
00083
00084
00085
00086 bool special_active(const config& cfg,bool self,bool report=false) const;
00087 bool special_affects_opponent(const config& cfg) const;
00088 bool special_affects_self(const config& cfg) const;
00089
00090 config cfg_;
00091 const unit_animation* animation(const game_display& disp, const gamemap::location& loc,const unit* my_unit,const unit_animation::hit_type hit,const attack_type* secondary_attack,int swing_num,int damage) const;
00092
00093
00094 std::vector<unit_animation> animation_;
00095 private:
00096 t_string description_;
00097 std::string id_;
00098 std::string type_;
00099 std::string icon_;
00100 std::string range_;
00101 int damage_;
00102 int num_attacks_;
00103 double attack_weight_;
00104 double defense_weight_;
00105
00106 int accuracy_;
00107 int parry_;
00108 };
00109
00110 class unit_movement_type;
00111
00112
00113
00114 class unit_movement_type
00115 {
00116 public:
00117
00118
00119 unit_movement_type(const config& cfg, const unit_movement_type* parent=NULL);
00120 unit_movement_type();
00121
00122 const t_string& name() const;
00123 int movement_cost(const gamemap& map, t_translation::t_terrain terrain, int recurse_count=0) const;
00124 int defense_modifier(const gamemap& map, t_translation::t_terrain terrain, int recurse_count=0) const;
00125 int damage_against(const attack_type& attack) const { return resistance_against(attack); }
00126 int resistance_against(const attack_type& attack) const;
00127
00128 string_map damage_table() const;
00129
00130 void set_parent(const unit_movement_type* parent) { parent_ = parent; }
00131
00132 bool is_flying() const;
00133 const std::map<t_translation::t_terrain, int>& movement_costs() const { return moveCosts_; }
00134 const std::map<t_translation::t_terrain, int>& defense_mods() const { return defenseMods_; }
00135
00136 const config& get_cfg() const { return cfg_; }
00137 const unit_movement_type* get_parent() const { return parent_; }
00138 private:
00139 mutable std::map<t_translation::t_terrain, int> moveCosts_;
00140 mutable std::map<t_translation::t_terrain, int> defenseMods_;
00141
00142 const unit_movement_type* parent_;
00143
00144 config cfg_;
00145 };
00146
00147 typedef std::map<std::string,unit_movement_type> movement_type_map;
00148
00149 class unit_type
00150 {
00151 public:
00152 friend class unit;
00153 friend class unit_type_data;
00154
00155 unit_type();
00156 unit_type(const config& cfg, const movement_type_map& movement_types,
00157 const race_map& races, const std::vector<config*>& traits);
00158 unit_type(const unit_type& o);
00159
00160 ~unit_type();
00161
00162
00163 void build_full(const config& cfg, const movement_type_map& movement_types,
00164 const race_map& races, const std::vector<config*>& traits);
00165
00166 void build_help_index(const config& cfg, const race_map& races);
00167
00168
00169
00170
00171
00172 void add_advancement(const unit_type &advance_to,int experience);
00173
00174
00175 void add_advancesfrom(std::string unit_id);
00176
00177 const unit_type& get_gender_unit_type(unit_race::GENDER gender) const;
00178 const unit_type& get_variation(const std::string& name) const;
00179
00180 const std::string& undead_variation() const { return undead_variation_; }
00181
00182 unsigned int num_traits() const { return (num_traits_ ? num_traits_ : race_->num_traits()); }
00183
00184
00185 const t_string& type_name() const { return type_name_; }
00186
00187 const std::string& id() const { return id_; }
00188 const t_string& unit_description() const;
00189 int hitpoints() const { return hitpoints_; }
00190 int level() const { return level_; }
00191 int movement() const { return movement_; }
00192 int cost() const { return cost_; }
00193 const std::string& usage() const { return usage_; }
00194 const std::string& image() const { return image_; }
00195 const std::string& image_profile() const;
00196
00197 const std::vector<unit_animation>& animations() const;
00198
00199 const std::string& flag_rgb() const { return flag_rgb_; }
00200
00201 std::vector<attack_type> attacks() const;
00202 const unit_movement_type& movement_type() const { return movementType_; }
00203
00204 int experience_needed(bool with_acceleration=true) const;
00205 std::vector<std::string> advances_to() const { return advances_to_; }
00206 std::vector<std::string> advances_from() const { return advances_from_; }
00207 const config::child_list& modification_advancements() const { return cfg_.get_children("advancement"); }
00208
00209 struct experience_accelerator {
00210 experience_accelerator(int modifier);
00211 ~experience_accelerator();
00212 static int get_acceleration();
00213 private:
00214 int old_value_;
00215 };
00216
00217 enum ALIGNMENT { LAWFUL, NEUTRAL, CHAOTIC };
00218
00219 ALIGNMENT alignment() const { return alignment_; }
00220 static const char* alignment_description(ALIGNMENT align);
00221 static const char* alignment_id(ALIGNMENT align);
00222
00223 fixed_t alpha() const { return alpha_; }
00224
00225 const std::vector<std::string>& abilities() const { return abilities_; }
00226 const std::vector<std::string>& ability_tooltips() const { return ability_tooltips_; }
00227
00228 bool can_advance() const { return !advances_to_.empty(); }
00229
00230 bool not_living() const;
00231
00232 bool has_zoc() const { return zoc_; }
00233
00234 bool has_ability(const std::string& ability) const;
00235 bool has_ability_by_id(const std::string& ability) const;
00236
00237 const std::vector<config*> possible_traits() const { return possibleTraits_.get_children("trait"); }
00238 bool has_random_traits() const { return (num_traits() > 0 && possible_traits().size() > 1); }
00239
00240 const std::vector<unit_race::GENDER>& genders() const { return genders_; }
00241
00242 const std::string& race() const;
00243 bool hide_help() const { return hide_help_; }
00244
00245 enum BUILD_STATUS {NOT_BUILT, HELP_INDEX, WITHOUT_ANIMATIONS, FULL};
00246
00247 BUILD_STATUS build_status() const { return build_status_; }
00248 private:
00249 void operator=(const unit_type& o);
00250
00251 config cfg_;
00252
00253 std::string id_;
00254 t_string type_name_;
00255 t_string description_;
00256 int hitpoints_;
00257 int level_;
00258 int movement_;
00259 int cost_;
00260 std::string usage_;
00261 std::string undead_variation_;
00262
00263 std::string image_;
00264 std::string image_profile_;
00265 std::string flag_rgb_;
00266
00267 unsigned int num_traits_;
00268
00269 unit_type* gender_types_[2];
00270
00271 typedef std::map<std::string,unit_type*> variations_map;
00272 variations_map variations_;
00273
00274 const unit_race* race_;
00275
00276 fixed_t alpha_;
00277
00278 std::vector<std::string> abilities_;
00279 std::vector<std::string> ability_tooltips_;
00280
00281 bool zoc_, hide_help_;
00282
00283 std::vector<std::string> advances_to_;
00284 std::vector<std::string> advances_from_;
00285 int experience_needed_;
00286
00287
00288 ALIGNMENT alignment_;
00289
00290 unit_movement_type movementType_;
00291
00292 config possibleTraits_;
00293
00294 std::vector<unit_race::GENDER> genders_;
00295
00296
00297 mutable std::vector<unit_animation> animations_;
00298
00299 BUILD_STATUS build_status_;
00300 };
00301
00302 class unit_type_data
00303 {
00304 public:
00305 static unit_type_data& instance() {
00306 if (instance_ == NULL)
00307 instance_ = new unit_type_data();
00308
00309 return *instance_;
00310 }
00311
00312 typedef std::map<std::string,unit_type> unit_type_map;
00313
00314 class unit_type_map_wrapper
00315 {
00316 friend class unit_type_data;
00317
00318 public:
00319 const race_map& races() const { return races_; }
00320 void set_config(const config& cfg);
00321
00322 unit_type_map::const_iterator begin() const { return types_.begin(); }
00323 unit_type_map::const_iterator end() const { return types_.end(); }
00324 unit_type_map::const_iterator find(const std::string& key, unit_type::BUILD_STATUS status = unit_type::FULL) const;
00325
00326 void build_all(unit_type::BUILD_STATUS status) const;
00327
00328 private:
00329 unit_type_map_wrapper();
00330 unit_type_map_wrapper(unit_type_map_wrapper& ) {}
00331
00332 void set_unit_config(const config& unit_cfg) { unit_cfg_ = &unit_cfg; }
00333 void set_unit_traits(const config::child_list unit_traits) { unit_traits_ = unit_traits; }
00334
00335 const config& find_config(const std::string& key) const;
00336 std::pair<unit_type_map::iterator, bool> insert(const std::pair<std::string,unit_type>& utype) { return types_.insert(utype); }
00337 void clear() {
00338 types_.clear();
00339 movement_types_.clear();
00340 races_.clear();
00341 }
00342
00343 unit_type& build_unit_type(const std::string& key, unit_type::BUILD_STATUS status) const;
00344 void add_advancefrom(const config& unit_cfg) const;
00345 void add_advancement(const config& cfg, unit_type& to_unit) const;
00346
00347 mutable unit_type_map types_;
00348 mutable unit_type_map dummy_unit_map_;
00349 movement_type_map movement_types_;
00350 race_map races_;
00351 config::child_list unit_traits_;
00352 const config* unit_cfg_;
00353 };
00354
00355 static unit_type_map_wrapper& types() { return instance().unit_types_; }
00356
00357 private:
00358 static unit_type_data* instance_;
00359 mutable unit_type_map_wrapper unit_types_;
00360
00361 unit_type_data();
00362 };
00363
00364 #endif