mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-15 13:33:36 +02:00
Fixed at least one of the #1428 infinite turns cases.
This commit is contained in:
parent
9aaaa0027e
commit
b62bb096a7
@ -1228,9 +1228,7 @@ void VCAI::recruitCreatures(const CGDwelling * d)
|
|||||||
// if(containsSavedRes(c->cost))
|
// if(containsSavedRes(c->cost))
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
TResources myRes = cb->getResourceAmount();
|
amin(count, freeResources() / VLC->creh->creatures[creID]->cost);
|
||||||
myRes[Res::GOLD] -= GOLD_RESERVE;
|
|
||||||
amin(count, myRes / VLC->creh->creatures[creID]->cost);
|
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
cb->recruitCreatures(d, creID, count, i);
|
cb->recruitCreatures(d, creID, count, i);
|
||||||
}
|
}
|
||||||
@ -1900,6 +1898,11 @@ void VCAI::tryRealize(CGoal g)
|
|||||||
//cb->recalculatePaths();
|
//cb->recalculatePaths();
|
||||||
if(!g.hero->movement)
|
if(!g.hero->movement)
|
||||||
throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!");
|
throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!");
|
||||||
|
if(g.tile == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2)
|
||||||
|
{
|
||||||
|
logAi->warnStream() << boost::format("Why do I want to move hero %s to tile %s? Already standing on that tile! ") % g.hero->name % g.tile;
|
||||||
|
throw goalFulfilledException (g);
|
||||||
|
}
|
||||||
//if(!g.isBlockedBorderGate(g.tile))
|
//if(!g.isBlockedBorderGate(g.tile))
|
||||||
//{
|
//{
|
||||||
if (ai->moveHeroToTile(g.tile, g.hero.get()))
|
if (ai->moveHeroToTile(g.tile, g.hero.get()))
|
||||||
@ -2614,6 +2617,14 @@ void VCAI::validateObject(ObjectIdRef obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TResources VCAI::freeResources() const
|
||||||
|
{
|
||||||
|
TResources myRes = cb->getResourceAmount();
|
||||||
|
myRes[Res::GOLD] -= GOLD_RESERVE;
|
||||||
|
vstd::amax(myRes[Res::GOLD], 0);
|
||||||
|
return myRes;
|
||||||
|
}
|
||||||
|
|
||||||
AIStatus::AIStatus()
|
AIStatus::AIStatus()
|
||||||
{
|
{
|
||||||
battle = NO_BATTLE;
|
battle = NO_BATTLE;
|
||||||
@ -3264,7 +3275,7 @@ TSubgoal CGoal::whatToDoToAchieve()
|
|||||||
{
|
{
|
||||||
for (auto type : creature.second)
|
for (auto type : creature.second)
|
||||||
{
|
{
|
||||||
if (type == objid)
|
if (type == objid && ai->freeResources().canAfford(VLC->creh->creatures[type]->cost))
|
||||||
dwellings.push_back(d);
|
dwellings.push_back(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3273,7 +3284,7 @@ TSubgoal CGoal::whatToDoToAchieve()
|
|||||||
if (dwellings.size())
|
if (dwellings.size())
|
||||||
{
|
{
|
||||||
boost::sort(dwellings, isCloser);
|
boost::sort(dwellings, isCloser);
|
||||||
return CGoal(GET_OBJ).setobjid (dwellings.front()->id.getNum()); //TODO: consider needed resources
|
return CGoal(GET_OBJ).setobjid (dwellings.front()->id.getNum());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return CGoal(EXPLORE);
|
return CGoal(EXPLORE);
|
||||||
@ -3435,9 +3446,12 @@ TSubgoal CGoal::whatToDoToAchieve()
|
|||||||
{
|
{
|
||||||
if(creLevel.first)
|
if(creLevel.first)
|
||||||
{
|
{
|
||||||
auto creature = VLC->creh->creatures[creLevel.second.front()];
|
for(auto & creatureID : creLevel.second)
|
||||||
if(cb->getResourceAmount().canAfford(creature->cost))
|
{
|
||||||
return false;
|
auto creature = VLC->creh->creatures[creatureID];
|
||||||
|
if(ai->freeResources().canAfford(creature->cost))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,6 +420,7 @@ public:
|
|||||||
|
|
||||||
std::vector<HeroPtr> getUnblockedHeroes() const;
|
std::vector<HeroPtr> getUnblockedHeroes() const;
|
||||||
HeroPtr primaryHero() const;
|
HeroPtr primaryHero() const;
|
||||||
|
TResources freeResources() const; //owned resources minus gold reserve
|
||||||
TResources estimateIncome() const;
|
TResources estimateIncome() const;
|
||||||
bool containsSavedRes(const TResources &cost) const;
|
bool containsSavedRes(const TResources &cost) const;
|
||||||
void checkHeroArmy (HeroPtr h);
|
void checkHeroArmy (HeroPtr h);
|
||||||
|
9
Global.h
9
Global.h
@ -629,6 +629,15 @@ namespace vstd
|
|||||||
return *pos;
|
return *pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
typename Container::const_reference atOrDefault(const Container &r, size_t index, const typename Container::const_reference &defaultValue)
|
||||||
|
{
|
||||||
|
if(isValidIndex(r, index))
|
||||||
|
return r[index];
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
using boost::math::round;
|
using boost::math::round;
|
||||||
}
|
}
|
||||||
using vstd::operator-=;
|
using vstd::operator-=;
|
||||||
|
@ -1431,7 +1431,10 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
text = CGI->generaltexth->allTexts[565]; //The %s casts %s
|
text = CGI->generaltexth->allTexts[565]; //The %s casts %s
|
||||||
boost::algorithm::replace_first(text, "%s", CGI->creh->creatures[sc->attackerType]->namePl); //casting stack
|
if(auto castingCreature = vstd::atOrDefault(CGI->creh->creatures, sc->attackerType, nullptr))
|
||||||
|
boost::algorithm::replace_first(text, "%s", castingCreature->namePl); //casting stack
|
||||||
|
else
|
||||||
|
boost::algorithm::replace_first(text, "%s", "@Unknown caster@"); //should not happen
|
||||||
}
|
}
|
||||||
if (plural)
|
if (plural)
|
||||||
{
|
{
|
||||||
@ -1459,9 +1462,9 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
|
|||||||
{
|
{
|
||||||
boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetHeroInfo(sc->side).name);
|
boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetHeroInfo(sc->side).name);
|
||||||
}
|
}
|
||||||
else if(sc->attackerType < CGI->creh->creatures.size())
|
if(auto castingCreature = vstd::atOrDefault(CGI->creh->creatures, sc->attackerType, nullptr))
|
||||||
{
|
{
|
||||||
boost::algorithm::replace_first(text, "%s", CGI->creh->creatures[sc->attackerType]->namePl); //creature caster
|
boost::algorithm::replace_first(text, "%s", castingCreature->namePl); //creature caster
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,10 @@ public:
|
|||||||
ConstTransitivePtr(T *Ptr = nullptr)
|
ConstTransitivePtr(T *Ptr = nullptr)
|
||||||
: ptr(Ptr)
|
: ptr(Ptr)
|
||||||
{}
|
{}
|
||||||
|
ConstTransitivePtr(std::nullptr_t)
|
||||||
|
: ptr(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
const T& operator*() const
|
const T& operator*() const
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user