The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
manager.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 - 2025
3 by Yurii Chernyi <terraninfo@terraninfo.net>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16/**
17 * Managing the AI lifecycle and interface for the rest of Wesnoth
18 * @file
19 */
20
21#include "ai/manager.hpp"
22
23#include "config.hpp" // for config, etc
24#include "game_events/pump.hpp"
25#include "log.hpp"
26#include "map/location.hpp" // for map_location
27#include "resources.hpp"
29#include "tod_manager.hpp"
30
31#include "ai/composite/ai.hpp" // for ai_composite
32#include "ai/composite/component.hpp" // for component_manager
33#include "ai/composite/engine.hpp" // for engine
35#include "ai/configuration.hpp" // for configuration
36#include "ai/contexts.hpp" // for readonly_context, etc
37#include "ai/default/contexts.hpp" // for default_ai_context, etc
38#include "ai/game_info.hpp" // for side_number, engine_ptr, etc
39#include "game_config.hpp" // for debug
41#include "ai/registry.hpp" // for init
42#include "ai/lua/engine_lua.hpp"
43
44#include <algorithm> // for min
45#include <cassert> // for assert
46#include <iterator> // for reverse_iterator, etc
47#include <map> // for _Rb_tree_iterator, etc
48#include <set> // for set
49#include <stack> // for stack
50#include <utility> // for pair, make_pair
51#include <vector> // for vector, allocator, etc
52
53#include <SDL3/SDL_timer.h>
54
55namespace ai {
56
57const std::string manager::AI_TYPE_COMPOSITE_AI = "composite_ai";
58const std::string manager::AI_TYPE_SAMPLE_AI = "sample_ai";
59const std::string manager::AI_TYPE_IDLE_AI = "idle_ai";
60const std::string manager::AI_TYPE_FORMULA_AI = "formula_ai";
61const std::string manager::AI_TYPE_DEFAULT = "default";
62
63static lg::log_domain log_ai_manager("ai/manager");
64#define DBG_AI_MANAGER LOG_STREAM(debug, log_ai_manager)
65#define LOG_AI_MANAGER LOG_STREAM(info, log_ai_manager)
66#define ERR_AI_MANAGER LOG_STREAM(err, log_ai_manager)
67
68static lg::log_domain log_ai_mod("ai/mod");
69#define DBG_AI_MOD LOG_STREAM(debug, log_ai_mod)
70#define LOG_AI_MOD LOG_STREAM(info, log_ai_mod)
71#define WRN_AI_MOD LOG_STREAM(warn, log_ai_mod)
72#define ERR_AI_MOD LOG_STREAM(err, log_ai_mod)
73
75 : ai_(), side_context_(nullptr), readonly_context_(nullptr), readwrite_context_(nullptr), default_ai_context_(nullptr), side_(side), cfg_(cfg)
76{
77 DBG_AI_MANAGER << describe_ai() << "Preparing new AI holder";
78}
79
81{
82 if (side_context_ == nullptr) {
83 side_context_.reset(new side_context_impl(side,cfg_));
84 } else {
85 side_context_->set_side(side);
86 }
87 if (readonly_context_ == nullptr){
89 readonly_context_->on_readonly_context_create();
90 }
91 if (readwrite_context_ == nullptr){
93 }
94 if (default_ai_context_ == nullptr){
96 }
97 if (!ai_){
99 }
100
101 if (ai_) {
102 ai_->on_create();
103 for (config &mod_ai : cfg_.child_range("modify_ai")) {
104 if (!mod_ai.has_attribute("side")) {
105 mod_ai["side"] = side;
106 }
107 modify_ai(mod_ai);
108 }
109 for(config& micro : cfg_.child_range("micro_ai")) {
110 micro["side"] = side;
111 micro["action"] = "add";
112 micro_ai(micro);
113 }
114 cfg_.clear_children("modify_ai", "micro_ai");
115
116 std::vector<engine_ptr> engines = ai_->get_engines();
117 for (std::vector<engine_ptr>::iterator it = engines.begin(); it != engines.end(); ++it)
118 {
119 (*it)->set_ai_context(&(ai_->get_ai_context()));
120 }
121
122 } else {
123 ERR_AI_MANAGER << describe_ai()<<"AI lazy initialization error!";
124 }
125
126}
127
129{
130 try {
131 if (ai_) {
132 LOG_AI_MANAGER << describe_ai() << "Managed AI will be deleted";
133 }
134 } catch (...) {}
135}
136
138{
139 if (!ai_) {
140 init(side_);
141 }
142 assert(ai_);
143
144 return *ai_;
145}
146
148{
149 if (!ai_) {
150 init(side_);
151 }
152 assert(ai_);
153
154 auto engine = ai_->get_engine_by_cfg(config{"engine", "lua"});
155 if(auto lua = std::dynamic_pointer_cast<engine_lua>(engine)) {
156 lua->apply_micro_ai(cfg);
157 }
158}
159
161{
162 if (!ai_) {
163 // if not initialized, initialize now.
164 get_ai_ref();
165 }
166 const std::string &act = cfg["action"];
167 LOG_AI_MOD << "side "<< side_ << " "<<act<<"_ai_component \""<<cfg["path"]<<"\"";
168 DBG_AI_MOD << std::endl << cfg;
169 DBG_AI_MOD << "side "<< side_ << " before "<<act<<"_ai_component"<<std::endl << to_config();
170 bool res = false;
171 if (act == "add") {
173 } else if (act == "change") {
175 } else if (act == "delete") {
177 } else {
178 ERR_AI_MOD << "modify_ai tag has invalid 'action' attribute " << act;
179 }
180 DBG_AI_MOD << "side "<< side_ << " after [modify_ai]"<<act<<std::endl << to_config();
181 if (!res) {
182 LOG_AI_MOD << act << "_ai_component failed";
183 } else {
184 LOG_AI_MOD << act << "_ai_component success";
185 }
186
187}
188
190{
191 if(!ai_) {
192 get_ai_ref();
193 }
194 for(const config& aspect : cfg.child_range("aspect")) {
195 const std::string& id = aspect["id"];
196 for(const config& facet : aspect.child_range("facet")) {
197 ai_->add_facet(id, facet);
198 }
199 }
200 for(const config& goal : cfg.child_range("goal")) {
201 ai_->add_goal(goal);
202 }
203 for(const config& stage : cfg.child_range("stage")) {
204 if(stage["name"] != "empty") {
205 ai_->add_stage(stage);
206 }
207 }
208 for(config mod : cfg.child_range("modify_ai")) {
209 if (!mod.has_attribute("side")) {
210 mod["side"] = side_context_->get_side();
211 }
212 modify_ai(mod);
213 }
214 for(config micro : cfg.child_range("micro_ai")) {
215 micro["side"] = side_context_->get_side();
216 micro["action"] = "add";
217 micro_ai(micro);
218 }
219}
220
222{
223 if (!ai_) {
224 return cfg_;
225 } else {
226 config cfg = ai_->to_config();
227 if (side_context_!=nullptr) {
228 cfg.merge_with(side_context_->to_side_context_config());
229 }
230 if (readonly_context_!=nullptr) {
231 cfg.merge_with(readonly_context_->to_readonly_context_config());
232 }
233 if (readwrite_context_!=nullptr) {
234 cfg.merge_with(readwrite_context_->to_readwrite_context_config());
235 }
236 if (default_ai_context_!=nullptr) {
237 cfg.merge_with(default_ai_context_->to_default_ai_context_config());
238 }
239
240 return cfg;
241 }
242}
243
244std::string holder::describe_ai() const
245{
246 if(ai_) {
247 return formatter() << ai_->describe_self() << " for side " << side_ << " : ";
248 } else {
249 return formatter() << "not initialized ai with id=[" << cfg_["id"] << "] for side " << side_ << " : ";
250 }
251}
252
254{
255 if (!ai_) {
256 get_ai_ref();
257 }
258 // These assignments are necessary because the code will otherwise not compile on some platforms with an lvalue/rvalue mismatch error
259 auto lik = ai_->get_leader_ignores_keep();
260 auto pl = ai_->get_passive_leader();
261 auto plsk = ai_->get_passive_leader_shares_keep();
262 // In order to display booleans as yes/no rather than 1/0 or true/false
263 config cfg;
264 cfg["allow_ally_villages"] = ai_->get_allow_ally_villages();
265 cfg["simple_targeting"] = ai_->get_simple_targeting();
266 cfg["support_villages"] = ai_->get_support_villages();
267 std::stringstream s;
268 s << "advancements: " << ai_->get_advancements().get_value() << std::endl;
269 s << "aggression: " << ai_->get_aggression() << std::endl;
270 s << "allow_ally_villages: " << cfg["allow_ally_villages"] << std::endl;
271 s << "caution: " << ai_->get_caution() << std::endl;
272 s << "grouping: " << ai_->get_grouping() << std::endl;
273 s << "leader_aggression: " << ai_->get_leader_aggression() << std::endl;
274 s << "leader_ignores_keep: " << utils::visit(leader_aspects_visitor(), lik) << std::endl;
275 s << "leader_value: " << ai_->get_leader_value() << std::endl;
276 s << "passive_leader: " << utils::visit(leader_aspects_visitor(), pl) << std::endl;
277 s << "passive_leader_shares_keep: " << utils::visit(leader_aspects_visitor(), plsk) << std::endl;
278 s << "recruitment_diversity: " << ai_->get_recruitment_diversity() << std::endl;
279 s << "recruitment_instructions: " << std::endl << "----config begin----" << std::endl;
280 s << ai_->get_recruitment_instructions() << "-----config end-----" << std::endl;
281 s << "recruitment_more: " << utils::join(ai_->get_recruitment_more()) << std::endl;
282 s << "recruitment_pattern: " << utils::join(ai_->get_recruitment_pattern()) << std::endl;
283 s << "recruitment_randomness: " << ai_->get_recruitment_randomness() << std::endl;
284 s << "recruitment_save_gold: " << std::endl << "----config begin----" << std::endl;
285 s << ai_->get_recruitment_save_gold() << "-----config end-----" << std::endl;
286 s << "retreat_enemy_weight: " << ai_->get_retreat_enemy_weight() << std::endl;
287 s << "retreat_factor: " << ai_->get_retreat_factor() << std::endl;
288 s << "scout_village_targeting: " << ai_->get_scout_village_targeting() << std::endl;
289 s << "simple_targeting: " << cfg["simple_targeting"] << std::endl;
290 s << "support_villages: " << cfg["support_villages"] << std::endl;
291 s << "village_value: " << ai_->get_village_value() << std::endl;
292 s << "villages_per_scout: " << ai_->get_villages_per_scout() << std::endl;
293
294 return s.str();
295}
296
298{
299 if (!ai_) {
300 get_ai_ref();
301 }
303}
304
305std::string holder::get_ai_identifier() const
306{
307 return cfg_["id"];
308}
309
310component* holder::get_component(component *root, const std::string &path) {
311 if (!game_config::debug) // Debug guard
312 {
313 return nullptr;
314 }
315
316 if (root == nullptr) // Return root component(ai_)
317 {
318 if (!ai_) {
319 init(side_);
320 }
321 assert(ai_);
322
323 return &*ai_;
324 }
325
326 return component_manager::get_component(root, path);
327}
328
329// =======================================================================
330// LIFECYCLE
331// =======================================================================
332
334 : history_()
335 , history_item_counter_(0)
336 , ai_info_()
337 , map_changed_("ai_map_changed")
338 , recruit_list_changed_("ai_recruit_list_changed")
339 , user_interact_("ai_user_interact")
340 , sync_network_("ai_sync_network")
341 , tod_changed_("ai_tod_changed")
342 , gamestate_changed_("ai_gamestate_changed")
343 , turn_started_("ai_turn_started")
344 , last_interact_()
345 , num_interact_(0)
346{
348 singleton_ = this;
349}
350
352 ai_map_.clear();
353 if(singleton_ == this) {
354 singleton_ = nullptr;
355 }
356}
357
359
361 user_interact_.attach_handler(event_observer);
362 sync_network_.attach_handler(event_observer);
363 turn_started_.attach_handler(event_observer);
364 gamestate_changed_.attach_handler(event_observer);
365}
366
368 user_interact_.detach_handler(event_observer);
369 sync_network_.detach_handler(event_observer);
370 turn_started_.detach_handler(event_observer);
371 gamestate_changed_.detach_handler(event_observer);
372}
373
375 gamestate_changed_.attach_handler(event_observer);
376 turn_started_.attach_handler(event_observer);
377 map_changed_.attach_handler(event_observer);
378}
379
381 gamestate_changed_.detach_handler(event_observer);
382 turn_started_.detach_handler(event_observer);
383 map_changed_.detach_handler(event_observer);
384}
385
387 tod_changed_.attach_handler(event_observer);
388}
389
393
395{
396 map_changed_.attach_handler(event_observer);
397}
398
403
405{
406 turn_started_.attach_handler(event_observer);
407}
408
413
415{
416 map_changed_.detach_handler(event_observer);
417}
418
420{
421 turn_started_.detach_handler(event_observer);
422}
423
426 return;
427 }
428
429 using namespace std::chrono_literals;
430 constexpr auto interact_time = 30ms;
431
432 const auto now = std::chrono::steady_clock::now();
433 const auto time_since_interact = now - last_interact_;
434 if(time_since_interact < interact_time) {
435 return;
436 }
437
440
441 last_interact_ = now;
442}
443
447
451
455
459
463
467
468// =======================================================================
469// ADD, CREATE AIs, OR LIST AI TYPES
470// =======================================================================
471
472bool manager::add_ai_for_side_from_file( side_number side, const std::string& file, bool replace )
473{
474 config cfg;
476 ERR_AI_MANAGER << " unable to read [SIDE] config for side "<< side << "from file [" << file <<"]";
477 return false;
478 }
479 return add_ai_for_side_from_config(side,cfg,replace);
480}
481
483 config parsed_cfg;
484 configuration::parse_side_config(side, cfg, parsed_cfg);
485
486 if (replace) {
487 remove_ai_for_side(side);
488 }
489
490 std::stack<holder>& ai_stack_for_specific_side = get_or_create_ai_stack_for_side(side);
491 ai_stack_for_specific_side.emplace(side, parsed_cfg);
492 return true;
493}
494
495// =======================================================================
496// REMOVE
497// =======================================================================
498
500{
501 std::stack<holder>& ai_stack_for_specific_side = get_or_create_ai_stack_for_side(side);
502 if (!ai_stack_for_specific_side.empty()){
503 ai_stack_for_specific_side.pop();
504 }
505}
506
508{
509 std::stack<holder>& ai_stack_for_specific_side = get_or_create_ai_stack_for_side(side);
510
511 //clear the stack. std::stack doesn't have a '.clear()' method to do it
512 while (!ai_stack_for_specific_side.empty()){
513 ai_stack_for_specific_side.pop();
514 }
515}
516
518{
519 ai_map_.clear();
520}
521
526
531
536
541
546
548{
550 {
551 static ai::holder empty_holder(side, config());
552 return empty_holder;
553 }
555}
556
561
566
568{
569 return ai_info_;
570}
571
576
577// =======================================================================
578// PROXY
579// =======================================================================
580
582 last_interact_ = {};
583 num_interact_ = 0;
584 const auto turn_start_time = std::chrono::steady_clock::now();
585 get_ai_info().recent_attacks.clear();
586 ai_composite& ai_obj = get_active_ai_for_side(side);
587 resources::game_events->pump().fire("ai_turn");
589 if (resources::tod_manager->has_tod_bonus_changed()) {
591 }
592 ai_obj.new_turn();
593 ai_obj.play_turn();
594 const auto turn_end_time = std::chrono::steady_clock::now();
595 DBG_AI_MANAGER << "side " << side << ": number of user interactions: "<<num_interact_;
596 DBG_AI_MANAGER << "side " << side << ": total turn time: " << (turn_end_time - turn_start_time).count() << " ms ";
597}
598
599// =======================================================================
600// PRIVATE
601// =======================================================================
602// =======================================================================
603// AI STACKS
604// =======================================================================
606{
607 AI_map_of_stacks::iterator iter = ai_map_.find(side);
608 if (iter!=ai_map_.end()){
609 return iter->second;
610 }
611 return ai_map_.emplace(side, std::stack<holder>()).first->second;
612}
613
614// =======================================================================
615// AI HOLDERS
616// =======================================================================
618{
619 std::stack<holder>& ai_stack_for_specific_side = get_or_create_ai_stack_for_side(side);
620
621 if (!ai_stack_for_specific_side.empty()){
622 return ai_stack_for_specific_side.top();
623 } else {
625 ai_stack_for_specific_side.emplace(side, cfg);
626 return ai_stack_for_specific_side.top();
627 }
628}
629
630// =======================================================================
631// AI POINTERS
632// =======================================================================
633
638
639// =======================================================================
640// MISC
641// =======================================================================
642
643} //end of namespace ai
#define LOG_AI_MOD
Definition manager.cpp:70
#define DBG_AI_MOD
Definition manager.cpp:69
#define ERR_AI_MOD
Definition manager.cpp:72
#define LOG_AI_MANAGER
Definition manager.cpp:65
#define DBG_AI_MANAGER
Definition manager.cpp:64
#define ERR_AI_MANAGER
Definition manager.cpp:66
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
Composite AI with turn sequence which is a vector of stages.
virtual void new_turn()
On new turn.
Definition ai.cpp:149
void play_turn()
Play the turn.
Definition ai.cpp:127
static bool delete_component(component *root, const std::string &path)
static component * get_component(component *root, const std::string &path)
static bool change_component(component *root, const std::string &path, const config &cfg)
static bool add_component(component *root, const std::string &path, const config &cfg)
static std::string print_component_tree(component *root, const std::string &path)
static bool get_side_config_from_file(const std::string &file, config &cfg)
get side config from file
static bool parse_side_config(side_number side, const config &original_cfg, config &cfg)
static const config & get_default_ai_parameters()
get default AI parameters
std::set< map_location > recent_attacks
Base class that holds the AI and current AI parameters.
Definition manager.hpp:50
std::string describe_ai() const
Definition manager.cpp:244
std::string get_ai_structure()
Definition manager.cpp:297
config to_config() const
Definition manager.cpp:221
composite_ai_ptr ai_
Definition manager.hpp:78
std::string get_ai_identifier() const
Definition manager.cpp:305
void micro_ai(const config &cfg)
Definition manager.cpp:147
void modify_ai(const config &cfg)
Definition manager.cpp:160
config cfg_
Definition manager.hpp:84
ai_composite & get_ai_ref()
Definition manager.cpp:137
virtual ~holder()
Definition manager.cpp:128
component * get_component(component *root, const std::string &path)
Definition manager.cpp:310
std::unique_ptr< side_context > side_context_
Definition manager.hpp:79
side_number side_
Definition manager.hpp:83
std::unique_ptr< readwrite_context > readwrite_context_
Definition manager.hpp:81
std::string get_ai_overview()
Definition manager.cpp:253
std::unique_ptr< readonly_context > readonly_context_
Definition manager.hpp:80
void init(side_number side)
Definition manager.cpp:80
void append_ai(const config &cfg)
Definition manager.cpp:189
std::unique_ptr< default_ai_context > default_ai_context_
Definition manager.hpp:82
holder(side_number side, const config &cfg)
Definition manager.cpp:74
Class that manages AIs for all sides and manages AI redeployment.
Definition manager.hpp:111
static const std::string AI_TYPE_SAMPLE_AI
Definition manager.hpp:121
events::generic_event map_changed_
Definition manager.hpp:410
std::string get_active_ai_identifier_for_side(side_number side)
Gets AI algorithm identifier for active AI of the given side.
Definition manager.cpp:542
void clear_ais()
Clears all the AIs.
Definition manager.cpp:517
std::string get_active_ai_overview_for_side(side_number side)
Gets AI Overview for active AI of the given side.
Definition manager.cpp:532
ai_composite & get_active_ai_for_side(side_number side)
Gets active AI for specified side.
Definition manager.cpp:634
void raise_tod_changed()
Notifies all observers of 'ai_tod_changed' event.
Definition manager.cpp:452
bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace=true)
Adds active AI for specified side from cfg.
Definition manager.cpp:482
config to_config(side_number side)
Gets AI config for active AI of the given side.
Definition manager.cpp:557
events::generic_event user_interact_
Definition manager.hpp:412
void remove_all_ais_for_side(side_number side)
Removes all AIs from side.
Definition manager.cpp:507
void remove_gamestate_observer(events::observer *event_observer)
Removes an observer of game events except ai_user_interact event and ai_sync_network event.
Definition manager.cpp:380
void remove_observer(events::observer *event_observer)
Removes an observer of game events.
Definition manager.cpp:367
void raise_turn_started()
Notifies all observers of 'ai_turn_started' event.
Definition manager.cpp:456
static manager * singleton_
Definition manager.hpp:422
static const std::string AI_TYPE_IDLE_AI
Definition manager.hpp:122
static const std::string AI_TYPE_COMPOSITE_AI
Definition manager.hpp:120
void raise_gamestate_changed()
Notifies all observers of 'ai_gamestate_changed' event.
Definition manager.cpp:448
void add_gamestate_observer(events::observer *event_observer)
Adds observer of game events except ai_user_interact event and ai_sync_network event.
Definition manager.cpp:374
void append_active_ai_for_side(ai::side_number side, const config &cfg)
Appends AI parameters to active AI of the given side.
Definition manager.cpp:527
AI_map_of_stacks ai_map_
Definition manager.hpp:420
std::string get_active_ai_structure_for_side(side_number side)
Gets AI Structure for active AI of the given side.
Definition manager.cpp:537
events::generic_event sync_network_
Definition manager.hpp:413
void raise_user_interact()
Notifies all observers of 'ai_user_interact' event.
Definition manager.cpp:424
static const std::string AI_TYPE_FORMULA_AI
Definition manager.hpp:123
events::generic_event recruit_list_changed_
Definition manager.hpp:411
std::stack< holder > & get_or_create_ai_stack_for_side(side_number side)
Gets the AI stack for the specified side, create it if it doesn't exist.
Definition manager.cpp:605
holder & get_active_ai_holder_for_side(side_number side)
Gets active holder for specified side.
Definition manager.cpp:617
void add_recruit_list_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_recruit_list_changed' event.
Definition manager.cpp:399
game_info & get_active_ai_info_for_side(side_number side)
Gets AI info for active AI of the given side.
Definition manager.cpp:562
void add_map_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_map_changed' event.
Definition manager.cpp:394
void add_turn_started_observer(events::observer *event_observer)
Adds an observer of 'ai_turn_started' event.
Definition manager.cpp:404
static const std::string AI_TYPE_DEFAULT
Definition manager.hpp:126
game_info & get_ai_info()
Gets global AI-game info.
Definition manager.cpp:567
game_info ai_info_
Definition manager.hpp:408
events::generic_event gamestate_changed_
Definition manager.hpp:415
const ai::unit_advancements_aspect & get_advancement_aspect_for_side(side_number side)
Definition manager.cpp:572
bool add_ai_for_side_from_file(side_number side, const std::string &file, bool replace=true)
Adds active AI for specified side from file.
Definition manager.cpp:472
events::generic_event turn_started_
Definition manager.hpp:416
void remove_ai_for_side(side_number side)
Removes top-level AI from side.
Definition manager.cpp:499
void modify_active_ai_for_side(ai::side_number side, const config &cfg)
Modifies AI parameters for active AI of the given side.
Definition manager.cpp:522
int num_interact_
Definition manager.hpp:418
void play_turn(side_number side)
Plays a turn for the specified side using its active AI.
Definition manager.cpp:581
std::chrono::steady_clock::time_point last_interact_
Definition manager.hpp:417
void raise_map_changed()
Notifies all observers of 'ai_map_changed' event.
Definition manager.cpp:464
void raise_recruit_list_changed()
Notifies all observers of 'ai_recruit_list_changed' event.
Definition manager.cpp:460
void remove_turn_started_observer(events::observer *event_observer)
Deletes an observer of 'ai_turn_started' event.
Definition manager.cpp:419
ai::holder & get_active_ai_holder_for_side_dbg(side_number side)
Gets the active AI holder for debug purposes.
Definition manager.cpp:547
void raise_sync_network()
Notifies all observers of 'ai_sync_network' event.
Definition manager.cpp:444
events::generic_event tod_changed_
Definition manager.hpp:414
void remove_map_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_map_changed' event.
Definition manager.cpp:414
void add_tod_changed_observer(events::observer *event_observer)
Adds an observer of 'ai_tod_changed' event.
Definition manager.cpp:386
void remove_tod_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_tod_changed' event.
Definition manager.cpp:390
void add_observer(events::observer *event_observer)
Adds observer of game events.
Definition manager.cpp:360
void remove_recruit_list_changed_observer(events::observer *event_observer)
Deletes an observer of 'ai_recruit_list_changed' event.
Definition manager.cpp:409
virtual const unit_advancements_aspect & get_advancements() const override
Definition contexts.hpp:538
virtual void add_facet(const std::string &id, const config &cfg) const override
Definition contexts.hpp:568
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
child_itors child_range(std::string_view key)
Definition config.cpp:268
void clear_children(T... keys)
Definition config.hpp:601
void merge_with(const config &c)
Merge config 'c' into this config, overwriting this config's values.
Definition config.cpp:1097
virtual bool attach_handler(observer *obs)
virtual bool detach_handler(observer *obs)
virtual void notify_observers()
std::ostringstream wrapper.
Definition formatter.hpp:40
game_events::wml_event_pump & pump()
Definition manager.cpp:257
pump_result_t fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
Definition pump.cpp:399
A component of the AI framework.
Definitions for the interface to Wesnoth Markup Language (WML).
Managing the AIs configuration - headers.
Helper functions for the object which operates in the context of AI for specific side this is part of...
Default AI contexts.
AI Support engine - creating specific ai components from config.
LUA AI Support engine - creating specific ai components from config.
const config * cfg
Game information for the AI.
Standard logging facilities (interface).
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition actions.cpp:59
static lg::log_domain log_ai_mod("ai/mod")
static lg::log_domain log_ai_manager("ai/manager")
int side_number
Definition game_info.hpp:40
const bool & debug
::tod_manager * tod_manager
Definition resources.cpp:29
bool simulation
Definition resources.cpp:35
game_events::manager * game_events
Definition resources.cpp:24
std::string join(const Range &v, const std::string &s=",")
Generates a new string joining container items in a list.
Define the game's event mechanism.
All known AI parts.
static map_location::direction s