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

Implemented preserving hero on retreat on 7th day after end of turn

This commit is contained in:
Ivan Savenko 2023-07-11 23:37:17 +03:00
parent 9a38d8ea97
commit cb16636fce
5 changed files with 73 additions and 15 deletions

View File

@ -113,6 +113,15 @@ void TavernHeroesPool::onNewDay()
hero.second->setMovementPoints(hero.second->movementPointsLimit(true));
hero.second->mana = hero.second->manaLimit();
}
for (auto & slot : currentTavern)
{
if (slot.role == TavernSlotRole::RETREATED_TODAY)
slot.role = TavernSlotRole::RETREATED;
if (slot.role == TavernSlotRole::SURRENDERED_TODAY)
slot.role = TavernSlotRole::SURRENDERED;
}
}
void TavernHeroesPool::addHeroToPool(CGHeroInstance * hero)

View File

@ -26,10 +26,10 @@ enum class TavernSlotRole : int8_t
FULL_ARMY, // hero was added to tavern on new week and still has full army
RETREATED, // hero was owned by player before, but have retreated from battle and only has 1 creature in army
SURRENDERED, // hero was owned by player before, but have surrendered in battle and kept some troops
RETREATED_TODAY,
// SURRENDERED_DAY7, // helper value for heroes that surrendered after 7th day during enemy turn
// RETREATED_DAY7,
SURRENDERED, // hero was owned by player before, but have surrendered in battle and kept some troops
SURRENDERED_TODAY,
};
VCMI_LIB_NAMESPACE_END

View File

@ -99,8 +99,6 @@ class CGameHandler : public IGameCallback, public CBattleInfoCallback, public En
std::shared_ptr<CApplier<CBaseForGHApply>> applier;
std::unique_ptr<boost::thread> battleThread;
void deserializationFix();
public:
std::unique_ptr<HeroPoolProcessor> heroPool;
@ -365,6 +363,8 @@ public:
scripting::Pool * getContextPool() const override;
#endif
std::list<PlayerColor> generatePlayerTurnOrder() const;
friend class CVCMIServer;
private:
std::unique_ptr<events::EventBus> serverEventBus;
@ -373,8 +373,9 @@ private:
#endif
void reinitScripting();
void deserializationFix();
std::list<PlayerColor> generatePlayerTurnOrder() const;
void makeStackDoNothing(const CStack * next);
void getVictoryLossMessage(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult, InfoWindow & out) const;

View File

@ -32,6 +32,29 @@ HeroPoolProcessor::HeroPoolProcessor(CGameHandler * gameHandler)
{
}
bool HeroPoolProcessor::playerEndedTurn(const PlayerColor & player)
{
// our player is acting right now and have not ended turn
if (player == gameHandler->gameState()->currentPlayer)
return false;
auto turnOrder = gameHandler->generatePlayerTurnOrder();
for (auto const & entry : turnOrder)
{
// our player is yet to start turn
if (entry == gameHandler->gameState()->currentPlayer)
return false;
// our player have finished turn
if (entry == player)
return true;
}
assert(false);
return false;
}
TavernHeroSlot HeroPoolProcessor::selectSlotForRole(const PlayerColor & player, TavernSlotRole roleID)
{
const auto & hpool = gameHandler->gameState()->hpool;
@ -67,8 +90,12 @@ TavernHeroSlot HeroPoolProcessor::selectSlotForRole(const PlayerColor & player,
void HeroPoolProcessor::onHeroSurrendered(const PlayerColor & color, const CGHeroInstance * hero)
{
SetAvailableHero sah;
sah.slotID = selectSlotForRole(color, TavernSlotRole::SURRENDERED);
sah.roleID = TavernSlotRole::SURRENDERED;
if (playerEndedTurn(color))
sah.roleID = TavernSlotRole::SURRENDERED_TODAY;
else
sah.roleID = TavernSlotRole::SURRENDERED;
sah.slotID = selectSlotForRole(color, sah.roleID);
sah.player = color;
sah.hid = hero->subID;
sah.army.clear();
@ -79,8 +106,12 @@ void HeroPoolProcessor::onHeroSurrendered(const PlayerColor & color, const CGHer
void HeroPoolProcessor::onHeroEscaped(const PlayerColor & color, const CGHeroInstance * hero)
{
SetAvailableHero sah;
sah.slotID = selectSlotForRole(color, TavernSlotRole::RETREATED);
sah.roleID = TavernSlotRole::RETREATED;
if (playerEndedTurn(color))
sah.roleID = TavernSlotRole::RETREATED_TODAY;
else
sah.roleID = TavernSlotRole::RETREATED;
sah.slotID = selectSlotForRole(color, sah.roleID);
sah.player = color;
sah.hid = hero->subID;
@ -131,10 +162,26 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
void HeroPoolProcessor::onNewWeek(const PlayerColor & color)
{
clearHeroFromSlot(color, TavernHeroSlot::NATIVE);
clearHeroFromSlot(color, TavernHeroSlot::RANDOM);
selectNewHeroForSlot(color, TavernHeroSlot::NATIVE, true, true);
selectNewHeroForSlot(color, TavernHeroSlot::RANDOM, false, true);
const auto & hpool = gameHandler->gameState()->hpool;
const auto & heroes = hpool->getHeroesFor(color);
const auto nativeSlotRole = heroes.size() < 1 ? TavernSlotRole::NONE : hpool->getSlotRole(heroes[0]->type->getId());
const auto randomSlotRole = heroes.size() < 2 ? TavernSlotRole::NONE : hpool->getSlotRole(heroes[1]->type->getId());
bool resetNativeSlot = nativeSlotRole != TavernSlotRole::RETREATED_TODAY && nativeSlotRole != TavernSlotRole::SURRENDERED_TODAY;
bool resetRandomSlot = randomSlotRole != TavernSlotRole::RETREATED_TODAY && randomSlotRole != TavernSlotRole::SURRENDERED_TODAY;
if (resetNativeSlot)
clearHeroFromSlot(color, TavernHeroSlot::NATIVE);
if (resetRandomSlot)
clearHeroFromSlot(color, TavernHeroSlot::RANDOM);
if (resetNativeSlot)
selectNewHeroForSlot(color, TavernHeroSlot::NATIVE, true, true);
if (resetRandomSlot)
selectNewHeroForSlot(color, TavernHeroSlot::RANDOM, false, true);
}
bool HeroPoolProcessor::hireHero(const CGObjectInstance *obj, const HeroTypeID & heroToRecruit, const PlayerColor & player)

View File

@ -17,7 +17,6 @@ class PlayerColor;
class CGHeroInstance;
class HeroTypeID;
class CGObjectInstance;
class FactionID;
class CRandomGenerator;
class CHeroClass;
@ -43,6 +42,8 @@ class HeroPoolProcessor : boost::noncopyable
CRandomGenerator & getRandomGenerator(const PlayerColor & player);
TavernHeroSlot selectSlotForRole(const PlayerColor & player, TavernSlotRole roleID);
bool playerEndedTurn(const PlayerColor & player);
public:
CGameHandler * gameHandler;