NewTurnProcessor.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * NewTurnProcessor.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "NewTurnProcessor.h"
  12. #include "HeroPoolProcessor.h"
  13. #include "../CGameHandler.h"
  14. #include "../../lib/CPlayerState.h"
  15. #include "../../lib/GameSettings.h"
  16. #include "../../lib/StartInfo.h"
  17. #include "../../lib/TerrainHandler.h"
  18. #include "../../lib/entities/building/CBuilding.h"
  19. #include "../../lib/entities/faction/CTownHandler.h"
  20. #include "../../lib/gameState/CGameState.h"
  21. #include "../../lib/mapObjects/CGHeroInstance.h"
  22. #include "../../lib/mapObjects/CGTownInstance.h"
  23. #include "../../lib/mapping/CMap.h"
  24. #include "../../lib/networkPacks/PacksForClient.h"
  25. #include "../../lib/pathfinder/TurnInfo.h"
  26. #include <vstd/RNG.h>
  27. NewTurnProcessor::NewTurnProcessor(CGameHandler * gameHandler)
  28. :gameHandler(gameHandler)
  29. {
  30. }
  31. void NewTurnProcessor::onPlayerTurnStarted(PlayerColor which)
  32. {
  33. const auto * playerState = gameHandler->gameState()->getPlayerState(which);
  34. gameHandler->handleTimeEvents(which);
  35. for (auto t : playerState->towns)
  36. gameHandler->handleTownEvents(t);
  37. for (auto t : playerState->towns)
  38. {
  39. //garrison hero first - consistent with original H3 Mana Vortex and Battle Scholar Academy levelup windows order
  40. if (t->garrisonHero != nullptr)
  41. gameHandler->objectVisited(t, t->garrisonHero);
  42. if (t->visitingHero != nullptr)
  43. gameHandler->objectVisited(t, t->visitingHero);
  44. }
  45. }
  46. void NewTurnProcessor::onPlayerTurnEnded(PlayerColor which)
  47. {
  48. const auto * playerState = gameHandler->gameState()->getPlayerState(which);
  49. assert(playerState->status == EPlayerStatus::INGAME);
  50. if (playerState->towns.empty())
  51. {
  52. DaysWithoutTown pack;
  53. pack.player = which;
  54. pack.daysWithoutCastle = playerState->daysWithoutCastle.value_or(0) + 1;
  55. gameHandler->sendAndApply(&pack);
  56. }
  57. else
  58. {
  59. if (playerState->daysWithoutCastle.has_value())
  60. {
  61. DaysWithoutTown pack;
  62. pack.player = which;
  63. pack.daysWithoutCastle = std::nullopt;
  64. gameHandler->sendAndApply(&pack);
  65. }
  66. }
  67. // check for 7 days without castle
  68. gameHandler->checkVictoryLossConditionsForPlayer(which);
  69. bool newWeek = gameHandler->getDate(Date::DAY_OF_WEEK) == 7; // end of 7th day
  70. if (newWeek) //new heroes in tavern
  71. gameHandler->heroPool->onNewWeek(which);
  72. }
  73. ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool newWeek)
  74. {
  75. const auto & playerSettings = gameHandler->gameState()->scenarioOps->getIthPlayersSettings(playerID);
  76. const PlayerState & state = gameHandler->gameState()->players.at(playerID);
  77. ResourceSet income;
  78. for (const auto & hero : state.heroes)
  79. {
  80. for (GameResID k : GameResID::ALL_RESOURCES())
  81. income[k] += hero->valOfBonuses(BonusType::GENERATE_RESOURCE, BonusSubtypeID(k));
  82. }
  83. for (const auto & town : state.towns)
  84. {
  85. income += town->dailyIncome();
  86. if (newWeek && town->hasBuilt(BuildingSubID::TREASURY))
  87. {
  88. //give 10% of starting gold
  89. income[EGameResID::GOLD] += state.resources[EGameResID::GOLD] / 10;
  90. }
  91. //give resources if there's a Mystic Pond
  92. if (newWeek && town->hasBuilt(BuildingSubID::MYSTIC_POND))
  93. {
  94. static constexpr std::array rareResources = {
  95. GameResID::MERCURY,
  96. GameResID::SULFUR,
  97. GameResID::CRYSTAL,
  98. GameResID::GEMS
  99. };
  100. auto resID = *RandomGeneratorUtil::nextItem(rareResources, gameHandler->getRandomGenerator());
  101. int resVal = gameHandler->getRandomGenerator().nextInt(1, 4);
  102. income[resID] += resVal;
  103. gameHandler->setObjPropertyValue(town->id, ObjProperty::BONUS_VALUE_FIRST, resID);
  104. gameHandler->setObjPropertyValue(town->id, ObjProperty::BONUS_VALUE_SECOND, resVal);
  105. }
  106. }
  107. for (GameResID k = GameResID::WOOD; k < GameResID::COUNT; k++)
  108. {
  109. income += state.valOfBonuses(BonusType::RESOURCES_CONSTANT_BOOST, BonusSubtypeID(k));
  110. income += state.valOfBonuses(BonusType::RESOURCES_TOWN_MULTIPLYING_BOOST, BonusSubtypeID(k)) * state.towns.size();
  111. }
  112. if(newWeek) //weekly crystal generation if 1 or more crystal dragons in any hero army or town garrison
  113. {
  114. bool hasCrystalGenCreature = false;
  115. for (const auto & hero : state.heroes)
  116. for(auto stack : hero->stacks)
  117. if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
  118. hasCrystalGenCreature = true;
  119. for(const auto & town : state.towns)
  120. for(auto stack : town->stacks)
  121. if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
  122. hasCrystalGenCreature = true;
  123. if(hasCrystalGenCreature)
  124. income[EGameResID::CRYSTAL] += 3;
  125. }
  126. TResources incomeHandicapped = income * playerSettings.handicap.percentIncome / 100;
  127. return incomeHandicapped;
  128. }