mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- generic string ID -> numeric ID resolution system
- - hero army and creature upgrade names are resolved using new system - - faction names and creatures in towns are resolved using new system - (linux) replaced build_data.sh with hopefully better vcmibuilder script - minor fixes
This commit is contained in:
parent
c9dd80ea6d
commit
85a23e298c
@ -113,6 +113,8 @@ if (NOT APPLE)
|
||||
install(DIRECTORY Mods/vcmi DESTINATION ${DATA_DIR}/Mods PATTERN ".svn" EXCLUDE)
|
||||
# copy only fs.json for WoG
|
||||
install(FILES Mods/WoG/filesystem.json DESTINATION ${DATA_DIR}/Mods/WoG)
|
||||
|
||||
install(FILES vcmibuilder DESTINATION ${BIN_DIR})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
|
160
build_data.sh
160
build_data.sh
@ -1,160 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2009,2010,2011 Frank Zago
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
|
||||
# Extract game data from various archives and create a tree with the right files
|
||||
|
||||
# Tools needed:
|
||||
# unshield: sudo apt-get install unshield
|
||||
# rename (from perl)
|
||||
# unrar: sudo apt-get install unrar
|
||||
|
||||
# Data files needed:
|
||||
# data1.cab and data1.hdr from the original 1st CDROM
|
||||
# Heroes3.snd from the original 2nd CDROM
|
||||
# the WoG release v3.58f: allinone_358f.zip
|
||||
# the VCMI distribution: vcmi_089.zip
|
||||
# the menu graphic pack: vcmi32menu.zip
|
||||
|
||||
# Usage: put this script and the 4 data files into the same directory
|
||||
# and run the script.
|
||||
|
||||
|
||||
DESTDIR=`pwd`/vcmi
|
||||
rm -rf $DESTDIR
|
||||
mkdir $DESTDIR
|
||||
|
||||
# Extract Data from original CD-ROM
|
||||
# 376917499 2002-06-14 14:32 _setup/data1.cab
|
||||
# 27308 2002-06-14 14:32 _setup/data1.hdr
|
||||
|
||||
rm -rf temp
|
||||
mkdir temp
|
||||
cd temp
|
||||
|
||||
echo Extracting data1.cab
|
||||
unshield x ../data1.cab || exit 1
|
||||
echo Done extracting data1.cab
|
||||
|
||||
rm -rf CommonFiles
|
||||
rm -rf GameUpdate
|
||||
rm -rf Support
|
||||
rm -rf Program_Files/mplayer
|
||||
rm -rf Program_Files/ONLINE
|
||||
|
||||
find . -name "*.DLL" | xargs rm -f
|
||||
find . -name "*.dll" | xargs rm -f
|
||||
find . -name "*.pdf" -print0 | xargs -0 rm -f
|
||||
find . -name "*.HLP" | xargs rm -f
|
||||
find . -name "*.TXT" | xargs rm -f
|
||||
find . -name "*.cnt" | xargs rm -f
|
||||
find . -name "*.exe" | xargs rm -f
|
||||
find . -name "*.EXE" | xargs rm -f
|
||||
find . -name "*.ASI" | xargs rm -f
|
||||
|
||||
# Tree is clean. Move extracted files to their final destination
|
||||
mv Program_Files/* $DESTDIR
|
||||
cd ..
|
||||
|
||||
# Copy Heroes3.snd from 2nd CDROM and rename it to avoid a name conflict.
|
||||
cp Heroes3.snd $DESTDIR/Data/Heroes3-cd2.snd
|
||||
|
||||
# Extract Data from WoG
|
||||
# 39753248 allinone_358f.zip
|
||||
|
||||
rm -rf temp
|
||||
mkdir temp
|
||||
cd temp
|
||||
|
||||
unzip ../allinone_358f.zip
|
||||
cd WoG_Install
|
||||
mkdir temp
|
||||
cd temp
|
||||
unrar x -o+ ../main1.wog
|
||||
unrar x -o+ ../main2.wog
|
||||
unrar x -o+ ../main3.wog
|
||||
unrar x -o+ ../main4.wog
|
||||
#unrar x -o+ ../main5.wog
|
||||
#unrar x -o+ ../main6_optional.wog
|
||||
#unrar x -o+ ../main7_optional.wog
|
||||
#unrar x -o+ ../main8_optional.wog
|
||||
#unrar x -o+ ../main9_optional.wog
|
||||
|
||||
mkdir -p $DESTDIR/Data/zvs/
|
||||
mv data/zvs/Lib1.res $DESTDIR/Data/zvs/
|
||||
|
||||
rm -rf picsall Documentation Data data update
|
||||
rm -f action.txt h3bitmap.txt H3sprite.txt InstMult.txt
|
||||
rm -f ACTION.TXT H3BITMAP.TXT H3SPRITE.TXT INSTMULT.TXT
|
||||
rm -f *.DLL *.dll *.fnt readme.txt *.exe *.EXE *.lod *.vid h3ab_ahd.snd
|
||||
|
||||
rename 'y/a-z/A-Z/' *
|
||||
|
||||
# Tree is clean. Move extracted files to their final destination
|
||||
|
||||
mv MAPS/* $DESTDIR/Maps
|
||||
rmdir MAPS
|
||||
mkdir $DESTDIR/Sprites
|
||||
mv *.MSK *.DEF $DESTDIR/Sprites
|
||||
mv * $DESTDIR/Data/
|
||||
|
||||
cd ../../..
|
||||
|
||||
|
||||
# Extract Data from VCMI release
|
||||
|
||||
rm -rf temp
|
||||
mkdir temp
|
||||
cd temp
|
||||
|
||||
#7zr x ../vcmi_088b.7z
|
||||
unzip ../vcmi_089.zip
|
||||
|
||||
find . -name "*.dll" | xargs rm -f
|
||||
find . -name "*.DLL" | xargs rm -f
|
||||
find . -name "*.exe" | xargs rm -f
|
||||
rm -rf AI
|
||||
rm -f AUTHORS ChangeLog license.txt Microsoft.VC90.CRT.manifest
|
||||
rm -rf MP3
|
||||
rm -rf Games
|
||||
|
||||
# Tree is clean. Move extracted files to their final destination
|
||||
|
||||
cp -a . $DESTDIR
|
||||
|
||||
cd ..
|
||||
|
||||
|
||||
# Extract graphics package
|
||||
|
||||
rm -rf temp
|
||||
mkdir temp
|
||||
cd temp
|
||||
|
||||
unzip ../vcmi32menu.zip
|
||||
|
||||
# Tree is already clean. Move extracted files to their final destination
|
||||
|
||||
cp -a . $DESTDIR
|
||||
|
||||
cd ..
|
||||
|
||||
|
||||
# Done
|
||||
echo
|
||||
echo The complete game data is at $DESTDIR
|
||||
echo You could move it to /usr/local/share/games/
|
||||
echo and configure vcmi with:
|
||||
echo ./configure --datadir=/usr/local/share/games/ --bindir=\`pwd\` --libdir=\`pwd\`
|
||||
echo
|
||||
echo If you want to run from your VCMI tree, create those links
|
||||
echo at the root of your VCMI tree:
|
||||
echo ln -s client/vcmiclient .
|
||||
echo ln -s server/vcmiserver .
|
||||
echo ln -s AI/GeniusAI/.libs/GeniusAI.so .
|
@ -294,7 +294,7 @@ void CTownList::CTownItem::update()
|
||||
{
|
||||
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
|
||||
|
||||
picture->setFrame(iconIndex);
|
||||
picture->setFrame(iconIndex + 2);
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
@ -1072,7 +1072,7 @@ void CCreaInfo::clickRight(tribool down, bool previousState)
|
||||
CInfoPopup *mess = new CInfoPopup();//creating popup
|
||||
mess->free = true;
|
||||
mess->bitmap = CMessage::drawBoxTextBitmapSub
|
||||
(LOCPLINT->playerID, descr,graphics->bigImgs[creature->idNumber],"");
|
||||
(LOCPLINT->playerID, descr,graphics->bigImgs[creature->iconIndex],"");
|
||||
mess->pos.x = screen->w/2 - mess->bitmap->w/2;
|
||||
mess->pos.y = screen->h/2 - mess->bitmap->h/2;
|
||||
GH.pushInt(mess);
|
||||
|
@ -837,7 +837,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
|
||||
{
|
||||
|
||||
PixelFormat screenFormat = PIX_FMT_NONE;
|
||||
if (screen->format->Bshift < screen->format->Rshift)
|
||||
if (screen->format->Bshift > screen->format->Rshift)
|
||||
{
|
||||
// this a BGR surface
|
||||
switch (screen->format->BytesPerPixel)
|
||||
|
@ -134,7 +134,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11], [12, 13] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Pikeman", "Halberdier"],
|
||||
["Archer", "HeavyCrossbowman"],
|
||||
["Griffin", "RoyalGriffin"],
|
||||
["Swordsman", "Crusader"],
|
||||
["Monk", "Zealot"],
|
||||
["Cavalier", "Champion"],
|
||||
["Angel", "Archangel"]
|
||||
],
|
||||
"horde" : [ 2, -1 ],
|
||||
"primaryResource" : 127,
|
||||
"mageGuild" : 4,
|
||||
@ -375,7 +384,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [14, 15], [16, 17], [18, 19], [20, 21], [22, 23], [24, 25], [26, 27] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Centaur", "EliteCentaur"],
|
||||
["Dwarf", "BattleDwarf"],
|
||||
["WoodElf", "GrandElf"],
|
||||
["Pegasus", "SilverPegasus"],
|
||||
["Treefolk", "BriarTreefolk"],
|
||||
["Unicorn", "WarUnicorn"],
|
||||
["GreenDragon", "GoldDragon"]
|
||||
],
|
||||
"horde" : [ 1, 4 ],
|
||||
"mageGuild" : 5,
|
||||
"primaryResource" : 4,
|
||||
@ -612,7 +630,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [28, 29], [30, 31], [32, 33], [34, 35], [36, 37], [38, 39], [40, 41] ],
|
||||
"creatures" :
|
||||
[
|
||||
["ApprenticeGremlin", "MasterGremlin"],
|
||||
["StoneGargoyle", "ObsidianGargoyle"],
|
||||
["IronGolem", "StoneGolem"],
|
||||
["Mage", "ArchMage"],
|
||||
["Genie", "Caliph"],
|
||||
["NagaSentinel", "NagaGuardian"],
|
||||
["LesserTitan", "GreaterTitan"]
|
||||
],
|
||||
"horde" : [ 1, -1 ],
|
||||
"primaryResource" : 5,
|
||||
"mageGuild" : 5,
|
||||
@ -847,7 +874,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [42, 43], [44, 45], [46, 47], [48, 49], [50, 51], [52, 53], [54, 55] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Imp", "Familiar"],
|
||||
["Gog", "Magog"],
|
||||
["HellHound", "Cerberus"],
|
||||
["Single-HornedDemon", "Dual-HornedDemon"],
|
||||
["PitFiend", "PitFoe"],
|
||||
["Efreet", "EfreetSultan"],
|
||||
["Devil", "ArchDevil"]
|
||||
],
|
||||
"horde" : [ 0, 2 ],
|
||||
"mageGuild" : 5,
|
||||
"primaryResource" : 1,
|
||||
@ -1088,7 +1124,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [56, 57], [58, 59], [60, 61], [62, 63], [64, 65], [66, 67], [68, 69] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Skeleton", "SkeletonWarrior"],
|
||||
["Zombie", "ZombieLord"],
|
||||
["Wight", "Wraith"],
|
||||
["Vampire", "Nosferatu"],
|
||||
["Lich", "PowerLich"],
|
||||
["BlackKnight", "BlackLord"],
|
||||
["BoneDragon", "GhostDragon"]
|
||||
],
|
||||
"horde" : [ 0, -1 ],
|
||||
"mageGuild" : 5,
|
||||
"primaryResource" : 127,
|
||||
@ -1323,7 +1368,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [70, 71], [72, 73], [74, 75], [76, 77], [78, 79], [80, 81], [82, 83] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Troglodyte", "InfernalTroglodyte"],
|
||||
["Harpy", "HarpyHag"],
|
||||
["Beholder", "EvilEye"],
|
||||
["Medusa", "MedusaQueen"],
|
||||
["Minotaur", "MinotaurKing"],
|
||||
["Manticore", "Scorpicore"],
|
||||
["RedDragon", "BlackDragon"]
|
||||
],
|
||||
"horde" : [ 0, -1 ],
|
||||
"mageGuild" : 5,
|
||||
"primaryResource" : 3,
|
||||
@ -1556,7 +1610,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [84, 85], [86, 87], [88, 89], [90, 91], [92, 93], [94, 95], [96, 97] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Goblin", "Hobgoblin"],
|
||||
["GoblinWolfRider", "HobgoblinWolfRider"],
|
||||
["Orc", "OrcChieftain"],
|
||||
["Ogre", "OgreMage"],
|
||||
["Roc", "Thunderbird"],
|
||||
["Cyclops", "CyclopsLord"],
|
||||
["YoungBehemoth", "AncientBehemoth"]
|
||||
],
|
||||
"horde" : [ 0, -1 ],
|
||||
"mageGuild" : 3,
|
||||
"primaryResource" : 127,
|
||||
@ -1791,7 +1854,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [98, 99], [100, 101], [104, 105], [106, 107], [102, 103], [108, 109], [110, 111] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Gnoll", "GnollMarauder"],
|
||||
["PrimitiveLizardman", "AdvancedLizardman"],
|
||||
["Dragonflies", "FireDragonFly"],
|
||||
["Basilisk", "GreaterBasilisk"],
|
||||
["CopperGorgon", "BronzeGorgon"],
|
||||
["Wyvern", "WyvernMonarch"],
|
||||
["Hydra", "ChaosHydra"]
|
||||
],
|
||||
"horde" : [ 0, -1 ],
|
||||
"mageGuild" : 3,
|
||||
"primaryResource" : 127,
|
||||
@ -2031,7 +2103,16 @@
|
||||
[ [ 30, 37 ], [ 31, 38 ], [ 32, 39 ], [ 33, 40 ] ],
|
||||
[ [ 34, 41 ], [ 35, 42 ], [ 36, 43 ] ]
|
||||
],
|
||||
"creatures" : [ [118, 119], [112, 127], [115, 123], [114, 129], [113, 125], [120, 121], [130, 131] ],
|
||||
"creatures" :
|
||||
[
|
||||
["Pixie", "Sprite"],
|
||||
["AirElemental", "StormElemental"],
|
||||
["WaterElemental", "IceElemental"],
|
||||
["FireElemental", "ElectricityElemental"],
|
||||
["EarthElemental", "StoneElemental"],
|
||||
["PsiElemental", "MagicElemental"],
|
||||
["Firebird", "Pheonix"]
|
||||
],
|
||||
"horde" : [ 0, -1 ],
|
||||
"mageGuild" : 5,
|
||||
"primaryResource" : 1,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -318,21 +318,23 @@ void CCreatureHandler::loadCreatures()
|
||||
int creatureID = creature["id"].Float();
|
||||
const JsonNode *value;
|
||||
|
||||
/* A creature can have several names. */
|
||||
BOOST_FOREACH(const JsonNode &name, creature["name"].Vector())
|
||||
{
|
||||
boost::assign::insert(nameToID)(name.String(), creatureID);
|
||||
}
|
||||
|
||||
// Set various creature properties
|
||||
CCreature *c = creatures[creatureID];
|
||||
c->level = creature["level"].Float();
|
||||
c->faction = creature["faction"].Float();
|
||||
|
||||
c->animDefName = creature["defname"].String();
|
||||
|
||||
VLC->modh->identifiers.requestIdentifier(std::string("faction.") + creature["faction"].String(), [=](si32 faction)
|
||||
{
|
||||
c->faction = faction;
|
||||
});
|
||||
|
||||
BOOST_FOREACH(const JsonNode &value, creature["upgrades"].Vector())
|
||||
{
|
||||
c->upgradeNames.insert(value.String());
|
||||
VLC->modh->identifiers.requestIdentifier(std::string("creature.") + value.String(), [=](si32 identifier)
|
||||
{
|
||||
c->upgrades.insert(identifier);
|
||||
});
|
||||
}
|
||||
|
||||
value = &creature["projectile_defname"];
|
||||
@ -360,6 +362,12 @@ void CCreatureHandler::loadCreatures()
|
||||
AddAbility(c, ability.Vector());
|
||||
}
|
||||
}
|
||||
|
||||
/* A creature can have several names. */
|
||||
BOOST_FOREACH(const JsonNode &name, creature["name"].Vector())
|
||||
{
|
||||
VLC->modh->identifiers.registerObject(std::string("creature.") + name.String(), c->idNumber);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const JsonNode &creature, config["unused_creatures"].Vector())
|
||||
@ -568,34 +576,12 @@ void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser &
|
||||
parser.endLine();
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadSoundsInfo()
|
||||
void CCreatureHandler::loadCreatureSounds(JsonNode node, si32 creaID) // passing node by value to get clearer binding code
|
||||
{
|
||||
tlog5 << "\t\tReading config/cr_sounds.json" << std::endl;
|
||||
const JsonNode config(ResourceID("config/cr_sounds.json"));
|
||||
|
||||
if (!config["creature_sounds"].isNull())
|
||||
{
|
||||
|
||||
BOOST_FOREACH(const JsonNode &node, config["creature_sounds"].Vector())
|
||||
{
|
||||
const JsonNode *value;
|
||||
int id;
|
||||
|
||||
value = &node["name"];
|
||||
|
||||
bmap<std::string,int>::const_iterator i = nameToID.find(value->String());
|
||||
if (i != nameToID.end())
|
||||
id = i->second;
|
||||
else
|
||||
{
|
||||
tlog1 << "Sound info for an unknown creature: " << value->String() << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* This is a bit ugly. Maybe we should use an array for
|
||||
* sound ids instead of separate variables and define
|
||||
* attack/defend/killed/... as indexes. */
|
||||
#define GET_SOUND_VALUE(value_name) do { value = &node[#value_name]; if (!value->isNull()) creatures[id]->sounds.value_name = value->String(); } while(0)
|
||||
/* This is a bit ugly. Maybe we should use an array for
|
||||
* sound ids instead of separate variables and define
|
||||
* attack/defend/killed/... as indexes. */
|
||||
#define GET_SOUND_VALUE(value_name) do { creatures[creaID]->sounds.value_name = node[#value_name].String(); } while(0)
|
||||
GET_SOUND_VALUE(attack);
|
||||
GET_SOUND_VALUE(defend);
|
||||
GET_SOUND_VALUE(killed);
|
||||
@ -607,6 +593,20 @@ void CCreatureHandler::loadSoundsInfo()
|
||||
GET_SOUND_VALUE(startMoving);
|
||||
GET_SOUND_VALUE(endMoving);
|
||||
#undef GET_SOUND_VALUE
|
||||
}
|
||||
|
||||
void CCreatureHandler::loadSoundsInfo()
|
||||
{
|
||||
tlog5 << "\t\tReading config/cr_sounds.json" << std::endl;
|
||||
const JsonNode config(ResourceID("config/cr_sounds.json"));
|
||||
|
||||
if (!config["creature_sounds"].isNull())
|
||||
{
|
||||
|
||||
BOOST_FOREACH(const JsonNode &node, config["creature_sounds"].Vector())
|
||||
{
|
||||
VLC->modh->identifiers.requestIdentifier(std::string("creature.") + node["name"].String(),
|
||||
boost::bind(&CCreatureHandler::loadCreatureSounds, this, node, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -620,11 +620,10 @@ void CCreatureHandler::load(const JsonNode & node)
|
||||
CCreature * creature = loadCreature(entry.second);
|
||||
creature->nameRef = entry.first;
|
||||
creature->idNumber = creatures.size();
|
||||
nameToID[entry.first] = creatures.size();
|
||||
|
||||
creatures.push_back(creature);
|
||||
tlog3 << "Added creature: " << entry.first << "\n";
|
||||
//TODO: notify modHandler that this refName can be resolved to ID
|
||||
VLC->modh->identifiers.registerObject(std::string("creature.") + creature->nameRef, creature->idNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -640,7 +639,6 @@ CCreature * CCreatureHandler::loadCreature(const JsonNode & node)
|
||||
cre->cost = Res::ResourceSet(node["cost"]);
|
||||
|
||||
cre->level = node["level"].Float();
|
||||
cre->faction = node["faction"].Float(); //TODO: replaced by string -> id conversion
|
||||
cre->fightValue = node["fightValue"].Float();
|
||||
cre->AIValue = node["aiValue"].Float();
|
||||
cre->growth = node["growth"].Float();
|
||||
@ -658,10 +656,22 @@ CCreature * CCreatureHandler::loadCreature(const JsonNode & node)
|
||||
cre->ammMin = amounts["min"].Float();
|
||||
cre->ammMax = amounts["max"].Float();
|
||||
|
||||
std::string factionStr = node["faction"].String();
|
||||
if (factionStr.empty())
|
||||
factionStr = "neutral"; //TODO: should be done in schema
|
||||
|
||||
VLC->modh->identifiers.requestIdentifier(std::string("faction.") + factionStr, [=](si32 faction)
|
||||
{
|
||||
cre->faction = faction;
|
||||
});
|
||||
|
||||
//optional
|
||||
BOOST_FOREACH (auto & str, node["upgrades"].Vector())
|
||||
{
|
||||
cre->upgradeNames.insert (str.String());
|
||||
VLC->modh->identifiers.requestIdentifier(std::string("creature.") + str.String(), [=](si32 identifier)
|
||||
{
|
||||
cre->upgrades.insert(identifier);
|
||||
});
|
||||
}
|
||||
|
||||
if (!node["shots"].isNull())
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
bool valid() const;
|
||||
|
||||
void addBonus(int val, int type, int subtype = -1);
|
||||
std::string nodeName() const OVERRIDE;
|
||||
std::string nodeName() const override;
|
||||
//void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
|
||||
|
||||
template<typename RanGen>
|
||||
@ -102,7 +102,7 @@ public:
|
||||
{
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & namePl & nameSing & nameRef
|
||||
& cost & upgradeNames & upgrades
|
||||
& cost & upgrades
|
||||
& fightValue & AIValue & growth & hordeGrowth
|
||||
& ammMin & ammMax & level
|
||||
& abilityText & abilityRefs & animDefName & advMapDef;
|
||||
@ -131,7 +131,6 @@ public:
|
||||
std::set<int> notUsedMonsters;
|
||||
std::set<TCreature> doubledCreatures; //they get double week
|
||||
std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info
|
||||
bmap<std::string,int> nameToID;
|
||||
|
||||
//stack exp
|
||||
std::map<TBonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description
|
||||
@ -160,6 +159,7 @@ public:
|
||||
/// read one line from cranim.txt
|
||||
void loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser &parser);
|
||||
/// load cr_sounds.json config
|
||||
void loadCreatureSounds(JsonNode node, si32 creaID);
|
||||
void loadSoundsInfo();
|
||||
/// parse crexpbon.txt file from H3
|
||||
void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser);
|
||||
@ -177,7 +177,7 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
|
||||
h & notUsedMonsters & creatures & nameToID;
|
||||
h & notUsedMonsters & creatures;
|
||||
h & stackBonuses & expRanks & maxExpPerBattle & expAfterUpgrade;
|
||||
h & factionCommanders & skillLevels & skillRequirements & commanderLevelPremy;
|
||||
h & allCreatures;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "JsonNode.h"
|
||||
#include "GameConstants.h"
|
||||
#include "BattleHex.h"
|
||||
#include "CModHandler.h"
|
||||
|
||||
/*
|
||||
* CHeroHandler.cpp, part of VCMI engine
|
||||
@ -134,10 +135,15 @@ void CHeroHandler::loadHeroes()
|
||||
|
||||
for(int x=0;x<3;x++)
|
||||
{
|
||||
hero->lowStack[x] = parser.readNumber();
|
||||
hero->highStack[x] = parser.readNumber();
|
||||
hero->refTypeStack[x] = parser.readString();
|
||||
boost::algorithm::replace_all(hero->refTypeStack[x], " ", ""); //remove spaces
|
||||
hero->initialArmy[x].minAmount = parser.readNumber();
|
||||
hero->initialArmy[x].maxAmount = parser.readNumber();
|
||||
|
||||
std::string refName = parser.readString();
|
||||
boost::algorithm::replace_all(refName, " ", ""); //remove spaces
|
||||
VLC->modh->identifiers.requestIdentifier(std::string("creature.") + refName, [=](si32 creature)
|
||||
{
|
||||
hero->initialArmy[x].creature = creature;
|
||||
});
|
||||
}
|
||||
parser.endLine();
|
||||
|
||||
|
@ -33,14 +33,27 @@ struct SSpecialtyInfo
|
||||
class DLL_LINKAGE CHero
|
||||
{
|
||||
public:
|
||||
struct InitialArmyStack
|
||||
{
|
||||
ui32 minAmount;
|
||||
ui32 maxAmount;
|
||||
TCreature creature;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & minAmount & maxAmount & creature;
|
||||
}
|
||||
};
|
||||
|
||||
enum EHeroClasses {KNIGHT, CLERIC, RANGER, DRUID, ALCHEMIST, WIZARD,
|
||||
DEMONIAC, HERETIC, DEATHKNIGHT, NECROMANCER, WARLOCK, OVERLORD,
|
||||
BARBARIAN, BATTLEMAGE, BEASTMASTER, WITCH, PLANESWALKER, ELEMENTALIST};
|
||||
|
||||
std::string name; //name of hero
|
||||
si32 ID;
|
||||
ui32 lowStack[3], highStack[3]; //amount of units; described below
|
||||
std::string refTypeStack[3]; //reference names of units appearing in hero's army if he is recruited in tavern
|
||||
|
||||
InitialArmyStack initialArmy[3];
|
||||
|
||||
CHeroClass * heroClass;
|
||||
EHeroClasses heroType; //hero class
|
||||
std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
|
||||
@ -54,7 +67,7 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & name & ID & lowStack & highStack & refTypeStack & heroClass & heroType & secSkillsInit & spec & startingSpell & sex;
|
||||
h & name & ID & initialArmy & heroClass & heroType & secSkillsInit & spec & startingSpell & sex;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "JsonNode.h"
|
||||
#include "Filesystem/CResourceLoader.h"
|
||||
#include "Filesystem/ISimpleResourceLoader.h"
|
||||
|
||||
/*
|
||||
* CModHandler.h, part of VCMI engine
|
||||
*
|
||||
@ -25,6 +26,46 @@ class CTownHandler;
|
||||
class CGeneralTextHandler;
|
||||
class ResourceLocator;
|
||||
|
||||
void CIdentifierStorage::requestIdentifier(std::string name, const boost::function<void(si32)> & callback)
|
||||
{
|
||||
auto iter = registeredObjects.find(name);
|
||||
|
||||
if (iter != registeredObjects.end())
|
||||
callback(iter->second); //already registered - trigger callback immediately
|
||||
else
|
||||
missingObjects[name].push_back(callback); // queue callback
|
||||
}
|
||||
|
||||
void CIdentifierStorage::registerObject(std::string name, si32 identifier)
|
||||
{
|
||||
// do not allow to register same object twice
|
||||
assert(registeredObjects.find(name) == registeredObjects.end());
|
||||
|
||||
registeredObjects[name] = identifier;
|
||||
|
||||
auto iter = missingObjects.find(name);
|
||||
if (iter != missingObjects.end())
|
||||
{
|
||||
//call all awaiting callbacks
|
||||
BOOST_FOREACH(auto function, iter->second)
|
||||
{
|
||||
function(identifier);
|
||||
}
|
||||
missingObjects.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void CIdentifierStorage::finalize() const
|
||||
{
|
||||
// print list of missing objects and crash
|
||||
// in future should try to do some cleanup (like returning all id's as 0)
|
||||
BOOST_FOREACH(auto object, missingObjects)
|
||||
{
|
||||
tlog1 << "Error: object " << object.first << " was not found!\n";
|
||||
}
|
||||
assert(missingObjects.empty());
|
||||
}
|
||||
|
||||
CModHandler::CModHandler()
|
||||
{
|
||||
VLC->modh = this;
|
||||
@ -99,6 +140,7 @@ void CModHandler::loadActiveMods()
|
||||
VLC->creh->load(config["creatures"]);
|
||||
}
|
||||
VLC->creh->buildBonusTreeForTiers(); //do that after all new creatures are loaded
|
||||
identifiers.finalize();
|
||||
}
|
||||
|
||||
void CModHandler::reload()
|
||||
@ -118,16 +160,6 @@ void CModHandler::reload()
|
||||
|
||||
VLC->dobjinfo->gobjs[Obj::MONSTER][crea->idNumber] = info;
|
||||
}
|
||||
BOOST_FOREACH(auto up, crea->upgradeNames)
|
||||
{
|
||||
auto it = VLC->creh->nameToID.find(up);
|
||||
if (it != VLC->creh->nameToID.end())
|
||||
{
|
||||
crea->upgrades.insert (it->second);
|
||||
}
|
||||
else
|
||||
tlog2 << "Not found upgrade with name " << up << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,24 @@ class CModIndentifier;
|
||||
class CModInfo;
|
||||
class JsonNode;
|
||||
|
||||
/// class that stores all object identifiers strings and maps them to numeric ID's
|
||||
/// if possible, objects ID's should be in format <type>.<name>, camelCase e.g. "creature.grandElf"
|
||||
class CIdentifierStorage
|
||||
{
|
||||
std::map<std::string, si32 > registeredObjects;
|
||||
std::map<std::string, std::vector<boost::function<void(si32)> > > missingObjects;
|
||||
|
||||
public:
|
||||
/// request identifier for specific object name. If ID is not yet resolved callback will be queued
|
||||
/// and will be called later
|
||||
void requestIdentifier(std::string name, const boost::function<void(si32)> & callback);
|
||||
/// registers new object, calls all associated callbacks
|
||||
void registerObject(std::string name, si32 identifier);
|
||||
|
||||
/// called at the very end of loading to check for any missing ID's
|
||||
void finalize() const;
|
||||
};
|
||||
|
||||
typedef si32 TModID;
|
||||
|
||||
class DLL_LINKAGE CModInfo
|
||||
@ -41,12 +59,14 @@ public:
|
||||
|
||||
class DLL_LINKAGE CModHandler
|
||||
{
|
||||
public:
|
||||
//std::string currentConfig; //save settings in this file
|
||||
|
||||
std::map <TModID, CModInfo> allMods;
|
||||
std::set <TModID> activeMods;//TODO: use me
|
||||
|
||||
public:
|
||||
CIdentifierStorage identifiers;
|
||||
|
||||
/// management of game settings config
|
||||
void loadConfigFromFile (std::string name);
|
||||
void saveConfigToFile (std::string name);
|
||||
|
@ -783,38 +783,27 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
|
||||
|
||||
for(int stackNo=0; stackNo < howManyStacks; stackNo++)
|
||||
{
|
||||
int creID = 0;
|
||||
auto creItr = VLC->creh->nameToID.find(type->refTypeStack[stackNo]);
|
||||
if(creItr == VLC->creh->nameToID.end())
|
||||
{
|
||||
tlog1 << "Cannot find a creature named " << type->refTypeStack[stackNo] << std::endl;
|
||||
tlog1 << "Available creatures: \n";
|
||||
BOOST_FOREACH(auto i, VLC->creh->nameToID)
|
||||
{
|
||||
tlog1 << boost::format("\t%s => %d\n") % i.first % i.second;
|
||||
}
|
||||
}
|
||||
else
|
||||
creID = creItr->second;
|
||||
auto & stack = type->initialArmy[stackNo];
|
||||
|
||||
int range = type->highStack[stackNo] - type->lowStack[stackNo];
|
||||
int count = ran()%(range+1) + type->lowStack[stackNo];
|
||||
int range = stack.maxAmount - stack.minAmount;
|
||||
int count = ran()%(range+1) + stack.minAmount;
|
||||
|
||||
if(creID>=145 && creID<=149) //war machine
|
||||
if(stack.creature >= 145 &&
|
||||
stack.creature <= 149) //war machine
|
||||
{
|
||||
warMachinesGiven++;
|
||||
if(dst != this)
|
||||
continue;
|
||||
|
||||
int slot = -1, aid = -1;
|
||||
switch (creID)
|
||||
switch (stack.creature)
|
||||
{
|
||||
case 145: //catapult
|
||||
slot = ArtifactPosition::MACH4;
|
||||
aid = 3;
|
||||
break;
|
||||
default:
|
||||
aid = CArtHandler::convertMachineID(creID,true);
|
||||
aid = CArtHandler::convertMachineID(stack.creature, true);
|
||||
slot = 9 + aid;
|
||||
break;
|
||||
}
|
||||
@ -825,7 +814,7 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
|
||||
tlog3 << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid << std::endl;
|
||||
}
|
||||
else
|
||||
dst->setCreature(stackNo-warMachinesGiven, creID, count);
|
||||
dst->setCreature(stackNo-warMachinesGiven, stack.creature, count);
|
||||
}
|
||||
}
|
||||
void CGHeroInstance::initHeroDefInfo()
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "JsonNode.h"
|
||||
#include "GameConstants.h"
|
||||
#include "CModHandler.h"
|
||||
#include "Filesystem/CResourceLoader.h"
|
||||
|
||||
/*
|
||||
@ -402,14 +403,24 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source)
|
||||
town.hordeLvl[town.hordeLvl.size()] = node.Float();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const JsonNode &list, source["creatures"].Vector())
|
||||
const JsonVector & creatures = source["creatures"].Vector();
|
||||
|
||||
town.creatures.resize(creatures.size());
|
||||
|
||||
for (size_t i=0; i< creatures.size(); i++)
|
||||
{
|
||||
std::vector<TCreature> level;
|
||||
BOOST_FOREACH(const JsonNode &node, list.Vector())
|
||||
const JsonVector & level = creatures[i].Vector();
|
||||
|
||||
town.creatures[i].resize(level.size());
|
||||
|
||||
for (size_t j=0; j<level.size(); j++)
|
||||
{
|
||||
level.push_back(node.Float());
|
||||
VLC->modh->identifiers.requestIdentifier(std::string("creature.") + level[j].String(), [=, &town](si32 creature)
|
||||
{
|
||||
town.creatures[i][j] = creature;
|
||||
});
|
||||
}
|
||||
town.creatures.push_back(level);
|
||||
|
||||
}
|
||||
|
||||
loadBuildings(town, source["buildings"]);
|
||||
@ -471,6 +482,7 @@ void CTownHandler::load(const JsonNode &source)
|
||||
loadPuzzle(faction, node.second["puzzleMap"]);
|
||||
|
||||
tlog3 << "Added faction: " << node.first << "\n";
|
||||
VLC->modh->identifiers.registerObject(std::string("faction.") + node.first, faction.factionID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,7 +716,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
if(result == 1) //retreat
|
||||
{
|
||||
sah.army[0].clear();
|
||||
sah.army[0].setCreature(0, VLC->creh->nameToID[loserHero->type->refTypeStack[0]],1);
|
||||
sah.army[0].setCreature(0, loserHero->type->initialArmy[0].creature, 1);
|
||||
}
|
||||
|
||||
if(const CGHeroInstance *another = getPlayer(loser)->availableHeroes[1])
|
||||
@ -3195,7 +3195,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, ui8 player)
|
||||
{
|
||||
sah.hid[hid] = newHero->subID;
|
||||
sah.army[hid].clear();
|
||||
sah.army[hid].setCreature(0, VLC->creh->nameToID[newHero->type->refTypeStack[0]],1);
|
||||
sah.army[hid].setCreature(0, newHero->type->initialArmy[0].creature, 1);
|
||||
}
|
||||
else
|
||||
sah.hid[hid] = -1;
|
||||
|
257
vcmibuilder
Executable file
257
vcmibuilder
Executable file
@ -0,0 +1,257 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# VCMI data builder script
|
||||
# Extracts game data from various sources and creates a tree with the right files
|
||||
#
|
||||
# Authors: listed in file AUTHORS in main folder
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
|
||||
# no console arguments - print help
|
||||
if [ $# -eq 0 ] ; then
|
||||
print_help=true
|
||||
fi
|
||||
|
||||
# command line parsing
|
||||
# can't use system getopt which is not cross-platform (BSD/Mac)
|
||||
# can't use built-in getopts which can't parse long options (too difficult to avoid - e.g. CD1/CD2)
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case $1 in
|
||||
--cd1) cd1_dir=$2 ; shift 2 ;;
|
||||
--cd2) cd2_dir=$2 ; shift 2 ;;
|
||||
--gog) gog_file=$2 ; shift 2 ;;
|
||||
--data) data_dir=$2 ; shift 2 ;;
|
||||
--wog) wog_archive=$2 ; shift 2 ;;
|
||||
--vcmi) vcmi_archive=$2 ; shift 2 ;;
|
||||
--download) download=true ; shift 1 ;;
|
||||
--validate) validate=true ; shift 1 ;;
|
||||
*) print_help=true ; shift 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -n "$print_help" ]]
|
||||
then
|
||||
echo "VCMI data builder utility"
|
||||
echo "Usage: vcmibuilder <options>"
|
||||
echo "Options:"
|
||||
echo " --cd1 DIRECTORY " "Path to mounted first CD with Heroes 3 install files"
|
||||
echo " " "Requires unshield"
|
||||
echo
|
||||
echo " --cd2 DIRECTORY " "Path to second CD with Heroes 3 data files."
|
||||
echo
|
||||
echo " --gog EXECUTABLE " "Path to gog.com executable"
|
||||
echo " " "Requires innoextract ( http://constexpr.org/innoextract/ )"
|
||||
echo
|
||||
echo " --data DIRECTORY " "Path to installed Heroes 3 data"
|
||||
echo
|
||||
echo " --wog ARCHIVE " "Path to manually downloaded WoG archive"
|
||||
echo " " "Requires unzip"
|
||||
echo
|
||||
echo " --vcmi ARCHIVE " "Path to manually downloaded VCMI data package"
|
||||
echo " " "Requires unzip"
|
||||
echo
|
||||
echo " --download " "If specified vcmibuilder will download packages using wget"
|
||||
echo " " "Requires wget and Internet connection"
|
||||
echo
|
||||
echo " --validate " "If specified vcmibuilder will run basic validness checks"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# test presence of program $1, $2 will be passed as parameters to test presence
|
||||
test_utility ()
|
||||
{
|
||||
$1 $2 > /dev/null 2>&1 || { echo "$1 was not found. Please install it" 1>&2 ; exit 1; }
|
||||
}
|
||||
|
||||
#print error message and exit
|
||||
fail ()
|
||||
{
|
||||
$2
|
||||
echo "$1" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# print warning to stderr.
|
||||
warning ()
|
||||
{
|
||||
echo "$1" 1>&2
|
||||
warn_user=true
|
||||
}
|
||||
|
||||
# check if selected options are correct.
|
||||
|
||||
if [[ -n "$data_dir" ]]
|
||||
then
|
||||
if [[ -n "$gog_file" ]] || [[ -n "$cd1_dir" ]] || [[ -n "$cd2_dir" ]]
|
||||
then
|
||||
warning "Warning: Installed data dir was specified. Both gog and cd options will be ignored"
|
||||
unset gog_file cd1_dir cd2_dir
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$gog_file" ]]
|
||||
then
|
||||
test_utility "innoextract"
|
||||
if [[ -n "$cd1_dir" ]] || [[ -n "$cd2_dir" ]]
|
||||
then
|
||||
warning "Warning: Both gog and cd options were specified. cd options will be ignored"
|
||||
unset cd1_dir cd2_dir
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$cd1_dir" ]]
|
||||
then
|
||||
test_utility "unshield" "-V"
|
||||
fi
|
||||
|
||||
if [[ -n "$download" ]]
|
||||
then
|
||||
if [[ -n "$wog_archive" ]] && [[ -n "$vcmi_archive" ]]
|
||||
then
|
||||
warning "Warning: Both wog and vcmi options were specified. Download option will not be used"
|
||||
unset download
|
||||
else
|
||||
test_utility "wget" "-V"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$download" ]] || [[ -n "$wog_archive" ]] || [[ -n "$vcmi_archive" ]]
|
||||
then
|
||||
test_utility "unzip"
|
||||
fi
|
||||
|
||||
if [[ -z "$gog_file" ]] && [[ -z "$data_dir" ]] && ( [[ -z "$cd1_dir" ]] || [[ -z "$cd2_dir" ]] )
|
||||
then
|
||||
warning "Warning: Selected options will not create complete Heroes 3 data!"
|
||||
fi
|
||||
|
||||
if [[ -z "$download" ]] && ( [[ -z "$wog_archive" ]] || [[ -z "$vcmi_archive" ]])
|
||||
then
|
||||
warning "Warning: Selected options will not create complete VCMI data!"
|
||||
fi
|
||||
|
||||
# if at least one warning has been printed - ask for confirmation
|
||||
if [[ -n "$warn_user" ]]
|
||||
then
|
||||
read -p "Do you wish to continue? (y/n) " -n 1
|
||||
echo #print eol
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# start installation
|
||||
|
||||
dest_dir="./vcmi"
|
||||
mkdir -p $dest_dir
|
||||
|
||||
if [[ -n "$gog_file" ]]
|
||||
then
|
||||
data_dir="./app"
|
||||
# innoextract always reports error (iconv 84 error). Just test file for presence
|
||||
test -f $gog_file || fail "Error: gog.com executable was not found!"
|
||||
innoextract -s -p 1 $gog_file
|
||||
fi
|
||||
|
||||
if [[ -n "$cd1_dir" ]]
|
||||
then
|
||||
data_dir="./cddir"
|
||||
mkdir -p $data_dir
|
||||
unshield -d $data_dir x $cd1_dir/_setup/data1.cab || fail "Error: failed to extract from Install Shield installer!" "rm -rf ./cddir"
|
||||
|
||||
# a bit tricky - different releases have different root directory. Move extracted files to data_dir
|
||||
if [ -d $data_dir/"Heroes3" ]
|
||||
then
|
||||
mv $data_dir/Heroes3/* $data_dir
|
||||
elif [ -d $data_dir"/Program_Files" ]
|
||||
then
|
||||
mv $data_dir/Program_Files/* $data_dir
|
||||
else
|
||||
echo "Error: failed to find extracted game files!"
|
||||
echo "Extracted directories are: "
|
||||
ls -la $data_dir
|
||||
echo "Please report this on vcmi.eu"
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$cd2_dir" ]]
|
||||
then
|
||||
mkdir -p $dest_dir/Data
|
||||
|
||||
if [ -d $cd2_dir/heroes3 ]
|
||||
then
|
||||
cp $cd2_dir/heroes3/Data/Heroes3.vid $dest_dir/Data/VIDEO.VID
|
||||
cp $cd2_dir/heroes3/Data/Heroes3.snd $dest_dir/Data/Heroes3-cd2.snd
|
||||
else
|
||||
cp $cd2_dir/Heroes3/Data/Heroes3.vid $dest_dir/Data/VIDEO.VID
|
||||
cp $cd2_dir/Heroes3/Data/Heroes3.snd $dest_dir/Data/Heroes3-cd2.snd
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$data_dir" ]]
|
||||
then
|
||||
cp -r $data_dir/Data $dest_dir
|
||||
cp -r $data_dir/Maps $dest_dir
|
||||
|
||||
# this folder is named differently from time to time
|
||||
# vcmi can handle any case but script can't
|
||||
if [ -d $data_dir/MP3 ]
|
||||
then
|
||||
cp -r $data_dir/MP3 $dest_dir
|
||||
else
|
||||
cp -r $data_dir/Mp3 $dest_dir
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$download" ]]
|
||||
then
|
||||
if [[ -z "$wog_archive" ]]
|
||||
then
|
||||
wget "http://download.vcmi.eu/WoG/wog.zip" -O wog.zip || fail "Error: failed to download WoG archive!" "rm -f wog.zip"
|
||||
wog_archive="./wog.zip"
|
||||
fi
|
||||
|
||||
if [[ -z "$vcmi_archive" ]]
|
||||
then
|
||||
wget "http://download.vcmi.eu/core.zip" -O core.zip || fail "Error: failed to download WoG archive!" "rm -f core.zip"
|
||||
vcmi_archive="./core.zip"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$wog_archive" ]]
|
||||
then
|
||||
echo "decompressing $wog_archive"
|
||||
unzip -qo $wog_archive -d $dest_dir || fail "Error: failed to extract WoG archive!"
|
||||
fi
|
||||
|
||||
if [[ -n "$vcmi_archive" ]]
|
||||
then
|
||||
echo "decompressing $vcmi_archive"
|
||||
unzip -qo $vcmi_archive -d $dest_dir || fail "Error: failed to extract WoG archive!"
|
||||
fi
|
||||
|
||||
if [[ -n "$validate" ]]
|
||||
then
|
||||
test -f $dest_dir/Data/H3bitmap.lod || fail "Error: Heroes 3 data files are missing!"
|
||||
test -f $dest_dir/Data/H3sprite.lod || fail "Error: Heroes 3 data files are missing!"
|
||||
test -f $dest_dir/Data/VIDEO.VID || fail "Error: Heroes 3 data files (CD2) are missing!"
|
||||
test -d $dest_dir/Mods/WoG/Data || fail "Error: WoG data files are missing!"
|
||||
test -d $dest_dir/Mods/vcmi/Data || fail "Error: VCMI data files are missing!"
|
||||
fi
|
||||
|
||||
#TODO: Cleanup? How?
|
||||
|
||||
echo
|
||||
echo "vcmibuilder finished succesfully"
|
||||
echo "resulting data was placed into $PWD/vcmi"
|
||||
echo "any other files in current directory can be removed"
|
||||
echo
|
||||
|
Loading…
Reference in New Issue
Block a user