| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- /*
- * NewTurnProcessor.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "NewTurnProcessor.h"
- #include "HeroPoolProcessor.h"
- #include "../CGameHandler.h"
- #include "../../lib/CPlayerState.h"
- #include "../../lib/GameSettings.h"
- #include "../../lib/StartInfo.h"
- #include "../../lib/TerrainHandler.h"
- #include "../../lib/entities/building/CBuilding.h"
- #include "../../lib/entities/faction/CTownHandler.h"
- #include "../../lib/gameState/CGameState.h"
- #include "../../lib/mapObjects/CGHeroInstance.h"
- #include "../../lib/mapObjects/CGTownInstance.h"
- #include "../../lib/mapping/CMap.h"
- #include "../../lib/networkPacks/PacksForClient.h"
- #include "../../lib/pathfinder/TurnInfo.h"
- #include <vstd/RNG.h>
- NewTurnProcessor::NewTurnProcessor(CGameHandler * gameHandler)
- :gameHandler(gameHandler)
- {
- }
- void NewTurnProcessor::onPlayerTurnStarted(PlayerColor which)
- {
- const auto * playerState = gameHandler->gameState()->getPlayerState(which);
- gameHandler->handleTimeEvents(which);
- for (auto t : playerState->towns)
- gameHandler->handleTownEvents(t);
- for (auto t : playerState->towns)
- {
- //garrison hero first - consistent with original H3 Mana Vortex and Battle Scholar Academy levelup windows order
- if (t->garrisonHero != nullptr)
- gameHandler->objectVisited(t, t->garrisonHero);
- if (t->visitingHero != nullptr)
- gameHandler->objectVisited(t, t->visitingHero);
- }
- }
- void NewTurnProcessor::onPlayerTurnEnded(PlayerColor which)
- {
- const auto * playerState = gameHandler->gameState()->getPlayerState(which);
- assert(playerState->status == EPlayerStatus::INGAME);
- if (playerState->towns.empty())
- {
- DaysWithoutTown pack;
- pack.player = which;
- pack.daysWithoutCastle = playerState->daysWithoutCastle.value_or(0) + 1;
- gameHandler->sendAndApply(&pack);
- }
- else
- {
- if (playerState->daysWithoutCastle.has_value())
- {
- DaysWithoutTown pack;
- pack.player = which;
- pack.daysWithoutCastle = std::nullopt;
- gameHandler->sendAndApply(&pack);
- }
- }
- // check for 7 days without castle
- gameHandler->checkVictoryLossConditionsForPlayer(which);
- bool newWeek = gameHandler->getDate(Date::DAY_OF_WEEK) == 7; // end of 7th day
- if (newWeek) //new heroes in tavern
- gameHandler->heroPool->onNewWeek(which);
- }
- ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool newWeek)
- {
- const auto & playerSettings = gameHandler->gameState()->scenarioOps->getIthPlayersSettings(playerID);
- const PlayerState & state = gameHandler->gameState()->players.at(playerID);
- ResourceSet income;
- for (const auto & hero : state.heroes)
- {
- for (GameResID k : GameResID::ALL_RESOURCES())
- income[k] += hero->valOfBonuses(BonusType::GENERATE_RESOURCE, BonusSubtypeID(k));
- }
- for (const auto & town : state.towns)
- {
- income += town->dailyIncome();
- if (newWeek && town->hasBuilt(BuildingSubID::TREASURY))
- {
- //give 10% of starting gold
- income[EGameResID::GOLD] += state.resources[EGameResID::GOLD] / 10;
- }
- //give resources if there's a Mystic Pond
- if (newWeek && town->hasBuilt(BuildingSubID::MYSTIC_POND))
- {
- static constexpr std::array rareResources = {
- GameResID::MERCURY,
- GameResID::SULFUR,
- GameResID::CRYSTAL,
- GameResID::GEMS
- };
- auto resID = *RandomGeneratorUtil::nextItem(rareResources, gameHandler->getRandomGenerator());
- int resVal = gameHandler->getRandomGenerator().nextInt(1, 4);
- income[resID] += resVal;
- gameHandler->setObjPropertyValue(town->id, ObjProperty::BONUS_VALUE_FIRST, resID);
- gameHandler->setObjPropertyValue(town->id, ObjProperty::BONUS_VALUE_SECOND, resVal);
- }
- }
- for (GameResID k = GameResID::WOOD; k < GameResID::COUNT; k++)
- {
- income += state.valOfBonuses(BonusType::RESOURCES_CONSTANT_BOOST, BonusSubtypeID(k));
- income += state.valOfBonuses(BonusType::RESOURCES_TOWN_MULTIPLYING_BOOST, BonusSubtypeID(k)) * state.towns.size();
- }
- if(newWeek) //weekly crystal generation if 1 or more crystal dragons in any hero army or town garrison
- {
- bool hasCrystalGenCreature = false;
- for (const auto & hero : state.heroes)
- for(auto stack : hero->stacks)
- if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
- hasCrystalGenCreature = true;
- for(const auto & town : state.towns)
- for(auto stack : town->stacks)
- if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
- hasCrystalGenCreature = true;
- if(hasCrystalGenCreature)
- income[EGameResID::CRYSTAL] += 3;
- }
- TResources incomeHandicapped = income * playerSettings.handicap.percentIncome / 100;
- return incomeHandicapped;
- }
|