Author: silene
Date: Sun Sep 12 20:37:58 2010
New Revision: 46418

URL: http://svn.gna.org/viewcvs/wesnoth?rev=46418&view=rev
Log:
Allowed negative defense values as a way to set upper bounds.
Example: [defense] village=-60 means that the unit cannot have less than 60 def 
(more than 40% def) on terrains containing villages.

Modified:
    trunk/changelog
    trunk/data/scenario-test.cfg
    trunk/src/unit.hpp
    trunk/src/unit_types.cpp
    trunk/src/unit_types.hpp

Modified: trunk/changelog
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=46418&r1=46417&r2=46418&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Sun Sep 12 20:37:58 2010
@@ -109,6 +109,9 @@
      floating-point divide.
    * Allow time_area to define local time of day on map border (bug #16508)
    * Fix time of day not changing in time area (bug #16584)
+   * Allowed negative defense values as a way to set upper bounds,
+     e.g. village=-60 means that a unit cannot have less than 60 def (more
+     than 40% def) on terrains containing villages.
  * Miscellaneous and bug fixes:
    * Removed: statistics upload code.
    * Changed: compiler mode set to c++98

Modified: trunk/data/scenario-test.cfg
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/data/scenario-test.cfg?rev=46418&r1=46417&r2=46418&view=diff
==============================================================================
--- trunk/data/scenario-test.cfg (original)
+++ trunk/data/scenario-test.cfg Sun Sep 12 20:37:58 2010
@@ -93,23 +93,13 @@
                     availability="musthave"
                     male_name="feral"
                     female_name="female^feral"
-                    description="Receive only 40% defense in villages"
+                    description="Receive at most 40% defense in villages"
                     [effect]
-                        apply_to=new_ability
-                        [abilities]
-                            [defense]
-                                id=feral
-                                name=""
-                                description=""
-                                value=60
-                                cumulative=no
-                                [filter_self]
-                                    [filter_location]
-                                        terrain=*^V*
-                                    [/filter_location]
-                                [/filter_self]
-                            [/defense]
-                        [/abilities]
+                        apply_to=defense
+                        replace=yes
+                        [defense]
+                            village=-60
+                        [/defense]
                     [/effect]
                 [/trait]
             [/modifications]

Modified: trunk/src/unit.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit.hpp?rev=46418&r1=46417&r2=46418&view=diff
==============================================================================
--- trunk/src/unit.hpp (original)
+++ trunk/src/unit.hpp Sun Sep 12 20:37:58 2010
@@ -399,7 +399,7 @@
        int movement_;
        int max_movement_;
        mutable std::map<t_translation::t_terrain, int> movement_costs_; // 
movement cost cache
-       mutable std::map<t_translation::t_terrain, int> defense_mods_; // 
defense modifiers cache
+       mutable defense_cache defense_mods_; // defense modifiers cache
        bool hold_position_;
        bool end_turn_;
        bool resting_;

Modified: trunk/src/unit_types.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit_types.cpp?rev=46418&r1=46417&r2=46418&view=diff
==============================================================================
--- trunk/src/unit_types.cpp (original)
+++ trunk/src/unit_types.cpp Sun Sep 12 20:37:58 2010
@@ -315,19 +315,6 @@
                return cfg_["name"];
 }
 
-int unit_movement_type::movement_cost(const gamemap& map,
-               t_translation::t_terrain terrain) const
-{
-       int res = movement_cost_internal(moveCosts_, cfg_, parent_, map, 
terrain);
-       return res;
-}
-
-int unit_movement_type::defense_modifier(const gamemap& map,
-               t_translation::t_terrain terrain) const
-{
-       return defense_modifier_internal(defenseMods_, cfg_, parent_, map, 
terrain);
-}
-
 int unit_movement_type::resistance_against(const attack_type& attack) const
 {
        bool result_found = false;
@@ -454,33 +441,37 @@
        return res;
 }
 
-int defense_modifier_internal(std::map<t_translation::t_terrain, int>& 
defense_mods,
+const defense_range &defense_range_modifier_internal(defense_cache 
&defense_mods,
                const config& cfg, const unit_movement_type* parent,
                const gamemap& map, t_translation::t_terrain terrain, int 
recurse_count)
 {
-       const std::map<t_translation::t_terrain, int>::const_iterator i = 
defense_mods.find(terrain);
-       if (i != defense_mods.end()) return i->second;
-
-       bool result_found = false;
-       int res = 100;
+       defense_range dummy = { 0, 100 };
+       std::pair<defense_cache::iterator, bool> ib =
+               defense_mods.insert(defense_cache::value_type(terrain, dummy));
+       if (!ib.second) return ib.first->second;
+
+       defense_range &res = ib.first->second;
 
        // If this is an alias, then select the best of all underlying terrains.
        const t_translation::t_list& underlying = 
map.underlying_def_terrain(terrain);
        assert(!underlying.empty());
 
        if (underlying.size() != 1 || underlying.front() != terrain) {
-               bool revert = (underlying.front() == t_translation::MINUS ? 
true : false);
+               bool revert = underlying.front() == t_translation::MINUS;
                if(recurse_count >= 90) {
                        ERR_CF << "infinite defense_modifier recursion: "
                                << t_translation::write_terrain_code(terrain)
                                << " depth " << recurse_count << "\n";
                }
                if (recurse_count >= 100) {
-                       defense_mods.insert(std::pair<t_translation::t_terrain, 
int>(terrain, res));
                        return res;
                }
 
-               res = revert ? 0 : 100;
+               if (revert) {
+                       res.max_ = 0;
+                       res.min_ = 100;
+               }
+
                for (t_translation::t_list::const_iterator i = 
underlying.begin();
                                i != underlying.end(); ++i) {
 
@@ -491,50 +482,57 @@
                                revert = true;
                                continue;
                        }
-                       const int value = 
defense_modifier_internal(defense_mods, cfg, parent,
-                                       map, *i, recurse_count + 1);
-
-                       if (value < res && !revert) {
-                               res = value;
-                       } else if (value > res && revert) {
-                               res = value;
+                       const defense_range &inh = 
defense_range_modifier_internal
+                               (defense_mods, cfg, parent, map, *i, 
recurse_count + 1);
+
+                       if (!revert) {
+                               if (inh.max_ < res.max_) res.max_ = inh.max_;
+                               if (inh.min_ > res.min_) res.min_ = inh.min_;
+                       } else {
+                               if (inh.max_ > res.max_) res.max_ = inh.max_;
+                               if (inh.min_ < res.min_) res.min_ = inh.min_;
                        }
                }
 
-               defense_mods.insert(std::pair<t_translation::t_terrain, 
int>(terrain, res));
-               return res;
-       }
-
-       if (const config& defense = cfg.child("defense")) {
-               if (underlying.size() != 1) {
-                       ERR_CF << "Terrain '" << terrain << "' has "
-                               << underlying.size() << " underlying names - 0 
expected.\n";
-
-                       defense_mods.insert(std::pair<t_translation::t_terrain, 
int>(terrain, res));
-                       return res;
-               }
-
+               goto check;
+       }
+
+       if (const config& defense = cfg.child("defense"))
+       {
                const std::string& id = 
map.get_terrain_info(underlying.front()).id();
                if (const config::attribute_value *val = defense.get(id)) {
-                       res = *val;
-                       result_found = true;
-               }
-       }
-
-       if (!result_found && parent != NULL) {
-               res = parent->defense_modifier(map, terrain);
-       }
-
-       if (res < 0) {
-               WRN_CF << "Defense '" << res << "' is '< 0' reset to 0 (100% 
defense).\n";
-               res = 0;
-       } else if (res > 100) {
-               WRN_CF << "Defense '" << res << "' is '> 100' reset to 100 (0% 
defense).\n";
-               res = 100;
-       }
-
-       defense_mods.insert(std::pair<t_translation::t_terrain, int>(terrain, 
res));
+                       int def = *val;
+                       if (def >= 0) res.max_ = def;
+                       else res.max_ = res.min_ = -def;
+                       goto check;
+               }
+       }
+
+       if (parent) {
+               return parent->defense_range_modifier(map, terrain);
+       }
+
+       check:
+
+       if (res.min_ < 0) {
+               WRN_CF << "Defense '" << res.min_ << "' is '< 0' reset to 0 
(100% defense).\n";
+               res.min_ = 0;
+       }
+       if (res.max_ > 100) {
+               WRN_CF << "Defense '" << res.max_ << "' is '> 100' reset to 100 
(0% defense).\n";
+               res.max_ = 100;
+       }
+
        return res;
+}
+
+int defense_modifier_internal(defense_cache &defense_mods,
+       const config &cfg, const unit_movement_type *parent,
+       const gamemap &map, t_translation::t_terrain terrain, int recurse_count)
+{
+       const defense_range &def = defense_range_modifier_internal(defense_mods,
+               cfg, parent, map, terrain, recurse_count);
+       return (std::max)(def.max_, def.min_);
 }
 
 static const unit_race& dummy_race(){

Modified: trunk/src/unit_types.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit_types.hpp?rev=46418&r1=46417&r2=46418&view=diff
==============================================================================
--- trunk/src/unit_types.hpp (original)
+++ trunk/src/unit_types.hpp Sun Sep 12 20:37:58 2010
@@ -103,6 +103,29 @@
 
 class unit_movement_type;
 
+/**
+ * Possible range of the defense. When a single value is needed, #max_
+ * (maximum defense) is selected, unless #min_ is bigger.
+ */
+struct defense_range
+{
+       int min_, max_;
+};
+
+typedef std::map<t_translation::t_terrain, defense_range> defense_cache;
+
+const defense_range &defense_range_modifier_internal(defense_cache 
&defense_mods,
+       const config &cfg, const unit_movement_type *parent,
+       const gamemap &map, t_translation::t_terrain terrain, int recurse_count 
= 0);
+
+int defense_modifier_internal(defense_cache &defense_mods,
+       const config &cfg, const unit_movement_type *parent,
+       const gamemap &map, t_translation::t_terrain terrain, int recurse_count 
= 0);
+
+int movement_cost_internal(std::map<t_translation::t_terrain, int> &move_costs,
+       const config &cfg, const unit_movement_type *parent,
+       const gamemap &map, t_translation::t_terrain terrain, int recurse_count 
= 0);
+
 //the 'unit movement type' is the basic size of the unit - flying, small land,
 //large land, etc etc.
 class unit_movement_type
@@ -119,8 +142,12 @@
        unit_movement_type();
 
        std::string name() const;
-       int movement_cost(const gamemap& map, t_translation::t_terrain terrain) 
const;
-       int defense_modifier(const gamemap& map, t_translation::t_terrain 
terrain) const;
+       int movement_cost(const gamemap &map, t_translation::t_terrain terrain) 
const
+       { return movement_cost_internal(moveCosts_, cfg_, parent_, map, 
terrain); }
+       int defense_modifier(const gamemap &map, t_translation::t_terrain 
terrain) const
+       { return defense_modifier_internal(defenseMods_, cfg_, parent_, map, 
terrain); }
+       const defense_range &defense_range_modifier(const gamemap &map, 
t_translation::t_terrain terrain) const
+       { return defense_range_modifier_internal(defenseMods_, cfg_, parent_, 
map, terrain); }
        int damage_against(const attack_type& attack) const { return 
resistance_against(attack); }
        int resistance_against(const attack_type& attack) const;
 
@@ -129,28 +156,17 @@
        void set_parent(const unit_movement_type* parent) { parent_ = parent; }
 
        bool is_flying() const;
-       const std::map<t_translation::t_terrain, int>& movement_costs() const { 
return moveCosts_; }
-       const std::map<t_translation::t_terrain, int>& defense_mods() const { 
return defenseMods_; }
 
        const config& get_cfg() const { return cfg_; }
        const unit_movement_type* get_parent() const { return parent_; }
 private:
        mutable std::map<t_translation::t_terrain, int> moveCosts_;
-       mutable std::map<t_translation::t_terrain, int> defenseMods_;
+       mutable defense_cache defenseMods_;
 
        const unit_movement_type* parent_;
 
        config cfg_;
 };
-
-int movement_cost_internal(std::map<t_translation::t_terrain, int>& move_costs,
-               const config& cfg, const unit_movement_type* parent,
-               const gamemap& map,     t_translation::t_terrain terrain, int 
recurse_count = 0);
-
-int defense_modifier_internal(std::map<t_translation::t_terrain, int>& 
defense_mods,
-               const config& cfg, const unit_movement_type* parent,
-               const gamemap& map, t_translation::t_terrain terrain, int 
recurse_count = 0);
-
 
 typedef std::map<std::string,unit_movement_type> movement_type_map;
 


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to