mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
Parsing & loading for new creatures. A lot of tweaks & improvements. Still needs some work.
This commit is contained in:
@@ -464,7 +464,6 @@ void CCreatureHandler::loadCreatures()
|
|||||||
notUsedMonsters += creature.Float();
|
notUsedMonsters += creature.Float();
|
||||||
}
|
}
|
||||||
|
|
||||||
buildBonusTreeForTiers();
|
|
||||||
loadAnimationInfo();
|
loadAnimationInfo();
|
||||||
loadSoundsInfo();
|
loadSoundsInfo();
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class DLL_LINKAGE CCreature : public CBonusSystemNode
|
|||||||
public:
|
public:
|
||||||
std::string namePl, nameSing, nameRef; //name in singular and plural form; and reference name
|
std::string namePl, nameSing, nameRef; //name in singular and plural form; and reference name
|
||||||
TResources cost; //cost[res_id] - amount of that resource
|
TResources cost; //cost[res_id] - amount of that resource
|
||||||
|
std::set<std::string> upgradeNames; //for reference, they are later transformed info ui32 upgrades
|
||||||
std::set<ui32> upgrades; // IDs of creatures to which this creature can be upgraded
|
std::set<ui32> upgrades; // IDs of creatures to which this creature can be upgraded
|
||||||
//damage, hp. etc are handled by Bonuses
|
//damage, hp. etc are handled by Bonuses
|
||||||
ui32 fightValue, AIValue, growth, hordeGrowth;
|
ui32 fightValue, AIValue, growth, hordeGrowth;
|
||||||
@@ -44,6 +45,7 @@ public:
|
|||||||
int upperRightMissleOffsetX, rightMissleOffsetX, lowerRightMissleOffsetX, upperRightMissleOffsetY, rightMissleOffsetY, lowerRightMissleOffsetY;
|
int upperRightMissleOffsetX, rightMissleOffsetX, lowerRightMissleOffsetX, upperRightMissleOffsetY, rightMissleOffsetY, lowerRightMissleOffsetY;
|
||||||
double missleFrameAngles[12];
|
double missleFrameAngles[12];
|
||||||
int troopCountLocationOffset, attackClimaxFrame;
|
int troopCountLocationOffset, attackClimaxFrame;
|
||||||
|
std::string projectile;
|
||||||
///end of anim info
|
///end of anim info
|
||||||
|
|
||||||
//sound info
|
//sound info
|
||||||
@@ -97,7 +99,7 @@ public:
|
|||||||
{
|
{
|
||||||
h & static_cast<CBonusSystemNode&>(*this);
|
h & static_cast<CBonusSystemNode&>(*this);
|
||||||
h & namePl & nameSing & nameRef
|
h & namePl & nameSing & nameRef
|
||||||
& cost & upgrades
|
& cost & upgradeNames & upgrades
|
||||||
& fightValue & AIValue & growth & hordeGrowth
|
& fightValue & AIValue & growth & hordeGrowth
|
||||||
& ammMin & ammMax & level
|
& ammMin & ammMax & level
|
||||||
& abilityText & abilityRefs & animDefName
|
& abilityText & abilityRefs & animDefName
|
||||||
@@ -106,7 +108,7 @@ public:
|
|||||||
& timeBetweenFidgets & walkAnimationTime & attackAnimationTime & flightAnimationDistance
|
& timeBetweenFidgets & walkAnimationTime & attackAnimationTime & flightAnimationDistance
|
||||||
& upperRightMissleOffsetX & rightMissleOffsetX & lowerRightMissleOffsetX & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY
|
& upperRightMissleOffsetX & rightMissleOffsetX & lowerRightMissleOffsetX & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY
|
||||||
& missleFrameAngles & troopCountLocationOffset & attackClimaxFrame;
|
& missleFrameAngles & troopCountLocationOffset & attackClimaxFrame;
|
||||||
h & sounds;
|
h & sounds & projectile;
|
||||||
|
|
||||||
h & doubleWide;
|
h & doubleWide;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "CModHandler.h"
|
#include "CModHandler.h"
|
||||||
#include "JsonNode.h"
|
#include "JsonNode.h"
|
||||||
#include "Filesystem\CResourceLoader.h" //TODO: reorganize
|
#include "Filesystem\CResourceLoader.h"
|
||||||
|
#include "Filesystem\ISimpleResourceLoader.h"
|
||||||
/*
|
/*
|
||||||
* CModHandler.h, part of VCMI engine
|
* CModHandler.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
@@ -21,6 +22,7 @@ class CObjectHandler;
|
|||||||
class CDefObjInfoHandler;
|
class CDefObjInfoHandler;
|
||||||
class CTownHandler;
|
class CTownHandler;
|
||||||
class CGeneralTextHandler;
|
class CGeneralTextHandler;
|
||||||
|
class ResourceLocator;
|
||||||
|
|
||||||
CModHandler::CModHandler()
|
CModHandler::CModHandler()
|
||||||
{
|
{
|
||||||
@@ -63,41 +65,32 @@ void CModHandler::loadConfigFromFile (std::string name)
|
|||||||
modules.COMMANDERS = gameModules["COMMANDERS"].Bool();
|
modules.COMMANDERS = gameModules["COMMANDERS"].Bool();
|
||||||
modules.MITHRIL = gameModules["MITHRIL"].Bool();
|
modules.MITHRIL = gameModules["MITHRIL"].Bool();
|
||||||
|
|
||||||
//auto mods = config["activeMods"]; //TODO: load only mods from the list
|
//TODO: load only mods from the list
|
||||||
|
|
||||||
auto resourceLoader = CResourceHandler::get();
|
//TODO: read mods from Mods/ folder
|
||||||
auto iterator = resourceLoader->getIterator([](const ResourceID & ident) -> bool
|
|
||||||
|
auto & configList = CResourceHandler::get()->getResourcesWithName (ResourceID("CONFIG/MODS/HOTA/MOD", EResType::TEXT));
|
||||||
|
|
||||||
|
BOOST_FOREACH(auto & entry, configList)
|
||||||
{
|
{
|
||||||
std::string name = ident.getName();
|
auto stream = entry.getLoader()->load (entry.getResourceName());
|
||||||
|
std::unique_ptr<ui8[]> textData (new ui8[stream->getSize()]);
|
||||||
|
stream->read (textData.get(), stream->getSize());
|
||||||
|
|
||||||
return ident.getType() == EResType::TEXT
|
tlog3 << "\t\tFound mod file: " << entry.getResourceName() << "\n";
|
||||||
&& std::count(name.begin(), name.end(), '/') == 3
|
const JsonNode config ((char*)textData.get(), stream->getSize());
|
||||||
&& boost::algorithm::starts_with(name, "ALL/MODS/")
|
|
||||||
&& boost::algorithm::ends_with(name, "MOD"); //all mods have "mod.json" name - does it make sense?
|
|
||||||
});
|
|
||||||
|
|
||||||
std::set<std::string> foundMods;
|
|
||||||
while (iterator.hasNext())
|
|
||||||
{
|
|
||||||
foundMods.insert(iterator->getName());
|
|
||||||
++iterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH (auto mod, foundMods)
|
|
||||||
{
|
|
||||||
tlog3 << "\t\tFound mod file: " << mod << "\n";
|
|
||||||
|
|
||||||
const JsonNode config (ResourceID("mod"));
|
|
||||||
const JsonNode *value = &config["creatures"];
|
const JsonNode *value = &config["creatures"];
|
||||||
if (!value->isNull())
|
if (!value->isNull())
|
||||||
{
|
{
|
||||||
BOOST_FOREACH (auto creature, value->Vector())
|
BOOST_FOREACH (auto creature, value->Vector())
|
||||||
{
|
{
|
||||||
auto cre = loadCreature (creature);
|
auto cre = loadCreature (creature); //create and push back creature
|
||||||
addNewCreature (cre);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void CModHandler::saveConfigToFile (std::string name)
|
void CModHandler::saveConfigToFile (std::string name)
|
||||||
{
|
{
|
||||||
@@ -119,18 +112,19 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
|
|||||||
cre->idNumber = creatures.size();
|
cre->idNumber = creatures.size();
|
||||||
const JsonNode *value; //optional value
|
const JsonNode *value; //optional value
|
||||||
|
|
||||||
//TODO: ref name
|
//TODO: ref name?
|
||||||
auto name = node["name"];
|
auto name = node["name"];
|
||||||
cre->nameSing = name["singular"].String();
|
cre->nameSing = name["singular"].String();
|
||||||
cre->namePl = name["plural"].String();
|
cre->namePl = name["plural"].String();
|
||||||
//TODO: map name->id
|
cre->nameRef = cre->nameSing;
|
||||||
|
|
||||||
|
//TODO: export resource set to separate function?
|
||||||
auto cost = node["cost"];
|
auto cost = node["cost"];
|
||||||
if (cost.getType() == JsonNode::DATA_FLOAT) //gold
|
if (cost.getType() == JsonNode::DATA_FLOAT) //gold
|
||||||
{
|
{
|
||||||
cre->cost[Res::GOLD] = cost.Float();
|
cre->cost[Res::GOLD] = cost.Float();
|
||||||
}
|
}
|
||||||
else
|
else if (cost.getType() == JsonNode::DATA_VECTOR)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
BOOST_FOREACH (auto val, cost.Vector())
|
BOOST_FOREACH (auto val, cost.Vector())
|
||||||
@@ -138,6 +132,33 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
|
|||||||
cre->cost[i++] = val.Float();
|
cre->cost[i++] = val.Float();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else //damn you...
|
||||||
|
{
|
||||||
|
value = &cost["gold"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::GOLD] = value->Float();
|
||||||
|
value = &cost["gems"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::GEMS] = value->Float();
|
||||||
|
value = &cost["crystal"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::CRYSTAL] = value->Float();
|
||||||
|
value = &cost["mercury"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::MERCURY] = value->Float();
|
||||||
|
value = &cost["sulfur"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::SULFUR] = value->Float();
|
||||||
|
value = &cost["ore"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::ORE] = value->Float();
|
||||||
|
value = &cost["wood"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::WOOD] = value->Float();
|
||||||
|
value = &cost["mithril"];
|
||||||
|
if (!value->isNull())
|
||||||
|
cre->cost[Res::MITHRIL] = value->Float();
|
||||||
|
}
|
||||||
|
|
||||||
cre->level = node["level"].Float();
|
cre->level = node["level"].Float();
|
||||||
cre->faction = -1; //TODO: node["faction"].String() to id or just node["faction"].Float();
|
cre->faction = -1; //TODO: node["faction"].String() to id or just node["faction"].Float();
|
||||||
@@ -149,11 +170,20 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
|
|||||||
cre->addBonus(node["speed"].Float(), Bonus::STACKS_SPEED);
|
cre->addBonus(node["speed"].Float(), Bonus::STACKS_SPEED);
|
||||||
cre->addBonus(node["attack"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
|
cre->addBonus(node["attack"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
|
||||||
cre->addBonus(node["defense"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
|
cre->addBonus(node["defense"].Float(), Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
|
||||||
auto vec = node["damage"].Vector();
|
auto vec = node["damage"];
|
||||||
cre->addBonus(vec[0].Float(), Bonus::CREATURE_DAMAGE, 1);
|
cre->addBonus(vec["min"].Float(), Bonus::CREATURE_DAMAGE, 1);
|
||||||
cre->addBonus(vec[1].Float(), Bonus::CREATURE_DAMAGE, 2);
|
cre->addBonus(vec["max"].Float(), Bonus::CREATURE_DAMAGE, 2);
|
||||||
|
|
||||||
//optional
|
//optional
|
||||||
|
value = &node["upgrades"];
|
||||||
|
if (!value->isNull())
|
||||||
|
{
|
||||||
|
BOOST_FOREACH (auto str, value->Vector())
|
||||||
|
{
|
||||||
|
cre->upgradeNames.insert (str.String());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
value = &node["shots"];
|
value = &node["shots"];
|
||||||
if (!value->isNull())
|
if (!value->isNull())
|
||||||
cre->addBonus(value->Float(), Bonus::SHOTS);
|
cre->addBonus(value->Float(), Bonus::SHOTS);
|
||||||
@@ -162,7 +192,11 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
|
|||||||
if (!value->isNull())
|
if (!value->isNull())
|
||||||
cre->addBonus(value->Float(), Bonus::CASTS);
|
cre->addBonus(value->Float(), Bonus::CASTS);
|
||||||
|
|
||||||
|
value = &node["doubleWide"];
|
||||||
|
if (!value->isNull())
|
||||||
cre->doubleWide = value->Bool();
|
cre->doubleWide = value->Bool();
|
||||||
|
else
|
||||||
|
cre->doubleWide = false;
|
||||||
|
|
||||||
value = &node["abilities"];
|
value = &node["abilities"];
|
||||||
if (!value->isNull())
|
if (!value->isNull())
|
||||||
@@ -198,8 +232,10 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
|
|||||||
{
|
{
|
||||||
cre->missleFrameAngles[i++] = angle.Float();
|
cre->missleFrameAngles[i++] = angle.Float();
|
||||||
}
|
}
|
||||||
//we need to know creature id to add it
|
//TODO: we need to know creature id to add it
|
||||||
VLC->creh->idToProjectile[cre->idNumber] = value->String();
|
//FIXME: creature handler is not yet initialized
|
||||||
|
//VLC->creh->idToProjectile[cre->idNumber] = "PLCBOWX.DEF";
|
||||||
|
cre->projectile = "PLCBOWX.DEF";
|
||||||
|
|
||||||
auto sounds = node["sound"];
|
auto sounds = node["sound"];
|
||||||
|
|
||||||
@@ -229,7 +265,24 @@ void CModHandler::recreateHandlers()
|
|||||||
BOOST_FOREACH (auto creature, creatures)
|
BOOST_FOREACH (auto creature, creatures)
|
||||||
{
|
{
|
||||||
VLC->creh->creatures.push_back (creature);
|
VLC->creh->creatures.push_back (creature);
|
||||||
|
//TODO: use refName?
|
||||||
|
//if (creature->nameRef.size())
|
||||||
|
// VLC->creh->nameToID[creature->nameRef] = creature->idNumber;
|
||||||
|
VLC->creh->nameToID[creature->nameSing] = creature->idNumber;
|
||||||
}
|
}
|
||||||
|
BOOST_FOREACH (auto creature, VLC->creh->creatures) //populate upgrades described with string
|
||||||
|
{
|
||||||
|
BOOST_FOREACH (auto upgradeName, creature->upgradeNames)
|
||||||
|
{
|
||||||
|
auto it = VLC->creh->nameToID.find(upgradeName);
|
||||||
|
if (it != VLC->creh->nameToID.end())
|
||||||
|
{
|
||||||
|
creature->upgrades.insert (it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VLC->creh->buildBonusTreeForTiers(); //do that after all new creatures are loaded
|
||||||
|
|
||||||
BOOST_FOREACH (auto mod, activeMods) //inactive part
|
BOOST_FOREACH (auto mod, activeMods) //inactive part
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -330,7 +330,8 @@ void CResourceHandler::initialize()
|
|||||||
//create "LOCAL" dir with current userDir (may be same as rootDir)
|
//create "LOCAL" dir with current userDir (may be same as rootDir)
|
||||||
initialLoader->addLoader("LOCAL/", userDir, false);
|
initialLoader->addLoader("LOCAL/", userDir, false);
|
||||||
|
|
||||||
recurseInDir("ALL/CONFIG", 0);// look for configs
|
//recurseInDir("ALL/CONFIG", 0);// look for configs
|
||||||
|
recurseInDir("ALL/CONFIG", 4);// look for mods (2) and mod files (3) in config folder
|
||||||
recurseInDir("ALL/DATA", 0); // look for archives
|
recurseInDir("ALL/DATA", 0); // look for archives
|
||||||
recurseInDir("ALL/MODS", 2); // look for mods. Depth 2 is required for now but won't cause issues if no mods present
|
recurseInDir("ALL/MODS", 2); // look for mods. Depth 2 is required for now but won't cause issues if no mods present
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user