From 6a9e91b99b59b9804138f6c18364ef556ce23533 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Fri, 20 Jul 2018 21:14:57 +0200 Subject: [PATCH 01/19] Added basic interface for AI to evaluate objects --- AI/VCAI/MapObjectsEvaluator.cpp | 40 +++++++++++++++++++++++++++++++++ AI/VCAI/MapObjectsEvaluator.h | 21 +++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 AI/VCAI/MapObjectsEvaluator.cpp create mode 100644 AI/VCAI/MapObjectsEvaluator.h diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp new file mode 100644 index 000000000..f552b51f2 --- /dev/null +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -0,0 +1,40 @@ +#include "StdInc.h" +#include "MapObjectsEvaluator.h" +#include "../../lib/GameConstants.h" +#include "../../lib/VCMI_Lib.h" +#include "../../lib/mapObjects/CObjectClassesHandler.h" + +std::map> MapObjectsEvaluator::objectDatabase = std::map>(); + +void MapObjectsEvaluator::init() +{ + for(auto primaryID : VLC->objtypeh->knownObjects()) + { + auto newObject = std::pair>(primaryID, std::map()); + for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID)) + { + auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); + if(!handler->isStaticObject() && handler->getRMGInfo().value) + { + newObject.second.insert(std::pair(secondaryID, handler->getRMGInfo().value)); + } + } + objectDatabase.insert(newObject); + } +} + +boost::optional MapObjectsEvaluator::getObjectValue(int primaryID, int secondaryID) +{ + auto object = objectDatabase.find(primaryID); + if(object != objectDatabase.end()) + { + auto subobjects = (*object).second; + auto desiredObject = subobjects.find(secondaryID); + if(desiredObject != subobjects.end()) + { + return (*desiredObject).second; + } + } + logGlobal->trace("Unknown object for AI, ID: " + std::to_string(primaryID) + " SubID: " + std::to_string(secondaryID)); + return boost::optional(); +} diff --git a/AI/VCAI/MapObjectsEvaluator.h b/AI/VCAI/MapObjectsEvaluator.h new file mode 100644 index 000000000..fd7dad6ff --- /dev/null +++ b/AI/VCAI/MapObjectsEvaluator.h @@ -0,0 +1,21 @@ +/* +* MapObjectsEvaluator.h, part of VCMI engine +* +* Authors: listed in file AUTHORS in main folder +* +* License: GNU General Public License v2.0 or later +* Full text of license available in license.txt file, in main folder +* +*/ +#pragma once + +class MapObjectsEvaluator +{ +private: + static std::map> objectDatabase; //each object contains map of subobjects with their values + +public: + static void init(); + static boost::optional getObjectValue(int primaryID, int secondaryID); +}; + From 36f501ebf32db3cbe8ab28525aa30fd6e3174566 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sat, 21 Jul 2018 11:28:55 +0200 Subject: [PATCH 02/19] Implement MapObjectsEvaluator as singleton utility --- AI/VCAI/MapObjectsEvaluator.cpp | 12 +++++++++--- AI/VCAI/MapObjectsEvaluator.h | 8 +++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index f552b51f2..b18fe698d 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -4,9 +4,15 @@ #include "../../lib/VCMI_Lib.h" #include "../../lib/mapObjects/CObjectClassesHandler.h" -std::map> MapObjectsEvaluator::objectDatabase = std::map>(); +MapObjectsEvaluator & MapObjectsEvaluator::getInstance() +{ + if(singletonInstance == nullptr) + singletonInstance.reset(new MapObjectsEvaluator()); -void MapObjectsEvaluator::init() + return *(singletonInstance.get()); +} + +MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::map>()) { for(auto primaryID : VLC->objtypeh->knownObjects()) { @@ -35,6 +41,6 @@ boost::optional MapObjectsEvaluator::getObjectValue(int primaryID, int seco return (*desiredObject).second; } } - logGlobal->trace("Unknown object for AI, ID: " + std::to_string(primaryID) + " SubID: " + std::to_string(secondaryID)); + logGlobal->trace("Unknown object for AI, ID: " + std::to_string(primaryID) + ", SubID: " + std::to_string(secondaryID)); return boost::optional(); } diff --git a/AI/VCAI/MapObjectsEvaluator.h b/AI/VCAI/MapObjectsEvaluator.h index fd7dad6ff..1888080fd 100644 --- a/AI/VCAI/MapObjectsEvaluator.h +++ b/AI/VCAI/MapObjectsEvaluator.h @@ -12,10 +12,12 @@ class MapObjectsEvaluator { private: - static std::map> objectDatabase; //each object contains map of subobjects with their values + std::map> objectDatabase; //each object contains map of subobjects with their values (std::map>) + static std::unique_ptr singletonInstance; public: - static void init(); - static boost::optional getObjectValue(int primaryID, int secondaryID); + MapObjectsEvaluator(); + static MapObjectsEvaluator & getInstance(); + boost::optional getObjectValue(int primaryID, int secondaryID); }; From 82da82fbeb1e2c7459d210aca9c2eaed3f71ad15 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sat, 21 Jul 2018 14:30:38 +0200 Subject: [PATCH 03/19] Polish object database, add data operations --- AI/VCAI/MapObjectsEvaluator.cpp | 36 ++++++++++++++++++++------------- AI/VCAI/MapObjectsEvaluator.h | 28 ++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index b18fe698d..7592f9467 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -12,35 +12,43 @@ MapObjectsEvaluator & MapObjectsEvaluator::getInstance() return *(singletonInstance.get()); } -MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::map>()) +MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::map()) { for(auto primaryID : VLC->objtypeh->knownObjects()) { - auto newObject = std::pair>(primaryID, std::map()); for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID)) { auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); if(!handler->isStaticObject() && handler->getRMGInfo().value) { - newObject.second.insert(std::pair(secondaryID, handler->getRMGInfo().value)); + AiMapObjectID newObjectType = AiMapObjectID(primaryID, secondaryID); + std::pair newObject = { newObjectType, handler->getRMGInfo().value }; + objectDatabase.insert(newObject); } - } - objectDatabase.insert(newObject); + } } } boost::optional MapObjectsEvaluator::getObjectValue(int primaryID, int secondaryID) { - auto object = objectDatabase.find(primaryID); + AiMapObjectID internalIdentifier = AiMapObjectID(primaryID, secondaryID); + auto object = objectDatabase.find(internalIdentifier); if(object != objectDatabase.end()) - { - auto subobjects = (*object).second; - auto desiredObject = subobjects.find(secondaryID); - if(desiredObject != subobjects.end()) - { - return (*desiredObject).second; - } - } + return object->second; + logGlobal->trace("Unknown object for AI, ID: " + std::to_string(primaryID) + ", SubID: " + std::to_string(secondaryID)); return boost::optional(); } + +void MapObjectsEvaluator::addObjectData(int primaryID, int secondaryID, int value) //by current design it updates value if already in AI database +{ + AiMapObjectID internalIdentifier = AiMapObjectID(primaryID, secondaryID); + objectDatabase.insert_or_assign(internalIdentifier, value); +} + +void MapObjectsEvaluator::removeObjectData(int primaryID, int secondaryID, int value) +{ + AiMapObjectID internalIdentifier = AiMapObjectID(primaryID, secondaryID); + vstd::erase_if_present(objectDatabase, internalIdentifier); +} + diff --git a/AI/VCAI/MapObjectsEvaluator.h b/AI/VCAI/MapObjectsEvaluator.h index 1888080fd..03886e12a 100644 --- a/AI/VCAI/MapObjectsEvaluator.h +++ b/AI/VCAI/MapObjectsEvaluator.h @@ -9,15 +9,41 @@ */ #pragma once +struct AiMapObjectID +{ + int primaryID; + int secondaryID; + + AiMapObjectID(int primID, int secID) : primaryID(primID), secondaryID(secID) {}; +}; + +inline bool operator<(const AiMapObjectID& obj1, const AiMapObjectID& obj2) +{ + if(obj1.primaryID != obj2.primaryID) + return obj1.primaryID < obj2.primaryID; + else + return obj1.secondaryID < obj2.secondaryID; +} + +inline bool operator==(const AiMapObjectID& obj1, const AiMapObjectID& obj2) +{ + if(obj1.primaryID == obj2.primaryID) + return obj1.secondaryID == obj2.secondaryID; + + return false; +} + class MapObjectsEvaluator { private: - std::map> objectDatabase; //each object contains map of subobjects with their values (std::map>) + std::map objectDatabase; //value for each object type static std::unique_ptr singletonInstance; public: MapObjectsEvaluator(); static MapObjectsEvaluator & getInstance(); boost::optional getObjectValue(int primaryID, int secondaryID); + void addObjectData(int primaryID, int secondaryID, int value); + void removeObjectData(int primaryID, int secondaryID, int value); }; From 08a66abdccc6160c3b79dd317d73c69ec5ed4c2c Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sat, 21 Jul 2018 15:42:17 +0200 Subject: [PATCH 04/19] Singleton implementation fix --- AI/VCAI/MapObjectsEvaluator.cpp | 1 + AI/VCAI/MapObjectsEvaluator.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index 7592f9467..d46323a8a 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -6,6 +6,7 @@ MapObjectsEvaluator & MapObjectsEvaluator::getInstance() { + static std::unique_ptr singletonInstance; if(singletonInstance == nullptr) singletonInstance.reset(new MapObjectsEvaluator()); diff --git a/AI/VCAI/MapObjectsEvaluator.h b/AI/VCAI/MapObjectsEvaluator.h index 03886e12a..4c228f03c 100644 --- a/AI/VCAI/MapObjectsEvaluator.h +++ b/AI/VCAI/MapObjectsEvaluator.h @@ -37,7 +37,6 @@ class MapObjectsEvaluator { private: std::map objectDatabase; //value for each object type - static std::unique_ptr singletonInstance; public: MapObjectsEvaluator(); From 2c1d91e2ffd7d50b76d575b7b932c83036f135bd Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sun, 22 Jul 2018 18:12:29 +0200 Subject: [PATCH 05/19] Move object ID struct to lib --- AI/VCAI/MapObjectsEvaluator.cpp | 1 - AI/VCAI/MapObjectsEvaluator.h | 25 +----------------------- lib/mapObjects/CObjectClassesHandler.cpp | 5 +++++ lib/mapObjects/CObjectClassesHandler.h | 25 ++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index d46323a8a..4568e0ed8 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -2,7 +2,6 @@ #include "MapObjectsEvaluator.h" #include "../../lib/GameConstants.h" #include "../../lib/VCMI_Lib.h" -#include "../../lib/mapObjects/CObjectClassesHandler.h" MapObjectsEvaluator & MapObjectsEvaluator::getInstance() { diff --git a/AI/VCAI/MapObjectsEvaluator.h b/AI/VCAI/MapObjectsEvaluator.h index 4c228f03c..9c9a52ea8 100644 --- a/AI/VCAI/MapObjectsEvaluator.h +++ b/AI/VCAI/MapObjectsEvaluator.h @@ -8,30 +8,7 @@ * */ #pragma once - -struct AiMapObjectID -{ - int primaryID; - int secondaryID; - - AiMapObjectID(int primID, int secID) : primaryID(primID), secondaryID(secID) {}; -}; - -inline bool operator<(const AiMapObjectID& obj1, const AiMapObjectID& obj2) -{ - if(obj1.primaryID != obj2.primaryID) - return obj1.primaryID < obj2.primaryID; - else - return obj1.secondaryID < obj2.secondaryID; -} - -inline bool operator==(const AiMapObjectID& obj1, const AiMapObjectID& obj2) -{ - if(obj1.primaryID == obj2.primaryID) - return obj1.secondaryID == obj2.secondaryID; - - return false; -} +#include "../../lib/mapObjects/CObjectClassesHandler.h" class MapObjectsEvaluator { diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index 8f43a808f..6fc0d2c8b 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -285,6 +285,11 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(std::string type, std::s throw std::runtime_error("Object type handler not found"); } +TObjectTypeHandler CObjectClassesHandler::getHandlerFor(AiMapObjectID compoundIdentifier) const +{ + return getHandlerFor(compoundIdentifier.primaryID, compoundIdentifier.secondaryID); +} + std::set CObjectClassesHandler::knownObjects() const { std::set ret; diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index c94732f2b..428259d18 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -65,6 +65,30 @@ struct DLL_LINKAGE RandomMapInfo } }; +struct DLL_LINKAGE AiMapObjectID +{ + si32 primaryID; + si32 secondaryID; + + AiMapObjectID(si32 primID, si32 secID) : primaryID(primID), secondaryID(secID) {}; + + bool operator<(const AiMapObjectID& other) + { + if(this->primaryID != other.primaryID) + return this->primaryID < other.primaryID; + else + return this->secondaryID < other.secondaryID; + } + + bool operator==(const AiMapObjectID& other) + { + if(this->primaryID == other.primaryID) + return this->secondaryID == other.secondaryID; + + return false; + } +}; + class DLL_LINKAGE IObjectInfo { public: @@ -274,6 +298,7 @@ public: /// returns handler for specified object (ID-based). ObjectHandler keeps ownership TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const; TObjectTypeHandler getHandlerFor(std::string type, std::string subtype) const; + TObjectTypeHandler getHandlerFor(AiMapObjectID compoundIdentifier) const; std::string getObjectName(si32 type) const; std::string getObjectName(si32 type, si32 subtype) const; From 21c1f47a7876af6db8947ae8a8827179b02e63a6 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sun, 22 Jul 2018 19:12:11 +0200 Subject: [PATCH 06/19] Fixes --- AI/VCAI/MapObjectsEvaluator.cpp | 14 +++++++------- AI/VCAI/MapObjectsEvaluator.h | 4 ++-- lib/mapObjects/CObjectClassesHandler.cpp | 2 +- lib/mapObjects/CObjectClassesHandler.h | 15 ++++++--------- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index 4568e0ed8..c82c890d8 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -12,7 +12,7 @@ MapObjectsEvaluator & MapObjectsEvaluator::getInstance() return *(singletonInstance.get()); } -MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::map()) +MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::map()) { for(auto primaryID : VLC->objtypeh->knownObjects()) { @@ -21,17 +21,17 @@ MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::mapobjtypeh->getHandlerFor(primaryID, secondaryID); if(!handler->isStaticObject() && handler->getRMGInfo().value) { - AiMapObjectID newObjectType = AiMapObjectID(primaryID, secondaryID); - std::pair newObject = { newObjectType, handler->getRMGInfo().value }; + CompoundMapObjectID newObjectType = CompoundMapObjectID(primaryID, secondaryID); + std::pair newObject = { newObjectType, handler->getRMGInfo().value }; objectDatabase.insert(newObject); } } } } -boost::optional MapObjectsEvaluator::getObjectValue(int primaryID, int secondaryID) +boost::optional MapObjectsEvaluator::getObjectValue(int primaryID, int secondaryID) const { - AiMapObjectID internalIdentifier = AiMapObjectID(primaryID, secondaryID); + CompoundMapObjectID internalIdentifier = CompoundMapObjectID(primaryID, secondaryID); auto object = objectDatabase.find(internalIdentifier); if(object != objectDatabase.end()) return object->second; @@ -42,13 +42,13 @@ boost::optional MapObjectsEvaluator::getObjectValue(int primaryID, int seco void MapObjectsEvaluator::addObjectData(int primaryID, int secondaryID, int value) //by current design it updates value if already in AI database { - AiMapObjectID internalIdentifier = AiMapObjectID(primaryID, secondaryID); + CompoundMapObjectID internalIdentifier = CompoundMapObjectID(primaryID, secondaryID); objectDatabase.insert_or_assign(internalIdentifier, value); } void MapObjectsEvaluator::removeObjectData(int primaryID, int secondaryID, int value) { - AiMapObjectID internalIdentifier = AiMapObjectID(primaryID, secondaryID); + CompoundMapObjectID internalIdentifier = CompoundMapObjectID(primaryID, secondaryID); vstd::erase_if_present(objectDatabase, internalIdentifier); } diff --git a/AI/VCAI/MapObjectsEvaluator.h b/AI/VCAI/MapObjectsEvaluator.h index 9c9a52ea8..a7d625244 100644 --- a/AI/VCAI/MapObjectsEvaluator.h +++ b/AI/VCAI/MapObjectsEvaluator.h @@ -13,12 +13,12 @@ class MapObjectsEvaluator { private: - std::map objectDatabase; //value for each object type + std::map objectDatabase; //value for each object type public: MapObjectsEvaluator(); static MapObjectsEvaluator & getInstance(); - boost::optional getObjectValue(int primaryID, int secondaryID); + boost::optional getObjectValue(int primaryID, int secondaryID) const; void addObjectData(int primaryID, int secondaryID, int value); void removeObjectData(int primaryID, int secondaryID, int value); }; diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index 6fc0d2c8b..d5edc4a1c 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -285,7 +285,7 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(std::string type, std::s throw std::runtime_error("Object type handler not found"); } -TObjectTypeHandler CObjectClassesHandler::getHandlerFor(AiMapObjectID compoundIdentifier) const +TObjectTypeHandler CObjectClassesHandler::getHandlerFor(CompoundMapObjectID compoundIdentifier) const { return getHandlerFor(compoundIdentifier.primaryID, compoundIdentifier.secondaryID); } diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index 428259d18..82fa44cdb 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -65,22 +65,19 @@ struct DLL_LINKAGE RandomMapInfo } }; -struct DLL_LINKAGE AiMapObjectID +struct DLL_LINKAGE CompoundMapObjectID { si32 primaryID; si32 secondaryID; - AiMapObjectID(si32 primID, si32 secID) : primaryID(primID), secondaryID(secID) {}; + CompoundMapObjectID(si32 primID, si32 secID) : primaryID(primID), secondaryID(secID) {}; - bool operator<(const AiMapObjectID& other) + bool operator<(const CompoundMapObjectID& other) const { - if(this->primaryID != other.primaryID) - return this->primaryID < other.primaryID; - else - return this->secondaryID < other.secondaryID; + return (this->primaryID == other.primaryID) && (this->secondaryID == other.secondaryID); } - bool operator==(const AiMapObjectID& other) + bool operator==(const CompoundMapObjectID& other) const { if(this->primaryID == other.primaryID) return this->secondaryID == other.secondaryID; @@ -298,7 +295,7 @@ public: /// returns handler for specified object (ID-based). ObjectHandler keeps ownership TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const; TObjectTypeHandler getHandlerFor(std::string type, std::string subtype) const; - TObjectTypeHandler getHandlerFor(AiMapObjectID compoundIdentifier) const; + TObjectTypeHandler getHandlerFor(CompoundMapObjectID compoundIdentifier) const; std::string getObjectName(si32 type) const; std::string getObjectName(si32 type, si32 subtype) const; From 1a78ea15bb517f29e3f48256be68f00a576d8621 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sun, 22 Jul 2018 19:53:06 +0200 Subject: [PATCH 07/19] Tweaks --- AI/VCAI/MapObjectsEvaluator.cpp | 8 +++----- AI/VCAI/MapObjectsEvaluator.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index c82c890d8..740174a6a 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -12,7 +12,7 @@ MapObjectsEvaluator & MapObjectsEvaluator::getInstance() return *(singletonInstance.get()); } -MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::map()) +MapObjectsEvaluator::MapObjectsEvaluator() { for(auto primaryID : VLC->objtypeh->knownObjects()) { @@ -21,9 +21,7 @@ MapObjectsEvaluator::MapObjectsEvaluator() : objectDatabase(std::mapobjtypeh->getHandlerFor(primaryID, secondaryID); if(!handler->isStaticObject() && handler->getRMGInfo().value) { - CompoundMapObjectID newObjectType = CompoundMapObjectID(primaryID, secondaryID); - std::pair newObject = { newObjectType, handler->getRMGInfo().value }; - objectDatabase.insert(newObject); + objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = handler->getRMGInfo().value; } } } @@ -46,7 +44,7 @@ void MapObjectsEvaluator::addObjectData(int primaryID, int secondaryID, int valu objectDatabase.insert_or_assign(internalIdentifier, value); } -void MapObjectsEvaluator::removeObjectData(int primaryID, int secondaryID, int value) +void MapObjectsEvaluator::removeObjectData(int primaryID, int secondaryID) { CompoundMapObjectID internalIdentifier = CompoundMapObjectID(primaryID, secondaryID); vstd::erase_if_present(objectDatabase, internalIdentifier); diff --git a/AI/VCAI/MapObjectsEvaluator.h b/AI/VCAI/MapObjectsEvaluator.h index a7d625244..bdee725b6 100644 --- a/AI/VCAI/MapObjectsEvaluator.h +++ b/AI/VCAI/MapObjectsEvaluator.h @@ -20,6 +20,6 @@ public: static MapObjectsEvaluator & getInstance(); boost::optional getObjectValue(int primaryID, int secondaryID) const; void addObjectData(int primaryID, int secondaryID, int value); - void removeObjectData(int primaryID, int secondaryID, int value); + void removeObjectData(int primaryID, int secondaryID); }; From 13cca972d67f2f9973f9cdcf1cd663d1aa4841ad Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 23 Jul 2018 19:47:07 +0200 Subject: [PATCH 08/19] Add visual studio file changes in advance --- AI/VCAI/VCAI.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AI/VCAI/VCAI.vcxproj b/AI/VCAI/VCAI.vcxproj index 2069fb806..72b355308 100644 --- a/AI/VCAI/VCAI.vcxproj +++ b/AI/VCAI/VCAI.vcxproj @@ -141,6 +141,7 @@ + Create Create @@ -153,6 +154,7 @@ + From 615df6203db0177ab6e17aab2cbc9d1c35ad6398 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Thu, 26 Jul 2018 16:43:40 +0200 Subject: [PATCH 09/19] Oprator overload correction... --- lib/mapObjects/CObjectClassesHandler.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index 82fa44cdb..d23fdb033 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -74,15 +74,15 @@ struct DLL_LINKAGE CompoundMapObjectID bool operator<(const CompoundMapObjectID& other) const { - return (this->primaryID == other.primaryID) && (this->secondaryID == other.secondaryID); + if(this->primaryID != other.primaryID) + return this->primaryID < other.primaryID; + else + return this->secondaryID < other.secondaryID; } bool operator==(const CompoundMapObjectID& other) const { - if(this->primaryID == other.primaryID) - return this->secondaryID == other.secondaryID; - - return false; + return (this->primaryID == other.primaryID) && (this->secondaryID == other.secondaryID); } }; From 27541a72f52d8a0a3b5c9382518175abcb9b1613 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Fri, 27 Jul 2018 02:21:51 +0200 Subject: [PATCH 10/19] Extract FuzzyHelper distance calculation --- AI/VCAI/Fuzzy.cpp | 29 +++++++++++++++-------------- AI/VCAI/Fuzzy.h | 2 ++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/AI/VCAI/Fuzzy.cpp b/AI/VCAI/Fuzzy.cpp index 87750a443..e35c3747f 100644 --- a/AI/VCAI/Fuzzy.cpp +++ b/AI/VCAI/Fuzzy.cpp @@ -199,6 +199,20 @@ void FuzzyHelper::initTacticalAdvantage() } } +float FuzzyHelper::calculateTurnDistanceInputValue(const CGHeroInstance * h, int3 tile) const +{ + float turns = 0.0f; + float distance = CPathfinderHelper::getMovementCost(h, tile); + if(distance) + { + if(distance < h->movement) //we can move there within one turn + turns = (fl::scalar)distance / h->movement; + else + turns = 1 + (fl::scalar)(distance - h->movement) / h->maxMovePoints(true); //bool on land? + } + return turns; +} + ui64 FuzzyHelper::estimateBankDanger(const CBank * bank) { //this one is not fuzzy anymore, just calculate weighted average @@ -420,20 +434,7 @@ float FuzzyHelper::evaluate(Goals::VisitTile & g) return 0; //assert(cb->isInTheMap(g.tile)); - float turns = 0; - float distance = CPathfinderHelper::getMovementCost(g.hero.h, g.tile); - if(!distance) //we stand on that tile - { - turns = 0; - } - else - { - if(distance < g.hero->movement) //we can move there within one turn - turns = (fl::scalar)distance / g.hero->movement; - else - turns = 1 + (fl::scalar)(distance - g.hero->movement) / g.hero->maxMovePoints(true); //bool on land? - } - + float turns = calculateTurnDistanceInputValue(g.hero.h, g.tile); float missionImportance = 0; if(vstd::contains(ai->lockedHeroes, g.hero)) missionImportance = ai->lockedHeroes[g.hero]->priority; diff --git a/AI/VCAI/Fuzzy.h b/AI/VCAI/Fuzzy.h index 6e4f4d27b..0668b55d0 100644 --- a/AI/VCAI/Fuzzy.h +++ b/AI/VCAI/Fuzzy.h @@ -56,6 +56,8 @@ class FuzzyHelper } vt; +private: + float calculateTurnDistanceInputValue(const CGHeroInstance * h, int3 tile) const; public: enum RuleBlocks {BANK_DANGER, TACTICAL_ADVANTAGE, VISIT_TILE}; From df00ced2042d5680ed7beeabbcf2434798ea1239 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Fri, 27 Jul 2018 02:28:12 +0200 Subject: [PATCH 11/19] Create fuzzy logic map object evaluation fundamentals --- AI/VCAI/Fuzzy.cpp | 91 +++++++++++++++++++++++++++++++++ AI/VCAI/Fuzzy.h | 12 ++++- AI/VCAI/MapObjectsEvaluator.cpp | 2 +- AI/VCAI/VCAI.cpp | 7 ++- 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/AI/VCAI/Fuzzy.cpp b/AI/VCAI/Fuzzy.cpp index e35c3747f..e37c050b6 100644 --- a/AI/VCAI/Fuzzy.cpp +++ b/AI/VCAI/Fuzzy.cpp @@ -19,6 +19,7 @@ #include "../../lib/VCMI_Lib.h" #include "../../CCallback.h" #include "VCAI.h" +#include "MapObjectsEvaluator.h" #define MIN_AI_STRENGHT (0.5f) //lower when combat AI gets smarter #define UNGUARDED_OBJECT (100.0f) //we consider unguarded objects 100 times weaker than us @@ -97,6 +98,8 @@ FuzzyHelper::FuzzyHelper() ta.configure(); initVisitTile(); vt.configure(); + initWanderTarget(); + wanderTarget.configure(); } @@ -286,6 +289,38 @@ float FuzzyHelper::getTacticalAdvantage(const CArmedInstance * we, const CArmedI return output; } +float FuzzyHelper::getWanderTargetObjectValue(const CGHeroInstance & h, const ObjectIdRef & obj) +{ + float distFromObject = calculateTurnDistanceInputValue(&h, obj->pos); + boost::optional objValueKnownByAI = MapObjectsEvaluator::getInstance().getObjectValue(obj->ID, obj->subID); + int objValue = 0; + + if(objValueKnownByAI.is_initialized()) + { + objValue = objValueKnownByAI.value(); + } + else + { + MapObjectsEvaluator::getInstance().addObjectData(obj->ID, obj->subID, 0); + logGlobal->warn("AI met object type it doesn't know - ID: " + std::to_string(obj->ID) + ", subID: " + std::to_string(obj->subID) + " - adding to database with value " + std::to_string(objValue)); + } + + float output = -1.0f; + try + { + wanderTarget.distance->setValue(distFromObject); + wanderTarget.objectValue->setValue(objValue); + wanderTarget.engine.process(); + output = wanderTarget.visitGain->getValue(); + } + catch (fl::Exception & fe) + { + logAi->error("evaluate getWanderTargetObjectValue: %s", fe.getWhat()); + } + assert(output >= 0.0f); + return output; +} + FuzzyHelper::TacticalAdvantage::~TacticalAdvantage() { //TODO: smart pointers? @@ -427,6 +462,55 @@ void FuzzyHelper::initVisitTile() } } +void FuzzyHelper::initWanderTarget() +{ + try + { + wanderTarget.distance = new fl::InputVariable("distance"); //distance on map from object + wanderTarget.objectValue = new fl::InputVariable("objectValue"); //value of that object type known by AI + wanderTarget.visitGain = new fl::OutputVariable("visitGain"); + wanderTarget.visitGain->setMinimum(0); + wanderTarget.visitGain->setMaximum(10); + + wanderTarget.engine.addInputVariable(wanderTarget.distance); + wanderTarget.engine.addInputVariable(wanderTarget.objectValue); + wanderTarget.engine.addOutputVariable(wanderTarget.visitGain); + + //for now distance variable same as in as VisitTile + wanderTarget.distance->addTerm(new fl::Ramp("SHORT", 0.5, 0)); + wanderTarget.distance->addTerm(new fl::Triangle("MEDIUM", 0.1, 0.8)); + wanderTarget.distance->addTerm(new fl::Ramp("LONG", 0.5, 3)); + wanderTarget.distance->setRange(0, 3.0); + + //objectValue ranges are based on checking RMG priorities of some objects and trying to guess sane value ranges + wanderTarget.objectValue->addTerm(new fl::Ramp("LOW", 3000, 0)); //I have feeling that concave shape might work well instead of ramp for objectValue FL terms + wanderTarget.objectValue->addTerm(new fl::Triangle("MEDIUM", 2500, 6000)); + wanderTarget.objectValue->addTerm(new fl::Ramp("HIGH", 5000, 20000)); + wanderTarget.objectValue->setRange(0, 20000); //relic artifact value is border value by design, even better things are scaled down. + + wanderTarget.visitGain->addTerm(new fl::Ramp("LOW", 5, 0)); + wanderTarget.visitGain->addTerm(new fl::Triangle("MEDIUM", 4, 6)); + wanderTarget.visitGain->addTerm(new fl::Ramp("LOW", 5, 10)); + wanderTarget.visitGain->setRange(0, 10); + + wanderTarget.addRule("if distance is LONG and objectValue is HIGH then visitGain is MEDIUM"); + wanderTarget.addRule("if distance is MEDIUM and objectValue is HIGH then visitGain is somewhat HIGH"); + wanderTarget.addRule("if distance is SHORT and objectValue is HIGH then visitGain is HIGH"); + + wanderTarget.addRule("if distance is LONG and objectValue is MEDIUM then visitGain is somewhat LOW"); + wanderTarget.addRule("if distance is MEDIUM and objectValue is MEDIUM then visitGain is MEDIUM"); + wanderTarget.addRule("if distance is SHORT and objectValue is MEDIUM then visitGain is somewhat HIGH"); + + wanderTarget.addRule("if distance is LONG and objectValue is LOW then visitGain is very LOW"); + wanderTarget.addRule("if distance is MEDIUM and objectValue is LOW then visitGain is LOW"); + wanderTarget.addRule("if distance is SHORT and objectValue is LOW then visitGain is MEDIUM"); + } + catch(fl::Exception & fe) + { + logAi->error("FindWanderTarget: %s", fe.getWhat()); + } +} + float FuzzyHelper::evaluate(Goals::VisitTile & g) { //we assume that hero is already set and we want to choose most suitable one for the mission @@ -546,3 +630,10 @@ void FuzzyHelper::setPriority(Goals::TSubgoal & g) { g->setpriority(g->accept(this)); //this enforces returned value is set } + +FuzzyHelper::EvalWanderTargetObject::~EvalWanderTargetObject() +{ + delete distance; + delete objectValue; + delete visitGain; +} diff --git a/AI/VCAI/Fuzzy.h b/AI/VCAI/Fuzzy.h index 0668b55d0..b9286539d 100644 --- a/AI/VCAI/Fuzzy.h +++ b/AI/VCAI/Fuzzy.h @@ -55,7 +55,15 @@ class FuzzyHelper ~EvalVisitTile(); } vt; - + class EvalWanderTargetObject : public engineBase //designed for use with VCAI::wander() + { + public: + fl::InputVariable * distance; + fl::InputVariable * objectValue; + fl::OutputVariable * visitGain; + ~EvalWanderTargetObject(); + } wanderTarget; + private: float calculateTurnDistanceInputValue(const CGHeroInstance * h, int3 tile) const; @@ -66,6 +74,7 @@ public: FuzzyHelper(); void initTacticalAdvantage(); void initVisitTile(); + void initWanderTarget(); float evaluate(Goals::Explore & g); float evaluate(Goals::RecruitHero & g); @@ -83,6 +92,7 @@ public: ui64 estimateBankDanger(const CBank * bank); float getTacticalAdvantage(const CArmedInstance * we, const CArmedInstance * enemy); //returns factor how many times enemy is stronger than us + float getWanderTargetObjectValue(const CGHeroInstance & h, const ObjectIdRef & obj); Goals::TSubgoal chooseSolution(Goals::TGoalVec vec); //std::shared_ptr chooseSolution (std::vector> & vec); diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index 740174a6a..5c0b88a7a 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -19,7 +19,7 @@ MapObjectsEvaluator::MapObjectsEvaluator() for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID)) { auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); - if(!handler->isStaticObject() && handler->getRMGInfo().value) + if(!handler->isStaticObject()) { objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = handler->getRMGInfo().value; } diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index e3cd8c034..3e09a167e 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -1540,7 +1540,12 @@ void VCAI::wander(HeroPtr h) if(dests.size()) //performance improvement { - const ObjectIdRef & dest = *boost::min_element(dests, CDistanceSorter(h.get())); //find next closest one + auto fuzzyLogicSorter = [h](const ObjectIdRef & l, const ObjectIdRef & r) -> bool + { + return fh->getWanderTargetObjectValue( *h.get(), l) < fh->getWanderTargetObjectValue(*h.get(), r); + }; + + const ObjectIdRef & dest = *boost::max_element(dests, fuzzyLogicSorter); //find best object to visit based on fuzzy logic evaluation //wander should not cause heroes to be reserved - they are always considered free logAi->debug("Of all %d destinations, object oid=%d seems nice", dests.size(), dest.id.getNum()); From b37ba8e046a9061afe79fc6f6b0fec817a4d2396 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sat, 28 Jul 2018 00:43:56 +0200 Subject: [PATCH 12/19] Initial version of AI object value config --- config/schemas/object.json | 3 +++ config/schemas/objectType.json | 3 +++ lib/mapObjects/CObjectClassesHandler.cpp | 20 ++++++++++++++++++++ lib/mapObjects/CObjectClassesHandler.h | 16 +++++++++++++++- lib/serializer/CSerializer.h | 2 +- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/config/schemas/object.json b/config/schemas/object.json index 09cd96feb..d5c2c9b78 100644 --- a/config/schemas/object.json +++ b/config/schemas/object.json @@ -13,6 +13,9 @@ "name": { "type":"string", }, + "defaultAiValue": { + "type":"number", + }, "handler": { "type":"string", diff --git a/config/schemas/objectType.json b/config/schemas/objectType.json index 076fca19b..52797c95b 100644 --- a/config/schemas/objectType.json +++ b/config/schemas/objectType.json @@ -13,6 +13,9 @@ "name": { "type":"string", }, + "aiValue": { + "type":"number", + }, "sounds": { "type":"object", diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index d5edc4a1c..fce778e8a 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -206,6 +206,11 @@ CObjectClassesHandler::ObjectContainter * CObjectClassesHandler::loadFromJson(co obj->handlerName = json["handler"].String(); obj->base = json["base"]; obj->id = selectNextID(json["index"], objects, 256); + if(json["defaultAiValue"].isNull()) + obj->groupDefaultAiValue = boost::none; + else + obj->groupDefaultAiValue = json["defaultAiValue"].Integer(); + for (auto entry : json["types"].Struct()) { loadObjectEntry(entry.first, entry.second, obj); @@ -387,6 +392,11 @@ std::string CObjectClassesHandler::getObjectHandlerName(si32 type) const return objects.at(type)->handlerName; } +boost::optional CObjectClassesHandler::getObjGroupAiValue(si32 primaryID) const +{ + return objects.at(primaryID)->groupDefaultAiValue; +} + AObjectTypeHandler::AObjectTypeHandler(): type(-1), subtype(-1) { @@ -457,6 +467,11 @@ void AObjectTypeHandler::init(const JsonNode & input, boost::optional AObjectTypeHandler::getAiValue() const +{ + return aiValue; +} + bool AObjectTypeHandler::isStaticObject() { return false; // most of classes are not static diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index d23fdb033..b1abc2813 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -146,6 +146,8 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable std::vector templates; SObjectSounds sounds; + + boost::optional aiValue; protected: void preInitObject(CGObjectInstance * obj) const; virtual bool objectFilter(const CGObjectInstance *, const ObjectTemplate &) const; @@ -184,6 +186,8 @@ public: const RandomMapInfo & getRMGInfo(); + boost::optional getAiValue() const; + virtual bool isStaticObject(); virtual void afterLoadFinalization(); @@ -215,6 +219,10 @@ public: { h & sounds; } + if(version >= 788) + { + h & aiValue; + } } }; @@ -237,6 +245,8 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase SObjectSounds sounds; + boost::optional groupDefaultAiValue; + template void serialize(Handler &h, const int version) { h & name; @@ -252,6 +262,10 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase { h & sounds; } + if(version >= 788) + { + h & groupDefaultAiValue; + } } }; @@ -306,7 +320,7 @@ public: /// Returns handler string describing the handler (for use in client) std::string getObjectHandlerName(si32 type) const; - + boost::optional getObjGroupAiValue(si32 primaryID) const; //default AI value of objects belonging to particular primaryID template void serialize(Handler &h, const int version) { diff --git a/lib/serializer/CSerializer.h b/lib/serializer/CSerializer.h index 1e16806c6..8c1e1e5b0 100644 --- a/lib/serializer/CSerializer.h +++ b/lib/serializer/CSerializer.h @@ -12,7 +12,7 @@ #include "../ConstTransitivePtr.h" #include "../GameConstants.h" -const ui32 SERIALIZATION_VERSION = 787; +const ui32 SERIALIZATION_VERSION = 788; const ui32 MINIMAL_SERIALIZATION_VERSION = 753; const std::string SAVEGAME_MAGIC = "VCMISVG"; From d3e53bea2f2fdc68f70da9ba9c9bc9a2ae0020c5 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sat, 28 Jul 2018 12:58:18 +0200 Subject: [PATCH 13/19] Add aiValue handling for MapObjectsEvaluator --- AI/VCAI/MapObjectsEvaluator.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index 5c0b88a7a..b692918ab 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -21,7 +21,18 @@ MapObjectsEvaluator::MapObjectsEvaluator() auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); if(!handler->isStaticObject()) { - objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = handler->getRMGInfo().value; + if(handler->getAiValue().is_initialized()) + { + objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = handler->getAiValue().value(); + } + else if(VLC->objtypeh->getObjGroupAiValue(primaryID).is_initialized()) //if value is not initialized - fallback to default value for this object family if it exists + { + objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = VLC->objtypeh->getObjGroupAiValue(primaryID).value(); + } + else + { + objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = 0; //some default handling when aiValue not found + } } } } From f906d98fe544f4e754804c829a97a6aca2e2cd50 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sun, 29 Jul 2018 16:02:18 +0200 Subject: [PATCH 14/19] Bugfix... --- AI/VCAI/Fuzzy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AI/VCAI/Fuzzy.cpp b/AI/VCAI/Fuzzy.cpp index e37c050b6..0115dd1ae 100644 --- a/AI/VCAI/Fuzzy.cpp +++ b/AI/VCAI/Fuzzy.cpp @@ -490,7 +490,7 @@ void FuzzyHelper::initWanderTarget() wanderTarget.visitGain->addTerm(new fl::Ramp("LOW", 5, 0)); wanderTarget.visitGain->addTerm(new fl::Triangle("MEDIUM", 4, 6)); - wanderTarget.visitGain->addTerm(new fl::Ramp("LOW", 5, 10)); + wanderTarget.visitGain->addTerm(new fl::Ramp("HIGH", 5, 10)); wanderTarget.visitGain->setRange(0, 10); wanderTarget.addRule("if distance is LONG and objectValue is HIGH then visitGain is MEDIUM"); From 393b25eb7f6098a477dbac3783e63a2bab7da042 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Sun, 29 Jul 2018 19:31:01 +0200 Subject: [PATCH 15/19] Minor tweaks/fixes --- AI/VCAI/Fuzzy.cpp | 4 ++-- AI/VCAI/VCAI.cpp | 4 ++-- lib/mapObjects/CObjectClassesHandler.h | 4 ++-- lib/serializer/CSerializer.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/AI/VCAI/Fuzzy.cpp b/AI/VCAI/Fuzzy.cpp index 0115dd1ae..945d0641d 100644 --- a/AI/VCAI/Fuzzy.cpp +++ b/AI/VCAI/Fuzzy.cpp @@ -295,9 +295,9 @@ float FuzzyHelper::getWanderTargetObjectValue(const CGHeroInstance & h, const Ob boost::optional objValueKnownByAI = MapObjectsEvaluator::getInstance().getObjectValue(obj->ID, obj->subID); int objValue = 0; - if(objValueKnownByAI.is_initialized()) + if(objValueKnownByAI.is_initialized()) //consider adding value manipulation based on object instances on map { - objValue = objValueKnownByAI.value(); + objValue = std::min(std::max(objValueKnownByAI.value(), 0), 20000); } else { diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 3e09a167e..6efb1fca8 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -1540,12 +1540,12 @@ void VCAI::wander(HeroPtr h) if(dests.size()) //performance improvement { - auto fuzzyLogicSorter = [h](const ObjectIdRef & l, const ObjectIdRef & r) -> bool + auto fuzzyLogicSorter = [h](const ObjectIdRef & l, const ObjectIdRef & r) -> bool //TODO: create elementar GetObj goal usable for goal decomposition and Wander based on VisitTile logic and object value on top of it { return fh->getWanderTargetObjectValue( *h.get(), l) < fh->getWanderTargetObjectValue(*h.get(), r); }; - const ObjectIdRef & dest = *boost::max_element(dests, fuzzyLogicSorter); //find best object to visit based on fuzzy logic evaluation + const ObjectIdRef & dest = *boost::max_element(dests, fuzzyLogicSorter); //find best object to visit based on fuzzy logic evaluation, TODO: use elementar version of GetObj here in future //wander should not cause heroes to be reserved - they are always considered free logAi->debug("Of all %d destinations, object oid=%d seems nice", dests.size(), dest.id.getNum()); diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index b1abc2813..9ea070f47 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -219,7 +219,7 @@ public: { h & sounds; } - if(version >= 788) + if(version >= 789) { h & aiValue; } @@ -262,7 +262,7 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase { h & sounds; } - if(version >= 788) + if(version >= 789) { h & groupDefaultAiValue; } diff --git a/lib/serializer/CSerializer.h b/lib/serializer/CSerializer.h index 8c1e1e5b0..436a124ca 100644 --- a/lib/serializer/CSerializer.h +++ b/lib/serializer/CSerializer.h @@ -12,7 +12,7 @@ #include "../ConstTransitivePtr.h" #include "../GameConstants.h" -const ui32 SERIALIZATION_VERSION = 788; +const ui32 SERIALIZATION_VERSION = 789; const ui32 MINIMAL_SERIALIZATION_VERSION = 753; const std::string SAVEGAME_MAGIC = "VCMISVG"; From 3e31e67653a2a59ecf0959f69f0cd987079eb78e Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 30 Jul 2018 01:27:02 +0200 Subject: [PATCH 16/19] Initial AI value labeling for map objects --- config/objects/creatureBanks.json | 12 +++++++++ config/objects/generic.json | 34 ++++++++++++++++++++++++- config/objects/moddables.json | 41 ++++++++++++++++++++++--------- config/objects/rewardable.json | 37 +++++++++++++++++++++++++++- 4 files changed, 111 insertions(+), 13 deletions(-) diff --git a/config/objects/creatureBanks.json b/config/objects/creatureBanks.json index 18aeec4c3..2a841cd6d 100644 --- a/config/objects/creatureBanks.json +++ b/config/objects/creatureBanks.json @@ -12,6 +12,7 @@ { "index" : 0, "name" : "Cyclops Stockpile", + "aiValue" : 3000, "sounds" : { "ambient" : ["LOOPCAVE"] }, @@ -120,6 +121,7 @@ "index" : 1, "resetDuration" : 0, "name" : "Dwarven Treasury", + "aiValue" : 2000, "sounds" : { "ambient" : ["LOOPDWAR"] }, @@ -210,6 +212,7 @@ "index" : 2, "resetDuration" : 0, "name" : "Griffin Conservatory", + "aiValue" : 9000, "sounds" : { "ambient" : ["LOOPGRIF"] }, @@ -284,6 +287,7 @@ "index" : 3, "resetDuration" : 0, "name" : "Imp Cache", + "aiValue" : 1500, "sounds" : { "ambient" : ["LOOPFIRE"] }, @@ -373,6 +377,7 @@ "index" : 4, "resetDuration" : 0, "name" : "Medusa Stores", + "aiValue" : 1500, "sounds" : { "ambient" : ["LOOPMEDU"] }, @@ -463,6 +468,7 @@ "index" : 5, "resetDuration" : 0, "name" : "Naga Bank", + "aiValue" : 3000, "sounds" : { "ambient" : ["LOOPNAGA"] }, @@ -553,6 +559,7 @@ "index" : 6, "resetDuration" : 0, "name" : "Dragon Fly Hive", + "aiValue" : 9000, "sounds" : { "ambient" : ["LOOPLEAR"] }, @@ -633,6 +640,7 @@ "index" : 0, "resetDuration" : 0, "name" : "Shipwreck", + "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 100 @@ -724,6 +732,7 @@ "index" : 0, "resetDuration" : 0, "name" : "Derelict Ship", + "aiValue" : 4000, "rmg" : { "value" : 4000, "rarity" : 20 @@ -822,6 +831,7 @@ "index" : 0, "resetDuration" : 0, "name" : "Crypt", + "aiValue" : 1500, "rmg" : { "value" : 1000, "rarity" : 100 @@ -917,6 +927,7 @@ "index" : 0, "resetDuration" : 0, "name" : "Dragon Utopia", + "aiValue" : 11000, "rmg" : { "value" : 10000, "rarity" : 100 @@ -1031,6 +1042,7 @@ "index" : 0, "resetDuration" : 0, "name" : "Pyramid", + "aiValue" : 8000, "rmg" : { "value" : 5000, "rarity" : 20 diff --git a/config/objects/generic.json b/config/objects/generic.json index 76fb27a71..7b5ee3c0c 100644 --- a/config/objects/generic.json +++ b/config/objects/generic.json @@ -10,7 +10,7 @@ } }, "types" : { - "prison" : { "index" : 0 } + "prison" : { "index" : 0, "aiValue" : 5000 } } }, @@ -25,6 +25,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -45,6 +46,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -65,6 +67,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -79,6 +82,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -100,6 +104,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 8000, "rmg" : { "value" : 8000, "rarity" : 20 @@ -120,6 +125,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 10000, "templates" : { "normal" : { "animation" : "ava0128.def", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } }, @@ -151,6 +157,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 750, "templates" : { "base" : { "animation" : "avxredw.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "VV", "VA"], "allowedTerrains":["grass", "swamp", "dirt", "sand", "lava", "rough"] }, @@ -176,6 +183,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 750, "rmg" : { "zoneLimit" : 1, "value" : 750, @@ -195,6 +203,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { } } @@ -246,6 +255,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 2000, "rmg" : { "value" : 5000, "rarity" : 20 @@ -265,6 +275,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "zoneLimit" : 1, "value" : 1500, @@ -285,6 +296,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "rmg" : { "value" : 500, "rarity" : 100 @@ -304,6 +316,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 100 @@ -323,6 +336,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 3000, "rmg" : { "value" : 3000, "rarity" : 100 @@ -344,6 +358,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 0, "rmg" : { } } @@ -360,6 +375,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 750, "rmg" : { } } @@ -376,6 +392,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "rmg" : { } } @@ -392,6 +409,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 350, "rmg" : { "mapLimit" : 48, "value" : 3500, @@ -411,6 +429,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 0, "rmg" : { } } @@ -428,6 +447,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 100 @@ -447,6 +467,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1000, "rmg" : { } } @@ -463,6 +484,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 0, "rmg" : { } } @@ -480,6 +502,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "mapLimit" : 32, "value" : 100, @@ -500,6 +523,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "templates" : { "green" : { "animation" : "avxdent.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "BA"], "allowedTerrains":["grass", "swamp", "dirt"] }, @@ -524,6 +548,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 2500, "rmg" : { "value" : 2500, "rarity" : 20 @@ -542,6 +567,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "zoneLimit" : 3, "value" : 1500, @@ -565,6 +591,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 10000, "rmg" : { } } @@ -581,6 +608,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 250, "rmg" : { "zoneLimit" : 1, "value" : 250, @@ -819,6 +847,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 7000, "rmg" : { "zoneLimit" : 1, "value" : 7000, @@ -833,6 +862,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 0, "rmg" : { } } @@ -850,6 +880,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -870,6 +901,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, diff --git a/config/objects/moddables.json b/config/objects/moddables.json index 458816934..3b8b6aa7a 100644 --- a/config/objects/moddables.json +++ b/config/objects/moddables.json @@ -23,6 +23,7 @@ "hero" : { "index" :34, "handler": "hero", + "defaultAiValue" : 5000, "base" : { "base" : { "visitableFrom" : [ "+++", "+-+", "+++" ], @@ -63,14 +64,14 @@ } }, "types" : { - "wood" : { "index" : 0, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTwood0.def" } } }, - "mercury" : { "index" : 1, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTmerc0.def" } } }, - "ore" : { "index" : 2, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTore0.def" } } }, - "sulfur" : { "index" : 3, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTsulf0.def" } } }, - "crystal" : { "index" : 4, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } }, - "gems" : { "index" : 5, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgems0.def" } } }, - "gold" : { "index" : 6, "rmg" : { "value" : 750, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgold0.def" } } }, - "mithril" : { "index" : 7 } // TODO: move to WoG? + "wood" : { "index" : 0, "aiValue" : 1400, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTwood0.def" } } }, + "mercury" : { "index" : 1, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTmerc0.def" } } }, + "ore" : { "index" : 2, "aiValue" : 1400, "rmg" : { "value" : 1400, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTore0.def" } } }, + "sulfur" : { "index" : 3, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTsulf0.def" } } }, + "crystal" : { "index" : 4, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTcrys0.def" } } }, + "gems" : { "index" : 5, "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgems0.def" } } }, + "gold" : { "index" : 6, "aiValue" : 750, "rmg" : { "value" : 750, "rarity" : 300 }, "templates" : { "res" : { "animation" : "AVTgold0.def" } } }, + "mithril" : { "index" : 7, "aiValue" : 3500 } // TODO: move to WoG? } }, @@ -78,6 +79,7 @@ "town" : { "index" :98, "handler": "town", + "defaultAiValue" : 20000, "base" : { "filters" : { // village image - fort not present @@ -107,6 +109,7 @@ "boat" : { "index" :8, "handler": "boat", + "defaultAiValue" : 0, "base" : { "base" : { "visitableFrom" : [ "+++", "+-+", "+++" ], @@ -124,6 +127,7 @@ "borderGuard" : { "index" :9, "handler": "borderGuard", + "defaultAiValue" : 0, "base" : { "sounds" : { "visit" : ["CAVEHEAD"], @@ -144,6 +148,7 @@ "borderGate" : { "index" :212, "handler": "borderGate", + "defaultAiValue" : 0, "base" : { "sounds" : { "visit" : ["CAVEHEAD"] @@ -163,6 +168,7 @@ "keymasterTent" : { "index" :10, "handler": "keymaster", + "defaultAiValue" : 10000, "base" : { "sounds" : { "visit" : ["CAVEHEAD"] @@ -183,6 +189,7 @@ "seerHut" : { "index" :83, "handler": "seerHut", + "defaultAiValue" : 10000, "base" : { "base" : { "visitableFrom" : [ "---", "+++", "+++" ], @@ -209,9 +216,9 @@ } }, "types" : { - "water" : { "index" : 0, "rmg" : { "zoneLimit" : 1, "value" : 5000, "rarity" : 20 } }, - "land" : { "index" : 1, "rmg" : { "zoneLimit" : 1, "value" : 10000, "rarity" : 20 } }, - "subterra" : { "index" : 2, "rmg" : { "zoneLimit" : 1, "value" : 7500, "rarity" : 20 } } + "water" : { "index" : 0, "aiValue" : 5000, "rmg" : { "zoneLimit" : 1, "value" : 5000, "rarity" : 20 } }, + "land" : { "index" : 1, "aiValue": 10000, "rmg" : { "zoneLimit" : 1, "value" : 10000, "rarity" : 20 } }, + "subterra" : { "index" : 2, "aiValue" : 7500, "rmg" : { "zoneLimit" : 1, "value" : 7500, "rarity" : 20 } } } }, @@ -227,6 +234,7 @@ "types" : { "sawmill" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500 }, @@ -236,6 +244,7 @@ }, "alchemistLab" : { "index" : 1, + "aiValue" : 3500, "rmg" : { "value" : 3500 }, @@ -245,6 +254,7 @@ }, "orePit" : { "index" : 2, + "aiValue" : 1500, "rmg" : { "value" : 1500 }, @@ -254,6 +264,7 @@ }, "sulfurDune" : { "index" : 3, + "aiValue" : 3500, "rmg" : { "value" : 3500 }, @@ -263,6 +274,7 @@ }, "crystalCavern" : { "index" : 4, + "aiValue" : 3500, "rmg" : { "value" : 3500 }, @@ -272,6 +284,7 @@ }, "gemPond" : { "index" : 5, + "aiValue" : 3500, "rmg" : { "value" : 3500 }, @@ -281,6 +294,7 @@ }, "goldMine" : { "index" : 6, + "aiValue" : 7000, "rmg" : { "value" : 7000 }, @@ -290,6 +304,7 @@ }, "abandoned" : { "index" : 7, + "aiValue" : 3500, "sounds" : { "ambient" : ["LOOPCAVE"], "visit" : ["MYSTERY"] @@ -300,6 +315,7 @@ "abandonedMine" : { "index" :220, "handler": "mine", + "defaultAiValue" : 3500, "base" : { "sounds" : { "ambient" : ["LOOPCAVE"] @@ -313,6 +329,7 @@ "garrisonHorizontal": { "index" :33, "handler": "garrison", + "defaultAiValue" : 0, "base" : { "sounds" : { "visit" : ["MILITARY"] @@ -336,6 +353,7 @@ "garrisonVertical" : { "index" :219, "handler": "garrison", + "defaultAiValue" : 0, "base" : { "sounds" : { "visit" : ["MILITARY"] @@ -454,6 +472,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "templates" : { "normal" : { "visitableFrom" : [ "+++", "+-+", "+++" ], diff --git a/config/objects/rewardable.json b/config/objects/rewardable.json index e173f3704..95399f840 100644 --- a/config/objects/rewardable.json +++ b/config/objects/rewardable.json @@ -12,7 +12,8 @@ }, "types" : { "object" : { - "index" : 0//, + "index" : 0, + "aiValue" : 500//, //"rmg" : { // "zoneLimit" : 1, // "value" : 500, @@ -35,6 +36,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "rmg" : { "value" : 500, "rarity" : 50 @@ -54,6 +56,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 80 @@ -73,6 +76,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 750, "rmg" : { "value" : 750, "rarity" : 50 @@ -92,6 +96,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "rmg" : { "value" : 500, "rarity" : 100 @@ -110,6 +115,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "rmg" : { "value" : 500, "rarity" : 100 @@ -128,6 +134,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "rmg" : { "value" : 500, "rarity" : 50 @@ -146,6 +153,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 6000, "rmg" : { "value" : 6000, "rarity" : 20 @@ -167,6 +175,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 500 @@ -186,6 +195,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 2000, "rmg" : { "value" : 2000, "rarity" : 100 @@ -205,6 +215,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 500 @@ -224,6 +235,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 50 @@ -243,6 +255,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 1000 @@ -263,6 +276,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 3000, "rmg" : { "value" : 3000, "rarity" : 50 @@ -282,6 +296,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 100 @@ -301,6 +316,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 100 @@ -319,6 +335,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 12000, "rmg" : { "value" : 12000, "rarity" : 20 @@ -338,6 +355,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 100 @@ -357,6 +375,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 100 @@ -375,6 +394,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 2500, "rmg" : { "mapLimit" : 100, "value" : 2500, @@ -395,6 +415,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1000, "rmg" : { "value" : 1000, "rarity" : 50 @@ -414,6 +435,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1000, "rmg" : { "value" : 1000, "rarity" : 50 @@ -433,6 +455,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 1500, "rmg" : { "value" : 1500, "rarity" : 200 @@ -454,6 +477,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "value" : 100, "rarity" : 100 @@ -472,6 +496,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -492,6 +517,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -512,6 +538,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -532,6 +559,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -551,6 +579,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -573,6 +602,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "value" : 100, "rarity" : 20 @@ -591,6 +621,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -611,6 +642,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 200, "rmg" : { "zoneLimit" : 1, "value" : 200, @@ -631,6 +663,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -651,6 +684,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 100, "rmg" : { "zoneLimit" : 1, "value" : 100, @@ -670,6 +704,7 @@ "types" : { "object" : { "index" : 0, + "aiValue" : 500, "rmg" : { "zoneLimit" : 1, "value" : 500, From 123ca6c41727d3ad1bcd1e66838c903f1ef1ec96 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 30 Jul 2018 01:39:47 +0200 Subject: [PATCH 17/19] Update CMakeLists.txt --- AI/VCAI/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AI/VCAI/CMakeLists.txt b/AI/VCAI/CMakeLists.txt index 8d2973275..a4fb5e9a3 100644 --- a/AI/VCAI/CMakeLists.txt +++ b/AI/VCAI/CMakeLists.txt @@ -11,6 +11,7 @@ set(VCAI_SRCS AIUtility.cpp AIhelper.cpp ResourceManager.cpp + MapObjectsEvaluator.cpp Fuzzy.cpp Goals.cpp main.cpp @@ -23,6 +24,7 @@ set(VCAI_HEADERS AIUtility.h AIhelper.h ResourceManager.h + MapObjectsEvaluator.h Fuzzy.h Goals.h VCAI.h From 0786bd915a65fdf5d6bef3b389449f34fe6dc638 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 30 Jul 2018 14:07:39 +0200 Subject: [PATCH 18/19] remove C++17 insert_or_assign usage --- AI/VCAI/MapObjectsEvaluator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index b692918ab..e214e097c 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -52,7 +52,7 @@ boost::optional MapObjectsEvaluator::getObjectValue(int primaryID, int seco void MapObjectsEvaluator::addObjectData(int primaryID, int secondaryID, int value) //by current design it updates value if already in AI database { CompoundMapObjectID internalIdentifier = CompoundMapObjectID(primaryID, secondaryID); - objectDatabase.insert_or_assign(internalIdentifier, value); + objectDatabase[internalIdentifier] = value; } void MapObjectsEvaluator::removeObjectData(int primaryID, int secondaryID) From 22b02ecc784e3ffd92690310abce5a0704d31116 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 30 Jul 2018 15:32:55 +0200 Subject: [PATCH 19/19] Use boost::optional "better way" --- AI/VCAI/Fuzzy.cpp | 4 ++-- AI/VCAI/MapObjectsEvaluator.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/AI/VCAI/Fuzzy.cpp b/AI/VCAI/Fuzzy.cpp index 4d60d7e5c..3db117451 100644 --- a/AI/VCAI/Fuzzy.cpp +++ b/AI/VCAI/Fuzzy.cpp @@ -295,9 +295,9 @@ float FuzzyHelper::getWanderTargetObjectValue(const CGHeroInstance & h, const Ob boost::optional objValueKnownByAI = MapObjectsEvaluator::getInstance().getObjectValue(obj->ID, obj->subID); int objValue = 0; - if(objValueKnownByAI.is_initialized()) //consider adding value manipulation based on object instances on map + if(objValueKnownByAI != boost::none) //consider adding value manipulation based on object instances on map { - objValue = std::min(std::max(objValueKnownByAI.value(), 0), 20000); + objValue = std::min(std::max(objValueKnownByAI.get(), 0), 20000); } else { diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index e214e097c..7783f68dd 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -21,13 +21,13 @@ MapObjectsEvaluator::MapObjectsEvaluator() auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); if(!handler->isStaticObject()) { - if(handler->getAiValue().is_initialized()) + if(handler->getAiValue() != boost::none) { - objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = handler->getAiValue().value(); + objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = handler->getAiValue().get(); } - else if(VLC->objtypeh->getObjGroupAiValue(primaryID).is_initialized()) //if value is not initialized - fallback to default value for this object family if it exists + else if(VLC->objtypeh->getObjGroupAiValue(primaryID) != boost::none) //if value is not initialized - fallback to default value for this object family if it exists { - objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = VLC->objtypeh->getObjGroupAiValue(primaryID).value(); + objectDatabase[CompoundMapObjectID(primaryID, secondaryID)] = VLC->objtypeh->getObjGroupAiValue(primaryID).get(); } else {