1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-17 20:58:07 +02:00

Merge pull request #5383 from IvanSavenko/bugfixing

[1.6.6] Fixes for issues in 1.6.5
This commit is contained in:
Ivan Savenko 2025-02-09 19:27:43 +02:00 committed by GitHub
commit c13edc8af3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 184 additions and 27 deletions

View File

@ -533,7 +533,7 @@ void BattleFieldController::showHighlightedHexes(Canvas & canvas)
BattleHexArray hoveredMoveHexes = getHighlightedHexesForMovementTarget();
BattleHex hoveredHex = getHoveredHex();
BattleHexArray hoveredMouseHex = hoveredHex.isValid() ? BattleHexArray({ hoveredHex }) : BattleHexArray();
BattleHexArray hoveredMouseHex = hoveredHex.isAvailable() ? BattleHexArray({ hoveredHex }) : BattleHexArray();
const CStack * hoveredStack = getHoveredStack();
if(!hoveredStack && hoveredHex == BattleHex::INVALID)

View File

@ -691,7 +691,7 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
if (spellBonuses->empty())
throw std::runtime_error("Failed to find effects for spell " + effect.toSpell()->getJsonKey());
int duration = spellBonuses->front()->duration;
int duration = spellBonuses->front()->turnsRemain;
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SpellInt"), effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed));
if(settings["general"]["enableUiEnhancements"].Bool())

View File

@ -28,6 +28,7 @@
#include "../widgets/Images.h"
#include "../widgets/MiscWidgets.h"
#include "../widgets/ObjectLists.h"
#include "../widgets/Slider.h"
#include "../widgets/TextControls.h"
#include "../../lib/CConfigHandler.h"
@ -126,6 +127,15 @@ std::shared_ptr<CIntObject> GlobalLobbyWidget::buildItemList(const JsonNode & co
auto result = std::make_shared<CListBox>(callback, position, itemOffset, visibleAmount, totalAmount, initialPos, sliderMode, Rect(sliderPosition, sliderSize));
if (result->getSlider())
{
Point scrollBoundsDimensions(sliderPosition.x + result->getSlider()->pos.w, result->getSlider()->pos.h);
Point scrollBoundsOffset = -sliderPosition;
result->getSlider()->setScrollBounds(Rect(scrollBoundsOffset, scrollBoundsDimensions));
result->getSlider()->setPanningStep(itemOffset.length());
}
result->setRedrawParent(true);
return result;
}

View File

@ -247,7 +247,7 @@ AssetGenerator::CanvasPtr AssetGenerator::createCampaignBackground()
AssetGenerator::CanvasPtr AssetGenerator::createChroniclesCampaignImages(int chronicle)
{
auto imgPathBg = ImagePath::builtin("data/chronicles_" + std::to_string(chronicle) + "/GamSelBk");
auto imgPathBg = ImagePath::builtin("chronicles_" + std::to_string(chronicle) + "/GamSelBk");
auto locator = ImageLocator(imgPathBg, EImageBlitMode::OPAQUE);
std::shared_ptr<IImage> img = GH.renderHandler().loadImage(locator);

View File

@ -25,6 +25,11 @@ CanvasImage::CanvasImage(const Point & size, CanvasScalingPolicy scalingPolicy)
{
}
CanvasImage::~CanvasImage()
{
SDL_FreeSurface(surface);
}
void CanvasImage::draw(SDL_Surface * where, const Point & pos, const Rect * src, int scalingFactor) const
{
if(src)

View File

@ -16,6 +16,7 @@ class CanvasImage : public IImage
{
public:
CanvasImage(const Point & size, CanvasScalingPolicy scalingPolicy);
~CanvasImage();
Canvas getCanvas();

View File

@ -379,7 +379,7 @@ void RenderHandler::addImageListEntries(const EntityService * service)
if (imageName.empty())
return;
auto & layout = getAnimationLayout(AnimationPath::builtin("SPRITES/" + listName), 1, EImageBlitMode::SIMPLE);
auto & layout = getAnimationLayout(AnimationPath::builtin("SPRITES/" + listName), 1, EImageBlitMode::COLORKEY);
JsonNode entry;
entry["file"].String() = imageName;
@ -417,8 +417,8 @@ static void detectOverlappingBuildings(RenderHandler * renderHandler, const Fact
if (left->pos.z != right->pos.z)
continue; // buildings already have different z-index and have well-defined overlap logic
auto leftImage = renderHandler->loadImage(left->defName, 0, 0, EImageBlitMode::SIMPLE);
auto rightImage = renderHandler->loadImage(right->defName, 0, 0, EImageBlitMode::SIMPLE);
auto leftImage = renderHandler->loadImage(left->defName, 0, 0, EImageBlitMode::COLORKEY);
auto rightImage = renderHandler->loadImage(right->defName, 0, 0, EImageBlitMode::COLORKEY);
Rect leftRect( left->pos.x, left->pos.y, leftImage->width(), leftImage->height());
Rect rightRect( right->pos.x, right->pos.y, rightImage->width(), rightImage->height());

View File

@ -168,6 +168,11 @@ std::shared_ptr<CIntObject> CListBox::getItem(size_t which)
return std::shared_ptr<CIntObject>();
}
std::shared_ptr<CSlider> CListBox::getSlider()
{
return slider;
}
size_t CListBox::getIndexOf(std::shared_ptr<CIntObject> item)
{
size_t i=first;

View File

@ -91,6 +91,8 @@ public:
//return item with index which or null if not present
std::shared_ptr<CIntObject> getItem(size_t which);
std::shared_ptr<CSlider> getSlider();
//return currently active items
const std::list<std::shared_ptr<CIntObject>> & getItems();

View File

@ -238,7 +238,7 @@ CStackWindow::ActiveSpellsSection::ActiveSpellsSection(CStackWindow * owner, int
if (spellBonuses->empty())
throw std::runtime_error("Failed to find effects for spell " + effect.toSpell()->getJsonKey());
int duration = spellBonuses->front()->duration;
int duration = spellBonuses->front()->turnsRemain;
boost::replace_first(spellText, "%d", std::to_string(duration));
spellIcons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SpellInt"), effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed));

View File

@ -50,7 +50,7 @@
},
"chr":
{
"images" : [ {"x": 0, "y": 0, "name":"data/CampaignBackground8"} ],
"images" : [ {"x": 0, "y": 0, "name":"CampaignBackground8"} ],
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN" },
"items":
[

View File

@ -2370,5 +2370,120 @@
},
"victoryIconIndex" : 11,
"victoryString" : "core.vcdesc.0"
},
"data/gelu:1" : { // Cutthroats
"defeatIconIndex" : 1,
"defeatString" : "core.lcdesc.2",
"triggeredEvents" : {
"heroesMustSurvive" : {
"condition" : [
"allOf",
[ "isHuman", { "value" : 1 } ],
[ "noneOf",
[ "control", { "position" : [ 11, 8, 0 ], "type" : "hero" } ] // Gelu
]
],
"effect" : {
"messageToSend" : "core.genrltxt.5",
"type" : "defeat"
},
"message" : "core.genrltxt.253"
},
"specialVictory" : {
"condition" : [ "haveArtifact", { "type" : "artifact.ringOfVitality" } ],
"effect" : {
"messageToSend" : "core.genrltxt.281",
"type" : "victory"
},
"message" : "core.genrltxt.280"
},
"standardDefeat" : {
"condition" : [ "daysWithoutTown", { "value" : 7 } ],
"effect" : {
"messageToSend" : "core.genrltxt.8",
"type" : "defeat"
},
"message" : "core.genrltxt.7"
}
},
"victoryIconIndex" : 0,
"victoryString" : "core.vcdesc.1"
},
"data/gelu:2" : { // Valley of the Dragon Lords
"defeatIconIndex" : 1,
"defeatString" : "core.lcdesc.2",
"triggeredEvents" : {
"heroesMustSurvive" : {
"condition" : [
"allOf",
[ "isHuman", { "value" : 1 } ],
[ "noneOf",
[ "control", { "position" : [ 62, 12, 0 ], "type" : "hero" } ] // Gelu
]
],
"effect" : {
"messageToSend" : "core.genrltxt.5",
"type" : "defeat"
},
"message" : "core.genrltxt.253"
},
"specialVictory" : {
"condition" : [ "haveArtifact", { "type" : "artifact.ringOfLife" } ],
"effect" : {
"messageToSend" : "core.genrltxt.281",
"type" : "victory"
},
"message" : "core.genrltxt.280"
},
"standardDefeat" : {
"condition" : [ "daysWithoutTown", { "value" : 7 } ],
"effect" : {
"messageToSend" : "core.genrltxt.8",
"type" : "defeat"
},
"message" : "core.genrltxt.7"
}
},
"victoryIconIndex" : 0,
"victoryString" : "core.vcdesc.1"
},
"data/gelu:3" : { // A Thief in the Night
"defeatIconIndex" : 1,
"defeatString" : "core.lcdesc.2",
"triggeredEvents" : {
"heroesMustSurvive" : {
"condition" : [
"allOf",
[ "isHuman", { "value" : 1 } ],
[ "noneOf",
[ "control", { "position" : [ 50, 9, 0 ], "type" : "hero" } ] // Gelu
]
],
"effect" : {
"messageToSend" : "core.genrltxt.5",
"type" : "defeat"
},
"message" : "core.genrltxt.253"
},
"specialVictory" : {
"condition" : [ "haveArtifact", { "type" : "artifact.vialOfLifeblood" } ],
"effect" : {
"messageToSend" : "core.genrltxt.281",
"type" : "victory"
},
"message" : "core.genrltxt.280"
},
"standardDefeat" : {
"condition" : [ "daysWithoutTown", { "value" : 7 } ],
"effect" : {
"messageToSend" : "core.genrltxt.8",
"type" : "defeat"
},
"message" : "core.genrltxt.7"
}
},
"victoryIconIndex" : 0,
"victoryString" : "core.vcdesc.1"
}
}

View File

@ -188,6 +188,7 @@ std::shared_ptr<Bonus> CBonusSystemNode::getUpdatedBonus(const std::shared_ptr<B
CBonusSystemNode::CBonusSystemNode(bool isHypotetic):
nodeType(UNKNOWN),
cachedLast(0),
nodeChanged(0),
isHypotheticNode(isHypotetic)
{
}
@ -195,6 +196,7 @@ CBonusSystemNode::CBonusSystemNode(bool isHypotetic):
CBonusSystemNode::CBonusSystemNode(ENodeTypes NodeType):
nodeType(NodeType),
cachedLast(0),
nodeChanged(0),
isHypotheticNode(false)
{
}

View File

@ -183,14 +183,9 @@ void CResourceHandler::initialize()
knownLoaders["saves"] = new CFilesystemLoader("SAVES/", VCMIDirs::get().userSavePath());
knownLoaders["config"] = new CFilesystemLoader("CONFIG/", VCMIDirs::get().userConfigPath());
knownLoaders["gen_data"] = new CFilesystemLoader("DATA/", VCMIDirs::get().userDataPath() / "Generated" / "Data");
knownLoaders["gen_sprites"] = new CFilesystemLoader("SPRITES/", VCMIDirs::get().userDataPath() / "Generated" / "Sprites");
auto * localFS = new CFilesystemList();
localFS->addLoader(knownLoaders["saves"], true);
localFS->addLoader(knownLoaders["config"], true);
localFS->addLoader(knownLoaders["gen_data"], true);
localFS->addLoader(knownLoaders["gen_sprites"], true);
addFilesystem("root", "initial", createInitial());
addFilesystem("root", "data", new CFilesystemList());

View File

@ -117,8 +117,17 @@ void CMapHeader::setupEvents()
defeatMessage.appendTextID("core.lcdesc.0");
}
CMapHeader::CMapHeader() : version(EMapFormat::VCMI), height(72), width(72),
twoLevel(true), difficulty(EMapDifficulty::NORMAL), levelLimit(0), howManyTeams(0), areAnyPlayers(false)
CMapHeader::CMapHeader()
: version(EMapFormat::VCMI)
, height(72)
, width(72)
, twoLevel(true)
, difficulty(EMapDifficulty::NORMAL)
, levelLimit(0)
, howManyTeams(0)
, areAnyPlayers(false)
, victoryIconIndex(0)
, defeatIconIndex(0)
{
setupEvents();
allowedHeroes = VLC->heroh->getDefaultAllowed();

View File

@ -216,22 +216,25 @@ InternalConnection::InternalConnection(INetworkConnectionListener & listener, co
void InternalConnection::receivePacket(const std::vector<std::byte> & message)
{
io->post([self = shared_from_this(), message](){
io->post([self = std::static_pointer_cast<InternalConnection>(shared_from_this()), message](){
if (self->connectionActive)
self->listener.onPacketReceived(self, message);
});
}
void InternalConnection::disconnect()
{
io->post([self = shared_from_this()](){
io->post([self = std::static_pointer_cast<InternalConnection>(shared_from_this())](){
self->listener.onDisconnected(self, "Internal connection has been terminated");
self->otherSideWeak.reset();
self->connectionActive = false;
});
}
void InternalConnection::connectTo(std::shared_ptr<IInternalConnection> connection)
{
otherSideWeak = connection;
connectionActive = true;
}
void InternalConnection::sendPacket(const std::vector<std::byte> & message)
@ -240,8 +243,6 @@ void InternalConnection::sendPacket(const std::vector<std::byte> & message)
if (otherSide)
otherSide->receivePacket(message);
else
throw std::runtime_error("Failed to send packet! Connection has been deleted!");
}
void InternalConnection::setAsyncWritesEnabled(bool on)
@ -257,6 +258,7 @@ void InternalConnection::close()
otherSide->disconnect();
otherSideWeak.reset();
connectionActive = false;
}
VCMI_LIB_NAMESPACE_END

View File

@ -51,6 +51,7 @@ class InternalConnection final : public IInternalConnection, public std::enable_
std::weak_ptr<IInternalConnection> otherSideWeak;
std::shared_ptr<NetworkContext> io;
INetworkConnectionListener & listener;
bool connectionActive = false;
public:
InternalConnection(INetworkConnectionListener & listener, const std::shared_ptr<NetworkContext> & context);

View File

@ -40,15 +40,23 @@ namespace PathfinderUtil
}
else
{
bool hasBlockedVisitable = false;
bool hasVisitable = false;
for(const CGObjectInstance * obj : tinfo.visitableObjects)
{
if(obj->isBlockedVisitable())
return EPathAccessibility::BLOCKVIS;
else if(obj->passableFor(player))
return EPathAccessibility::ACCESSIBLE;
else if(obj->ID != Obj::EVENT)
return EPathAccessibility::VISITABLE;
hasBlockedVisitable = true;
else if(!obj->passableFor(player) && obj->ID != Obj::EVENT)
hasVisitable = true;
}
if(hasBlockedVisitable)
return EPathAccessibility::BLOCKVIS;
if(hasVisitable)
return EPathAccessibility::VISITABLE;
return EPathAccessibility::ACCESSIBLE;
}
}
else if(tinfo.blocked())

View File

@ -102,7 +102,8 @@ std::unique_ptr<CPack> CConnection::retrievePack(const std::vector<std::byte> &
if (packReader->position != data.size())
throw std::runtime_error("Failed to retrieve pack! Not all data has been read!");
logNetwork->trace("Received CPack of type %s", typeid(result.get()).name());
auto packRawPtr = result.get();
logNetwork->trace("Received CPack of type %s", typeid(*packRawPtr).name());
deserializer->loadedPointers.clear();
deserializer->loadedSharedPointers.clear();
return result;

View File

@ -249,6 +249,8 @@ void TurnOrderProcessor::doStartNewDay()
assert(awaitingPlayers.empty());
assert(actingPlayers.empty());
gameHandler->onNewTurn();
bool activePlayer = false;
for (auto player : actedPlayers)
{
@ -264,7 +266,6 @@ void TurnOrderProcessor::doStartNewDay()
std::swap(actedPlayers, awaitingPlayers);
gameHandler->onNewTurn();
updateAndNotifyContactStatus();
tryStartTurnsForPlayers();
}