mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
- support for new heroes and hero classes
- moved hero-specific data from text handler to CHero - moved hero classes-specific data into heroClasses.json
This commit is contained in:
@@ -239,10 +239,13 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
|||||||
//loading hero animations
|
//loading hero animations
|
||||||
if(hero1) // attacking hero
|
if(hero1) // attacking hero
|
||||||
{
|
{
|
||||||
int type = hero1->type->heroClass->id;
|
std::string battleImage;
|
||||||
if ( type % 2 ) type--;
|
if ( hero1->sex )
|
||||||
if ( hero1->sex ) type++;
|
battleImage = hero1->type->heroClass->imageBattleFemale;
|
||||||
attackingHero = new CBattleHero(graphics->battleHeroes[type], false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : NULL, this);
|
else
|
||||||
|
battleImage = hero1->type->heroClass->imageBattleMale;
|
||||||
|
|
||||||
|
attackingHero = new CBattleHero(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : NULL, this);
|
||||||
attackingHero->pos = genRect(attackingHero->dh->ourImages[0].bitmap->h, attackingHero->dh->ourImages[0].bitmap->w, pos.x - 43, pos.y - 19);
|
attackingHero->pos = genRect(attackingHero->dh->ourImages[0].bitmap->h, attackingHero->dh->ourImages[0].bitmap->w, pos.x - 43, pos.y - 19);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -251,10 +254,13 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
|||||||
}
|
}
|
||||||
if(hero2) // defending hero
|
if(hero2) // defending hero
|
||||||
{
|
{
|
||||||
int type = hero2->type->heroClass->id;
|
std::string battleImage;
|
||||||
if ( type % 2 ) type--;
|
if ( hero2->sex )
|
||||||
if ( hero2->sex ) type++;
|
battleImage = hero1->type->heroClass->imageBattleFemale;
|
||||||
defendingHero = new CBattleHero(graphics->battleHeroes[type ], true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : NULL, this);
|
else
|
||||||
|
battleImage = hero1->type->heroClass->imageBattleMale;
|
||||||
|
|
||||||
|
defendingHero = new CBattleHero(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : NULL, this);
|
||||||
defendingHero->pos = genRect(defendingHero->dh->ourImages[0].bitmap->h, defendingHero->dh->ourImages[0].bitmap->w, pos.x + 693, pos.y - 19);
|
defendingHero->pos = genRect(defendingHero->dh->ourImages[0].bitmap->h, defendingHero->dh->ourImages[0].bitmap->w, pos.x + 693, pos.y - 19);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -175,8 +175,8 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
|
|||||||
|
|
||||||
assert(hero == curHero);
|
assert(hero == curHero);
|
||||||
|
|
||||||
specArea->text = CGI->generaltexth->hTxts[curHero->subID].longBonus;
|
specArea->text = curHero->type->specDescr;
|
||||||
specImage->setFrame(curHero->subID);
|
specImage->setFrame(curHero->type->imageIndex);
|
||||||
|
|
||||||
tacticsButton->callback.clear();
|
tacticsButton->callback.clear();
|
||||||
tacticsButton->callback2.clear();
|
tacticsButton->callback2.clear();
|
||||||
@@ -378,7 +378,7 @@ void CHeroWindow::showAll(SDL_Surface * to)
|
|||||||
|
|
||||||
//printing special ability
|
//printing special ability
|
||||||
printAtLoc(CGI->generaltexth->jktexts[5].substr(1, CGI->generaltexth->jktexts[5].size()-2), 69, 183, FONT_SMALL, Colors::YELLOW, to);
|
printAtLoc(CGI->generaltexth->jktexts[5].substr(1, CGI->generaltexth->jktexts[5].size()-2), 69, 183, FONT_SMALL, Colors::YELLOW, to);
|
||||||
printAtLoc(CGI->generaltexth->hTxts[curHero->subID].bonusName, 69, 205, FONT_SMALL, Colors::WHITE, to);
|
printAtLoc(curHero->type->specName, 69, 205, FONT_SMALL, Colors::WHITE, to);
|
||||||
|
|
||||||
//printing necessery texts
|
//printing necessery texts
|
||||||
printAtLoc(CGI->generaltexth->jktexts[6].substr(1, CGI->generaltexth->jktexts[6].size()-2), 69, 232, FONT_SMALL, Colors::YELLOW, to);
|
printAtLoc(CGI->generaltexth->jktexts[6].substr(1, CGI->generaltexth->jktexts[6].size()-2), 69, 232, FONT_SMALL, Colors::YELLOW, to);
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ std::string InfoBoxAbstractHeroData::getNameText()
|
|||||||
return text.substr(begin, end-begin);
|
return text.substr(begin, end-begin);
|
||||||
}
|
}
|
||||||
case HERO_SPECIAL:
|
case HERO_SPECIAL:
|
||||||
return CGI->generaltexth->hTxts[getSubID()].bonusName;
|
return CGI->heroh->heroes[getSubID()]->specName;
|
||||||
case HERO_SECONDARY_SKILL:
|
case HERO_SECONDARY_SKILL:
|
||||||
if (getValue())
|
if (getValue())
|
||||||
return CGI->generaltexth->skillName[getSubID()];
|
return CGI->generaltexth->skillName[getSubID()];
|
||||||
@@ -237,6 +237,7 @@ size_t InfoBoxAbstractHeroData::getImageIndex()
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case HERO_SPECIAL:
|
case HERO_SPECIAL:
|
||||||
|
return VLC->heroh->heroes[getSubID()]->imageIndex;
|
||||||
case HERO_PRIMARY_SKILL:
|
case HERO_PRIMARY_SKILL:
|
||||||
return getSubID();
|
return getSubID();
|
||||||
case HERO_MANA:
|
case HERO_MANA:
|
||||||
@@ -262,7 +263,7 @@ bool InfoBoxAbstractHeroData::prepareMessage(std::string &text, CComponent **com
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case HERO_SPECIAL:
|
case HERO_SPECIAL:
|
||||||
text = CGI->generaltexth->hTxts[getSubID()].longBonus;
|
text = CGI->heroh->heroes[getSubID()]->specDescr;
|
||||||
*comp = NULL;
|
*comp = NULL;
|
||||||
return true;
|
return true;
|
||||||
case HERO_PRIMARY_SKILL:
|
case HERO_PRIMARY_SKILL:
|
||||||
@@ -918,7 +919,7 @@ CHeroItem::CHeroItem(const CGHeroInstance* Hero, CArtifactsOfHero::SCommonPart *
|
|||||||
|
|
||||||
garr = new CGarrisonInt(6, 78, 4, Point(), NULL, Point(), hero, NULL, true, true);
|
garr = new CGarrisonInt(6, 78, 4, Point(), NULL, Point(), hero, NULL, true, true);
|
||||||
|
|
||||||
portrait = new CAnimImage("PortraitsLarge", hero->subID, 0, 5, 6);
|
portrait = new CAnimImage("PortraitsLarge", hero->portrait, 0, 5, 6);
|
||||||
heroArea = new CHeroArea(5, 6, hero);
|
heroArea = new CHeroArea(5, 6, hero);
|
||||||
|
|
||||||
name = new CLabel(73, 7, FONT_SMALL, TOPLEFT, Colors::WHITE, hero->name);
|
name = new CLabel(73, 7, FONT_SMALL, TOPLEFT, Colors::WHITE, hero->name);
|
||||||
|
|||||||
@@ -2640,7 +2640,7 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex()
|
|||||||
{
|
{
|
||||||
if(settings.heroPortrait >= 0)
|
if(settings.heroPortrait >= 0)
|
||||||
return settings.heroPortrait;
|
return settings.heroPortrait;
|
||||||
return settings.hero;
|
return CGI->heroh->heroes[settings.hero]->imageIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2870,10 +2870,10 @@ void OptionsTab::CPregameTooltipBox::genHeroWindow()
|
|||||||
genHeader();
|
genHeader();
|
||||||
|
|
||||||
// speciality
|
// speciality
|
||||||
new CAnimImage("UN44", settings.hero, 0, pos.w / 2 - 22, 134);
|
new CAnimImage("UN44", CGI->heroh->heroes[settings.hero]->imageIndex, 0, pos.w / 2 - 22, 134);
|
||||||
|
|
||||||
new CLabel(pos.w / 2 + 4, 117, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[78]);
|
new CLabel(pos.w / 2 + 4, 117, FONT_MEDIUM, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[78]);
|
||||||
new CLabel(pos.w / 2, 188, FONT_SMALL, CENTER, Colors::WHITE, CGI->generaltexth->hTxts[settings.hero].bonusName);
|
new CLabel(pos.w / 2, 188, FONT_SMALL, CENTER, Colors::WHITE, CGI->heroh->heroes[settings.hero]->specName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsTab::CPregameTooltipBox::genBonusWindow()
|
void OptionsTab::CPregameTooltipBox::genBonusWindow()
|
||||||
|
|||||||
@@ -943,7 +943,7 @@ size_t CComponent::getIndex()
|
|||||||
case morale: return val+3;
|
case morale: return val+3;
|
||||||
case luck: return val+3;
|
case luck: return val+3;
|
||||||
case building: return val;
|
case building: return val;
|
||||||
case hero: return subtype;
|
case hero: return CGI->heroh->heroes[subtype]->imageIndex;
|
||||||
case flag: return subtype;
|
case flag: return subtype;
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
@@ -3706,7 +3706,7 @@ CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const
|
|||||||
h->name.c_str(), h->level, h->type->heroClass->name.c_str(), artifs);
|
h->name.c_str(), h->level, h->type->heroClass->name.c_str(), artifs);
|
||||||
descr[sizeof(descr)-1] = '\0';
|
descr[sizeof(descr)-1] = '\0';
|
||||||
|
|
||||||
new CAnimImage("portraitsLarge", h->subID);
|
new CAnimImage("portraitsLarge", h->portrait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4965,7 +4965,7 @@ void CExchangeWindow::prepareBackground()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//hero's specialty
|
//hero's specialty
|
||||||
new CAnimImage("UN32", heroInst[b]->subID, 0, 67 + 490*b, 45);
|
new CAnimImage("UN32", heroInst[b]->type->imageIndex, 0, 67 + 490*b, 45);
|
||||||
|
|
||||||
//experience
|
//experience
|
||||||
new CAnimImage("PSKIL32", 4, 0, 103 + 490*b, 45);
|
new CAnimImage("PSKIL32", 4, 0, 103 + 490*b, 45);
|
||||||
@@ -5042,7 +5042,7 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2):
|
|||||||
speciality[b] = new LRClickableAreaWText();
|
speciality[b] = new LRClickableAreaWText();
|
||||||
speciality[b]->pos = genRect(32, 32, pos.x + 69 + 490*b, pos.y + 45);
|
speciality[b]->pos = genRect(32, 32, pos.x + 69 + 490*b, pos.y + 45);
|
||||||
speciality[b]->hoverText = CGI->generaltexth->heroscrn[27];
|
speciality[b]->hoverText = CGI->generaltexth->heroscrn[27];
|
||||||
speciality[b]->text = CGI->generaltexth->hTxts[heroInst[b]->subID].longBonus;
|
speciality[b]->text = heroInst[b]->type->specDescr;
|
||||||
|
|
||||||
experience[b] = new LRClickableAreaWText();
|
experience[b] = new LRClickableAreaWText();
|
||||||
experience[b]->pos = genRect(32, 32, pos.x + 105 + 490*b, pos.y + 45);
|
experience[b]->pos = genRect(32, 32, pos.x + 105 + 490*b, pos.y + 45);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "CGameInfo.h"
|
#include "CGameInfo.h"
|
||||||
#include "../lib/VCMI_Lib.h"
|
#include "../lib/VCMI_Lib.h"
|
||||||
#include "../CCallback.h"
|
#include "../CCallback.h"
|
||||||
|
#include "../lib/CHeroHandler.h"
|
||||||
#include "../lib/CTownHandler.h"
|
#include "../lib/CTownHandler.h"
|
||||||
#include "../lib/CObjectHandler.h"
|
#include "../lib/CObjectHandler.h"
|
||||||
#include "../lib/CGeneralTextHandler.h"
|
#include "../lib/CGeneralTextHandler.h"
|
||||||
@@ -103,16 +104,6 @@ void Graphics::initializeBattleGraphics()
|
|||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//initializing battle hero animation
|
|
||||||
idx = config["heroes"].Vector().size();
|
|
||||||
battleHeroes.resize(idx);
|
|
||||||
|
|
||||||
idx = 0;
|
|
||||||
BOOST_FOREACH(const JsonNode &h, config["heroes"].Vector()) {
|
|
||||||
battleHeroes[idx] = h.String();
|
|
||||||
idx ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//initialization of AC->def name mapping
|
//initialization of AC->def name mapping
|
||||||
BOOST_FOREACH(const JsonNode &ac, config["ac_mapping"].Vector()) {
|
BOOST_FOREACH(const JsonNode &ac, config["ac_mapping"].Vector()) {
|
||||||
int ACid = ac["id"].Float();
|
int ACid = ac["id"].Float();
|
||||||
@@ -169,22 +160,26 @@ void Graphics::loadHeroAnims()
|
|||||||
std::vector<std::pair<int,int> > rotations; //first - group number to be rotated1, second - group number after rotation1
|
std::vector<std::pair<int,int> > rotations; //first - group number to be rotated1, second - group number after rotation1
|
||||||
rotations += std::make_pair(6,10), std::make_pair(7,11), std::make_pair(8,12), std::make_pair(1,13),
|
rotations += std::make_pair(6,10), std::make_pair(7,11), std::make_pair(8,12), std::make_pair(1,13),
|
||||||
std::make_pair(2,14), std::make_pair(3,15);
|
std::make_pair(2,14), std::make_pair(3,15);
|
||||||
for(size_t i=0; i<GameConstants::F_NUMBER * 2; ++i)
|
|
||||||
|
for(size_t i=0; i<CGI->heroh->classes.heroClasses.size(); ++i)
|
||||||
{
|
{
|
||||||
std::ostringstream nm;
|
const CHeroClass * hc = CGI->heroh->classes.heroClasses[i];
|
||||||
nm << "AH" << std::setw(2) << std::setfill('0') << i << "_.DEF";
|
|
||||||
loadHeroAnim(nm.str(), rotations, &Graphics::heroAnims);
|
if (!vstd::contains(heroAnims, hc->imageMapFemale))
|
||||||
|
heroAnims[hc->imageMapFemale] = loadHeroAnim(hc->imageMapFemale, rotations);
|
||||||
|
|
||||||
|
if (!vstd::contains(heroAnims, hc->imageMapMale))
|
||||||
|
heroAnims[hc->imageMapMale] = loadHeroAnim(hc->imageMapMale, rotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadHeroAnim("AB01_.DEF", rotations, &Graphics::boatAnims);
|
boatAnims.push_back(loadHeroAnim("AB01_.DEF", rotations));
|
||||||
loadHeroAnim("AB02_.DEF", rotations, &Graphics::boatAnims);
|
boatAnims.push_back(loadHeroAnim("AB02_.DEF", rotations));
|
||||||
loadHeroAnim("AB03_.DEF", rotations, &Graphics::boatAnims);
|
boatAnims.push_back(loadHeroAnim("AB03_.DEF", rotations));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::loadHeroAnim( const std::string &name, const std::vector<std::pair<int,int> > &rotations, std::vector<CDefEssential *> Graphics::*dst )
|
CDefEssential * Graphics::loadHeroAnim( const std::string &name, const std::vector<std::pair<int,int> > &rotations)
|
||||||
{
|
{
|
||||||
CDefEssential *anim = CDefHandler::giveDefEss(name);
|
CDefEssential *anim = CDefHandler::giveDefEss(name);
|
||||||
(this->*dst).push_back(anim);
|
|
||||||
int pom = 0; //how many groups has been rotated
|
int pom = 0; //how many groups has been rotated
|
||||||
for(int o=7; pom<6; ++o)
|
for(int o=7; pom<6; ++o)
|
||||||
{
|
{
|
||||||
@@ -216,6 +211,7 @@ void Graphics::loadHeroAnim( const std::string &name, const std::vector<std::pai
|
|||||||
{
|
{
|
||||||
CSDL_Ext::alphaTransform(anim->ourImages[ff].bitmap);
|
CSDL_Ext::alphaTransform(anim->ourImages[ff].bitmap);
|
||||||
}
|
}
|
||||||
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::loadHeroFlags(std::pair<std::vector<CDefEssential *> Graphics::*, std::vector<const char *> > &pr, bool mode)
|
void Graphics::loadHeroFlags(std::pair<std::vector<CDefEssential *> Graphics::*, std::vector<const char *> > &pr, bool mode)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
CDefEssential * resources32; //resources 32x32
|
CDefEssential * resources32; //resources 32x32
|
||||||
CDefEssential * flags;
|
CDefEssential * flags;
|
||||||
CDefEssential * heroMoveArrows;
|
CDefEssential * heroMoveArrows;
|
||||||
std::vector<CDefEssential *> heroAnims; // [class id: 0 - 17] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
std::map<std::string, CDefEssential *> heroAnims; // [hero class def name] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||||
std::vector<CDefEssential *> boatAnims; // [boat type: 0 - 3] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
std::vector<CDefEssential *> boatAnims; // [boat type: 0 - 3] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||||
CDefHandler * FoWfullHide; //for Fog of War
|
CDefHandler * FoWfullHide; //for Fog of War
|
||||||
CDefHandler * FoWpartialHide; //for For of War
|
CDefHandler * FoWpartialHide; //for For of War
|
||||||
@@ -63,7 +63,6 @@ public:
|
|||||||
std::map<int, std::string> ERMUtoPicture[GameConstants::F_NUMBER]; //maps building ID to it's picture's name for each town type
|
std::map<int, std::string> ERMUtoPicture[GameConstants::F_NUMBER]; //maps building ID to it's picture's name for each town type
|
||||||
//for battles
|
//for battles
|
||||||
std::vector< std::vector< std::string > > battleBacks; //battleBacks[terType] - vector of possible names for certain terrain type
|
std::vector< std::vector< std::string > > battleBacks; //battleBacks[terType] - vector of possible names for certain terrain type
|
||||||
std::vector< std::string > battleHeroes; //battleHeroes[hero type] - name of def that has hero animation for battle
|
|
||||||
std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names
|
std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names
|
||||||
CDefEssential * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
|
CDefEssential * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
|
||||||
//spells
|
//spells
|
||||||
@@ -75,7 +74,7 @@ public:
|
|||||||
void loadHeroFlags();
|
void loadHeroFlags();
|
||||||
void loadHeroFlags(std::pair<std::vector<CDefEssential *> Graphics::*, std::vector<const char *> > &pr, bool mode);
|
void loadHeroFlags(std::pair<std::vector<CDefEssential *> Graphics::*, std::vector<const char *> > &pr, bool mode);
|
||||||
void loadHeroAnims();
|
void loadHeroAnims();
|
||||||
void loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations, std::vector<CDefEssential *> Graphics::*dst);
|
CDefEssential * loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations);
|
||||||
void loadErmuToPicture();
|
void loadErmuToPicture();
|
||||||
void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player
|
void blueToPlayersAdv(SDL_Surface * sur, int player); //replaces blue interface colour with a color of player
|
||||||
void loadTrueType();
|
void loadTrueType();
|
||||||
|
|||||||
@@ -566,9 +566,12 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
|
|||||||
dir = themp->moveDir;
|
dir = themp->moveDir;
|
||||||
|
|
||||||
//pick graphics of hero (or boat if hero is sailing)
|
//pick graphics of hero (or boat if hero is sailing)
|
||||||
iv = (themp->boat)
|
if (themp->boat)
|
||||||
? &graphics->boatAnims[themp->boat->subID]->ourImages
|
iv = &graphics->boatAnims[themp->boat->subID]->ourImages;
|
||||||
: &graphics->heroAnims[themp->type->heroClass->id]->ourImages;
|
else if (themp->sex)
|
||||||
|
iv = &graphics->heroAnims[themp->type->heroClass->imageMapFemale]->ourImages;
|
||||||
|
else
|
||||||
|
iv = &graphics->heroAnims[themp->type->heroClass->imageMapMale]->ourImages;
|
||||||
|
|
||||||
//pick appropriate flag set
|
//pick appropriate flag set
|
||||||
if(themp->boat)
|
if(themp->boat)
|
||||||
|
|||||||
@@ -28,29 +28,6 @@
|
|||||||
"CMBKDECK.BMP"
|
"CMBKDECK.BMP"
|
||||||
],
|
],
|
||||||
|
|
||||||
// Hero animation used in battles.
|
|
||||||
// Each 2 def represent male and female heroes for each race
|
|
||||||
"heroes": [
|
|
||||||
"CH00.DEF",
|
|
||||||
"CH01.DEF",
|
|
||||||
"CH02.DEF",
|
|
||||||
"CH03.DEF",
|
|
||||||
"CH05.DEF",
|
|
||||||
"CH04.DEF",
|
|
||||||
"CH06.DEF",
|
|
||||||
"CH07.DEF",
|
|
||||||
"CH08.DEF",
|
|
||||||
"CH09.DEF",
|
|
||||||
"CH010.DEF",
|
|
||||||
"CH11.DEF",
|
|
||||||
"CH013.DEF",
|
|
||||||
"CH012.DEF",
|
|
||||||
"CH014.DEF",
|
|
||||||
"CH015.DEF",
|
|
||||||
"CH16.DEF",
|
|
||||||
"CH17.DEF"
|
|
||||||
],
|
|
||||||
|
|
||||||
// WoG_Ac_format_to_def_names_mapping
|
// WoG_Ac_format_to_def_names_mapping
|
||||||
"ac_mapping": [
|
"ac_mapping": [
|
||||||
{ "id": 0, "defnames": [ "C10SPW.DEF" ] },
|
{ "id": 0, "defnames": [ "C10SPW.DEF" ] },
|
||||||
|
|||||||
38
config/heroClasses.json
Normal file
38
config/heroClasses.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
// battle animations for heroes, ordered by faction
|
||||||
|
"heroBattleAnim" :
|
||||||
|
[
|
||||||
|
{ "male" : "CH00.DEF", "female" : "CH01.DEF" },
|
||||||
|
{ "male" : "CH02.DEF", "female" : "CH03.DEF" },
|
||||||
|
{ "male" : "CH05.DEF", "female" : "CH04.DEF" },
|
||||||
|
{ "male" : "CH06.DEF", "female" : "CH07.DEF" },
|
||||||
|
{ "male" : "CH08.DEF", "female" : "CH09.DEF" },
|
||||||
|
{ "male" : "CH010.DEF", "female" : "CH11.DEF" },
|
||||||
|
{ "male" : "CH013.DEF", "female" : "CH012.DEF" },
|
||||||
|
{ "male" : "CH014.DEF", "female" : "CH015.DEF" },
|
||||||
|
{ "male" : "CH16.DEF", "female" : "CH17.DEF" }
|
||||||
|
],
|
||||||
|
|
||||||
|
// map animations for heroes, ordered by hero class
|
||||||
|
"heroMapAnim" :
|
||||||
|
[
|
||||||
|
"AH00_.def",
|
||||||
|
"AH01_.def",
|
||||||
|
"AH02_.def",
|
||||||
|
"AH03_.def",
|
||||||
|
"AH04_.def",
|
||||||
|
"AH05_.def",
|
||||||
|
"AH06_.def",
|
||||||
|
"AH07_.def",
|
||||||
|
"AH08_.def",
|
||||||
|
"AH09_.def",
|
||||||
|
"AH10_.def",
|
||||||
|
"AH11_.def",
|
||||||
|
"AH12_.def",
|
||||||
|
"AH13_.def",
|
||||||
|
"AH14_.def",
|
||||||
|
"AH15_.def",
|
||||||
|
"AH16_.def",
|
||||||
|
"AH17_.def"
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -189,25 +189,6 @@ void CGeneralTextHandler::load()
|
|||||||
}
|
}
|
||||||
while (parser.endLine());
|
while (parser.endLine());
|
||||||
}
|
}
|
||||||
{
|
|
||||||
CLegacyConfigParser parser("DATA/HEROSPEC.TXT");
|
|
||||||
CLegacyConfigParser bioParser("DATA/HEROBIOS.TXT");
|
|
||||||
|
|
||||||
//skip header
|
|
||||||
parser.endLine();
|
|
||||||
parser.endLine();
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
HeroTexts texts;
|
|
||||||
texts.bonusName = parser.readString();
|
|
||||||
texts.shortBonus = parser.readString();
|
|
||||||
texts.longBonus = parser.readString();
|
|
||||||
texts.biography = bioParser.readString();
|
|
||||||
hTxts.push_back(texts);
|
|
||||||
}
|
|
||||||
while (parser.endLine() && bioParser.endLine());
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
CLegacyConfigParser nameParser("DATA/MINENAME.TXT");
|
CLegacyConfigParser nameParser("DATA/MINENAME.TXT");
|
||||||
CLegacyConfigParser eventParser("DATA/MINEEVNT.TXT");
|
CLegacyConfigParser eventParser("DATA/MINEEVNT.TXT");
|
||||||
|
|||||||
@@ -58,14 +58,6 @@ public:
|
|||||||
class DLL_LINKAGE CGeneralTextHandler //Handles general texts
|
class DLL_LINKAGE CGeneralTextHandler //Handles general texts
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class HeroTexts
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string bonusName, shortBonus, longBonus; //for special abilities
|
|
||||||
std::string biography; //biography, of course
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<HeroTexts> hTxts;
|
|
||||||
std::vector<std::string> allTexts;
|
std::vector<std::string> allTexts;
|
||||||
|
|
||||||
std::vector<std::string> arraytxt;
|
std::vector<std::string> arraytxt;
|
||||||
|
|||||||
@@ -20,12 +20,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CHeroClass::CHeroClass()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
CHeroClass::~CHeroClass()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
int CHeroClass::chooseSecSkill(const std::set<int> & possibles) const //picks secondary skill out from given possibilities
|
int CHeroClass::chooseSecSkill(const std::set<int> & possibles) const //picks secondary skill out from given possibilities
|
||||||
{
|
{
|
||||||
if(possibles.size()==1)
|
if(possibles.size()==1)
|
||||||
@@ -119,17 +113,81 @@ void CHeroClassHandler::load()
|
|||||||
VLC->modh->identifiers.registerObject("heroClass." + GameConstants::HERO_CLASSES_NAMES[hc->id], hc->id);
|
VLC->modh->identifiers.registerObject("heroClass." + GameConstants::HERO_CLASSES_NAMES[hc->id], hc->id);
|
||||||
}
|
}
|
||||||
while (parser.endLine() && !parser.isNextEntryEmpty());
|
while (parser.endLine() && !parser.isNextEntryEmpty());
|
||||||
|
|
||||||
|
const JsonNode & heroGraphics = JsonNode(ResourceID("config/heroClasses.json"));
|
||||||
|
|
||||||
|
for (size_t i=0; i<heroClasses.size(); i++)
|
||||||
|
{
|
||||||
|
const JsonNode & battle = heroGraphics["heroBattleAnim"].Vector()[i/2];
|
||||||
|
|
||||||
|
heroClasses[i]->imageBattleFemale = battle["female"].String();
|
||||||
|
heroClasses[i]->imageBattleMale = battle["male"].String();
|
||||||
|
|
||||||
|
const JsonNode & map = heroGraphics["heroMapAnim"].Vector()[i];
|
||||||
|
|
||||||
|
heroClasses[i]->imageMapMale = map.String();
|
||||||
|
heroClasses[i]->imageMapFemale = map.String();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroClassHandler::load(const JsonNode & classes)
|
void CHeroClassHandler::load(const JsonNode & classes)
|
||||||
{
|
{
|
||||||
//TODO
|
BOOST_FOREACH(auto & entry, classes.Struct())
|
||||||
|
{
|
||||||
|
if (!entry.second.isNull()) // may happens if mod removed creature by setting json entry to null
|
||||||
|
{
|
||||||
|
CHeroClass * heroClass = loadClass(entry.second);
|
||||||
|
heroClass->identifier = entry.first;
|
||||||
|
heroClass->id = heroClasses.size();
|
||||||
|
|
||||||
|
heroClasses.push_back(heroClass);
|
||||||
|
tlog3 << "Added hero class: " << entry.first << "\n";
|
||||||
|
VLC->modh->identifiers.registerObject("heroClass." + heroClass->identifier, heroClass->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeroClass *CHeroClassHandler::loadClass(const JsonNode & heroClass)
|
CHeroClass *CHeroClassHandler::loadClass(const JsonNode & node)
|
||||||
{
|
{
|
||||||
//TODO
|
CHeroClass * heroClass = new CHeroClass;
|
||||||
return new CHeroClass;
|
|
||||||
|
heroClass->imageBattleFemale = node["animation"]["battle"]["female"].String();
|
||||||
|
heroClass->imageBattleMale = node["animation"]["battle"]["male"].String();
|
||||||
|
heroClass->imageMapFemale = node["animation"]["map"]["female"].String();
|
||||||
|
heroClass->imageMapMale = node["animation"]["map"]["male"].String();
|
||||||
|
|
||||||
|
heroClass->name = node["name"].String();
|
||||||
|
|
||||||
|
BOOST_FOREACH(const std::string & pSkill, PrimarySkill::names)
|
||||||
|
{
|
||||||
|
heroClass->primarySkillInitial.push_back(node["primarySkills"][pSkill].Float());
|
||||||
|
heroClass->primarySkillLowLevel.push_back(node["lowLevelChance"][pSkill].Float());
|
||||||
|
heroClass->primarySkillHighLevel.push_back(node["highLevelChance"][pSkill].Float());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const std::string & secSkill, SecondarySkill::names)
|
||||||
|
{
|
||||||
|
heroClass->secSkillProbability.push_back(node["secondarySkills"][secSkill].Float());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(auto & tavern, node["tavern"].Struct())
|
||||||
|
{
|
||||||
|
int value = tavern.second.Float();
|
||||||
|
|
||||||
|
VLC->modh->identifiers.requestIdentifier("faction." + tavern.first,
|
||||||
|
[=](si32 factionID)
|
||||||
|
{
|
||||||
|
heroClass->selectionProbability[factionID] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VLC->modh->identifiers.requestIdentifier("faction." + node["faction"].String(),
|
||||||
|
[=](si32 factionID)
|
||||||
|
{
|
||||||
|
heroClass->faction = factionID;
|
||||||
|
});
|
||||||
|
|
||||||
|
return heroClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeroClassHandler::~CHeroClassHandler()
|
CHeroClassHandler::~CHeroClassHandler()
|
||||||
@@ -149,21 +207,102 @@ CHeroHandler::~CHeroHandler()
|
|||||||
CHeroHandler::CHeroHandler()
|
CHeroHandler::CHeroHandler()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CHeroHandler::load(const JsonNode & heroes)
|
void CHeroHandler::load(const JsonNode & input)
|
||||||
{
|
{
|
||||||
//TODO
|
BOOST_FOREACH(auto & entry, input.Struct())
|
||||||
|
{
|
||||||
|
if (!entry.second.isNull()) // may happens if mod removed creature by setting json entry to null
|
||||||
|
{
|
||||||
|
CHero * hero = loadHero(entry.second);
|
||||||
|
hero->ID = heroes.size();
|
||||||
|
|
||||||
|
heroes.push_back(hero);
|
||||||
|
tlog3 << "Added hero : " << entry.first << "\n";
|
||||||
|
VLC->modh->identifiers.registerObject("hero." + entry.first, hero->ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CHero * CHeroHandler::loadHero(const JsonNode & hero)
|
CHero * CHeroHandler::loadHero(const JsonNode & node)
|
||||||
{
|
{
|
||||||
//TODO
|
CHero * hero = new CHero;
|
||||||
return new CHero;
|
|
||||||
|
hero->name = node["texts"]["name"].String();
|
||||||
|
hero->biography = node["texts"]["biography"].String();
|
||||||
|
hero->specName = node["texts"]["specialty"]["name"].String();
|
||||||
|
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();
|
||||||
|
hero->portraitLarge = node["images"]["large"].String();
|
||||||
|
|
||||||
|
assert(node["army"].Vector().size() <= 3); // anything bigger is useless - army initialization uses up to 3 slots
|
||||||
|
hero->initialArmy.resize(node["army"].Vector().size());
|
||||||
|
|
||||||
|
for (size_t i=0; i< hero->initialArmy.size(); i++)
|
||||||
|
{
|
||||||
|
const JsonNode & source = node["army"].Vector()[i];
|
||||||
|
|
||||||
|
hero->initialArmy[i].minAmount = source["min"].Float();
|
||||||
|
hero->initialArmy[i].maxAmount = source["max"].Float();
|
||||||
|
|
||||||
|
assert(hero->initialArmy[i].minAmount <= hero->initialArmy[i].maxAmount);
|
||||||
|
|
||||||
|
VLC->modh->identifiers.requestIdentifier(std::string("creature.") + source["creature"].String(), [=](si32 creature)
|
||||||
|
{
|
||||||
|
hero->initialArmy[i].creature = creature;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadHeroJson(hero, node);
|
||||||
|
return hero;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHeroHandler::loadHeroJson(CHero * hero, const JsonNode & node)
|
||||||
|
{
|
||||||
|
// sex: 0=male, 1=female
|
||||||
|
hero->sex = !!node["female"].Bool();
|
||||||
|
|
||||||
|
BOOST_FOREACH(const JsonNode &set, node["skills"].Vector())
|
||||||
|
{
|
||||||
|
int skillID = boost::range::find(SecondarySkill::names, set["skill"].String()) - boost::begin(SecondarySkill::names);
|
||||||
|
int skillLevel = boost::range::find(SecondarySkill::levels, set["level"].String()) - boost::begin(SecondarySkill::levels);
|
||||||
|
|
||||||
|
hero->secSkillsInit.push_back(std::make_pair(skillID, skillLevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const JsonNode & spell, node["spellbook"].Vector())
|
||||||
|
{
|
||||||
|
hero->spells.insert(spell.Float());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const JsonNode &specialty, node["specialties"].Vector())
|
||||||
|
{
|
||||||
|
SSpecialtyInfo spec;
|
||||||
|
|
||||||
|
spec.type = specialty["type"].Float();
|
||||||
|
spec.val = specialty["val"].Float();
|
||||||
|
spec.subtype = specialty["subtype"].Float();
|
||||||
|
spec.additionalinfo = specialty["info"].Float();
|
||||||
|
|
||||||
|
hero->spec.push_back(spec); //put a copy of dummy
|
||||||
|
}
|
||||||
|
|
||||||
|
VLC->modh->identifiers.requestIdentifier("heroClass." + node["class"].String(),
|
||||||
|
[=](si32 classID)
|
||||||
|
{
|
||||||
|
hero->heroClass = classes.heroClasses[classID];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroHandler::load()
|
void CHeroHandler::load()
|
||||||
{
|
{
|
||||||
classes.load();
|
classes.load();
|
||||||
loadHeroes();
|
loadHeroes();
|
||||||
|
loadHeroTexts();
|
||||||
loadObstacles();
|
loadObstacles();
|
||||||
loadTerrains();
|
loadTerrains();
|
||||||
loadBallistics();
|
loadBallistics();
|
||||||
@@ -233,6 +372,7 @@ void CHeroHandler::loadHeroes()
|
|||||||
CHero * hero = new CHero;
|
CHero * hero = new CHero;
|
||||||
hero->name = parser.readString();
|
hero->name = parser.readString();
|
||||||
|
|
||||||
|
hero->initialArmy.resize(3);
|
||||||
for(int x=0;x<3;x++)
|
for(int x=0;x<3;x++)
|
||||||
{
|
{
|
||||||
hero->initialArmy[x].minAmount = parser.readNumber();
|
hero->initialArmy[x].minAmount = parser.readNumber();
|
||||||
@@ -248,6 +388,7 @@ void CHeroHandler::loadHeroes()
|
|||||||
parser.endLine();
|
parser.endLine();
|
||||||
|
|
||||||
hero->ID = heroes.size();
|
hero->ID = heroes.size();
|
||||||
|
hero->imageIndex = hero->ID;
|
||||||
heroes.push_back(hero);
|
heroes.push_back(hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,42 +396,31 @@ void CHeroHandler::loadHeroes()
|
|||||||
const JsonNode config(ResourceID("config/heroes.json"));
|
const JsonNode config(ResourceID("config/heroes.json"));
|
||||||
BOOST_FOREACH(const JsonNode &hero, config["heroes"].Vector())
|
BOOST_FOREACH(const JsonNode &hero, config["heroes"].Vector())
|
||||||
{
|
{
|
||||||
CHero * currentHero = heroes[hero["id"].Float()];
|
loadHeroJson(heroes[hero["id"].Float()], hero);
|
||||||
|
|
||||||
// sex: 0=male, 1=female
|
|
||||||
currentHero->sex = !!hero["female"].Bool();
|
|
||||||
|
|
||||||
BOOST_FOREACH(const JsonNode &set, hero["skill_set"].Vector())
|
|
||||||
{
|
|
||||||
int skillID = boost::range::find(SecondarySkill::names, set["skill"].String()) - boost::begin(SecondarySkill::names);
|
|
||||||
int skillLevel = boost::range::find(SecondarySkill::levels, set["level"].String()) - boost::begin(SecondarySkill::levels);
|
|
||||||
currentHero->secSkillsInit.push_back(std::make_pair(skillID, skillLevel));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hero["spell"].isNull()) {
|
|
||||||
currentHero->startingSpell = hero["spell"].Float();
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(const JsonNode &specialty, hero["specialties"].Vector())
|
|
||||||
{
|
|
||||||
SSpecialtyInfo dummy;
|
|
||||||
|
|
||||||
dummy.type = specialty["type"].Float();
|
|
||||||
dummy.val = specialty["val"].Float();
|
|
||||||
dummy.subtype = specialty["subtype"].Float();
|
|
||||||
dummy.additionalinfo = specialty["info"].Float();
|
|
||||||
|
|
||||||
currentHero->spec.push_back(dummy); //put a copy of dummy
|
|
||||||
}
|
|
||||||
|
|
||||||
VLC->modh->identifiers.requestIdentifier("heroClass." + hero["class"].String(),
|
|
||||||
[=](si32 classID)
|
|
||||||
{
|
|
||||||
currentHero->heroClass = classes.heroClasses[classID];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHeroHandler::loadHeroTexts()
|
||||||
|
{
|
||||||
|
CLegacyConfigParser parser("DATA/HEROSPEC.TXT");
|
||||||
|
CLegacyConfigParser bioParser("DATA/HEROBIOS.TXT");
|
||||||
|
|
||||||
|
//skip header
|
||||||
|
parser.endLine();
|
||||||
|
parser.endLine();
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
CHero * hero = heroes[i++];
|
||||||
|
hero->specName = parser.readString();
|
||||||
|
hero->specTooltip = parser.readString();
|
||||||
|
hero->specDescr = parser.readString();
|
||||||
|
hero->biography = bioParser.readString();
|
||||||
|
}
|
||||||
|
while (parser.endLine() && bioParser.endLine() && heroes.size() < i);
|
||||||
|
}
|
||||||
|
|
||||||
void CHeroHandler::loadBallistics()
|
void CHeroHandler::loadBallistics()
|
||||||
{
|
{
|
||||||
CLegacyConfigParser ballParser("DATA/BALLIST.TXT");
|
CLegacyConfigParser ballParser("DATA/BALLIST.TXT");
|
||||||
@@ -360,15 +490,4 @@ std::vector<ui8> CHeroHandler::getDefaultAllowedHeroes() const
|
|||||||
allowedHeroes[4] = 0;
|
allowedHeroes[4] = 0;
|
||||||
allowedHeroes[25] = 0;
|
allowedHeroes[25] = 0;
|
||||||
return allowedHeroes;
|
return allowedHeroes;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHero::CHero()
|
|
||||||
{
|
|
||||||
startingSpell = -1;
|
|
||||||
sex = 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
CHero::~CHero()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#include "../lib/ConstTransitivePtr.h"
|
#include "../lib/ConstTransitivePtr.h"
|
||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
|
|
||||||
@@ -13,6 +12,7 @@
|
|||||||
* Full text of license available in license.txt file, in main folder
|
* Full text of license available in license.txt file, in main folder
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CHeroClass;
|
class CHeroClass;
|
||||||
class CDefHandler;
|
class CDefHandler;
|
||||||
class CGameInfo;
|
class CGameInfo;
|
||||||
@@ -46,23 +46,35 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string name; //name of hero
|
|
||||||
si32 ID;
|
si32 ID;
|
||||||
|
si32 imageIndex;
|
||||||
|
|
||||||
InitialArmyStack initialArmy[3];
|
std::vector<InitialArmyStack> initialArmy;
|
||||||
|
|
||||||
CHeroClass * heroClass;
|
CHeroClass * heroClass;
|
||||||
std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
|
std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
|
||||||
std::vector<SSpecialtyInfo> spec;
|
std::vector<SSpecialtyInfo> spec;
|
||||||
si32 startingSpell; //-1 if none
|
std::set<si32> spells;
|
||||||
ui8 sex; // default sex: 0=male, 1=female
|
ui8 sex; // default sex: 0=male, 1=female
|
||||||
|
|
||||||
CHero();
|
/// Localized texts
|
||||||
~CHero();
|
std::string name; //name of hero
|
||||||
|
std::string biography;
|
||||||
|
std::string specName;
|
||||||
|
std::string specDescr;
|
||||||
|
std::string specTooltip;
|
||||||
|
|
||||||
|
/// Graphics
|
||||||
|
std::string iconSpecSmall;
|
||||||
|
std::string iconSpecLarge;
|
||||||
|
std::string portraitSmall;
|
||||||
|
std::string portraitLarge;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & name & ID & initialArmy & heroClass & secSkillsInit & spec & startingSpell & sex;
|
h & ID & imageIndex & initialArmy & heroClass & secSkillsInit & spec & spells & sex;
|
||||||
|
h & name & biography & specName & specDescr & specTooltip;
|
||||||
|
h & iconSpecSmall & iconSpecLarge & portraitSmall & portraitLarge;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,9 +95,12 @@ public:
|
|||||||
|
|
||||||
std::map<TFaction, int> selectionProbability; //probability of selection in towns
|
std::map<TFaction, int> selectionProbability; //probability of selection in towns
|
||||||
|
|
||||||
|
std::string imageBattleMale;
|
||||||
|
std::string imageBattleFemale;
|
||||||
|
std::string imageMapMale;
|
||||||
|
std::string imageMapFemale;
|
||||||
|
|
||||||
int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities
|
int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities
|
||||||
CHeroClass(); //c-tor
|
|
||||||
~CHeroClass(); //d-tor
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
@@ -93,6 +108,7 @@ public:
|
|||||||
h & primarySkillInitial & primarySkillLowLevel;
|
h & primarySkillInitial & primarySkillLowLevel;
|
||||||
h & primarySkillHighLevel & secSkillProbability;
|
h & primarySkillHighLevel & secSkillProbability;
|
||||||
h & selectionProbability;
|
h & selectionProbability;
|
||||||
|
h & imageBattleMale & imageBattleFemale & imageMapMale & imageMapFemale;
|
||||||
}
|
}
|
||||||
EAlignment::EAlignment getAlignment() const;
|
EAlignment::EAlignment getAlignment() const;
|
||||||
};
|
};
|
||||||
@@ -130,7 +146,7 @@ public:
|
|||||||
void load(const JsonNode & classes);
|
void load(const JsonNode & classes);
|
||||||
|
|
||||||
/// load one class from json
|
/// load one class from json
|
||||||
CHeroClass * loadClass(const JsonNode & heroClass);
|
CHeroClass * loadClass(const JsonNode & node);
|
||||||
|
|
||||||
~CHeroClassHandler();
|
~CHeroClassHandler();
|
||||||
|
|
||||||
@@ -146,6 +162,8 @@ class DLL_LINKAGE CHeroHandler
|
|||||||
/// consists of 201 values. Any higher levels require experience larger that ui64 can hold
|
/// consists of 201 values. Any higher levels require experience larger that ui64 can hold
|
||||||
std::vector<ui64> expPerLevel;
|
std::vector<ui64> expPerLevel;
|
||||||
|
|
||||||
|
/// common function for loading heroes from mods and from H3
|
||||||
|
void loadHeroJson(CHero * hero, const JsonNode & node);
|
||||||
public:
|
public:
|
||||||
CHeroClassHandler classes;
|
CHeroClassHandler classes;
|
||||||
|
|
||||||
@@ -177,12 +195,13 @@ public:
|
|||||||
void load(const JsonNode & heroes);
|
void load(const JsonNode & heroes);
|
||||||
|
|
||||||
/// Load single hero from json
|
/// Load single hero from json
|
||||||
CHero * loadHero(const JsonNode & hero);
|
CHero * loadHero(const JsonNode & node);
|
||||||
|
|
||||||
/// Load everything (calls functions below + classes.load())
|
/// Load everything (calls functions below + classes.load())
|
||||||
void load();
|
void load();
|
||||||
|
|
||||||
void loadHeroes();
|
void loadHeroes();
|
||||||
|
void loadHeroTexts();
|
||||||
void loadExperience();
|
void loadExperience();
|
||||||
void loadBallistics();
|
void loadBallistics();
|
||||||
void loadTerrains();
|
void loadTerrains();
|
||||||
|
|||||||
@@ -708,19 +708,23 @@ void CGHeroInstance::initHero()
|
|||||||
initHeroDefInfo();
|
initHeroDefInfo();
|
||||||
if(!type)
|
if(!type)
|
||||||
type = VLC->heroh->heroes[subID];
|
type = VLC->heroh->heroes[subID];
|
||||||
if(!vstd::contains(spells, 0xffffffff) && type->startingSpell >= 0) //hero starts with a spell
|
|
||||||
spells.insert(type->startingSpell);
|
if(!vstd::contains(spells, 0xffffffff)) //hero starts with a spell
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(auto spellID, type->spells)
|
||||||
|
spells.insert(spellID);
|
||||||
|
}
|
||||||
else //remove placeholder
|
else //remove placeholder
|
||||||
spells -= 0xffffffff;
|
spells -= 0xffffffff;
|
||||||
|
|
||||||
if(!getArt(ArtifactPosition::MACH4) && !getArt(ArtifactPosition::SPELLBOOK) && type->startingSpell >= 0) //no catapult means we haven't read pre-existent set -> use default rules for spellbook
|
if(!getArt(ArtifactPosition::MACH4) && !getArt(ArtifactPosition::SPELLBOOK) && !type->spells.empty()) //no catapult means we haven't read pre-existent set -> use default rules for spellbook
|
||||||
putArtifact(ArtifactPosition::SPELLBOOK, CArtifactInstance::createNewArtifactInstance(0));
|
putArtifact(ArtifactPosition::SPELLBOOK, CArtifactInstance::createNewArtifactInstance(0));
|
||||||
|
|
||||||
if(!getArt(ArtifactPosition::MACH4))
|
if(!getArt(ArtifactPosition::MACH4))
|
||||||
putArtifact(ArtifactPosition::MACH4, CArtifactInstance::createNewArtifactInstance(3)); //everyone has a catapult
|
putArtifact(ArtifactPosition::MACH4, CArtifactInstance::createNewArtifactInstance(3)); //everyone has a catapult
|
||||||
|
|
||||||
if(portrait < 0 || portrait == 255)
|
if(portrait < 0 || portrait == 255)
|
||||||
portrait = subID;
|
portrait = type->imageIndex;
|
||||||
if(!hasBonus(Selector::sourceType(Bonus::HERO_BASE_SKILL)))
|
if(!hasBonus(Selector::sourceType(Bonus::HERO_BASE_SKILL)))
|
||||||
{
|
{
|
||||||
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
|
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
|
||||||
@@ -781,6 +785,8 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
|
|||||||
else
|
else
|
||||||
howManyStacks = 3;
|
howManyStacks = 3;
|
||||||
|
|
||||||
|
vstd::amin(howManyStacks, type->initialArmy.size());
|
||||||
|
|
||||||
for(int stackNo=0; stackNo < howManyStacks; stackNo++)
|
for(int stackNo=0; stackNo < howManyStacks; stackNo++)
|
||||||
{
|
{
|
||||||
auto & stack = type->initialArmy[stackNo];
|
auto & stack = type->initialArmy[stackNo];
|
||||||
@@ -892,8 +898,7 @@ const std::string & CGHeroInstance::getBiography() const
|
|||||||
{
|
{
|
||||||
if (biography.length())
|
if (biography.length())
|
||||||
return biography;
|
return biography;
|
||||||
else
|
return type->biography;
|
||||||
return VLC->generaltexth->hTxts[subID].biography;
|
|
||||||
}
|
}
|
||||||
void CGHeroInstance::initObj()
|
void CGHeroInstance::initObj()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -472,7 +472,13 @@ void CTownHandler::load(const JsonNode &source)
|
|||||||
{
|
{
|
||||||
BOOST_FOREACH(auto & node, source.Struct())
|
BOOST_FOREACH(auto & node, source.Struct())
|
||||||
{
|
{
|
||||||
int id = node.second["index"].Float();
|
int id;
|
||||||
|
|
||||||
|
if (node.second["index"].isNull())
|
||||||
|
id = factions.rbegin()->first + 1;
|
||||||
|
else
|
||||||
|
id = node.second["index"].Float();
|
||||||
|
|
||||||
CFaction & faction = factions[id];
|
CFaction & faction = factions[id];
|
||||||
|
|
||||||
faction.factionID = id;
|
faction.factionID = id;
|
||||||
|
|||||||
@@ -416,16 +416,16 @@ bool JsonParser::extractWhitespace(bool verbose)
|
|||||||
|
|
||||||
bool JsonParser::extractEscaping(std::string &str)
|
bool JsonParser::extractEscaping(std::string &str)
|
||||||
{
|
{
|
||||||
switch(input[pos++])
|
switch(input[pos])
|
||||||
{
|
{
|
||||||
break; case '\"': str += '\"';
|
break; case '\"': str += '\"';
|
||||||
break; case '\\': str += '\\';
|
break; case '\\': str += '\\';
|
||||||
break; case '/': str += '/';
|
break; case '/': str += '/';
|
||||||
break; case '\b': str += '\b';
|
break; case 'b': str += '\b';
|
||||||
break; case '\f': str += '\f';
|
break; case 'f': str += '\f';
|
||||||
break; case '\n': str += '\n';
|
break; case 'n': str += '\n';
|
||||||
break; case '\r': str += '\r';
|
break; case 'r': str += '\r';
|
||||||
break; case '\t': str += '\t';
|
break; case 't': str += '\t';
|
||||||
break; default: return error("Unknown escape sequence!", true);
|
break; default: return error("Unknown escape sequence!", true);
|
||||||
};
|
};
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user