2022-11-20 19:11:34 +02:00
|
|
|
/*
|
2022-12-11 23:16:23 +02:00
|
|
|
* BattleStacksController.h, part of VCMI engine
|
2022-11-20 19:11:34 +02:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
|
2023-02-01 20:42:06 +02:00
|
|
|
#include "../render/ColorFilter.h"
|
2022-11-27 02:26:02 +02:00
|
|
|
|
2022-11-29 02:00:08 +02:00
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
2022-11-20 19:11:34 +02:00
|
|
|
struct BattleHex;
|
2022-11-29 02:00:08 +02:00
|
|
|
class BattleAction;
|
|
|
|
class CStack;
|
2022-12-15 23:24:03 +02:00
|
|
|
class CSpell;
|
2022-11-29 02:00:08 +02:00
|
|
|
class SpellID;
|
2023-01-18 17:32:57 +02:00
|
|
|
class Point;
|
2022-11-29 02:00:08 +02:00
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|
|
|
|
|
2022-11-20 19:11:34 +02:00
|
|
|
struct StackAttackedInfo;
|
2022-12-11 12:29:11 +02:00
|
|
|
struct StackAttackInfo;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-15 23:24:03 +02:00
|
|
|
class ColorFilter;
|
2022-12-11 22:09:57 +02:00
|
|
|
class Canvas;
|
2022-12-09 13:26:17 +02:00
|
|
|
class BattleInterface;
|
2022-12-12 22:04:25 +02:00
|
|
|
class BattleAnimation;
|
2022-12-09 13:26:17 +02:00
|
|
|
class CreatureAnimation;
|
2022-12-12 22:04:25 +02:00
|
|
|
class BattleAnimation;
|
2022-12-09 13:26:17 +02:00
|
|
|
class BattleRenderer;
|
2022-11-25 00:26:14 +02:00
|
|
|
class IImage;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-15 23:24:03 +02:00
|
|
|
struct BattleStackFilterEffect
|
|
|
|
{
|
|
|
|
ColorFilter effect;
|
|
|
|
const CStack * target;
|
|
|
|
const CSpell * source;
|
|
|
|
bool persistent;
|
|
|
|
};
|
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// Class responsible for handling stacks in battle
|
|
|
|
/// Handles ordering of stacks animation
|
|
|
|
/// As well as rendering of stacks, their amount boxes
|
|
|
|
/// And any other effect applied to stacks
|
2022-12-09 13:26:17 +02:00
|
|
|
class BattleStacksController
|
2022-11-20 19:11:34 +02:00
|
|
|
{
|
2022-12-13 13:58:16 +02:00
|
|
|
BattleInterface & owner;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-11-25 00:26:14 +02:00
|
|
|
std::shared_ptr<IImage> amountNormal;
|
|
|
|
std::shared_ptr<IImage> amountNegative;
|
|
|
|
std::shared_ptr<IImage> amountPositive;
|
|
|
|
std::shared_ptr<IImage> amountEffNeutral;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// currently displayed animations <anim, initialized>
|
2022-12-12 22:04:25 +02:00
|
|
|
std::vector<BattleAnimation *> currentAnimations;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-15 23:24:03 +02:00
|
|
|
/// currently active color effects on stacks, in order of their addition (which corresponds to their apply order)
|
|
|
|
std::vector<BattleStackFilterEffect> stackFilterEffects;
|
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
|
|
|
|
std::map<int32_t, std::shared_ptr<CreatureAnimation>> stackAnimation;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// <creatureID, if false reverse creature's animation> //TODO: move it to battle callback
|
|
|
|
std::map<int, bool> stackFacingRight;
|
|
|
|
|
2022-12-15 23:24:03 +02:00
|
|
|
/// currently active stack; nullptr - no one
|
2022-12-11 23:16:23 +02:00
|
|
|
const CStack *activeStack;
|
|
|
|
|
2023-01-22 21:03:11 +02:00
|
|
|
/// stacks or their battle queue images below mouse pointer (multiple stacks possible while spellcasting), used for border animation
|
2022-12-17 00:10:12 +02:00
|
|
|
std::vector<const CStack *> mouseHoveredStacks;
|
2022-12-11 23:16:23 +02:00
|
|
|
|
|
|
|
///when animation is playing, we should wait till the end to make the next stack active; nullptr of none
|
|
|
|
const CStack *stackToActivate;
|
|
|
|
|
|
|
|
/// stack that was selected for multi-target spells - Teleport / Sacrifice
|
|
|
|
const CStack *selectedStack;
|
|
|
|
|
|
|
|
/// for giving IDs for animations
|
|
|
|
ui32 animIDhelper;
|
2022-11-25 00:26:14 +02:00
|
|
|
|
2022-12-13 15:10:31 +02:00
|
|
|
bool stackNeedsAmountBox(const CStack * stack) const;
|
2022-12-11 22:09:57 +02:00
|
|
|
void showStackAmountBox(Canvas & canvas, const CStack * stack);
|
2022-12-13 15:10:31 +02:00
|
|
|
BattleHex getStackCurrentPosition(const CStack * stack) const;
|
2022-11-26 23:12:20 +02:00
|
|
|
|
|
|
|
std::shared_ptr<IImage> getStackAmountBox(const CStack * stack);
|
2022-11-25 00:26:14 +02:00
|
|
|
|
2022-12-11 12:29:11 +02:00
|
|
|
void executeAttackAnimations();
|
2022-12-15 23:24:03 +02:00
|
|
|
void removeExpiredColorFilters();
|
2022-12-17 00:10:12 +02:00
|
|
|
|
2023-01-04 23:04:48 +02:00
|
|
|
void initializeBattleAnimations();
|
|
|
|
void stepFrameBattleAnimations();
|
|
|
|
|
2022-12-17 00:10:12 +02:00
|
|
|
void updateBattleAnimations();
|
|
|
|
void updateHoveredStacks();
|
|
|
|
|
|
|
|
std::vector<const CStack *> selectHoveredStacks();
|
|
|
|
|
2022-12-18 11:42:02 +02:00
|
|
|
bool shouldAttackFacingRight(const CStack * attacker, const CStack * defender);
|
|
|
|
|
2022-11-20 19:11:34 +02:00
|
|
|
public:
|
2022-12-13 13:58:16 +02:00
|
|
|
BattleStacksController(BattleInterface & owner);
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
bool shouldRotate(const CStack * stack, const BattleHex & oldPos, const BattleHex & nextHex) const;
|
|
|
|
bool facingRight(const CStack * stack) const;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
|
|
|
void stackReset(const CStack * stack);
|
2022-12-14 12:04:37 +02:00
|
|
|
void stackAdded(const CStack * stack, bool instant); //new stack appeared on battlefield
|
2022-11-20 19:11:34 +02:00
|
|
|
void stackRemoved(uint32_t stackID); //stack disappeared from batlefiled
|
|
|
|
void stackActivated(const CStack *stack); //active stack has been changed
|
|
|
|
void stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance); //stack with id number moved to destHex
|
2022-12-18 18:26:43 +02:00
|
|
|
void stackTeleported(const CStack *stack, std::vector<BattleHex> destHex, int distance); //stack with id number moved to destHex
|
2022-11-20 19:11:34 +02:00
|
|
|
void stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
|
2022-12-11 12:29:11 +02:00
|
|
|
void stackAttacking(const StackAttackInfo & info); //called when stack with id ID is attacking something on hex dest
|
2022-11-20 19:11:34 +02:00
|
|
|
|
|
|
|
void startAction(const BattleAction* action);
|
|
|
|
void endAction(const BattleAction* action);
|
|
|
|
|
|
|
|
void activateStack(); //sets activeStack to stackToActivate etc. //FIXME: No, it's not clear at all
|
|
|
|
|
|
|
|
void setActiveStack(const CStack *stack);
|
|
|
|
void setSelectedStack(const CStack *stack);
|
|
|
|
|
2022-12-11 22:09:57 +02:00
|
|
|
void showAliveStack(Canvas & canvas, const CStack * stack);
|
|
|
|
void showStack(Canvas & canvas, const CStack * stack);
|
2022-11-25 00:26:14 +02:00
|
|
|
|
2022-12-09 13:26:17 +02:00
|
|
|
void collectRenderableObjects(BattleRenderer & renderer);
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-15 23:24:03 +02:00
|
|
|
/// Adds new color filter effect targeting stack
|
|
|
|
/// Effect will last as long as stack is affected by specified spell (unless effect is persistent)
|
|
|
|
/// If effect from same (target, source) already exists, it will be updated
|
|
|
|
void setStackColorFilter(const ColorFilter & effect, const CStack * target, const CSpell *source, bool persistent);
|
2022-12-12 22:04:25 +02:00
|
|
|
void addNewAnim(BattleAnimation *anim); //adds new anim to pendingAnims
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
const CStack* getActiveStack() const;
|
|
|
|
const CStack* getSelectedStack() const;
|
2023-01-22 21:06:10 +02:00
|
|
|
const std::vector<uint32_t> getHoveredStacksUnitIds() const;
|
2022-11-20 19:11:34 +02:00
|
|
|
|
2022-12-17 00:10:12 +02:00
|
|
|
void update();
|
|
|
|
|
2022-11-27 02:26:02 +02:00
|
|
|
/// returns position of animation needed to place stack in specific hex
|
2022-12-11 23:16:23 +02:00
|
|
|
Point getStackPositionAtHex(BattleHex hexNum, const CStack * creature) const;
|
2022-11-27 02:26:02 +02:00
|
|
|
|
2022-12-12 22:04:25 +02:00
|
|
|
friend class BattleAnimation; // for exposing pendingAnims/creAnims/creDir to animations
|
2022-11-20 19:11:34 +02:00
|
|
|
};
|