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