From ef6220ebec9b67e511d546d199a3fcd33de50e1d Mon Sep 17 00:00:00 2001 From: Dmitry Orlov Date: Sun, 13 Dec 2020 03:33:28 +0300 Subject: [PATCH] Fix: Creature resolution failed when mod is in the custom directory --- AI/StupidAI/StupidAI.cpp | 2 +- Global.h | 18 ++++++++++ lib/CModHandler.cpp | 54 ++++++++++------------------- lib/serializer/JsonDeserializer.cpp | 12 +++++++ 4 files changed, 49 insertions(+), 37 deletions(-) diff --git a/AI/StupidAI/StupidAI.cpp b/AI/StupidAI/StupidAI.cpp index 0efcdb2fa..7ee0c8028 100644 --- a/AI/StupidAI/StupidAI.cpp +++ b/AI/StupidAI/StupidAI.cpp @@ -231,10 +231,10 @@ void CStupidAI::print(const std::string &text) const BattleAction CStupidAI::goTowards(const CStack * stack, const CStack * enemy) const { + auto destination = enemy->getPosition(); assert(destination.isValid()); auto reachability = cb->getReachability(stack); auto avHexes = cb->battleGetAvailableHexes(reachability, stack); - auto destination = enemy->getPosition(); if(vstd::contains(avHexes, destination)) return BattleAction::makeMove(stack, destination); diff --git a/Global.h b/Global.h index ed0bc63dd..506f0fc51 100644 --- a/Global.h +++ b/Global.h @@ -727,6 +727,24 @@ namespace vstd } using boost::math::round; + + static std::pair splitStringToPair(std::string input, char separator) + { + std::pair ret; + size_t splitPos = input.find(separator); + + if (splitPos == std::string::npos) + { + ret.first.clear(); + ret.second = input; + } + else + { + ret.first = input.substr(0, splitPos); + ret.second = input.substr(splitPos + 1); + } + return ret; + } } using vstd::operator-=; using vstd::make_unique; diff --git a/lib/CModHandler.cpp b/lib/CModHandler.cpp index 060812a82..509ba4498 100644 --- a/lib/CModHandler.cpp +++ b/lib/CModHandler.cpp @@ -66,24 +66,6 @@ CIdentifierStorage::ObjectCallback::ObjectCallback( optional(optional) {} -static std::pair splitString(std::string input, char separator) -{ - std::pair ret; - size_t splitPos = input.find(separator); - - if (splitPos == std::string::npos) - { - ret.first.clear(); - ret.second = input; - } - else - { - ret.first = input.substr(0, splitPos); - ret.second = input.substr(splitPos + 1); - } - return ret; -} - void CIdentifierStorage::requestIdentifier(ObjectCallback callback) { checkIdentifier(callback.type); @@ -99,51 +81,51 @@ void CIdentifierStorage::requestIdentifier(ObjectCallback callback) void CIdentifierStorage::requestIdentifier(std::string scope, std::string type, std::string name, const std::function & callback) { - auto pair = splitString(name, ':'); // remoteScope:name + auto pair = vstd::splitStringToPair(name, ':'); // remoteScope:name requestIdentifier(ObjectCallback(scope, pair.first, type, pair.second, callback, false)); } void CIdentifierStorage::requestIdentifier(std::string scope, std::string fullName, const std::function& callback) { - auto scopeAndFullName = splitString(fullName, ':'); - auto typeAndName = splitString(scopeAndFullName.second, '.'); + auto scopeAndFullName = vstd::splitStringToPair(fullName, ':'); + auto typeAndName = vstd::splitStringToPair(scopeAndFullName.second, '.'); requestIdentifier(ObjectCallback(scope, scopeAndFullName.first, typeAndName.first, typeAndName.second, callback, false)); } void CIdentifierStorage::requestIdentifier(std::string type, const JsonNode & name, const std::function & callback) { - auto pair = splitString(name.String(), ':'); // remoteScope:name + auto pair = vstd::splitStringToPair(name.String(), ':'); // remoteScope:name requestIdentifier(ObjectCallback(name.meta, pair.first, type, pair.second, callback, false)); } void CIdentifierStorage::requestIdentifier(const JsonNode & name, const std::function & callback) { - auto pair = splitString(name.String(), ':'); // remoteScope: - auto pair2 = splitString(pair.second, '.'); // type.name + auto pair = vstd::splitStringToPair(name.String(), ':'); // remoteScope: + auto pair2 = vstd::splitStringToPair(pair.second, '.'); // type.name requestIdentifier(ObjectCallback(name.meta, pair.first, pair2.first, pair2.second, callback, false)); } void CIdentifierStorage::tryRequestIdentifier(std::string scope, std::string type, std::string name, const std::function & callback) { - auto pair = splitString(name, ':'); // remoteScope:name + auto pair = vstd::splitStringToPair(name, ':'); // remoteScope:name requestIdentifier(ObjectCallback(scope, pair.first, type, pair.second, callback, true)); } void CIdentifierStorage::tryRequestIdentifier(std::string type, const JsonNode & name, const std::function & callback) { - auto pair = splitString(name.String(), ':'); // remoteScope:name + auto pair = vstd::splitStringToPair(name.String(), ':'); // remoteScope:name requestIdentifier(ObjectCallback(name.meta, pair.first, type, pair.second, callback, true)); } boost::optional CIdentifierStorage::getIdentifier(std::string scope, std::string type, std::string name, bool silent) { - auto pair = splitString(name, ':'); // remoteScope:name + auto pair = vstd::splitStringToPair(name, ':'); // remoteScope:name auto idList = getPossibleIdentifiers(ObjectCallback(scope, pair.first, type, pair.second, std::function(), silent)); if (idList.size() == 1) @@ -156,7 +138,7 @@ boost::optional CIdentifierStorage::getIdentifier(std::string scope, std:: boost::optional CIdentifierStorage::getIdentifier(std::string type, const JsonNode & name, bool silent) { - auto pair = splitString(name.String(), ':'); // remoteScope:name + auto pair = vstd::splitStringToPair(name.String(), ':'); // remoteScope:name auto idList = getPossibleIdentifiers(ObjectCallback(name.meta, pair.first, type, pair.second, std::function(), silent)); if (idList.size() == 1) @@ -169,8 +151,8 @@ boost::optional CIdentifierStorage::getIdentifier(std::string type, const boost::optional CIdentifierStorage::getIdentifier(const JsonNode & name, bool silent) { - auto pair = splitString(name.String(), ':'); // remoteScope: - auto pair2 = splitString(pair.second, '.'); // type.name + auto pair = vstd::splitStringToPair(name.String(), ':'); // remoteScope: + auto pair2 = vstd::splitStringToPair(pair.second, '.'); // type.name auto idList = getPossibleIdentifiers(ObjectCallback(name.meta, pair.first, pair2.first, pair2.second, std::function(), silent)); if (idList.size() == 1) @@ -183,8 +165,8 @@ boost::optional CIdentifierStorage::getIdentifier(const JsonNode & name, b boost::optional CIdentifierStorage::getIdentifier(std::string scope, std::string fullName, bool silent) { - auto pair = splitString(fullName, ':'); // remoteScope: - auto pair2 = splitString(pair.second, '.'); // type.name + auto pair = vstd::splitStringToPair(fullName, ':'); // remoteScope: + auto pair2 = vstd::splitStringToPair(pair.second, '.'); // type.name auto idList = getPossibleIdentifiers(ObjectCallback(scope, pair.first, pair2.first, pair2.second, std::function(), silent)); if (idList.size() == 1) @@ -1010,7 +992,7 @@ void CModHandler::afterLoad(bool onlyEssential) std::string CModHandler::normalizeIdentifier(const std::string & scope, const std::string & remoteScope, const std::string & identifier) { - auto p = splitString(identifier, ':'); + auto p = vstd::splitStringToPair(identifier, ':'); if(p.first.empty()) p.first = scope; @@ -1023,11 +1005,11 @@ std::string CModHandler::normalizeIdentifier(const std::string & scope, const st void CModHandler::parseIdentifier(const std::string & fullIdentifier, std::string & scope, std::string & type, std::string & identifier) { - auto p = splitString(fullIdentifier, ':'); + auto p = vstd::splitStringToPair(fullIdentifier, ':'); scope = p.first; - auto p2 = splitString(p.second, '.'); + auto p2 = vstd::splitStringToPair(p.second, '.'); if(p2.first != "") { @@ -1050,7 +1032,7 @@ std::string CModHandler::makeFullIdentifier(const std::string & scope, const std std::string actualName = identifier; //ignore scope if identifier is scoped - auto scopeAndName = splitString(identifier, ':'); + auto scopeAndName = vstd::splitStringToPair(identifier, ':'); if(scopeAndName.first != "") { diff --git a/lib/serializer/JsonDeserializer.cpp b/lib/serializer/JsonDeserializer.cpp index a6ef4d38b..c6f284ef4 100644 --- a/lib/serializer/JsonDeserializer.cpp +++ b/lib/serializer/JsonDeserializer.cpp @@ -37,6 +37,18 @@ void JsonDeserializer::serializeInternal(const std::string & fieldName, si32 & v if(identifier != "") { si32 rawId = decoder(identifier); + + if(rawId < 0) //may be, user has installed the mod into another directory... + { + auto internalId = vstd::splitStringToPair(identifier, ':').second; + auto currentScope = getCurrent().meta; + auto actualId = currentScope.length() > 0 ? currentScope + ":" + internalId : internalId; + + rawId = decoder(actualId); + + if(rawId >= 0) + logMod->warn("Identifier %s has been resolved as %s instead of %s", internalId, actualId, identifier); + } if(rawId >= 0) value = rawId; }