Author: dragonking
Date: Fri Jul 11 21:23:55 2008
New Revision: 27912
URL: http://svn.gna.org/viewcvs/wesnoth?rev=27912&view=rev
Log:
New formula AI function: max_possible_damage_with_retaliation
Modified:
trunk/src/formula_ai.cpp
Modified: trunk/src/formula_ai.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/formula_ai.cpp?rev=27912&r1=27911&r2=27912&view=diff
==============================================================================
--- trunk/src/formula_ai.cpp (original)
+++ trunk/src/formula_ai.cpp Fri Jul 11 21:23:55 2008
@@ -833,7 +833,7 @@
std::vector<attack_type> attacks_tmp;
std::vector<attack_type>& attacks = attacks_tmp;
- //we have to make sure that this fuction works with any
combination of unit_callable/unit_type_callable passed to it
+ //we have to make sure that this function works with any
combination of unit_callable/unit_type_callable passed to it
const unit_callable* u_attacker =
try_convert_variant<unit_callable>(u1);
if (u_attacker)
{
@@ -870,7 +870,177 @@
const formula_ai& ai_;
};
+
+
+class max_possible_damage_with_retaliation_function : public
function_expression {
+public:
+ max_possible_damage_with_retaliation_function(const args_list& args,
const formula_ai& ai_object)
+ : function_expression("max_possible_damage_with_retaliation", args,
2, 2), ai_(ai_object)
+ {}
+private:
+ variant execute(const formula_callable& variables) const {
+ variant u1 = args()[0]->evaluate(variables);
+ variant u2 = args()[1]->evaluate(variables);
+ if(u1.is_null() || u2.is_null()) {
+ return variant();
+ }
+ std::vector<variant> vars;
+
+ //store best damage and best attack causing it
+ int best = 0;
+ std::vector<attack_type>::const_iterator best_attack;
+
+ //vectors with attacks for attacker and defender
+ std::vector<attack_type> att_attacks_tmp;
+ std::vector<attack_type>& att_attacks = att_attacks_tmp;
+
+ std::vector<attack_type> def_attacks_tmp;
+ std::vector<attack_type>& def_attacks = def_attacks_tmp;
+
+ //we have to make sure that this fuction works with any
combination of unit_callable/unit_type_callable passed to it
+ const unit_callable* u_attacker =
try_convert_variant<unit_callable>(u1);
+ if (u_attacker)
+ {
+ const unit& attacker = u_attacker->get_unit();
+ att_attacks = attacker.attacks();
+
+ const unit_callable* u_defender =
try_convert_variant<unit_callable>(u2);
+ if (u_defender)
+ {
+ const unit& defender = u_defender->get_unit();
+
+ for(std::vector<attack_type>::const_iterator i
= att_attacks.begin(); i != att_attacks.end(); ++i) {
+ const int dmg =
round_damage(i->damage(), defender.damage_from(*i, false, gamemap::location()),
100) * i->num_attacks();
+ if(dmg > best)
+ {
+ best = dmg;
+ best_attack = i;
+ }
+ }
+
+ //we have max damage inflicted by attacker, now
we need to search for max possible damage of defender (search only for attack
with the same range)
+ vars.push_back(variant(best));
+
+ best = 0;
+ def_attacks = defender.attacks();
+
+ for(std::vector<attack_type>::const_iterator i
= def_attacks.begin(); i != def_attacks.end(); ++i) {
+ if(i->range() != best_attack->range())
+ continue;
+
+ const int dmg =
round_damage(i->damage(), attacker.damage_from(*i, false, gamemap::location()),
100) * i->num_attacks();
+ if(dmg > best)
+ best = dmg;
+ }
+
+ vars.push_back(variant(best));
+ return variant(&vars);
+
+ } else
+ {
+ const unit_type& defender =
convert_variant<unit_type_callable>(u2)->get_unit_type();
+
+ for(std::vector<attack_type>::const_iterator i
= att_attacks.begin(); i != att_attacks.end(); ++i) {
+ const int dmg =
round_damage(i->damage(), defender.movement_type().resistance_against(*i), 100)
* i->num_attacks();
+ if(dmg > best)
+ {
+ best = dmg;
+ best_attack = i;
+ }
+ }
+
+ vars.push_back(variant(best));
+
+ best = 0;
+ def_attacks_tmp = defender.attacks();
+
+ for(std::vector<attack_type>::const_iterator i
= def_attacks.begin(); i != def_attacks.end(); ++i) {
+ if(i->range() != best_attack->range())
+ continue;
+
+ const int dmg =
round_damage(i->damage(), attacker.damage_from(*i, false, gamemap::location()),
100) * i->num_attacks();
+ if(dmg > best)
+ best = dmg;
+ }
+
+ vars.push_back(variant(best));
+ return variant(&vars);
+ }
+
+ } else
+ {
+ const unit_type& attacker =
convert_variant<unit_type_callable>(u1)->get_unit_type();
+ att_attacks = attacker.attacks();
+
+ const unit_callable* u_defender =
try_convert_variant<unit_callable>(u2);
+ if (u_defender)
+ {
+ const unit& defender = u_defender->get_unit();
+
+ for(std::vector<attack_type>::const_iterator i
= att_attacks.begin(); i != att_attacks.end(); ++i) {
+ const int dmg =
round_damage(i->damage(), defender.damage_from(*i, false, gamemap::location()),
100) * i->num_attacks();
+ if(dmg > best)
+ {
+ best = dmg;
+ best_attack = i;
+ }
+ }
+
+ //we have max damage inflicted by attacker, now
we need to search for max possible damage of defender (search only for attack
with the same range)
+ vars.push_back(variant(best));
+
+ best = 0;
+ def_attacks = defender.attacks();
+
+ for(std::vector<attack_type>::const_iterator i
= def_attacks.begin(); i != def_attacks.end(); ++i) {
+ if(i->range() != best_attack->range())
+ continue;
+
+ const int dmg =
round_damage(i->damage(), attacker.movement_type().resistance_against(*i), 100)
* i->num_attacks();
+ if(dmg > best)
+ best = dmg;
+ }
+
+ vars.push_back(variant(best));
+ return variant(&vars);
+
+ } else
+ {
+ const unit_type& defender =
convert_variant<unit_type_callable>(u2)->get_unit_type();
+
+ for(std::vector<attack_type>::const_iterator i
= att_attacks.begin(); i != att_attacks.end(); ++i) {
+ const int dmg =
round_damage(i->damage(), defender.movement_type().resistance_against(*i), 100)
* i->num_attacks();
+ if(dmg > best)
+ {
+ best = dmg;
+ best_attack = i;
+ }
+ }
+
+ vars.push_back(variant(best));
+
+ best = 0;
+ def_attacks_tmp = defender.attacks();
+
+ for(std::vector<attack_type>::const_iterator i
= def_attacks.begin(); i != def_attacks.end(); ++i) {
+ if(i->range() != best_attack->range())
+ continue;
+
+ const int dmg =
round_damage(i->damage(), attacker.movement_type().resistance_against(*i), 100)
* i->num_attacks();
+ if(dmg > best)
+ best = dmg;
+ }
+
+ vars.push_back(variant(best));
+ return variant(&vars);
+ }
+ }
+ }
+
+ const formula_ai& ai_;
+};
}
+
namespace game_logic {
expression_ptr ai_function_symbol_table::create_function(const std::string &fn,
@@ -907,6 +1077,8 @@
return expression_ptr(new movement_cost_function(args, ai_));
} else if(fn == "max_possible_damage") {
return expression_ptr(new max_possible_damage_function(args,
ai_));
+ } else if(fn == "max_possible_damage_with_retaliation") {
+ return expression_ptr(new
max_possible_damage_with_retaliation_function(args, ai_));
} else if(fn == "distance_to_nearest_unowned_village") {
return expression_ptr(new
distance_to_nearest_unowned_village_function(args, ai_));
} else if(fn == "nearest_keep") {
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits