1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-29 23:07:48 +02:00

Fixes for handling of oversized map dwellings

- Marked large version of H3 Unicorn's Glade as not usable for random
dwelling replacement
- Shifted oversized dwellings - that have at most 2x2 as blocked tile,
but have non-blocked tile column will now be placed correctly
- This fixes incorrect random dwelling replacement of the only oversized
H3 dwelling - Portal of Glory
- Game will now detect & report invalid dwelling templates from mods
- Updated docs to clarify dwellings format
This commit is contained in:
Ivan Savenko
2025-05-12 17:50:36 +03:00
parent 29207c0b0f
commit cb70cc48d6
9 changed files with 102 additions and 3 deletions

View File

@@ -175,6 +175,7 @@ void AObjectTypeHandler::clearTemplates()
void AObjectTypeHandler::addTemplate(const std::shared_ptr<const ObjectTemplate> & templ)
{
templates.push_back(templ);
onTemplateAdded(templ);
}
void AObjectTypeHandler::addTemplate(JsonNode config)

View File

@@ -57,6 +57,8 @@ protected:
/// initialization for classes that inherit this one
virtual void initTypeData(const JsonNode & input);
virtual void onTemplateAdded(const std::shared_ptr<const ObjectTemplate>) {}
public:
AObjectTypeHandler();

View File

@@ -15,7 +15,9 @@
#include "../json/JsonRandom.h"
#include "../GameLibrary.h"
#include "../mapObjects/CGDwelling.h"
#include "../mapObjects/ObjectTemplate.h"
#include "../modding/IdentifierStorage.h"
#include "../CConfigHandler.h"
VCMI_LIB_NAMESPACE_BEGIN
@@ -52,6 +54,30 @@ void DwellingInstanceConstructor::initTypeData(const JsonNode & input)
}
guards = input["guards"];
bannedForRandomDwelling = input["bannedForRandomDwelling"].Bool();
for (const auto & mapTemplate : getTemplates())
onTemplateAdded(mapTemplate);
}
void DwellingInstanceConstructor::onTemplateAdded(const std::shared_ptr<const ObjectTemplate> mapTemplate)
{
if (bannedForRandomDwelling || settings["mods"]["validation"].String() == "off")
return;
bool invalidForRandomDwelling = false;
int3 corner = mapTemplate->getCornerOffset();
for (const auto & tile : mapTemplate->getBlockedOffsets())
invalidForRandomDwelling |= (tile.x != -corner.x && tile.x != -corner.x-1) || (tile.y != -corner.y && tile.y != -corner.y-1);
for (const auto & tile : {mapTemplate->getVisitableOffset()})
invalidForRandomDwelling |= (tile.x != corner.x && tile.x != corner.x+1) || tile.y != corner.y;
invalidForRandomDwelling |= !mapTemplate->isBlockedAt(corner.x+0, corner.y) && !mapTemplate->isVisibleAt(corner.x+0, corner.y);
invalidForRandomDwelling |= !mapTemplate->isBlockedAt(corner.x+1, corner.y) && !mapTemplate->isVisibleAt(corner.x+1, corner.y);
if (invalidForRandomDwelling)
logMod->warn("Dwelling %s has template %s which is not valid for a random dwelling! Dwellings must not block tiles outside 2x2 range and must be visitable in bottom row. Change dwelling mask or mark dwelling as 'bannedForRandomDwelling'", getJsonKey(), mapTemplate->animationFile.getOriginalName());
}
bool DwellingInstanceConstructor::isBannedForRandomDwelling() const
@@ -152,5 +178,4 @@ std::vector<const CCreature *> DwellingInstanceConstructor::getProducedCreatures
return creatures;
}
VCMI_LIB_NAMESPACE_END

View File

@@ -28,6 +28,7 @@ class DwellingInstanceConstructor : public CDefaultObjectTypeHandler<CGDwelling>
protected:
bool objectFilter(const CGObjectInstance * obj, std::shared_ptr<const ObjectTemplate> tmpl) const override;
void initTypeData(const JsonNode & input) override;
void onTemplateAdded(const std::shared_ptr<const ObjectTemplate>) override;
public:
bool hasNameTextID() const override;