From 18526e499a082d849295f0db93cdc9b5ea223df7 Mon Sep 17 00:00:00 2001 From: gfgtdf Date: Mon, 3 Sep 2018 22:23:55 +0200 Subject: [PATCH] fix crash in ai code when a side has multiple leaders see https://github.com/wesnoth/wesnoth/issues/3240 Just fixing the crash, not sure how the code should behave in this case, it would be nice if someone who knows more about the ai code would either implement that todo or remove the second warning. An alternative fix would be to move the 'calculate_moves' inside the ai_leaders loop. --- src/ai/default/ca.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ai/default/ca.cpp b/src/ai/default/ca.cpp index 41a6f8e62c25..4fb327bc1406 100644 --- a/src/ai/default/ca.cpp +++ b/src/ai/default/ca.cpp @@ -1617,6 +1617,11 @@ void leader_shares_keep_phase::execute() //check for each ai leader if he should move away from his keep for (unit_map::unit_iterator &ai_leader : ai_leaders) { + if(!ai_leader.valid()) { + //This can happen if wml killed or moved a leader during a movement events of another leader + WRN_AI_TESTING_AI_DEFAULT << "leader_shares_keep_phase: Leader vanished.\n"; + continue; + } //only if leader is on a keep const map_location &keep = ai_leader->get_location(); if ( !resources::gameboard->map().is_keep(keep) ) { @@ -1631,6 +1636,12 @@ void leader_shares_keep_phase::execute() //for each leader, check if he's allied and can reach our keep for(path_map::const_iterator i = possible_moves.begin(); i != possible_moves.end(); ++i){ const unit_map::const_iterator itor = resources::gameboard->units().find(i->first); + if(!itor.valid()) { + //This can happen if wml killed or moved a unit during a movement events of another leader + WRN_AI_TESTING_AI_DEFAULT << "leader_shares_keep_phase: Unit vanished.\n"; + continue; + } + team &leader_team = resources::gameboard->get_team(itor->side()); if(itor != resources::gameboard->units().end() && itor->can_recruit() && itor->side() != get_side() && (leader_team.total_income() + leader_team.gold() > leader_team.minimum_recruit_price())){ pathfind::paths::dest_vect::const_iterator tokeep = i->second.destinations.find(keep); @@ -1670,6 +1681,7 @@ void leader_shares_keep_phase::execute() }else{ ai_leader->set_goto(keep); } + //TODO: maybe we should we fix the entry in possible_moves for this move to avoid getting the 'Unit vanished' warning above. }else{ LOG_AI_TESTING_AI_DEFAULT << get_name() << "::execute not ok" << std::endl; }