mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
- fixed empty tavern in new towns
- by default new heroes\new towns will be enabled on maps (no effect without mods)
This commit is contained in:
parent
e775ad8804
commit
ff146a80fe
@ -2298,16 +2298,16 @@ void OptionsTab::nextHero( int player, int dir )
|
|||||||
|
|
||||||
if (s.hero == PlayerSettings::RANDOM) // first/last available
|
if (s.hero == PlayerSettings::RANDOM) // first/last available
|
||||||
{
|
{
|
||||||
int max = (s.castle*GameConstants::HEROES_PER_TYPE*2+15),
|
int max = CGI->heroh->heroes.size(),
|
||||||
min = (s.castle*GameConstants::HEROES_PER_TYPE*2);
|
min = 0;
|
||||||
s.hero = nextAllowedHero(min,max,0,dir);
|
s.hero = nextAllowedHero(player, min,max,0,dir);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(dir > 0)
|
if(dir > 0)
|
||||||
s.hero = nextAllowedHero(s.hero,(s.castle*GameConstants::HEROES_PER_TYPE*2+16),1,dir);
|
s.hero = nextAllowedHero(player, s.hero, CGI->heroh->heroes.size(), 1, dir);
|
||||||
else
|
else
|
||||||
s.hero = nextAllowedHero(s.castle*GameConstants::HEROES_PER_TYPE*2-1,s.hero,1,dir);
|
s.hero = nextAllowedHero(player, 0, s.hero, 1, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(old != s.hero)
|
if(old != s.hero)
|
||||||
@ -2320,26 +2320,27 @@ void OptionsTab::nextHero( int player, int dir )
|
|||||||
SEL->propagateOptions();
|
SEL->propagateOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
int OptionsTab::nextAllowedHero( int min, int max, int incl, int dir )
|
int OptionsTab::nextAllowedHero( int player, int min, int max, int incl, int dir )
|
||||||
{
|
{
|
||||||
if(dir>0)
|
if(dir>0)
|
||||||
{
|
{
|
||||||
for(int i=min+incl; i<=max-incl; i++)
|
for(int i=min+incl; i<=max-incl; i++)
|
||||||
if(canUseThisHero(i))
|
if(canUseThisHero(player, i))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int i=max-incl; i>=min+incl; i--)
|
for(int i=max-incl; i>=min+incl; i--)
|
||||||
if(canUseThisHero(i))
|
if(canUseThisHero(player, i))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OptionsTab::canUseThisHero( int ID )
|
bool OptionsTab::canUseThisHero( int player, int ID )
|
||||||
{
|
{
|
||||||
return CGI->heroh->heroes.size() > ID
|
return CGI->heroh->heroes.size() > ID
|
||||||
|
&& SEL->sInfo.playerInfos[player].castle == CGI->heroh->heroes[ID]->heroClass->faction
|
||||||
&& !vstd::contains(usedHeroes, ID)
|
&& !vstd::contains(usedHeroes, ID)
|
||||||
&& SEL->current->mapHeader->allowedHeroes[ID];
|
&& SEL->current->mapHeader->allowedHeroes[ID];
|
||||||
}
|
}
|
||||||
|
@ -276,9 +276,9 @@ public:
|
|||||||
~OptionsTab();
|
~OptionsTab();
|
||||||
void showAll(SDL_Surface * to);
|
void showAll(SDL_Surface * to);
|
||||||
|
|
||||||
int nextAllowedHero( int min, int max, int incl, int dir );
|
int nextAllowedHero(int player, int min, int max, int incl, int dir );
|
||||||
|
|
||||||
bool canUseThisHero( int ID );
|
bool canUseThisHero(int player, int ID );
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
"id": 4,
|
"id": 4,
|
||||||
"class" : "knight",
|
"class" : "knight",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "leadership", "level": "basic" },
|
{ "skill" : "leadership", "level": "basic" },
|
||||||
@ -2103,6 +2104,7 @@
|
|||||||
"id": 144,
|
"id": 144,
|
||||||
"class" : "knight",
|
"class" : "knight",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "leadership", "level": "advanced" }
|
{ "skill" : "leadership", "level": "advanced" }
|
||||||
@ -2116,6 +2118,7 @@
|
|||||||
"id": 145,
|
"id": 145,
|
||||||
"class" : "witch",
|
"class" : "witch",
|
||||||
"female": true,
|
"female": true,
|
||||||
|
"special" : true,
|
||||||
"spellbook": [ 22 ],
|
"spellbook": [ 22 ],
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
@ -2130,6 +2133,7 @@
|
|||||||
"id": 146,
|
"id": 146,
|
||||||
"class" : "knight",
|
"class" : "knight",
|
||||||
"female": true,
|
"female": true,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "leadership", "level": "basic" },
|
{ "skill" : "leadership", "level": "basic" },
|
||||||
@ -2144,6 +2148,7 @@
|
|||||||
"id": 147,
|
"id": 147,
|
||||||
"class" : "wizard",
|
"class" : "wizard",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"spellbook": [ 53 ],
|
"spellbook": [ 53 ],
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
@ -2159,6 +2164,7 @@
|
|||||||
"id": 148,
|
"id": 148,
|
||||||
"class" : "ranger",
|
"class" : "ranger",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "archery", "level": "basic" },
|
{ "skill" : "archery", "level": "basic" },
|
||||||
@ -2174,6 +2180,7 @@
|
|||||||
"id": 149,
|
"id": 149,
|
||||||
"class" : "barbarian",
|
"class" : "barbarian",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "offence", "level": "advanced" }
|
{ "skill" : "offence", "level": "advanced" }
|
||||||
@ -2189,6 +2196,7 @@
|
|||||||
"id": 150,
|
"id": 150,
|
||||||
"class" : "deathknight",
|
"class" : "deathknight",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"spellbook": [ 54 ],
|
"spellbook": [ 54 ],
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
@ -2205,6 +2213,7 @@
|
|||||||
"id": 151,
|
"id": 151,
|
||||||
"class" : "warlock",
|
"class" : "warlock",
|
||||||
"female": true,
|
"female": true,
|
||||||
|
"special" : true,
|
||||||
"spellbook": [ 15 ],
|
"spellbook": [ 15 ],
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
@ -2221,6 +2230,7 @@
|
|||||||
"id": 152,
|
"id": 152,
|
||||||
"class" : "knight",
|
"class" : "knight",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "leadership", "level": "basic" },
|
{ "skill" : "leadership", "level": "basic" },
|
||||||
@ -2235,6 +2245,7 @@
|
|||||||
"id": 153,
|
"id": 153,
|
||||||
"class" : "warlock",
|
"class" : "warlock",
|
||||||
"female": true,
|
"female": true,
|
||||||
|
"special" : true,
|
||||||
"spellbook": [ 15 ],
|
"spellbook": [ 15 ],
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
@ -2251,6 +2262,7 @@
|
|||||||
"id": 154,
|
"id": 154,
|
||||||
"class" : "barbarian",
|
"class" : "barbarian",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "tactics", "level": "basic" },
|
{ "skill" : "tactics", "level": "basic" },
|
||||||
@ -2265,6 +2277,7 @@
|
|||||||
"id": 155,
|
"id": 155,
|
||||||
"class" : "demoniac",
|
"class" : "demoniac",
|
||||||
"female": false,
|
"female": false,
|
||||||
|
"special" : true,
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "leadership", "level": "basic" },
|
{ "skill" : "leadership", "level": "basic" },
|
||||||
|
@ -217,7 +217,7 @@ void CHeroHandler::load(const JsonNode & input)
|
|||||||
hero->ID = heroes.size();
|
hero->ID = heroes.size();
|
||||||
|
|
||||||
heroes.push_back(hero);
|
heroes.push_back(hero);
|
||||||
tlog3 << "Added hero : " << entry.first << "\n";
|
tlog3 << "Added hero: " << entry.first << "\n";
|
||||||
VLC->modh->identifiers.registerObject("hero." + entry.first, hero->ID);
|
VLC->modh->identifiers.registerObject("hero." + entry.first, hero->ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,7 +264,8 @@ CHero * CHeroHandler::loadHero(const JsonNode & node)
|
|||||||
void CHeroHandler::loadHeroJson(CHero * hero, const JsonNode & node)
|
void CHeroHandler::loadHeroJson(CHero * hero, const JsonNode & node)
|
||||||
{
|
{
|
||||||
// sex: 0=male, 1=female
|
// sex: 0=male, 1=female
|
||||||
hero->sex = !!node["female"].Bool();
|
hero->sex = node["female"].Bool();
|
||||||
|
hero->special = node["special"].Bool();
|
||||||
|
|
||||||
BOOST_FOREACH(const JsonNode &set, node["skills"].Vector())
|
BOOST_FOREACH(const JsonNode &set, node["skills"].Vector())
|
||||||
{
|
{
|
||||||
@ -418,7 +419,7 @@ void CHeroHandler::loadHeroTexts()
|
|||||||
hero->specDescr = parser.readString();
|
hero->specDescr = parser.readString();
|
||||||
hero->biography = bioParser.readString();
|
hero->biography = bioParser.readString();
|
||||||
}
|
}
|
||||||
while (parser.endLine() && bioParser.endLine() && heroes.size() < i);
|
while (parser.endLine() && bioParser.endLine() && heroes.size() > i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroHandler::loadBallistics()
|
void CHeroHandler::loadBallistics()
|
||||||
@ -482,12 +483,12 @@ std::vector<ui8> CHeroHandler::getDefaultAllowedHeroes() const
|
|||||||
{
|
{
|
||||||
// Look Data/HOTRAITS.txt for reference
|
// Look Data/HOTRAITS.txt for reference
|
||||||
std::vector<ui8> allowedHeroes;
|
std::vector<ui8> allowedHeroes;
|
||||||
allowedHeroes.resize(156, 1);
|
allowedHeroes.reserve(heroes.size());
|
||||||
for(int i = 145; i < 156; ++i)
|
|
||||||
|
BOOST_FOREACH(const CHero * hero, heroes)
|
||||||
{
|
{
|
||||||
allowedHeroes[i] = 0;
|
allowedHeroes.push_back(!hero->special);
|
||||||
}
|
}
|
||||||
allowedHeroes[4] = 0;
|
|
||||||
allowedHeroes[25] = 0;
|
|
||||||
return allowedHeroes;
|
return allowedHeroes;
|
||||||
}
|
}
|
@ -56,6 +56,7 @@ public:
|
|||||||
std::vector<SSpecialtyInfo> spec;
|
std::vector<SSpecialtyInfo> spec;
|
||||||
std::set<si32> spells;
|
std::set<si32> spells;
|
||||||
ui8 sex; // default sex: 0=male, 1=female
|
ui8 sex; // default sex: 0=male, 1=female
|
||||||
|
ui8 special; // hero is special and won't be placed in game (unless preset on map), e.g. campaign heroes
|
||||||
|
|
||||||
/// Localized texts
|
/// Localized texts
|
||||||
std::string name; //name of hero
|
std::string name; //name of hero
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "JsonNode.h"
|
#include "JsonNode.h"
|
||||||
#include "StringConstants.h"
|
#include "StringConstants.h"
|
||||||
#include "CModHandler.h"
|
#include "CModHandler.h"
|
||||||
|
#include "CHeroHandler.h"
|
||||||
#include "CArtHandler.h"
|
#include "CArtHandler.h"
|
||||||
#include "Filesystem/CResourceLoader.h"
|
#include "Filesystem/CResourceLoader.h"
|
||||||
|
|
||||||
@ -435,7 +436,17 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source)
|
|||||||
town.creatures[i][j] = creature;
|
town.creatures[i][j] = creature;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set chance of specific hero class to appear in this town
|
||||||
|
BOOST_FOREACH(auto &node, source["tavern"].Struct())
|
||||||
|
{
|
||||||
|
int chance = node.second.Float();
|
||||||
|
|
||||||
|
VLC->modh->identifiers.requestIdentifier(std::string("heroClass.") + node.first, [=, &town](si32 classID)
|
||||||
|
{
|
||||||
|
VLC->heroh->classes.heroClasses[classID]->selectionProbability[town.typeID] = chance;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBuildings(town, source["buildings"]);
|
loadBuildings(town, source["buildings"]);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "../VCMI_Lib.h"
|
#include "../VCMI_Lib.h"
|
||||||
#include "../CSpellHandler.h"
|
#include "../CSpellHandler.h"
|
||||||
#include "../CCreatureHandler.h"
|
#include "../CCreatureHandler.h"
|
||||||
|
#include "../CHeroHandler.h"
|
||||||
#include "../CObjectHandler.h"
|
#include "../CObjectHandler.h"
|
||||||
#include "../CDefObjInfoHandler.h"
|
#include "../CDefObjInfoHandler.h"
|
||||||
|
|
||||||
@ -268,17 +269,19 @@ void CMapLoaderH3M::readPlayerInfo()
|
|||||||
|
|
||||||
// Factions this player can choose
|
// Factions this player can choose
|
||||||
ui16 allowedFactions = buffer[pos++];
|
ui16 allowedFactions = buffer[pos++];
|
||||||
if(mapHeader->version != EMapFormat::ROE)
|
// How many factions will be read from map
|
||||||
{
|
ui16 totalFactions = GameConstants::F_NUMBER;
|
||||||
allowedFactions += (buffer[pos++]) * 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapHeader->players[i].allowedFactions.clear();
|
if(mapHeader->version != EMapFormat::ROE)
|
||||||
for(int fact = 0; fact < 16; ++fact)
|
allowedFactions += (buffer[pos++]) * 256;
|
||||||
|
else
|
||||||
|
totalFactions--; //exclude conflux for ROE
|
||||||
|
|
||||||
|
for(int fact = 0; fact < totalFactions; ++fact)
|
||||||
{
|
{
|
||||||
if(allowedFactions & (1 << fact))
|
if(!(allowedFactions & (1 << fact)))
|
||||||
{
|
{
|
||||||
mapHeader->players[i].allowedFactions.insert(fact);
|
mapHeader->players[i].allowedFactions.erase(fact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,7 +478,7 @@ void CMapLoaderH3M::readTeamInfo()
|
|||||||
void CMapLoaderH3M::readAllowedHeroes()
|
void CMapLoaderH3M::readAllowedHeroes()
|
||||||
{
|
{
|
||||||
int pom = pos;
|
int pom = pos;
|
||||||
mapHeader->allowedHeroes.resize(GameConstants::HEROES_QUANTITY, false);
|
mapHeader->allowedHeroes.resize(VLC->heroh->heroes.size(), true);
|
||||||
for(; pos < pom + (mapHeader->version == EMapFormat::ROE ? 16 : 20) ; ++pos)
|
for(; pos < pom + (mapHeader->version == EMapFormat::ROE ? 16 : 20) ; ++pos)
|
||||||
{
|
{
|
||||||
ui8 c = buffer[pos];
|
ui8 c = buffer[pos];
|
||||||
@ -483,9 +486,9 @@ void CMapLoaderH3M::readAllowedHeroes()
|
|||||||
{
|
{
|
||||||
if((pos - pom) * 8 + yy < GameConstants::HEROES_QUANTITY)
|
if((pos - pom) * 8 + yy < GameConstants::HEROES_QUANTITY)
|
||||||
{
|
{
|
||||||
if(c == (c | static_cast<ui8>(std::pow(2., yy))))
|
if(c != (c | static_cast<ui8>(std::pow(2., yy))))
|
||||||
{
|
{
|
||||||
mapHeader->allowedHeroes[(pos - pom) * 8 + yy] = true;
|
mapHeader->allowedHeroes[(pos - pom) * 8 + yy] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user