mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- finally, solution for imageIndex fields. All image lists will be generated in runtime
- iconIndex fields from json are no longer used - simple check for missing icons on startup
This commit is contained in:
parent
7a3f5dc23b
commit
3285f1910b
@ -164,7 +164,7 @@
|
||||
{ "frame" : 160, "file" : "HPS134Nc.bmp"},
|
||||
{ "frame" : 161, "file" : "HPS135Wi.bmp"},
|
||||
{ "frame" : 162, "file" : "HPS136Wi.bmp"},
|
||||
{ "frame" : 200, "file" : "HPSRAND1.bmp"}, //random hero
|
||||
{ "frame" : 201, "file" : "HPSRAND6.bmp"} //no hero
|
||||
{ "frame" : 163, "file" : "HPSRAND1.bmp"}, //random hero
|
||||
{ "frame" : 164, "file" : "HPSRAND6.bmp"} //no hero
|
||||
]
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ const std::map<size_t, size_t > CDefFile::getEntries() const
|
||||
{
|
||||
std::map<size_t, size_t > ret;
|
||||
|
||||
for (std::map<size_t, std::vector <size_t> >::const_iterator mapIt = offset.begin(); mapIt!=offset.end(); ++mapIt)
|
||||
for (auto mapIt = offset.begin(); mapIt!=offset.end(); ++mapIt)
|
||||
ret[mapIt->first] = mapIt->second.size();
|
||||
return ret;
|
||||
}
|
||||
@ -935,10 +935,21 @@ bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group)
|
||||
//try to get image from def
|
||||
if (source[group][frame].getType() == JsonNode::DATA_NULL)
|
||||
{
|
||||
if (compressed)
|
||||
images[group][frame] = new CompImage(file, frame, group);
|
||||
else
|
||||
images[group][frame] = new SDLImage(file, frame, group);
|
||||
auto frameList = file->getEntries();
|
||||
|
||||
if (vstd::contains(frameList, group) && frameList.at(group) > frame) // frame is present
|
||||
{
|
||||
if (compressed)
|
||||
images[group][frame] = new CompImage(file, frame, group);
|
||||
else
|
||||
images[group][frame] = new SDLImage(file, frame, group);
|
||||
}
|
||||
else // missing image
|
||||
{
|
||||
printError(frame, group, "LoadFrame");
|
||||
images[group][frame] = new SDLImage("DEFAULT", compressed);
|
||||
}
|
||||
|
||||
}
|
||||
else //load from separate file
|
||||
{
|
||||
@ -972,6 +983,38 @@ bool CAnimation::unloadFrame(size_t frame, size_t group)
|
||||
return false;
|
||||
}
|
||||
|
||||
void CAnimation::initFromJson(const JsonNode & config)
|
||||
{
|
||||
std::string basepath;
|
||||
basepath = config["basepath"].String();
|
||||
|
||||
BOOST_FOREACH(const JsonNode &group, config["sequences"].Vector())
|
||||
{
|
||||
size_t groupID = group["group"].Float();//TODO: string-to-value conversion("moving" -> MOVING)
|
||||
source[groupID].clear();
|
||||
|
||||
BOOST_FOREACH(const JsonNode &frame, group["frames"].Vector())
|
||||
{
|
||||
source[groupID].push_back(JsonNode());
|
||||
std::string filename = frame.String();
|
||||
source[groupID].back()["file"].String() = basepath + filename;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const JsonNode &node, config["images"].Vector())
|
||||
{
|
||||
size_t group = node["group"].Float();
|
||||
size_t frame = node["frame"].Float();
|
||||
|
||||
if (source[group].size() <= frame)
|
||||
source[group].resize(frame+1);
|
||||
|
||||
source[group][frame] = node;
|
||||
std::string filename = node["file"].String();
|
||||
source[group][frame]["file"].String() = basepath + filename;
|
||||
}
|
||||
}
|
||||
|
||||
void CAnimation::init(CDefFile * file)
|
||||
{
|
||||
if (file)
|
||||
@ -982,8 +1025,12 @@ void CAnimation::init(CDefFile * file)
|
||||
source[mapIt->first].resize(mapIt->second);
|
||||
}
|
||||
|
||||
auto & configList = CResourceHandler::get()->getResourcesWithName(
|
||||
ResourceID(std::string("SPRITES/") + name, EResType::TEXT));
|
||||
ResourceID resID(std::string("SPRITES/") + name, EResType::TEXT);
|
||||
|
||||
if (vstd::contains(graphics->imageLists, resID.getName()))
|
||||
initFromJson(graphics->imageLists[resID.getName()]);
|
||||
|
||||
auto & configList = CResourceHandler::get()->getResourcesWithName(resID);
|
||||
|
||||
BOOST_FOREACH(auto & entry, configList)
|
||||
{
|
||||
@ -993,34 +1040,7 @@ void CAnimation::init(CDefFile * file)
|
||||
|
||||
const JsonNode config((char*)textData.get(), stream->getSize());
|
||||
|
||||
std::string basepath;
|
||||
basepath = config["basepath"].String();
|
||||
|
||||
BOOST_FOREACH(const JsonNode &group, config["sequences"].Vector())
|
||||
{
|
||||
size_t groupID = group["group"].Float();//TODO: string-to-value conversion("moving" -> MOVING)
|
||||
source[groupID].clear();
|
||||
|
||||
BOOST_FOREACH(const JsonNode &frame, group["frames"].Vector())
|
||||
{
|
||||
source[groupID].push_back(JsonNode());
|
||||
std::string filename = frame.String();
|
||||
source[groupID].back()["file"].String() = basepath + filename;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const JsonNode &node, config["images"].Vector())
|
||||
{
|
||||
size_t group = node["group"].Float();
|
||||
size_t frame = node["frame"].Float();
|
||||
|
||||
if (source[group].size() <= frame)
|
||||
source[group].resize(frame+1);
|
||||
|
||||
source[group][frame] = node;
|
||||
std::string filename = node["file"].String();
|
||||
source[group][frame]["file"].String() = basepath + filename;
|
||||
}
|
||||
initFromJson(config);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,6 +175,7 @@ private:
|
||||
bool unloadFrame(size_t frame, size_t group);
|
||||
|
||||
//initialize animation from file
|
||||
void initFromJson(const JsonNode & input);
|
||||
void init(CDefFile * file);
|
||||
|
||||
//try to open def file
|
||||
|
@ -139,11 +139,13 @@ void init()
|
||||
|
||||
pomtime.getDiff();
|
||||
CCS->curh = new CCursorHandler;
|
||||
graphics = new Graphics(); // should be before curh->init()
|
||||
|
||||
CCS->curh->initCursor();
|
||||
CCS->curh->show();
|
||||
logGlobal->infoStream()<<"Screen handler: "<<pomtime.getDiff();
|
||||
pomtime.getDiff();
|
||||
graphics = new Graphics();
|
||||
|
||||
graphics->loadHeroAnims();
|
||||
logGlobal->infoStream()<<"\tMain graphics: "<<tmh.getDiff();
|
||||
logGlobal->infoStream()<<"Initializing game graphics: "<<tmh.getDiff();
|
||||
|
@ -2633,7 +2633,7 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex()
|
||||
WOOD = 0, ORE = 0, MITHRIL = 10, // resources unavailable in bonuses file
|
||||
|
||||
TOWN_RANDOM = 38, TOWN_NONE = 39, // Special frames in ITPA
|
||||
HERO_RANDOM = 200, HERO_NONE = 201 // Special frames in PortraitsSmall
|
||||
HERO_RANDOM = 163, HERO_NONE = 164 // Special frames in PortraitsSmall
|
||||
};
|
||||
|
||||
switch(type)
|
||||
|
@ -126,6 +126,7 @@ Graphics::Graphics()
|
||||
tasks += boost::bind(&Graphics::loadHeroFlags,this);
|
||||
tasks += boost::bind(&Graphics::initializeBattleGraphics,this);
|
||||
tasks += boost::bind(&Graphics::loadErmuToPicture,this);
|
||||
tasks += boost::bind(&Graphics::initializeImageLists,this);
|
||||
tasks += GET_DEF_ESS(resources32,"RESOURCE.DEF");
|
||||
tasks += GET_DEF_ESS(spellscr,"SPELLSCR.DEF");
|
||||
tasks += GET_DEF_ESS(heroMoveArrows,"ADAG.DEF");
|
||||
@ -417,3 +418,58 @@ void Graphics::loadErmuToPicture()
|
||||
}
|
||||
assert (etp_idx == 44);
|
||||
}
|
||||
|
||||
void Graphics::addImageListEntry(size_t index, std::string listName, std::string imageName)
|
||||
{
|
||||
if (!imageName.empty())
|
||||
{
|
||||
if (!CResourceHandler::get()->existsResource(ResourceID("SPRITES/" + imageName, EResType::IMAGE)))
|
||||
logGlobal->errorStream() << "Required image " << "SPRITES/" << imageName << " is missing!";
|
||||
|
||||
JsonNode entry;
|
||||
entry["frame"].Float() = index;
|
||||
entry["file"].String() = imageName;
|
||||
|
||||
imageLists["SPRITES/" + listName]["images"].Vector().push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::initializeImageLists()
|
||||
{
|
||||
BOOST_FOREACH(const CCreature * creature, CGI->creh->creatures)
|
||||
{
|
||||
addImageListEntry(creature->iconIndex, "CPRSMALL", creature->smallIconName);
|
||||
addImageListEntry(creature->iconIndex, "TWCRPORT", creature->largeIconName);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const CHero * hero, CGI->heroh->heroes)
|
||||
{
|
||||
addImageListEntry(hero->imageIndex, "UN32", hero->iconSpecSmall);
|
||||
addImageListEntry(hero->imageIndex, "UN44", hero->iconSpecLarge);
|
||||
addImageListEntry(hero->imageIndex, "PORTRAITSLARGE", hero->portraitLarge);
|
||||
addImageListEntry(hero->imageIndex, "PORTRAITSSMALL", hero->portraitSmall);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const CArtifact * art, CGI->arth->artifacts)
|
||||
{
|
||||
addImageListEntry(art->iconIndex, "ARTIFACT", art->image);
|
||||
addImageListEntry(art->iconIndex, "ARTIFACTLARGE", art->large);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const CFaction * faction, CGI->townh->factions)
|
||||
{
|
||||
if (faction->town)
|
||||
{
|
||||
auto & info = faction->town->clientInfo;
|
||||
addImageListEntry(info.icons[0][0], "ITPT", info.iconLarge[0][0]);
|
||||
addImageListEntry(info.icons[0][1], "ITPT", info.iconLarge[0][1]);
|
||||
addImageListEntry(info.icons[1][0], "ITPT", info.iconLarge[1][0]);
|
||||
addImageListEntry(info.icons[1][1], "ITPT", info.iconLarge[1][1]);
|
||||
|
||||
addImageListEntry(info.icons[0][0] + 2, "ITPA", info.iconSmall[0][0]);
|
||||
addImageListEntry(info.icons[0][1] + 2, "ITPA", info.iconSmall[0][1]);
|
||||
addImageListEntry(info.icons[1][0] + 2, "ITPA", info.iconSmall[1][0]);
|
||||
addImageListEntry(info.icons[1][1] + 2, "ITPA", info.iconSmall[1][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ enum EFonts
|
||||
/// Handles fonts, hero images, town images, various graphics
|
||||
class Graphics
|
||||
{
|
||||
void addImageListEntry(size_t index, std::string listName, std::string imageName);
|
||||
|
||||
public:
|
||||
//Fonts
|
||||
static const int FONTS_NUMBER = 9;
|
||||
@ -54,6 +56,8 @@ public:
|
||||
CDefHandler * FoWfullHide; //for Fog of War
|
||||
CDefHandler * FoWpartialHide; //for For of War
|
||||
|
||||
std::map<std::string, JsonNode> imageLists;
|
||||
|
||||
std::map<std::string, CDefEssential *> advmapobjGraphics;
|
||||
CDefEssential * getDef(const CGObjectInstance * obj);
|
||||
CDefEssential * getDef(const CGDefInfo * info);
|
||||
@ -75,7 +79,9 @@ public:
|
||||
CDefEssential * loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations);
|
||||
void loadErmuToPicture();
|
||||
void blueToPlayersAdv(SDL_Surface * sur, PlayerColor player); //replaces blue interface colour with a color of player
|
||||
|
||||
void loadFonts();
|
||||
void initializeImageLists();
|
||||
};
|
||||
|
||||
extern Graphics * graphics;
|
||||
|
@ -114,11 +114,6 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBCSUP_5.def", "x" : 160, "y" : 190, "z" : -1, "border" : "TOCSCAV2.bmp", "area" : "TZCSCAV2.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBCSUP_6.def", "x" : 303, "y" : 0, "z" : -1, "border" : "TOCSANG2.bmp", "area" : "TZCSANG2.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 18, "built" : 19 },
|
||||
"fort" : {"normal" : 0, "built" : 1 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/CstleTown",
|
||||
|
||||
|
@ -118,11 +118,7 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBELUP_5.def", "x" : 394, "y" : 283, "z" : 2, "border" : "TOELUP_5.bmp", "area" : "TZELUP_5.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBELUP_6.def", "x" : 43, "y" : 0, "z" : -2, "border" : "TOELUP_6.bmp", "area" : "TZELUP_6.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 34, "built" : 35 },
|
||||
"fort" : {"normal" : 16, "built" : 17 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/ElemTown",
|
||||
|
||||
"townBackground": "TBELBACK.bmp",
|
||||
|
@ -113,11 +113,7 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBDNUP_5.def", "x" : 270, "y" : 253, "z" : -1, "border" : "TODMAN2.bmp", "area" : "TZDMAN2.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBDNUP_6.def", "x" : 550, "y" : 0, "z" : -1, "border" : "TODDRA2A.bmp", "area" : "TZDDRA2A.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 28, "built" : 29 },
|
||||
"fort" : {"normal" : 10, "built" : 11 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/Dungeon",
|
||||
|
||||
"townBackground": "TBDNBACK.bmp",
|
||||
|
@ -114,11 +114,7 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBFRUP_5.def", "x" : 0, "y" : 4, "border" : "TOFWYV2.bmp", "area" : "TZFWYV2.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBFRUP_6.def", "x" : 587, "y" : 263, "z" : 5, "border" : "TOFHYD2A.bmp", "area" : "TZFHYD2A.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 32, "built" : 33 },
|
||||
"fort" : {"normal" : 14, "built" : 15 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/FortressTown",
|
||||
|
||||
"townBackground": "TBFRBACK.bmp",
|
||||
|
@ -114,11 +114,7 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBINUP_5.def", "x" : 220, "y" : 282, "z" : 5, "border" : "TOIEFR2.bmp", "area" : "TZIEFR2.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBINUP_6.def", "x" : 420, "y" : 105, "z" : -1, "border" : "TOIDVL2.bmp", "area" : "TZIDVL2.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 24, "built" : 25 },
|
||||
"fort" : {"normal" : 6, "built" : 7 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/InfernoTown",
|
||||
|
||||
"townBackground": "TBINBACK.bmp",
|
||||
|
@ -118,11 +118,7 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBNCUP_5.def", "x" : 0, "y" : 30, "border" : "TONBKN2.bmp", "area" : "TZNBKN2.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBNCUP_6.def", "x" : 662, "y" : 23, "border" : "TONBON2.bmp", "area" : "TZNBON2.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 26, "built" : 27 },
|
||||
"fort" : {"normal" : 8, "built" : 9 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/NecroTown",
|
||||
|
||||
"townBackground": "TBNCBACK.bmp",
|
||||
|
@ -118,11 +118,6 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBRMUP_5.def", "x" : 362, "y" : 90, "z" : -2, "border" : "TORUNI2.bmp", "area" : "TZRUNI2.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBRMUP_6.def", "x" : 502, "y" : 5, "z" : -5, "border" : "TORDR2AA.bmp", "area" : "TZRDR2AA.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 20, "built" : 21 },
|
||||
"fort" : {"normal" : 2, "built" : 3 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/Rampart",
|
||||
|
||||
|
@ -112,11 +112,7 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBSTUP_5.def", "x" : 616, "y" : 93, "z" : -2, "border" : "TOSCYC2A.bmp", "area" : "TZSCYC2A.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBSTUP_6.def", "x" : 604, "y" : 0, "border" : "TOSBEH2A.bmp", "area" : "TZSBEH2A.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 30, "built" : 31 },
|
||||
"fort" : {"normal" : 12, "built" : 13 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/Stronghold",
|
||||
|
||||
"townBackground": "TBSTBACK.bmp",
|
||||
|
@ -113,11 +113,6 @@
|
||||
"dwellingUpLvl6": { "id" : 42, "animation" : "TBTWUP_5.def", "x" : 681, "y" : 157, "z" : 2, "border" : "TOTNAG2.bmp", "area" : "TZTNAG2.bmp" },
|
||||
"dwellingUpLvl7": { "id" : 43, "animation" : "TBTWUP_6.def", "x" : 75, "y" : 91, "z" : -1, "border" : "TOTTIT2.bmp", "area" : "TZTTIT2.bmp" }
|
||||
},
|
||||
"icons" :
|
||||
{
|
||||
"village" : {"normal" : 22, "built" : 23 },
|
||||
"fort" : {"normal" : 4, "built" : 5 }
|
||||
},
|
||||
|
||||
"musicTheme" : "music/TowerTown",
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI artifact format",
|
||||
"description" : "Format used to define new artifacts in VCMI",
|
||||
"required" : [ "class", "graphics", "text", "type", "value" ],
|
||||
"required" : [ "class", "text", "type", "value" ],
|
||||
|
||||
"definitions" : {
|
||||
"growingBonusList" : {
|
||||
@ -46,13 +46,8 @@
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "Graphical files associated with the artifact",
|
||||
//"required" : [ "iconIndex", "image", "map" ],
|
||||
"required" : [ "iconIndex" ],
|
||||
"required" : [ "image", "map" ],
|
||||
"properties":{
|
||||
"iconIndex": {
|
||||
"type":"number",
|
||||
"description": "index of icon of this artifact in .def file"
|
||||
},
|
||||
"image": {
|
||||
"type":"string",
|
||||
"description": "Base image for this artifact, used for example in hero screen"
|
||||
|
@ -166,8 +166,7 @@
|
||||
"additionalProperties" : false,
|
||||
"description": "Describes how this creature looks like during battles",
|
||||
"required" : [
|
||||
"animationTime", "iconIndex",
|
||||
"map", "animation", "timeBetweenFidgets"
|
||||
"animationTime", "animation", "timeBetweenFidgets"
|
||||
],
|
||||
"properties":{
|
||||
"animationTime": {
|
||||
@ -198,10 +197,6 @@
|
||||
"type":"string",
|
||||
"description": "Small icon for this creature, used for example in exchange screen"
|
||||
},
|
||||
"iconIndex": {
|
||||
"type":"number",
|
||||
"description": "Index of icon of this creature in .def file"
|
||||
},
|
||||
|
||||
"map": {
|
||||
"type":"string",
|
||||
|
@ -1,4 +1,32 @@
|
||||
{
|
||||
"definitions" : {
|
||||
"townIcon" :
|
||||
{
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "small", "large" ],
|
||||
"properties" : {
|
||||
"small" : { "type" : "string" },
|
||||
"large" : { "type" : "string" }
|
||||
}
|
||||
},
|
||||
"townIconPair" : {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "normal", "built" ],
|
||||
"properties": {
|
||||
"built": {
|
||||
"$ref" : "#/definitions/townIcon",
|
||||
"description": "Icon used after player build something in town"
|
||||
},
|
||||
"normal": {
|
||||
"$ref" : "#/definitions/townIcon",
|
||||
"description": "Icon used normally"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"type":"object",
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI faction format",
|
||||
@ -79,7 +107,7 @@
|
||||
"additionalProperties" : false,
|
||||
"required" : [
|
||||
"adventureMap", "buildingsIcons", "buildings", "creatures", "guildWindow", "names",
|
||||
"hallBackground", "hallSlots", "horde", "icons", "mageGuild", "moatDamage",
|
||||
"hallBackground", "hallSlots", "horde", "mageGuild", "moatDamage",
|
||||
"musicTheme", "siege", "structures", "townBackground", "warMachine"
|
||||
],
|
||||
"description": "town",
|
||||
@ -193,36 +221,12 @@
|
||||
"required" : [ "fort", "village" ],
|
||||
"properties":{
|
||||
"fort": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "normal", "built" ],
|
||||
"description": "Icons for town with built fort",
|
||||
"properties":{
|
||||
"built": {
|
||||
"type":"number",
|
||||
"description": "Icon used after player build something in town"
|
||||
},
|
||||
"normal": {
|
||||
"type":"number",
|
||||
"description": "Icon used normally"
|
||||
}
|
||||
}
|
||||
"$ref" : "#/definitions/townIconPair",
|
||||
"description": "Icons for town with built fort"
|
||||
},
|
||||
"village": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "normal", "built" ],
|
||||
"description": "Icons for town without fort",
|
||||
"properties":{
|
||||
"built": {
|
||||
"type":"number",
|
||||
"description": "Icon used after player build something in town"
|
||||
},
|
||||
"normal": {
|
||||
"type":"number",
|
||||
"description": "Icon used normally"
|
||||
}
|
||||
}
|
||||
"$ref" : "#/definitions/townIconPair",
|
||||
"description": "Icons for town without fort"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -3,7 +3,16 @@
|
||||
"$schema": "http://json-schema.org/draft-04/schema",
|
||||
"title" : "VCMI hero format",
|
||||
"description" : "Format used to define new heroes in VCMI",
|
||||
"required": [ "army", "class", "images", "skills", "texts" ],
|
||||
"required": [ "army", "class", "skills", "texts" ],
|
||||
|
||||
"oneOf" : [
|
||||
{
|
||||
"required" : [ "images" ]
|
||||
},
|
||||
{
|
||||
"required" : [ "index" ]
|
||||
}
|
||||
],
|
||||
|
||||
"additionalProperties" : false,
|
||||
"properties":{
|
||||
@ -46,18 +55,14 @@
|
||||
},
|
||||
"female": {
|
||||
"type":"boolean",
|
||||
"description": "This hero is female by default"
|
||||
"description": "This hero is female (changeable via editor)"
|
||||
},
|
||||
"images": {
|
||||
"type":"object",
|
||||
"additionalProperties" : false,
|
||||
"description": "images",
|
||||
"required": [ "index" ],
|
||||
"required": [ "large", "small", "specialtyLarge", "specialtySmall" ],
|
||||
"properties":{
|
||||
"index": {
|
||||
"type":"number",
|
||||
"description": "Index of image in portraitsLarge/portraitsSmall files"
|
||||
},
|
||||
"large": {
|
||||
"type":"string",
|
||||
"description": "Large version of portrait for use in hero screen"
|
||||
|
@ -173,7 +173,6 @@ std::vector<JsonNode> CArtHandler::loadLegacyData(size_t dataSize)
|
||||
{
|
||||
JsonNode artData;
|
||||
|
||||
artData["graphics"]["iconIndex"].Float() = i;
|
||||
artData["text"]["name"].String() = parser.readString();
|
||||
artData["text"]["event"].String() = events.readString();
|
||||
artData["value"].Float() = parser.readNumber();
|
||||
@ -200,6 +199,10 @@ void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->id = ArtifactID(artifacts.size());
|
||||
if (object->id < ArtifactID::ART_SELECTION)
|
||||
object->iconIndex = object->id;
|
||||
else
|
||||
object->iconIndex = object->id + 2;
|
||||
|
||||
artifacts.push_back(object);
|
||||
|
||||
@ -210,6 +213,10 @@ void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->id = ArtifactID(index);
|
||||
if (object->id < ArtifactID::ART_SELECTION)
|
||||
object->iconIndex = object->id;
|
||||
else
|
||||
object->iconIndex = object->id + 2;
|
||||
|
||||
assert(artifacts[index] == nullptr); // ensure that this id was not loaded before
|
||||
artifacts[index] = object;
|
||||
@ -236,7 +243,6 @@ CArtifact * CArtHandler::loadFromJson(const JsonNode & node)
|
||||
art->eventText = text["event"].String();
|
||||
|
||||
const JsonNode & graphics = node["graphics"];
|
||||
art->iconIndex = graphics["iconIndex"].Float();
|
||||
art->image = graphics["image"].String();
|
||||
|
||||
if (!graphics["large"].isNull())
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
std::string image;
|
||||
std::string large; // big image for cutom artifacts, used in drag & drop
|
||||
std::string advMapDef; //used for adventure map object
|
||||
si32 iconIndex; //TODO: handle automatically
|
||||
si32 iconIndex;
|
||||
|
||||
const std::string &Name() const; //getter
|
||||
const std::string &Description() const; //getter
|
||||
|
@ -282,8 +282,6 @@ std::vector<JsonNode> CCreatureHandler::loadLegacyData(size_t dataSize)
|
||||
|
||||
JsonNode data;
|
||||
|
||||
data["graphics"]["iconIndex"].Float() = h3Data.size() + 2; // +2 for empty\selection images
|
||||
|
||||
data["name"]["singular"].String() = parser.readString();
|
||||
data["name"]["plural"].String() = parser.readString();
|
||||
|
||||
@ -326,6 +324,7 @@ void CCreatureHandler::loadObject(std::string scope, std::string name, const Jso
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->idNumber = CreatureID(creatures.size());
|
||||
object->iconIndex = object->idNumber + 2;
|
||||
|
||||
creatures.push_back(object);
|
||||
|
||||
@ -341,6 +340,7 @@ void CCreatureHandler::loadObject(std::string scope, std::string name, const Jso
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->idNumber = CreatureID(index);
|
||||
object->iconIndex = object->idNumber + 2;
|
||||
|
||||
assert(creatures[index] == nullptr); // ensure that this id was not loaded before
|
||||
creatures[index] = object;
|
||||
@ -584,7 +584,8 @@ void CCreatureHandler::loadJsonAnimation(CCreature * cre, const JsonNode & graph
|
||||
cre->animation.missleFrameAngles = missile["frameAngles"].convertTo<std::vector<double> >();
|
||||
|
||||
cre->advMapDef = graphics["map"].String();
|
||||
cre->iconIndex = graphics["iconIndex"].Float();
|
||||
cre->smallIconName = graphics["iconSmall"].String();
|
||||
cre->largeIconName = graphics["iconLarge"].String();
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & config)
|
||||
|
@ -49,6 +49,10 @@ public:
|
||||
std::string advMapDef; //for new creatures only, image for adventure map
|
||||
si32 iconIndex; // index of icon in files like twcrport
|
||||
|
||||
/// names of files with appropriate icons. Used only during loading
|
||||
std::string smallIconName;
|
||||
std::string largeIconName;
|
||||
|
||||
struct CreatureAnimation
|
||||
{
|
||||
double timeBetweenFidgets, walkAnimationTime, attackAnimationTime, flightAnimationDistance;
|
||||
@ -123,7 +127,7 @@ public:
|
||||
& fightValue & AIValue & growth & hordeGrowth
|
||||
& ammMin & ammMax & level
|
||||
& abilityText & animDefName & advMapDef;
|
||||
h & iconIndex;
|
||||
h & iconIndex & smallIconName & largeIconName;
|
||||
|
||||
h & idNumber & faction & sounds & animation;
|
||||
|
||||
|
@ -228,7 +228,6 @@ CHero * CHeroHandler::loadFromJson(const JsonNode & node)
|
||||
hero->specTooltip = node["texts"]["specialty"]["tooltip"].String();
|
||||
hero->specDescr = node["texts"]["specialty"]["description"].String();
|
||||
|
||||
hero->imageIndex = node["images"]["index"].Float();
|
||||
hero->iconSpecSmall = node["images"]["specialtySmall"].String();
|
||||
hero->iconSpecLarge = node["images"]["specialtyLarge"].String();
|
||||
hero->portraitSmall = node["images"]["small"].String();
|
||||
@ -439,8 +438,6 @@ std::vector<JsonNode> CHeroHandler::loadLegacyData(size_t dataSize)
|
||||
heroData["texts"]["specialty"]["tooltip"].String() = specParser.readString();
|
||||
heroData["texts"]["specialty"]["description"].String() = specParser.readString();
|
||||
|
||||
heroData["images"]["index"].Float() = i;
|
||||
|
||||
for(int x=0;x<3;x++)
|
||||
{
|
||||
JsonNode armySlot;
|
||||
@ -463,6 +460,7 @@ void CHeroHandler::loadObject(std::string scope, std::string name, const JsonNod
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->ID = heroes.size();
|
||||
object->imageIndex = heroes.size() + 8; // 2 special frames + some extra portraits
|
||||
|
||||
heroes.push_back(object);
|
||||
|
||||
@ -473,6 +471,7 @@ void CHeroHandler::loadObject(std::string scope, std::string name, const JsonNod
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->ID = index;
|
||||
object->imageIndex = index;
|
||||
|
||||
assert(heroes[index] == nullptr); // ensure that this id was not loaded before
|
||||
heroes[index] = object;
|
||||
|
@ -70,11 +70,11 @@ static void showInfoDialog(const PlayerColor playerID, const ui32 txtID, const u
|
||||
IObjectInterface::cb->sendAndApply(&iw);
|
||||
}
|
||||
|
||||
static void showInfoDialog(const ObjectInstanceID heroID, const ui32 txtID, const ui16 soundID)
|
||||
/*static void showInfoDialog(const ObjectInstanceID heroID, const ui32 txtID, const ui16 soundID)
|
||||
{
|
||||
const PlayerColor playerID = IObjectInterface::cb->getOwner(heroID);
|
||||
showInfoDialog(playerID,txtID,soundID);
|
||||
}
|
||||
}*/
|
||||
|
||||
static void showInfoDialog(const CGHeroInstance* h, const ui32 txtID, const ui16 soundID)
|
||||
{
|
||||
|
@ -428,32 +428,33 @@ void CTownHandler::loadSiegeScreen(CTown &town, const JsonNode & source)
|
||||
pos[1] = JsonToPoint(source["static"]["background"]);
|
||||
}
|
||||
|
||||
static void readIcon(JsonNode source, std::string & small, std::string & large)
|
||||
{
|
||||
if (source.getType() == JsonNode::DATA_STRUCT) // don't crash on old format
|
||||
{
|
||||
small = source["small"].String();
|
||||
large = source["large"].String();
|
||||
}
|
||||
}
|
||||
|
||||
void CTownHandler::loadClientData(CTown &town, const JsonNode & source)
|
||||
{
|
||||
town.clientInfo.icons[0][0] = source["icons"]["village"]["normal"].Float();
|
||||
town.clientInfo.icons[0][1] = source["icons"]["village"]["built"].Float();
|
||||
town.clientInfo.icons[1][0] = source["icons"]["fort"]["normal"].Float();
|
||||
town.clientInfo.icons[1][1] = source["icons"]["fort"]["built"].Float();
|
||||
CTown::ClientInfo & info = town.clientInfo;
|
||||
|
||||
town.clientInfo.hallBackground = source["hallBackground"].String();
|
||||
town.clientInfo.musicTheme = source["musicTheme"].String();
|
||||
town.clientInfo.townBackground = source["townBackground"].String();
|
||||
town.clientInfo.guildWindow = source["guildWindow"].String();
|
||||
town.clientInfo.buildingsIcons = source["buildingsIcons"].String();
|
||||
readIcon(source["icons"]["village"]["normal"], info.iconSmall[0][0], info.iconLarge[0][0]);
|
||||
readIcon(source["icons"]["village"]["built"], info.iconSmall[0][1], info.iconLarge[0][1]);
|
||||
readIcon(source["icons"]["fort"]["normal"], info.iconSmall[1][0], info.iconLarge[1][0]);
|
||||
readIcon(source["icons"]["fort"]["built"], info.iconSmall[1][1], info.iconLarge[1][1]);
|
||||
|
||||
town.clientInfo.advMapVillage = source["adventureMap"]["village"].String();
|
||||
town.clientInfo.advMapCastle = source["adventureMap"]["castle"].String();
|
||||
town.clientInfo.advMapCapitol = source["adventureMap"]["capitol"].String();
|
||||
info.hallBackground = source["hallBackground"].String();
|
||||
info.musicTheme = source["musicTheme"].String();
|
||||
info.townBackground = source["townBackground"].String();
|
||||
info.guildWindow = source["guildWindow"].String();
|
||||
info.buildingsIcons = source["buildingsIcons"].String();
|
||||
|
||||
const JsonNode *value = &source["adventureMap"]["dwellings"];
|
||||
if (!value->isNull())
|
||||
{
|
||||
BOOST_FOREACH (const JsonNode &d, value->Vector())
|
||||
{
|
||||
town.dwellings.push_back (d["graphics"].String());
|
||||
town.dwellingNames.push_back (d["name"].String());
|
||||
}
|
||||
}
|
||||
info.advMapVillage = source["adventureMap"]["village"].String();
|
||||
info.advMapCastle = source["adventureMap"]["castle"].String();
|
||||
info.advMapCapitol = source["adventureMap"]["capitol"].String();
|
||||
|
||||
loadTownHall(town, source["hallSlots"]);
|
||||
loadStructures(town, source["structures"]);
|
||||
@ -525,6 +526,12 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source)
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_FOREACH (const JsonNode &d, source["adventureMap"]["dwellings"].Vector())
|
||||
{
|
||||
town.dwellings.push_back (d["graphics"].String());
|
||||
town.dwellingNames.push_back (d["name"].String());
|
||||
}
|
||||
|
||||
loadBuildings(town, source["buildings"]);
|
||||
loadClientData(town,source);
|
||||
}
|
||||
@ -597,6 +604,14 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->index = factions.size();
|
||||
if (object->town)
|
||||
{
|
||||
auto & info = object->town->clientInfo;
|
||||
info.icons[0][0] = 8 + object->index * 4 + 0;
|
||||
info.icons[0][1] = 8 + object->index * 4 + 1;
|
||||
info.icons[1][0] = 8 + object->index * 4 + 2;
|
||||
info.icons[1][1] = 8 + object->index * 4 + 3;
|
||||
}
|
||||
|
||||
factions.push_back(object);
|
||||
|
||||
@ -607,6 +622,14 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod
|
||||
{
|
||||
auto object = loadFromJson(data);
|
||||
object->index = index;
|
||||
if (object->town)
|
||||
{
|
||||
auto & info = object->town->clientInfo;
|
||||
info.icons[0][0] = (GameConstants::F_NUMBER + object->index) * 2 + 0;
|
||||
info.icons[0][1] = (GameConstants::F_NUMBER + object->index) * 2 + 1;
|
||||
info.icons[1][0] = object->index * 2 + 0;
|
||||
info.icons[1][1] = object->index * 2 + 1;
|
||||
}
|
||||
|
||||
assert(factions[index] == nullptr); // ensure that this id was not loaded before
|
||||
factions[index] = object;
|
||||
|
@ -163,6 +163,8 @@ public:
|
||||
|
||||
//icons [fort is present?][build limit reached?] -> index of icon in def files
|
||||
int icons[2][2];
|
||||
std::string iconSmall[2][2]; /// icon names used during loading
|
||||
std::string iconLarge[2][2];
|
||||
|
||||
std::string musicTheme;
|
||||
std::string townBackground;
|
||||
@ -187,8 +189,8 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & icons & musicTheme & townBackground & guildWindow & buildingsIcons & hallBackground & hallSlots & structures;
|
||||
h & advMapVillage & advMapCastle & advMapCapitol;
|
||||
h & icons & iconSmall & iconLarge & musicTheme & townBackground & guildWindow & buildingsIcons & hallBackground;
|
||||
h & advMapVillage & advMapCastle & advMapCapitol & hallSlots & structures;
|
||||
h & siegePrefix & siegePositions & siegeShooter & siegeShooterCropHeight;
|
||||
}
|
||||
} clientInfo;
|
||||
|
Loading…
Reference in New Issue
Block a user