1 /* GemRB - Infinity Engine Emulator
2  * Copyright (C) 2006 The GemRB Project
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  *
19  */
20 
21 /**
22  * @file Particles.h
23  * Declares Particles class implementing weather and spark effects
24  * and related defines
25  */
26 
27 #ifndef PARTICLES_H
28 #define PARTICLES_H
29 
30 #include "exports.h"
31 #include "ie_types.h"
32 
33 #include "Region.h"
34 
35 namespace GemRB {
36 
37 class CharAnimations;
38 class Scriptable;
39 
40 //global phase for the while spark structure
41 #define P_GROW  0
42 #define P_FADE  1
43 #define P_EMPTY 2
44 
45 // this structure holds data for a single particle element
46 struct Element {
47 	int state;
48 	Point pos;
ElementElement49 	Element(): state(-1) {};
50 };
51 
52 /**
53  * @class Particles
54  * Class holding information about particles and rendering them.
55  */
56 
57 #define SP_TYPE_POINT  0
58 #define SP_TYPE_LINE   1
59 #define SP_TYPE_CIRCLE 2
60 #define SP_TYPE_BITMAP 3
61 
62 #define SP_PATH_FALL   0       //free falling
63 #define SP_PATH_FOUNT  1       //going up and down
64 #define SP_PATH_FLIT   2       //flitting
65 #define SP_PATH_RAIN   3       //falling and vanishing quickly
66 #define SP_PATH_EXPL   4       //explosion (mostly used with fragments)
67 
68 #define SP_SPAWN_NONE  0       //don't create new sparks
69 #define SP_SPAWN_FULL  1       //fill all at setup, then switch to none
70 #define SP_SPAWN_SOME  2       //add some new elements regularly
71 
72 // order of names as in sprklclr.2da is never used, they permuted it for some reason
73 // NOTE: the first (default) phase is almost white for most colors
74 #define SPARK_COLOR_BLUE 2
75 #define SPARK_COLOR_GOLD 4
76 #define SPARK_COLOR_PURPLE 6
77 #define SPARK_COLOR_ICE 9
78 #define SPARK_COLOR_STONE 10
79 #define SPARK_COLOR_BLACK 1
80 #define SPARK_COLOR_CHROM 3
81 #define SPARK_COLOR_RED 7
82 #define SPARK_COLOR_GREEN 5
83 #define SPARK_COLOR_WHITE 8
84 #define SPARK_COLOR_MAGENTA 11
85 #define SPARK_COLOR_ORANGE 12
86 #define SPARK_COLOR_CUSTOM 0
87 
88 #define MAX_SPARK_COLOR  13
89 #define MAX_SPARK_PHASE  5
90 
91 class GEM_EXPORT Particles {
92 public:
93 	Particles(int s);
94 	~Particles();
95 
96 	void SetBitmap(unsigned int FragAnimID);
SetPhase(ieByte ph)97 	void SetPhase(ieByte ph) { phase = ph; }
GetPhase()98 	int GetPhase() const { return phase; }
MatchPos(const Point & p)99 	bool MatchPos(const Point &p) const { return pos.x==p.x && pos.y==p.y; }
100 	void SetType(ieByte t, ieByte p=SP_PATH_FALL, ieByte st=SP_SPAWN_NONE)
101 	{
102 		type=t;
103 		path=p;
104 		spawn_type=st;
105 	}
SetRegion(int x,int y,int w,int h)106 	void SetRegion(int x, int y, int w, int h)
107 	{
108 		pos.x = x;
109 		pos.y = y;
110 		pos.w = w;
111 		pos.h = h;
112 	}
SetTimeToLive(int ttl)113 	void SetTimeToLive(int ttl) { timetolive = ttl; }
SetColor(ieByte c)114 	void SetColor(ieByte c) { color=c; }
SetOwner(Scriptable * o)115 	void SetOwner(Scriptable *o) { owner=o; }
116 	/* returns true if it cannot add new elements */
117 	bool AddNew(const Point &point);
118 	void Draw(Point p);
119 	void AddParticles(int count);
120 	/* returns true if it could be destroyed (didn't draw anything) */
121 	int Update();
GetHeight()122 	int GetHeight() const { return pos.y+pos.h; }
123 private:
124 	Element *points = nullptr;
125 	ieDword timetolive = 0;
126 //	ieDword target;    //could be 0, in that case target is pos
127 	ieWord size = 0;       // spark number
128 	ieWord last_insert = 0;// last spark idx added
129 	Scriptable *owner = nullptr; // could be area or game or actor
130 	Region pos;
131 	ieByte phase = P_FADE;      // global phase
132 	ieByte type = SP_TYPE_POINT;       // draw type (snow, rain)
133 	ieByte path = SP_PATH_FALL;       // path type
134 	ieByte color = 0;      // general spark color (index, see SPARK_COLOR_*)
135 	ieByte spawn_type = SP_SPAWN_NONE;
136 	//use char animations for the fragment animations
137 	//1. the cycles are loaded only when needed
138 	//2. the fragments ARE avatar animations in the original IE (for some unknown reason)
139 	CharAnimations *fragments = nullptr;
140 };
141 
142 }
143 
144 #endif  // ! PARTICLES_H
145