mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-03 18:17:20 +00:00
Updated parts of unit class to use t_token...
...in place of std:string in order to speed up comparisons, copies and hashing which are 1 cycle operations. Added z_sub t_token. Added lru_cache unit test
This commit is contained in:
parent
abb678b080
commit
576a3feab1
@ -545,6 +545,7 @@ test_sources = Split("""
|
||||
tests/test_image_modifications.cpp
|
||||
tests/test_interpolate_variables_into_thing.cpp
|
||||
tests/test_lexical_cast.cpp
|
||||
tests/test_lru_cache.cpp
|
||||
tests/test_network_worker.cpp
|
||||
tests/test_team.cpp
|
||||
tests/test_unit_map.cpp
|
||||
|
@ -57,6 +57,13 @@ static lg::log_domain log_ai("ai/general");
|
||||
#pragma warning(disable:4250)
|
||||
#endif
|
||||
|
||||
namespace{
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_chance_to_hit("chance_to_hit", false);
|
||||
static const config::t_token z_poison("poison", false);
|
||||
}
|
||||
|
||||
namespace ai {
|
||||
|
||||
typedef util::array<map_location,6> adjacent_tiles_array;
|
||||
@ -370,10 +377,10 @@ int ai_default_recruitment_stage::average_resistance_against(const unit_type& a,
|
||||
if (steadfast && resistance < 100)
|
||||
resistance = std::max<int>(resistance * 2 - 100, 50);
|
||||
// Do not look for filters or values, simply assume 70% if CTH is customized.
|
||||
int cth = i->get_special_bool("chance_to_hit", true) ? 70 : defense;
|
||||
int cth = i->get_special_bool(z_chance_to_hit, true) ? 70 : defense;
|
||||
int weight = i->damage() * i->num_attacks();
|
||||
// if cth == 0 the division will do 0/0 so don't execute this part
|
||||
if (living && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
if (living && cth != 0 && i->get_special_bool(z_poison, true)) {
|
||||
// Compute the probability of not poisoning the unit.
|
||||
int prob = 100;
|
||||
for (int j = 0; j < i->num_attacks(); ++j)
|
||||
|
@ -40,6 +40,15 @@ static lg::log_domain log_ai_testing_aspect_attacks("ai/aspect/attacks");
|
||||
#define LOG_AI LOG_STREAM(info, log_ai_testing_aspect_attacks)
|
||||
#define ERR_AI LOG_STREAM(err, log_ai_testing_aspect_attacks)
|
||||
|
||||
|
||||
namespace{
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_backstab("backstab", false);
|
||||
static const config::t_token z_slow("slow", false);
|
||||
static const config::t_token z_value("value", false);
|
||||
}
|
||||
|
||||
aspect_attacks::aspect_attacks(readonly_context &context, const config &cfg, const std::string &id)
|
||||
: typesafe_aspect<attacks_vector>(context,cfg,id)
|
||||
, filter_own_()
|
||||
@ -165,11 +174,11 @@ void aspect_attacks::do_attack_analysis(
|
||||
std::vector<attack_type>& attacks = unit_itor->attacks();
|
||||
for(std::vector<attack_type>::iterator a = attacks.begin(); a != attacks.end(); ++a) {
|
||||
a->set_specials_context(map_location(), map_location(), units_, true, NULL);
|
||||
if(a->get_special_bool("backstab")) {
|
||||
if(a->get_special_bool(z_backstab)) {
|
||||
backstab = true;
|
||||
}
|
||||
|
||||
if(a->get_special_bool("slow")) {
|
||||
if(a->get_special_bool(z_slow)) {
|
||||
slow = true;
|
||||
}
|
||||
}
|
||||
@ -255,7 +264,7 @@ void aspect_attacks::do_attack_analysis(
|
||||
}
|
||||
|
||||
unit_ability_list abil = unit_itor->get_abilities("leadership",tiles[j]);
|
||||
int best_leadership_bonus = abil.highest("value").first;
|
||||
int best_leadership_bonus = abil.highest(z_value).first;
|
||||
double leadership_bonus = static_cast<double>(best_leadership_bonus+100)/100.0;
|
||||
if (leadership_bonus > 1.1) {
|
||||
LOG_AI << unit_itor->name() << " is getting leadership " << leadership_bonus << "\n";
|
||||
|
@ -43,6 +43,15 @@ static lg::log_domain log_ai_testing_ai_default("ai/ca/testing_ai_default");
|
||||
#define ERR_AI_TESTING_AI_DEFAULT LOG_STREAM(err, log_ai_testing_ai_default)
|
||||
|
||||
|
||||
namespace{
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_chance_to_hit("chance_to_hit", false);
|
||||
static const config::t_token z_poison("poison", false);
|
||||
static const config::t_token z_guardian("guardian", false);
|
||||
}
|
||||
|
||||
|
||||
namespace ai {
|
||||
|
||||
namespace testing_ai_default {
|
||||
@ -414,10 +423,10 @@ int recruitment_phase::average_resistance_against(const unit_type& a, const unit
|
||||
if (steadfast && resistance < 100)
|
||||
resistance = std::max<int>(resistance * 2 - 100, 50);
|
||||
// Do not look for filters or values, simply assume 70% if CTH is customized.
|
||||
int cth = i->get_special_bool("chance_to_hit", true) ? 70 : defense;
|
||||
int cth = i->get_special_bool(z_chance_to_hit, true) ? 70 : defense;
|
||||
int weight = i->damage() * i->num_attacks();
|
||||
// if cth == 0 the division will do 0/0 so don't execute this part
|
||||
if (living && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
if (living && cth != 0 && i->get_special_bool(z_poison, true)) {
|
||||
// Compute the probability of not poisoning the unit.
|
||||
int prob = 100;
|
||||
for (int j = 0; j < i->num_attacks(); ++j)
|
||||
@ -1029,7 +1038,7 @@ void get_villages_phase::find_villages(
|
||||
}
|
||||
|
||||
const unit_map::const_iterator u = resources::units->find(j->second);
|
||||
if (u == resources::units->end() || u->get_state("guardian")) {
|
||||
if (u == resources::units->end() || u->get_state(z_guardian)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,12 @@
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace{
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_guardian("guardian", false);
|
||||
}
|
||||
|
||||
namespace ai {
|
||||
|
||||
namespace testing_ai_default {
|
||||
@ -292,7 +298,7 @@ std::pair<map_location,map_location> testing_move_to_targets_phase::choose_move(
|
||||
}
|
||||
|
||||
//guardian units stay put
|
||||
if (u->get_state("guardian")) {
|
||||
if (u->get_state(z_guardian)) {
|
||||
LOG_AI << u->type_id() << " is guardian, staying still\n";
|
||||
return std::make_pair(u->get_location(), u->get_location());
|
||||
}
|
||||
@ -386,7 +392,7 @@ std::pair<map_location,map_location> testing_move_to_targets_phase::choose_move(
|
||||
//now see if any other unit can put a better bid forward
|
||||
for(++u; u != units_.end(); ++u) {
|
||||
if (u->side() != get_side() || u->can_recruit() ||
|
||||
u->movement_left() <= 0 || u->get_state("guardian") ||
|
||||
u->movement_left() <= 0 || u->get_state(z_guardian) ||
|
||||
u->incapacitated())
|
||||
{
|
||||
continue;
|
||||
|
@ -41,6 +41,13 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
namespace{
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_chance_to_hit("chance_to_hit", false);
|
||||
static const config::t_token z_poison("poison", false);
|
||||
static const config::t_token z_guardian("guardian", false);
|
||||
}
|
||||
|
||||
namespace ai {
|
||||
|
||||
@ -299,10 +306,10 @@ static int average_resistance_against(const unit_type& a, const unit_type& b)
|
||||
if (steadfast && resistance < 100)
|
||||
resistance = std::max<int>(resistance * 2 - 100, 50);
|
||||
// Do not look for filters or values, simply assume 70% if CTH is customized.
|
||||
int cth = i->get_special_bool("chance_to_hit", true) ? 70 : defense;
|
||||
int cth = i->get_special_bool(z_chance_to_hit, true) ? 70 : defense;
|
||||
int weight = i->damage() * i->num_attacks();
|
||||
// if cth == 0 the division will do 0/0 so don't execute this part
|
||||
if (living && cth != 0 && i->get_special_bool("poison", true)) {
|
||||
if (living && cth != 0 && i->get_special_bool(z_poison, true)) {
|
||||
// Compute the probability of not poisoning the unit.
|
||||
int prob = 100;
|
||||
for (int j = 0; j < i->num_attacks(); ++j)
|
||||
|
@ -24,6 +24,12 @@
|
||||
#include "resources.hpp"
|
||||
#include "unit_abilities.hpp"
|
||||
|
||||
namespace {
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_damage("damage", false);
|
||||
}
|
||||
|
||||
// Conversion routine for both unscathed and damage change percentage.
|
||||
static void format_prob(char str_buf[10], double prob)
|
||||
{
|
||||
@ -158,7 +164,7 @@ void battle_prediction_pane::get_unit_strings(const battle_context_unit_stats& s
|
||||
weapon->set_specials_context(u_loc, opp_loc, *resources::units, stats.is_attacker, opp_weapon);
|
||||
|
||||
// Get damage modifiers.
|
||||
unit_ability_list dmg_specials = weapon->get_specials("damage");
|
||||
unit_ability_list dmg_specials = weapon->get_specials(z_damage);
|
||||
unit_abilities::effect dmg_effect(dmg_specials, weapon->damage(), stats.backstab_pos);
|
||||
|
||||
// Get the SET damage modifier, if any.
|
||||
|
@ -171,7 +171,8 @@ variant unit_callable::get_value(const std::string& key) const
|
||||
} else if(key == "leader") {
|
||||
return variant(u_.can_recruit());
|
||||
} else if(key == "undead") {
|
||||
return variant(u_.get_state("not_living") ? 1 : 0);
|
||||
static const config::t_token z_not_living("not_living");
|
||||
return variant(u_.get_state(z_not_living) ? 1 : 0);
|
||||
} else if(key == "attacks") {
|
||||
const std::vector<attack_type>& att = u_.attacks();
|
||||
std::vector<variant> res;
|
||||
@ -208,19 +209,19 @@ variant unit_callable::get_value(const std::string& key) const
|
||||
} else if(key == "attacks_left") {
|
||||
return variant(u_.attacks_left());
|
||||
} else if(key == "traits") {
|
||||
const std::vector<std::string> traits = u_.get_traits_list();
|
||||
const std::vector<config::t_token> traits = u_.get_traits_list();
|
||||
std::vector<variant> res;
|
||||
|
||||
if(traits.empty())
|
||||
return variant( &res );
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = traits.begin(); it != traits.end(); ++it)
|
||||
for (std::vector<config::t_token>::const_iterator it = traits.begin(); it != traits.end(); ++it)
|
||||
{
|
||||
res.push_back( variant(*it) );
|
||||
}
|
||||
return variant( &res );
|
||||
} else if(key == "states") {
|
||||
const std::map<std::string, std::string>& states_map = u_.get_states();
|
||||
const std::map<config::t_token, config::t_token>& states_map = u_.get_states();
|
||||
|
||||
return convert_map( states_map );
|
||||
} else if(key == "side") {
|
||||
|
@ -664,8 +664,8 @@ void config::remove_child(const t_token &key, unsigned index)
|
||||
|
||||
void config::remove_child(const std::string &key, unsigned index) {return remove_child(t_token( key ), index);}
|
||||
|
||||
#ifdef DEBUG
|
||||
//#define COUNT_THE_NUMBER_OF_STRING_TO_TOKEN_CONVERSIONS
|
||||
#ifdef COUNT_THE_NUMBER_OF_STRING_TO_TOKEN_CONVERSIONS
|
||||
namespace{
|
||||
static n_count_logger::t_count_logger<std::string> count_btok1("config index as std::string (BAD)",11);
|
||||
}
|
||||
@ -697,7 +697,7 @@ config::attribute_value &config::operator[](const attribute_value &key){
|
||||
return operator[](key.token());}
|
||||
|
||||
config::attribute_value &config::operator[](const std::string &key){
|
||||
#ifdef DEBUG
|
||||
#ifdef COUNT_THE_NUMBER_OF_STRING_TO_TOKEN_CONVERSIONS
|
||||
count_btok1.inc(key); //debug
|
||||
#endif
|
||||
return operator[](t_token(key));}
|
||||
|
@ -68,6 +68,9 @@ static lg::log_domain log_display("display");
|
||||
static lg::log_domain log_config("config");
|
||||
#define ERR_CF LOG_STREAM(err, log_config)
|
||||
|
||||
namespace{
|
||||
static const config::t_token z_advance("advance");
|
||||
}
|
||||
namespace dialogs
|
||||
{
|
||||
|
||||
@ -97,7 +100,7 @@ int advance_unit_dialog(const map_location &loc)
|
||||
{
|
||||
if (mod["always_display"].to_bool()) always_display = true;
|
||||
sample_units.push_back(::get_advanced_unit(*u, u->type_id()));
|
||||
sample_units.back().add_modification("advance", mod);
|
||||
sample_units.back().add_modification(z_advance, mod);
|
||||
const unit& type = sample_units.back();
|
||||
if (!mod["image"].empty()) {
|
||||
lang_options.push_back(IMAGE_PREFIX + mod["image"].str() + COLUMN_SEPARATOR + mod["description"].str());
|
||||
@ -224,7 +227,7 @@ bool animate_unit_advancement(const map_location &loc, size_t choice, const bool
|
||||
}
|
||||
|
||||
amla_unit.set_experience(amla_unit.experience() - amla_unit.max_experience());
|
||||
amla_unit.add_modification("advance",mod_option);
|
||||
amla_unit.add_modification(z_advance,mod_option);
|
||||
resources::units->replace(loc, amla_unit);
|
||||
|
||||
if(fire_event)
|
||||
@ -383,7 +386,7 @@ void save_preview_pane::draw_contents()
|
||||
#ifdef LOW_MEM
|
||||
const surface image(image::get_image(leader->image()));
|
||||
#else
|
||||
const surface image(image::get_image(leader->image() + "~RC(" + leader->flag_rgb() + ">1)"));
|
||||
const surface image(image::get_image(leader->image() + "~RC(" + static_cast<std::string const &>(leader->flag_rgb()) + ">1)"));
|
||||
#endif
|
||||
|
||||
if(image != NULL) {
|
||||
@ -977,7 +980,7 @@ const unit_types_preview_pane::details unit_types_preview_pane::get_details() co
|
||||
//FIXME: There should be a better way to deal with this
|
||||
unit_types.find(t->id(), unit_type::WITHOUT_ANIMATIONS);
|
||||
|
||||
std::string mod = "~RC(" + t->flag_rgb() + ">" + team::get_side_color_index(side_) + ")";
|
||||
std::string mod = "~RC(" + static_cast<std::string const &>(t->flag_rgb()) + ">" + team::get_side_color_index(side_) + ")";
|
||||
det.image = image::get_image(t->image()+mod);
|
||||
|
||||
det.name = "";
|
||||
|
@ -288,25 +288,6 @@ private:
|
||||
*/
|
||||
class t_operation_interp : public t_operation {
|
||||
|
||||
///interpolates the attribute_value value into a token
|
||||
///todo remove this once you can type x.token() where x is a config
|
||||
// struct do_interp_visitor : public boost::static_visitor<void> {
|
||||
// ///todo put back thonsew
|
||||
// // : public config::attribute_value::default_visitor {
|
||||
// // using default_visitor::operator();
|
||||
// t_token & self_;
|
||||
// do_interp_visitor(t_token & t):self_(t) {}
|
||||
// void operator()() { self_ = z_empty; }
|
||||
// void operator()(bool const b) {self_ = t_token(str_cast(b)); }
|
||||
// void operator()(int const i) {self_ = t_token(str_cast(i)); }
|
||||
// void operator()(double const d) {self_ = t_token( str_cast(d)); }
|
||||
// void operator()(n_token::t_token const & tok){self_ = tok; }
|
||||
// void operator()(const t_string &s){ self_=t_token(s);}
|
||||
// ///todo remove 3 lines
|
||||
// void operator()(boost::blank const &){self_ = z_empty; }
|
||||
// void operator()(std::string const & s){self_=t_token(s);}
|
||||
// };
|
||||
|
||||
public :
|
||||
|
||||
///Grab the top item on the stack, look it up in the variable set and append it to the second item on the stack
|
||||
@ -315,13 +296,6 @@ public :
|
||||
t_token var_name(stack.back());
|
||||
config::attribute_value stuffing(variable_set.get_variable_const(var_name ));
|
||||
DEBUG_INTERP << string(var_name, stuffing) << "\n";
|
||||
|
||||
///todo replace next 4 lines with this->lhs_ = stuffing.token();
|
||||
// t_token rhs;
|
||||
// do_interp_visitor visitor(rhs);
|
||||
// ///todo swap next 2
|
||||
// //stuffing.apply_visitor(visitor);
|
||||
// boost::apply_visitor(visitor, stuffing.to_value());
|
||||
|
||||
stack.pop_back();
|
||||
t_operation_append append(stuffing.token());
|
||||
|
@ -79,6 +79,201 @@ static lg::log_domain log_wml("wml");
|
||||
static lg::log_domain log_config("config");
|
||||
#define ERR_CF LOG_STREAM(err, log_config)
|
||||
|
||||
namespace{
|
||||
static const config::t_token z_id("id");
|
||||
static const config::t_token z_this_unit("this_unit");
|
||||
static const config::t_token z_variable("variable");
|
||||
static const config::t_token z_time_of_day("time_of_day");
|
||||
static const config::t_token z_x("x");
|
||||
static const config::t_token z_y("y");
|
||||
static const config::t_token z_x1("x1");
|
||||
static const config::t_token z_x2("x2");
|
||||
static const config::t_token z_y1("y1");
|
||||
static const config::t_token z_y2("y2");
|
||||
static const config::t_token z_have_unit("have_unit");
|
||||
static const config::t_token z_count("count");
|
||||
static const config::t_token z_search_recall_list("search_recall_list");
|
||||
static const config::t_token z_have_location("have_location");
|
||||
static const config::t_token z_name("name");
|
||||
static const config::t_token z_equals("equals");
|
||||
static const config::t_token z_not_equals("not_equals");
|
||||
static const config::t_token z_numerical_equals("numerical_equals");
|
||||
static const config::t_token z_numerical_not_equals("numerical_not_equals");
|
||||
static const config::t_token z_boolean_equals("boolean_equals");
|
||||
static const config::t_token z_boolean_not_equals("boolean_not_equals");
|
||||
static const config::t_token z_less_than("less_than");
|
||||
static const config::t_token z_greater_than("greater_than");
|
||||
static const config::t_token z_greater_than_equal_to("greater_than_equal_to");
|
||||
static const config::t_token z_less_than_equal_to("less_than_equal_to");
|
||||
static const config::t_token z_and("and");
|
||||
static const config::t_token z_or("or");
|
||||
static const config::t_token z_not("not");
|
||||
static const config::t_token z_contains("contains");
|
||||
static const config::t_token z_backwards_compat("backwards_compat");
|
||||
static const config::t_token z_logger("logger");
|
||||
static const config::t_token z_message("message");
|
||||
static const config::t_token z_side("side");
|
||||
static const config::t_token z_filter_side("filter_side");
|
||||
static const config::t_token z_remove("remove");
|
||||
static const config::t_token z_source("source");
|
||||
static const config::t_token z_target("target");
|
||||
static const config::t_token z_bidirectional("bidirectional");
|
||||
static const config::t_token z_check_passability("check_passability");
|
||||
static const config::t_token z_clear_shroud("clear_shroud");
|
||||
static const config::t_token z_animate("animate");
|
||||
static const config::t_token z_type("type");
|
||||
static const config::t_token z_filter("filter");
|
||||
static const config::t_token z_music("music");
|
||||
static const config::t_token z_sound("sound");
|
||||
static const config::t_token z_red("red");
|
||||
static const config::t_token z_green("green");
|
||||
static const config::t_token z_blue("blue");
|
||||
static const config::t_token z_turn("turn");
|
||||
static const config::t_token z_team_name("team_name");
|
||||
static const config::t_token z_user_team_name("user_team_name");
|
||||
static const config::t_token z_controller("controller");
|
||||
static const config::t_token z_recruit("recruit");
|
||||
static const config::t_token z_shroud_data("shroud_data");
|
||||
static const config::t_token z_ai("ai");
|
||||
static const config::t_token z_switch_ai("switch_ai");
|
||||
static const config::t_token z_income("income");
|
||||
static const config::t_token z_gold("gold");
|
||||
static const config::t_token z_shroud("shroud");
|
||||
static const config::t_token z_hidden("hidden");
|
||||
static const config::t_token z_fog("fog");
|
||||
static const config::t_token z_village_gold("village_gold");
|
||||
static const config::t_token z_value("value");
|
||||
static const config::t_token z_share_view("share_view");
|
||||
static const config::t_token z_add("add");
|
||||
static const config::t_token z_current("current");
|
||||
static const config::t_token z_turn_number("turn_number");
|
||||
static const config::t_token z_variation("variation");
|
||||
static const config::t_token z_image_mods("image_mods");
|
||||
static const config::t_token z_gender("gender");
|
||||
static const config::t_token z_effect("effect");
|
||||
static const config::t_token z_apply_to("apply_to");
|
||||
static const config::t_token z_fake_unit("fake_unit");
|
||||
static const config::t_token z_skip_steps("skip_steps");
|
||||
static const config::t_token z_literal("literal");
|
||||
static const config::t_token z_sub("sub");
|
||||
static const config::t_token z_multiply("multiply");
|
||||
static const config::t_token z_share_maps("share_maps");
|
||||
static const config::t_token z_image_mod("image_mod");
|
||||
static const config::t_token z_divide("divide");
|
||||
static const config::t_token z_modulo("modulo");
|
||||
static const config::t_token z_round("round");
|
||||
static const config::t_token z_ceil("ceil");
|
||||
static const config::t_token z_floor("floor");
|
||||
static const config::t_token z_ipart("ipart");
|
||||
static const config::t_token z_fpart("fpart");
|
||||
static const config::t_token z_string_length("string_length");
|
||||
static const config::t_token z_time("time");
|
||||
static const config::t_token z_stamp("stamp");
|
||||
static const config::t_token z_rand("rand");
|
||||
static const config::t_token z_join("join");
|
||||
static const config::t_token z_separator("separartor");
|
||||
static const config::t_token z_key("key");
|
||||
static const config::t_token z_to_variable("to_variable");
|
||||
static const config::t_token z_remove_empty("remove_empty");
|
||||
static const config::t_token z_mode("mode");
|
||||
static const config::t_token z_extend("extend");
|
||||
static const config::t_token z_append("append");
|
||||
static const config::t_token z_merge("merge");
|
||||
static const config::t_token z_insert("insert");
|
||||
static const config::t_token z_split("split");
|
||||
static const config::t_token z_replace("replace");
|
||||
static const config::t_token z_list("list");
|
||||
static const config::t_token z_role("role");
|
||||
static const config::t_token z_mask("mask");
|
||||
static const config::t_token z_border("border");
|
||||
static const config::t_token z_show("show");
|
||||
static const config::t_token z_fire_event("fire_event");
|
||||
static const config::t_token z_then("then");
|
||||
static const config::t_token z_object("object");
|
||||
static const config::t_token z_size("size");
|
||||
static const config::t_token z_text("text");
|
||||
static const config::t_token z_duration("duration");
|
||||
static const config::t_token z_secondary_unit("secondary_unit");
|
||||
static const config::t_token z_die("die");
|
||||
static const config::t_token z_needs_select("needs_select");
|
||||
static const config::t_token z_show_if("show_if");
|
||||
static const config::t_token z_filter_location("filter_location");
|
||||
static const config::t_token z_command("command");
|
||||
static const config::t_token z_find_vacant("find_vacant");
|
||||
static const config::t_token z_cannot_use_message("cannot_use_message");
|
||||
static const config::t_token z_recall("recall");
|
||||
static const config::t_token z_else("else");
|
||||
static const config::t_token z_silent("silent");
|
||||
//static const config::t_token z_("");
|
||||
static const config::t_token z_advance("advance");
|
||||
static const config::t_token z_choose("choose");
|
||||
static const config::t_token z_location("location");
|
||||
static const config::t_token z_owner_side("owner_side");
|
||||
static const config::t_token z_store_villages("store_villages");
|
||||
static const config::t_token z_next_scenario("next_scenario");
|
||||
static const config::t_token z_end_text("end_text");
|
||||
static const config::t_token z_end_text_duration("end_text_duration");
|
||||
static const config::t_token z_result("result");
|
||||
static const config::t_token z_victory("victory");
|
||||
static const config::t_token z_defeat("defeat");
|
||||
static const config::t_token z_carryover_report("carryover_report");
|
||||
static const config::t_token z_save("save");
|
||||
static const config::t_token z_linger_mode("linger_mode");
|
||||
static const config::t_token z_reveal_map("reveal_map");
|
||||
static const config::t_token z_bonus("bonus");
|
||||
static const config::t_token z_carryover_percentage("carryover_percentage");
|
||||
static const config::t_token z_carryover_add("carryover_add");
|
||||
static const config::t_token z_filter_second("filter_second");
|
||||
static const config::t_token z_heals("heals");
|
||||
static const config::t_token z_amount("amount");
|
||||
static const config::t_token z_moves("moves");
|
||||
static const config::t_token z_restore_attacks("restore_attacks");
|
||||
static const config::t_token z_restore_statuses("restore_statuses");
|
||||
static const config::t_token z_full("full");
|
||||
static const config::t_token z_heal_amount("heal_amount");
|
||||
static const config::t_token z_topic("topic");
|
||||
static const config::t_token z_speaker("speaker");
|
||||
static const config::t_token z_unit("unit");
|
||||
static const config::t_token z_second_unit("second_unit");
|
||||
static const config::t_token z_narrator("narrator");
|
||||
static const config::t_token z_caption("caption");
|
||||
static const config::t_token z_label("label");
|
||||
static const config::t_token z_option("option");
|
||||
static const config::t_token z_text_input("text_input");
|
||||
static const config::t_token z_max_length("max_length");
|
||||
static const config::t_token z_side_for("side_for");
|
||||
static const config::t_token z_scroll("scroll");
|
||||
static const config::t_token z_time_area("time_area");
|
||||
static const config::t_token z_input("input");
|
||||
static const config::t_token z_map("map");
|
||||
static const config::t_token z_delayed("delayed");
|
||||
static const config::t_token z_expand("expand");
|
||||
static const config::t_token z_shrink("shrink");
|
||||
static const config::t_token z_first_time_only("first_time_only");
|
||||
static const config::t_token z_allow_undo("allow_undo");
|
||||
static const config::t_token z_weapon("weapon");
|
||||
static const config::t_token z_first("first");
|
||||
static const config::t_token z_second("second");
|
||||
static const config::t_token z_second_weapon("second_weapon");
|
||||
static const config::t_token z_filter_condition("filter_condition");
|
||||
static const config::t_token z_filter_attack("filter_attack");
|
||||
static const config::t_token z_filter_second_attack("filter_second_attack");
|
||||
static const config::t_token z_handle_event_command("handle_event_command");
|
||||
static const config::t_token z_empty("empty");
|
||||
static const config::t_token z_event("event");
|
||||
static const config::t_token z_unit_wml_ids("unit_wml_ids");
|
||||
static const config::t_token z_used_items("used_items");
|
||||
static const config::t_token z_select("select");
|
||||
static const config::t_token z_delayed_variable_substitution("delayed_variable_substitution");
|
||||
// static const config::t_token z_("");
|
||||
// static const config::t_token z_("");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* State when processing a flight of events or commands.
|
||||
*/
|
||||
@ -1036,7 +1231,7 @@ game_display::fake_unit *create_fake_unit(const vconfig& cfg)
|
||||
config &effect = mod.add_child("effect");
|
||||
effect["apply_to"] = "variation";
|
||||
effect["name"] = variation;
|
||||
fake_unit->add_modification("variation",mod);
|
||||
fake_unit->add_modification(z_variation,mod);
|
||||
}
|
||||
|
||||
if(!img_mods.empty()) {
|
||||
@ -1044,7 +1239,7 @@ game_display::fake_unit *create_fake_unit(const vconfig& cfg)
|
||||
config &effect = mod.add_child("effect");
|
||||
effect["apply_to"] = "image_mod";
|
||||
effect["add"] = img_mods;
|
||||
fake_unit->add_modification("image_mod",mod);
|
||||
fake_unit->add_modification(z_image_mod,mod);
|
||||
}
|
||||
|
||||
return fake_unit;
|
||||
@ -1408,8 +1603,8 @@ WML_HANDLER_FUNCTION(set_variable, /*event_info*/, cfg)
|
||||
|
||||
|
||||
WML_HANDLER_FUNCTION(set_variables, /*event_info*/, cfg)
|
||||
{
|
||||
const t_string& name = cfg["name"];
|
||||
{
|
||||
const config::attribute_value & name = cfg["name"];
|
||||
variable_info dest(name, true, variable_info::TYPE_CONTAINER);
|
||||
|
||||
std::string mode = cfg["mode"]; // replace, append, merge, or insert
|
||||
@ -1441,7 +1636,7 @@ WML_HANDLER_FUNCTION(set_variables, /*event_info*/, cfg)
|
||||
{
|
||||
variable_info tovar(cfg["to_variable"], false, variable_info::TYPE_CONTAINER);
|
||||
if(tovar.is_valid()) {
|
||||
if(tovar.explicit_index) {
|
||||
if(tovar.is_explicit_index()) {
|
||||
data.add_child(dest.key, tovar.as_container());
|
||||
} else {
|
||||
variable_info::array_range range = tovar.as_array();
|
||||
@ -1497,7 +1692,7 @@ WML_HANDLER_FUNCTION(set_variables, /*event_info*/, cfg)
|
||||
}
|
||||
if(mode == "replace")
|
||||
{
|
||||
if(dest.explicit_index) {
|
||||
if(dest.is_explicit_index()) {
|
||||
dest.vars->remove_child(dest.key, dest.index);
|
||||
} else {
|
||||
dest.vars->clear_children(dest.key);
|
||||
@ -1507,7 +1702,7 @@ WML_HANDLER_FUNCTION(set_variables, /*event_info*/, cfg)
|
||||
{
|
||||
if(mode == "merge")
|
||||
{
|
||||
if(dest.explicit_index) {
|
||||
if(dest.is_explicit_index()) {
|
||||
// merging multiple children into a single explicit index
|
||||
// requires that they first be merged with each other
|
||||
data.merge_children(dest.key);
|
||||
@ -1515,7 +1710,7 @@ WML_HANDLER_FUNCTION(set_variables, /*event_info*/, cfg)
|
||||
} else {
|
||||
dest.vars->merge_with(data);
|
||||
}
|
||||
} else if(mode == "insert" || dest.explicit_index) {
|
||||
} else if(mode == "insert" || dest.is_explicit_index()) {
|
||||
foreach (const config &child, data.child_range(dest.key))
|
||||
{
|
||||
dest.vars->add_child_at(dest.key, child, dest.index++);
|
||||
@ -1548,7 +1743,7 @@ WML_HANDLER_FUNCTION(role, /*event_info*/, cfg)
|
||||
unit_map::iterator itor;
|
||||
foreach (unit &u, *resources::units) {
|
||||
if (game_events::unit_matches_filter(u, filter)) {
|
||||
u.set_role(cfg["role"]);
|
||||
u.set_role(cfg[z_role].token());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -1585,7 +1780,7 @@ WML_HANDLER_FUNCTION(role, /*event_info*/, cfg)
|
||||
unit& u = pi->recall_list()[i];
|
||||
scoped_recall_unit auto_store("this_unit", player_id, i);
|
||||
if (u.matches_filter(filter, map_location())) {
|
||||
u.set_role(cfg["role"]);
|
||||
u.set_role(cfg[z_role].token());
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
@ -1796,7 +1991,7 @@ WML_HANDLER_FUNCTION(object, event_info, cfg)
|
||||
{
|
||||
text = cfg["description"].str();
|
||||
|
||||
u->add_modification("object", cfg.get_parsed_config());
|
||||
u->add_modification(z_object, cfg.get_parsed_config());
|
||||
|
||||
resources::screen->select_hex(event_info.loc1);
|
||||
resources::screen->invalidate_unit();
|
||||
|
@ -170,8 +170,7 @@ namespace{
|
||||
static const config::t_token z_scroll_to_leader("scroll_to_leader", false);
|
||||
static const config::t_token z_color_lock("color_lock", false);
|
||||
static const config::t_token z_faction("faction", false);
|
||||
static const config::t_token z_image("image", false);
|
||||
static const config::t_token z_description("description", false);
|
||||
static const config::t_token z_empty("", false);
|
||||
}
|
||||
|
||||
game_classification::game_classification():
|
||||
@ -500,7 +499,7 @@ void extract_summary_from_config(config& cfg_save, config& cfg_summary)
|
||||
cfg_summary[z_campaign] = cfg_save[z_campaign];
|
||||
cfg_summary[z_difficulty] = cfg_save[z_difficulty];
|
||||
cfg_summary[z_version] = cfg_save[z_version];
|
||||
cfg_summary[z_corrupt] = "";
|
||||
cfg_summary[z_corrupt] = z_empty;
|
||||
|
||||
if(has_snapshot) {
|
||||
cfg_summary[z_turn] = cfg_snapshot[z_turn_at];
|
||||
@ -559,7 +558,7 @@ void extract_summary_from_config(config& cfg_save, config& cfg_summary)
|
||||
|
||||
cfg_summary[z_leader] = leader;
|
||||
cfg_summary[z_leader_image] = leader_image;
|
||||
cfg_summary[z_map_data] = "";
|
||||
cfg_summary[z_map_data] = z_empty;
|
||||
|
||||
if(!shrouded) {
|
||||
if(has_snapshot) {
|
||||
@ -578,6 +577,7 @@ config::attribute_value &game_state::get_variable(const config::t_token& key) {
|
||||
return variable_info(key, true, variable_info::TYPE_SCALAR).as_scalar(); }
|
||||
|
||||
config::attribute_value game_state::get_variable_const(const config::t_token &key) const {
|
||||
|
||||
variable_info to_get(key, false, variable_info::TYPE_SCALAR);
|
||||
if (!to_get.is_valid()) {
|
||||
config::attribute_value &to_return = temporaries_[key];
|
||||
@ -607,7 +607,7 @@ config& game_state::add_variable_cfg(const config::t_token& key, const config& v
|
||||
void game_state::clear_variable_cfg(const config::t_token& varname) {
|
||||
variable_info to_clear(varname, false, variable_info::TYPE_CONTAINER);
|
||||
if(!to_clear.is_valid()) return;
|
||||
if(to_clear.explicit_index) {
|
||||
if(to_clear.is_explicit_index()) {
|
||||
to_clear.vars->remove_child(to_clear.key, to_clear.index);
|
||||
} else {
|
||||
to_clear.vars->clear_children(to_clear.key);
|
||||
@ -617,7 +617,7 @@ void game_state::clear_variable_cfg(const config::t_token& varname) {
|
||||
void game_state::clear_variable(const config::t_token& varname) {
|
||||
variable_info to_clear(varname, false);
|
||||
if(!to_clear.is_valid()) return;
|
||||
if(to_clear.explicit_index) {
|
||||
if(to_clear.is_explicit_index()) {
|
||||
to_clear.vars->remove_child(to_clear.key, to_clear.index);
|
||||
} else {
|
||||
to_clear.vars->clear_children(to_clear.key);
|
||||
|
@ -34,6 +34,14 @@
|
||||
#include <cassert>
|
||||
#include <ctime>
|
||||
|
||||
namespace {
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_swarm("swarm", false);
|
||||
static const config::t_token z_swarm_attacks_min("swarm_attacks_min", false);
|
||||
static const config::t_token z_swarm_attacks_max("swarm_attacks_max", false);
|
||||
}
|
||||
|
||||
static void add_text(config &report, const std::string &text,
|
||||
const std::string &tooltip, const std::string &help = "")
|
||||
{
|
||||
@ -432,11 +440,11 @@ REPORT_GENERATOR(unit_weapons)
|
||||
|
||||
int base_nattacks = at.num_attacks();
|
||||
int nattacks = base_nattacks;
|
||||
unit_ability_list swarm = at.get_specials("swarm");
|
||||
unit_ability_list swarm = at.get_specials(z_swarm);
|
||||
if (!swarm.empty())
|
||||
{
|
||||
int swarm_max_attacks = swarm.highest("swarm_attacks_max", nattacks).first;
|
||||
int swarm_min_attacks = swarm.highest("swarm_attacks_min").first;
|
||||
int swarm_max_attacks = swarm.highest(z_swarm_attacks_max, nattacks).first;
|
||||
int swarm_min_attacks = swarm.highest(z_swarm_attacks_min).first;
|
||||
int hitp = u->hitpoints();
|
||||
int mhitp = u->max_hitpoints();
|
||||
nattacks = swarm_min_attacks + (swarm_max_attacks - swarm_min_attacks) * hitp / mhitp;
|
||||
|
@ -1342,12 +1342,12 @@ static int intf_fire_event(lua_State *L)
|
||||
static int intf_get_variable(lua_State *L)
|
||||
{
|
||||
char const *m = luaL_checkstring(L, 1);
|
||||
variable_info v(m, false, variable_info::TYPE_SCALAR);
|
||||
variable_info v(config::t_token(m), false, variable_info::TYPE_SCALAR);
|
||||
if (v.is_valid()) {
|
||||
luaW_pushscalar(L, v.as_scalar());
|
||||
return 1;
|
||||
} else {
|
||||
variable_info w(m, false, variable_info::TYPE_CONTAINER);
|
||||
variable_info w(config::t_token(m), false, variable_info::TYPE_CONTAINER);
|
||||
if (w.is_valid()) {
|
||||
lua_newtable(L);
|
||||
if (lua_toboolean(L, 2))
|
||||
@ -1371,7 +1371,8 @@ static int intf_set_variable(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
variable_info v(m);
|
||||
config::t_token mm(m);
|
||||
variable_info v(mm);
|
||||
switch (lua_type(L, 2)) {
|
||||
case LUA_TBOOLEAN:
|
||||
v.as_scalar() = bool(lua_toboolean(L, 2));
|
||||
|
@ -371,7 +371,7 @@ void terrain_filter::get_locations(t_maploc_set& locs, bool with_border, gamemap
|
||||
variable_info vi(cfg_[z_find_in].token(), false, variable_info::TYPE_CONTAINER);
|
||||
if(!vi.is_valid()) {
|
||||
xy_set.clear();
|
||||
} else if(vi.explicit_index) {
|
||||
} else if(vi.is_explicit_index()) {
|
||||
map_location test_loc(vi.as_container(),NULL);
|
||||
if(xy_set.count(test_loc)) {
|
||||
xy_set.clear();
|
||||
|
@ -42,7 +42,7 @@ namespace{
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_1 ) {
|
||||
#ifdef DEBUG
|
||||
lg::set_log_domain_severity("interpolate", 0); //4 is debug comments
|
||||
// lg::set_log_domain_severity("interpolate", 0); //4 is debug comments
|
||||
#endif
|
||||
utils::string_map symbols;
|
||||
std::string nothing = "no change";
|
||||
|
67
src/tests/test_lru_cache.cpp
Normal file
67
src/tests/test_lru_cache.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2008 - 2011 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of thie Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "utils/lru_cache.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
/*
|
||||
./test --report_level=detailed --log_level=all --run_test=lru_cache_suite
|
||||
|
||||
*/
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( lru_cache_suite )
|
||||
|
||||
namespace{
|
||||
static const uint CACHE_SIZE = 10;
|
||||
static const uint STEP_SIZE = 1000;
|
||||
|
||||
void check_equal(int l, int r) {
|
||||
int ll(l + STEP_SIZE);
|
||||
BOOST_CHECK_MESSAGE(ll == r, "\nLeft \""<< ll <<"\"" << "should equal right \""<<r<<"\"\n"); }
|
||||
void check_not_equal(int l, int r) {
|
||||
int ll(l + STEP_SIZE);
|
||||
BOOST_CHECK_MESSAGE(ll != r, "\nLeft \""<< ll <<"\"" << "should not equal right \""<<r<<"\"\n"); }
|
||||
|
||||
struct t_gen_cache_item {
|
||||
int operator()(int const & in) const {
|
||||
return in + STEP_SIZE ; }
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_lru_cache1 ) {
|
||||
|
||||
|
||||
typedef n_lru_cache::t_lru_cache<int, int, t_gen_cache_item> t_cache;
|
||||
|
||||
static t_cache cache( t_gen_cache_item(), CACHE_SIZE);
|
||||
|
||||
|
||||
for (int i = 1; i<20; ++i){
|
||||
int from_cache(cache.check( i ));
|
||||
int hit_me(cache.check( 1 ));
|
||||
|
||||
cache.invalidate(4);
|
||||
|
||||
check_equal(1, hit_me);
|
||||
check_equal(i, from_cache);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4: */
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
1274
src/unit.cpp
1274
src/unit.cpp
File diff suppressed because it is too large
Load Diff
183
src/unit.hpp
183
src/unit.hpp
@ -26,6 +26,17 @@ class game_display;
|
||||
class game_state;
|
||||
class vconfig;
|
||||
class team;
|
||||
typedef std::vector<team> t_teams;
|
||||
|
||||
namespace{
|
||||
static const config::t_token z_description("description", false);
|
||||
// static const config::t_token z_advancement("advancement", false);
|
||||
static const config::t_token z_ellipse("ellipse", false);
|
||||
static const config::t_token z_image("image", false);
|
||||
static const config::t_token z_halo("halo", false);
|
||||
static const config::t_token z_usage("usage", false);
|
||||
//static const config::t_token z_("", false);
|
||||
}
|
||||
|
||||
class unit_ability_list
|
||||
{
|
||||
@ -37,8 +48,8 @@ public:
|
||||
|
||||
bool empty() const;
|
||||
|
||||
std::pair<int,map_location> highest(const std::string& key, int def=0) const;
|
||||
std::pair<int,map_location> lowest(const std::string& key, int def=0) const;
|
||||
std::pair<int,map_location> highest(const config::t_token& key, int def=0) const;
|
||||
std::pair<int,map_location> lowest(const config::t_token& key, int def=0) const;
|
||||
|
||||
std::vector<std::pair<const config *, map_location> > cfgs;
|
||||
};
|
||||
@ -85,24 +96,24 @@ public:
|
||||
const unit_type* type() const;
|
||||
|
||||
/** id assigned by wml */
|
||||
const std::string& id() const { if (id_.empty()) return type_name(); else return id_; }
|
||||
const std::string& id() const { if (id_.empty()){ return type_name();} else return id_; }
|
||||
/** The unique internal ID of the unit */
|
||||
size_t underlying_id() const { return underlying_id_; }
|
||||
|
||||
/** The unit type name */
|
||||
const t_string& type_name() const {return type_name_;}
|
||||
const std::string& undead_variation() const {return undead_variation_;}
|
||||
const config::t_token& undead_variation() const {return undead_variation_;}
|
||||
|
||||
/** The unit name for display */
|
||||
const t_string &name() const { return name_; }
|
||||
void set_name(const t_string &name) { name_ = name; }
|
||||
void rename(const std::string& name) {if (!unrenamable_) name_= name;}
|
||||
void rename(const std::string& name) {if (!unrenamable_) name_= t_string(name);}
|
||||
|
||||
/** The unit's profile */
|
||||
std::string small_profile() const;
|
||||
std::string big_profile() const;
|
||||
/** Information about the unit -- a detailed description of it */
|
||||
t_string unit_description() const { return cfg_["description"]; }
|
||||
t_string unit_description() const { return cfg_[z_description]; }
|
||||
|
||||
int hitpoints() const { return hit_points_; }
|
||||
int max_hitpoints() const { return max_hit_points_; }
|
||||
@ -122,7 +133,7 @@ public:
|
||||
bool unrenamable() const { return unrenamable_; }
|
||||
int side() const { return side_; }
|
||||
std::string side_id() const;
|
||||
const std::string& team_color() const { return flag_rgb_; }
|
||||
const config::t_token& team_color() const { return flag_rgb_; }
|
||||
unit_race::GENDER gender() const { return gender_; }
|
||||
void set_side(unsigned int new_side) { side_ = new_side; }
|
||||
fixed_t alpha() const { return alpha_; }
|
||||
@ -157,35 +168,43 @@ public:
|
||||
bool resting() const { return resting_; }
|
||||
void set_resting(bool rest) { resting_ = rest; }
|
||||
|
||||
const std::map<std::string,std::string> get_states() const;
|
||||
bool get_state(const std::string& state) const;
|
||||
void set_state(const std::string &state, bool value);
|
||||
const std::map<config::t_token,config::t_token> get_states() const;
|
||||
bool get_state(const config::t_token& state) const;
|
||||
void set_state(const config::t_token &state, bool value);
|
||||
enum state_t { STATE_SLOWED = 0, STATE_POISONED, STATE_PETRIFIED,
|
||||
STATE_UNCOVERED, STATE_NOT_MOVED, STATE_UNHEALABLE, STATE_UNKNOWN = -1 };
|
||||
void set_state(state_t state, bool value);
|
||||
bool get_state(state_t state) const;
|
||||
static state_t get_known_boolean_state_id(const std::string &state);
|
||||
static std::map<std::string, state_t> get_known_boolean_state_names();
|
||||
static state_t get_known_boolean_state_id(const config::t_token &state);
|
||||
static std::map<config::t_token, state_t> get_known_boolean_state_names();
|
||||
|
||||
bool has_moved() const { return movement_left() != total_movement(); }
|
||||
bool has_goto() const { return get_goto().valid(); }
|
||||
bool emits_zoc() const { return emit_zoc_ && !incapacitated();}
|
||||
bool matches_id(const std::string& unit_id) const;
|
||||
bool matches_idt(const config::t_token& unit_id) const{ return id_ == unit_id; }
|
||||
bool matches_id(const std::string& unit_id) const {return matches_idt(config::t_token(unit_id));}
|
||||
/* cfg: standard unit filter */
|
||||
bool matches_filter(const vconfig& cfg,const map_location& loc,bool use_flat_tod=false) const;
|
||||
bool matches_filter(const vconfig& cfg,const map_location& loc,bool use_flat_tod=false
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager) const;
|
||||
const std::vector<std::string>& overlays() const { return overlays_; }
|
||||
|
||||
void write(config& cfg) const;
|
||||
|
||||
void set_role(const std::string& role) { role_ = role; }
|
||||
const std::string &get_role() const { return role_; }
|
||||
void set_role(const config::t_token& role) { role_ = role; }
|
||||
void set_role(const std::string& role) { set_role(role);}
|
||||
const config::t_token &get_role() const { return role_; }
|
||||
|
||||
void assign_ai_special(const std::string& s) { ai_special_ = s;}
|
||||
std::string get_ai_special() const { return(ai_special_); }
|
||||
void assign_ai_special(const config::t_token& s) { ai_special_ = s;}
|
||||
config::t_token get_ai_special() const { return(ai_special_); }
|
||||
const std::vector<attack_type>& attacks() const { return attacks_; }
|
||||
std::vector<attack_type>& attacks() { return attacks_; }
|
||||
|
||||
int damage_from(const attack_type& attack,bool attacker,const map_location& loc) const { return resistance_against(attack,attacker,loc); }
|
||||
int damage_from(const attack_type& attack,bool attacker,const map_location& loc) const {
|
||||
return resistance_against(attack,attacker,loc); }
|
||||
|
||||
/** A SDL surface, ready for display for place where we need a still-image of the unit. */
|
||||
const surface still_image(bool scaled = false) const;
|
||||
@ -210,7 +229,7 @@ public:
|
||||
bool invalidate(const map_location &loc);
|
||||
const std::vector<t_string>& trait_names() const { return trait_names_; }
|
||||
const std::vector<t_string>& trait_descriptions() const { return trait_descriptions_; }
|
||||
std::vector<std::string> get_traits_list() const;
|
||||
std::vector<config::t_token> get_traits_list() const;
|
||||
|
||||
int cost () const { return unit_value_; }
|
||||
|
||||
@ -229,11 +248,11 @@ public:
|
||||
bool is_flying() const { return flying_; }
|
||||
bool is_fearless() const { return is_fearless_; }
|
||||
bool is_healthy() const { return is_healthy_; }
|
||||
int movement_cost(const t_translation::t_terrain terrain) const;
|
||||
int defense_modifier(t_translation::t_terrain terrain) const;
|
||||
int movement_cost(const t_translation::t_terrain terrain, gamemap const & game_map = *resources::game_map) const;
|
||||
int defense_modifier(t_translation::t_terrain terrain, gamemap const & game_map = *resources::game_map ) const;
|
||||
int resistance_against(const std::string& damage_name,bool attacker,const map_location& loc) const;
|
||||
int resistance_against(const attack_type& damage_type,bool attacker,const map_location& loc) const
|
||||
{return resistance_against(damage_type.type(), attacker, loc);};
|
||||
int resistance_against(const attack_type& damage_type,bool attacker,const map_location& loc) const {
|
||||
return resistance_against(damage_type.type(), attacker, loc);};
|
||||
|
||||
//return resistances without any abilities applied
|
||||
utils::string_map get_base_resistances() const;
|
||||
@ -247,12 +266,16 @@ public:
|
||||
|
||||
std::vector<config> get_modification_advances() const;
|
||||
config::const_child_itors modification_advancements() const
|
||||
{ return cfg_.child_range("advancement"); }
|
||||
{ return cfg_.child_range(z_advancement); }
|
||||
|
||||
size_t modification_count(const std::string& type, const std::string& id) const;
|
||||
size_t modification_count(const config::t_token& type, const std::string& id) const;
|
||||
|
||||
void add_modification(const std::string& type, const config& modification,
|
||||
bool no_add=false);
|
||||
void add_modification(const config::t_token& type, const config& mod, bool no_add=false
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager);
|
||||
|
||||
bool move_interrupted() const { return movement_left() > 0 && interrupted_move_.x >= 0 && interrupted_move_.y >= 0; }
|
||||
const map_location& get_interrupted_move() const { return interrupted_move_; }
|
||||
@ -268,15 +291,15 @@ public:
|
||||
Uint32 text_color = 0, STATE state = STATE_ANIM);
|
||||
|
||||
/** The name of the file to game_display (used in menus). */
|
||||
std::string absolute_image() const { return cfg_["image"]; }
|
||||
std::string image_halo() const { return cfg_["halo"]; }
|
||||
std::string absolute_image() const { return cfg_[z_image]; }
|
||||
config::t_token image_halo() const { return cfg_[z_halo]; }
|
||||
|
||||
std::string image_ellipse() const { return cfg_["ellipse"]; }
|
||||
config::t_token image_ellipse() const { return cfg_[z_ellipse]; }
|
||||
|
||||
config &variables() { return variables_; }
|
||||
const config &variables() const { return variables_; }
|
||||
|
||||
std::string usage() const { return cfg_["usage"]; }
|
||||
config::t_token usage() const { return cfg_[z_usage]; }
|
||||
unit_type::ALIGNMENT alignment() const { return alignment_; }
|
||||
const unit_race* race() const { return race_; }
|
||||
|
||||
@ -288,15 +311,32 @@ public:
|
||||
const attack_type* attack=NULL,const attack_type* second_attack = NULL,
|
||||
int swing_num =0) const;
|
||||
|
||||
bool get_ability_bool(const std::string& ability, const map_location& loc) const;
|
||||
bool get_ability_bool(const std::string &ability) const
|
||||
{ return get_ability_bool(ability, loc_); }
|
||||
unit_ability_list get_abilities(const std::string &ability, const map_location& loc) const;
|
||||
unit_ability_list get_abilities(const std::string &ability) const
|
||||
{ return get_abilities(ability, loc_); }
|
||||
bool get_ability_bool(const config::t_token& ability, const map_location& loc
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager) const;
|
||||
bool get_ability_bool(const config::t_token& ability
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager) const {
|
||||
return get_ability_bool(ability, loc_, game_map, units, teams, lua_kernel, tod_manager);}
|
||||
inline bool get_ability_bool(const std::string& ability, const map_location& loc ) const {
|
||||
return get_ability_bool(config::t_token(ability), loc); }
|
||||
inline bool get_ability_bool(const std::string& ability) const {
|
||||
return get_ability_bool(config::t_token(ability), loc_); }
|
||||
unit_ability_list get_abilities(const config::t_token &ability, const map_location& loc) const;
|
||||
unit_ability_list get_abilities(const config::t_token &ability) const {return get_abilities(ability, loc_); }
|
||||
unit_ability_list get_abilities(const std::string &ability, const map_location& loc) const {
|
||||
return get_abilities(config::t_token(ability), loc);}
|
||||
unit_ability_list get_abilities(const std::string &ability) const {return get_abilities(config::t_token(ability), loc_); }
|
||||
std::vector<std::string> ability_tooltips(bool force_active = false) const;
|
||||
std::vector<std::string> get_ability_list() const;
|
||||
bool has_ability_type(const std::string& ability) const;
|
||||
bool has_ability_type(const config::t_token& ability) const;
|
||||
bool has_ability_type(const std::string& ability) const {return has_ability_type(config::t_token(ability));}
|
||||
|
||||
const game_logic::map_formula_callable_ptr& formula_vars() const { return formula_vars_; }
|
||||
void add_formula_var(std::string str, variant var);
|
||||
@ -313,7 +353,7 @@ public:
|
||||
void generate_name(rand_rng::simple_rng *rng = 0);
|
||||
|
||||
// Only see_all=true use caching
|
||||
bool invisible(const map_location& loc, bool see_all=true) const;
|
||||
bool invisible(const map_location& loc, bool see_all=true,unit_map const & units = *resources::units, t_teams const & teams = *resources::teams) const;
|
||||
|
||||
/** Mark this unit as clone so it can be inserted to unit_map
|
||||
* @returns self (for convenience)
|
||||
@ -338,15 +378,37 @@ public:
|
||||
private:
|
||||
void advance_to(const config &old_cfg, const unit_type *t,
|
||||
bool use_traits, game_state *state);
|
||||
bool internal_matches_filter(const vconfig& cfg, const map_location& loc, bool use_flat_tod
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager) const;
|
||||
|
||||
bool internal_matches_filter(const vconfig& cfg,const map_location& loc,
|
||||
bool use_flat_tod) const;
|
||||
/*
|
||||
* cfg: an ability WML structure
|
||||
*/
|
||||
bool ability_active(const std::string& ability,const config& cfg,const map_location& loc) const;
|
||||
bool ability_affects_adjacent(const std::string& ability,const config& cfg,int dir,const map_location& loc) const;
|
||||
bool ability_affects_self(const std::string& ability,const config& cfg,const map_location& loc) const;
|
||||
bool ability_active(const std::string& ability,const config& cfg,const map_location& loc
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager) const;
|
||||
|
||||
bool ability_affects_adjacent(const std::string& ability,const config& cfg,int dir,const map_location& loc
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager) const;
|
||||
bool ability_affects_self(const std::string& ability,const config& cfg,const map_location& loc
|
||||
, gamemap const & game_map = *resources::game_map
|
||||
, unit_map const & units =*resources::units
|
||||
, t_teams const & teams = *resources::teams
|
||||
, LuaKernel & lua_kernel = *resources::lua_kernel
|
||||
, tod_manager const & tod_manager = *resources::tod_manager) const;
|
||||
bool resistance_filter_matches(const config& cfg,bool attacker,const std::string& damage_name, int res) const;
|
||||
|
||||
bool has_ability_by_id(const std::string& ability) const;
|
||||
@ -363,12 +425,12 @@ private:
|
||||
std::vector<std::string> advances_to_;
|
||||
std::string type_;
|
||||
const unit_race* race_;
|
||||
std::string id_;
|
||||
config::t_token id_;
|
||||
t_string name_;
|
||||
size_t underlying_id_;
|
||||
t_string type_name_;
|
||||
std::string undead_variation_;
|
||||
std::string variation_;
|
||||
config::t_token undead_variation_;
|
||||
config::t_token variation_;
|
||||
|
||||
int hit_points_;
|
||||
int max_hit_points_;
|
||||
@ -378,7 +440,7 @@ private:
|
||||
bool canrecruit_;
|
||||
std::vector<std::string> recruit_list_;
|
||||
unit_type::ALIGNMENT alignment_;
|
||||
std::string flag_rgb_;
|
||||
config::t_token flag_rgb_;
|
||||
std::string image_mods_;
|
||||
|
||||
bool unrenamable_;
|
||||
@ -402,17 +464,17 @@ private:
|
||||
int attacks_left_;
|
||||
int max_attacks_;
|
||||
|
||||
std::set<std::string> states_;
|
||||
std::set<config::t_token> states_;
|
||||
std::vector<bool> known_boolean_states_;
|
||||
static std::map<std::string, state_t> known_boolean_state_names_;
|
||||
static std::map<config::t_token, state_t> known_boolean_state_names_;
|
||||
config variables_;
|
||||
bool emit_zoc_;
|
||||
STATE state_;
|
||||
|
||||
std::vector<std::string> overlays_;
|
||||
|
||||
std::string role_;
|
||||
std::string ai_special_;
|
||||
config::t_token role_;
|
||||
config::t_token ai_special_;
|
||||
std::vector<attack_type> attacks_;
|
||||
map_location::DIRECTION facing_;
|
||||
|
||||
@ -444,7 +506,7 @@ private:
|
||||
friend void attack_type::set_specials_context(const map_location& loc, const map_location&, const unit& un, bool) const;
|
||||
|
||||
/** Hold the visibility status cache for a unit, mutable since it's a cache. */
|
||||
mutable std::map<map_location, bool> invisibility_cache_;
|
||||
mutable boost::unordered_map<map_location, bool> invisibility_cache_;
|
||||
|
||||
/**
|
||||
* Clears the cache.
|
||||
@ -467,18 +529,21 @@ private:
|
||||
};
|
||||
|
||||
/** Returns the number of units of the side @a side_num. */
|
||||
int side_units(int side_num);
|
||||
int side_units(int side_num, unit_map const & units = *resources::units) ;
|
||||
|
||||
/** Returns the total cost of units of side @a side_num. */
|
||||
int side_units_cost(int side_num);
|
||||
int side_units_cost(int side_num, unit_map const & units = *resources::units);
|
||||
|
||||
int side_upkeep(int side_num);
|
||||
int side_upkeep(int side_num, unit_map const & units = *resources::units);
|
||||
|
||||
unit_map::iterator find_visible_unit(const map_location &loc,
|
||||
const team ¤t_team, bool see_all = false);
|
||||
//The ackward orderding here allows the linker to disambiguate the return type using the passed in unit_map
|
||||
unit_map::const_iterator find_visible_unit(unit_map const & units, const map_location &loc, const team ¤t_team, bool const see_all = false, gamemap const & map = *resources::game_map);
|
||||
unit_map::iterator find_visible_unit(unit_map & units, const map_location &loc, const team ¤t_team, bool const see_all = false, gamemap const & map = *resources::game_map);
|
||||
|
||||
unit *get_visible_unit(const map_location &loc,
|
||||
const team ¤t_team, bool see_all = false);
|
||||
inline unit_map::iterator find_visible_unit(const map_location &loc, const team ¤t_team, bool const see_all = false) {
|
||||
return find_visible_unit( *resources::units, loc, current_team, see_all, *resources::game_map); }
|
||||
|
||||
unit *get_visible_unit(const map_location &loc, const team ¤t_team, bool const see_all = false, gamemap const & map = *resources::game_map, unit_map & units = *resources::units);
|
||||
|
||||
struct team_data
|
||||
{
|
||||
|
@ -105,40 +105,100 @@ A poisoned unit cannot be cured of its poison by a healer, and must seek the car
|
||||
*/
|
||||
|
||||
|
||||
namespace {
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_affect_allies("affect_allies", false);
|
||||
static const config::t_token z_affect_enemies("affect_enemies", false);
|
||||
static const config::t_token z_affect_self("affect_self", false);
|
||||
static const config::t_token z_abilities("abilities", false);
|
||||
static const config::t_token z_id("id", false);
|
||||
static const config::t_token z_female("female", false);
|
||||
static const config::t_token z_female_name("female_name", false);
|
||||
static const config::t_token z_name("name", false);
|
||||
static const config::t_token z_name_inactive("name_inactive", false);
|
||||
static const config::t_token z_female_name_inactive("female_name_inactive", false);
|
||||
static const config::t_token z_description_inactive("description_inactive", false);
|
||||
static const config::t_token z_illuminates("illuminates", false);
|
||||
static const config::t_token z_filter("filter", false);
|
||||
static const config::t_token z_filter_adjacent("filter_adjacent", false);
|
||||
static const config::t_token z_filter_adjacent_location("filter_adjacent_location", false);
|
||||
static const config::t_token z_adjacent("adjacent", false);
|
||||
static const config::t_token z_n("n", false);
|
||||
static const config::t_token z_ne("ne", false);
|
||||
static const config::t_token z_se("se", false);
|
||||
static const config::t_token z_s("s", false);
|
||||
static const config::t_token z_sw("sw", false);
|
||||
static const config::t_token z_nw("nw", false);
|
||||
static const config::t_token z_affect_adjacent("affect_adjacent", false);
|
||||
static const config::t_token z_filter_self("filter_self", false);
|
||||
static const config::t_token z_cumulative("cumulative", false);
|
||||
static const config::t_token z_specials("specials", false);
|
||||
static const config::t_token z_apply_to("apply_to", false);
|
||||
static const config::t_token z_both("both", false);
|
||||
static const config::t_token z_opponent("opponent", false);
|
||||
static const config::t_token z_defender("defender", false);
|
||||
static const config::t_token z_attacker("attacker", false);
|
||||
static const config::t_token z_filter_base_value("filter_base_value", false);
|
||||
static const config::t_token z_equals("equals", false);
|
||||
static const config::t_token z_not_equals("not_equals", false);
|
||||
static const config::t_token z_less_than("less_than", false);
|
||||
static const config::t_token z_greater_than("greater_than", false);
|
||||
static const config::t_token z_greater_than_equal_to("greater_than_equal_to", false);
|
||||
static const config::t_token z_less_than_equal_to("less_than_equal_to", false);
|
||||
static const config::t_token z_backstab("backstab", false);
|
||||
static const config::t_token z_value("value", false);
|
||||
static const config::t_token z_add("add", false);
|
||||
static const config::t_token z_sub("sub", false);
|
||||
static const config::t_token z_multiply("multiply", false);
|
||||
static const config::t_token z_active_on("active_on", false);
|
||||
static const config::t_token z_offense("offense", false);
|
||||
static const config::t_token z_filter_weapon("filter_weapon", false);
|
||||
static const config::t_token z_filter_opponent("filter_opponent", false);
|
||||
static const config::t_token z_defense("defense", false);
|
||||
static const config::t_token z_filter_attacker("filter_attacker", false);
|
||||
static const config::t_token z_filter_defender("filter_defender", false);
|
||||
static const config::t_token z_self("self", false);
|
||||
static const config::t_token z_divide("divide", false);
|
||||
// static const config::t_token z_("", false);
|
||||
// static const config::t_token z_("", false);
|
||||
// static const config::t_token z_("", false);
|
||||
|
||||
}
|
||||
namespace unit_abilities {
|
||||
|
||||
static bool affects_side(const config& cfg, const std::vector<team>& teams, size_t side, size_t other_side)
|
||||
static bool affects_side(const config& cfg, const t_teams& teams, size_t side, size_t other_side)
|
||||
{
|
||||
if (side == other_side)
|
||||
return cfg["affect_allies"].to_bool(true);
|
||||
return cfg[z_affect_allies].to_bool(true);
|
||||
if (teams[side - 1].is_enemy(other_side))
|
||||
return cfg["affect_enemies"].to_bool();
|
||||
return cfg[z_affect_enemies].to_bool();
|
||||
else
|
||||
return cfg["affect_allies"].to_bool();
|
||||
return cfg[z_affect_allies].to_bool();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool unit::get_ability_bool(const std::string& ability, const map_location& loc) const
|
||||
bool unit::get_ability_bool(const config::t_token& ability, const map_location& loc, gamemap const & game_map, unit_map const & units, t_teams const & teams, LuaKernel & lua_kernel, tod_manager const & tod_manager) const
|
||||
{
|
||||
if (const config &abilities = cfg_.child("abilities"))
|
||||
if (const config &abilities = cfg_.child(z_abilities))
|
||||
{
|
||||
foreach (const config &i, abilities.child_range(ability)) {
|
||||
if (ability_active(ability, i, loc) &&
|
||||
ability_affects_self(ability, i, loc))
|
||||
if (ability_active(ability, i, loc, game_map, units, teams, lua_kernel, tod_manager)
|
||||
&& ability_affects_self(ability, i, loc))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const unit_map& units = *resources::units;
|
||||
//const unit_map& units = *resources::units;
|
||||
map_location adjacent[6];
|
||||
get_adjacent_tiles(loc,adjacent);
|
||||
for(int i = 0; i != 6; ++i) {
|
||||
const unit_map::const_iterator it = units.find(adjacent[i]);
|
||||
if (it == units.end() || it->incapacitated())
|
||||
continue;
|
||||
const config &adj_abilities = it->cfg_.child("abilities");
|
||||
const config &adj_abilities = it->cfg_.child(z_abilities);
|
||||
if (!adj_abilities)
|
||||
continue;
|
||||
foreach (const config &j, adj_abilities.child_range(ability)) {
|
||||
@ -152,11 +212,11 @@ bool unit::get_ability_bool(const std::string& ability, const map_location& loc)
|
||||
|
||||
return false;
|
||||
}
|
||||
unit_ability_list unit::get_abilities(const std::string& ability, const map_location& loc) const
|
||||
unit_ability_list unit::get_abilities(const config::t_token& ability, const map_location& loc) const
|
||||
{
|
||||
unit_ability_list res;
|
||||
|
||||
if (const config &abilities = cfg_.child("abilities"))
|
||||
if (const config &abilities = cfg_.child(z_abilities))
|
||||
{
|
||||
foreach (const config &i, abilities.child_range(ability)) {
|
||||
if (ability_active(ability, i, loc) &&
|
||||
@ -172,7 +232,7 @@ unit_ability_list unit::get_abilities(const std::string& ability, const map_loca
|
||||
const unit_map::const_iterator it = units.find(adjacent[i]);
|
||||
if (it == units.end() || it->incapacitated())
|
||||
continue;
|
||||
const config &adj_abilities = it->cfg_.child("abilities");
|
||||
const config &adj_abilities = it->cfg_.child(z_abilities);
|
||||
if (!adj_abilities)
|
||||
continue;
|
||||
foreach (const config &j, adj_abilities.child_range(ability)) {
|
||||
@ -191,10 +251,10 @@ std::vector<std::string> unit::get_ability_list() const
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
const config &abilities = cfg_.child("abilities");
|
||||
const config &abilities = cfg_.child(z_abilities);
|
||||
if (!abilities) return res;
|
||||
foreach (const config::any_child &ab, abilities.all_children_range()) {
|
||||
std::string const &id = ab.cfg["id"];
|
||||
std::string const &id = ab.cfg[z_id];
|
||||
if (!id.empty())
|
||||
res.push_back(id);
|
||||
}
|
||||
@ -205,7 +265,7 @@ std::vector<std::string> unit::ability_tooltips(bool force_active) const
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
const config &abilities = cfg_.child("abilities");
|
||||
const config &abilities = cfg_.child(z_abilities);
|
||||
if (!abilities) return res;
|
||||
|
||||
foreach (const config::any_child &ab, abilities.all_children_range())
|
||||
@ -213,23 +273,23 @@ std::vector<std::string> unit::ability_tooltips(bool force_active) const
|
||||
if (force_active || ability_active(ab.key, ab.cfg, loc_))
|
||||
{
|
||||
std::string const &name =
|
||||
gender_ == unit_race::MALE || ab.cfg["female_name"].empty() ?
|
||||
ab.cfg["name"] : ab.cfg["female_name"];
|
||||
gender_ == unit_race::MALE || ab.cfg[z_female_name].empty() ?
|
||||
ab.cfg[z_name] : ab.cfg[z_female_name];
|
||||
|
||||
if (!name.empty()) {
|
||||
res.push_back(name);
|
||||
res.push_back(ab.cfg["description"]);
|
||||
res.push_back(ab.cfg[z_description]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string const &name =
|
||||
gender_ == unit_race::MALE || ab.cfg["female_name_inactive"].empty() ?
|
||||
ab.cfg["name_inactive"] : ab.cfg["female_name_inactive"];
|
||||
gender_ == unit_race::MALE || ab.cfg[z_female_name_inactive].empty() ?
|
||||
ab.cfg[z_name_inactive] : ab.cfg[z_female_name_inactive];
|
||||
|
||||
if (!name.empty()) {
|
||||
res.push_back(name);
|
||||
res.push_back(ab.cfg["description_inactive"]);
|
||||
res.push_back(ab.cfg[z_description_inactive]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,26 +304,29 @@ std::vector<std::string> unit::ability_tooltips(bool force_active) const
|
||||
static bool cache_illuminates(int &cache, std::string const &ability)
|
||||
{
|
||||
if (cache < 0)
|
||||
cache = (ability == "illuminates");
|
||||
cache = (ability == z_illuminates);
|
||||
return (cache != 0);
|
||||
}
|
||||
|
||||
bool unit::ability_active(const std::string& ability,const config& cfg,const map_location& loc) const
|
||||
bool unit::ability_active(const std::string& ability,const config& cfg,const map_location& loc
|
||||
, gamemap const & game_map, unit_map const & units
|
||||
, t_teams const & teams, LuaKernel & lua_kernel
|
||||
, tod_manager const & tod_manager) const
|
||||
{
|
||||
int illuminates = -1;
|
||||
assert(resources::units && resources::game_map && resources::teams && resources::tod_manager);
|
||||
//assert(resources::units && resources::game_map && resources::teams && resources::tod_manager);
|
||||
|
||||
if (const config &afilter = cfg.child("filter"))
|
||||
if (!matches_filter(vconfig(afilter), loc, cache_illuminates(illuminates, ability)))
|
||||
if (const config &afilter = cfg.child(z_filter))
|
||||
if (!matches_filter(vconfig(afilter), loc, cache_illuminates(illuminates, ability),game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
|
||||
map_location adjacent[6];
|
||||
get_adjacent_tiles(loc,adjacent);
|
||||
const unit_map& units = *resources::units;
|
||||
//const unit_map& units = *resources::units;
|
||||
|
||||
foreach (const config &i, cfg.child_range("filter_adjacent"))
|
||||
foreach (const config &i, cfg.child_range(z_filter_adjacent))
|
||||
{
|
||||
foreach (const std::string &j, utils::split(i["adjacent"]))
|
||||
foreach (const std::string &j, utils::split(i[z_adjacent]))
|
||||
{
|
||||
map_location::DIRECTION index =
|
||||
map_location::parse_direction(j);
|
||||
@ -273,14 +336,14 @@ bool unit::ability_active(const std::string& ability,const config& cfg,const map
|
||||
if (unit == units.end())
|
||||
return false;
|
||||
if (!unit->matches_filter(vconfig(i), unit->get_location(),
|
||||
cache_illuminates(illuminates, ability)))
|
||||
cache_illuminates(illuminates, ability), game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const config &i, cfg.child_range("filter_adjacent_location"))
|
||||
foreach (const config &i, cfg.child_range(z_filter_adjacent_location))
|
||||
{
|
||||
foreach (const std::string &j, utils::split(i["adjacent"]))
|
||||
foreach (const std::string &j, utils::split(i[z_adjacent]))
|
||||
{
|
||||
map_location::DIRECTION index = map_location::parse_direction(j);
|
||||
if (index == map_location::NDIRECTIONS) {
|
||||
@ -300,19 +363,24 @@ bool unit::ability_active(const std::string& ability,const config& cfg,const map
|
||||
* cfg: an ability WML structure
|
||||
*
|
||||
*/
|
||||
bool unit::ability_affects_adjacent(const std::string& ability, const config& cfg,int dir,const map_location& loc) const
|
||||
bool unit::ability_affects_adjacent(const std::string& ability, const config& cfg,int dir,
|
||||
const map_location& loc,
|
||||
gamemap const & game_map, unit_map const & units,
|
||||
t_teams const & teams, LuaKernel & lua_kernel,
|
||||
tod_manager const & tod_manager
|
||||
) const
|
||||
{
|
||||
int illuminates = -1;
|
||||
|
||||
assert(dir >=0 && dir <= 5);
|
||||
static const std::string adjacent_names[6] = {"n","ne","se","s","sw","nw"};
|
||||
foreach (const config &i, cfg.child_range("affect_adjacent"))
|
||||
static const std::string adjacent_names[6] = {z_n,z_ne,z_se,z_s,z_sw,z_nw};
|
||||
foreach (const config &i, cfg.child_range(z_affect_adjacent))
|
||||
{
|
||||
std::vector<std::string> dirs = utils::split(i["adjacent"]);
|
||||
std::vector<std::string> dirs = utils::split(i[z_adjacent]);
|
||||
if(std::find(dirs.begin(),dirs.end(),adjacent_names[dir]) != dirs.end()) {
|
||||
if (const config &filter = i.child("filter")) {
|
||||
if (const config &filter = i.child(z_filter)) {
|
||||
if (matches_filter(vconfig(filter), loc,
|
||||
cache_illuminates(illuminates, ability)))
|
||||
cache_illuminates(illuminates, ability), game_map, units, teams, lua_kernel, tod_manager))
|
||||
return true;
|
||||
} else
|
||||
return true;
|
||||
@ -325,18 +393,22 @@ bool unit::ability_affects_adjacent(const std::string& ability, const config& cf
|
||||
* cfg: an ability WML structure
|
||||
*
|
||||
*/
|
||||
bool unit::ability_affects_self(const std::string& ability,const config& cfg,const map_location& loc) const
|
||||
{
|
||||
bool unit::ability_affects_self(const std::string& ability,const config& cfg,const map_location& loc
|
||||
, gamemap const & game_map, unit_map const & units
|
||||
, t_teams const & teams, LuaKernel & lua_kernel
|
||||
, tod_manager const & tod_manager
|
||||
) const {
|
||||
int illuminates = -1;
|
||||
const config &filter = cfg.child("filter_self");
|
||||
bool affect_self = cfg["affect_self"].to_bool(true);
|
||||
const config &filter = cfg.child(z_filter_self);
|
||||
bool affect_self = cfg[z_affect_self].to_bool(true);
|
||||
if (!filter || !affect_self) return affect_self;
|
||||
return matches_filter(vconfig(filter), loc,cache_illuminates(illuminates, ability));
|
||||
return matches_filter(vconfig(filter),
|
||||
loc, cache_illuminates(illuminates, ability),game_map, units, teams, lua_kernel, tod_manager);
|
||||
}
|
||||
|
||||
bool unit::has_ability_type(const std::string& ability) const
|
||||
bool unit::has_ability_type(const config::t_token& ability) const
|
||||
{
|
||||
if (const config &list = cfg_.child("abilities")) {
|
||||
if (const config &list = cfg_.child(z_abilities)) {
|
||||
config::const_child_itors itors = list.child_range(ability);
|
||||
return itors.first != itors.second;
|
||||
}
|
||||
@ -349,8 +421,7 @@ bool unit_ability_list::empty() const
|
||||
return cfgs.empty();
|
||||
}
|
||||
|
||||
std::pair<int,map_location> unit_ability_list::highest(const std::string& key, int def) const
|
||||
{
|
||||
std::pair<int,map_location> unit_ability_list::highest(const config::t_token& key, int def) const {
|
||||
if (cfgs.empty()) {
|
||||
return std::make_pair(def, map_location());
|
||||
}
|
||||
@ -365,7 +436,7 @@ std::pair<int,map_location> unit_ability_list::highest(const std::string& key, i
|
||||
foreach (pt const &p, cfgs)
|
||||
{
|
||||
int value = (*p.first)[key].to_int(def);
|
||||
if ((*p.first)["cumulative"].to_bool()) {
|
||||
if ((*p.first)[z_cumulative].to_bool()) {
|
||||
stack += value;
|
||||
if (value < 0) value = -value;
|
||||
if (only_cumulative && value >= abs_max) {
|
||||
@ -381,7 +452,7 @@ std::pair<int,map_location> unit_ability_list::highest(const std::string& key, i
|
||||
return std::make_pair(flat + stack, best_loc);
|
||||
}
|
||||
|
||||
std::pair<int,map_location> unit_ability_list::lowest(const std::string& key, int def) const
|
||||
std::pair<int,map_location> unit_ability_list::lowest(const config::t_token& key, int def) const
|
||||
{
|
||||
if (cfgs.empty()) {
|
||||
return std::make_pair(def, map_location());
|
||||
@ -397,7 +468,7 @@ std::pair<int,map_location> unit_ability_list::lowest(const std::string& key, in
|
||||
foreach (pt const &p, cfgs)
|
||||
{
|
||||
int value = (*p.first)[key].to_int(def);
|
||||
if ((*p.first)["cumulative"].to_bool()) {
|
||||
if ((*p.first)[z_cumulative].to_bool()) {
|
||||
stack += value;
|
||||
if (value < 0) value = -value;
|
||||
if (only_cumulative && value <= abs_max) {
|
||||
@ -443,10 +514,10 @@ std::pair<int,map_location> unit_ability_list::lowest(const std::string& key, in
|
||||
|
||||
namespace {
|
||||
bool get_special_children(std::vector<const config*>& result, const config& parent,
|
||||
const std::string& id, bool just_peeking=false) {
|
||||
const config::t_token& id, bool just_peeking=false) {
|
||||
foreach (const config::any_child &sp, parent.all_children_range())
|
||||
{
|
||||
if (sp.key == config::t_token(id) || sp.cfg["id"] == config::t_token(id)) {
|
||||
if (sp.key == id || sp.cfg[z_id] == id) {
|
||||
if(just_peeking) {
|
||||
return true; // peek succeeded, abort
|
||||
} else {
|
||||
@ -458,10 +529,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool attack_type::get_special_bool(const std::string& special,bool force) const
|
||||
bool attack_type::get_special_bool(const config::t_token& special,bool force) const
|
||||
{
|
||||
// log_scope("get_special_bool");
|
||||
if (const config &specials = cfg_.child("specials"))
|
||||
if (const config &specials = cfg_.child(z_specials))
|
||||
{
|
||||
std::vector<const config*> list;
|
||||
if (get_special_children(list, specials, special, force)) return true;
|
||||
@ -472,7 +543,7 @@ bool attack_type::get_special_bool(const std::string& special,bool force) const
|
||||
}
|
||||
}
|
||||
if (force || !other_attack_) return false;
|
||||
if (const config &specials = other_attack_->cfg_.child("specials"))
|
||||
if (const config &specials = other_attack_->cfg_.child(z_specials))
|
||||
{
|
||||
std::vector<const config*> list;
|
||||
get_special_children(list, specials, special);
|
||||
@ -485,11 +556,10 @@ bool attack_type::get_special_bool(const std::string& special,bool force) const
|
||||
return false;
|
||||
}
|
||||
|
||||
unit_ability_list attack_type::get_specials(const std::string& special) const
|
||||
{
|
||||
unit_ability_list attack_type::get_specials(const config::t_token& special) const {
|
||||
// log_scope("get_specials");
|
||||
unit_ability_list res;
|
||||
if (const config &specials = cfg_.child("specials"))
|
||||
if (const config &specials = cfg_.child(z_specials))
|
||||
{
|
||||
foreach (const config &i, specials.child_range(special)) {
|
||||
if (special_active(i, true))
|
||||
@ -498,7 +568,7 @@ unit_ability_list attack_type::get_specials(const std::string& special) const
|
||||
}
|
||||
}
|
||||
if (!other_attack_) return res;
|
||||
if (const config &specials = other_attack_->cfg_.child("specials"))
|
||||
if (const config &specials = other_attack_->cfg_.child(z_specials))
|
||||
{
|
||||
foreach (const config &i, specials.child_range(special)) {
|
||||
if (other_attack_->special_active(i, false))
|
||||
@ -512,22 +582,22 @@ std::vector<t_string> attack_type::special_tooltips(bool force) const
|
||||
{
|
||||
// log_scope("special_tooltips");
|
||||
std::vector<t_string> res;
|
||||
const config &specials = cfg_.child("specials");
|
||||
const config &specials = cfg_.child(z_specials);
|
||||
if (!specials) return res;
|
||||
|
||||
foreach (const config::any_child &sp, specials.all_children_range())
|
||||
{
|
||||
if (force || special_active(sp.cfg, true)) {
|
||||
const t_string &name = sp.cfg["name"];
|
||||
const t_string &name = sp.cfg[z_name];
|
||||
if (!name.empty()) {
|
||||
res.push_back(name);
|
||||
res.push_back(sp.cfg["description"]);
|
||||
res.push_back(sp.cfg[z_description]);
|
||||
}
|
||||
} else {
|
||||
t_string const &name = sp.cfg["name_inactive"];
|
||||
t_string const &name = sp.cfg[z_name_inactive];
|
||||
if (!name.empty()) {
|
||||
res.push_back(name);
|
||||
res.push_back(sp.cfg["description_inactive"]);
|
||||
res.push_back(sp.cfg[z_description_inactive]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -537,14 +607,14 @@ std::string attack_type::weapon_specials(bool force) const
|
||||
{
|
||||
// log_scope("weapon_specials");
|
||||
std::string res;
|
||||
const config &specials = cfg_.child("specials");
|
||||
const config &specials = cfg_.child(z_specials);
|
||||
if (!specials) return res;
|
||||
|
||||
foreach (const config::any_child &sp, specials.all_children_range())
|
||||
{
|
||||
char const *s = force || special_active(sp.cfg, true) ?
|
||||
"name" : "name_inactive";
|
||||
std::string const &name = sp.cfg[s];
|
||||
config::t_token const *s = force || special_active(sp.cfg, true) ?
|
||||
&z_name : &z_name_inactive;
|
||||
config::t_token const &name = sp.cfg[*s];
|
||||
|
||||
if (!name.empty()) {
|
||||
if (!res.empty()) res += ',';
|
||||
@ -562,7 +632,10 @@ std::string attack_type::weapon_specials(bool force) const
|
||||
* cfg: a weapon special WML structure
|
||||
*
|
||||
*/
|
||||
bool attack_type::special_active(const config& cfg, bool self) const
|
||||
bool attack_type::special_active(gamemap const & game_map, unit_map const & units,
|
||||
t_teams const & teams, LuaKernel & lua_kernel,
|
||||
tod_manager const & tod_manager,
|
||||
const config& cfg, bool self) const
|
||||
{
|
||||
// log_scope("special_active");
|
||||
assert(unitmap_ != NULL);
|
||||
@ -581,85 +654,85 @@ bool attack_type::special_active(const config& cfg, bool self) const
|
||||
|
||||
if(attacker_) {
|
||||
{
|
||||
std::string const &active = cfg["active_on"];
|
||||
if (!active.empty() && active != "offense")
|
||||
std::string const &active = cfg[z_active_on];
|
||||
if (!active.empty() && active != z_offense)
|
||||
return false;
|
||||
}
|
||||
if (const config &filter_self = cfg.child("filter_self"))
|
||||
if (const config &filter_self = cfg.child(z_filter_self))
|
||||
{
|
||||
if (att == unitmap_->end() ||
|
||||
!att->matches_filter(vconfig(filter_self), aloc_))
|
||||
!att->matches_filter(vconfig(filter_self), aloc_, false, game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
if (const config &filter_weapon = filter_self.child("filter_weapon")) {
|
||||
if (const config &filter_weapon = filter_self.child(z_filter_weapon)) {
|
||||
if (!matches_filter(filter_weapon, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (const config &filter_opponent = cfg.child("filter_opponent"))
|
||||
if (const config &filter_opponent = cfg.child(z_filter_opponent))
|
||||
{
|
||||
if (def == unitmap_->end() ||
|
||||
!def->matches_filter(vconfig(filter_opponent), dloc_))
|
||||
!def->matches_filter(vconfig(filter_opponent), dloc_,false, game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
if (const config &filter_weapon = filter_opponent.child("filter_weapon")) {
|
||||
if (const config &filter_weapon = filter_opponent.child(z_filter_weapon)) {
|
||||
if (!other_attack_ ||
|
||||
!other_attack_->matches_filter(filter_weapon, true))
|
||||
!other_attack_->matches_filter( filter_weapon, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
{
|
||||
std::string const &active = cfg["active_on"];
|
||||
if (!active.empty() && active != "defense")
|
||||
std::string const &active = cfg[z_active_on];
|
||||
if (!active.empty() && active != z_defense)
|
||||
return false;
|
||||
}
|
||||
if (const config &filter_self = cfg.child("filter_self"))
|
||||
if (const config &filter_self = cfg.child(z_filter_self))
|
||||
{
|
||||
if (def == unitmap_->end() ||
|
||||
!def->matches_filter(vconfig(filter_self), dloc_))
|
||||
!def->matches_filter(vconfig(filter_self), dloc_, false, game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
if (const config &filter_weapon = filter_self.child("filter_weapon")) {
|
||||
if (!matches_filter(filter_weapon, true))
|
||||
if (const config &filter_weapon = filter_self.child(z_filter_weapon)) {
|
||||
if (!matches_filter( filter_weapon, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (const config &filter_opponent = cfg.child("filter_opponent"))
|
||||
if (const config &filter_opponent = cfg.child(z_filter_opponent))
|
||||
{
|
||||
if (att == unitmap_->end() ||
|
||||
!att->matches_filter(vconfig(filter_opponent), aloc_))
|
||||
!att->matches_filter(vconfig(filter_opponent), aloc_, false, game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
if (const config &filter_weapon = filter_opponent.child("filter_weapon")) {
|
||||
if (const config &filter_weapon = filter_opponent.child(z_filter_weapon)) {
|
||||
if (!other_attack_ ||
|
||||
!other_attack_->matches_filter(filter_weapon, true))
|
||||
!other_attack_->matches_filter( filter_weapon, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const config &filter_attacker = cfg.child("filter_attacker"))
|
||||
if (const config &filter_attacker = cfg.child(z_filter_attacker))
|
||||
{
|
||||
if (att == unitmap_->end() ||
|
||||
!att->matches_filter(vconfig(filter_attacker), aloc_))
|
||||
!att->matches_filter(vconfig(filter_attacker), aloc_, false, game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
if (const config &filter_weapon = filter_attacker.child("filter_weapon"))
|
||||
if (const config &filter_weapon = filter_attacker.child(z_filter_weapon))
|
||||
{
|
||||
if (attacker_) {
|
||||
if (!matches_filter(filter_weapon, true))
|
||||
return false;
|
||||
} else {
|
||||
if (!other_attack_ ||
|
||||
!other_attack_->matches_filter(filter_weapon, true))
|
||||
!other_attack_->matches_filter( filter_weapon, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const config &filter_defender = cfg.child("filter_defender"))
|
||||
if (const config &filter_defender = cfg.child(z_filter_defender))
|
||||
{
|
||||
if (def == unitmap_->end() ||
|
||||
!def->matches_filter(vconfig(filter_defender), dloc_))
|
||||
!def->matches_filter(vconfig(filter_defender), dloc_, false, game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
if (const config &filter_weapon = filter_defender.child("filter_weapon"))
|
||||
if (const config &filter_weapon = filter_defender.child(z_filter_weapon))
|
||||
{
|
||||
if (!attacker_) {
|
||||
if(!matches_filter(filter_weapon, true))
|
||||
if(!matches_filter( filter_weapon, true))
|
||||
return false;
|
||||
} else {
|
||||
if (!other_attack_ ||
|
||||
@ -675,9 +748,9 @@ bool attack_type::special_active(const config& cfg, bool self) const
|
||||
get_adjacent_tiles(dloc_,adjacent);
|
||||
}
|
||||
|
||||
foreach (const config &i, cfg.child_range("filter_adjacent"))
|
||||
foreach (const config &i, cfg.child_range(z_filter_adjacent))
|
||||
{
|
||||
foreach (const std::string &j, utils::split(i["adjacent"]))
|
||||
foreach (const std::string &j, utils::split(i[z_adjacent]))
|
||||
{
|
||||
map_location::DIRECTION index =
|
||||
map_location::parse_direction(j);
|
||||
@ -685,14 +758,14 @@ bool attack_type::special_active(const config& cfg, bool self) const
|
||||
continue;
|
||||
unit_map::const_iterator unit = unitmap_->find(adjacent[index]);
|
||||
if (unit == unitmap_->end() ||
|
||||
!unit->matches_filter(vconfig(i), unit->get_location()))
|
||||
!unit->matches_filter(vconfig(i), unit->get_location(), false, game_map, units, teams, lua_kernel, tod_manager))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const config &i, cfg.child_range("filter_adjacent_location"))
|
||||
foreach (const config &i, cfg.child_range(z_filter_adjacent_location))
|
||||
{
|
||||
foreach (const std::string &j, utils::split(i["adjacent"]))
|
||||
foreach (const std::string &j, utils::split(i[z_adjacent]))
|
||||
{
|
||||
map_location::DIRECTION index =
|
||||
map_location::parse_direction(j);
|
||||
@ -714,16 +787,16 @@ bool attack_type::special_active(const config& cfg, bool self) const
|
||||
bool attack_type::special_affects_opponent(const config& cfg) const
|
||||
{
|
||||
// log_scope("special_affects_opponent");
|
||||
std::string const &apply_to = cfg["apply_to"];
|
||||
std::string const &apply_to = cfg[z_apply_to];
|
||||
if (apply_to.empty())
|
||||
return false;
|
||||
if (apply_to == "both")
|
||||
if (apply_to == z_both)
|
||||
return true;
|
||||
if (apply_to == "opponent")
|
||||
if (apply_to == z_opponent)
|
||||
return true;
|
||||
if (attacker_ && apply_to == "defender")
|
||||
if (attacker_ && apply_to == z_defender)
|
||||
return true;
|
||||
if (!attacker_ && apply_to == "attacker")
|
||||
if (!attacker_ && apply_to == z_attacker)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -735,16 +808,16 @@ bool attack_type::special_affects_opponent(const config& cfg) const
|
||||
bool attack_type::special_affects_self(const config& cfg) const
|
||||
{
|
||||
// log_scope("special_affects_self");
|
||||
std::string const &apply_to = cfg["apply_to"];
|
||||
std::string const &apply_to = cfg[z_apply_to];
|
||||
if (apply_to.empty())
|
||||
return true;
|
||||
if (apply_to == "both")
|
||||
if (apply_to == z_both)
|
||||
return true;
|
||||
if (apply_to == "self")
|
||||
if (apply_to == z_self)
|
||||
return true;
|
||||
if (attacker_ && apply_to == "attacker")
|
||||
if (attacker_ && apply_to == z_attacker)
|
||||
return true;
|
||||
if (!attacker_ && apply_to == "defender")
|
||||
if (!attacker_ && apply_to == z_defender)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -783,13 +856,13 @@ void individual_effect::set(value_modifier t, int val, const config *abil, const
|
||||
|
||||
bool filter_base_matches(const config& cfg, int def)
|
||||
{
|
||||
if (const config &apply_filter = cfg.child("filter_base_value")) {
|
||||
config::attribute_value cond_eq = apply_filter["equals"];
|
||||
config::attribute_value cond_ne = apply_filter["not_equals"];
|
||||
config::attribute_value cond_lt = apply_filter["less_than"];
|
||||
config::attribute_value cond_gt = apply_filter["greater_than"];
|
||||
config::attribute_value cond_ge = apply_filter["greater_than_equal_to"];
|
||||
config::attribute_value cond_le = apply_filter["less_than_equal_to"];
|
||||
if (const config &apply_filter = cfg.child(z_filter_base_value)) {
|
||||
config::attribute_value cond_eq = apply_filter[z_equals];
|
||||
config::attribute_value cond_ne = apply_filter[z_not_equals];
|
||||
config::attribute_value cond_lt = apply_filter[z_less_than];
|
||||
config::attribute_value cond_gt = apply_filter[z_greater_than];
|
||||
config::attribute_value cond_ge = apply_filter[z_greater_than_equal_to];
|
||||
config::attribute_value cond_le = apply_filter[z_less_than_equal_to];
|
||||
return (cond_eq.empty() || def == cond_eq.to_int()) &&
|
||||
(cond_ne.empty() || def != cond_ne.to_int()) &&
|
||||
(cond_lt.empty() || def < cond_lt.to_int()) &&
|
||||
@ -816,16 +889,16 @@ effect::effect(const unit_ability_list& list, int def, bool backstab) :
|
||||
for (std::vector< std::pair<const config *, map_location> >::const_iterator
|
||||
i = list.cfgs.begin(), i_end = list.cfgs.end(); i != i_end; ++i) {
|
||||
const config& cfg = (*i->first);
|
||||
std::string const &effect_id = cfg[cfg["id"].empty() ? "name" : "id"];
|
||||
std::string const &effect_id = cfg[cfg[z_id].empty() ? z_name : z_id];
|
||||
|
||||
if (!backstab && cfg["backstab"].to_bool())
|
||||
if (!backstab && cfg[z_backstab].to_bool())
|
||||
continue;
|
||||
if (!filter_base_matches(cfg, def))
|
||||
continue;
|
||||
|
||||
if (const config::attribute_value *v = cfg.get("value")) {
|
||||
if (const config::attribute_value *v = cfg.get(z_value)) {
|
||||
int value = *v;
|
||||
bool cumulative = cfg["cumulative"].to_bool();
|
||||
bool cumulative = cfg[z_cumulative].to_bool();
|
||||
if (!value_is_set && !cumulative) {
|
||||
value_set = value;
|
||||
set_effect.set(SET, value, i->first, i->second);
|
||||
@ -839,29 +912,29 @@ effect::effect(const unit_ability_list& list, int def, bool backstab) :
|
||||
value_is_set = true;
|
||||
}
|
||||
|
||||
if (const config::attribute_value *v = cfg.get("add")) {
|
||||
if (const config::attribute_value *v = cfg.get(z_add)) {
|
||||
int add = *v;
|
||||
std::map<std::string,individual_effect>::iterator add_effect = values_add.find(effect_id);
|
||||
if(add_effect == values_add.end() || add > add_effect->second.value) {
|
||||
values_add[effect_id].set(ADD,add,i->first,i->second);
|
||||
}
|
||||
}
|
||||
if (const config::attribute_value *v = cfg.get("sub")) {
|
||||
if (const config::attribute_value *v = cfg.get(z_sub)) {
|
||||
int sub = - *v;
|
||||
std::map<std::string,individual_effect>::iterator sub_effect = values_add.find(effect_id);
|
||||
if(sub_effect == values_add.end() || sub > sub_effect->second.value) {
|
||||
values_add[effect_id].set(ADD,sub,i->first,i->second);
|
||||
}
|
||||
}
|
||||
if (const config::attribute_value *v = cfg.get("multiply")) {
|
||||
if (const config::attribute_value *v = cfg.get(z_multiply)) {
|
||||
int multiply = int(v->to_double() * 100);
|
||||
std::map<std::string,individual_effect>::iterator mul_effect = values_mul.find(effect_id);
|
||||
if(mul_effect == values_mul.end() || multiply > mul_effect->second.value) {
|
||||
values_mul[effect_id].set(MUL,multiply,i->first,i->second);
|
||||
}
|
||||
}
|
||||
if (const config::attribute_value *v = cfg.get("divide")) {
|
||||
if (*v == 0) {
|
||||
if (const config::attribute_value *v = cfg.get(z_divide)) {
|
||||
if (v->to_int() == 0) {
|
||||
ERR_NG << "division by zero with divide= in ability/weapon special " << effect_id << "\n";
|
||||
}
|
||||
else {
|
||||
|
@ -39,6 +39,226 @@ static lg::log_domain log_config("config");
|
||||
static lg::log_domain log_unit("unit");
|
||||
#define DBG_UT LOG_STREAM(debug, log_unit)
|
||||
|
||||
namespace{
|
||||
//Static tokens are replacements for string literals in code
|
||||
//They allow for fast comparison operations.
|
||||
static const config::t_token z_gender("gender", false);
|
||||
static const config::t_token z_type("type", false);
|
||||
static const config::t_token z_id("id", false);
|
||||
static const config::t_token z_name("name", false);
|
||||
static const config::t_token z_random_gender("random_gender", false);
|
||||
static const config::t_token z_x("x", false);
|
||||
static const config::t_token z_y("y", false);
|
||||
static const config::t_token z_variation("variation", false);
|
||||
static const config::t_token z_canrecruit("canrecruit", false);
|
||||
static const config::t_token z_role("role", false);
|
||||
static const config::t_token z_ai_special("ai_special", false);
|
||||
static const config::t_token z_side("side", false);
|
||||
static const config::t_token z_underlying_id("underlying_id", false);
|
||||
static const config::t_token z_overlays("overlays", false);
|
||||
static const config::t_token z_variables("variables", false);
|
||||
static const config::t_token z_facing("facing", false);
|
||||
static const config::t_token z_flying("flying", false);
|
||||
static const config::t_token z_modification("modifications", false);
|
||||
static const config::t_token z_race("race", false);
|
||||
static const config::t_token z_undead_variation("undead_variation", false);
|
||||
static const config::t_token z_max_attacks("max_attacks", false);
|
||||
static const config::t_token z_attacks_left("attacks_left", false);
|
||||
static const config::t_token z_alpha("alpha", false);
|
||||
static const config::t_token z_zoc("zoc", false);
|
||||
static const config::t_token z_description("description", false);
|
||||
static const config::t_token z_cost("cost", false);
|
||||
static const config::t_token z_profile("profile", false);
|
||||
static const config::t_token z_small_profile("small_profile", false);
|
||||
static const config::t_token z_max_hitpoints("max_hitpoints", false);
|
||||
static const config::t_token z_max_moves("max_moves", false);
|
||||
static const config::t_token z_max_experience("max_experience", false);
|
||||
static const config::t_token z_advances_to("advances_to", false);
|
||||
static const config::t_token z_null("null", false);
|
||||
static const config::t_token z_ai("ai", false);
|
||||
static const config::t_token z_formula("formula", false);
|
||||
static const config::t_token z_loop_formula("loop_formula", false);
|
||||
static const config::t_token z_priority("priority", false);
|
||||
static const config::t_token z_vars("vars", false);
|
||||
static const config::t_token z_guardian("guardian", false);
|
||||
static const config::t_token z_hitpoints("hitpoints", false);
|
||||
static const config::t_token z_goto_x("goto_x", false);
|
||||
static const config::t_token z_goto_y("goto_y", false);
|
||||
static const config::t_token z_experience("experience", false);
|
||||
static const config::t_token z_resting("resting", false);
|
||||
static const config::t_token z_unrenamable("unrenamable", false);
|
||||
static const config::t_token z_lawful("lawful", false);
|
||||
static const config::t_token z_neutral("neutral", false);
|
||||
static const config::t_token z_chaotic("chaotic", false);
|
||||
static const config::t_token z_liminal("liminal", false);
|
||||
static const config::t_token z_upkeep("upkeep", false);
|
||||
static const config::t_token z_full("full", false);
|
||||
static const config::t_token z_flag_rgb("flag_rgb", false);
|
||||
static const config::t_token z_language_name("language_name", false);
|
||||
// static const config::t_token z_halo("halo", false);
|
||||
// static const config::t_token z_ellipse("ellipse", false);
|
||||
// static const config::t_token z_usage("usage", false);
|
||||
static const config::t_token z_generate_name("generate_name", false);
|
||||
static const config::t_token z_availability("availability", false);
|
||||
static const config::t_token z_musthave("musthave", false);
|
||||
// static const config::t_token z_trait("trait", false);
|
||||
static const config::t_token z_random_traits("random_traits", false);
|
||||
static const config::t_token z_male("male", false);
|
||||
static const config::t_token z_female("female", false);
|
||||
static const config::t_token z_unit_image("unit_image", false);
|
||||
static const config::t_token z_duration("duration", false);
|
||||
static const config::t_token z_prev_type("prev_type", false);
|
||||
static const config::t_token z_forever("forever", false);
|
||||
static const config::t_token z_abilities("abilities", false);
|
||||
static const config::t_token z_speaker("speaker", false);
|
||||
static const config::t_token z_has_weapon("has_weapon", false);
|
||||
static const config::t_token z_defense("defense", false);
|
||||
static const config::t_token z_visible("visible", false);
|
||||
static const config::t_token z_viewing_side("viewing_side", false);
|
||||
static const config::t_token z_filter_vision("filter_vision", false);
|
||||
static const config::t_token z_adjacent("adjacent", false);
|
||||
static const config::t_token z_is_enemy("is_enemy", false);
|
||||
static const config::t_token z_count("count", false);
|
||||
static const config::t_token z_find_in("find_in", false);
|
||||
static const config::t_token z_lua_function("lua_function", false);
|
||||
static const config::t_token z_status("status", false);
|
||||
static const config::t_token z_loyal("loyal", false);
|
||||
static const config::t_token z_free("free", false);
|
||||
static const config::t_token z_active_on("active_on", false);
|
||||
static const config::t_token z_apply_to("apply_to", false);
|
||||
static const config::t_token z_icon("icon", false);
|
||||
static const config::t_token z_strict_amla("strict_amla", false);
|
||||
static const config::t_token z_require_amla("require_amla", false);
|
||||
static const config::t_token z_times("times", false);
|
||||
static const config::t_token z_empty("", false);
|
||||
static const config::t_token z_modifications("modifications", false);
|
||||
static const config::t_token z_level("level", false);
|
||||
static const config::t_token z_attack("attack", false);
|
||||
static const config::t_token z_resistance("resistance", false);
|
||||
static const config::t_token z_healable("healable", false);
|
||||
static const config::t_token z_unhealable("unhealable", false);
|
||||
static const config::t_token z_waypoints("waypoints", false);
|
||||
static const config::t_token z_moves("moves", false);
|
||||
static const config::t_token z_alignment("alignment", false);
|
||||
static const config::t_token z_placement("placement", false);
|
||||
static const config::t_token z_do_not_list("do_not_list", false);
|
||||
static const config::t_token z_event("event", false);
|
||||
static const config::t_token z_any("any", false);
|
||||
static const config::t_token z_die("die", false);
|
||||
static const config::t_token z_flies("flies", false);
|
||||
static const config::t_token z_inherit("inherit", false);
|
||||
static const config::t_token z_variation_name("variation_name", false);
|
||||
static const config::t_token z_ignore_race_traits("ignore_race_traits", false);
|
||||
static const config::t_token z_hide_help("hide_help", false);
|
||||
static const config::t_token z_yes("yes", false);
|
||||
static const config::t_token z_no("no", false);
|
||||
static const config::t_token z_slowed("slowed", false);
|
||||
static const config::t_token z_poisoned("poisoned", false);
|
||||
static const config::t_token z_petrified("petrified", false);
|
||||
static const config::t_token z_uncovered("uncovered", false);
|
||||
static const config::t_token z_not_moved("not_moved", false);
|
||||
static const config::t_token z_this_unit("this_unit", false);
|
||||
static const config::t_token z_and("and", false);
|
||||
static const config::t_token z_or("or", false);
|
||||
static const config::t_token z_not("not", false);
|
||||
static const config::t_token z_filter("filter", false);
|
||||
static const config::t_token z_recall("recall", false);
|
||||
static const config::t_token z_ability("ability", false);
|
||||
static const config::t_token z_movement_cost("movement_cost", false);
|
||||
static const config::t_token z_movement_costs("movement_costs", false);
|
||||
static const config::t_token z_filter_wml("filter_wml", false);
|
||||
static const config::t_token z_filter_adjacent("filter_adjacent", false);
|
||||
static const config::t_token z_standing("standing", false);
|
||||
static const config::t_token z_ghosted("ghosted", false);
|
||||
static const config::t_token z_disabled_ghosted("disabled_ghosted", false);
|
||||
static const config::t_token z_image("image", false);
|
||||
static const config::t_token z_movement("movement", false);
|
||||
static const config::t_token z_die_sound("die_sound", false);
|
||||
static const config::t_token z_movement_type("movement_type", false);
|
||||
static const config::t_token z_filter_location("filter_location", false);
|
||||
static const config::t_token z__disabled_("_disabled_", false);
|
||||
static const config::t_token z_idling("idling", false);
|
||||
static const config::t_token z_selected("selected", false);
|
||||
static const config::t_token z__disabled_selected_("_disabled_selected_", false);
|
||||
static const config::t_token z_offense("offense", false);
|
||||
static const config::t_token z_max_value("max_value", false);
|
||||
static const config::t_token z_advance("advance", false);
|
||||
static const config::t_token z_max_times("max_times", false);
|
||||
static const config::t_token z_fearless("fearless", false);
|
||||
static const config::t_token z_healthy("healthy", false);
|
||||
static const config::t_token z_effect("effect", false);
|
||||
static const config::t_token z_unit_type("unit_type", false);
|
||||
static const config::t_token z_unit_gender("unit_gender", false);
|
||||
static const config::t_token z_portrait("portriat", false);
|
||||
static const config::t_token z_small_portrait("small_portriat", false);
|
||||
static const config::t_token z_new_attack("new_attack", false);
|
||||
static const config::t_token z_remove_attacks("remove_attacks", false);
|
||||
static const config::t_token z_wesnoth("wesnoth", false);
|
||||
static const config::t_token z_attack_list("attack_list", false);
|
||||
static const config::t_token z_effect_description("effect_description", false);
|
||||
static const config::t_token z_increase("increase", false);
|
||||
static const config::t_token z_increase_total("increase_total", false);
|
||||
static const config::t_token z_set("set", false);
|
||||
static const config::t_token z_set_total("set_total", false);
|
||||
static const config::t_token z_violate_maximum("violate_maximum", false);
|
||||
static const config::t_token z_HP("HP", false);
|
||||
static const config::t_token z_remove("remove", false);
|
||||
static const config::t_token z_replace("replace", false);
|
||||
static const config::t_token z_heal_full("heal_full", false);
|
||||
static const config::t_token z_add("add", false);
|
||||
static const config::t_token z_value("value", false);
|
||||
static const config::t_token z_new_ability("new_ability", false);
|
||||
static const config::t_token z_remove_ability("remove_ability", false);
|
||||
static const config::t_token z_image_mod("image_mod", false);
|
||||
static const config::t_token z_new_animation("new_animation", false);
|
||||
static const config::t_token z_female_name("female_name", false);
|
||||
static const config::t_token z_male_name("male_name", false);
|
||||
static const config::t_token z_ignore_global_traits("ignore_global_traits", false);
|
||||
static const config::t_token z_range("range", false);
|
||||
static const config::t_token z_damage("damage", false);
|
||||
static const config::t_token z_number("number", false);
|
||||
static const config::t_token z_specials("specials", false);
|
||||
static const config::t_token z_description_inactive("description_inactive", false);
|
||||
static const config::t_token z_name_inactive("name_inactive", false);
|
||||
static const config::t_token z_advance_from("advance_from", false);
|
||||
static const config::t_token z_hides("hides", false);
|
||||
static const config::t_token z_Unit("Unit", false);
|
||||
static const config::t_token z_attack_weight("attack_weight", false);
|
||||
static const config::t_token z_defense_weight("defense_weight", false);
|
||||
static const config::t_token z_accuracy("accuracy", false);
|
||||
static const config::t_token z_parry("parry", false);
|
||||
static const config::t_token z_special("special", false);
|
||||
static const config::t_token z_set_name("set_name", false);
|
||||
static const config::t_token z_set_description("set_description", false);
|
||||
static const config::t_token z_set_type("set_type", false);
|
||||
static const config::t_token z_remove_specials("remove_specials", false);
|
||||
static const config::t_token z_set_specials("set_specials", false);
|
||||
static const config::t_token z_increase_damage("increase_damage", false);
|
||||
static const config::t_token z_increase_attacks("increase_attacks", false);
|
||||
static const config::t_token z_attacks("attacks", false);
|
||||
static const config::t_token z_usage("usage", false);
|
||||
static const config::t_token z_num_traits("num_traits", false);
|
||||
static const config::t_token z_movetype("movetype", false);
|
||||
static const config::t_token z_base_unit("base_unit", false);
|
||||
static const config::t_token z_all("all", false);
|
||||
static const config::t_token z_random("random", false);
|
||||
static const config::t_token z_type_adv_tree("type_adv_tree", false);
|
||||
static const config::t_token z_unit("unit", false);
|
||||
static const config::t_token z_not_living("not_living", false);
|
||||
static const config::t_token z_increase_parry("increase_parry", false);
|
||||
static const config::t_token z_increase_accuracy("increase_accuracy", false);
|
||||
static const config::t_token z_mode("mode", false);
|
||||
static const config::t_token z_append("append", false);
|
||||
static const config::t_token z_advancefrom("advancefrom", false);
|
||||
// static const config::t_token z_("", false);
|
||||
// static const config::t_token z_("", false);
|
||||
// static const config::t_token z_("", false);
|
||||
// static const config::t_token z_("", false);
|
||||
// static const config::t_token z_("", false);
|
||||
|
||||
|
||||
|
||||
}
|
||||
attack_type::attack_type(const config& cfg) :
|
||||
aloc_(),
|
||||
dloc_(),
|
||||
@ -46,25 +266,25 @@ attack_type::attack_type(const config& cfg) :
|
||||
unitmap_(NULL),
|
||||
other_attack_(NULL),
|
||||
cfg_(cfg),
|
||||
description_(cfg["description"].t_str()),
|
||||
id_(cfg["name"]),
|
||||
type_(cfg["type"]),
|
||||
icon_(cfg["icon"]),
|
||||
range_(cfg["range"]),
|
||||
damage_(cfg["damage"]),
|
||||
num_attacks_(cfg["number"]),
|
||||
attack_weight_(cfg["attack_weight"].to_double(1.0)),
|
||||
defense_weight_(cfg["defense_weight"].to_double(1.0)),
|
||||
accuracy_(cfg["accuracy"]),
|
||||
parry_(cfg["parry"])
|
||||
description_(cfg[z_description].t_str()),
|
||||
id_(cfg[z_name]),
|
||||
type_(cfg[z_type]),
|
||||
icon_(cfg[z_icon]),
|
||||
range_(cfg[z_range]),
|
||||
damage_(cfg[z_damage]),
|
||||
num_attacks_(cfg[z_number]),
|
||||
attack_weight_(cfg[z_attack_weight].to_double(1.0)),
|
||||
defense_weight_(cfg[z_defense_weight].to_double(1.0)),
|
||||
accuracy_(cfg[z_accuracy]),
|
||||
parry_(cfg[z_parry])
|
||||
|
||||
{
|
||||
if (description_.empty())
|
||||
description_ = egettext(id_.c_str());
|
||||
description_ = egettext(id().c_str());
|
||||
|
||||
if(icon_.empty()){
|
||||
if (id_ != "")
|
||||
icon_ = "attacks/" + id_ + ".png";
|
||||
if (id() != z_empty)
|
||||
icon_ = "attacks/" + id() + ".png";
|
||||
else
|
||||
icon_ = "attacks/blank-attack.png";
|
||||
}
|
||||
@ -92,11 +312,11 @@ std::string attack_type::accuracy_parry_description() const
|
||||
|
||||
bool attack_type::matches_filter(const config& cfg,bool self) const
|
||||
{
|
||||
const std::vector<std::string>& filter_range = utils::split(cfg["range"]);
|
||||
const std::string& filter_damage = cfg["damage"];
|
||||
const std::vector<std::string> filter_name = utils::split(cfg["name"]);
|
||||
const std::vector<std::string> filter_type = utils::split(cfg["type"]);
|
||||
const std::string filter_special = cfg["special"];
|
||||
const std::vector<std::string>& filter_range = utils::split(cfg[z_range]);
|
||||
const std::string& filter_damage = cfg[z_damage];
|
||||
const std::vector<std::string> filter_name = utils::split(cfg[z_name]);
|
||||
const std::vector<std::string> filter_type = utils::split(cfg[z_type]);
|
||||
const config::t_token filter_special = cfg[z_special];
|
||||
|
||||
if(filter_range.empty() == false && std::find(filter_range.begin(),filter_range.end(),range()) == filter_range.end())
|
||||
return false;
|
||||
@ -122,58 +342,58 @@ bool attack_type::apply_modification(const config& cfg,std::string* description)
|
||||
if(!matches_filter(cfg,0))
|
||||
return false;
|
||||
|
||||
const std::string& set_name = cfg["set_name"];
|
||||
const t_string& set_desc = cfg["set_description"];
|
||||
const std::string& set_type = cfg["set_type"];
|
||||
const std::string& del_specials = cfg["remove_specials"];
|
||||
const config &set_specials = cfg.child("set_specials");
|
||||
const std::string& increase_damage = cfg["increase_damage"];
|
||||
const std::string& increase_attacks = cfg["increase_attacks"];
|
||||
const std::string& set_attack_weight = cfg["attack_weight"];
|
||||
const std::string& set_defense_weight = cfg["defense_weight"];
|
||||
const std::string& increase_accuracy = cfg["increase_accuracy"];
|
||||
const std::string& increase_parry = cfg["increase_parry"];
|
||||
const std::string& set_name = cfg[z_set_name];
|
||||
const t_string& set_desc = cfg[z_set_description];
|
||||
const std::string& set_type = cfg[z_set_type];
|
||||
const std::string& del_specials = cfg[z_remove_specials];
|
||||
const config &set_specials = cfg.child(z_set_specials);
|
||||
const std::string& increase_damage = cfg[z_increase_damage];
|
||||
const std::string& increase_attacks = cfg[z_increase_attacks];
|
||||
const std::string& set_attack_weight = cfg[z_attack_weight];
|
||||
const std::string& set_defense_weight = cfg[z_defense_weight];
|
||||
const std::string& increase_accuracy = cfg[z_increase_accuracy];
|
||||
const std::string& increase_parry = cfg[z_increase_parry];
|
||||
|
||||
std::stringstream desc;
|
||||
|
||||
if(set_name.empty() == false) {
|
||||
id_ = set_name;
|
||||
cfg_["name"] = id_;
|
||||
cfg_[z_name] = id();
|
||||
}
|
||||
|
||||
if(set_desc.empty() == false) {
|
||||
description_ = set_desc;
|
||||
cfg_["description"] = description_;
|
||||
cfg_[z_description] = description_;
|
||||
}
|
||||
|
||||
if(set_type.empty() == false) {
|
||||
type_ = set_type;
|
||||
cfg_["type"] = type_;
|
||||
cfg_[z_type] = type_;
|
||||
}
|
||||
|
||||
if(del_specials.empty() == false) {
|
||||
const std::vector<std::string>& dsl = utils::split(del_specials);
|
||||
if (config &specials = cfg_.child("specials"))
|
||||
if (config &specials = cfg_.child(z_specials))
|
||||
{
|
||||
config new_specials;
|
||||
foreach (const config::any_child &vp, specials.all_children_range()) {
|
||||
std::vector<std::string>::const_iterator found_id =
|
||||
std::find(dsl.begin(), dsl.end(), vp.cfg["id"]);
|
||||
std::find(dsl.begin(), dsl.end(), vp.cfg[z_id]);
|
||||
if (found_id == dsl.end()) {
|
||||
new_specials.add_child(vp.key, vp.cfg);
|
||||
}
|
||||
}
|
||||
cfg_.clear_children("specials");
|
||||
cfg_.add_child("specials",new_specials);
|
||||
cfg_.clear_children(z_specials);
|
||||
cfg_.add_child(z_specials,new_specials);
|
||||
}
|
||||
}
|
||||
|
||||
if (set_specials) {
|
||||
const std::string &mode = set_specials["mode"];
|
||||
if (mode != "append") {
|
||||
cfg_.clear_children("specials");
|
||||
const std::string &mode = set_specials[z_mode];
|
||||
if (mode != z_append) {
|
||||
cfg_.clear_children(z_specials);
|
||||
}
|
||||
config &new_specials = cfg_.child_or_add("specials");
|
||||
config &new_specials = cfg_.child_or_add(z_specials);
|
||||
foreach (const config::any_child &value, set_specials.all_children_range()) {
|
||||
new_specials.add_child(value.key, value.cfg);
|
||||
}
|
||||
@ -184,18 +404,18 @@ bool attack_type::apply_modification(const config& cfg,std::string* description)
|
||||
if (damage_ < 0) {
|
||||
damage_ = 0;
|
||||
}
|
||||
cfg_["damage"] = damage_;
|
||||
cfg_[z_damage] = damage_;
|
||||
|
||||
if(description != NULL) {
|
||||
int inc_damage = lexical_cast<int>(increase_damage);
|
||||
desc << utils::signed_value(inc_damage) << " "
|
||||
<< _n("damage","damage", inc_damage);
|
||||
<< _n("damage", "damage", inc_damage);
|
||||
}
|
||||
}
|
||||
|
||||
if(increase_attacks.empty() == false) {
|
||||
num_attacks_ = utils::apply_modifier(num_attacks_, increase_attacks, 1);
|
||||
cfg_["number"] = num_attacks_;
|
||||
cfg_[z_number] = num_attacks_;
|
||||
|
||||
if(description != NULL) {
|
||||
int inc_attacks = lexical_cast<int>(increase_attacks);
|
||||
@ -206,7 +426,7 @@ bool attack_type::apply_modification(const config& cfg,std::string* description)
|
||||
|
||||
if(increase_accuracy.empty() == false) {
|
||||
accuracy_ = utils::apply_modifier(accuracy_, increase_accuracy, 1);
|
||||
cfg_["accuracy"] = accuracy_;
|
||||
cfg_[z_accuracy] = accuracy_;
|
||||
|
||||
if(description != NULL) {
|
||||
int inc_acc = lexical_cast<int>(increase_accuracy);
|
||||
@ -218,7 +438,7 @@ bool attack_type::apply_modification(const config& cfg,std::string* description)
|
||||
|
||||
if(increase_parry.empty() == false) {
|
||||
parry_ = utils::apply_modifier(parry_, increase_parry, 1);
|
||||
cfg_["parry"] = parry_;
|
||||
cfg_[z_parry] = parry_;
|
||||
|
||||
if(description != NULL) {
|
||||
int inc_parry = lexical_cast<int>(increase_parry);
|
||||
@ -229,12 +449,12 @@ bool attack_type::apply_modification(const config& cfg,std::string* description)
|
||||
|
||||
if(set_attack_weight.empty() == false) {
|
||||
attack_weight_ = lexical_cast_default<double>(set_attack_weight,1.0);
|
||||
cfg_["attack_weight"] = attack_weight_;
|
||||
cfg_[z_attack_weight] = attack_weight_;
|
||||
}
|
||||
|
||||
if(set_defense_weight.empty() == false) {
|
||||
defense_weight_ = lexical_cast_default<double>(set_defense_weight,1.0);
|
||||
cfg_["defense_weight"] = defense_weight_;
|
||||
cfg_[z_defense_weight] = defense_weight_;
|
||||
}
|
||||
|
||||
if(description != NULL) {
|
||||
@ -250,8 +470,8 @@ bool attack_type::describe_modification(const config& cfg,std::string* descripti
|
||||
if(!matches_filter(cfg,0))
|
||||
return false;
|
||||
|
||||
const std::string& increase_damage = cfg["increase_damage"];
|
||||
const std::string& increase_attacks = cfg["increase_attacks"];
|
||||
const std::string& increase_damage = cfg[z_increase_damage];
|
||||
const std::string& increase_attacks = cfg[z_increase_attacks];
|
||||
|
||||
std::stringstream desc;
|
||||
|
||||
@ -288,22 +508,22 @@ unit_movement_type::unit_movement_type(const config& cfg, const unit_movement_ty
|
||||
//so we filter to keep only keys related to movement_type
|
||||
//FIXME: This helps but it's still not clean, both cfg use a "name" key
|
||||
|
||||
const t_string& name = cfg["name"];
|
||||
const t_string& name = cfg[z_name];
|
||||
if (!name.empty())
|
||||
cfg_["name"]= cfg["name"];
|
||||
cfg_[z_name]= cfg[z_name];
|
||||
|
||||
const t_string& flies = cfg["flies"];
|
||||
const t_string& flies = cfg[z_flies];
|
||||
if (!flies.empty())
|
||||
cfg_["flies"]= cfg["flies"];
|
||||
cfg_[z_flies]= cfg[z_flies];
|
||||
|
||||
if (const config &movement_costs = cfg.child("movement_costs"))
|
||||
cfg_.add_child("movement_costs", movement_costs);
|
||||
if (const config &movement_costs = cfg.child(z_movement_costs))
|
||||
cfg_.add_child(z_movement_costs, movement_costs);
|
||||
|
||||
if (const config &defense = cfg.child("defense"))
|
||||
cfg_.add_child("defense", defense);
|
||||
if (const config &defense = cfg.child(z_defense))
|
||||
cfg_.add_child(z_defense, defense);
|
||||
|
||||
if (const config &resistance = cfg.child("resistance"))
|
||||
cfg_.add_child("resistance", resistance);
|
||||
if (const config &resistance = cfg.child(z_resistance))
|
||||
cfg_.add_child(z_resistance, resistance);
|
||||
}
|
||||
|
||||
unit_movement_type::unit_movement_type(): moveCosts_(), defenseMods_(), parent_(NULL), cfg_()
|
||||
@ -311,10 +531,10 @@ unit_movement_type::unit_movement_type(): moveCosts_(), defenseMods_(), parent_(
|
||||
|
||||
std::string unit_movement_type::name() const
|
||||
{
|
||||
if (!cfg_.has_attribute("name") && parent_)
|
||||
if (!cfg_.has_attribute(z_name) && parent_)
|
||||
return parent_->name();
|
||||
else
|
||||
return cfg_["name"];
|
||||
return cfg_[z_name];
|
||||
}
|
||||
|
||||
int unit_movement_type::resistance_against(const attack_type& attack) const
|
||||
@ -322,7 +542,7 @@ int unit_movement_type::resistance_against(const attack_type& attack) const
|
||||
bool result_found = false;
|
||||
int res = 100;
|
||||
|
||||
if (const config &resistance = cfg_.child("resistance"))
|
||||
if (const config &resistance = cfg_.child(z_resistance))
|
||||
{
|
||||
if (const::config::attribute_value *val = resistance.get(attack.type())) {
|
||||
res = *val;
|
||||
@ -343,7 +563,7 @@ utils::string_map unit_movement_type::damage_table() const
|
||||
if(parent_ != NULL)
|
||||
res = parent_->damage_table();
|
||||
|
||||
if (const config &resistance = cfg_.child("resistance"))
|
||||
if (const config &resistance = cfg_.child(z_resistance))
|
||||
{
|
||||
foreach (const config::attribute &i, resistance.attribute_range()) {
|
||||
res[i.first] = i.second;
|
||||
@ -355,10 +575,10 @@ utils::string_map unit_movement_type::damage_table() const
|
||||
|
||||
bool unit_movement_type::is_flying() const
|
||||
{
|
||||
if (!cfg_.has_attribute("flies") && parent_)
|
||||
if (!cfg_.has_attribute(z_flies) && parent_)
|
||||
return parent_->is_flying();
|
||||
|
||||
return cfg_["flies"].to_bool();
|
||||
return cfg_[z_flies].to_bool();
|
||||
}
|
||||
|
||||
int movement_cost_internal(std::map<t_translation::t_terrain, int>& move_costs,
|
||||
@ -413,7 +633,7 @@ int movement_cost_internal(std::map<t_translation::t_terrain, int>& move_costs,
|
||||
bool result_found = false;
|
||||
int res = impassable;
|
||||
|
||||
if (const config& movement_costs = cfg.child("movement_costs")) {
|
||||
if (const config& movement_costs = cfg.child(z_movement_costs)) {
|
||||
if (underlying.size() != 1) {
|
||||
ERR_CF << "Terrain '" << terrain << "' has "
|
||||
<< underlying.size() << " underlying names - 0 expected.\n";
|
||||
@ -499,7 +719,7 @@ const defense_range &defense_range_modifier_internal(defense_cache &defense_mods
|
||||
goto check;
|
||||
}
|
||||
|
||||
if (const config& defense = cfg.child("defense"))
|
||||
if (const config& defense = cfg.child(z_defense))
|
||||
{
|
||||
const std::string& id = map.get_terrain_info(underlying.front()).id();
|
||||
if (const config::attribute_value *val = defense.get(id)) {
|
||||
@ -603,7 +823,7 @@ unit_type::unit_type(const unit_type& o) :
|
||||
|
||||
unit_type::unit_type(config &cfg) :
|
||||
cfg_(cfg),
|
||||
id_(cfg["id"]),
|
||||
id_(cfg[z_id]),
|
||||
type_name_(),
|
||||
description_(),
|
||||
hitpoints_(0),
|
||||
@ -666,32 +886,33 @@ void unit_type::build_full(const movement_type_map &mv_types,
|
||||
|
||||
foreach (const config &t, traits)
|
||||
{
|
||||
possibleTraits_.add_child("trait", t);
|
||||
possibleTraits_.add_child(z_trait, t);
|
||||
}
|
||||
foreach (config &var_cfg, cfg.child_range("variation"))
|
||||
foreach (config &var_cfg, cfg.child_range(z_variation))
|
||||
{
|
||||
if (var_cfg["inherit"].to_bool()) {
|
||||
if (var_cfg[z_inherit].to_bool()) {
|
||||
config nvar_cfg(cfg);
|
||||
nvar_cfg.merge_with(var_cfg);
|
||||
nvar_cfg.clear_children("variation");
|
||||
nvar_cfg.clear_children(z_variation);
|
||||
var_cfg.swap(nvar_cfg);
|
||||
}
|
||||
unit_type *ut = new unit_type(var_cfg);
|
||||
ut->build_full(mv_types, races, traits);
|
||||
variations_.insert(std::make_pair(var_cfg["variation_name"], ut));
|
||||
variations_.insert(std::make_pair(var_cfg[z_variation_name], ut));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (gender_types_[i])
|
||||
if (gender_types_[i]){
|
||||
gender_types_[i]->build_full(mv_types, races, traits);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& align = cfg["alignment"];
|
||||
if(align == "lawful")
|
||||
const config::attribute_value& align = cfg[z_alignment];
|
||||
if(align == z_lawful)
|
||||
alignment_ = LAWFUL;
|
||||
else if(align == "chaotic")
|
||||
else if(align == z_chaotic)
|
||||
alignment_ = CHAOTIC;
|
||||
else if(align == "neutral")
|
||||
else if(align == z_neutral)
|
||||
alignment_ = NEUTRAL;
|
||||
else if(align == "liminal")
|
||||
alignment_ = LIMINAL;
|
||||
@ -705,31 +926,31 @@ void unit_type::build_full(const movement_type_map &mv_types,
|
||||
if (!race_->uses_global_traits()) {
|
||||
possibleTraits_.clear();
|
||||
}
|
||||
if (cfg["ignore_race_traits"].to_bool()) {
|
||||
if (cfg[z_ignore_race_traits].to_bool()) {
|
||||
possibleTraits_.clear();
|
||||
} else {
|
||||
foreach (const config &t, race_->additional_traits())
|
||||
{
|
||||
if (alignment_ != NEUTRAL || t["id"] != "fearless")
|
||||
possibleTraits_.add_child("trait", t);
|
||||
if (alignment_ != NEUTRAL || t[z_id] != z_fearless)
|
||||
possibleTraits_.add_child(z_trait, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert any traits that are just for this unit type
|
||||
foreach (const config &trait, cfg.child_range("trait"))
|
||||
foreach (const config &trait, cfg.child_range(z_trait))
|
||||
{
|
||||
possibleTraits_.add_child("trait", trait);
|
||||
possibleTraits_.add_child(z_trait, trait);
|
||||
}
|
||||
|
||||
zoc_ = cfg["zoc"].to_bool(level_ > 0);
|
||||
zoc_ = cfg[z_zoc].to_bool(level_ > 0);
|
||||
|
||||
const std::string& alpha_blend = cfg["alpha"];
|
||||
const std::string& alpha_blend = cfg[z_alpha];
|
||||
if(alpha_blend.empty() == false) {
|
||||
alpha_ = ftofxp(atof(alpha_blend.c_str()));
|
||||
}
|
||||
|
||||
const std::string& move_type = cfg["movement_type"];
|
||||
const std::string& move_type = cfg[z_movement_type];
|
||||
|
||||
const movement_type_map::const_iterator it = mv_types.find(move_type);
|
||||
|
||||
@ -741,11 +962,11 @@ void unit_type::build_full(const movement_type_map &mv_types,
|
||||
DBG_UT << "no parent found for movement_type " << move_type << "\n";
|
||||
}
|
||||
|
||||
flag_rgb_ = cfg["flag_rgb"].str();
|
||||
flag_rgb_ = cfg[z_flag_rgb].token();
|
||||
game_config::add_color_info(cfg);
|
||||
|
||||
|
||||
foreach (const config &portrait, cfg_.child_range("portrait")) {
|
||||
foreach (const config &portrait, cfg_.child_range(z_portrait)) {
|
||||
portraits_.push_back(tportrait(portrait));
|
||||
}
|
||||
|
||||
@ -762,18 +983,18 @@ void unit_type::build_help_index(const movement_type_map &mv_types,
|
||||
|
||||
const config &cfg = cfg_;
|
||||
|
||||
type_name_ = cfg_["name"];
|
||||
description_ = cfg_["description"];
|
||||
hitpoints_ = cfg["hitpoints"].to_int(1);
|
||||
level_ = cfg["level"];
|
||||
movement_ = cfg["movement"].to_int(1);
|
||||
max_attacks_ = cfg["attacks"].to_int(1);
|
||||
cost_ = cfg["cost"].to_int(1);
|
||||
usage_ = cfg_["usage"].str();
|
||||
undead_variation_ = cfg_["undead_variation"].str();
|
||||
image_ = cfg_["image"].str();
|
||||
small_profile_ = cfg_["small_profile"].str();
|
||||
big_profile_ = cfg_["profile"].str();
|
||||
type_name_ = cfg_[z_name];
|
||||
description_ = cfg_[z_description];
|
||||
hitpoints_ = cfg[z_hitpoints].to_int(1);
|
||||
level_ = cfg[z_level];
|
||||
movement_ = cfg[z_movement].to_int(1);
|
||||
max_attacks_ = cfg[z_attacks].to_int(1);
|
||||
cost_ = cfg[z_cost].to_int(1);
|
||||
usage_ = cfg_[z_usage].str();
|
||||
undead_variation_ = cfg_[z_undead_variation].token();
|
||||
image_ = cfg_[z_image].str();
|
||||
small_profile_ = cfg_[z_small_profile].str();
|
||||
big_profile_ = cfg_[z_profile].str();
|
||||
adjust_profile(small_profile_, big_profile_, image_);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
@ -781,7 +1002,7 @@ void unit_type::build_help_index(const movement_type_map &mv_types,
|
||||
gender_types_[i]->build_help_index(mv_types, races, traits);
|
||||
}
|
||||
|
||||
const race_map::const_iterator race_it = races.find(cfg["race"]);
|
||||
const race_map::const_iterator race_it = races.find(cfg[z_race]);
|
||||
if(race_it != races.end()) {
|
||||
race_ = &race_it->second;
|
||||
} else {
|
||||
@ -789,9 +1010,9 @@ void unit_type::build_help_index(const movement_type_map &mv_types,
|
||||
}
|
||||
|
||||
// if num_traits is not defined, we use the num_traits from race
|
||||
num_traits_ = cfg["num_traits"].to_int(race_->num_traits());
|
||||
num_traits_ = cfg[z_num_traits].to_int(race_->num_traits());
|
||||
|
||||
const std::vector<std::string> genders = utils::split(cfg["gender"]);
|
||||
const std::vector<std::string> genders = utils::split(cfg[z_gender]);
|
||||
for(std::vector<std::string>::const_iterator g = genders.begin(); g != genders.end(); ++g) {
|
||||
genders_.push_back(string_gender(*g));
|
||||
}
|
||||
@ -799,36 +1020,36 @@ void unit_type::build_help_index(const movement_type_map &mv_types,
|
||||
genders_.push_back(unit_race::MALE);
|
||||
}
|
||||
|
||||
if (const config &abil_cfg = cfg.child("abilities"))
|
||||
if (const config &abil_cfg = cfg.child(z_abilities))
|
||||
{
|
||||
foreach (const config::any_child &ab, abil_cfg.all_children_range()) {
|
||||
const std::string &name = ab.cfg["name"];
|
||||
const std::string &name = ab.cfg[z_name];
|
||||
if (!name.empty()) {
|
||||
abilities_.push_back(name);
|
||||
ability_tooltips_.push_back(ab.cfg["description"]);
|
||||
ability_tooltips_.push_back(ab.cfg[z_description]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const config &adv, cfg.child_range("advancement"))
|
||||
foreach (const config &adv, cfg.child_range(z_advancement))
|
||||
{
|
||||
foreach (const config &effect, adv.child_range("effect"))
|
||||
foreach (const config &effect, adv.child_range(z_effect))
|
||||
{
|
||||
const config &abil_cfg = effect.child("abilities");
|
||||
if (!abil_cfg || effect["apply_to"] != "new_ability") {
|
||||
const config &abil_cfg = effect.child(z_abilities);
|
||||
if (!abil_cfg || effect[z_apply_to] != z_new_ability) {
|
||||
continue;
|
||||
}
|
||||
foreach (const config::any_child &ab, abil_cfg.all_children_range()) {
|
||||
const std::string &name = ab.cfg["name"];
|
||||
const std::string &name = ab.cfg[z_name];
|
||||
if (!name.empty()) {
|
||||
adv_abilities_.push_back(name);
|
||||
adv_ability_tooltips_.push_back(ab.cfg["description"]);
|
||||
adv_ability_tooltips_.push_back(ab.cfg[z_description]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hide_help_= cfg["hide_help"].to_bool();
|
||||
hide_help_= cfg[z_hide_help].to_bool();
|
||||
|
||||
build_status_ = HELP_INDEX;
|
||||
}
|
||||
@ -841,45 +1062,51 @@ void unit_type::build_created(const movement_type_map &mv_types,
|
||||
|
||||
config &cfg = cfg_;
|
||||
|
||||
if (config &male_cfg = cfg.child("male"))
|
||||
if (config &male_cfg = cfg.child(z_male))
|
||||
{
|
||||
if (male_cfg["inherit"].to_bool(true)) {
|
||||
if (male_cfg[z_inherit].to_bool(true)) {
|
||||
config m_cfg(cfg);
|
||||
m_cfg.merge_with(male_cfg);
|
||||
male_cfg.swap(m_cfg);
|
||||
}
|
||||
male_cfg.clear_children("male");
|
||||
male_cfg.clear_children("female");
|
||||
male_cfg.clear_children(z_male);
|
||||
male_cfg.clear_children(z_female);
|
||||
gender_types_[0] = new unit_type(male_cfg);
|
||||
}
|
||||
|
||||
if (config &female_cfg = cfg.child("female"))
|
||||
if (config &female_cfg = cfg.child(z_female))
|
||||
{
|
||||
if (female_cfg["inherit"].to_bool(true)) {
|
||||
if (female_cfg[z_inherit].to_bool(true)) {
|
||||
config f_cfg(cfg);
|
||||
f_cfg.merge_with(female_cfg);
|
||||
female_cfg.swap(f_cfg);
|
||||
}
|
||||
female_cfg.clear_children("male");
|
||||
female_cfg.clear_children("female");
|
||||
female_cfg.clear_children(z_male);
|
||||
female_cfg.clear_children(z_female);
|
||||
gender_types_[1] = new unit_type(female_cfg);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (gender_types_[i])
|
||||
gender_types_[i]->build_created(mv_types, races, traits);
|
||||
if (gender_types_[i]){
|
||||
gender_types_[i]->build_created(mv_types, races, traits);}
|
||||
}
|
||||
|
||||
const std::string& advances_to_val = cfg["advances_to"];
|
||||
if(advances_to_val != "null" && advances_to_val != "")
|
||||
const std::string& advances_to_val = cfg[z_advances_to];
|
||||
if(advances_to_val != z_null && advances_to_val != z_empty)
|
||||
advances_to_ = utils::split(advances_to_val);
|
||||
DBG_UT << "unit_type '" << id_ << "' advances to : " << advances_to_val << "\n";
|
||||
DBG_UT << "unit_type '" << id() << "' advances to : " << advances_to_val << "\n";
|
||||
|
||||
experience_needed_ = cfg["experience"].to_int(500);
|
||||
experience_needed_ = cfg[z_experience].to_int(500);
|
||||
|
||||
build_status_ = CREATED;
|
||||
}
|
||||
|
||||
const unit_type& unit_type::get_gender_unit_type(config::t_token gender) const
|
||||
{
|
||||
if (gender == z_female) return get_gender_unit_type(unit_race::FEMALE);
|
||||
else if (gender == z_male) return get_gender_unit_type(unit_race::MALE);
|
||||
else return *this;
|
||||
}
|
||||
const unit_type& unit_type::get_gender_unit_type(std::string gender) const
|
||||
{
|
||||
if (gender == "female") return get_gender_unit_type(unit_race::FEMALE);
|
||||
@ -928,7 +1155,7 @@ const std::vector<unit_animation>& unit_type::animations() const {
|
||||
std::vector<attack_type> unit_type::attacks() const
|
||||
{
|
||||
std::vector<attack_type> res;
|
||||
foreach (const config &att, cfg_.child_range("attack")) {
|
||||
foreach (const config &att, cfg_.child_range(z_attack)) {
|
||||
res.push_back(attack_type(att));
|
||||
}
|
||||
|
||||
@ -982,10 +1209,10 @@ const char* unit_type::alignment_id(unit_type::ALIGNMENT align)
|
||||
|
||||
bool unit_type::has_ability_by_id(const std::string& ability) const
|
||||
{
|
||||
if (const config &abil = cfg_.child("abilities"))
|
||||
if (const config &abil = cfg_.child(z_abilities))
|
||||
{
|
||||
foreach (const config::any_child &ab, abil.all_children_range()) {
|
||||
if (ab.cfg["id"] == ability)
|
||||
if (ab.cfg[z_id] == ability)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -996,11 +1223,11 @@ std::vector<std::string> unit_type::get_ability_list() const
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
const config &abilities = cfg_.child("abilities");
|
||||
const config &abilities = cfg_.child(z_abilities);
|
||||
if (!abilities) return res;
|
||||
|
||||
foreach (const config::any_child &ab, abilities.all_children_range()) {
|
||||
const std::string &id = ab.cfg["id"];
|
||||
const std::string &id = ab.cfg[z_id];
|
||||
if (!id.empty())
|
||||
res.push_back(id);
|
||||
}
|
||||
@ -1009,13 +1236,13 @@ std::vector<std::string> unit_type::get_ability_list() const
|
||||
}
|
||||
|
||||
bool unit_type::hide_help() const {
|
||||
return hide_help_ || unit_types.hide_help(id_, race_->id());
|
||||
return hide_help_ || unit_types.hide_help(id(), race_->id());
|
||||
}
|
||||
|
||||
void unit_type::add_advancement(const unit_type &to_unit,int xp)
|
||||
{
|
||||
const std::string &to_id = to_unit.cfg_["id"];
|
||||
const std::string &from_id = cfg_["id"];
|
||||
const std::string &to_id = to_unit.cfg_[z_id];
|
||||
const std::string &from_id = cfg_[z_id];
|
||||
|
||||
// Add extra advancement path to this unit type
|
||||
LOG_CONFIG << "adding advancement from " << from_id << " to " << to_id << "\n";
|
||||
@ -1082,7 +1309,7 @@ static void advancement_tree_internal(const std::string& id, std::set<std::strin
|
||||
std::set<std::string> unit_type::advancement_tree() const
|
||||
{
|
||||
std::set<std::string> tree;
|
||||
advancement_tree_internal(id_, tree);
|
||||
advancement_tree_internal(id(), tree);
|
||||
return tree;
|
||||
}
|
||||
|
||||
@ -1095,7 +1322,7 @@ const std::vector<std::string> unit_type::advances_from() const
|
||||
foreach (const unit_type_data::unit_type_map::value_type &ut, unit_types.types())
|
||||
{
|
||||
foreach(const std::string& adv, ut.second.advances_to()) {
|
||||
if (adv == id_)
|
||||
if (adv == id())
|
||||
adv_from.push_back(ut.second.id());
|
||||
}
|
||||
}
|
||||
@ -1116,12 +1343,12 @@ unit_type_data::unit_type_data() :
|
||||
|
||||
void unit_type_data::set_config(config &cfg)
|
||||
{
|
||||
DBG_UT << "unit_type_data::set_config, name: " << cfg["name"] << "\n";
|
||||
DBG_UT << "unit_type_data::set_config, name: " << cfg[z_name] << "\n";
|
||||
|
||||
clear();
|
||||
set_unit_config(cfg);
|
||||
|
||||
foreach (const config &mt, cfg.child_range("movetype"))
|
||||
foreach (const config &mt, cfg.child_range(z_movetype))
|
||||
{
|
||||
const unit_movement_type move_type(mt);
|
||||
movement_types_.insert(
|
||||
@ -1129,21 +1356,21 @@ void unit_type_data::set_config(config &cfg)
|
||||
loadscreen::increment_progress();
|
||||
}
|
||||
|
||||
foreach (const config &r, cfg.child_range("race"))
|
||||
foreach (const config &r, cfg.child_range(z_race))
|
||||
{
|
||||
const unit_race race(r);
|
||||
races_.insert(std::pair<std::string,unit_race>(race.id(),race));
|
||||
loadscreen::increment_progress();
|
||||
}
|
||||
|
||||
foreach (config &ut, cfg.child_range("unit_type"))
|
||||
foreach (config &ut, cfg.child_range(z_unit_type))
|
||||
{
|
||||
std::string id = ut["id"];
|
||||
if (const config &bu = ut.child("base_unit"))
|
||||
std::string id = ut[z_id];
|
||||
if (const config &bu = ut.child(z_base_unit))
|
||||
{
|
||||
// Derive a new unit type from an existing base unit id
|
||||
config merge_cfg = find_config(bu["id"]);
|
||||
ut.clear_children("base_unit");
|
||||
config merge_cfg = find_config(bu[z_id]);
|
||||
ut.clear_children(z_base_unit);
|
||||
merge_cfg.merge_with(ut);
|
||||
ut.swap(merge_cfg);
|
||||
}
|
||||
@ -1155,15 +1382,15 @@ void unit_type_data::set_config(config &cfg)
|
||||
|
||||
build_all(unit_type::CREATED);
|
||||
|
||||
if (const config &hide_help = cfg.child("hide_help")) {
|
||||
hide_help_all_ = hide_help["all"].to_bool();
|
||||
if (const config &hide_help = cfg.child(z_hide_help)) {
|
||||
hide_help_all_ = hide_help[z_all].to_bool();
|
||||
read_hide_help(hide_help);
|
||||
}
|
||||
}
|
||||
|
||||
const unit_type *unit_type_data::find(const std::string& key, unit_type::BUILD_STATUS status) const
|
||||
{
|
||||
if (key.empty() || key == "random") return NULL;
|
||||
if (key.empty() || key == z_random) return NULL;
|
||||
|
||||
DBG_CF << "trying to find " << key << " in unit_type list (unit_type_data.unit_types)\n";
|
||||
const unit_type_map::iterator itor = types_.find(key);
|
||||
@ -1192,7 +1419,7 @@ void unit_type_data::check_types(const std::vector<std::string>& types) const
|
||||
|
||||
const config& unit_type_data::find_config(const std::string& key) const
|
||||
{
|
||||
const config &cfg = unit_cfg_->find_child("unit_type", "id", key);
|
||||
const config &cfg = unit_cfg_->find_child(z_unit_type, z_id, key);
|
||||
|
||||
if (cfg)
|
||||
return cfg;
|
||||
@ -1240,14 +1467,14 @@ unit_type &unit_type_data::build_unit_type(const unit_type_map::iterator &ut, un
|
||||
|
||||
switch (status) {
|
||||
case unit_type::CREATED:
|
||||
ut->second.build_created(movement_types_, races_, unit_cfg_->child_range("trait"));
|
||||
ut->second.build_created(movement_types_, races_, unit_cfg_->child_range(z_trait));
|
||||
break;
|
||||
case unit_type::HELP_INDEX:
|
||||
// Build the data needed to feed the help index.
|
||||
ut->second.build_help_index(movement_types_, races_, unit_cfg_->child_range("trait"));
|
||||
ut->second.build_help_index(movement_types_, races_, unit_cfg_->child_range(z_trait));
|
||||
break;
|
||||
default:
|
||||
ut->second.build_full(movement_types_, races_, unit_cfg_->child_range("trait"));
|
||||
ut->second.build_full(movement_types_, races_, unit_cfg_->child_range(z_trait));
|
||||
}
|
||||
|
||||
return ut->second;
|
||||
@ -1261,13 +1488,13 @@ void unit_type_data::read_hide_help(const config& cfg)
|
||||
hide_help_race_.push_back(std::set<std::string>());
|
||||
hide_help_type_.push_back(std::set<std::string>());
|
||||
|
||||
std::vector<std::string> races = utils::split(cfg["race"]);
|
||||
std::vector<std::string> races = utils::split(cfg[z_race]);
|
||||
hide_help_race_.back().insert(races.begin(), races.end());
|
||||
|
||||
std::vector<std::string> types = utils::split(cfg["type"]);
|
||||
std::vector<std::string> types = utils::split(cfg[z_type]);
|
||||
hide_help_type_.back().insert(types.begin(), types.end());
|
||||
|
||||
std::vector<std::string> trees = utils::split(cfg["type_adv_tree"]);
|
||||
std::vector<std::string> trees = utils::split(cfg[z_type_adv_tree]);
|
||||
hide_help_type_.back().insert(trees.begin(), trees.end());
|
||||
foreach(const std::string& t_id, trees) {
|
||||
unit_type_map::iterator ut = types_.find(t_id);
|
||||
@ -1278,7 +1505,7 @@ void unit_type_data::read_hide_help(const config& cfg)
|
||||
}
|
||||
|
||||
// we call recursively all the imbricated [not] tags
|
||||
read_hide_help(cfg.child("not"));
|
||||
read_hide_help(cfg.child(z_not));
|
||||
}
|
||||
|
||||
bool unit_type_data::hide_help(const std::string& type, const std::string& race) const
|
||||
@ -1300,10 +1527,10 @@ void unit_type_data::add_advancement(unit_type& to_unit) const
|
||||
{
|
||||
const config& cfg = to_unit.get_cfg();
|
||||
|
||||
foreach (const config &af, cfg.child_range("advancefrom"))
|
||||
foreach (const config &af, cfg.child_range(z_advancefrom))
|
||||
{
|
||||
const std::string &from = af["unit"];
|
||||
int xp = af["experience"];
|
||||
const std::string &from = af[z_unit];
|
||||
int xp = af[z_experience];
|
||||
|
||||
unit_type_data::unit_type_map::iterator from_unit = types_.find(from);
|
||||
|
||||
@ -1341,17 +1568,17 @@ bool unit_type::not_living() const
|
||||
// that unit::apply_modifications does things.
|
||||
foreach (const config &mod, possible_traits())
|
||||
{
|
||||
if (mod["availability"] != "musthave")
|
||||
if (mod[z_availability] != z_musthave)
|
||||
continue;
|
||||
|
||||
foreach (const config &effect, mod.child_range("effect"))
|
||||
foreach (const config &effect, mod.child_range(z_effect))
|
||||
{
|
||||
// See if the effect only applies to
|
||||
// certain unit types But don't worry
|
||||
// about gender checks, since we don't
|
||||
// know what the gender of the
|
||||
// hypothetical recruit is.
|
||||
const std::string &ut = effect["unit_type"];
|
||||
const std::string &ut = effect[z_unit_type];
|
||||
if (!ut.empty()) {
|
||||
const std::vector<std::string> &types = utils::split(ut);
|
||||
if(std::find(types.begin(), types.end(), id()) == types.end())
|
||||
@ -1359,13 +1586,13 @@ bool unit_type::not_living() const
|
||||
}
|
||||
|
||||
// We're only interested in status changes.
|
||||
if (effect["apply_to"] != "status") {
|
||||
if (effect[z_apply_to] != z_status) {
|
||||
continue;
|
||||
}
|
||||
if (effect["add"] == "not_living") {
|
||||
if (effect[z_add] == z_not_living) {
|
||||
not_living = true;
|
||||
}
|
||||
if (effect["remove"] == "not_living") {
|
||||
if (effect[z_remove] == z_not_living) {
|
||||
not_living = false;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "unit_animation.hpp"
|
||||
#include "portrait.hpp"
|
||||
#include "race.hpp"
|
||||
#include "resources.hpp"
|
||||
|
||||
class gamemap;
|
||||
class unit;
|
||||
@ -26,6 +27,12 @@ class unit_map;
|
||||
class unit_type_data;
|
||||
|
||||
|
||||
namespace{
|
||||
static const config::t_token z_movement_used("movement_used", false);
|
||||
static const config::t_token z_advancement("advancement", false);
|
||||
static const config::t_token z_trait("trait", false);
|
||||
//static const config::t_token z_("", false);
|
||||
}
|
||||
//and how much damage it does.
|
||||
class attack_type
|
||||
{
|
||||
@ -47,8 +54,8 @@ public:
|
||||
double attack_weight() const { return attack_weight_; }
|
||||
double defense_weight() const { return defense_weight_; }
|
||||
|
||||
bool get_special_bool(const std::string& special,bool force=false) const;
|
||||
unit_ability_list get_specials(const std::string& special) const;
|
||||
bool get_special_bool(const config::t_token& special,bool force=false) const;
|
||||
unit_ability_list get_specials(const config::t_token& special) const;
|
||||
std::vector<t_string> special_tooltips(bool force=false) const;
|
||||
std::string weapon_specials(bool force=false) const;
|
||||
void set_specials_context(const map_location& aloc,const map_location& dloc,
|
||||
@ -59,7 +66,7 @@ public:
|
||||
bool apply_modification(const config& cfg,std::string* description);
|
||||
bool describe_modification(const config& cfg,std::string* description);
|
||||
|
||||
int movement_used() const { return cfg_["movement_used"].to_int(100000); }
|
||||
int movement_used() const { return cfg_[z_movement_used].to_int(100000); }
|
||||
|
||||
config& get_cfg() { return cfg_; }
|
||||
const config& get_cfg() const { return cfg_; }
|
||||
@ -70,7 +77,13 @@ public:
|
||||
/*
|
||||
* cfg: a weapon special WML structure
|
||||
*/
|
||||
bool special_active(const config& cfg, bool self) const;
|
||||
bool special_active(gamemap const & game_map, unit_map const & units,
|
||||
t_teams const & teams, LuaKernel & lua_kernel,
|
||||
tod_manager const & tod_manager,
|
||||
const config& cfg, bool self) const;
|
||||
inline bool special_active(const config& cfg, bool self) const {
|
||||
return special_active(*resources::game_map, *resources::units,*resources::teams,
|
||||
*resources::lua_kernel, *resources::tod_manager, cfg, self);}
|
||||
bool special_affects_opponent(const config& cfg) const;
|
||||
bool special_affects_self(const config& cfg) const;
|
||||
|
||||
@ -204,13 +217,14 @@ public:
|
||||
const std::vector<std::string> advances_from() const;
|
||||
|
||||
config::const_child_itors modification_advancements() const
|
||||
{ return cfg_.child_range("advancement"); }
|
||||
{ return cfg_.child_range(z_advancement); }
|
||||
|
||||
const unit_type& get_gender_unit_type(config::t_token gender) const;
|
||||
const unit_type& get_gender_unit_type(std::string gender) const;
|
||||
const unit_type& get_gender_unit_type(unit_race::GENDER gender) const;
|
||||
const unit_type& get_variation(const std::string& name) const;
|
||||
/** Info on the type of unit that the unit reanimates as. */
|
||||
const std::string& undead_variation() const { return undead_variation_; }
|
||||
const config::t_token& undead_variation() const { return undead_variation_; }
|
||||
|
||||
unsigned int num_traits() const { return num_traits_; }
|
||||
|
||||
@ -233,7 +247,7 @@ public:
|
||||
|
||||
const std::vector<unit_animation>& animations() const;
|
||||
|
||||
const std::string& flag_rgb() const { return flag_rgb_; }
|
||||
const config::t_token& flag_rgb() const { return flag_rgb_; }
|
||||
|
||||
std::vector<attack_type> attacks() const;
|
||||
const unit_movement_type& movement_type() const { return movementType_; }
|
||||
@ -273,7 +287,7 @@ public:
|
||||
std::vector<std::string> get_ability_list() const;
|
||||
|
||||
config::const_child_itors possible_traits() const
|
||||
{ return possibleTraits_.child_range("trait"); }
|
||||
{ return possibleTraits_.child_range(z_trait); }
|
||||
bool has_random_traits() const;
|
||||
|
||||
const std::vector<unit_race::GENDER>& genders() const { return genders_; }
|
||||
@ -303,12 +317,12 @@ private:
|
||||
int max_attacks_;
|
||||
int cost_;
|
||||
std::string usage_;
|
||||
std::string undead_variation_;
|
||||
config::t_token undead_variation_;
|
||||
|
||||
std::string image_;
|
||||
std::string small_profile_;
|
||||
std::string big_profile_;
|
||||
std::string flag_rgb_;
|
||||
config::t_token flag_rgb_;
|
||||
|
||||
unsigned int num_traits_;
|
||||
|
||||
|
@ -625,7 +625,7 @@ public:
|
||||
assert(false);
|
||||
break;
|
||||
case ']':
|
||||
std::string index_str(skey.substr(i_start_of_token, i ));
|
||||
std::string index_str(skey.substr(i_start_of_token, i - i_start_of_token ));
|
||||
std::istringstream is(index_str);
|
||||
size_t index;
|
||||
is >> index;
|
||||
@ -647,11 +647,11 @@ public:
|
||||
} else {
|
||||
switch(c){
|
||||
case '.' :
|
||||
parsed_tokens.push_back(t_parsed(t_token(skey.substr(i_start_of_token, i ))));
|
||||
parsed_tokens.push_back(t_parsed(t_token(skey.substr(i_start_of_token, i - i_start_of_token ))));
|
||||
i_start_of_token = i + 1;
|
||||
break;
|
||||
case '[':
|
||||
parsed_tokens.push_back(t_parsed(t_token(skey.substr(i_start_of_token, i ))));
|
||||
parsed_tokens.push_back(t_parsed(t_token(skey.substr(i_start_of_token, i - i_start_of_token ))));
|
||||
i_start_of_token = i + 1;
|
||||
is_lbrack=true;
|
||||
break;
|
||||
@ -662,7 +662,7 @@ public:
|
||||
++i;
|
||||
}
|
||||
if(i_start_of_token != i){
|
||||
parsed_tokens.push_back(t_token(skey.substr(i_start_of_token, i )));
|
||||
parsed_tokens.push_back(t_token(skey.substr(i_start_of_token, i - i_start_of_token )));
|
||||
}
|
||||
|
||||
return parsed_tokens;
|
||||
@ -670,7 +670,7 @@ public:
|
||||
};
|
||||
|
||||
// typedef boost::unordered_map<config::t_token, t_parsed_tokens> t_all_parsed;
|
||||
static const uint CACHE_SIZE = 1000;
|
||||
static const uint CACHE_SIZE = 10000;
|
||||
typedef n_lru_cache::t_lru_cache<config::t_token, t_parsed_tokens, t_parse_token> t_all_parsed;
|
||||
|
||||
|
||||
@ -712,7 +712,7 @@ void variable_info::init(const config::t_token& varname, bool force_valid) {
|
||||
|
||||
t_parsed_tokens tokens(cache.check(varname));
|
||||
|
||||
if(tokens.empty()){return;}
|
||||
if(tokens.empty()){ return; }
|
||||
|
||||
activate_scope_variable(tokens);
|
||||
vars = &repos->variables_;
|
||||
@ -724,8 +724,10 @@ void variable_info::init(const config::t_token& varname, bool force_valid) {
|
||||
while (i < last_token){
|
||||
int inner_index = 0;
|
||||
int size = vars->child_count( i->token);
|
||||
|
||||
if(i->index != t_parsed::NO_INDEX){
|
||||
inner_index = i->index;
|
||||
|
||||
if(size <= inner_index) {
|
||||
bool last_key_is_not_length ((i == second_last_token) && (last_token->token != z_length));
|
||||
if(force_valid) {
|
||||
@ -772,6 +774,7 @@ void variable_info::init(const config::t_token& varname, bool force_valid) {
|
||||
|
||||
key = i->token;
|
||||
if(i->index != t_parsed::NO_INDEX){
|
||||
explicit_index_ = true;
|
||||
size_t size = vars->child_count(key);
|
||||
index = i->index;
|
||||
if(size <= index) {
|
||||
@ -804,7 +807,7 @@ void variable_info::init(const config::t_token& varname, bool force_valid) {
|
||||
WRN_NG << "variable_info: using explicitly indexed "
|
||||
"container as wrong WML type, " << varname << '\n';
|
||||
}
|
||||
explicit_index = false;
|
||||
explicit_index_ = false;
|
||||
index = 0;
|
||||
} else {
|
||||
// Final variable is not an explicit index [...]
|
||||
@ -825,15 +828,19 @@ void variable_info::init(const config::t_token& varname, bool force_valid) {
|
||||
}
|
||||
|
||||
variable_info::variable_info(const config::t_token& varname, bool force_valid, TYPE validation_type)
|
||||
: vartype(validation_type), is_valid_(false), key(varname), explicit_index(false), index(0), vars(NULL) {
|
||||
: vartype(validation_type), is_valid_(false), explicit_index_(false), key(varname), index(0), vars(NULL) {
|
||||
init( varname, force_valid) ;}
|
||||
|
||||
variable_info::variable_info(const t_string& varname, bool force_valid, TYPE validation_type)
|
||||
: vartype(validation_type), is_valid_(false), explicit_index_(false),key(varname.token()), index(0), vars(NULL) {
|
||||
init(varname.token(), force_valid);}
|
||||
|
||||
variable_info::variable_info(const std::string& varname, bool force_valid, TYPE validation_type)
|
||||
: vartype(validation_type), is_valid_(false), key(varname), explicit_index(false), index(0), vars(NULL) {
|
||||
: vartype(validation_type), is_valid_(false), explicit_index_(false), key(varname), index(0), vars(NULL) {
|
||||
init(config::t_token(varname), force_valid);}
|
||||
|
||||
variable_info::variable_info(const config::attribute_value& varname, bool force_valid, TYPE validation_type)
|
||||
: vartype(validation_type), is_valid_(false), key(varname.token()), explicit_index(false), index(0), vars(NULL) {
|
||||
: vartype(validation_type), is_valid_(false), explicit_index_(false), key(varname.token()), index(0), vars(NULL) {
|
||||
init(varname.token(), force_valid);}
|
||||
|
||||
|
||||
@ -845,7 +852,7 @@ config::attribute_value &variable_info::as_scalar() {
|
||||
|
||||
config& variable_info::as_container() {
|
||||
assert(is_valid_);
|
||||
if(explicit_index) {
|
||||
if(explicit_index_) {
|
||||
// Empty data for explicit index was already created if it was needed
|
||||
return vars->child(key, index);
|
||||
}
|
||||
|
@ -229,6 +229,7 @@ public:
|
||||
TYPE_UNSPECIFIED };
|
||||
|
||||
variable_info(const config::t_token& varname, bool force_valid=true, TYPE validation_type=TYPE_UNSPECIFIED);
|
||||
variable_info(const t_string& varname, bool force_valid=true, TYPE validation_type=TYPE_UNSPECIFIED);
|
||||
variable_info(const std::string& varname, bool force_valid=true, TYPE validation_type=TYPE_UNSPECIFIED);
|
||||
variable_info(const config::attribute_value& varname, bool force_valid=true, TYPE validation_type=TYPE_UNSPECIFIED);
|
||||
|
||||
@ -240,17 +241,17 @@ public:
|
||||
config& as_container();
|
||||
array_range as_array(); //range may be empty
|
||||
bool is_valid() const {return is_valid_;}
|
||||
bool is_explicit_index() const {return explicit_index;}
|
||||
bool is_explicit_index() const {return explicit_index_;}
|
||||
|
||||
private:
|
||||
void init(const config::t_token& varname, bool force_valid=true);
|
||||
public: ///todo make these private
|
||||
TYPE vartype; ///default is TYPE_UNSPECIFIED
|
||||
bool is_valid_;
|
||||
config::t_token key; ///the name of the internal attribute or child
|
||||
bool explicit_index; ///true if query ended in [...] specifier
|
||||
size_t index; //'the index of the child
|
||||
config *vars; ///the containing node in game_state::variables
|
||||
bool explicit_index_; ///true if query ended in [...] specifier
|
||||
public: ///todo make these private
|
||||
config::t_token key; /// the name of the internal attribute or child
|
||||
size_t index; /// the index of the child
|
||||
config *vars; /// the containing node in game_state::variables
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user