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)
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);
if(img)
{

View File

@ -16,12 +16,12 @@ class BattleInterface;
enum class EBattleFieldLayer {
// confirmed ordering requirements:
OBSTACLES = 0,
OBSTACLES_BG = 0,
CORPSES = 0,
WALLS = 1,
HEROES = 2,
STACKS = 2, // after corpses, obstacles, walls
BATTLEMENTS = 3, // after stacks
OBSTACLES_FG = 3, // after stacks
STACK_AMOUNTS = 3, // after stacks, obstacles, corpses
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){
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);
});
}

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,15 @@
"$schema" : "http://json-schema.org/draft-04/schema",
"title" : "VCMI obstacle format",
"description" : "Format used to define new obstacles in VCMI",
"required" : [ "animation" ],
"required" : [ "animation", "width", "height", "blockedTiles" ],
"anyOf" : [
{
"required" : [ "allowedTerrains" ]
},
{
"required" : [ "specialBattlefields" ]
}
],
"additionalProperties" : false,
"properties" : {
"allowedTerrains" : {
@ -41,9 +49,9 @@
{ "format" : "imageFile" }
]
},
"unknown" : {
"type" : "number",
"description" : "Unknown field"
"foreground" : {
"type" : "boolean",
"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->blockedTiles = json["blockedTiles"].convertTo<std::vector<si16>>();
info->isAbsoluteObstacle = json["absolute"].Bool();
info->isForegroundObstacle = json["foreground"].Bool();
objects.emplace_back(info);

View File

@ -20,11 +20,11 @@ VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE ObstacleInfo : public EntityT<Obstacle>
{
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)
: 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<std::string> allowedSpecialBfields;
//TODO: here is extra field to implement it's logic in the future but save backward compatibility
int obstacleType = -1;
ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
bool isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
bool isForegroundObstacle;
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)
@ -57,7 +55,6 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & obstacle;
h & obstacleType;
h & iconIndex;
h & identifier;
h & animation;
@ -66,6 +63,7 @@ public:
h & allowedTerrains;
h & allowedSpecialBfields;
h & isAbsoluteObstacle;
h & isForegroundObstacle;
h & width;
h & height;
h & blockedTiles;