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:
commit
c13edc8af3
@ -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)
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -16,6 +16,7 @@ class CanvasImage : public IImage
|
||||
{
|
||||
public:
|
||||
CanvasImage(const Point & size, CanvasScalingPolicy scalingPolicy);
|
||||
~CanvasImage();
|
||||
|
||||
Canvas getCanvas();
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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":
|
||||
[
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user