unit_types.hpp

Go to the documentation of this file.
00001 /* $Id: unit_types.hpp 26759 2008-05-21 19:09:44Z mordante $ */
00002 /*
00003    Copyright (C) 2003 - 2008 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 version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
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 //and how much damage it does.
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     //this function returns a random animation out of the possible
00066     //animations for this attack. It will not return the same attack
00067     //each time.
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      * cfg: a weapon special WML structure
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     // made public to ease backward compatibility for WML syntax
00093     // to be removed (with all corresponding code once 1.3.6 is reached
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 //the 'unit movement type' is the basic size of the unit - flying, small land,
00113 //large land, etc etc.
00114 class unit_movement_type
00115 {
00116 public:
00117     //this class assumes that the passed in reference will remain valid
00118     //for at least as long as the class instance
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     /** Load data into an empty unit_type */
00163     void build_full(const config& cfg, const movement_type_map& movement_types,
00164               const race_map& races, const std::vector<config*>& traits);
00165     /** Partially load data into an empty unit_type */
00166     void build_help_index(const config& cfg, const race_map& races);
00167 
00168     /**
00169      * Adds an additional advancement path to a unit type.
00170      * This is used to implement the [advancefrom] tag.
00171      */
00172     void add_advancement(const unit_type &advance_to,int experience);
00173 
00174     /** Adds units that this unit advances from, for help file purposes. */
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     /** Info on the type of unit that the unit reanimates as. */
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     /** The name of the unit in the current language setting. */
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     // animations are loaded only after the first animations() call
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& /*utf*/) {}
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

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs