1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Implemented foreground/background obstacles:

- obstacles now have "foreground" field
- if "foreground" field set, obstacle will appear on top of other
objects, such as units
- if "foreground" is not set, obstacle will appear below units
- updated schema and cleared up obstacles config
This commit is contained in:
Ivan Savenko 2023-06-06 15:53:14 +03:00
parent ee8c8dca7b
commit 428fb832c6
7 changed files with 62 additions and 208 deletions

View File

@ -148,7 +148,11 @@ void BattleObstacleController::collectRenderableObjects(BattleRenderer & rendere
if (obstacle->obstacleType == CObstacleInstance::MOAT) if (obstacle->obstacleType == CObstacleInstance::MOAT)
continue; continue;
renderer.insert(EBattleFieldLayer::OBSTACLES, obstacle->pos, [this, obstacle]( BattleRenderer::RendererRef canvas ){ bool isForeground = obstacle->obstacleType == CObstacleInstance::USUAL && obstacle->getInfo().isForegroundObstacle;
auto layer = isForeground ? EBattleFieldLayer::OBSTACLES_FG : EBattleFieldLayer::OBSTACLES_BG;
renderer.insert(layer, obstacle->pos, [this, obstacle]( BattleRenderer::RendererRef canvas ){
auto img = getObstacleImage(*obstacle); auto img = getObstacleImage(*obstacle);
if(img) if(img)
{ {

View File

@ -16,12 +16,12 @@ class BattleInterface;
enum class EBattleFieldLayer { enum class EBattleFieldLayer {
// confirmed ordering requirements: // confirmed ordering requirements:
OBSTACLES = 0, OBSTACLES_BG = 0,
CORPSES = 0, CORPSES = 0,
WALLS = 1, WALLS = 1,
HEROES = 2, HEROES = 2,
STACKS = 2, // after corpses, obstacles, walls STACKS = 2, // after corpses, obstacles, walls
BATTLEMENTS = 3, // after stacks OBSTACLES_FG = 3, // after stacks
STACK_AMOUNTS = 3, // after stacks, obstacles, corpses STACK_AMOUNTS = 3, // after stacks, obstacles, corpses
EFFECTS = 4, // after obstacles, battlements EFFECTS = 4, // after obstacles, battlements
}; };

View File

@ -307,7 +307,7 @@ void BattleSiegeController::collectRenderableObjects(BattleRenderer & renderer)
renderer.insert( EBattleFieldLayer::STACKS, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererRef canvas){ renderer.insert( EBattleFieldLayer::STACKS, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererRef canvas){
owner.stacksController->showStack(canvas, getTurretStack(wallPiece)); owner.stacksController->showStack(canvas, getTurretStack(wallPiece));
}); });
renderer.insert( EBattleFieldLayer::BATTLEMENTS, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererRef canvas){ renderer.insert( EBattleFieldLayer::OBSTACLES_FG, getWallPiecePosition(wallPiece), [this, wallPiece](BattleRenderer::RendererRef canvas){
showWallPiece(canvas, wallPiece); showWallPiece(canvas, wallPiece);
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,15 @@
"$schema" : "http://json-schema.org/draft-04/schema", "$schema" : "http://json-schema.org/draft-04/schema",
"title" : "VCMI obstacle format", "title" : "VCMI obstacle format",
"description" : "Format used to define new obstacles in VCMI", "description" : "Format used to define new obstacles in VCMI",
"required" : [ "animation" ], "required" : [ "animation", "width", "height", "blockedTiles" ],
"anyOf" : [
{
"required" : [ "allowedTerrains" ]
},
{
"required" : [ "specialBattlefields" ]
}
],
"additionalProperties" : false, "additionalProperties" : false,
"properties" : { "properties" : {
"allowedTerrains" : { "allowedTerrains" : {
@ -41,9 +49,9 @@
{ "format" : "imageFile" } { "format" : "imageFile" }
] ]
}, },
"unknown" : { "foreground" : {
"type" : "number", "type" : "boolean",
"description" : "Unknown field" "description" : "If set to true, obstacle will appear in front of units or other battlefield objects"
} }
} }
} }

View File

@ -103,6 +103,7 @@ ObstacleInfo * ObstacleHandler::loadFromJson(const std::string & scope, const Js
info->allowedSpecialBfields.emplace_back(t.String()); info->allowedSpecialBfields.emplace_back(t.String());
info->blockedTiles = json["blockedTiles"].convertTo<std::vector<si16>>(); info->blockedTiles = json["blockedTiles"].convertTo<std::vector<si16>>();
info->isAbsoluteObstacle = json["absolute"].Bool(); info->isAbsoluteObstacle = json["absolute"].Bool();
info->isForegroundObstacle = json["foreground"].Bool();
objects.emplace_back(info); objects.emplace_back(info);

View File

@ -20,11 +20,11 @@ VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE ObstacleInfo : public EntityT<Obstacle> class DLL_LINKAGE ObstacleInfo : public EntityT<Obstacle>
{ {
public: public:
ObstacleInfo(): obstacle(-1), width(0), height(0), isAbsoluteObstacle(false), iconIndex(0) ObstacleInfo(): obstacle(-1), width(0), height(0), isAbsoluteObstacle(false), iconIndex(0), isForegroundObstacle(false)
{} {}
ObstacleInfo(Obstacle obstacle, std::string identifier) ObstacleInfo(Obstacle obstacle, std::string identifier)
: obstacle(obstacle), identifier(identifier), iconIndex(obstacle.getNum()), width(0), height(0), isAbsoluteObstacle(false) : obstacle(obstacle), identifier(identifier), iconIndex(obstacle.getNum()), width(0), height(0), isAbsoluteObstacle(false), isForegroundObstacle(false)
{ {
} }
@ -35,10 +35,8 @@ public:
std::vector<TerrainId> allowedTerrains; std::vector<TerrainId> allowedTerrains;
std::vector<std::string> allowedSpecialBfields; std::vector<std::string> allowedSpecialBfields;
//TODO: here is extra field to implement it's logic in the future but save backward compatibility bool isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
int obstacleType = -1; bool isForegroundObstacle;
ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm) si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm)
std::vector<si16> blockedTiles; //offsets relative to obstacle position (that is its left bottom corner) std::vector<si16> blockedTiles; //offsets relative to obstacle position (that is its left bottom corner)
@ -57,7 +55,6 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & obstacle; h & obstacle;
h & obstacleType;
h & iconIndex; h & iconIndex;
h & identifier; h & identifier;
h & animation; h & animation;
@ -66,6 +63,7 @@ public:
h & allowedTerrains; h & allowedTerrains;
h & allowedSpecialBfields; h & allowedSpecialBfields;
h & isAbsoluteObstacle; h & isAbsoluteObstacle;
h & isForegroundObstacle;
h & width; h & width;
h & height; h & height;
h & blockedTiles; h & blockedTiles;