The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
aspect_attacks.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2016 by Yurii Chernyi <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * Stage: fallback to other AI
17  * @file
18  */
19 
21 
22 #include "ai/manager.hpp"
23 #include "actions/attack.hpp"
24 #include "game_board.hpp"
25 #include "log.hpp"
26 #include "map/map.hpp"
27 #include "team.hpp"
28 #include "tod_manager.hpp"
29 #include "resources.hpp"
30 #include "units/unit.hpp"
31 #include "pathfind/pathfind.hpp"
32 #include "units/filter.hpp"
33 #include "scripting/lua_api.hpp"
34 #include "lua/lauxlib.h"
35 
36 namespace ai {
37 
38 namespace ai_default_rca {
39 
40 static lg::log_domain log_ai_testing_aspect_attacks("ai/aspect/attacks");
41 #define DBG_AI LOG_STREAM(debug, log_ai_testing_aspect_attacks)
42 #define LOG_AI LOG_STREAM(info, log_ai_testing_aspect_attacks)
43 #define ERR_AI LOG_STREAM(err, log_ai_testing_aspect_attacks)
44 
46  : typesafe_aspect<attacks_vector>(context,cfg,id)
47 {
48 }
49 
51  : aspect_attacks_base(context,cfg,id)
52  , filter_own_()
53  , filter_enemy_()
54 {
55  if (const config &filter_own = cfg.child("filter_own")) {
56  vconfig vcfg(filter_own);
57  vcfg.make_safe();
59  }
60  if (const config &filter_enemy = cfg.child("filter_enemy")) {
61  vconfig vcfg(filter_enemy);
62  vcfg.make_safe();
64  }
65 }
66 
68 {
69  this->value_ = analyze_targets();
70  this->valid_ = true;
71 }
72 
74 {
75  const move_map& srcdst = get_srcdst();
76  const move_map& dstsrc = get_dstsrc();
77  const move_map& enemy_srcdst = get_enemy_srcdst();
78  const move_map& enemy_dstsrc = get_enemy_dstsrc();
79 
82 
83  std::vector<map_location> unit_locs;
84  for(unit_map::const_iterator i = units_.begin(); i != units_.end(); ++i) {
85  if (i->side() == get_side() && i->attacks_left() && !(i->can_recruit() && get_passive_leader())) {
86  if (!is_allowed_attacker(*i)) {
87  continue;
88  }
89  unit_locs.push_back(i->get_location());
90  }
91  }
92 
93  bool used_locations[6];
94  std::fill(used_locations,used_locations+6,false);
95 
96  moves_map dummy_moves;
97  move_map fullmove_srcdst, fullmove_dstsrc;
98  calculate_possible_moves(dummy_moves,fullmove_srcdst,fullmove_dstsrc,false,true);
99 
100  unit_stats_cache().clear();
101 
102  for(unit_map::const_iterator j = units_.begin(); j != units_.end(); ++j) {
103 
104  // Attack anyone who is on the enemy side,
105  // and who is not invisible or petrified.
106  if (current_team().is_enemy(j->side()) && !j->incapacitated() &&
107  !j->invisible(j->get_location()))
108  {
109  if (!is_allowed_enemy(*j)) {
110  continue;
111  }
112  map_location adjacent[6];
113  get_adjacent_tiles(j->get_location(), adjacent);
114  attack_analysis analysis;
115  analysis.target = j->get_location();
116  analysis.vulnerability = 0.0;
117  analysis.support = 0.0;
118  do_attack_analysis(j->get_location(), srcdst, dstsrc,
119  fullmove_srcdst, fullmove_dstsrc, enemy_srcdst, enemy_dstsrc,
120  adjacent,used_locations,unit_locs,*res,analysis, current_team());
121  }
122  }
123  return res;
124 }
125 
126 
127 
129  const map_location& loc,
130  const move_map& srcdst, const move_map& dstsrc,
131  const move_map& fullmove_srcdst, const move_map& fullmove_dstsrc,
132  const move_map& enemy_srcdst, const move_map& enemy_dstsrc,
133  const map_location* tiles, bool* used_locations,
134  std::vector<map_location>& units,
135  std::vector<attack_analysis>& result,
136  attack_analysis& cur_analysis,
137  const team &current_team
138  ) const
139 {
140  // This function is called fairly frequently, so interact with the user here.
141 
143  const int default_attack_depth = 5;
144  if(cur_analysis.movements.size() >= size_t(default_attack_depth)) {
145  //std::cerr << "ANALYSIS " << cur_analysis.movements.size() << " >= " << get_attack_depth() << "\n";
146  return;
147  }
148  const gamemap &map_ = resources::gameboard->map();
150  std::vector<team> &teams_ = *resources::teams;
151 
152 
153  const size_t max_positions = 1000;
154  if(result.size() > max_positions && !cur_analysis.movements.empty()) {
155  LOG_AI << "cut analysis short with number of positions\n";
156  return;
157  }
158 
159  for(size_t i = 0; i != units.size(); ++i) {
160  const map_location current_unit = units[i];
161 
162  unit_map::iterator unit_itor = units_.find(current_unit);
163  assert(unit_itor != units_.end());
164 
165  // See if the unit has the backstab ability.
166  // Units with backstab will want to try to have a
167  // friendly unit opposite the position they move to.
168  //
169  // See if the unit has the slow ability -- units with slow only attack first.
170  bool backstab = false, slow = false;
171  std::vector<attack_type>& attacks = unit_itor->attacks();
172  for(std::vector<attack_type>::iterator a = attacks.begin(); a != attacks.end(); ++a) {
173  // For speed, just assume these specials will be active if
174  // they are present.
175  if ( a->get_special_bool("backstab", true) ) {
176  backstab = true;
177  }
178 
179  if ( a->get_special_bool("slow", true) ) {
180  slow = true;
181  }
182  }
183 
184  if(slow && cur_analysis.movements.empty() == false) {
185  continue;
186  }
187 
188  // Check if the friendly unit is surrounded,
189  // A unit is surrounded if it is flanked by enemy units
190  // and at least one other enemy unit is nearby
191  // or if the unit is totaly surrounded by enemies
192  // with max. one tile to escape.
193  bool is_surrounded = false;
194  bool is_flanked = false;
195  int enemy_units_around = 0;
196  int accessible_tiles = 0;
197  map_location adj[6];
198  get_adjacent_tiles(current_unit, adj);
199 
200  size_t tile;
201  for(tile = 0; tile != 3; ++tile) {
202 
203  const unit_map::const_iterator tmp_unit = units_.find(adj[tile]);
204  bool possible_flanked = false;
205 
206  if(map_.on_board(adj[tile]))
207  {
208  accessible_tiles++;
209  if (tmp_unit != units_.end() && current_team.is_enemy(tmp_unit->side()))
210  {
211  enemy_units_around++;
212  possible_flanked = true;
213  }
214  }
215 
216  const unit_map::const_iterator tmp_opposite_unit = units_.find(adj[tile + 3]);
217  if(map_.on_board(adj[tile + 3]))
218  {
219  accessible_tiles++;
220  if (tmp_opposite_unit != units_.end() && current_team.is_enemy(tmp_opposite_unit->side()))
221  {
222  enemy_units_around++;
223  if(possible_flanked)
224  {
225  is_flanked = true;
226  }
227  }
228  }
229  }
230 
231  if((is_flanked && enemy_units_around > 2) || enemy_units_around >= accessible_tiles - 1)
232  is_surrounded = true;
233 
234 
235 
236  double best_vulnerability = 0.0, best_support = 0.0;
237  int best_rating = 0;
238  int cur_position = -1;
239 
240  // Iterate over positions adjacent to the unit, finding the best rated one.
241  for(int j = 0; j != 6; ++j) {
242 
243  // If in this planned attack, a unit is already in this location.
244  if(used_locations[j]) {
245  continue;
246  }
247 
248  // See if the current unit can reach that position.
249  if (tiles[j] != current_unit) {
250  typedef std::multimap<map_location,map_location>::const_iterator Itor;
251  std::pair<Itor,Itor> its = dstsrc.equal_range(tiles[j]);
252  while(its.first != its.second) {
253  if(its.first->second == current_unit)
254  break;
255  ++its.first;
256  }
257 
258  // If the unit can't move to this location.
259  if(its.first == its.second || units_.find(tiles[j]) != units_.end()) {
260  continue;
261  }
262  }
263 
264  unit_ability_list abil = unit_itor->get_abilities("leadership",tiles[j]);
265  int best_leadership_bonus = abil.highest("value").first;
266  double leadership_bonus = static_cast<double>(best_leadership_bonus+100)/100.0;
267  if (leadership_bonus > 1.1) {
268  LOG_AI << unit_itor->name() << " is getting leadership " << leadership_bonus << "\n";
269  }
270 
271  // Check to see whether this move would be a backstab.
272  int backstab_bonus = 1;
273  double surround_bonus = 1.0;
274 
275  if(tiles[(j+3)%6] != current_unit) {
276  const unit_map::const_iterator itor = units_.find(tiles[(j+3)%6]);
277 
278  // Note that we *could* also check if a unit plans to move there
279  // before we're at this stage, but we don't because, since the
280  // attack calculations don't actually take backstab into account (too complicated),
281  // this could actually make our analysis look *worse* instead of better.
282  // So we only check for 'concrete' backstab opportunities.
283  // That would also break backstab_check, since it assumes
284  // the defender is in place.
285  if(itor != units_.end() &&
286  backstab_check(tiles[j], loc, units_, teams_)) {
287  if(backstab) {
288  backstab_bonus = 2;
289  }
290 
291  // No surround bonus if target is skirmisher
292  if (!itor->get_ability_bool("skirmisher"))
293  surround_bonus = 1.2;
294  }
295 
296 
297  }
298 
299  // See if this position is the best rated we've seen so far.
300  int rating = static_cast<int>(rate_terrain(*unit_itor, tiles[j]) * backstab_bonus * leadership_bonus);
301  if(cur_position >= 0 && rating < best_rating) {
302  continue;
303  }
304 
305  // Find out how vulnerable we are to attack from enemy units in this hex.
306  //FIXME: suokko's r29531 multiplied this by a constant 1.5. ?
307  const double vulnerability = power_projection(tiles[j],enemy_dstsrc);//?
308 
309  // Calculate how much support we have on this hex from allies.
310  const double support = power_projection(tiles[j], fullmove_dstsrc);//?
311 
312  // If this is a position with equal defense to another position,
313  // but more vulnerability then we don't want to use it.
314 #ifdef SUOKKO
315  //FIXME: this code was in sukko's r29531 Correct?
316  // scale vulnerability to 60 hp unit
317  if(cur_position >= 0 && rating < best_rating
318  && (vulnerability/surround_bonus*30.0)/unit_itor->second.hitpoints() -
319  (support*surround_bonus*30.0)/unit_itor->second.max_hitpoints()
320  > best_vulnerability - best_support) {
321  continue;
322  }
323 #else
324  if(cur_position >= 0 && rating == best_rating && vulnerability/surround_bonus - support*surround_bonus >= best_vulnerability - best_support) {
325  continue;
326  }
327 #endif
328  cur_position = j;
329  best_rating = rating;
330 #ifdef SUOKKO
331  //FIXME: this code was in sukko's r29531 Correct?
332  best_vulnerability = (vulnerability/surround_bonus*30.0)/unit_itor->second.hitpoints();
333  best_support = (support*surround_bonus*30.0)/unit_itor->second.max_hitpoints();
334 #else
335  best_vulnerability = vulnerability/surround_bonus;
336  best_support = support*surround_bonus;
337 #endif
338  }
339 
340  if(cur_position != -1) {
341  units.erase(units.begin() + i);
342 
343  cur_analysis.movements.push_back(std::pair<map_location,map_location>(current_unit,tiles[cur_position]));
344 
345  cur_analysis.vulnerability += best_vulnerability;
346 
347  cur_analysis.support += best_support;
348 
349  cur_analysis.is_surrounded = is_surrounded;
350  cur_analysis.analyze(map_, units_, *this, dstsrc, srcdst, enemy_dstsrc, get_aggression());
351  result.push_back(cur_analysis);
352  used_locations[cur_position] = true;
353  do_attack_analysis(loc,srcdst,dstsrc,fullmove_srcdst,fullmove_dstsrc,enemy_srcdst,enemy_dstsrc,
354  tiles,used_locations,
355  units,result,cur_analysis, current_team);
356  used_locations[cur_position] = false;
357 
358 
359  cur_analysis.vulnerability -= best_vulnerability;
360  cur_analysis.support -= best_support;
361 
362  cur_analysis.movements.pop_back();
363 
364  units.insert(units.begin() + i, current_unit);
365  }
366  }
367 }
368 
370 {
371  const gamemap &map_ = resources::gameboard->map();
372  const t_translation::t_terrain terrain = map_.get_terrain(loc);
373  const int defense = u.defense_modifier(terrain);
374  int rating = 100 - defense;
375 
376  const int healing_value = 10;
377  const int friendly_village_value = 5;
378  const int neutral_village_value = 10;
379  const int enemy_village_value = 15;
380 
381  if(map_.gives_healing(terrain) && u.get_ability_bool("regenerate",loc) == false) {
382  rating += healing_value;
383  }
384 
385  if(map_.is_village(terrain)) {
386  int owner = resources::gameboard->village_owner(loc) + 1;
387 
388  if(owner == u.side()) {
389  rating += friendly_village_value;
390  } else if(owner == 0) {
391  rating += neutral_village_value;
392  } else {
393  rating += enemy_village_value;
394  }
395  }
396 
397  return rating;
398 }
399 
400 
402 {
404  if (filter_own_ && !filter_own_->empty()) {
405  cfg.add_child("filter_own", filter_own_->to_config());
406  }
407  if (filter_enemy_ && !filter_enemy_->empty()) {
408  cfg.add_child("filter_enemy", filter_enemy_->to_config());
409  }
410  return cfg;
411 }
412 
414 {
415  if (filter_own_) {
416  return (*filter_own_)(u);
417  }
418  return true;
419 }
420 
422 {
423  if (filter_enemy_) {
424  return (*filter_enemy_)(u);
425  }
426  return true;
427 }
428 
429 } // end of namespace testing_ai_default
430 
432  : aspect_attacks_base(context, cfg, id)
433  , handler_(), code_(), params_(cfg.child_or_empty("args"))
434 {
435  this->name_ = "lua_aspect";
436  if (cfg.has_attribute("code"))
437  {
438  code_ = cfg["code"].str();
439  }
440  else if (cfg.has_attribute("value"))
441  {
442  code_ = "return " + cfg["value"].apply_visitor(lua_aspect_visitor());
443  }
444  else
445  {
446  // error
447  return;
448  }
450 }
451 
453 {
455  handler_->handle(params_, true, obj_);
456  aspect_attacks_lua_filter filt = *obj_->get();
457  aspect_attacks_base::recalculate();
458  if(filt.lua) {
459  if(filt.ref_own_ != -1) {
461  }
462  if(filt.ref_enemy_ != -1) {
464  }
465  }
466  obj_.reset();
467 }
468 
470 {
471  config cfg = aspect::to_config();
472  cfg["code"] = code_;
473  if (!params_.empty()) {
474  cfg.add_child("args", params_);
475  }
476  return cfg;
477 }
478 
479 static bool call_lua_filter_fcn(lua_State* L, const unit& u, int idx)
480 {
482  new(lua_newuserdata(L, sizeof(lua_unit))) lua_unit(u.underlying_id());
485  lua_setmetatable(L, -2);
486  luaW_pcall(L, 1, 1);
487  bool result = luaW_toboolean(L, -1);
488  lua_pop(L, 1);
489  return result;
490 }
491 
493 {
494  const aspect_attacks_lua_filter& filt = *obj_->get();
495  if(filt.lua && filt.ref_own_ != -1) {
496  return call_lua_filter_fcn(filt.lua, u, filt.ref_own_);
497  } else if(filt.filter_own_) {
498  return (*filt.filter_own_)(u);
499  } else {
500  return true;
501  }
502 }
503 
505 {
506  const aspect_attacks_lua_filter& filt = *obj_->get();
507  if(filt.lua && filt.ref_enemy_ != -1) {
508  return call_lua_filter_fcn(filt.lua, u, filt.ref_enemy_);
509  } else if(filt.filter_enemy_) {
510  return (*filt.filter_enemy_)(u);
511  } else {
512  return true;
513  }
514 }
515 
516 } // end of namespace ai
virtual side_number get_side() const
Get the side number.
Definition: contexts.hpp:480
boost::shared_ptr< unit_filter > filter_own_
LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
Definition: lapi.cpp:643
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
Definition: lapi.cpp:579
virtual config to_config() const
Definition: aspect.cpp:117
unit_iterator end()
Definition: map.hpp:311
boost::shared_ptr< attacks_vector > analyze_targets() const
aspect_attacks_lua(readonly_context &context, const config &cfg, const std::string &id, boost::shared_ptr< lua_ai_context > &l_ctx)
static bool call_lua_filter_fcn(lua_State *L, const unit &u, int idx)
bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error)
Calls a Lua function stored below its nArgs arguments at the top of the stack.
Definition: lua_api.cpp:59
Definition: unit.hpp:95
size_t underlying_id() const
The unique internal ID of the unit.
Definition: unit.hpp:150
boost::shared_ptr< attacks_vector > value_
Definition: aspect.hpp:189
Various functions that implement attacks and attack calculations.
variant map_
Definition: formula.cpp:306
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.hpp:274
bool is_village(const map_location &loc) const
Definition: map.cpp:68
std::map< map_location, pathfind::paths > moves_map
The standard way in which a map of possible movement routes to location is recorded.
Definition: game_info.hpp:50
bool is_enemy(int n) const
Definition: team.hpp:247
boost::shared_ptr< lua_object< aspect_attacks_lua_filter > > obj_
map_location target
Definition: contexts.hpp:97
double vulnerability
The vulnerability is the power projection of enemy units onto the hex we're standing on...
Definition: contexts.hpp:134
unit_iterator begin()
Definition: map.hpp:308
boost::shared_ptr< lua_ai_action_handler > handler_
virtual unit_stats_cache_t & unit_stats_cache() const
Definition: contexts.hpp:995
int village_owner(const map_location &loc) const
Given the location of a village, will return the 0-based index of the team that currently owns it...
std::pair< int, map_location > highest(const std::string &key, int def=0) const
Definition: abilities.cpp:426
int side() const
Definition: unit.hpp:201
aspect_attacks_base(readonly_context &context, const config &cfg, const std::string &id)
luatypekey const getunitKey
Definition: lua_types.cpp:28
virtual config to_config() const
bool get_ability_bool(const std::string &tag_name, const map_location &loc) const
Returns true if the unit is currently under effect by an ability with this given TAG NAME...
Definition: abilities.cpp:129
-file sdl_utils.hpp
bool empty() const
Definition: config.cpp:1105
boost::shared_ptr< unit_filter > filter_enemy_
#define LOG_AI
LUA_API void * lua_newuserdata(lua_State *L, size_t size)
Definition: lapi.cpp:1169
int defense_modifier(const t_translation::t_terrain &terrain) const
Definition: unit.cpp:1520
#define lua_pop(L, n)
Definition: lua.h:322
virtual config to_config() const
virtual double power_projection(const map_location &loc, const move_map &dstsrc) const
Function which finds how much 'power' a side can attack a certain location with.
Definition: contexts.hpp:806
std::vector< attack_analysis > attacks_vector
Definition: game_info.hpp:56
std::multimap< map_location, map_location > move_map
The standard way in which a map of possible moves is recorded.
Definition: game_info.hpp:47
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:57
std::string name_
Definition: aspect.hpp:110
virtual double get_aggression() const
Definition: contexts.hpp:641
boost::shared_ptr< unit_filter > filter_own_
static lg::log_domain log_ai_testing_aspect_attacks("ai/aspect/attacks")
void analyze(const gamemap &map, unit_map &units, const readonly_context &ai_obj, const move_map &dstsrc, const move_map &srcdst, const move_map &enemy_dstsrc, double aggression)
Definition: attack.cpp:40
GLuint64EXT * result
Definition: glew.h:10727
std::vector< team > * teams
Definition: resources.cpp:29
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:811
void do_attack_analysis(const map_location &loc, const move_map &srcdst, const move_map &dstsrc, const move_map &fullmove_srcdst, const move_map &fullmove_dstsrc, const move_map &enemy_srcdst, const move_map &enemy_dstsrc, const map_location *tiles, bool *used_locations, std::vector< map_location > &units, std::vector< attack_analysis > &result, attack_analysis &cur_analysis, const team &current_team) const
filter_context * filter_con
Definition: resources.cpp:23
virtual bool is_allowed_enemy(const unit &u) const
game_board * gameboard
Definition: resources.cpp:20
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
boost::shared_ptr< unit_filter > filter_enemy_
Encapsulates the map of the game.
Definition: map.hpp:37
aspect_attacks(readonly_context &context, const config &cfg, const std::string &id)
config & add_child(const std::string &key)
Definition: config.cpp:743
LUA_API int lua_setmetatable(lua_State *L, int objindex)
Definition: lapi.cpp:806
Managing the AIs lifecycle - headers.
virtual const move_map & get_srcdst() const
Definition: contexts.hpp:854
virtual void calculate_possible_moves(std::map< map_location, pathfind::paths > &possible_moves, move_map &srcdst, move_map &dstsrc, bool enemy, bool assume_full_movement=false, const terrain_filter *remove_destinations=nullptr) const
Definition: contexts.hpp:588
static const ::config * terrain
The terrain used to create the cache.
Definition: minimap.cpp:135
virtual const move_map & get_enemy_dstsrc() const
Definition: contexts.hpp:709
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
virtual const move_map & get_enemy_srcdst() const
Definition: contexts.hpp:721
Encapsulates the map of the game.
Definition: location.hpp:38
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr != 0)...
Definition: lua_api.hpp:62
GLuint res
Definition: glew.h:9258
static void raise_user_interact()
Notifies all observers of 'ai_user_interact' event.
Definition: manager.cpp:431
bool backstab_check(const map_location &attacker_loc, const map_location &defender_loc, const unit_map &units, const std::vector< team > &teams)
Function to check if an attack will satisfy the requirements for backstab.
Definition: attack.cpp:1684
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
virtual bool is_allowed_attacker(const unit &u) const =0
virtual bool is_allowed_attacker(const unit &u) const
virtual bool get_passive_leader() const
Definition: contexts.hpp:788
std::vector< std::pair< map_location, map_location > > movements
Definition: contexts.hpp:98
size_t i
Definition: function.cpp:1057
ai::lua_ai_action_handler * create_lua_ai_action_handler(char const *code, ai::lua_ai_context &context)
boost::shared_ptr< std::vector< unit_const_ptr > > units_
Definition: dialogs.cpp:100
Aspect: attacks.
virtual const team & current_team() const
Definition: contexts.hpp:539
bool valid_
Definition: aspect.hpp:100
virtual const gamemap & map() const
Definition: game_board.hpp:98
t_translation::t_terrain get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:341
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:467
#define LUA_REGISTRYINDEX
Definition: lua.h:39
bool has_attribute(const std::string &key) const
Definition: config.cpp:514
virtual bool is_allowed_enemy(const unit &u) const =0
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
A variable-expanding proxy for the config class.
Definition: variable.hpp:36
Standard logging facilities (interface).
game_lua_kernel * lua_kernel
Definition: resources.cpp:25
Container associating units to locations.
Definition: map.hpp:90
LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
Definition: lauxlib.cpp:545
bool is_surrounded
Is true if the units involved in this attack sequence are surrounded.
Definition: contexts.hpp:143
virtual bool is_allowed_attacker(const unit &u) const
virtual void recalculate() const
unit_iterator find(size_t id)
Definition: map.cpp:285
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
virtual bool is_allowed_enemy(const unit &u) const
void make_safe() const
instruct the vconfig to make a private copy of its underlying data.
Definition: variable.cpp:119
static int rate_terrain(const unit &u, const map_location &loc)
This module contains various pathfinding functions and utilities.
LUA_API void lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:633
GLsizei const GLcharARB ** string
Definition: glew.h:4503
unit_map * units
Definition: resources.cpp:35
virtual const move_map & get_dstsrc() const
Definition: contexts.hpp:703
int gives_healing(const map_location &loc) const
Definition: map.cpp:70