The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
core.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 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  * @file
17  * Provides core classes for the Lua AI.
18  *
19  */
20 
21 #include <cassert>
22 #include <cstring>
23 
24 #include "ai/lua/core.hpp"
25 #include "ai/composite/aspect.hpp"
27 #include "scripting/lua_api.hpp"
28 #include "scripting/push_check.hpp"
29 #include "lua_object.hpp" // (Nephro)
30 
31 #include "attack_prediction.hpp"
32 #include "game_display.hpp"
33 #include "log.hpp"
34 #include "map/map.hpp"
35 #include "pathfind/pathfind.hpp"
36 #include "play_controller.hpp"
37 #include "resources.hpp"
38 #include "terrain/translation.hpp"
39 #include "terrain/filter.hpp"
40 #include "units/unit.hpp"
41 #include "ai/actions.hpp"
42 #include "ai/lua/engine_lua.hpp"
44 
45 #include "lua/lualib.h"
46 #include "lua/lauxlib.h"
47 #include "lua/llimits.h"
48 
49 static lg::log_domain log_ai_engine_lua("ai/engine/lua");
50 #define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
51 #define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
52 
53 static char const aisKey = 0;
54 
55 namespace ai {
56 
57 static void push_attack_analysis(lua_State *L, const attack_analysis&);
58 
60 {
61  // Create the ai elements table.
62  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
63  lua_newtable(L);
65 }
66 
68 {
69  int top = lua_gettop(L);
70 
71  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
73  lua_rawgeti(L, -1, num_);
74 
75  lua_getfield(L, -1, "params");
76  luaW_toconfig(L, -1, cfg);
77 
78  lua_settop(L, top);
79 }
80 
82 {
83  int top = lua_gettop(L);
84 
85  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
87  lua_rawgeti(L, -1, num_);
88 
89  luaW_pushconfig(L, cfg);
90  lua_setfield(L, -2, "params");
91 
92  lua_settop(L, top);
93 }
94 
96 {
97  int top = lua_gettop(L);
98 
99  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
101  lua_rawgeti(L, -1, num_);
102 
103  lua_getfield(L, -1, "data");
104  luaW_toconfig(L, -1, cfg);
105 
106  lua_settop(L, top);
107 }
108 
110 {
111  int top = lua_gettop(L);
112 
113  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
115  lua_rawgeti(L, -1, num_);
116 
117  luaW_pushconfig(L, cfg);
118  lua_setfield(L, -2, "data");
119 
120  lua_settop(L, top);
121 }
122 
124 {
125  return *(static_cast<ai::engine_lua*>(
127 }
128 
130 {
131  return get_engine(L).get_readonly_context();
132 }
133 
135 {
136  lua_ai_load ctx(*this, false);
137 }
138 
139 static void push_location_key(lua_State* L, const map_location& loc)
140 {
141  // This should be factored out. The same function is defined in data/lua/location_set.lua
142  // At this point, it is not clear, where this(hashing) function can be placed
143  // Implemented it this way, to test the new version of the data structure
144  // as requested from the users of LuaAI <Nephro>
145  int hashed_index = (loc.x + 1) * 16384 + (loc.y + 1) + 2000;
146  lua_pushinteger(L, hashed_index);
147 }
148 
150 {
151  lua_newtable(L);
152  lua_pushboolean(L,action_result->is_ok());
153  lua_setfield(L, -2, "ok");
154  lua_pushboolean(L,action_result->is_gamestate_changed());
155  lua_setfield(L, -2, "gamestate_changed");
156  lua_pushinteger(L,action_result->get_status());
157  lua_setfield(L, -2, "status");
158  lua_pushstring(L, actions::get_error_name(action_result->get_status()).c_str());
159  lua_setfield(L, -2, "result");
160  return 1;
161 }
162 
164 {
165  int index = 1;
166 
168  unit* leader = nullptr;
169  if (lua_isuserdata(L, index))
170  {
171  leader = luaW_tounit(L, index);
172  if (!leader) return luaL_argerror(L, 1, "unknown unit");
173  }
174  else return luaL_typerror(L, 1, "unit");
175  const map_location loc = leader->get_location();
176  const pathfind::paths leader_paths(*leader, false, true, context.current_team());
177  const map_location &res = context.suitable_keep(loc,leader_paths);
178  if (!res.valid()) {
179  return 0;
180  }
181  else {
182  lua_pushnumber(L, res.x+1);
183  lua_pushnumber(L, res.y+1);
184  return 2;
185  }
186 }
187 
188 static int ai_move(lua_State *L, bool exec, bool remove_movement)
189 {
190  int side = get_readonly_context(L).get_side();
191  map_location from = luaW_checklocation(L, 1);
192  map_location to = luaW_checklocation(L, 2);
193  bool unreach_is_ok = false;
194  if (lua_isboolean(L, 3)) {
195  unreach_is_ok = luaW_toboolean(L, 3);
196  }
197  ai::move_result_ptr move_result = ai::actions::execute_move_action(side,exec,from,to,remove_movement, unreach_is_ok);
198  return transform_ai_action(L,move_result);
199 }
200 
202 {
203  return ai_move(L, true, true);
204 }
205 
207 {
208  return ai_move(L, true, false);
209 }
210 
212 {
213  return ai_move(L, false, false);
214 }
215 
216 static int ai_attack(lua_State *L, bool exec)
217 {
219 
220  int side = context.get_side();
221  map_location attacker = luaW_checklocation(L, 1);
222  map_location defender = luaW_checklocation(L, 2);
223 
224  int attacker_weapon = -1;//-1 means 'select what is best'
225  double aggression = context.get_aggression();//use the aggression from the context
226 
227  if (!lua_isnoneornil(L, 3)) {
228  attacker_weapon = lua_tointeger(L, 3);
229  if (attacker_weapon != -1) {
230  attacker_weapon--; // Done for consistency of the Lua style
231  }
232  }
233 
234  //TODO: Right now, aggression is used by the attack execution functions to determine the weapon to be used.
235  // If a decision is made to expand the function that determines the weapon, this block must be refactored
236  // to parse aggression if a single int is on the stack, or create a table of parameters, if a table is on the
237  // stack.
238  if (!lua_isnoneornil(L, 4) && lua_isnumber(L,4)) {
239  aggression = lua_tonumber(L, 4);
240  }
241 
242  unit_advancements_aspect advancements = context.get_advancements();
243  ai::attack_result_ptr attack_result = ai::actions::execute_attack_action(side,exec,attacker,defender,attacker_weapon,aggression,advancements);
244  return transform_ai_action(L,attack_result);
245 }
246 
248 {
249  return ai_attack(L, true);
250 }
251 
253 {
254  return ai_attack(L, false);
255 }
256 
257 static int ai_stopunit_select(lua_State *L, bool exec, bool remove_movement, bool remove_attacks)
258 {
259  int side = get_readonly_context(L).get_side();
260  map_location loc = luaW_checklocation(L, 1);
261 
262  ai::stopunit_result_ptr stopunit_result = ai::actions::execute_stopunit_action(side,exec,loc,remove_movement,remove_attacks);
263  return transform_ai_action(L,stopunit_result);
264 }
265 
267 {
268  return ai_stopunit_select(L, true, true, false);
269 }
270 
272 {
273  return ai_stopunit_select(L, true, false, true);
274 }
275 
277 {
278  return ai_stopunit_select(L, true, true, true);
279 }
280 
282 {
283  return ai_stopunit_select(L, false, true, true);
284 }
285 
286 static int ai_synced_command(lua_State *L, bool exec)
287 {
288  const char *lua_code = luaL_checkstring(L, 1);
289  int side = get_readonly_context(L).get_side();
291  if (!lua_isnoneornil(L, 2)) {
292  location.x = lua_tonumber(L, 2);
293  location.y = lua_tonumber(L, 3);
294  }
295 
297  return transform_ai_action(L,synced_command_result);
298 }
299 
301 {
302  return ai_synced_command(L, true);
303 }
304 
306 {
307  return ai_synced_command(L, false);
308 }
309 
310 static int ai_recruit(lua_State *L, bool exec)
311 {
312  const char *unit_name = luaL_checkstring(L, 1);
313  int side = get_readonly_context(L).get_side();
314  map_location where;
315  if (!lua_isnoneornil(L, 2)) {
316  where.x = lua_tonumber(L, 2) - 1;
317  where.y = lua_tonumber(L, 3) - 1;
318  }
319  //TODO fendrin: talk to Crab about the from argument.
322  return transform_ai_action(L,recruit_result);
323 }
324 
326 {
327  return ai_recruit(L, true);
328 }
329 
331 {
332  return ai_recruit(L, false);
333 }
334 
335 static int ai_recall(lua_State *L, bool exec)
336 {
337  const char *unit_id = luaL_checkstring(L, 1);
338  int side = get_readonly_context(L).get_side();
339  map_location where;
340  if (!lua_isnoneornil(L, 2)) {
341  where.x = lua_tonumber(L, 2) - 1;
342  where.y = lua_tonumber(L, 3) - 1;
343  }
344  //TODO fendrin: talk to Crab about the from argument.
347  return transform_ai_action(L,recall_result);
348 }
349 
351 {
352  return ai_recall(L, true);
353 }
354 
356 {
357  return ai_recall(L, false);
358 }
359 
360 // Goals and targets
361 
362 
364 {
365  move_map enemy_dst_src = get_readonly_context(L).get_enemy_dstsrc();
366  std::vector<target> targets = get_engine(L).get_ai_context()->find_targets(enemy_dst_src);
367  int i = 1;
368 
369  lua_createtable(L, 0, 0);
370  for (std::vector<target>::iterator it = targets.begin(); it != targets.end(); ++it)
371  {
372  lua_pushinteger(L, i);
373 
374  //to factor out
375  lua_createtable(L, 3, 0);
376 
377 
378  lua_pushstring(L, "type");
379  lua_pushstring(L, it->type.to_string().c_str());
380  lua_rawset(L, -3);
381 
382  lua_pushstring(L, "loc");
383  luaW_pushlocation(L, it->loc);
384  lua_rawset(L, -3);
385 
386  lua_pushstring(L, "value");
387  lua_pushnumber(L, it->value);
388  lua_rawset(L, -3);
389 
390  lua_rawset(L, -3);
391  ++i;
392  }
393  return 1;
394 }
395 
396 // Aspect section
398 {
399  double aggression = get_readonly_context(L).get_aggression();
400  lua_pushnumber(L, aggression);
401  return 1;
402 }
403 
405 {
406  int attack_depth = get_readonly_context(L).get_attack_depth();
407  lua_pushnumber(L, attack_depth);
408  return 1;
409 }
410 
412 {
414  lua_createtable(L, attacks.size(), 0);
415  int table_index = lua_gettop(L);
416 
417  ai::attacks_vector::const_iterator it = attacks.begin();
418  for (int i = 1; it != attacks.end(); ++it, ++i)
419  {
420  push_attack_analysis(L, *it);
421 
422  lua_rawseti(L, table_index, i);
423  }
424  return 1;
425 }
426 
428 {
429  std::set<map_location> locs;
431  avoid.get_locations(locs);
432  lua_push(L, locs);
433 
434  return 1;
435 }
436 
438 {
439  double caution = get_readonly_context(L).get_caution();
440  lua_pushnumber(L, caution);
441  return 1;
442 }
443 
445 {
447  lua_pushstring(L, grouping.c_str());
448  return 1;
449 }
450 
452 {
453  double leader_aggression = get_readonly_context(L).get_leader_aggression();
454  lua_pushnumber(L, leader_aggression);
455  return 1;
456 }
457 
459 {
461  luaW_pushconfig(L, goal);
462  return 1;
463 }
464 
466 {
467  bool leader_ignores_keep = get_readonly_context(L).get_leader_ignores_keep();
468  lua_pushboolean(L, leader_ignores_keep);
469  return 1;
470 }
471 
473 {
474  double leader_value = get_readonly_context(L).get_leader_value();
475  lua_pushnumber(L, leader_value);
476  return 1;
477 }
478 
480 {
481  bool passive_leader = get_readonly_context(L).get_passive_leader();
482  lua_pushboolean(L, passive_leader);
483  return 1;
484 }
485 
487 {
488  bool passive_leader_shares_keep = get_readonly_context(L).get_passive_leader_shares_keep();
489  lua_pushboolean(L, passive_leader_shares_keep);
490  return 1;
491 }
492 
494 {
495  std::vector<std::string> recruiting = get_readonly_context(L).get_recruitment_pattern();
496  int size = recruiting.size();
497  lua_createtable(L, size, 0); // create an exmpty table with predefined size
498  for (int i = 0; i < size; ++i)
499  {
500  lua_pushinteger(L, i + 1); // Indexing in Lua starts from 1
501  lua_pushstring(L, recruiting[i].c_str());
502  lua_settable(L, -3);
503  }
504  return 1;
505 }
506 
508 {
509  double scout_village_targeting = get_readonly_context(L).get_scout_village_targeting();
510  lua_pushnumber(L, scout_village_targeting);
511  return 1;
512 }
513 
515 {
516  bool simple_targeting = get_readonly_context(L).get_simple_targeting();
517  lua_pushboolean(L, simple_targeting);
518  return 1;
519 }
520 
522 {
523  bool support_villages = get_readonly_context(L).get_support_villages();
524  lua_pushboolean(L, support_villages);
525  return 1;
526 }
527 
529 {
530  double village_value = get_readonly_context(L).get_village_value();
531  lua_pushnumber(L, village_value);
532  return 1;
533 }
534 
536 {
537  int villages_per_scout = get_readonly_context(L).get_villages_per_scout();
538  lua_pushnumber(L, villages_per_scout);
539  return 1;
540 }
541 // End of aspect section
542 
544 {
545  int top = lua_gettop(L);
546  // the attack_analysis table should be on top of the stack
547  lua_getfield(L, -1, "att_ptr"); // [-2: attack_analysis; -1: pointer to attack_analysis object in c++]
548  // now the pointer to our attack_analysis C++ object is on top
549  const attack_analysis* aa_ptr = static_cast< attack_analysis * >(lua_touserdata(L, -1));
550 
551  //[-2: attack_analysis; -1: pointer to attack_analysis object in c++]
552 
553  double aggression = get_readonly_context(L).get_aggression();
554 
555  double rating = aa_ptr->rating(aggression, get_readonly_context(L));
556 
557  lua_settop(L, top);
558 
559  lua_pushnumber(L, rating);
560  return 1;
561 }
562 
563 static void push_movements(lua_State *L, const std::vector< std::pair < map_location, map_location > > & moves)
564 {
565  lua_createtable(L, moves.size(), 0);
566 
567  int table_index = lua_gettop(L);
568 
569  std::vector< std::pair < map_location, map_location > >::const_iterator move = moves.begin();
570 
571  for (int i = 1; move != moves.end(); ++move, ++i)
572  {
573  lua_createtable(L, 2, 0); // Creating a table for a pair of map_location's
574 
575  lua_pushstring(L, "src");
576  luaW_pushlocation(L, move->first);
577  lua_rawset(L, -3);
578 
579  lua_pushstring(L, "dst");
580  luaW_pushlocation(L, move->second);
581  lua_rawset(L, -3);
582 
583  lua_rawseti(L, table_index, i); // setting the pair as an element of the movements table
584  }
585 
586 
587 }
588 
590 {
591  lua_newtable(L);
592 
593  // Pushing a pointer to the current object
594  lua_pushstring(L, "att_ptr");
595  lua_pushlightuserdata(L, const_cast<attack_analysis*>(&aa));
596  lua_rawset(L, -3);
597 
598  // Registering callback function for the rating method
599  lua_pushstring(L, "rating");
602  lua_rawset(L, -3);
603 
604  lua_pushstring(L, "movements");
605  push_movements(L, aa.movements);
606  lua_rawset(L, -3);
607 
608  lua_pushstring(L, "target");
609  luaW_pushlocation(L, aa.target);
610  lua_rawset(L, -3);
611 
612  lua_pushstring(L, "target_value");
614  lua_rawset(L, -3);
615 
616  lua_pushstring(L, "avg_losses");
617  lua_pushnumber(L, aa.avg_losses);
618  lua_rawset(L, -3);
619 
620  lua_pushstring(L, "chance_to_kill");
622  lua_rawset(L, -3);
623 
624  lua_pushstring(L, "avg_damage_inflicted");
626  lua_rawset(L, -3);
627 
628  lua_pushstring(L, "target_starting_damage");
630  lua_rawset(L, -3);
631 
632  lua_pushstring(L, "avg_damage_taken");
634  lua_rawset(L, -3);
635 
636  lua_pushstring(L, "resources_used");
638  lua_rawset(L, -3);
639 
640  lua_pushstring(L, "terrain_quality");
642  lua_rawset(L, -3);
643 
644  lua_pushstring(L, "alternative_terrain_quality");
646  lua_rawset(L, -3);
647 
648  lua_pushstring(L, "vulnerability");
650  lua_rawset(L, -3);
651 
652  lua_pushstring(L, "support");
653  lua_pushnumber(L, aa.support);
654  lua_rawset(L, -3);
655 
656  lua_pushstring(L, "leader_threat");
658  lua_rawset(L, -3);
659 
660  lua_pushstring(L, "uses_leader");
662  lua_rawset(L, -3);
663 
664  lua_pushstring(L, "is_surrounded");
666  lua_rawset(L, -3);
667 }
668 
669 static void push_move_map(lua_State *L, const move_map& m)
670 {
671  lua_createtable(L, 0, 0); // the main table
672 
673  if (m.empty())
674  {
675  return;
676  }
677 
678  move_map::const_iterator it = m.begin();
679 
680  int index = 1;
681 
682 
683 
684  do
685  {
686  map_location key = it->first;
687  push_location_key(L, key);
688 
689  lua_createtable(L, 0, 0);
690 
691  while (key == it->first) {
692 
693  luaW_pushlocation(L, it->second);
694  lua_rawseti(L, -2, index);
695 
696  ++index;
697  ++it;
698 
699  }
700 
701  lua_settable(L, -3);
702 
703  index = 1;
704 
705  } while (it != m.end());
706 }
707 
709 {
712  push_move_map(L, dst_src);
713  return 1;
714 }
715 
717 {
720  push_move_map(L, src_dst);
721  return 1;
722 }
723 
725 {
726  move_map enemy_dst_src = get_readonly_context(L).get_enemy_dstsrc();
728  push_move_map(L, enemy_dst_src);
729  return 1;
730 }
731 
733 {
734  move_map enemy_src_dst = get_readonly_context(L).get_enemy_srcdst();
736  push_move_map(L, enemy_src_dst);
737  return 1;
738 }
739 
741 {
743  lua_pushboolean(L, valid);
744  return 1;
745 }
746 
748 {
750  lua_pushboolean(L, valid);
751  return 1;
752 }
753 
755 {
757  lua_pushboolean(L, valid);
758  return 1;
759 }
760 
762 {
764  lua_pushboolean(L, valid);
765  return 1;
766 }
767 
769 {
771  return 1;
772 }
773 
775 {
777  return 1;
778 }
779 
780 template<typename T>
782 {
783  return boost::dynamic_pointer_cast<typesafe_aspect<T> >(p).get();
784 }
785 
787 {
788  const aspect_map& aspects = get_engine(L).get_readonly_context().get_aspects();
789  aspect_map::const_iterator iter = aspects.find(luaL_checkstring(L, 2));
790  if(iter == aspects.end()) {
791  return 0;
792  }
793 
794  // For attacks, just fall back to existing function
795  if(iter->first == "attacks") {
798  lua_call(L, 0, 1);
799  return 1;
800  }
801 
802  typedef std::vector<std::string> string_list;
803  if(typesafe_aspect<bool>* aspect = try_aspect_as<bool>(iter->second)) {
804  lua_pushboolean(L, aspect->get());
805  } else if(typesafe_aspect<int>* aspect = try_aspect_as<int>(iter->second)) {
806  lua_pushinteger(L, aspect->get());
807  } else if(typesafe_aspect<double>* aspect = try_aspect_as<double>(iter->second)) {
808  lua_pushnumber(L, aspect->get());
809  } else if(typesafe_aspect<config>* aspect = try_aspect_as<config>(iter->second)) {
810  luaW_pushconfig(L, aspect->get());
811  } else if(typesafe_aspect<string_list>* aspect = try_aspect_as<string_list>(iter->second)) {
812  lua_push(L, aspect->get());
813  } else if(typesafe_aspect<terrain_filter>* aspect = try_aspect_as<terrain_filter>(iter->second)) {
814  std::set<map_location> result;
815  aspect->get().get_locations(result);
816  lua_push(L, result);
817  } else if(typesafe_aspect<attacks_vector>* aspect = try_aspect_as<attacks_vector>(iter->second)) {
818  // This case is caught separately above, but should the get_* aspect functions ever be
819  // deprecated, this is the place to move the code of cfun_ai_get_attacks to.
820  (void) aspect;
821  } else if(typesafe_aspect<unit_advancements_aspect>* aspect = try_aspect_as<unit_advancements_aspect>(iter->second)) {
822  const unit_advancements_aspect& val = aspect->get();
823  int my_side = luaW_getglobal(L, "ai", "side") - 1;
824  lua_newtable(L);
825  for (unit_map::const_iterator u = resources::units->begin(); u != resources::units->end(); ++u) {
826  if (!u.valid() || u->side() != my_side) {
827  continue;
828  }
829  push_location_key(L, u->get_location());
830  lua_push(L, val.get_advancements(u));
831  lua_settable(L, -3);
832  }
833  } else {
834  lua_pushnil(L);
835  }
836  return 1;
837 }
838 
840 {
841  lua_pushstring(L, "attempted to write to the ai.aspects table, which is read-only");
842  return lua_error(L);
843 }
844 
845 static int impl_ai_get(lua_State* L)
846 {
847  if(!lua_isstring(L,2)) {
848  return 0;
849  }
851  std::string m = lua_tostring(L,2);
852  if(m == "side") {
854  return 1;
855  }
856  if(m == "aspects") {
857  lua_newtable(L); // [-1: Aspects table]
858  lua_newtable(L); // [-1: Aspects metatable -2: Aspects table]
859  lua_pushlightuserdata(L, &engine); // [-1: Engine -2: Aspects mt -3: Aspects table]
860  lua_pushcclosure(L, &impl_ai_aspect_get, 1); // [-1: Metafunction -2: Aspects mt -3: Aspects table]
861  lua_setfield(L, -2, "__index"); // [-1: Aspects metatable -2: Aspects table]
862  lua_pushcfunction(L, &impl_ai_aspect_set); // [-1: Metafunction -2: Aspects mt -3: Aspects table]
863  lua_setfield(L, -2, "__newindex"); // [-1: Aspects metatable -2: Aspects table]
864  lua_setmetatable(L, -2); // [-1: Aspects table]
865  return 1;
866  }
867  static luaL_Reg const callbacks[] = {
868  // Move maps
869  { "get_new_dst_src", &cfun_ai_get_dstsrc },
870  { "get_new_src_dst", &cfun_ai_get_srcdst },
871  { "get_new_enemy_dst_src", &cfun_ai_get_enemy_dstsrc },
872  { "get_new_enemy_src_dst", &cfun_ai_get_enemy_srcdst },
873  { "recalculate_move_maps", &cfun_ai_recalculate_move_maps },
874  { "recalculate_enemy_move_maps", &cfun_ai_recalculate_move_maps_enemy },
875  // End of move maps
876  // Goals and targets
877  { "get_targets", &cfun_ai_get_targets },
878  // End of G & T
879  // Aspects
880  { "get_aggression", &cfun_ai_get_aggression },
881  { "get_avoid", &cfun_ai_get_avoid },
882  { "get_attack_depth", &cfun_ai_get_attack_depth },
883  { "get_attacks", &cfun_ai_get_attacks },
884  { "get_caution", &cfun_ai_get_caution },
885  { "get_grouping", &cfun_ai_get_grouping },
886  { "get_leader_aggression", &cfun_ai_get_leader_aggression },
887  { "get_leader_goal", &cfun_ai_get_leader_goal },
888  { "get_leader_ignores_keep", &cfun_ai_get_leader_ignores_keep },
889  { "get_leader_value", &cfun_ai_get_leader_value },
890  { "get_passive_leader", &cfun_ai_get_passive_leader },
891  { "get_passive_leader_shares_keep", &cfun_ai_get_passive_leader_shares_keep },
892  { "get_recruitment_pattern", &cfun_ai_get_recruitment_pattern },
893  { "get_scout_village_targeting", &cfun_ai_get_scout_village_targeting },
894  { "get_simple_targeting", &cfun_ai_get_simple_targeting },
895  { "get_support_villages", &cfun_ai_get_support_villages },
896  { "get_village_value", &cfun_ai_get_village_value },
897  { "get_villages_per_scout", &cfun_ai_get_villages_per_scout },
898  // End of aspects
899  // Validation/cache functions
900  { "is_dst_src_valid", &cfun_ai_is_dst_src_valid },
901  { "is_enemy_dst_src_valid", &cfun_ai_is_dst_src_enemy_valid },
902  { "is_src_dst_valid", &cfun_ai_is_src_dst_valid },
903  { "is_enemy_src_dst_valid", &cfun_ai_is_src_dst_enemy_valid },
904  // End of validation functions
905  { "suitable_keep", &cfun_ai_get_suitable_keep },
906  { "check_recall", &cfun_ai_check_recall },
907  { "check_move", &cfun_ai_check_move },
908  { "check_stopunit", &cfun_ai_check_stopunit },
909  { "check_synced_command", &cfun_ai_check_synced_command },
910  { "check_attack", &cfun_ai_check_attack },
911  { "check_recruit", &cfun_ai_check_recruit },
912  //{ "",},
913  //{ "",},
914  { nullptr, nullptr } };
915  for (const luaL_Reg* p = callbacks; p->name; ++p) {
916  if(m == p->name) {
917  lua_pushlightuserdata(L, &engine); // [-1: engine ...]
918  lua_pushcclosure(L, p->func, 1); // [-1: function ...]
919  // Store the function so that __index doesn't need to be called next time
920  lua_pushstring(L, p->name); // [-1: name -2: function ...]
921  lua_pushvalue(L, -2); // [-1: function -2: name -3: function ...]
922  lua_rawset(L, 1); // [-1: function ...]
923  return 1;
924  }
925  }
926  lua_pushstring(L, "read_only");
927  lua_rawget(L, 1);
928  bool read_only = luaW_toboolean(L, -1);
929  lua_pop(L, 1);
930  if(read_only) {
931  return 0;
932  }
933  static luaL_Reg const mutating_callbacks[] = {
934  { "attack", &cfun_ai_execute_attack },
935  { "move", &cfun_ai_execute_move_partial },
936  { "move_full", &cfun_ai_execute_move_full },
937  { "recall", &cfun_ai_execute_recall },
938  { "recruit", &cfun_ai_execute_recruit },
939  { "stopunit_all", &cfun_ai_execute_stopunit_all },
940  { "stopunit_attacks", &cfun_ai_execute_stopunit_attacks },
941  { "stopunit_moves", &cfun_ai_execute_stopunit_moves },
942  { "synced_command", &cfun_ai_execute_synced_command },
943  { nullptr, nullptr } };
944  for (const luaL_Reg* p = mutating_callbacks; p->name; ++p) {
945  if(m == p->name) {
946  lua_pushlightuserdata(L, &engine);
947  lua_pushcclosure(L, p->func, 1);
948  return 1;
949  }
950  }
951  return 0;
952 }
953 
955  //push data table here
956  lua_newtable(L); // [-1: ai table]
957  lua_newtable(L); // [-1: metatable -2: ai table]
958  lua_pushlightuserdata(L, engine); // [-1: engine -2: metatable -3: ai table]
959  lua_pushcclosure(L, &impl_ai_get, 1); // [-1: metafunc -2: metatable -3: ai table]
960  lua_setfield(L, -2, "__index"); // [-1: metatable -2: ai table]
961  lua_setmetatable(L, -2); // [-1: ai table]
962 }
963 
965 {
966  // Retrieve the ai elements table from the registry.
967  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
968  lua_rawget(L, LUA_REGISTRYINDEX); // [-1: AIs registry table]
969  size_t length_ai = lua_rawlen(L, -1); // length of table
970  lua_newtable(L); // [-1: AI state table -2: AIs registry table]
971  generate_and_push_ai_table(L, engine); // [-1: AI routines -2: AI state -3: AIs registry]
972  lua_setfield(L, -2, "ai"); // [-1: AI state -2: AIs registry]
973  lua_pushvalue(L, -1); // [-1: AI state -2: AI state -3: AIs registry]
974  lua_rawseti(L, -3, length_ai + 1); // [-1: AI state -2: AIs registry]
975  lua_remove(L, -2); // [-1: AI state table]
976  return length_ai + 1;
977 }
978 
980 {
981  int res_ai = luaL_loadstring(L, code); // [-1: AI code]
982  if (res_ai != 0)
983  {
984 
985  char const *m = lua_tostring(L, -1);
986  ERR_LUA << "error while initializing ai: " <<m << '\n';
987  lua_pop(L, 2);//return with stack size 0 []
988  return nullptr;
989  }
990  //push data table here
991  size_t idx = generate_and_push_ai_state(L, engine); // [-1: AI state -2: AI code]
992  lua_pushvalue(L, -2); // [-1: AI code -2: AI state -3: AI code]
993  lua_setfield(L, -2, "update_self"); // [-1: AI state -2: AI code]
994  lua_pushlightuserdata(L, engine);
995  lua_setfield(L, -2, "engine"); // [-1: AI state -2: AI code]
996  lua_pop(L, 2);
997  return new lua_ai_context(L, idx, engine->get_readonly_context().get_side());
998 }
999 
1001 {
1002  lua_ai_load ctx(*this, true); // [-1: AI state table]
1003 
1004  // Load the AI code and arguments
1005  lua_getfield(L, -1, "update_self"); // [-1: AI code -2: AI state]
1006  lua_getfield(L, -2, "params"); // [-1: Arguments -2: AI code -3: AI state]
1007  lua_getfield(L, -3, "data"); // [-1: Persistent data -2: Arguments -3: AI code -4: AI state]
1008 
1009  // Call the function
1010  if (!luaW_pcall(L, 2, 1, true)) { // [-1: Result -2: AI state]
1011  lua_pop(L, 2); // (The result in this case is an error message.)
1012  return; // return with stack size 0 []
1013  }
1014 
1015  // Store the state for use by components
1016  lua_setfield(L, -2, "self"); // [-1: AI state]
1017 
1018  // And return with empty stack.
1019  lua_pop(L, 1);
1020 }
1021 
1023 {
1024  int res = luaL_loadstring(L, code);//stack size is now 1 [ -1: f]
1025  if (res)
1026  {
1027  char const *m = lua_tostring(L, -1);
1028  ERR_LUA << "error while creating ai function: " <<m << '\n';
1029  lua_pop(L, 2);//return with stack size 0 []
1030  return nullptr;
1031  }
1032 
1033  // Retrieve the ai elements table from the registry.
1034  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
1035  lua_rawget(L, LUA_REGISTRYINDEX); //stack size is now 2 [-1: ais_table -2: f]
1036  // Push the function in the table so that it is not collected.
1037  size_t length = lua_rawlen(L, -1);//length of ais_table
1038  lua_pushvalue(L, -2); //stack size is now 3: [-1: f -2: ais_table -3: f]
1039  lua_rawseti(L, -2, length + 1);// ais_table[length+1]=f. stack size is now 2 [-1: ais_table -2: f]
1040  lua_remove(L, -1);//stack size is now 1 [-1: f]
1041  lua_remove(L, -1);//stack size is now 0 []
1042  // Create the proxy C++ action handler.
1043  return new lua_ai_action_handler(L, context, length + 1);
1044 }
1045 
1046 
1047 int lua_ai_load::refcount = 0;
1048 
1049 lua_ai_load::lua_ai_load(lua_ai_context& ctx, bool read_only) : L(ctx.L), was_readonly(false)
1050 {
1051  refcount++;
1052  // Check if the AI table is already loaded. If so, we have less work to do.
1053  lua_getglobal(L, "ai");
1054  if(!lua_isnoneornil(L, -1)) {
1055  // Save the previous read-only state
1056  lua_getfield(L, -1, "read_only");
1057  was_readonly = luaW_toboolean(L, -1);
1058  lua_pop(L, 1);
1059  // Update the read-only state
1060  lua_pushstring(L, "read_only");
1061  lua_pushboolean(L, read_only);
1062  lua_rawset(L, -3);
1063  return; // Leave the AI table on the stack, as requested
1064  }
1065  lua_pop(L, 1); // Pop the nil value off the stack
1066  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey))); // [-1: key]
1067  lua_rawget(L, LUA_REGISTRYINDEX); // [-1: AI registry]
1068  lua_rawgeti(L, -1, ctx.num_); // [-1: AI state -2: AI registry]
1069  lua_remove(L,-2); // [-1: AI state]
1070 
1071  // Load the AI functions table into global scope
1072  lua_getfield(L, -1, "ai"); // [-1: AI functions -2: AI state]
1073  lua_pushstring(L, "read_only"); // [-1: key -2: AI functions -3: AI state]
1074  lua_pushboolean(L, read_only); // [-1: value -2: key -3: AI functions -4: AI state]
1075  lua_rawset(L, -3); // [-1: AI functions -2: AI state]
1076  lua_setglobal(L, "ai"); // [-1: AI state]
1077 }
1078 
1080 {
1081  refcount--;
1082  if (refcount == 0) {
1083  // Remove the AI functions from the global scope
1084  lua_pushnil(L);
1085  lua_setglobal(L, "ai");
1086  } else {
1087  // Restore the read-only state
1088  lua_getglobal(L, "ai");
1089  lua_pushstring(L, "read_only");
1091  lua_rawset(L, -3);
1092  lua_pop(L, 1);
1093  }
1094 }
1095 
1097 {
1098  // Remove the ai context from the registry, so that it can be collected.
1099  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
1101  lua_pushnil(L);
1102  lua_rawseti(L, -2, num_);
1103  lua_pop(L, 1);
1104 }
1105 
1106 void lua_ai_action_handler::handle(const config &cfg, bool read_only, lua_object_ptr l_obj)
1107 {
1108  int initial_top = lua_gettop(L);//get the old stack size
1109 
1110  // Load the context
1111  lua_ai_load ctx(context_, read_only); // [-1: AI state table]
1112 
1113  // Load the user function from the registry.
1114  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey))); // [-1: key -2: AI state]
1115  lua_rawget(L, LUA_REGISTRYINDEX); // [-1: AI registry -2: AI state]
1116  lua_rawgeti(L, -1, num_); // [-1: AI action -2: AI registry -3: AI state]
1117  lua_remove(L, -2); // [-1: AI action -2: AI state]
1118 
1119  // Load the arguments
1120  int iState = lua_absindex(L, -2);
1121  lua_getfield(L, iState, "self");
1122  luaW_pushconfig(L, cfg);
1123  lua_getfield(L, iState, "data");
1124 
1125  // Call the function
1126  luaW_pcall(L, 3, l_obj ? 1 : 0, true);
1127  if (l_obj) {
1128  l_obj->store(L, -1);
1129  }
1130 
1131  lua_settop(L, initial_top);//empty stack
1132 }
1133 
1135 {
1136  // Remove the function from the registry, so that it can be collected.
1137  lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey)));
1139  lua_pushnil(L);
1140  lua_rawseti(L, -2, num_);
1141  lua_pop(L, 1);
1142 }
1143 
1144 } // of namespace ai
static int ai_stopunit_select(lua_State *L, bool exec, bool remove_movement, bool remove_attacks)
Definition: core.cpp:257
bool leader_threat
Is true if the unit is a threat to our leader.
Definition: contexts.hpp:137
LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
Definition: lapi.cpp:643
#define lua_isnoneornil(L, n)
Definition: lua.h:337
static int cfun_ai_get_passive_leader_shares_keep(lua_State *L)
Definition: core.cpp:486
LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
Definition: lapi.cpp:579
static void push_move_map(lua_State *L, const move_map &m)
Definition: core.cpp:669
double avg_damage_taken
The average hitpoints damage taken.
Definition: contexts.hpp:115
virtual const move_map & get_srcdst() const =0
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:667
#define lua_pushcfunction(L, f)
Definition: lua.h:328
static ai::readonly_context & get_readonly_context(lua_State *L)
Definition: core.cpp:129
LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:622
virtual void set_src_dst_enemy_valid_lua()=0
unit_iterator end()
Definition: map.hpp:311
virtual bool is_src_dst_valid_lua() const =0
static int cfun_ai_check_synced_command(lua_State *L)
Definition: core.cpp:305
const map_location & get_location() const
Definition: unit.hpp:286
static int cfun_ai_execute_stopunit_attacks(lua_State *L)
Definition: core.cpp:271
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1806
virtual const aspect_map & get_aspects() const =0
virtual void set_src_dst_valid_lua()=0
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:159
static attack_result_ptr execute_attack_action(side_number side, bool execute, const map_location &attacker_loc, const map_location &defender_loc, int attacker_weapon, double aggression, const unit_advancements_aspect &advancements=unit_advancements_aspect())
Ask the game to attack an enemy defender using our unit attacker from attackers current location...
Definition: actions.cpp:994
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
LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
Definition: lauxlib.cpp:693
virtual std::string get_grouping() const =0
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:571
static int transform_ai_action(lua_State *L, ai::action_result_ptr action_result)
Definition: core.cpp:149
double avg_damage_inflicted
The average hitpoints damage inflicted.
Definition: contexts.hpp:110
Managing the AI-Game interaction - AI actions and their results.
virtual config get_leader_goal() const =0
const char * name
Definition: lauxlib.h:23
LUA_API void lua_getglobal(lua_State *L, const char *var)
Definition: lapi.cpp:602
virtual const map_location & suitable_keep(const map_location &leader_location, const pathfind::paths &leader_paths)=0
get most suitable keep for leader - nearest free that can be reached in 1 turn, if none - return near...
static int cfun_ai_get_scout_village_targeting(lua_State *L)
Definition: core.cpp:507
static int cfun_ai_execute_stopunit_moves(lua_State *L)
Definition: core.cpp:266
static int cfun_ai_execute_recruit(lua_State *L)
Definition: core.cpp:325
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.cpp:154
static int cfun_ai_get_avoid(lua_State *L)
Definition: core.cpp:427
virtual bool is_dst_src_enemy_valid_lua() const =0
static int cfun_ai_check_attack(lua_State *L)
Definition: core.cpp:252
static int cfun_ai_execute_recall(lua_State *L)
Definition: core.cpp:350
void get_persistent_data(config &) const
Definition: core.cpp:95
map_location target
Definition: contexts.hpp:97
LUA_API void lua_settable(lua_State *L, int idx)
Definition: lapi.cpp:741
static int cfun_ai_get_dstsrc(lua_State *L)
Definition: core.cpp:708
#define lua_tointeger(L, i)
Definition: lua.h:319
double vulnerability
The vulnerability is the power projection of enemy units onto the hex we're standing on...
Definition: contexts.hpp:134
GLuint const GLfloat * val
Definition: glew.h:2614
virtual void set_dst_src_valid_lua()=0
lua_ai_context & context_
Definition: core.hpp:75
virtual bool get_simple_targeting() const =0
static int cfun_ai_get_village_value(lua_State *L)
Definition: core.cpp:528
static lua_ai_context * create(lua_State *L, char const *code, engine_lua *engine)
Definition: core.cpp:979
virtual bool get_support_villages() const =0
virtual const move_map & get_enemy_dstsrc() const =0
static int cfun_attack_rating(lua_State *L)
Definition: core.cpp:543
#define ERR_LUA
Definition: core.cpp:51
#define lua_tonumber(L, i)
Definition: lua.h:318
virtual const move_map & get_enemy_srcdst() const =0
static int cfun_ai_get_srcdst(lua_State *L)
Definition: core.cpp:716
LUA_API int lua_isuserdata(lua_State *L, int idx)
Definition: lapi.cpp:274
virtual double get_village_value() const =0
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)
Definition: lapi.cpp:549
double resources_used
The sum of the values of units used in the attack.
Definition: contexts.hpp:118
double chance_to_kill
Estimated % chance to kill the unit.
Definition: contexts.hpp:107
static int cfun_ai_recalculate_move_maps(lua_State *L)
Definition: core.cpp:768
static config unit_name(const unit *u)
Definition: reports.cpp:133
virtual const attacks_vector & get_attacks() const =0
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:314
void handle(const config &cfg, bool read_only, lua_object_ptr l_obj)
Definition: core.cpp:1106
map_location luaW_checklocation(lua_State *L, int index)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:655
static void push_location_key(lua_State *L, const map_location &loc)
Definition: core.cpp:139
static int cfun_ai_get_leader_goal(lua_State *L)
Definition: core.cpp:458
LUA_API int lua_absindex(lua_State *L, int idx)
Definition: lapi.cpp:147
Lua object(value) wrapper implementation.
static int cfun_ai_execute_attack(lua_State *L)
Definition: core.cpp:247
static int cfun_ai_get_support_villages(lua_State *L)
Definition: core.cpp:521
static int ai_recall(lua_State *L, bool exec)
Definition: core.cpp:335
virtual bool get_passive_leader() const =0
static int cfun_ai_execute_synced_command(lua_State *L)
Definition: core.cpp:300
#define lua_pop(L, n)
Definition: lua.h:322
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
Definition: lua_api.cpp:183
GLuint GLsizei GLsizei * length
Definition: glew.h:1793
virtual const unit_advancements_aspect & get_advancements() const =0
double target_value
The value of the unit being targeted.
Definition: contexts.hpp:101
std::vector< attack_analysis > attacks_vector
Definition: game_info.hpp:56
static int cfun_ai_get_villages_per_scout(lua_State *L)
Definition: core.cpp:535
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
#define lua_upvalueindex(i)
Definition: lua.h:40
static int cfun_ai_get_leader_value(lua_State *L)
Definition: core.cpp:472
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:57
static int ai_synced_command(lua_State *L, bool exec)
Definition: core.cpp:286
void set_arguments(const config &)
Definition: core.cpp:81
LUA_API void lua_setglobal(lua_State *L, const char *var)
Definition: lapi.cpp:728
static recall_result_ptr execute_recall_action(side_number side, bool execute, const std::string &unit_id, const map_location &where, const map_location &from)
Ask the game to recall a unit for us on specified location.
Definition: actions.cpp:1019
GLuint64EXT * result
Definition: glew.h:10727
void set_persistent_data(const config &)
Definition: core.cpp:109
bool was_readonly
Definition: core.hpp:63
static int cfun_ai_is_src_dst_valid(lua_State *L)
Definition: core.cpp:754
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil...
Definition: lua_common.cpp:792
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:268
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:811
virtual const terrain_filter & get_avoid() const =0
static int cfun_ai_get_leader_ignores_keep(lua_State *L)
Definition: core.cpp:465
static char const aisKey
Definition: core.cpp:53
const std::vector< std::string > get_advancements(const unit_map::const_iterator &unit) const
double alternative_terrain_quality
The weighted average of the % defense of the best possible terrain that the attacking units could rea...
Definition: contexts.hpp:128
Proxy table for the AI context.
Definition: core.hpp:35
static int ai_move(lua_State *L, bool exec, bool remove_movement)
Definition: core.cpp:188
static lua_ai_action_handler * create(lua_State *L, char const *code, lua_ai_context &context)
Definition: core.cpp:1022
static int ai_recruit(lua_State *L, bool exec)
Definition: core.cpp:310
static int cfun_ai_get_aggression(lua_State *L)
Definition: core.cpp:397
static void push_attack_analysis(lua_State *L, const attack_analysis &)
Definition: core.cpp:589
lua_ai_load(lua_ai_context &ctx, bool read_only)
Definition: core.cpp:1049
static int impl_ai_aspect_get(lua_State *L)
Definition: core.cpp:786
static int cfun_ai_get_enemy_dstsrc(lua_State *L)
Definition: core.cpp:724
static int cfun_ai_get_attacks(lua_State *L)
Definition: core.cpp:411
static int refcount
Definition: core.hpp:61
static int cfun_ai_is_src_dst_enemy_valid(lua_State *L)
Definition: core.cpp:761
LUA_API int lua_setmetatable(lua_State *L, int objindex)
Definition: lapi.cpp:806
virtual int get_villages_per_scout() const =0
static int cfun_ai_get_simple_targeting(lua_State *L)
Definition: core.cpp:514
LUA_API void lua_remove(lua_State *L, int idx)
Definition: lapi.cpp:176
static const map_location & null_location()
Definition: location.hpp:195
GLfloat GLfloat p
Definition: glew.h:12766
static int cfun_ai_execute_stopunit_all(lua_State *L)
Definition: core.cpp:276
static void push_movements(lua_State *L, const std::vector< std::pair< map_location, map_location > > &moves)
Definition: core.cpp:563
static int cfun_ai_get_grouping(lua_State *L)
Definition: core.cpp:444
static int cfun_ai_check_stopunit(lua_State *L)
Definition: core.cpp:281
#define lua_newtable(L)
Definition: lua.h:324
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:459
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
Definition: lapi.cpp:467
Encapsulates the map of the game.
Definition: location.hpp:38
bool uses_leader
Is true if this attack sequence makes use of the leader.
Definition: contexts.hpp:140
#define lua_isboolean(L, n)
Definition: lua.h:334
static int cfun_ai_execute_move_full(lua_State *L)
Definition: core.cpp:201
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:675
void push_ai_table()
Definition: core.cpp:134
static int cfun_ai_get_targets(lua_State *L)
Definition: core.cpp:363
static int cfun_ai_check_recruit(lua_State *L)
Definition: core.cpp:330
GLuint res
Definition: glew.h:9258
LUA_API void * lua_touserdata(lua_State *L, int idx)
Definition: lapi.cpp:421
static int cfun_ai_is_dst_src_valid(lua_State *L)
Definition: core.cpp:740
static void init(lua_State *L)
Definition: core.cpp:59
void get_locations(std::set< map_location > &locs, bool with_border=false) const
Definition: filter.cpp:495
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.cpp:764
lua_ai_context(lua_State *l, int num, int side)
Definition: core.hpp:41
virtual const team & current_team() const =0
void get_arguments(config &) const
Definition: core.cpp:67
virtual void set_dst_src_enemy_valid_lua()=0
GLuint index
Definition: glew.h:1782
virtual bool is_src_dst_enemy_valid_lua() const =0
std::map< std::string, aspect_ptr > aspect_map
Definition: game_info.hpp:114
std::vector< std::pair< map_location, map_location > > movements
Definition: contexts.hpp:98
static int cfun_ai_recalculate_move_maps_enemy(lua_State *L)
Definition: core.cpp:774
double avg_losses
The value on average, of units lost in the combat.
Definition: contexts.hpp:104
static recruit_result_ptr execute_recruit_action(side_number side, bool execute, const std::string &unit_name, const map_location &where, const map_location &from)
Ask the game to recruit a unit for us on specified location.
Definition: actions.cpp:1030
LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *extramsg)
Definition: lauxlib.cpp:152
size_t i
Definition: function.cpp:1057
static synced_command_result_ptr execute_synced_command_action(side_number side, bool execute, const std::string &lua_code, const map_location &location)
Ask the game to run Lua code.
Definition: actions.cpp:1052
#define lua_tostring(L, i)
Definition: lua.h:345
virtual int get_attack_depth() const =0
LUA_API void lua_rawseti(lua_State *L, int idx, int n)
Definition: lapi.cpp:778
virtual const std::vector< std::string > get_recruitment_pattern() const =0
virtual bool get_passive_leader_shares_keep() const =0
static int impl_ai_aspect_set(lua_State *L)
Definition: core.cpp:839
static int cfun_ai_get_attack_depth(lua_State *L)
Definition: core.cpp:404
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:229
LUA_API int lua_isnumber(lua_State *L, int idx)
Definition: lapi.cpp:261
static int ai_attack(lua_State *L, bool exec)
Definition: core.cpp:216
virtual double get_leader_value() const =0
#define lua_call(L, n, r)
Definition: lua.h:252
Proxy class for calling AI action handlers defined in Lua.
Definition: core.hpp:71
static stopunit_result_ptr execute_stopunit_action(side_number side, bool execute, const map_location &unit_location, bool remove_movement, bool remove_attacks)
Ask the game to remove unit movements and/or attack.
Definition: actions.cpp:1041
static int cfun_ai_execute_move_partial(lua_State *L)
Definition: core.cpp:206
static int cfun_ai_check_move(lua_State *L)
Definition: core.cpp:211
LUA_API size_t lua_rawlen(lua_State *L, int idx)
Definition: lapi.cpp:401
lua_ai_action_handler(lua_State *l, lua_ai_context &context, int num)
Definition: core.hpp:77
GLsizeiptr size
Definition: glew.h:1649
#define LUA_REGISTRYINDEX
Definition: lua.h:39
virtual ai_context_ptr get_ai_context()
Definition: engine.cpp:133
static int impl_ai_get(lua_State *L)
Definition: core.cpp:845
LUA_API int lua_error(lua_State *L)
Definition: lapi.cpp:1099
static lg::log_domain log_ai_engine_lua("ai/engine/lua")
const GLdouble * m
Definition: glew.h:6968
virtual const move_map & get_dstsrc() const =0
void luaW_pushconfig(lua_State *L, config const &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:663
virtual double get_aggression() const =0
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:593
readonly_context & get_readonly_context()
Definition: engine.cpp:146
Composite AI contexts.
Standard logging facilities (interface).
virtual side_number get_side() const =0
Get the side number.
Object which contains all the possible locations a unit can move to, with associated best routes to t...
Definition: pathfind.hpp:71
virtual void recalculate_move_maps() const =0
virtual double get_leader_aggression() const =0
static size_t generate_and_push_ai_state(lua_State *L, ai::engine_lua *engine)
Definition: core.cpp:964
static int cfun_ai_get_caution(lua_State *L)
Definition: core.cpp:437
bool is_surrounded
Is true if the units involved in this attack sequence are surrounded.
Definition: contexts.hpp:143
map_location location
static int cfun_ai_get_passive_leader(lua_State *L)
Definition: core.cpp:479
virtual double get_scout_village_targeting() const =0
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
static void generate_and_push_ai_table(lua_State *L, ai::engine_lua *engine)
Definition: core.cpp:954
LUA AI Support engine - creating specific ai components from config.
virtual void recalculate_move_maps_enemy() const =0
virtual bool is_dst_src_valid_lua() const =0
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:477
This module contains various pathfinding functions and utilities.
LUALIB_API int luaL_typerror(lua_State *L, int narg, const char *tname)
Definition: lauxlib.cpp:176
static int cfun_ai_get_leader_aggression(lua_State *L)
Definition: core.cpp:451
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 std::vector< target > find_targets(const move_map &enemy_dstsrc)=0
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:507
typesafe_aspect< T > * try_aspect_as(aspect_ptr p)
Definition: core.cpp:781
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:752
static int cfun_ai_get_enemy_srcdst(lua_State *L)
Definition: core.cpp:732
void update_state()
Definition: core.cpp:1000
static int cfun_ai_get_suitable_keep(lua_State *L)
Definition: core.cpp:163
static move_result_ptr execute_move_action(side_number side, bool execute, const map_location &from, const map_location &to, bool remove_movement, bool unreach_is_ok=false)
Ask the game to move our unit from location 'from' to location 'to', optionally - doing a partial mov...
Definition: actions.cpp:1007
virtual double get_caution() const =0
static int cfun_ai_is_dst_src_enemy_valid(lua_State *L)
Definition: core.cpp:747
static int cfun_ai_get_recruitment_pattern(lua_State *L)
Definition: core.cpp:493
double rating(double aggression, const readonly_context &ai_obj) const
Definition: attack.cpp:264
static ai::engine_lua & get_engine(lua_State *L)
Definition: core.cpp:123
static const std::string & get_error_name(int error_code)
get human-readable name of the error by code.
Definition: actions.cpp:1062
static int cfun_ai_check_recall(lua_State *L)
Definition: core.cpp:355
const std::string valid
Little parts of regex templates used to parse Wml annoations.
virtual bool get_leader_ignores_keep() const =0
#define luaL_checkstring(L, n)
Definition: lauxlib.h:115