File: CCreatureAnimation.h

package info (click to toggle)
vcmi 0.99%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: stretch
  • size: 10,264 kB
  • ctags: 16,826
  • sloc: cpp: 121,945; objc: 248; sh: 193; makefile: 28; python: 13; ansic: 9
file content (142 lines) | stat: -rw-r--r-- 4,843 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#pragma once

#include "../../lib/FunctionList.h"
#include "../gui/SDL_Extensions.h"
#include "../widgets/Images.h"

/*
 * CCreatureAnimation.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
 *
 */

class CIntObject;
class CCreatureAnimation;

/// Namespace for some common controls of animations
namespace AnimationControls
{
	/// get SDL_Color for creature selection borders
	SDL_Color getBlueBorder();
	SDL_Color getGoldBorder();
	SDL_Color getNoBorder();

	/// creates animation object with preset speed control
	CCreatureAnimation * getAnimation(const CCreature * creature);

	/// returns animation speed of specific group, taking in mind game setting (in frames per second)
	float getCreatureAnimationSpeed(const CCreature * creature, const CCreatureAnimation * anim, size_t groupID);

	/// returns how far projectile should move each frame
	/// TODO: make it time-based
	float getProjectileSpeed();

	/// returns speed of any spell effects, including any special effects like morale (in frames per second)
	float getSpellEffectSpeed();

	/// returns duration of full movement animation, in seconds. Needed to move animation on screen
	float getMovementDuration(const CCreature * creature);

	/// Returns distance on which flying creatures should during one animation loop
	float getFlightDistance(const CCreature * creature);
}

/// Class which manages animations of creatures/units inside battles
/// TODO: split into constant image container and class that does *control* of animation
class CCreatureAnimation : public CIntObject
{
public:
	typedef std::function<float(CCreatureAnimation *, size_t)> TSpeedController;

private:
	std::string defName;

	int fullWidth, fullHeight;

	// palette, as read from def file
	std::array<SDL_Color, 256> palette;

	//key = id of group (note that some groups may be missing)
	//value = offset of pixel data for each frame, vector size = number of frames in group
	std::map<int, std::vector<unsigned int>> dataOffsets;

	//animation raw data
	//TODO: use vector instead?
	std::unique_ptr<ui8[]> pixelData;
	size_t pixelDataSize;

	// speed of animation, measure in frames per second
	float speed;

	// currently displayed frame. Float to allow H3-style animations where frames
	// don't display for integer number of frames
	float currentFrame;
	// cumulative, real-time duration of animation. Used for effects like selection border
	float elapsedTime;
	CCreatureAnim::EAnimType type; //type of animation being displayed

	// border color, disabled if alpha = 0
	SDL_Color border;

	TSpeedController speedController;

	bool once; // animation will be played once and the reset to idling

	ui8 * getPixelAddr(SDL_Surface * dest, int ftcpX, int ftcpY) const;

	template<int bpp>
	void putPixelAt(SDL_Surface * dest, int X, int Y, size_t index, const std::array<SDL_Color, 8> & special) const;

	template<int bpp>
	void putPixel( ui8 * dest, const SDL_Color & color, size_t index, const std::array<SDL_Color, 8> & special) const;

	template<int bpp>
	void nextFrameT(SDL_Surface * dest, bool rotate);

	void endAnimation();

	/// creates 8 special colors for current frame
	std::array<SDL_Color, 8> genSpecialPalette();
public:

	// function(s) that will be called when animation ends, after reset to 1st frame
	// NOTE that these function will be fired only once
	CFunctionList<void()> onAnimationReset;

	int getWidth() const;
	int getHeight() const;

	/// Constructor
	/// name - path to .def file, relative to SPRITES/ directory
	/// controller - function that will return for how long *each* frame
	/// in specified group of animation should be played, measured in seconds
	CCreatureAnimation(std::string name, TSpeedController speedController); //c-tor

	void setType(CCreatureAnim::EAnimType type); //sets type of animation and cleares framecount
	CCreatureAnim::EAnimType getType() const; //returns type of animation

	void nextFrame(SDL_Surface * dest, bool rotate);

	// should be called every frame, return true when animation was reset to beginning
	bool incrementFrame(float timePassed);
	void setBorderColor(SDL_Color palette);

	float getCurrentFrame() const; // Gets the current frame ID relative to frame group.

	void playOnce(CCreatureAnim::EAnimType type); //plays once given stage of animation, then resets to 2

	int framesInGroup(CCreatureAnim::EAnimType group) const; //retirns number of fromes in given group

	void pause();
	void play();

	//helpers. TODO: move them somewhere else
	bool isDead() const;
	bool isIdle() const;
	bool isMoving() const;
	bool isShooting() const;
};