1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Merge pull request #4363 from IvanSavenko/fixes_156

Fixes for 1.5.6 release
This commit is contained in:
Ivan Savenko 2024-08-02 21:23:27 +03:00 committed by GitHub
commit 7bcd6b1b0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 65 additions and 16 deletions

View File

@ -19,6 +19,7 @@
#include "../eventsSDL/InputHandler.h"
#include "../CGameInfo.h"
#include "../adventureMap/AdventureMapInterface.h"
#include "../render/Colors.h"
#include "../render/Graphics.h"
#include "../render/IFont.h"
@ -145,7 +146,13 @@ CGuiHandler::CGuiHandler()
{
}
CGuiHandler::~CGuiHandler() = default;
CGuiHandler::~CGuiHandler()
{
// enforce deletion order on shutdown
// all UI elements including adventure map must be destroyed before Gui Handler
// proper solution would be removal of adventureInt global
adventureInt.reset();
}
ShortcutHandler & CGuiHandler::shortcuts()
{

View File

@ -130,13 +130,15 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
if(!art)
return false;
bool takeable = travelOptions.artifactsKeptByHero.count(art->artType->getId());
ArtifactLocation al(hero.hero->id, artifactPosition);
if (takeable)
bool takeable = travelOptions.artifactsKeptByHero.count(art->artType->getId());
bool locked = hero.hero->getSlot(al.slot)->locked;
if (!locked && takeable)
hero.transferrableArtifacts.push_back(artifactPosition);
ArtifactLocation al(hero.hero->id, artifactPosition);
if(!takeable && !hero.hero->getSlot(al.slot)->locked) //don't try removing locked artifacts -> it crashes #1719
if (!locked && !takeable)
{
hero.hero->getArt(al.slot)->removeFrom(*hero.hero, al.slot);
return true;

View File

@ -346,15 +346,19 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const
std::vector<Component> CGDwelling::getPopupComponents(PlayerColor player) const
{
if (getOwner() != player)
return {};
bool visitedByOwner = getOwner() == player;
std::vector<Component> result;
if (ID == Obj::CREATURE_GENERATOR1 && !creatures.empty())
{
for (auto const & creature : creatures.front().second)
{
if (visitedByOwner)
result.emplace_back(ComponentType::CREATURE, creature, creatures.front().first);
else
result.emplace_back(ComponentType::CREATURE, creature);
}
}
if (ID == Obj::CREATURE_GENERATOR4)
@ -362,7 +366,12 @@ std::vector<Component> CGDwelling::getPopupComponents(PlayerColor player) const
for (auto const & creatureLevel : creatures)
{
if (!creatureLevel.second.empty())
{
if (visitedByOwner)
result.emplace_back(ComponentType::CREATURE, creatureLevel.second.back(), creatureLevel.first);
else
result.emplace_back(ComponentType::CREATURE, creatureLevel.second.back());
}
}
}
return result;

View File

@ -1709,6 +1709,16 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
setHeroTypeName(typeName);
}
if(!handler.saving)
{
if(!appearance)
{
// crossoverDeserialize
type = getHeroType().toHeroType();
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
}
}
CArmedInstance::serializeJsonOptions(handler);
{
@ -1724,13 +1734,6 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
if(!handler.saving)
{
if(!appearance)
{
// crossoverDeserialize
type = getHeroType().toHeroType();
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
}
patrol.patrolling = (rawPatrolRadius > NO_PATROLING);
patrol.initialPos = visitablePos();
patrol.patrolRadius = (rawPatrolRadius > NO_PATROLING) ? rawPatrolRadius : 0;

View File

@ -181,7 +181,26 @@ void CRewardableObject::heroLevelUpDone(const CGHeroInstance *hero) const
void CRewardableObject::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
{
if(answer == 0)
{
switch (configuration.visitMode)
{
case Rewardable::VISIT_UNLIMITED:
case Rewardable::VISIT_BONUS:
case Rewardable::VISIT_HERO:
case Rewardable::VISIT_LIMITER:
{
// workaround for object with refusable reward not getting marked as visited
// TODO: better solution that would also work for player-visitable objects
if (!wasScouted(hero->getOwner()))
{
ChangeObjectVisitors cov(ChangeObjectVisitors::VISITOR_ADD_TEAM, id, hero->id);
cb->sendAndApply(&cov);
}
}
}
return; // player refused
}
if(answer > 0 && answer-1 < configuration.info.size())
{

View File

@ -682,6 +682,15 @@ void CGameHandler::onNewTurn()
}
}
for (auto & player : gs->players)
{
if (player.second.status != EPlayerStatus::INGAME)
continue;
if (player.second.heroes.empty() && player.second.towns.empty())
throw std::runtime_error("Invalid player in player state! Player " + std::to_string(player.first.getNum()) + ", map name: " + gs->map->name.toString() + ", map description: " + gs->map->description.toString());
}
if (newWeek && !firstTurn)
{
n.specialWeek = NewTurn::NORMAL;