2022-11-17 13:21:03 +02:00
|
|
|
/*
|
2022-12-11 23:16:23 +02:00
|
|
|
* BattleSiegeController.h, part of VCMI engine
|
2022-11-17 13:21:03 +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
|
|
|
|
|
|
|
|
#include "../../lib/CCreatureHandler.h"
|
2023-01-18 15:50:52 +02:00
|
|
|
#include "../../lib/Point.h"
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2022-11-29 02:00:08 +02:00
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
class CStack;
|
2022-12-01 22:06:42 +02:00
|
|
|
class CSpell;
|
2022-11-29 02:00:08 +02:00
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|
|
|
|
|
2022-11-17 13:21:03 +02:00
|
|
|
class CAnimation;
|
2022-12-11 22:09:57 +02:00
|
|
|
class Canvas;
|
2022-12-09 13:26:17 +02:00
|
|
|
class BattleInterface;
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// Base class for projectiles
|
2022-11-25 16:32:23 +02:00
|
|
|
struct ProjectileBase
|
2022-11-17 13:21:03 +02:00
|
|
|
{
|
2022-11-25 16:32:23 +02:00
|
|
|
virtual ~ProjectileBase() = default;
|
2022-12-11 22:09:57 +02:00
|
|
|
virtual void show(Canvas & canvas) = 0;
|
2023-05-13 22:38:57 +02:00
|
|
|
virtual void tick(uint32_t msPassed) = 0;
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2022-11-25 16:32:23 +02:00
|
|
|
Point from; // initial position on the screen
|
|
|
|
Point dest; // target position on the screen
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2023-01-05 15:26:29 +02:00
|
|
|
float progress; // current position of projectile on from->dest line
|
|
|
|
float speed; // how much progress is gained per second
|
|
|
|
int shooterID; // ID of shooter stack
|
|
|
|
bool playing; // if set to true, projectile animation is playing, e.g. flying to target
|
2022-11-17 13:21:03 +02:00
|
|
|
};
|
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// Projectile for most shooters - render pre-selected frame moving in straight line from origin to destination
|
2022-11-25 16:32:23 +02:00
|
|
|
struct ProjectileMissile : ProjectileBase
|
|
|
|
{
|
2022-12-11 22:09:57 +02:00
|
|
|
void show(Canvas & canvas) override;
|
2023-05-13 22:38:57 +02:00
|
|
|
void tick(uint32_t msPassed) override;
|
2022-11-25 16:32:23 +02:00
|
|
|
|
|
|
|
std::shared_ptr<CAnimation> animation;
|
|
|
|
int frameNum; // frame to display from projectile animation
|
|
|
|
bool reverse; // if true, projectile will be flipped by vertical axis
|
|
|
|
};
|
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// Projectile for spell - render animation moving in straight line from origin to destination
|
2022-12-01 22:06:42 +02:00
|
|
|
struct ProjectileAnimatedMissile : ProjectileMissile
|
|
|
|
{
|
2023-05-13 22:38:57 +02:00
|
|
|
void tick(uint32_t msPassed) override;
|
2022-12-01 22:06:42 +02:00
|
|
|
float frameProgress;
|
|
|
|
};
|
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// Projectile for catapult - render spinning projectile moving at parabolic trajectory to its destination
|
2022-12-01 22:06:42 +02:00
|
|
|
struct ProjectileCatapult : ProjectileBase
|
2022-11-25 16:32:23 +02:00
|
|
|
{
|
2022-12-11 22:09:57 +02:00
|
|
|
void show(Canvas & canvas) override;
|
2023-05-13 22:38:57 +02:00
|
|
|
void tick(uint32_t msPassed) override;
|
2022-11-25 16:32:23 +02:00
|
|
|
|
2022-12-01 22:06:42 +02:00
|
|
|
std::shared_ptr<CAnimation> animation;
|
2023-01-27 23:16:02 +02:00
|
|
|
float frameProgress;
|
2022-11-25 16:32:23 +02:00
|
|
|
};
|
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// Projectile for mages/evil eye - render ray expanding from origin position to destination
|
2022-11-25 16:32:23 +02:00
|
|
|
struct ProjectileRay : ProjectileBase
|
2022-11-17 13:21:03 +02:00
|
|
|
{
|
2022-12-11 22:09:57 +02:00
|
|
|
void show(Canvas & canvas) override;
|
2023-05-13 22:38:57 +02:00
|
|
|
void tick(uint32_t msPassed) override;
|
2022-11-25 16:32:23 +02:00
|
|
|
|
|
|
|
std::vector<CCreature::CreatureAnimation::RayColor> rayConfig;
|
2022-11-17 13:21:03 +02:00
|
|
|
};
|
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// Class that manages all ongoing projectiles in the game
|
|
|
|
/// ... even though in H3 only 1 projectile can be on screen at any point of time
|
2022-12-09 13:26:17 +02:00
|
|
|
class BattleProjectileController
|
2022-11-17 13:21:03 +02:00
|
|
|
{
|
2022-12-13 13:58:16 +02:00
|
|
|
BattleInterface & owner;
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2022-11-25 16:32:23 +02:00
|
|
|
/// all projectiles loaded during current battle
|
|
|
|
std::map<std::string, std::shared_ptr<CAnimation>> projectilesCache;
|
|
|
|
|
|
|
|
/// projectiles currently flying on battlefield
|
|
|
|
std::vector<std::shared_ptr<ProjectileBase>> projectiles;
|
|
|
|
|
|
|
|
std::shared_ptr<CAnimation> getProjectileImage(const CStack * stack);
|
2022-12-01 22:06:42 +02:00
|
|
|
std::shared_ptr<CAnimation> createProjectileImage(const std::string & path );
|
2022-11-25 16:32:23 +02:00
|
|
|
void initStackProjectile(const CStack * stack);
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2022-12-13 13:58:16 +02:00
|
|
|
bool stackUsesRayProjectile(const CStack * stack) const;
|
|
|
|
bool stackUsesMissileProjectile(const CStack * stack) const;
|
2022-11-25 16:32:23 +02:00
|
|
|
|
2022-12-11 22:09:57 +02:00
|
|
|
void showProjectile(Canvas & canvas, std::shared_ptr<ProjectileBase> projectile);
|
2022-11-25 16:32:23 +02:00
|
|
|
|
2022-12-13 13:58:16 +02:00
|
|
|
const CCreature & getShooter(const CStack * stack) const;
|
2022-12-01 22:06:42 +02:00
|
|
|
|
|
|
|
int computeProjectileFrameID( Point from, Point dest, const CStack * stack);
|
2023-01-05 15:26:29 +02:00
|
|
|
float computeProjectileFlightTime( Point from, Point dest, double speed);
|
2022-12-11 23:16:23 +02:00
|
|
|
|
2022-11-17 13:21:03 +02:00
|
|
|
public:
|
2022-12-13 13:58:16 +02:00
|
|
|
BattleProjectileController(BattleInterface & owner);
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// renders all currently active projectiles
|
2023-05-13 22:38:57 +02:00
|
|
|
void render(Canvas & canvas);
|
|
|
|
|
|
|
|
/// updates positioning / animations of all projectiles
|
|
|
|
void tick(uint32_t msPassed);
|
2022-11-17 13:21:03 +02:00
|
|
|
|
2022-12-11 23:16:23 +02:00
|
|
|
/// returns true if stack has projectile that is yet to hit target
|
2022-12-15 23:24:03 +02:00
|
|
|
bool hasActiveProjectile(const CStack * stack, bool emittedOnly) const;
|
2022-12-11 23:16:23 +02:00
|
|
|
|
|
|
|
/// starts rendering previously created projectile
|
2022-11-27 17:24:45 +02:00
|
|
|
void emitStackProjectile(const CStack * stack);
|
2022-12-11 23:16:23 +02:00
|
|
|
|
|
|
|
/// creates (but not emits!) projectile and initializes it based on parameters
|
|
|
|
void createProjectile(const CStack * shooter, Point from, Point dest);
|
|
|
|
void createSpellProjectile(const CStack * shooter, Point from, Point dest, const CSpell * spell);
|
2022-12-01 22:06:42 +02:00
|
|
|
void createCatapultProjectile(const CStack * shooter, Point from, Point dest);
|
2022-11-17 13:21:03 +02:00
|
|
|
};
|