mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-09 02:58:28 +00:00
various tweaks of ai handling of map changes
solve some problems which might arise if map changes in the middle of the turn thanks to WML events
This commit is contained in:
parent
8c157b38e7
commit
08ac3d103d
@ -21,6 +21,8 @@
|
||||
{FOREACH MOVE_UNIT_store unit}
|
||||
{VARIABLE_OP MOVE_UNIT_store[$unit].x add {X_OFFSET}}
|
||||
{VARIABLE_OP MOVE_UNIT_store[$unit].y add {Y_OFFSET}}
|
||||
{VARIABLE_OP MOVE_UNIT_store[$unit].goto_x add {X_OFFSET}}
|
||||
{VARIABLE_OP MOVE_UNIT_store[$unit].goto_y add {Y_OFFSET}}
|
||||
{NEXT unit}
|
||||
|
||||
{FOREACH villages village}
|
||||
|
@ -204,6 +204,7 @@ readonly_context_impl::readonly_context_impl(side_context &context, const config
|
||||
add_known_aspect("support_villages",support_villages_);
|
||||
add_known_aspect("village_value",village_value_);
|
||||
add_known_aspect("villages_per_scout",villages_per_scout_);
|
||||
keeps_.init(get_info().map);
|
||||
|
||||
}
|
||||
|
||||
@ -797,6 +798,12 @@ void readonly_context_impl::invalidate_keeps_cache() const
|
||||
}
|
||||
|
||||
|
||||
void keeps_cache::handle_generic_event(const std::string &/*event_name*/)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void readonly_context_impl::invalidate_move_maps() const
|
||||
{
|
||||
move_maps_valid_ = false;
|
||||
@ -806,18 +813,47 @@ void readonly_context_impl::invalidate_move_maps() const
|
||||
|
||||
const std::set<map_location>& readonly_context_impl::keeps() const
|
||||
{
|
||||
gamemap &map_ = get_info().map;
|
||||
return keeps_.get();
|
||||
}
|
||||
|
||||
|
||||
keeps_cache::keeps_cache()
|
||||
{
|
||||
ai::manager::add_turn_started_observer(this);
|
||||
ai::manager::add_map_changed_observer(this);
|
||||
}
|
||||
|
||||
|
||||
keeps_cache::~keeps_cache()
|
||||
{
|
||||
ai::manager::remove_turn_started_observer(this);
|
||||
ai::manager::remove_map_changed_observer(this);
|
||||
}
|
||||
|
||||
void keeps_cache::clear()
|
||||
{
|
||||
keeps_.clear();
|
||||
}
|
||||
|
||||
|
||||
void keeps_cache::init(gamemap &map)
|
||||
{
|
||||
map_ = ↦
|
||||
}
|
||||
|
||||
const std::set<map_location>& keeps_cache::get()
|
||||
{
|
||||
if(keeps_.empty()) {
|
||||
// Generate the list of keeps:
|
||||
// iterate over the entire map and find all keeps.
|
||||
for(size_t x = 0; x != size_t(map_.w()); ++x) {
|
||||
for(size_t y = 0; y != size_t(map_.h()); ++y) {
|
||||
for(size_t x = 0; x != size_t(map_->w()); ++x) {
|
||||
for(size_t y = 0; y != size_t(map_->h()); ++y) {
|
||||
const map_location loc(x,y);
|
||||
if(map_.is_keep(loc)) {
|
||||
if(map_->is_keep(loc)) {
|
||||
map_location adj[6];
|
||||
get_adjacent_tiles(loc,adj);
|
||||
for(size_t n = 0; n != 6; ++n) {
|
||||
if(map_.is_castle(adj[n])) {
|
||||
if(map_->is_castle(adj[n])) {
|
||||
keeps_.insert(loc);
|
||||
break;
|
||||
}
|
||||
|
@ -96,6 +96,20 @@ struct defensive_position {
|
||||
double vulnerability, support;
|
||||
};
|
||||
|
||||
// keeps cache
|
||||
class keeps_cache : public events::observer
|
||||
{
|
||||
public:
|
||||
keeps_cache();
|
||||
~keeps_cache();
|
||||
void handle_generic_event(const std::string& event_name);
|
||||
void clear();
|
||||
const std::set<map_location>& get();
|
||||
void init(gamemap &map);
|
||||
private:
|
||||
gamemap *map_;
|
||||
std::set<map_location> keeps_;
|
||||
};
|
||||
|
||||
// side context
|
||||
|
||||
@ -1323,7 +1337,7 @@ private:
|
||||
mutable move_map enemy_srcdst_;
|
||||
aspect_type< std::string >::typesafe_ptr grouping_;
|
||||
std::vector< goal_ptr > goals_;
|
||||
mutable std::set<map_location> keeps_;
|
||||
mutable keeps_cache keeps_;
|
||||
aspect_type<double>::typesafe_ptr leader_aggression_;
|
||||
aspect_type< config >::typesafe_ptr leader_goal_;
|
||||
aspect_type< double >::typesafe_ptr leader_value_;
|
||||
|
@ -2010,12 +2010,18 @@ void ai_default::move_leader_after_recruit()
|
||||
leader_paths.destinations.contains(adj[n]) &&
|
||||
!is_accessible(adj[n], get_enemy_dstsrc()))
|
||||
{
|
||||
move_result_ptr move_res = check_move_action(keep,adj[n],true);
|
||||
if (!move_res->is_ok())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool gamestate_changed = false;
|
||||
map_location new_loc = move_unit(keep,adj[n],gamestate_changed);
|
||||
move_res->execute();
|
||||
gamestate_changed |= move_res->is_gamestate_changed();
|
||||
if (!gamestate_changed) {
|
||||
ERR_AI << "moving leader after recruit failed" << std::endl;
|
||||
}
|
||||
if (new_loc!=keep) {
|
||||
if (!move_res->is_ok()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +311,7 @@ events::generic_event manager::sync_network_("ai_sync_network");
|
||||
events::generic_event manager::gamestate_changed_("ai_gamestate_changed");
|
||||
events::generic_event manager::turn_started_("ai_turn_started");
|
||||
events::generic_event manager::recruit_list_changed_("ai_recruit_list_changed");
|
||||
events::generic_event manager::map_changed_("ai_map_changed");
|
||||
int manager::last_interact_ = 0;
|
||||
int manager::num_interact_ = 0;
|
||||
|
||||
@ -352,16 +353,24 @@ void manager::remove_observer(events::observer* event_observer){
|
||||
void manager::add_gamestate_observer( events::observer* event_observer){
|
||||
gamestate_changed_.attach_handler(event_observer);
|
||||
turn_started_.attach_handler(event_observer);
|
||||
map_changed_.attach_handler(event_observer);
|
||||
}
|
||||
|
||||
|
||||
void manager::remove_gamestate_observer(events::observer* event_observer){
|
||||
gamestate_changed_.detach_handler(event_observer);
|
||||
turn_started_.detach_handler(event_observer);
|
||||
map_changed_.detach_handler(event_observer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void manager::add_map_changed_observer( events::observer* event_observer )
|
||||
{
|
||||
map_changed_.attach_handler(event_observer);
|
||||
}
|
||||
|
||||
|
||||
void manager::add_recruit_list_changed_observer( events::observer* event_observer )
|
||||
{
|
||||
recruit_list_changed_.attach_handler(event_observer);
|
||||
@ -398,6 +407,12 @@ void manager::remove_user_interact_observer( events::observer* event_observer )
|
||||
}
|
||||
|
||||
|
||||
void manager::remove_map_changed_observer( events::observer* event_observer )
|
||||
{
|
||||
map_changed_.detach_handler(event_observer);
|
||||
}
|
||||
|
||||
|
||||
void manager::delete_sync_network_observer( events::observer* event_observer )
|
||||
{
|
||||
sync_network_.detach_handler(event_observer);
|
||||
@ -443,6 +458,11 @@ void manager::raise_recruit_list_changed() {
|
||||
}
|
||||
|
||||
|
||||
void manager::raise_map_changed() {
|
||||
map_changed_.notify_observers();
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// EVALUATION
|
||||
// =======================================================================
|
||||
|
@ -210,6 +210,17 @@ public:
|
||||
static void raise_turn_started();
|
||||
|
||||
|
||||
/**
|
||||
* Notifies all observers of 'ai_map_changed' event.
|
||||
*/
|
||||
static void raise_map_changed();
|
||||
|
||||
|
||||
/**
|
||||
* Adds an observer of 'ai_map_changed' event.
|
||||
*/
|
||||
static void add_map_changed_observer( events::observer* event_observer );
|
||||
|
||||
|
||||
/**
|
||||
* Adds an observer of 'ai_recruit_list_changed' event.
|
||||
@ -235,6 +246,12 @@ public:
|
||||
static void add_turn_started_observer( events::observer* event_observer );
|
||||
|
||||
|
||||
/**
|
||||
* Deletes an observer of 'ai_map_changed' event.
|
||||
*/
|
||||
static void remove_map_changed_observer( events::observer* event_observer );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deletes an observer of 'ai_recruit_list_changed' event.
|
||||
@ -451,6 +468,7 @@ private:
|
||||
static long history_item_counter_;
|
||||
static game_info *ai_info_;
|
||||
|
||||
static events::generic_event map_changed_;
|
||||
static events::generic_event recruit_list_changed_;
|
||||
static events::generic_event user_interact_;
|
||||
static events::generic_event sync_network_;
|
||||
|
@ -3446,6 +3446,7 @@ WML_HANDLER_FUNCTION(replace_map, /*event_info*/, cfg)
|
||||
*game_map = map;
|
||||
resources::screen->reload_map();
|
||||
screen_needs_rebuild = true;
|
||||
ai::manager::raise_map_changed();
|
||||
}
|
||||
|
||||
WML_HANDLER_FUNCTION(unit_worth, /*event_info*/, cfg)
|
||||
|
Loading…
x
Reference in New Issue
Block a user