From 7ec9601acdafd1e440f4a6a757aea06c36eddf0f Mon Sep 17 00:00:00 2001 From: Arseniy Shestakov Date: Wed, 14 Sep 2016 03:44:35 +0300 Subject: [PATCH] VCAI: safety checks to avoid crashes with boat objects Probably we should rewrite boat-related code to make AI boat handling easier. --- AI/VCAI/VCAI.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 177257139..20621d34a 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -115,15 +115,16 @@ void VCAI::heroMoved(const TryMoveHero & details) NET_EVENT_HANDLER; validateObject(details.id); //enemy hero may have left visible area + auto hero = cb->getHero(details.id); cachedSectorMaps.clear(); + const int3 from = CGHeroInstance::convertPosition(details.start, false), + to = CGHeroInstance::convertPosition(details.end, false); + const CGObjectInstance *o1 = vstd::frontOrNull(cb->getVisitableObjs(from)), + *o2 = vstd::frontOrNull(cb->getVisitableObjs(to)); + if(details.result == TryMoveHero::TELEPORTATION) { - const int3 from = CGHeroInstance::convertPosition(details.start, false), - to = CGHeroInstance::convertPosition(details.end, false); - const CGObjectInstance *o1 = vstd::frontOrNull(cb->getVisitableObjs(from)), - *o2 = vstd::frontOrNull(cb->getVisitableObjs(to)); - auto t1 = dynamic_cast(o1); auto t2 = dynamic_cast(o2); if(t1 && t2) @@ -139,6 +140,17 @@ void VCAI::heroMoved(const TryMoveHero & details) } } } + else if(details.result == TryMoveHero::EMBARK && hero) + { + //make sure AI not attempt to visit used boat + validateObject(hero->boat); + } + else if(details.result == TryMoveHero::DISEMBARK && o1) + { + auto boat = dynamic_cast(o1); + if(boat) + addVisitableObj(boat); + } } void VCAI::stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute) @@ -405,6 +417,9 @@ void VCAI::objectRemoved(const CGObjectInstance *obj) { vstd::erase_if_present(visitableObjs, hero->boat); vstd::erase_if_present(alreadyVisited, hero->boat); + + for (auto h : cb->getHeroesInfo()) + unreserveObject(h, hero->boat); } }