1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Merge pull request #175 from vmarkovtsev/feature/switch_retreat_no_troops

Feature/switch retreat no troops
This commit is contained in:
ArseniyShestakov 2016-01-27 18:49:29 +03:00
commit 3c84400262
10 changed files with 111 additions and 42 deletions

View File

@ -23,7 +23,8 @@
"ALL_CREATURES_GET_DOUBLE_MONTHS" : false, "ALL_CREATURES_GET_DOUBLE_MONTHS" : false,
"NEGATIVE_LUCK" : false, "NEGATIVE_LUCK" : false,
"MAX_HEROES_AVAILABLE_PER_PLAYER" : 16, "MAX_HEROES_AVAILABLE_PER_PLAYER" : 16,
"MAX_HEROES_ON_MAP_PER_PLAYER" : 8 "MAX_HEROES_ON_MAP_PER_PLAYER" : 8,
"WINNING_HERO_WITH_NO_TROOPS_RETREATS": true
}, },
"modules": "modules":

View File

@ -101,9 +101,9 @@ void CIdentifierStorage::requestIdentifier(std::string scope, std::string type,
void CIdentifierStorage::requestIdentifier(std::string scope, std::string fullName, const std::function<void(si32)>& callback) void CIdentifierStorage::requestIdentifier(std::string scope, std::string fullName, const std::function<void(si32)>& callback)
{ {
auto scopeAndFullName = splitString(fullName, ':'); auto scopeAndFullName = splitString(fullName, ':');
auto typeAndName = splitString(scopeAndFullName.second, '.'); auto typeAndName = splitString(scopeAndFullName.second, '.');
requestIdentifier(ObjectCallback(scope, scopeAndFullName.first, typeAndName.first, typeAndName.second, callback, false)); requestIdentifier(ObjectCallback(scope, scopeAndFullName.first, typeAndName.first, typeAndName.second, callback, false));
} }
@ -331,11 +331,11 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali
{ {
ModInfo & modInfo = modData[modName]; ModInfo & modInfo = modData[modName];
bool result = true; bool result = true;
auto performValidate = [&,this](JsonNode & data, const std::string & name){ auto performValidate = [&,this](JsonNode & data, const std::string & name){
handler->beforeValidate(data); handler->beforeValidate(data);
if (validate) if (validate)
result &= JsonUtils::validate(data, "vcmi:" + objectName, name); result &= JsonUtils::validate(data, "vcmi:" + objectName, name);
}; };
// apply patches // apply patches
@ -355,7 +355,7 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali
if (originalData.size() > index) if (originalData.size() > index)
{ {
JsonUtils::merge(originalData[index], data); JsonUtils::merge(originalData[index], data);
performValidate(originalData[index],name); performValidate(originalData[index],name);
handler->loadObject(modName, name, originalData[index], index); handler->loadObject(modName, name, originalData[index], index);
@ -550,21 +550,42 @@ CModHandler::CModHandler()
void CModHandler::loadConfigFromFile (std::string name) void CModHandler::loadConfigFromFile (std::string name)
{ {
std::string paths;
for(auto& p : CResourceHandler::get()->getResourceNames(ResourceID("config/" + name)))
{
paths += p + ", ";
}
paths = paths.substr(0, paths.size() - 2);
logGlobal->debugStream() << "Loading hardcoded features settings from [" << paths << "], result:";
settings.data = JsonUtils::assembleFromFiles("config/" + name); settings.data = JsonUtils::assembleFromFiles("config/" + name);
const JsonNode & hardcodedFeatures = settings.data["hardcodedFeatures"]; const JsonNode & hardcodedFeatures = settings.data["hardcodedFeatures"];
settings.MAX_HEROES_AVAILABLE_PER_PLAYER = hardcodedFeatures["MAX_HEROES_AVAILABLE_PER_PLAYER"].Float(); settings.MAX_HEROES_AVAILABLE_PER_PLAYER = hardcodedFeatures["MAX_HEROES_AVAILABLE_PER_PLAYER"].Float();
logGlobal->debugStream() << "\tMAX_HEROES_AVAILABLE_PER_PLAYER\t" << settings.MAX_HEROES_AVAILABLE_PER_PLAYER;
settings.MAX_HEROES_ON_MAP_PER_PLAYER = hardcodedFeatures["MAX_HEROES_ON_MAP_PER_PLAYER"].Float(); settings.MAX_HEROES_ON_MAP_PER_PLAYER = hardcodedFeatures["MAX_HEROES_ON_MAP_PER_PLAYER"].Float();
logGlobal->debugStream() << "\tMAX_HEROES_ON_MAP_PER_PLAYER\t" << settings.MAX_HEROES_ON_MAP_PER_PLAYER;
settings.CREEP_SIZE = hardcodedFeatures["CREEP_SIZE"].Float(); settings.CREEP_SIZE = hardcodedFeatures["CREEP_SIZE"].Float();
logGlobal->debugStream() << "\tCREEP_SIZE\t" << settings.CREEP_SIZE;
settings.WEEKLY_GROWTH = hardcodedFeatures["WEEKLY_GROWTH_PERCENT"].Float(); settings.WEEKLY_GROWTH = hardcodedFeatures["WEEKLY_GROWTH_PERCENT"].Float();
logGlobal->debugStream() << "\tWEEKLY_GROWTH\t" << settings.WEEKLY_GROWTH;
settings.NEUTRAL_STACK_EXP = hardcodedFeatures["NEUTRAL_STACK_EXP_DAILY"].Float(); settings.NEUTRAL_STACK_EXP = hardcodedFeatures["NEUTRAL_STACK_EXP_DAILY"].Float();
logGlobal->debugStream() << "\tNEUTRAL_STACK_EXP\t" << settings.NEUTRAL_STACK_EXP;
settings.MAX_BUILDING_PER_TURN = hardcodedFeatures["MAX_BUILDING_PER_TURN"].Float(); settings.MAX_BUILDING_PER_TURN = hardcodedFeatures["MAX_BUILDING_PER_TURN"].Float();
logGlobal->debugStream() << "\tMAX_BUILDING_PER_TURN\t" << settings.MAX_BUILDING_PER_TURN;
settings.DWELLINGS_ACCUMULATE_CREATURES = hardcodedFeatures["DWELLINGS_ACCUMULATE_CREATURES"].Bool(); settings.DWELLINGS_ACCUMULATE_CREATURES = hardcodedFeatures["DWELLINGS_ACCUMULATE_CREATURES"].Bool();
logGlobal->debugStream() << "\tDWELLINGS_ACCUMULATE_CREATURES\t" << settings.DWELLINGS_ACCUMULATE_CREATURES;
settings.ALL_CREATURES_GET_DOUBLE_MONTHS = hardcodedFeatures["ALL_CREATURES_GET_DOUBLE_MONTHS"].Bool(); settings.ALL_CREATURES_GET_DOUBLE_MONTHS = hardcodedFeatures["ALL_CREATURES_GET_DOUBLE_MONTHS"].Bool();
logGlobal->debugStream() << "\tALL_CREATURES_GET_DOUBLE_MONTHS\t" << settings.ALL_CREATURES_GET_DOUBLE_MONTHS;
settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS = hardcodedFeatures["WINNING_HERO_WITH_NO_TROOPS_RETREATS"].Bool();
logGlobal->debugStream() << "\tWINNING_HERO_WITH_NO_TROOPS_RETREATS\t" << settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS;
const JsonNode & gameModules = settings.data["modules"]; const JsonNode & gameModules = settings.data["modules"];
modules.STACK_EXP = gameModules["STACK_EXPERIENCE"].Bool(); modules.STACK_EXP = gameModules["STACK_EXPERIENCE"].Bool();
logGlobal->debugStream() << "\tSTACK_EXP\t" << modules.STACK_EXP;
modules.STACK_ARTIFACT = gameModules["STACK_ARTIFACTS"].Bool(); modules.STACK_ARTIFACT = gameModules["STACK_ARTIFACTS"].Bool();
logGlobal->debugStream() << "\tSTACK_ARTIFACT\t" << modules.STACK_ARTIFACT;
modules.COMMANDERS = gameModules["COMMANDERS"].Bool(); modules.COMMANDERS = gameModules["COMMANDERS"].Bool();
logGlobal->debugStream() << "\tCOMMANDERS\t" << modules.COMMANDERS;
modules.MITHRIL = gameModules["MITHRIL"].Bool(); modules.MITHRIL = gameModules["MITHRIL"].Bool();
logGlobal->debugStream() << "\tMITHRIL\t" << modules.MITHRIL;
} }
// currentList is passed by value to get current list of depending mods // currentList is passed by value to get current list of depending mods

View File

@ -73,7 +73,7 @@ public:
/// Function callback will be called during ID resolution phase of loading /// Function callback will be called during ID resolution phase of loading
void requestIdentifier(std::string scope, std::string type, std::string name, const std::function<void(si32)> & callback); void requestIdentifier(std::string scope, std::string type, std::string name, const std::function<void(si32)> & callback);
///fullName = [remoteScope:]type.name ///fullName = [remoteScope:]type.name
void requestIdentifier(std::string scope, std::string fullName, const std::function<void(si32)> & callback); void requestIdentifier(std::string scope, std::string fullName, const std::function<void(si32)> & callback);
void requestIdentifier(std::string type, const JsonNode & name, const std::function<void(si32)> & callback); void requestIdentifier(std::string type, const JsonNode & name, const std::function<void(si32)> & callback);
void requestIdentifier(const JsonNode & name, const std::function<void(si32)> & callback); void requestIdentifier(const JsonNode & name, const std::function<void(si32)> & callback);
@ -253,17 +253,27 @@ public:
int CREEP_SIZE; // neutral stacks won't grow beyond this number int CREEP_SIZE; // neutral stacks won't grow beyond this number
int WEEKLY_GROWTH; //percent int WEEKLY_GROWTH; //percent
int NEUTRAL_STACK_EXP; int NEUTRAL_STACK_EXP;
int MAX_BUILDING_PER_TURN; int MAX_BUILDING_PER_TURN;
bool DWELLINGS_ACCUMULATE_CREATURES; bool DWELLINGS_ACCUMULATE_CREATURES;
bool ALL_CREATURES_GET_DOUBLE_MONTHS; bool ALL_CREATURES_GET_DOUBLE_MONTHS;
int MAX_HEROES_AVAILABLE_PER_PLAYER; int MAX_HEROES_AVAILABLE_PER_PLAYER;
int MAX_HEROES_ON_MAP_PER_PLAYER; int MAX_HEROES_ON_MAP_PER_PLAYER;
bool WINNING_HERO_WITH_NO_TROOPS_RETREATS;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & data & CREEP_SIZE & WEEKLY_GROWTH & NEUTRAL_STACK_EXP & MAX_BUILDING_PER_TURN; h & data & CREEP_SIZE & WEEKLY_GROWTH & NEUTRAL_STACK_EXP & MAX_BUILDING_PER_TURN;
h & DWELLINGS_ACCUMULATE_CREATURES & ALL_CREATURES_GET_DOUBLE_MONTHS & MAX_HEROES_AVAILABLE_PER_PLAYER & MAX_HEROES_ON_MAP_PER_PLAYER; h & DWELLINGS_ACCUMULATE_CREATURES & ALL_CREATURES_GET_DOUBLE_MONTHS &
MAX_HEROES_AVAILABLE_PER_PLAYER & MAX_HEROES_ON_MAP_PER_PLAYER;
if(version >= 756)
{
h & WINNING_HERO_WITH_NO_TROOPS_RETREATS;
}
else if(!h.saving)
{
WINNING_HERO_WITH_NO_TROOPS_RETREATS = true;
}
} }
} settings; } settings;

View File

@ -27,7 +27,7 @@
#include "mapping/CCampaignHandler.h" //for CCampaignState #include "mapping/CCampaignHandler.h" //for CCampaignState
#include "rmg/CMapGenerator.h" // for CMapGenOptions #include "rmg/CMapGenerator.h" // for CMapGenOptions
const ui32 version = 755; const ui32 version = 756;
const ui32 minSupportedVersion = 753; const ui32 minSupportedVersion = 753;
class CISer; class CISer;

View File

@ -56,6 +56,15 @@ JsonNode::JsonNode(ResourceID && fileURI):
*this = parser.parse(fileURI.getName()); *this = parser.parse(fileURI.getName());
} }
JsonNode::JsonNode(const ResourceID & fileURI):
type(DATA_NULL)
{
auto file = CResourceHandler::get()->load(fileURI)->readAll();
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second);
*this = parser.parse(fileURI.getName());
}
JsonNode::JsonNode(ResourceID && fileURI, bool &isValidSyntax): JsonNode::JsonNode(ResourceID && fileURI, bool &isValidSyntax):
type(DATA_NULL) type(DATA_NULL)
{ {
@ -328,7 +337,7 @@ void JsonUtils::parseTypedBonusShort(const JsonVector& source, Bonus *dest)
resolveIdentifier(source[2],dest->subtype); resolveIdentifier(source[2],dest->subtype);
dest->additionalInfo = source[3].Float(); dest->additionalInfo = source[3].Float();
dest->duration = Bonus::PERMANENT; //TODO: handle flags (as integer) dest->duration = Bonus::PERMANENT; //TODO: handle flags (as integer)
dest->turnsRemain = 0; dest->turnsRemain = 0;
} }
@ -343,7 +352,7 @@ Bonus * JsonUtils::parseBonus (const JsonVector &ability_vec) //TODO: merge with
return b; return b;
} }
b->type = it->second; b->type = it->second;
parseTypedBonusShort(ability_vec, b); parseTypedBonusShort(ability_vec, b);
return b; return b;
} }

View File

@ -7,7 +7,7 @@
* Full text of license available in license.txt file, in main folder * Full text of license available in license.txt file, in main folder
* *
*/ */
#pragma once #pragma once
class JsonNode; class JsonNode;
@ -55,6 +55,7 @@ public:
explicit JsonNode(const char * data, size_t datasize); explicit JsonNode(const char * data, size_t datasize);
//Create tree from JSON file //Create tree from JSON file
explicit JsonNode(ResourceID && fileURI); explicit JsonNode(ResourceID && fileURI);
explicit JsonNode(const ResourceID & fileURI);
explicit JsonNode(ResourceID && fileURI, bool & isValidSyntax); explicit JsonNode(ResourceID && fileURI, bool & isValidSyntax);
//Copy c-tor //Copy c-tor
JsonNode(const JsonNode &copy); JsonNode(const JsonNode &copy);
@ -125,9 +126,9 @@ namespace JsonUtils
/** /**
* @brief parse short bonus format, excluding type * @brief parse short bonus format, excluding type
* @note sets duration to Permament * @note sets duration to Permament
*/ */
DLL_LINKAGE void parseTypedBonusShort(const JsonVector &source, Bonus *dest); DLL_LINKAGE void parseTypedBonusShort(const JsonVector &source, Bonus *dest);
/// ///
DLL_LINKAGE Bonus * parseBonus (const JsonVector &ability_vec); DLL_LINKAGE Bonus * parseBonus (const JsonVector &ability_vec);
DLL_LINKAGE Bonus * parseBonus (const JsonNode &bonus); DLL_LINKAGE Bonus * parseBonus (const JsonNode &bonus);
@ -144,7 +145,7 @@ namespace JsonUtils
* @note this function will destroy data in source * @note this function will destroy data in source
*/ */
DLL_LINKAGE void merge(JsonNode & dest, JsonNode & source); DLL_LINKAGE void merge(JsonNode & dest, JsonNode & source);
/** /**
* @brief recursively merges source into dest, replacing identical fields * @brief recursively merges source into dest, replacing identical fields
* struct : recursively calls this function * struct : recursively calls this function
@ -152,12 +153,12 @@ namespace JsonUtils
* values : value in source will replace value in dest * values : value in source will replace value in dest
* null : if value in source is present but set to null it will delete entry in dest * null : if value in source is present but set to null it will delete entry in dest
* @note this function will preserve data stored in source by creating copy * @note this function will preserve data stored in source by creating copy
*/ */
DLL_LINKAGE void mergeCopy(JsonNode & dest, JsonNode source); DLL_LINKAGE void mergeCopy(JsonNode & dest, JsonNode source);
/** @brief recursively merges descendant into copy of base node /** @brief recursively merges descendant into copy of base node
* Result emulates inheritance semantic * Result emulates inheritance semantic
* *
* *
*/ */
DLL_LINKAGE void inherit(JsonNode & descendant, const JsonNode & base); DLL_LINKAGE void inherit(JsonNode & descendant, const JsonNode & base);
@ -200,7 +201,7 @@ namespace JsonDetail
{ {
// conversion helpers for JsonNode::convertTo (partial template function instantiation is illegal in c++) // conversion helpers for JsonNode::convertTo (partial template function instantiation is illegal in c++)
template <typename T, int arithm> template <typename T, int arithm>
struct JsonConvImpl; struct JsonConvImpl;
template <typename T> template <typename T>
@ -229,7 +230,7 @@ namespace JsonDetail
///this should be triggered only for numeric types and enums ///this should be triggered only for numeric types and enums
static_assert(boost::mpl::or_<std::is_arithmetic<Type>, std::is_enum<Type>, boost::is_class<Type> >::value, "Unsupported type for JsonNode::convertTo()!"); static_assert(boost::mpl::or_<std::is_arithmetic<Type>, std::is_enum<Type>, boost::is_class<Type> >::value, "Unsupported type for JsonNode::convertTo()!");
return JsonConvImpl<Type, boost::mpl::or_<std::is_enum<Type>, boost::is_class<Type> >::value >::convertImpl(node); return JsonConvImpl<Type, boost::mpl::or_<std::is_enum<Type>, boost::is_class<Type> >::value >::convertImpl(node);
} }
}; };

View File

@ -87,6 +87,20 @@ boost::optional<std::string> CFilesystemList::getResourceName(const ResourceID &
return boost::optional<std::string>(); return boost::optional<std::string>();
} }
std::set<std::string> CFilesystemList::getResourceNames(const ResourceID & resourceName) const
{
std::set<std::string> paths;
for(auto& loader : getResourcesWithName(resourceName))
{
auto rn = loader->getResourceName(resourceName);
if(rn)
{
paths.insert(*rn);
}
}
return std::move(paths);
}
std::unordered_set<ResourceID> CFilesystemList::getFilteredFiles(std::function<bool(const ResourceID &)> filter) const std::unordered_set<ResourceID> CFilesystemList::getFilteredFiles(std::function<bool(const ResourceID &)> filter) const
{ {
std::unordered_set<ResourceID> ret; std::unordered_set<ResourceID> ret;

View File

@ -59,16 +59,9 @@ class DLL_LINKAGE CFilesystemList : public ISimpleResourceLoader
std::set<ISimpleResourceLoader *> writeableLoaders; std::set<ISimpleResourceLoader *> writeableLoaders;
//FIXME: this is only compile fix, should be removed in the end //FIXME: this is only compile fix, should be removed in the end
CFilesystemList(CFilesystemList &) CFilesystemList(CFilesystemList &) = delete;
{ CFilesystemList &operator=(CFilesystemList &) = delete;
//class is not copyable
}
CFilesystemList &operator=(CFilesystemList &)
{
//class is not copyable
return *this;
}
public: public:
CFilesystemList(); CFilesystemList();
~CFilesystemList(); ~CFilesystemList();
@ -78,6 +71,7 @@ public:
bool existsResource(const ResourceID & resourceName) const override; bool existsResource(const ResourceID & resourceName) const override;
std::string getMountPoint() const override; std::string getMountPoint() const override;
boost::optional<std::string> getResourceName(const ResourceID & resourceName) const override; boost::optional<std::string> getResourceName(const ResourceID & resourceName) const override;
std::set<std::string> getResourceNames(const ResourceID & resourceName) const override;
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override; std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
bool createResource(std::string filename, bool update = false) override; bool createResource(std::string filename, bool update = false) override;
std::vector<const ISimpleResourceLoader *> getResourcesWithName(const ResourceID & resourceName) const override; std::vector<const ISimpleResourceLoader *> getResourcesWithName(const ResourceID & resourceName) const override;

View File

@ -53,6 +53,22 @@ public:
return boost::optional<std::string>(); return boost::optional<std::string>();
} }
/**
* Gets all full names of matching resources, e.g. names of files in filesystem.
*
* @return std::set with names.
*/
virtual std::set<std::string> getResourceNames(const ResourceID & resourceName) const
{
std::set<std::string> result;
auto rn = getResourceName(resourceName);
if(rn)
{
result.insert(*rn);
}
return result;
}
/** /**
* Get list of files that matches filter function * Get list of files that matches filter function
* *

View File

@ -757,18 +757,21 @@ void CGameHandler::battleAfterLevelUp( const BattleResult &result )
RemoveObject ro(finishingBattle->winnerHero->id); RemoveObject ro(finishingBattle->winnerHero->id);
sendAndApply(&ro); sendAndApply(&ro);
SetAvailableHeroes sah; if (VLC->modh->settings.WINNING_HERO_WITH_NO_TROOPS_RETREATS)
sah.player = finishingBattle->victor; {
sah.hid[0] = finishingBattle->winnerHero->subID; SetAvailableHeroes sah;
sah.army[0].clear(); sah.player = finishingBattle->victor;
sah.army[0].setCreature(SlotID(0), finishingBattle->winnerHero->type->initialArmy.at(0).creature, 1); sah.hid[0] = finishingBattle->winnerHero->subID;
sah.army[0].clear();
sah.army[0].setCreature(SlotID(0), finishingBattle->winnerHero->type->initialArmy.at(0).creature, 1);
if(const CGHeroInstance *another = getPlayer(finishingBattle->victor)->availableHeroes.at(0)) if(const CGHeroInstance *another = getPlayer(finishingBattle->victor)->availableHeroes.at(0))
sah.hid[1] = another->subID; sah.hid[1] = another->subID;
else else
sah.hid[1] = -1; sah.hid[1] = -1;
sendAndApply(&sah); sendAndApply(&sah);
}
} }
} }