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

- some tweaks towards new towns

- it is possible for faction to have 0 available heroes
This commit is contained in:
Ivan Savenko 2012-10-06 08:47:13 +00:00
parent 9f0441a0be
commit da7a6234b1
6 changed files with 42 additions and 38 deletions

View File

@ -180,7 +180,6 @@ private:
class SiegeHelper class SiegeHelper
{ {
private: private:
static std::string townTypeInfixes[GameConstants::F_NUMBER]; //for internal use only - to build filenames
SDL_Surface* walls[18]; SDL_Surface* walls[18];
const CBattleInterface * owner; const CBattleInterface * owner;
public: public:

View File

@ -2012,7 +2012,9 @@ bool OptionsTab::canUseThisHero( int ID )
// if(CPG->ret.playerInfos[i].hero==ID) //hero is already taken // if(CPG->ret.playerInfos[i].hero==ID) //hero is already taken
// return false; // return false;
return !vstd::contains(usedHeroes, ID) && SEL->current->mapHeader->allowedHeroes[ID]; return CGI->heroh->heroes.size() > ID
&& !vstd::contains(usedHeroes, ID)
&& SEL->current->mapHeader->allowedHeroes[ID];
} }
void OptionsTab::nextBonus( int player, int dir ) void OptionsTab::nextBonus( int player, int dir )
@ -2334,12 +2336,12 @@ SDL_Surface * OptionsTab::SelectedBox::getImg() const
switch(which) switch(which)
{ {
case TOWN: case TOWN:
if (s.castle < GameConstants::F_NUMBER && s.castle >= 0) if (s.castle == -1)
return graphics->getPic(s.castle, true, false);
else if (s.castle == -1)
return CGP->rTown; return CGP->rTown;
else if (s.castle == -2) if (s.castle == -2)
return CGP->nTown; return CGP->nTown;
else
return graphics->getPic(s.castle, true, false);
case HERO: case HERO:
if (s.hero == -1) if (s.hero == -1)
{ {
@ -2370,12 +2372,12 @@ const std::string * OptionsTab::SelectedBox::getText() const
switch(which) switch(which)
{ {
case TOWN: case TOWN:
if (s.castle < GameConstants::F_NUMBER && s.castle >= 0) if (s.castle == -1)
return &CGI->townh->factions[s.castle].name;
else if (s.castle == -1)
return &CGI->generaltexth->allTexts[522]; return &CGI->generaltexth->allTexts[522];
else if (s.castle == -2) else if (s.castle == -2)
return &CGI->generaltexth->allTexts[523]; return &CGI->generaltexth->allTexts[523];
else
return &CGI->townh->factions[s.castle].name;
case HERO: case HERO:
if (s.hero == -1) if (s.hero == -1)
return &CGI->generaltexth->allTexts[522]; return &CGI->generaltexth->allTexts[522];

View File

@ -407,7 +407,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor p
} }
if(!pool.size()) if(!pool.size())
{ {
tlog1 << "Cannot pick native hero for " << player << ". Picking any...\n"; tlog1 << "Cannot pick native hero for " << int(player) << ". Picking any...\n";
return pickHeroFor(false, player, town, available); return pickHeroFor(false, player, town, available);
} }
else else
@ -428,10 +428,10 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, TPlayerColor p
sum += i->second->type->heroClass->selectionProbability[town->typeID]; //total weight sum += i->second->type->heroClass->selectionProbability[town->typeID]; //total weight
} }
} }
if(!pool.size()) if(!pool.size() || sum == 0)
{ {
tlog1 << "There are no heroes available for player " << player<<"!\n"; tlog1 << "There are no heroes available for player " << player<<"!\n";
return NULL; return nullptr;
} }
r = rand()%sum; r = rand()%sum;
@ -480,21 +480,32 @@ int CGameState::pickHero(int owner)
} }
} }
int i=0; //list of heroes for this faction
std::vector<si32> factionHeroes;
factionHeroes.reserve(GameConstants::HEROES_PER_TYPE*2);
do //try to find free hero of our faction size_t firstHero = ps.castle*GameConstants::HEROES_PER_TYPE*2;
size_t lastHero = std::min(firstHero + GameConstants::HEROES_PER_TYPE*2, VLC->heroh->heroes.size());
//generate list of heroes
for (si32 i=firstHero; i<lastHero; i++)
factionHeroes.push_back(i);
// we need random order to select hero
std::random_shuffle(factionHeroes.begin(), factionHeroes.end());
for (size_t i=0; i<factionHeroes.size(); i++)
{ {
i++; if (!map->getHero(factionHeroes[i]))
h = ps.castle*GameConstants::HEROES_PER_TYPE*2+(ran()%(GameConstants::HEROES_PER_TYPE*2));//->scenarioOps->playerInfos[pru].hero = VLC-> return factionHeroes[i];
} while( map->getHero(h) && i<(GameConstants::HEROES_QUANTITY+18+1));
if(i>GameConstants::HEROES_QUANTITY+18) //probably no free heroes - there's no point in further search, we'll take first free
{
tlog3 << "Warning: cannot find free hero - trying to get first available..."<<std::endl;
for(int j=0; j<GameConstants::HEROES_QUANTITY; j++)
if(!map->getHero(j))
h=j;
} }
return h;
tlog3 << "Warning: cannot find free hero - trying to get first available..."<<std::endl;
for(int j=0; j<VLC->heroh->heroes.size(); j++)
if(!map->getHero(j))
return j;
assert(0); //currrent code can't handle this situation
return -1; // no available heroes at all
} }

View File

@ -261,7 +261,7 @@ void CHeroHandler::loadHeroClasses()
hc->proSec[dd] = parser.readNumber(); hc->proSec[dd] = parser.readNumber();
} }
for(int dd=0; dd<ARRAY_COUNT(hc->selectionProbability); ++dd) for(int dd=0; dd<GameConstants::F_NUMBER; ++dd)
{ {
hc->selectionProbability[dd] = parser.readNumber(); hc->selectionProbability[dd] = parser.readNumber();
} }

View File

@ -68,7 +68,7 @@ public:
int initialPrimSkills[GameConstants::PRIMARY_SKILLS]; //initial values of primary skills, uses PrimarySkill enum int initialPrimSkills[GameConstants::PRIMARY_SKILLS]; //initial values of primary skills, uses PrimarySkill enum
std::vector<std::pair<int,int> > primChance;//primChance[PRIMARY_SKILL_ID] - first is for levels 2 - 9, second for 10+;;; probability (%) of getting point of primary skill when getting new level std::vector<std::pair<int,int> > primChance;//primChance[PRIMARY_SKILL_ID] - first is for levels 2 - 9, second for 10+;;; probability (%) of getting point of primary skill when getting new level
std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order
int selectionProbability[GameConstants::F_NUMBER]; //probability of selection in towns std::map<TFaction, int> selectionProbability; //probability of selection in towns
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(); //c-tor

View File

@ -117,19 +117,11 @@ struct DLL_LINKAGE PlayerInfo
si8 defaultCastle() const si8 defaultCastle() const
{ {
si8 ret = -2; assert(!allowedFactions.empty()); // impossible?
for (int j = 0; j < GameConstants::F_NUMBER && ret != -1; j++) //we start with none and find matching faction. if more than one, then set to random
{
if(vstd::contains(allowedFactions, j))
{
if (ret >= 0) //we've already assigned a castle and another one is possible -> set random and let player choose
ret = -1; //breaks
if (ret == -2) //first available castle - pick if (allowedFactions.size() == 1)
ret = j; return *allowedFactions.begin(); //only one faction s available - pick it
} return -1; // set to random
}
return ret;
} }
si8 defaultHero() const si8 defaultHero() const
{ {