| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- * 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/mapObjects/IOwnableObject.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 (const auto * t : playerState->getTowns())
- gameHandler->handleTownEvents(t);
- for (const auto * t : playerState->getTowns())
- {
- //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->getTowns().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->getPlayerSettings(playerID);
- const PlayerState & state = gameHandler->gameState()->players.at(playerID);
- ResourceSet income;
- for (const auto & town : state.getTowns())
- {
- 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.getTowns().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.getHeroes())
- for(auto stack : hero->stacks)
- if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
- hasCrystalGenCreature = true;
- for(const auto & town : state.getTowns())
- for(auto stack : town->stacks)
- if(stack.second->hasBonusOfType(BonusType::SPECIAL_CRYSTAL_GENERATION))
- hasCrystalGenCreature = true;
- if(hasCrystalGenCreature)
- income[EGameResID::CRYSTAL] += 3;
- }
- TResources incomeHandicapped = income;
- incomeHandicapped.applyHandicap(playerSettings->handicap.percentIncome);
- for (auto obj : state.getOwnedObjects())
- incomeHandicapped += obj->asOwnable()->dailyIncome();
- return incomeHandicapped;
- }
- SetAvailableCreatures NewTurnProcessor::generateTownGrowth(const CGTownInstance * t, EWeekType weekType, CreatureID creatureWeek, bool firstDay)
- {
- SetAvailableCreatures sac;
- PlayerColor player = t->tempOwner;
- sac.tid = t->id;
- sac.creatures = t->creatures;
- for (int k=0; k < t->town->creatures.size(); k++)
- {
- if (t->creatures.at(k).second.empty())
- continue;
- uint32_t creaturesBefore = t->creatures.at(k).first;
- uint32_t creatureGrowth = 0;
- const CCreature *cre = t->creatures.at(k).second.back().toCreature();
- if (firstDay)
- {
- creatureGrowth = cre->getGrowth();
- }
- else
- {
- creatureGrowth = t->creatureGrowth(k);
- //Deity of fire week - upgrade both imps and upgrades
- if (weekType == EWeekType::DEITYOFFIRE && vstd::contains(t->creatures.at(k).second, creatureWeek))
- creatureGrowth += 15;
- //bonus week, effect applies only to identical creatures
- if (weekType == EWeekType::BONUS_GROWTH && cre->getId() == creatureWeek)
- creatureGrowth += 5;
- }
- // Neutral towns have halved creature growth
- if (!player.isValidPlayer())
- creatureGrowth /= 2;
- uint32_t resultingCreatures = 0;
- if (weekType == EWeekType::PLAGUE)
- resultingCreatures = creaturesBefore / 2;
- else if (weekType == EWeekType::DOUBLE_GROWTH)
- resultingCreatures = (creaturesBefore + creatureGrowth) * 2;
- else
- resultingCreatures = creaturesBefore + creatureGrowth;
- sac.creatures.at(k).first = resultingCreatures;
- }
- return sac;
- }
|