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

Moved CBattleRenderer into a separate file

This commit is contained in:
Ivan Savenko 2022-12-06 13:41:29 +02:00
parent 1b4c5be4de
commit 2c05f588fd
15 changed files with 176 additions and 123 deletions

View File

@ -11,6 +11,7 @@ set(client_SRCS
battle/CBattleInterface.cpp
battle/CBattleObstacleController.cpp
battle/CBattleProjectileController.cpp
battle/CBattleRenderer.cpp
battle/CBattleSiegeController.cpp
battle/CBattleStacksController.cpp
battle/CCreatureAnimation.cpp
@ -93,6 +94,7 @@ set(client_HEADERS
battle/CBattleInterface.h
battle/CBattleObstacleController.h
battle/CBattleProjectileController.h
battle/CBattleRenderer.h
battle/CBattleSiegeController.h
battle/CBattleStacksController.h
battle/CCreatureAnimation.h

View File

@ -16,6 +16,7 @@
#include "CBattleInterfaceClasses.h"
#include "CBattleFieldController.h"
#include "CBattleStacksController.h"
#include "CBattleRenderer.h"
#include "../CMusicHandler.h"
#include "../CGameInfo.h"
@ -122,11 +123,11 @@ void CBattleEffectsController::startAction(const BattleAction* action)
}
}
void CBattleEffectsController::collectRenderableObjects(CBattleFieldRenderer & renderer)
void CBattleEffectsController::collectRenderableObjects(CBattleRenderer & renderer)
{
for (auto & elem : battleEffects)
{
renderer.insert( EBattleFieldLayer::EFFECTS, elem.position, [&elem](CBattleFieldRenderer::RendererPtr canvas)
renderer.insert( EBattleFieldLayer::EFFECTS, elem.position, [&elem](CBattleRenderer::RendererPtr canvas)
{
int currentFrame = static_cast<int>(floor(elem.currentFrame));
currentFrame %= elem.animation->size();

View File

@ -23,7 +23,7 @@ struct SDL_Surface;
class CAnimation;
class CCanvas;
class CBattleInterface;
class CBattleFieldRenderer;
class CBattleRenderer;
class CPointEffectAnimation;
namespace EBattleEffect
@ -78,7 +78,7 @@ public:
void battleTriggerEffect(const BattleTriggerEffect & bte);
void collectRenderableObjects(CBattleFieldRenderer & renderer);
void collectRenderableObjects(CBattleRenderer & renderer);
friend class CPointEffectAnimation;
};

View File

@ -18,6 +18,7 @@
#include "CBattleStacksController.h"
#include "CBattleObstacleController.h"
#include "CBattleProjectileController.h"
#include "CBattleRenderer.h"
#include "../CGameInfo.h"
#include "../CPlayerInterface.h"
@ -92,7 +93,7 @@ void CBattleFieldController::renderBattlefield(std::shared_ptr<CCanvas> canvas)
{
showBackground(canvas);
CBattleFieldRenderer renderer(owner);
CBattleRenderer renderer(owner);
renderer.execute(canvas);
@ -631,62 +632,3 @@ bool CBattleFieldController::stackCountOutsideHex(const BattleHex & number) cons
{
return stackCountOutsideHexes[number];
}
void CBattleFieldRenderer::collectObjects()
{
owner->collectRenderableObjects(*this);
owner->effectsController->collectRenderableObjects(*this);
owner->obstacleController->collectRenderableObjects(*this);
owner->siegeController->collectRenderableObjects(*this);
owner->stacksController->collectRenderableObjects(*this);
}
void CBattleFieldRenderer::sortObjects()
{
auto getRow = [](const RenderableInstance & object) -> int
{
if (object.tile.isValid())
return object.tile.getY();
if ( object.tile == BattleHex::HEX_BEFORE_ALL )
return -1;
if ( object.tile == BattleHex::HEX_AFTER_ALL )
return GameConstants::BFIELD_HEIGHT;
if ( object.tile == BattleHex::INVALID )
return GameConstants::BFIELD_HEIGHT;
assert(0);
return GameConstants::BFIELD_HEIGHT;
};
std::stable_sort(objects.begin(), objects.end(), [&](const RenderableInstance & left, const RenderableInstance & right){
if ( getRow(left) != getRow(right))
return getRow(left) < getRow(right);
return left.layer < right.layer;
});
}
void CBattleFieldRenderer::renderObjects(CBattleFieldRenderer::RendererPtr targetCanvas)
{
for (auto const & object : objects)
object.functor(targetCanvas);
}
CBattleFieldRenderer::CBattleFieldRenderer(CBattleInterface * owner):
owner(owner)
{
}
void CBattleFieldRenderer::insert(EBattleFieldLayer layer, BattleHex tile, CBattleFieldRenderer::RenderFunctor functor)
{
objects.push_back({ functor, layer, tile });
}
void CBattleFieldRenderer::execute(CBattleFieldRenderer::RendererPtr targetCanvas)
{
collectObjects();
sortObjects();
renderObjects(targetCanvas);
}

View File

@ -27,45 +27,6 @@ class CCanvas;
class IImage;
class CBattleInterface;
enum class EBattleFieldLayer {
// confirmed ordering requirements:
OBSTACLES = 0,
CORPSES = 0,
WALLS = 1,
HEROES = 1,
STACKS = 1, // after corpses, obstacles
BATTLEMENTS = 2, // after stacks
STACK_AMOUNTS = 2, // after stacks, obstacles, corpses
EFFECTS = 3, // after obstacles, battlements
};
class CBattleFieldRenderer
{
public:
using RendererPtr = std::shared_ptr<CCanvas>;
using RenderFunctor = std::function<void(RendererPtr)>;
private:
CBattleInterface * owner;
struct RenderableInstance
{
RenderFunctor functor;
EBattleFieldLayer layer;
BattleHex tile;
};
std::vector<RenderableInstance> objects;
void collectObjects();
void sortObjects();
void renderObjects(RendererPtr targetCanvas);
public:
CBattleFieldRenderer(CBattleInterface * owner);
void insert(EBattleFieldLayer layer, BattleHex tile, RenderFunctor functor);
void execute(RendererPtr targetCanvas);
};
class CBattleFieldController : public CIntObject
{
CBattleInterface * owner;

View File

@ -21,6 +21,7 @@
#include "CBattleFieldController.h"
#include "CBattleControlPanel.h"
#include "CBattleStacksController.h"
#include "CBattleRenderer.h"
#include "../CGameInfo.h"
#include "../CMessage.h"
@ -913,18 +914,18 @@ void CBattleInterface::show(SDL_Surface *to)
//activateStack();
}
void CBattleInterface::collectRenderableObjects(CBattleFieldRenderer & renderer)
void CBattleInterface::collectRenderableObjects(CBattleRenderer & renderer)
{
if (attackingHero)
{
renderer.insert(EBattleFieldLayer::HEROES, BattleHex(0),[this](CBattleFieldRenderer::RendererPtr canvas)
renderer.insert(EBattleFieldLayer::HEROES, BattleHex(0),[this](CBattleRenderer::RendererPtr canvas)
{
attackingHero->show(canvas->getSurface());
});
}
if (defendingHero)
{
renderer.insert(EBattleFieldLayer::HEROES, BattleHex(GameConstants::BFIELD_WIDTH-1),[this](CBattleFieldRenderer::RendererPtr canvas)
renderer.insert(EBattleFieldLayer::HEROES, BattleHex(GameConstants::BFIELD_WIDTH-1),[this](CBattleRenderer::RendererPtr canvas)
{
defendingHero->show(canvas->getSurface());
});

View File

@ -47,7 +47,7 @@ class CBattleProjectileController;
class CBattleSiegeController;
class CBattleObstacleController;
class CBattleFieldController;
class CBattleFieldRenderer;
class CBattleRenderer;
class CBattleControlPanel;
class CBattleStacksController;
class CBattleActionsController;
@ -143,7 +143,7 @@ public:
void show(SDL_Surface *to) override;
void showAll(SDL_Surface *to) override;
void collectRenderableObjects(CBattleFieldRenderer & renderer);
void collectRenderableObjects(CBattleRenderer & renderer);
//call-ins
void startAction(const BattleAction* action);

View File

@ -14,6 +14,7 @@
#include "CBattleFieldController.h"
#include "CBattleAnimations.h"
#include "CBattleStacksController.h"
#include "CBattleRenderer.h"
#include "../CPlayerInterface.h"
#include "../gui/CAnimation.h"
@ -126,7 +127,7 @@ void CBattleObstacleController::showAbsoluteObstacles(std::shared_ptr<CCanvas> c
}
}
void CBattleObstacleController::collectRenderableObjects(CBattleFieldRenderer & renderer)
void CBattleObstacleController::collectRenderableObjects(CBattleRenderer & renderer)
{
for (auto obstacle : owner->curInt->cb->battleGetAllObstacles())
{
@ -136,7 +137,7 @@ void CBattleObstacleController::collectRenderableObjects(CBattleFieldRenderer &
if (obstacle->obstacleType == CObstacleInstance::MOAT)
continue;
renderer.insert(EBattleFieldLayer::OBSTACLES, obstacle->pos, [this, obstacle]( CBattleFieldRenderer::RendererPtr canvas ){
renderer.insert(EBattleFieldLayer::OBSTACLES, obstacle->pos, [this, obstacle]( CBattleRenderer::RendererPtr canvas ){
auto img = getObstacleImage(*obstacle);
if(img)
{

View File

@ -21,7 +21,7 @@ class IImage;
class CCanvas;
class CAnimation;
class CBattleInterface;
class CBattleFieldRenderer;
class CBattleRenderer;
struct Point;
class CBattleObstacleController
@ -48,5 +48,5 @@ public:
void showObstacles(SDL_Surface *to, std::vector<std::shared_ptr<const CObstacleInstance>> &obstacles);
void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset);
void collectRenderableObjects(CBattleFieldRenderer & renderer);
void collectRenderableObjects(CBattleRenderer & renderer);
};

View File

@ -0,0 +1,77 @@
/*
* CBattleFieldController.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "CBattleRenderer.h"
#include "CBattleInterface.h"
#include "CBattleEffectsController.h"
#include "CBattleSiegeController.h"
#include "CBattleStacksController.h"
#include "CBattleObstacleController.h"
void CBattleRenderer::collectObjects()
{
owner->collectRenderableObjects(*this);
owner->effectsController->collectRenderableObjects(*this);
owner->obstacleController->collectRenderableObjects(*this);
owner->siegeController->collectRenderableObjects(*this);
owner->stacksController->collectRenderableObjects(*this);
}
void CBattleRenderer::sortObjects()
{
auto getRow = [](const RenderableInstance & object) -> int
{
if (object.tile.isValid())
return object.tile.getY();
if ( object.tile == BattleHex::HEX_BEFORE_ALL )
return -1;
if ( object.tile == BattleHex::HEX_AFTER_ALL )
return GameConstants::BFIELD_HEIGHT;
if ( object.tile == BattleHex::INVALID )
return GameConstants::BFIELD_HEIGHT;
assert(0);
return GameConstants::BFIELD_HEIGHT;
};
std::stable_sort(objects.begin(), objects.end(), [&](const RenderableInstance & left, const RenderableInstance & right){
if ( getRow(left) != getRow(right))
return getRow(left) < getRow(right);
return left.layer < right.layer;
});
}
void CBattleRenderer::renderObjects(CBattleRenderer::RendererPtr targetCanvas)
{
for (auto const & object : objects)
object.functor(targetCanvas);
}
CBattleRenderer::CBattleRenderer(CBattleInterface * owner):
owner(owner)
{
}
void CBattleRenderer::insert(EBattleFieldLayer layer, BattleHex tile, CBattleRenderer::RenderFunctor functor)
{
objects.push_back({ functor, layer, tile });
}
void CBattleRenderer::execute(CBattleRenderer::RendererPtr targetCanvas)
{
collectObjects();
sortObjects();
renderObjects(targetCanvas);
}

View File

@ -0,0 +1,66 @@
/*
* CBattleFieldController.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../../lib/battle/BattleHex.h"
VCMI_LIB_NAMESPACE_BEGIN
//class CStack;
VCMI_LIB_NAMESPACE_END
//struct SDL_Surface;
//struct Rect;
//struct Point;
//
//class CClickableHex;
class CCanvas;
//class IImage;
class CBattleInterface;
enum class EBattleFieldLayer {
// confirmed ordering requirements:
OBSTACLES = 0,
CORPSES = 0,
WALLS = 1,
HEROES = 1,
STACKS = 1, // after corpses, obstacles
BATTLEMENTS = 2, // after stacks
STACK_AMOUNTS = 2, // after stacks, obstacles, corpses
EFFECTS = 3, // after obstacles, battlements
};
class CBattleRenderer
{
public:
using RendererPtr = std::shared_ptr<CCanvas>;
using RenderFunctor = std::function<void(RendererPtr)>;
private:
CBattleInterface * owner;
struct RenderableInstance
{
RenderFunctor functor;
EBattleFieldLayer layer;
BattleHex tile;
};
std::vector<RenderableInstance> objects;
void collectObjects();
void sortObjects();
void renderObjects(RendererPtr targetCanvas);
public:
CBattleRenderer(CBattleInterface * owner);
void insert(EBattleFieldLayer layer, BattleHex tile, RenderFunctor functor);
void execute(RendererPtr targetCanvas);
};

View File

@ -15,6 +15,7 @@
#include "CBattleInterfaceClasses.h"
#include "CBattleStacksController.h"
#include "CBattleFieldController.h"
#include "CBattleRenderer.h"
#include "../CMusicHandler.h"
#include "../CGameInfo.h"
@ -280,7 +281,7 @@ const CStack * CBattleSiegeController::getTurretStack(EWallVisual::EWallVisual w
return nullptr;
}
void CBattleSiegeController::collectRenderableObjects(CBattleFieldRenderer & renderer)
void CBattleSiegeController::collectRenderableObjects(CBattleRenderer & renderer)
{
for (int i = EWallVisual::WALL_FIRST; i <= EWallVisual::WALL_LAST; ++i)
{
@ -296,14 +297,14 @@ void CBattleSiegeController::collectRenderableObjects(CBattleFieldRenderer & ren
wallPiece == EWallVisual::BOTTOM_BATTLEMENT ||
wallPiece == EWallVisual::UPPER_BATTLEMENT)
{
renderer.insert( EBattleFieldLayer::STACKS, getWallPiecePosition(wallPiece), [this, wallPiece](CBattleFieldRenderer::RendererPtr canvas){
renderer.insert( EBattleFieldLayer::STACKS, getWallPiecePosition(wallPiece), [this, wallPiece](CBattleRenderer::RendererPtr canvas){
owner->stacksController->showStack(canvas, getTurretStack(wallPiece));
});
renderer.insert( EBattleFieldLayer::BATTLEMENTS, getWallPiecePosition(wallPiece), [this, wallPiece](CBattleFieldRenderer::RendererPtr canvas){
renderer.insert( EBattleFieldLayer::BATTLEMENTS, getWallPiecePosition(wallPiece), [this, wallPiece](CBattleRenderer::RendererPtr canvas){
showWallPiece(canvas, wallPiece, owner->pos.topLeft());
});
}
renderer.insert( EBattleFieldLayer::WALLS, getWallPiecePosition(wallPiece), [this, wallPiece](CBattleFieldRenderer::RendererPtr canvas){
renderer.insert( EBattleFieldLayer::WALLS, getWallPiecePosition(wallPiece), [this, wallPiece](CBattleRenderer::RendererPtr canvas){
showWallPiece(canvas, wallPiece, owner->pos.topLeft());
});

View File

@ -25,7 +25,7 @@ struct Point;
struct SDL_Surface;
class CCanvas;
class CBattleInterface;
class CBattleFieldRenderer;
class CBattleRenderer;
class IImage;
namespace EWallVisual
@ -99,7 +99,7 @@ public:
/// call-ins from other battle controllers
void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset);
void collectRenderableObjects(CBattleFieldRenderer & renderer);
void collectRenderableObjects(CBattleRenderer & renderer);
/// queries from other battle controllers
bool isAttackableByCatapult(BattleHex hex) const;

View File

@ -18,6 +18,7 @@
#include "CBattleEffectsController.h"
#include "CBattleProjectileController.h"
#include "CBattleControlPanel.h"
#include "CBattleRenderer.h"
#include "CCreatureAnimation.h"
@ -116,7 +117,7 @@ BattleHex CBattleStacksController::getStackCurrentPosition(const CStack * stack)
return stack->getPosition();
}
void CBattleStacksController::collectRenderableObjects(CBattleFieldRenderer & renderer)
void CBattleStacksController::collectRenderableObjects(CBattleRenderer & renderer)
{
auto stacks = owner->curInt->cb->battleGetAllStacks(false);
@ -132,13 +133,13 @@ void CBattleStacksController::collectRenderableObjects(CBattleFieldRenderer & re
auto layer = stackAnimation[stack->ID]->isDead() ? EBattleFieldLayer::CORPSES : EBattleFieldLayer::STACKS;
auto location = getStackCurrentPosition(stack);
renderer.insert(layer, location, [this, stack]( CBattleFieldRenderer::RendererPtr renderer ){
renderer.insert(layer, location, [this, stack]( CBattleRenderer::RendererPtr renderer ){
showStack(renderer, stack);
});
if (stackNeedsAmountBox(stack))
{
renderer.insert(EBattleFieldLayer::STACK_AMOUNTS, location, [this, stack]( CBattleFieldRenderer::RendererPtr renderer ){
renderer.insert(EBattleFieldLayer::STACK_AMOUNTS, location, [this, stack]( CBattleRenderer::RendererPtr renderer ){
showStackAmountBox(renderer, stack);
});
}

View File

@ -28,7 +28,7 @@ class CBattleInterface;
class CBattleAnimation;
class CCreatureAnimation;
class CBattleAnimation;
class CBattleFieldRenderer;
class CBattleRenderer;
class IImage;
class CBattleStacksController
@ -89,7 +89,7 @@ public:
void showAliveStack(std::shared_ptr<CCanvas> canvas, const CStack * stack);
void showStack(std::shared_ptr<CCanvas> canvas, const CStack * stack);
void collectRenderableObjects(CBattleFieldRenderer & renderer);
void collectRenderableObjects(CBattleRenderer & renderer);
void addNewAnim(CBattleAnimation *anim); //adds new anim to pendingAnims
void updateBattleAnimations();