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

- added battleAI to CMake, compile fixes

- icons config for towns and creatures
This commit is contained in:
Ivan Savenko 2012-09-22 15:10:15 +00:00
parent bdc373227e
commit 8f936cd34d
18 changed files with 127 additions and 186 deletions

View File

@ -135,6 +135,7 @@ bool isCloser(const EnemyInfo & ei1, const EnemyInfo & ei2, const ReachabilityIn
return distToNearestNeighbour(ei1.s->position, dists) < distToNearestNeighbour(ei2.s->position, dists);
}
//FIXME: unused function
static bool willSecondHexBlockMoreEnemyShooters(const BattleHex &h1, const BattleHex &h2)
{
int shooters[2] = {0}; //count of shooters on hexes
@ -167,7 +168,7 @@ struct ThreatMap
const CStack *endangered;
std::array<int, GameConstants::BFIELD_SIZE> sufferedDamage;
struct ThreatMap(const CStack *Endangered)
ThreatMap(const CStack *Endangered)
: endangered(Endangered)
{
sufferedDamage.fill(0);
@ -491,7 +492,7 @@ BattleAction CBattleAI::goTowards(const CStack * stack, BattleHex destination)
BattleAction CBattleAI::useCatapult(const CStack * stack)
{
throw std::exception("The method or operation is not implemented.");
throw std::runtime_error("The method or operation is not implemented.");
}
bool isSupportedSpell(const CSpell *spell)
@ -553,7 +554,7 @@ void CBattleAI::attemptCastingSpell()
{
LOGL("Casting spells sounds like fun. Let's see...");
auto known = cb->battleGetFightingHero(side);
//auto known = cb->battleGetFightingHero(side);
//Get all spells we can cast
std::vector<const CSpell*> possibleSpells;

View File

@ -1,12 +1,12 @@
project(stupidAI)
project(battleAI)
cmake_minimum_required(VERSION 2.6)
include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/lib)
set(stupidAI_SRCS
StupidAI.cpp
set(battleAI_SRCS
BattleAI.cpp
main.cpp
)
add_library(StupidAI SHARED ${stupidAI_SRCS})
target_link_libraries(StupidAI vcmi)
add_library(BattleAI SHARED ${battleAI_SRCS})
target_link_libraries(BattleAI vcmi)

View File

@ -2,6 +2,7 @@ project(AI)
cmake_minimum_required(VERSION 2.6)
add_subdirectory(FuzzyLite)
add_subdirectory(BattleAI)
add_subdirectory(StupidAI)
add_subdirectory(EmptyAI)
add_subdirectory(VCAI)

View File

@ -9,6 +9,7 @@
#include "../lib/CObjectHandler.h"
#include "../lib/CGameState.h"
#include "../lib/CGeneralTextHandler.h"
#include "../lib/CTownHandler.h"
#include "../lib/NetPacks.h"
#include "../lib/CHeroHandler.h"
#include "CAdvmapInterface.h"
@ -291,12 +292,7 @@ CIntObject * CTownList::CTownItem::genSelection()
void CTownList::CTownItem::update()
{
size_t iconIndex = town->subID*2;
if (!town->hasFort())
iconIndex += GameConstants::F_NUMBER*2;
if(town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN)
iconIndex++;
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
picture->setFrame(iconIndex + 2);
redraw();

View File

@ -283,7 +283,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
//loading projectiles for units
BOOST_FOREACH(const CStack *s, stacks)
{
int creID = (s->getCreature()->idNumber == 149) ? CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] : s->getCreature()->idNumber; //id of creature whose shots should be loaded
//int creID = (s->getCreature()->idNumber == 149) ? CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] : s->getCreature()->idNumber; //id of creature whose shots should be loaded
if(s->getCreature()->isShooting())
{
CDefHandler *&projectile = idToProjectile[s->getCreature()->idNumber];

View File

@ -371,7 +371,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
bestMonsterID = it->second->type->idNumber;
}
}
new CAnimImage("TWCRPORT", bestMonsterID+2, 0, 392, 38);
new CAnimImage("TWCRPORT", CGI->creh->creatures[bestMonsterID]->iconIndex, 0, 392, 38);
//setting defenderName
defenderName = CGI->creh->creatures[bestMonsterID]->namePl;
}
@ -394,7 +394,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
int yPos = 344 + step*97;
for(std::map<ui32,si32>::const_iterator it=br.casualties[step].begin(); it!=br.casualties[step].end(); ++it)
{
new CAnimImage("CPRSMALL", it->first+2, 0, xPos, yPos);
new CAnimImage("CPRSMALL", CGI->creh->creatures[it->first]->iconIndex, 0, xPos, yPos);
std::ostringstream amount;
amount<<it->second;
new CLabel( xPos+16, yPos + 42, FONT_SMALL, CENTER, Colors::Cornsilk, amount.str());
@ -689,7 +689,7 @@ void CStackQueue::StackBox::setStack( const CStack *stack )
{
this->stack = stack;
assert(stack);
icon->setFrame(stack->getCreature()->idNumber + 2);
icon->setFrame(stack->getCreature()->iconIndex);
}
CStackQueue::StackBox::StackBox(bool small):

View File

@ -937,12 +937,7 @@ void CCastleInterface::recreateIcons()
delete fort;
delete hall;
size_t iconIndex = town->subID*2;
if (!town->hasFort())
iconIndex += GameConstants::F_NUMBER*2;
if(town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN)
iconIndex++;
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
icon->setFrame(iconIndex);
income->setTxt(boost::lexical_cast<std::string>(town->dailyIncome()));
@ -981,7 +976,7 @@ CCreaInfo::CCreaInfo(Point position, const CGTownInstance *Town, int Level, bool
ui32 creatureID = town->creatures[level].second.back();
creature = CGI->creh->creatures[creatureID];
picture = new CAnimImage("CPRSMALL", creatureID+2, 0, 8, 0);
picture = new CAnimImage("CPRSMALL", creature->iconIndex, 0, 8, 0);
std::string value;
if (showAvailable)

View File

@ -7,6 +7,7 @@
#include "../lib/CModHandler.h" //for buildings per turn
#include "../lib/CObjectHandler.h" //Hero/Town objects
#include "../lib/CHeroHandler.h" // only for calculating required xp? worth it?
#include "../lib/CTownHandler.h"
#include "CAnimation.h" //CAnimImage
#include "CAdvmapInterface.h" //CResDataBar
#include "CCastleInterface.h" //various town-specific classes
@ -794,12 +795,7 @@ CTownItem::CTownItem(const CGTownInstance* Town):
garr = new CGarrisonInt(313, 3, 4, Point(232,0), NULL, Point(313,2), town->getUpperArmy(), town->visitingHero, true, true, true);
heroes = new HeroSlots(town, Point(244,6), Point(475,6), garr, false);
size_t iconIndex = town->subID*2;
if (!town->hasFort())
iconIndex += GameConstants::F_NUMBER*2;
if(town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN)
iconIndex++;
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
picture = new CAnimImage("ITPT", iconIndex, 0, 5, 6);
townArea = new LRClickableAreaOpenTown;

View File

@ -155,6 +155,9 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(soundBase::soundID soundID)
Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound)
{
if (sound.empty())
return nullptr;
// Load and insert
try
{

View File

@ -160,13 +160,9 @@ void CTownTooltip::init(const InfoAboutTown &town)
assert(town.tType);
size_t imageIndex = town.tType->typeID * 2;
if (town.fortLevel == 0)
imageIndex += GameConstants::F_NUMBER * 2;
if (town.built >= CGI->modh->settings.MAX_BUILDING_PER_TURN)
imageIndex++;
size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->modh->settings.MAX_BUILDING_PER_TURN];
new CAnimImage("itpt", imageIndex, 0, 3, 2);
new CAnimImage("itpt", iconIndex, 0, 3, 2);
if(town.details)
{
@ -877,7 +873,7 @@ size_t CComponent::getIndex()
case primskill: return subtype;
case secskill: return subtype*3 + 3 + val - 1;
case resource: return subtype;
case creature: return subtype+2;
case creature: return CGI->creh->creatures[subtype]->iconIndex;
case artifact: return subtype;
case experience: return 4;
case spell: return subtype;

View File

@ -360,21 +360,11 @@ SDL_Surface * Graphics::getPic(int ID, bool fort, bool builded)
return smallIcons->ourImages[1].bitmap;
else if (ID==-3)
return smallIcons->ourImages[2+GameConstants::F_NUMBER*4].bitmap;
else if (ID>GameConstants::F_NUMBER || ID<-3)
#ifndef __GNUC__
throw new std::exception("Invalid ID");
#else
throw new std::exception();
#endif
else
{
int pom = 3;
if(!fort)
pom+=GameConstants::F_NUMBER*2;
pom += ID*2;
if (!builded)
pom--;
return smallIcons->ourImages[pom].bitmap;
assert(vstd::contains(CGI->townh->towns, ID));
int pom = CGI->townh->towns[ID].clientInfo.icons[fort][builded];
return smallIcons->ourImages[pom + 2].bitmap;
}
}

View File

@ -107,6 +107,12 @@
{ "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",
"townBackground": "TBCSBACK.bmp",
@ -285,6 +291,12 @@
{ "id" : 42, "animation" : "TBRMUP_5.def", "x" : 362, "y" : 90, "z" : -2, "border" : "TORUNI2.bmp", "area" : "TZRUNI2.bmp" },
{ "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",
"townBackground": "TBRMBACK.bmp",
@ -458,6 +470,12 @@
{ "id" : 42, "animation" : "TBTWUP_5.def", "x" : 681, "y" : 157, "z" : 2, "border" : "TOTNAG2.bmp", "area" : "TZTNAG2.bmp" },
{ "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",
"townBackground": "TBTWBACK.bmp",
@ -630,6 +648,11 @@
{ "id" : 42, "animation" : "TBINUP_5.def", "x" : 220, "y" : 282, "z" : 5, "border" : "TOIEFR2.bmp", "area" : "TZIEFR2.bmp" },
{ "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",
@ -808,6 +831,11 @@
{ "id" : 42, "animation" : "TBNCUP_5.def", "x" : 0, "y" : 30, "border" : "TONBKN2.bmp", "area" : "TZNBKN2.bmp" },
{ "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",
@ -980,6 +1008,11 @@
{ "id" : 42, "animation" : "TBDNUP_5.def", "x" : 270, "y" : 253, "z" : -1, "border" : "TODMAN2.bmp", "area" : "TZDMAN2.bmp" },
{ "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",
@ -1150,6 +1183,11 @@
{ "id" : 42, "animation" : "TBSTUP_5.def", "x" : 616, "y" : 93, "z" : -2, "border" : "TOSCYC2A.bmp", "area" : "TZSCYC2A.bmp" },
{ "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",
@ -1322,6 +1360,11 @@
{ "id" : 42, "animation" : "TBFRUP_5.def", "x" : 0, "y" : 4, "border" : "TOFWYV2.bmp", "area" : "TZFWYV2.bmp" },
{ "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",
@ -1499,6 +1542,11 @@
{ "id" : 42, "animation" : "TBELUP_5.def", "x" : 394, "y" : 283, "z" : 2, "border" : "TOELUP_5.bmp", "area" : "TZELUP_5.bmp" },
{ "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",

View File

@ -148,9 +148,6 @@ std::string CCreature::nodeName() const
bool CCreature::isItNativeTerrain(int terrain) const
{
if (faction > -1)
return VLC->townh->factions[faction].nativeTerrain == terrain;
else
return VLC->townh->factions[0].nativeTerrain == terrain; //FIXME: handle neutral faction properly
}
@ -168,20 +165,6 @@ int readNumber(int & befi, int & i, int andame, std::string & buf) //helper func
return ret;
}
double readFloat(int & befi, int & i, int andame, std::string & buf) //helper function for void CCreatureHandler::loadUnitAnimInfo()
{
befi=i;
for(; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
std::string tmp = buf.substr(befi, i-befi);
double ret = atof(buf.substr(befi, i-befi).c_str());
++i;
return ret;
}
/**
* Determines if a faction is good.
* @param ID of the faction.
@ -287,6 +270,7 @@ void CCreatureHandler::loadCreatures()
ncre.idNumber = creatures.size();
ncre.cost.resize(GameConstants::RESOURCE_QUANTITY);
ncre.level=0;
ncre.iconIndex = ncre.idNumber + 2; // +2 for empty\selection images
int befi=i;
for(; i<andame; ++i)
@ -624,73 +608,46 @@ void CCreatureHandler::loadCreatures()
void CCreatureHandler::loadAnimationInfo()
{
auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/CRANIM.TXT"));
std::string buf((char*)textFile.first.get(), textFile.second);
int andame = buf.size();
int i=0; //buf iterator
int hmcr=0;
for(; i<andame; ++i)
{
if(buf[i]=='\r')
++hmcr;
if(hmcr==2)
break;
}
i+=2;
CLegacyConfigParser parser("DATA/CRANIM.TXT");
parser.endLine(); // header
parser.endLine();
for(int dd=0; dd<creatures.size(); ++dd)
{
//tlog5 << "\t\t\tReading animation info for creature " << dd << std::endl;
loadUnitAnimInfo(*creatures[dd], buf, i);
while (parser.isNextEntryEmpty() && parser.endLine()) // skip empty lines
;
loadUnitAnimInfo(*creatures[dd], parser);
}
return;
}
void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int & i)
void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser & parser)
{
int befi=i;
unit.timeBetweenFidgets = readFloat(befi, i, src.size(), src);
while(unit.timeBetweenFidgets == 0.0)
{
for(; i<src.size(); ++i)
{
if(src[i]=='\r')
break;
}
i+=2;
unit.timeBetweenFidgets = readFloat(befi, i, src.size(), src);
}
unit.walkAnimationTime = readFloat(befi, i, src.size(), src);
unit.attackAnimationTime = readFloat(befi, i, src.size(), src);
unit.flightAnimationDistance = readFloat(befi, i, src.size(), src);
unit.timeBetweenFidgets = parser.readNumber();
unit.walkAnimationTime = parser.readNumber();
unit.attackAnimationTime = parser.readNumber();
unit.flightAnimationDistance = parser.readNumber();
///////////////////////
unit.upperRightMissleOffsetX = readNumber(befi, i, src.size(), src);
unit.upperRightMissleOffsetY = readNumber(befi, i, src.size(), src);
unit.rightMissleOffsetX = readNumber(befi, i, src.size(), src);
unit.rightMissleOffsetY = readNumber(befi, i, src.size(), src);
unit.lowerRightMissleOffsetX = readNumber(befi, i, src.size(), src);
unit.lowerRightMissleOffsetY = readNumber(befi, i, src.size(), src);
unit.upperRightMissleOffsetX = parser.readNumber();
unit.upperRightMissleOffsetY = parser.readNumber();
unit.rightMissleOffsetX = parser.readNumber();
unit.rightMissleOffsetY = parser.readNumber();
unit.lowerRightMissleOffsetX = parser.readNumber();
unit.lowerRightMissleOffsetY = parser.readNumber();
///////////////////////
for(int jjj=0; jjj<12; ++jjj)
{
unit.missleFrameAngles[jjj] = readFloat(befi, i, src.size(), src);
unit.missleFrameAngles[jjj] = parser.readNumber();
}
unit.troopCountLocationOffset= readNumber(befi, i, src.size(), src);
unit.attackClimaxFrame = readNumber(befi, i, src.size(), src);
unit.troopCountLocationOffset= parser.readNumber();
unit.attackClimaxFrame = parser.readNumber();
for(; i<src.size(); ++i)
{
if(src[i]=='\r')
break;
}
i+=2;
parser.endLine();
}
void CCreatureHandler::loadSoundsInfo()

View File

@ -38,6 +38,7 @@ public:
std::string animDefName;
std::string advMapDef; //for new creatures only
si32 idNumber;
si32 iconIndex; // index of icon in files like twcrport
si8 faction; //-1 = neutral
ui8 doubleWide;
@ -149,7 +150,7 @@ public:
void loadCreatures();
void buildBonusTreeForTiers();
void loadAnimationInfo();
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
void loadUnitAnimInfo(CCreature & unit, CLegacyConfigParser &parser);
void loadSoundsInfo();
void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser);
int stringToNumber(std::string & s);//help function for parsing CREXPBON.txt

View File

@ -2789,7 +2789,7 @@ DuelParameters DuelParameters::fromJSON(const std::string &fname)
if(ss.heroId != -1)
{
auto spells = n["spells"];
const JsonNode & spells = n["spells"];
if(spells.getType() == JsonNode::DATA_STRING && spells.String() == "all")
BOOST_FOREACH(auto spell, VLC->spellh->spells)
ss.spells.insert(spell->id);

View File

@ -84,7 +84,7 @@ void CModHandler::loadConfigFromFile (std::string name)
const JsonNode *value = &config["creatures"];
BOOST_FOREACH (auto creature, value->Vector())
{
auto cre = loadCreature (creature); //create and push back creature
auto cre = loadCreature (creature); //FIXME: unused variable 'cre' //create and push back creature
}
}
}
@ -114,51 +114,11 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
cre->namePl = name["plural"].String();
cre->nameRef = cre->nameSing;
//TODO: export resource set to separate function?
const JsonNode & cost = node["cost"];
if (cost.getType() == JsonNode::DATA_FLOAT) //gold
{
cre->cost[Res::GOLD] = cost.Float();
}
else if (cost.getType() == JsonNode::DATA_VECTOR)
{
int i = 0;
BOOST_FOREACH (auto & val, cost.Vector())
{
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->cost = Res::ResourceSet(node["cost"]);
cre->level = node["level"].Float();
cre->faction = -1; //neutral
//TODO: node["faction"].String() to id or just node["faction"].Float();
cre->faction = 9; //neutral faction is 9 for now. Will be replaced by string -> id conversion
//TODO: node["faction"].String() to id
cre->fightValue = node["fightValue"].Float();
cre->AIValue = node["aiValue"].Float();
cre->growth = node["growth"].Float();
@ -176,14 +136,10 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
cre->ammMax = amounts["max"].Float();
//optional
value = &node["upgrades"];
if (!value->isNull())
{
BOOST_FOREACH (auto & str, value->Vector())
BOOST_FOREACH (auto & str, node["upgrades"].Vector())
{
cre->upgradeNames.insert (str.String());
}
}
value = &node["shots"];
if (!value->isNull())
@ -193,20 +149,12 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
if (!value->isNull())
cre->addBonus(value->Float(), Bonus::CASTS);
value = &node["doubleWide"];
if (!value->isNull())
cre->doubleWide = value->Bool();
else
cre->doubleWide = false;
cre->doubleWide = node["doubleWide"].Bool();
value = &node["abilities"];
if (!value->isNull())
{
BOOST_FOREACH (const JsonNode &bonus, value->Vector())
BOOST_FOREACH (const JsonNode &bonus, node["abilities"].Vector())
{
cre->addNewBonus(ParseBonus(bonus));
}
}
//graphics
const JsonNode & graphics = node["graphics"];
@ -234,6 +182,7 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
cre->missleFrameAngles[i++] = angle.Float();
}
cre->advMapDef = graphics["map"].String();
cre->iconIndex = graphics["iconIndex"].Float();
//TODO: parse
cre->projectile = "PLCBOWX.DEF";
@ -241,7 +190,7 @@ CCreature * CModHandler::loadCreature (const JsonNode &node)
const JsonNode & sounds = node["sound"];
#define GET_SOUND_VALUE(value_name) do { value = &sounds[#value_name]; if (!value->isNull()) cre->sounds.value_name = value->String(); } while(0)
#define GET_SOUND_VALUE(value_name) do { cre->sounds.value_name = sounds[#value_name].String(); } while(0)
GET_SOUND_VALUE(attack);
GET_SOUND_VALUE(defend);
GET_SOUND_VALUE(killed);

View File

@ -252,6 +252,11 @@ void CTownHandler::loadTownHall(CTown &town, const JsonNode & source)
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();
town.clientInfo.hallBackground = source["hallBackground"].String();
town.clientInfo.musicTheme = source["musicTheme"].String();
town.clientInfo.townBackground = source["townBackground"].String();

View File

@ -105,6 +105,9 @@ public:
// Client-only data. Should be moved away from lib
struct ClientInfo
{
//icons [fort is present?][build limit reached?] -> index of icon in def files
int icons[2][2];
std::string musicTheme;
std::string townBackground;
std::string guildWindow;
@ -119,7 +122,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & musicTheme & townBackground & guildWindow & buildingsIcons & hallBackground & hallSlots & structures;
h & icons & musicTheme & townBackground & guildWindow & buildingsIcons & hallBackground & hallSlots & structures;
}
} clientInfo;