mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-24 03:47:18 +02:00
Fixed two possible block-ups in AI. Fixed possible problems with picking hero available to recruit (no more duplicates hopefully).
This commit is contained in:
parent
1872c2d575
commit
310c369265
@ -685,13 +685,15 @@ list<int> CBattleLogic::PerformDefaultAction(int stackID, int &additionalInfo)
|
||||
|
||||
for (std::map<int, int>::iterator it = votes.begin(); it != votes.end(); ++it)
|
||||
{
|
||||
if (it->second > max_vote)
|
||||
if (m_cb->battleGetStackByID(it->first)->attackerOwned == m_side //it's hostile stack
|
||||
&& it->second > max_vote)
|
||||
{
|
||||
max_vote = it->second;
|
||||
creatures.push_front(it->first);
|
||||
}
|
||||
}
|
||||
additionalInfo = 0; // list contains creatures which shoud be attacked
|
||||
|
||||
return creatures;
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, Hypotheti
|
||||
//buildBuilding
|
||||
if(hgs.heroModels.size()<3&&hgs.resourceAmounts[6]>=2500) //recruitHero
|
||||
{
|
||||
if(!t.visitingHero)
|
||||
if(!t.visitingHero && vstd::contains(t.t->builtBuildings, 5)) //no visiting hero and built tavern
|
||||
{
|
||||
for(int i =0; i < hgs.AvailableHeroesToBuy.size();i++)
|
||||
if(hgs.AvailableHeroesToBuy[i]!=NULL&&hgs.AvailableHeroesToBuy[i]->army.slots.size()>1)//only buy heros with units
|
||||
|
@ -662,39 +662,45 @@ bool CStack::willMove()
|
||||
&& ! hasFeatureOfType(StackFeature::NOT_ACTIVE); //eg. Ammo Cart
|
||||
}
|
||||
|
||||
CGHeroInstance* CGameState::HeroesPool::pickHeroFor(bool native, int player, const CTown *town, int notThatOne)
|
||||
CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, int player, const CTown *town, std::map<ui32,CGHeroInstance *> &available) const
|
||||
{
|
||||
CGHeroInstance *ret = NULL;
|
||||
|
||||
if(player<0 || player>=PLAYER_LIMIT)
|
||||
{
|
||||
tlog1 << "Cannot pick hero for " << town->Name() << ". Wrong owner!\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<CGHeroInstance *> pool;
|
||||
int sum=0, r;
|
||||
|
||||
if(native)
|
||||
{
|
||||
for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
|
||||
for(std::map<ui32,CGHeroInstance *>::iterator i=available.begin(); i!=available.end(); i++)
|
||||
{
|
||||
if(pavailable[i->first] & 1<<player
|
||||
&& i->second->type->heroType/2 == town->typeID
|
||||
&& i->second->subID != notThatOne
|
||||
)
|
||||
if(pavailable.find(i->first)->second & 1<<player
|
||||
&& i->second->type->heroType/2 == town->typeID)
|
||||
{
|
||||
pool.push_back(i->second);
|
||||
}
|
||||
}
|
||||
if(!pool.size())
|
||||
return pickHeroFor(false,player,town,notThatOne);
|
||||
{
|
||||
tlog1 << "Cannot pick native hero for " << player << ". Picking any...\n";
|
||||
return pickHeroFor(false, player, town, available);
|
||||
}
|
||||
else
|
||||
return pool[rand()%pool.size()];
|
||||
{
|
||||
ret = pool[rand()%pool.size()];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
|
||||
int sum=0, r;
|
||||
|
||||
for(std::map<ui32,CGHeroInstance *>::iterator i=available.begin(); i!=available.end(); i++)
|
||||
{
|
||||
if(pavailable[i->first] & 1<<player
|
||||
&& i->second->subID != notThatOne
|
||||
)
|
||||
if(pavailable.find(i->first)->second & 1<<player)
|
||||
{
|
||||
pool.push_back(i->second);
|
||||
sum += i->second->type->heroClass->selectionProbability[town->typeID];
|
||||
@ -705,17 +711,24 @@ CGHeroInstance* CGameState::HeroesPool::pickHeroFor(bool native, int player, con
|
||||
tlog1 << "There are no heroes available for player " << player<<"!\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = rand()%sum;
|
||||
for(unsigned int i=0; i<pool.size(); i++)
|
||||
{
|
||||
r -= pool[i]->type->heroClass->selectionProbability[town->typeID];
|
||||
if(r<0)
|
||||
return pool[i];
|
||||
ret = pool[i];
|
||||
}
|
||||
return pool[pool.size()-1];
|
||||
if(!ret)
|
||||
ret = pool.back();
|
||||
}
|
||||
|
||||
available.erase(ret->subID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//void CGameState::apply(CPack * pack)
|
||||
//{
|
||||
// while(!mx->try_lock())
|
||||
|
@ -251,7 +251,7 @@ public:
|
||||
std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
|
||||
std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
|
||||
|
||||
CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
|
||||
CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, std::map<ui32,CGHeroInstance *> &available) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -455,6 +455,7 @@ DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
|
||||
|
||||
DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
|
||||
{
|
||||
assert(vstd::contains(gs->hpool.heroesPool, hid));
|
||||
CGHeroInstance *h = gs->hpool.heroesPool[hid];
|
||||
CGTownInstance *t = gs->getTown(tid);
|
||||
h->setOwner(player);
|
||||
|
@ -660,6 +660,8 @@ void CGameHandler::newTurn()
|
||||
n.day = gs->day + 1;
|
||||
n.resetBuilded = true;
|
||||
|
||||
std::map<ui32,CGHeroInstance *> pool = gs->hpool.heroesPool;
|
||||
|
||||
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
{
|
||||
if(i->first == 255) continue;
|
||||
@ -667,12 +669,12 @@ void CGameHandler::newTurn()
|
||||
{
|
||||
SetAvailableHeroes sah;
|
||||
sah.player = i->first;
|
||||
CGHeroInstance *h = gs->hpool.pickHeroFor(true,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle]);
|
||||
CGHeroInstance *h = gs->hpool.pickHeroFor(true,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle], pool);
|
||||
if(h)
|
||||
sah.hid1 = h->subID;
|
||||
else
|
||||
sah.hid1 = -1;
|
||||
h = gs->hpool.pickHeroFor(false,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle],sah.hid1);
|
||||
h = gs->hpool.pickHeroFor(false,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle], pool);
|
||||
if(h)
|
||||
sah.hid2 = h->subID;
|
||||
else
|
||||
@ -2236,6 +2238,7 @@ bool CGameHandler::hireHero( ui32 tid, ui8 hid )
|
||||
)
|
||||
return false;
|
||||
CGHeroInstance *nh = gs->getPlayer(t->tempOwner)->availableHeroes[hid];
|
||||
assert(nh);
|
||||
|
||||
HeroRecruited hr;
|
||||
hr.tid = tid;
|
||||
@ -2244,9 +2247,18 @@ bool CGameHandler::hireHero( ui32 tid, ui8 hid )
|
||||
hr.tile = t->pos - int3(1,0,0);
|
||||
sendAndApply(&hr);
|
||||
|
||||
|
||||
std::map<ui32,CGHeroInstance *> pool = gs->hpool.heroesPool;
|
||||
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
for(std::vector<CGHeroInstance *>::iterator j = i->second.availableHeroes.begin(); j != i->second.availableHeroes.end(); j++)
|
||||
if(*j)
|
||||
pool.erase((**j).subID);
|
||||
|
||||
SetAvailableHeroes sah;
|
||||
(hid ? sah.hid2 : sah.hid1) = gs->hpool.pickHeroFor(false,t->tempOwner,t->town)->subID;
|
||||
(hid ? sah.hid1 : sah.hid2) = gs->getPlayer(t->tempOwner)->availableHeroes[!hid]->subID;
|
||||
CGHeroInstance *h1 = gs->hpool.pickHeroFor(false,t->tempOwner,t->town, pool),
|
||||
*h2 = gs->getPlayer(t->tempOwner)->availableHeroes[!hid];
|
||||
(hid ? sah.hid2 : sah.hid1) = h1 ? h1->subID : -1;
|
||||
(hid ? sah.hid1 : sah.hid2) = h2 ? h2->subID : -1;
|
||||
sah.player = t->tempOwner;
|
||||
sah.flags = hid+1;
|
||||
sendAndApply(&sah);
|
||||
|
Loading…
x
Reference in New Issue
Block a user