Author: dave
Date: Sun Apr 6 21:21:04 2008
New Revision: 25641
URL: http://svn.gna.org/viewcvs/wesnoth?rev=25641&view=rev
Log:
apply Alesis-Novik's patch to add battle outcomes function
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=25641&r1=25640&r2=25641&view=diff
==============================================================================
--- trunk/src/formula_ai.cpp (original)
+++ trunk/src/formula_ai.cpp Sun Apr 6 21:21:04 2008
@@ -21,6 +21,7 @@
#include "formula_callable.hpp"
#include "formula_function.hpp"
#include "pathutils.hpp"
+#include "attack_prediction.hpp"
namespace {
using namespace game_logic;
@@ -208,6 +209,108 @@
const formula_ai& ai_;
};
+
+
+class outcome_callable : public formula_callable {
+ std::vector<variant> hitLeft_, prob_, status_;
+ variant get_value(const std::string& key) const {
+ if(key == "hitpoints_left") {
+ return variant(new std::vector<variant>(hitLeft_));
+ } else if(key == "probability") {
+ return variant(new std::vector<variant>(prob_));
+ } else if(key == "possible_status") {
+ return variant(new std::vector<variant>(status_));
+ } else {
+ return variant();
+ }
+ }
+
+ void get_inputs(std::vector<game_logic::formula_input>* inputs) const {
+ inputs->push_back(game_logic::formula_input("hitpoints_left",
game_logic::FORMULA_READ_ONLY));
+ inputs->push_back(game_logic::formula_input("probability",
game_logic::FORMULA_READ_ONLY));
+ inputs->push_back(game_logic::formula_input("possible_status",
game_logic::FORMULA_READ_ONLY));
+ }
+public:
+ outcome_callable( const std::vector<variant>& hitLeft,
+ const std::vector<variant>& prob,
+ const std::vector<variant>& status)
+ : hitLeft_(hitLeft), prob_(prob), status_(status)
+ {
+ }
+
+ const std::vector<variant>& hitLeft() const { return hitLeft_; }
+ const std::vector<variant>& prob() const { return prob_; }
+ const std::vector<variant>& status() const { return status_; }
+};
+
+class calculate_outcome_function : public function_expression {
+public:
+ calculate_outcome_function(const args_list& args, const formula_ai& ai)
+ : function_expression("calculate_outcome", args, 3, 4), ai_(ai) {
+ }
+
+private:
+ variant execute(const formula_callable& variables) const {
+ std::vector<variant> vars;
+ int weapon;
+ if (args().size() > 3) weapon =
args()[3]->evaluate(variables).as_int();
+ else weapon = -1;
+ battle_context bc(ai_.get_info().map, ai_.get_info().teams,
ai_.get_info().units,
+ ai_.get_info().state,
convert_variant<location_callable>(args()[1]->evaluate(variables))->loc(),
+
convert_variant<location_callable>(args()[2]->evaluate(variables))->loc(),
weapon, -1, 1.0, NULL,
+
&ai_.get_info().units.find(convert_variant<location_callable>(args()[0]->evaluate(variables))->loc())->second);
+ std::vector<double> hp_dist =
bc.get_attacker_combatant().hp_dist;
+ std::vector<double>::iterator it = hp_dist.begin();
+ int i = 0;
+ std::vector<variant> hitLeft;
+ std::vector<variant> prob;
+ while (it != hp_dist.end()) {
+ if (*it != 0) {
+ hitLeft.push_back(variant(i));
+ prob.push_back(variant(int(*it*10000)));
+ }
+ ++it;
+ ++i;
+ }
+ std::vector<variant> status;
+ if (bc.get_attacker_combatant().poisoned != 0)
+ status.push_back(variant("Poisoned"));
+ if (bc.get_attacker_combatant().slowed != 0)
+ status.push_back(variant("Slowed"));
+ if (bc.get_defender_stats().stones && hitLeft[0].as_int() !=
bc.get_attacker_stats().hp)
+ status.push_back(variant("Stoned"));
+ if (bc.get_defender_stats().plagues && hitLeft[0].as_int() == 0)
+ status.push_back(variant("Zombiefied"));
+ vars.push_back(variant(new outcome_callable(hitLeft, prob,
status)));
+ hitLeft.clear();
+ prob.clear();
+ status.clear();
+ hp_dist = bc.get_defender_combatant().hp_dist;
+ it = hp_dist.begin();
+ i = 0;
+ while (it != hp_dist.end()) {
+ if (*it != 0) {
+ hitLeft.push_back(variant(i));
+ prob.push_back(variant(int(*it*10000)));
+ }
+ ++it;
+ ++i;
+ }
+ if (bc.get_defender_combatant().poisoned != 0)
+ status.push_back(variant("Poisoned"));
+ if (bc.get_defender_combatant().slowed != 0)
+ status.push_back(variant("Slowed"));
+ if (bc.get_attacker_stats().stones && hitLeft[0].as_int() !=
bc.get_attacker_stats().hp)
+ status.push_back(variant("Stoned"));
+ if (bc.get_attacker_stats().plagues && hitLeft[0].as_int() == 0)
+ status.push_back(variant("Zombiefied"));
+ vars.push_back(variant(new outcome_callable(hitLeft, prob,
status)));
+ return variant(&vars);
+ }
+
+ const formula_ai& ai_;
+};
+
class outcomes_function : public function_expression {
public:
@@ -628,6 +731,8 @@
return expression_ptr(new nearest_loc_function(args,
ai_));
} else if(fn == "close_enemies") {
return expression_ptr(new close_enemies_function(args,
ai_));
+ } else if(fn == "calculate_outcome") {
+ return expression_ptr(new
calculate_outcome_function(args, ai_));
} else if(fn == "distance_between") {
return expression_ptr(new
distance_between_function(args));
} else {
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits