From 71a3a1b79421916ae838f3a45d0eb1072e0bf4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rosen?= Date: Sun, 30 Mar 2008 21:13:49 +0000 Subject: [PATCH] add new distance functions to formula AI, patch 1033 by Alesis Novik --- data/core/about.cfg | 4 ++++ src/formula_ai.cpp | 29 +++++++++++++++++++++++++++++ src/pathutils.cpp | 24 ++++++++++++++++++++++++ src/pathutils.hpp | 9 +++++++++ 4 files changed, 66 insertions(+) diff --git a/data/core/about.cfg b/data/core/about.cfg index 30d18de9209..3f6318c3cb3 100644 --- a/data/core/about.cfg +++ b/data/core/about.cfg @@ -624,6 +624,10 @@ [about] title = _"Miscellaneous contributors" + + [entry] + name = "Alesis Novik" + [/entry] [entry] name = "Andrea Palmatè (afxgroup)" [/entry] diff --git a/src/formula_ai.cpp b/src/formula_ai.cpp index 8449b8f3110..bc0e3b6c57c 100644 --- a/src/formula_ai.cpp +++ b/src/formula_ai.cpp @@ -148,6 +148,33 @@ private: const formula_ai& ai_; }; +class close_enemies_function : public function_expression { +public: + close_enemies_function(const args_list& args, const formula_ai& ai) + : function_expression("close_enemies", args, 2, 2), ai_(ai) { + } + +private: + variant execute(const formula_callable& variables) const { + std::vector vars; + const gamemap::location loc = convert_variant(args()[0]->evaluate(variables))->loc(); + int range = args()[1]->evaluate(variables).as_int(); + unit_map::const_iterator un = ai_.get_info().units.begin(); + unit_map::const_iterator end = ai_.get_info().units.end(); + while (un != end) { + if (distance_between(loc, un->first) <= range) { + if (un->second.side() != ai_.get_info().team_num) { + vars.push_back(variant(new unit_callable(*un, ai_.current_team(), un->second.side()))); + } + } + ++un; + } + return variant(&vars); + } + + const formula_ai& ai_; +}; + class outcomes_function : public function_expression { public: outcomes_function(const args_list& args, const formula_ai& ai) @@ -563,6 +590,8 @@ class ai_function_symbol_table : public function_symbol_table { return expression_ptr(new distance_to_nearest_unowned_village_function(args, ai_)); } else if(fn == "nearest_keep") { return expression_ptr(new nearest_keep_function(args, ai_)); + } else if(fn == "close_enemies") { + return expression_ptr(new close_enemies_function(args, ai_)); } else if(fn == "distance_between") { return expression_ptr(new distance_between_function(args)); } else { diff --git a/src/pathutils.cpp b/src/pathutils.cpp index cb08cde59a3..fb5d551bccf 100644 --- a/src/pathutils.cpp +++ b/src/pathutils.cpp @@ -57,6 +57,30 @@ void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res) res->y = a.y - (is_even(a.x) ? 1:0); } +void get_tile_ring(const gamemap::location& a, const int r, std::vector& res) +{ + if(r <= 0) { + return; + } + + gamemap::location loc = a.get_direction(gamemap::location::SOUTH_WEST, r); + + for(int n = 0; n != 6; ++n) { + const gamemap::location::DIRECTION dir = static_cast(n); + for(int i = 0; i != r; ++i) { + res.push_back(loc); + loc = loc.get_direction(dir, 1); + } + } +} + +void get_tiles_in_radius(const gamemap::location& a, const int r, std::vector& res) +{ + for(int n = 0; n <= r; ++n) { + get_tile_ring(a, n, res); + } +} + bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b) { // Two tiles are adjacent: diff --git a/src/pathutils.hpp b/src/pathutils.hpp index ef3eff2b290..fbfed4d3fa7 100644 --- a/src/pathutils.hpp +++ b/src/pathutils.hpp @@ -27,6 +27,15 @@ bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b); //! res must point to an array of 6 location objects. void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res); + +//! Function which, given a location, will place all locations in a ring of +//! distance r in res. res must be a std::vector of location +void get_tile_ring(const gamemap::location& a, const int r, std::vector& res); + +//! Function which, given a location, will place all locations in the radius of r in res +//! res must be a std::vector of location +void get_tiles_in_radius(const gamemap::location& a, const int r, std::vector& res); + //! Function which gives the number of hexes between two tiles //! (i.e. the minimum number of hexes that have to be traversed //! to get from one hex to the other).