unit_types.hpp

Go to the documentation of this file.
00001 /* $Id: unit_types.hpp 54122 2012-05-08 00:05:33Z fendrin $ */
00002 /*
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 #ifndef UNIT_TYPES_H_INCLUDED
00016 #define UNIT_TYPES_H_INCLUDED
00017 
00018 #include "unit_animation.hpp"
00019 #include "portrait.hpp"
00020 #include "race.hpp"
00021 
00022 class gamemap;
00023 class unit;
00024 class unit_ability_list;
00025 class unit_map;
00026 class unit_type_data;
00027 
00028 
00029 //and how much damage it does.
00030 class attack_type
00031 {
00032 public:
00033 
00034     attack_type(const config& cfg);
00035     /** Default implementation, but defined out-of-line for efficiency reasons. */
00036     ~attack_type();
00037     const t_string& name() const { return description_; }
00038     const std::string& id() const { return id_; }
00039     const std::string& type() const { return type_; }
00040     const std::string& icon() const { return icon_; }
00041     const std::string& range() const { return range_; }
00042     std::string accuracy_parry_description() const;
00043     int accuracy() const { return accuracy_; }
00044     int parry() const { return parry_; }
00045     int damage() const { return damage_; }
00046     int num_attacks() const { return num_attacks_; }
00047     double attack_weight() const { return attack_weight_; }
00048     double defense_weight() const { return defense_weight_; }
00049 
00050     bool get_special_bool(const std::string& special,bool force=false) const;
00051     unit_ability_list get_specials(const std::string& special) const;
00052     std::vector<t_string> special_tooltips(bool force=false) const;
00053     std::string weapon_specials(bool force=false) const;
00054     void set_specials_context(const map_location& aloc,const map_location& dloc,
00055         const unit_map &unitmap, bool attacker, const attack_type *other_attack) const;
00056     void set_specials_context(const map_location& loc,const map_location& dloc, const unit& un, bool attacker =true) const;
00057 
00058     bool matches_filter(const config& cfg,bool self=false) const;
00059     bool apply_modification(const config& cfg,std::string* description);
00060     bool describe_modification(const config& cfg,std::string* description);
00061 
00062     int movement_used() const { return cfg_["movement_used"].to_int(100000); }
00063 
00064     config& get_cfg() { return cfg_; }
00065     const config& get_cfg() const { return cfg_; }
00066     mutable map_location aloc_,dloc_;
00067     mutable bool attacker_;
00068     mutable const unit_map* unitmap_;
00069     mutable const attack_type* other_attack_;
00070     /*
00071      * cfg: a weapon special WML structure
00072      */
00073     bool special_active(const config& cfg, bool self) const;
00074     bool special_affects_opponent(const config& cfg) const;
00075     bool special_affects_self(const config& cfg) const;
00076 
00077     //this function returns a random animation out of the possible
00078     //animations for this attack. It will not return the same attack
00079     //each time.
00080     const unit_animation* animation(const display& disp, const map_location& loc,const unit* my_unit,const unit_animation::hit_type hit,const attack_type* secondary_attack,int swing_num,int damage) const;
00081 private:
00082     config cfg_;
00083     t_string description_;
00084     std::string id_;
00085     std::string type_;
00086     std::string icon_;
00087     std::string range_;
00088     int damage_;
00089     int num_attacks_;
00090     double attack_weight_;
00091     double defense_weight_;
00092 
00093     int accuracy_;
00094     int parry_;
00095 };
00096 
00097 class unit_movement_type;
00098 
00099 /**
00100  * Possible range of the defense. When a single value is needed, #max_
00101  * (maximum defense) is selected, unless #min_ is bigger.
00102  */
00103 struct defense_range
00104 {
00105     int min_, max_;
00106 };
00107 
00108 typedef std::map<t_translation::t_terrain, defense_range> defense_cache;
00109 
00110 const defense_range &defense_range_modifier_internal(defense_cache &defense_mods,
00111     const config &cfg, const unit_movement_type *parent,
00112     const gamemap &map, t_translation::t_terrain terrain, int recurse_count = 0);
00113 
00114 int defense_modifier_internal(defense_cache &defense_mods,
00115     const config &cfg, const unit_movement_type *parent,
00116     const gamemap &map, t_translation::t_terrain terrain, int recurse_count = 0);
00117 
00118 int movement_cost_internal(std::map<t_translation::t_terrain, int> &move_costs,
00119     const config &cfg, const unit_movement_type *parent,
00120     const gamemap &map, t_translation::t_terrain terrain, int recurse_count = 0);
00121 
00122 //the 'unit movement type' is the basic size of the unit - flying, small land,
00123 //large land, etc etc.
00124 class unit_movement_type
00125 {
00126 public:
00127         //this move distance means a hex is unreachable
00128     //if there is an UNREACHABLE macro declared in the data tree
00129     //it should match this value.
00130     static const int UNREACHABLE = 99;
00131 
00132     //this class assumes that the passed in reference will remain valid
00133     //for at least as long as the class instance
00134     unit_movement_type(const config& cfg, const unit_movement_type* parent=NULL);
00135     unit_movement_type();
00136 
00137     std::string name() const;
00138     int movement_cost(const gamemap &map, t_translation::t_terrain terrain) const
00139     { return movement_cost_internal(moveCosts_, cfg_.child("movement_costs"), parent_, map, terrain); }
00140     int vision_cost(const gamemap &map, t_translation::t_terrain terrain) const
00141     { return movement_cost_internal(visionCosts_, cfg_.child("vision_costs"), parent_, map, terrain); }
00142     int defense_modifier(const gamemap &map, t_translation::t_terrain terrain) const
00143     { return defense_modifier_internal(defenseMods_, cfg_, parent_, map, terrain); }
00144     const defense_range &defense_range_modifier(const gamemap &map, t_translation::t_terrain terrain) const
00145     { return defense_range_modifier_internal(defenseMods_, cfg_, parent_, map, terrain); }
00146     int damage_against(const attack_type& attack) const { return resistance_against(attack); }
00147     int resistance_against(const attack_type& attack) const;
00148 
00149     utils::string_map damage_table() const;
00150 
00151     void set_parent(const unit_movement_type* parent) { parent_ = parent; }
00152 
00153     bool is_flying() const;
00154 
00155     const config& get_cfg() const { return cfg_; }
00156     const unit_movement_type* get_parent() const { return parent_; }
00157 private:
00158     mutable std::map<t_translation::t_terrain, int> moveCosts_;
00159     mutable std::map<t_translation::t_terrain, int> visionCosts_;
00160     mutable std::map<t_translation::t_terrain, int> jammingCosts_;
00161 
00162     mutable defense_cache defenseMods_;
00163 
00164     const unit_movement_type* parent_;
00165 
00166     config cfg_;
00167 };
00168 
00169 typedef std::map<std::string,unit_movement_type> movement_type_map;
00170 
00171 class unit_type
00172 {
00173 public:
00174     friend class unit;
00175     friend class unit_type_data;
00176 
00177     /**
00178      * Creates a unit type for the given config, but delays its build
00179      * till later.
00180      * @note @a cfg is not copied, so it has to point to some permanent
00181      *       storage, that is, a child of unit_type_data::unit_cfg.
00182      */
00183     unit_type();
00184     unit_type(config &cfg);
00185     unit_type(const unit_type& o);
00186 
00187     ~unit_type();
00188 
00189     /** Load data into an empty unit_type */
00190     void build_full(const movement_type_map &movement_types,
00191         const race_map &races, const config::const_child_itors &traits);
00192     /** Partially load data into an empty unit_type */
00193     void build_help_index(const movement_type_map &movement_types,
00194         const race_map &races, const config::const_child_itors &traits);
00195     /** Load the most needed data into an empty unit_type */
00196     void build_created(const movement_type_map &movement_types,
00197         const race_map &races, const config::const_child_itors &traits);
00198 
00199     /**
00200      * Adds an additional advancement path to a unit type.
00201      * This is used to implement the [advancefrom] tag.
00202      */
00203     void add_advancement(const unit_type &advance_to,int experience);
00204 
00205     /** Get the advancement tree
00206      *  Build a set of unit type's id of this unit type's advancement tree */
00207     std::set<std::string> advancement_tree() const;
00208 
00209     const std::vector<std::string>& advances_to() const { return advances_to_; }
00210     const std::vector<std::string> advances_from() const;
00211 
00212     config::const_child_itors modification_advancements() const
00213     { return cfg_.child_range("advancement"); }
00214 
00215     const unit_type& get_gender_unit_type(std::string gender) const;
00216     const unit_type& get_gender_unit_type(unit_race::GENDER gender) const;
00217     const unit_type& get_variation(const std::string& name) const;
00218     /** Info on the type of unit that the unit reanimates as. */
00219     const std::string& undead_variation() const { return undead_variation_; }
00220 
00221     unsigned int num_traits() const { return num_traits_; }
00222 
00223     /** The name of the unit in the current language setting. */
00224     const t_string& type_name() const { return type_name_; }
00225 
00226     const std::string& id() const { return id_; }
00227     // NOTE: this used to be a const object reference, but it messed up with the
00228     // translation engine upon changing the language in the same session.
00229     const t_string unit_description() const;
00230     int hitpoints() const { return hitpoints_; }
00231     int level() const { return level_; }
00232     int movement() const { return movement_; }
00233     int vision() const { return vision_; }
00234     int jamming() const {return jamming_; }
00235     int max_attacks() const { return max_attacks_; }
00236     int cost() const { return cost_; }
00237     const std::string& usage() const { return usage_; }
00238     const std::string& image() const { return image_; }
00239     const std::string& icon() const { return icon_; }
00240     const std::string &small_profile() const { return small_profile_; }
00241     const std::string &big_profile() const { return big_profile_; }
00242 
00243     const std::vector<unit_animation>& animations() const;
00244 
00245     const std::string& flag_rgb() const { return flag_rgb_; }
00246 
00247     std::vector<attack_type> attacks() const;
00248     const unit_movement_type& movement_type() const { return movementType_; }
00249 
00250     int experience_needed(bool with_acceleration=true) const;
00251 
00252     struct experience_accelerator {
00253         experience_accelerator(int modifier);
00254         ~experience_accelerator();
00255         static int get_acceleration();
00256     private:
00257         int old_value_;
00258     };
00259 
00260     enum ALIGNMENT { LAWFUL, NEUTRAL, CHAOTIC, LIMINAL };
00261 
00262     ALIGNMENT alignment() const { return alignment_; }
00263     static const char* alignment_description(ALIGNMENT align, unit_race::GENDER gender = unit_race::MALE);
00264     static const char* alignment_id(ALIGNMENT align);
00265 
00266     fixed_t alpha() const { return alpha_; }
00267 
00268     const std::vector<t_string>& abilities() const { return abilities_; }
00269     const std::vector<t_string>& ability_tooltips() const { return ability_tooltips_; }
00270 
00271     // some extra abilities may be gained through AMLA advancements
00272     const std::vector<t_string>& adv_abilities() const { return adv_abilities_; }
00273     const std::vector<t_string>& adv_ability_tooltips() const { return adv_ability_tooltips_; }
00274 
00275     bool can_advance() const { return !advances_to_.empty(); }
00276 
00277     bool not_living() const;
00278 
00279     bool has_zoc() const { return zoc_; }
00280 
00281     bool has_ability_by_id(const std::string& ability) const;
00282     std::vector<std::string> get_ability_list() const;
00283 
00284     config::const_child_itors possible_traits() const
00285     { return possibleTraits_.child_range("trait"); }
00286     bool has_random_traits() const;
00287 
00288     const std::vector<unit_race::GENDER>& genders() const { return genders_; }
00289 
00290     const std::string race() const { return cfg_["race"]; } //race_->id(); }
00291     bool hide_help() const;
00292 
00293     enum BUILD_STATUS {NOT_BUILT, CREATED, HELP_INDEX, WITHOUT_ANIMATIONS, FULL};
00294 
00295     BUILD_STATUS build_status() const { return build_status_; }
00296 
00297     const std::vector<tportrait>& portraits() const { return portraits_; }
00298 
00299     const config &get_cfg() const { return cfg_; }
00300 
00301 private:
00302     void operator=(const unit_type& o);
00303 
00304     config &cfg_;
00305 
00306     std::string id_;
00307     t_string type_name_;
00308     t_string description_;
00309     int hitpoints_;
00310     int level_;
00311     int movement_;
00312     int vision_;
00313     int jamming_;
00314     int max_attacks_;
00315     int cost_;
00316     std::string usage_;
00317     std::string undead_variation_;
00318 
00319     std::string image_;
00320     std::string icon_;
00321     std::string small_profile_;
00322     std::string big_profile_;
00323     std::string flag_rgb_;
00324 
00325     unsigned int num_traits_;
00326 
00327     unit_type* gender_types_[2];
00328 
00329     typedef std::map<std::string,unit_type*> variations_map;
00330     variations_map variations_;
00331 
00332     const unit_race* race_;
00333 
00334     fixed_t alpha_;
00335 
00336     std::vector<t_string> abilities_, adv_abilities_;
00337     std::vector<t_string> ability_tooltips_, adv_ability_tooltips_;
00338 
00339     bool zoc_, hide_help_;
00340 
00341     std::vector<std::string> advances_to_;
00342     int experience_needed_;
00343     bool in_advancefrom_;
00344 
00345 
00346     ALIGNMENT alignment_;
00347 
00348     unit_movement_type movementType_;
00349 
00350     config possibleTraits_;
00351 
00352     std::vector<unit_race::GENDER> genders_;
00353 
00354     // animations are loaded only after the first animations() call
00355     mutable std::vector<unit_animation> animations_;
00356 
00357     BUILD_STATUS build_status_;
00358 
00359     /** List with the portraits available for the unit. */
00360     std::vector<tportrait> portraits_;
00361 };
00362 
00363 class unit_type_data
00364 {
00365 public:
00366     unit_type_data();
00367 
00368     typedef std::map<std::string,unit_type> unit_type_map;
00369 
00370     const unit_type_map &types() const { return types_; }
00371     const race_map &races() const { return races_; }
00372     const config::const_child_itors traits() const { return unit_cfg_->child_range("trait"); }
00373     void set_config(config &cfg);
00374 
00375     const unit_type *find(const std::string &key, unit_type::BUILD_STATUS status = unit_type::FULL) const;
00376     void check_types(const std::vector<std::string>& types) const;
00377     const unit_race *find_race(const std::string &) const;
00378 
00379     void build_all(unit_type::BUILD_STATUS status);
00380 
00381     /** Checks if the [hide_help] tag contains these IDs. */
00382     bool hide_help(const std::string &type_id, const std::string &race_id) const;
00383 
00384 private:
00385     unit_type_data(const unit_type_data &);
00386 
00387     /** Parses the [hide_help] tag. */
00388     void read_hide_help(const config &cfg);
00389 
00390     void set_unit_config(const config& unit_cfg) { unit_cfg_ = &unit_cfg; }
00391 
00392     const config &find_config(const std::string &key) const;
00393     std::pair<unit_type_map::iterator, bool> insert(const std::pair<std::string, unit_type> &utype) { return types_.insert(utype); }
00394     void clear();
00395 
00396     unit_type& build_unit_type(const unit_type_map::iterator &ut, unit_type::BUILD_STATUS status) const;
00397     void add_advancefrom(const config& unit_cfg) const;
00398     void add_advancement(unit_type& to_unit) const;
00399 
00400     mutable unit_type_map types_;
00401     movement_type_map movement_types_;
00402     race_map races_;
00403 
00404     /** True if [hide_help] contains a 'all=yes' at its root. */
00405     bool hide_help_all_;
00406     // vectors containing the [hide_help] and its sub-tags [not]
00407     std::vector< std::set<std::string> > hide_help_type_;
00408     std::vector< std::set<std::string> > hide_help_race_;
00409 
00410     const config *unit_cfg_;
00411     unit_type::BUILD_STATUS build_status_;
00412 };
00413 
00414 extern unit_type_data unit_types;
00415 
00416 void adjust_profile(std::string &small, std::string &big, std::string const &def);
00417 
00418 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:14 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs