Move EventMgr to GUI.
[gemrb.git] / gemrb / core / Projectile.h
blob9a7838feadf0aa474036503c271d678c2eb85112
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2006 The GemRB Project
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.
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.
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.
21 /**
22 * @file Projectile.h
23 * Declares Projectile, class for supporting functionality of spell/item projectiles
24 * @author The GemRB Project
28 #ifndef PROJECTILE_H
29 #define PROJECTILE_H
31 #include "exports.h"
32 #include "ie_types.h"
34 #include "CharAnimations.h" //contains MAX_ORIENT
35 #include "Map.h"
36 #include "Palette.h"
37 #include "PathFinder.h"
39 //this is the height of the projectile when Spark Flag Fly = 1
40 #define FLY_HEIGHT 50
41 //this is supposed to move the projectile to the background
42 #define BACK_DEPTH 50
44 //projectile phases
45 #define P_UNINITED -1
46 #define P_TRAVEL 0 //projectile moves to target
47 #define P_TRIGGER 1 //projectile hovers over target, waits for trigger
48 #define P_EXPLODING1 2 //projectile explosion spreads
49 #define P_EXPLODING2 3 //projectile explosion repeats
50 #define P_EXPLODED 4 //projectile spread over area
51 #define P_EXPIRED 99 //projectile scheduled for removal (existing parts are still drawn)
53 //projectile spark flags
54 #define PSF_SPARKS 1
55 #define PSF_FLYING 2
56 #define PSF_LOOPING 4 //looping sound
57 #define PSF_IGNORE_CENTER 16
59 //projectile travel flags
60 #define PTF_COLOUR 1 //fake colours
61 #define PTF_SMOKE 2 //has smoke
62 #define PTF_TINT 8 //tint projectile
63 #define PTF_SHADOW 32 //has shadow bam
64 #define PTF_LIGHT 64 //has light shadow
65 #define PTF_BLEND 128 //blend colours
67 //projectile extended travel flags (gemrb specific)
68 #define PEF_BOUNCE 1 //bounce from walls (lightning bolt)
69 #define PEF_CONTINUE 2 //continue as a travel projectile after trigger (lightning bolt)
70 #define PEF_FREEZE 4 //stay around (ice dagger)
71 #define PEF_NO_TRAVEL 8 //all instant projectiles (draw upon holy might, finger of death)
72 #define PEF_TRAIL 16 //trail bams facing value uses the same field as the travel projectile (otherwise it defaults to 9) (shout in iwd)
73 #define PEF_CURVE 32 //curved path (magic missile)
74 #define PEF_RANDOM 64 //random starting frame for animation (?)
75 #define PEF_PILLAR 128 //draw all cycles simultaneously on top of each other (call lightning, flamestrike)
76 #define PEF_HALFTRANS 256 //half-transparency (holy might)
77 #define PEF_TINT 512 //use palette gradient as tint
78 #define PEF_ITERATION 1024 //create another projectile of type-1 (magic missiles)
79 #define PEF_TILED 2048 //tiled AOE (bg1 cone of cold/fire)
80 #define PEF_FALLING 4096 //projectile falls down vertically (cow)
81 #define PEF_INCOMING 8192 //projectile falls in on trajectory (comet)
82 #define PEF_LINE 16384 //solid line between source and target (agannazar's scorcher)
83 #define PEF_WALL 32768 //solid line in front of source, crossing target (wall of fire)
84 #define PEF_BACKGROUND 0x10000 //draw under target,overrides flying (dimension door)
85 #define PEF_POP 0x20000 //draw travel bam, then shadow, then travel bam backwards
86 #define PEF_UNPOP 0x40000 //draw shadow, then travel bam (this is an internal flag)
87 #define PEF_FADE 0x80000 //gradually fade on spot if used with PEF_FREEZE (ice dagger)
88 #define PEF_TEXT 0x100000//display text during setup
89 #define PEF_WANDERING 0x200000//random movement (no real path)
90 #define PEF_CYCLE 0x400000//random cycle
91 #define PEF_RGB 0x800000//rgb pulse on hit
93 //projectile area flags
94 #define PAF_VISIBLE 1 //the travel projectile is visible until explosion
95 #define PAF_INANIMATE 2 //target inanimates
96 #define PAF_TRIGGER 4 //explosion needs to be triggered
97 #define PAF_SYNC 8 //one explosion at a time
98 #define PAF_SECONDARY 16 //secondary projectiles at explosion
99 #define PAF_FRAGMENT 32 //fragments (charanimation) at explosion
100 #define PAF_ENEMY 64 //target party or not party
101 #define PAF_PARTY 128 //target party
102 #define PAF_TARGET (64|128)
103 #define PAF_LEV_MAGE 256
104 #define PAF_LEV_CLERIC 512
105 #define PAF_VVC 1024 //
106 #define PAF_CONE 2048 //enable cone shape
107 #define PAF_NO_WALL 0x1000 //pass through walls
108 #define PAF_TRIGGER_D 0x2000 //delayed trigger (only if animation is over 30)
109 #define PAF_DELAY 0x4000 //
110 #define PAF_AFFECT_ONE 0x8000 //
113 //area projectile flags (in areapro.2da)
114 //this functionality was hardcoded in the original engine, so the bit flags are
115 //completely arbitrary (i assign them as need arises)
116 //child projectiles need to be tinted (example: stinking cloud, counter example: fireball)
117 #define APF_TINT 1
118 //child projectiles fill the whole area (example: stinking cloud, counter example: fireball)
119 #define APF_FILL 2
120 //child projectiles start in their destination (example: icestorm, counter example: fireball)
121 #define APF_SCATTER 4
122 //the explosion vvc has gradient (example: icestorm, counter example: fireball)
123 #define APF_VVCPAL 8
124 //there is an additional added scatter after the initial spreading ring
125 #define APF_SPREAD 16
126 //the spread projectile needs gradient colouring,not tint (example:web, counter example: stinking cloud)
127 #define APF_PALETTE 32
128 //use both animations in the spread
129 #define APF_BOTH 64
130 //more child projectiles
131 #define APF_MORE 128
132 //apply spell on caster if failed to find target
133 #define APF_SPELLFAIL 256
135 struct ProjectileExtension
137 ieDword AFlags;
138 ieWord TriggerRadius;
139 ieWord ExplosionRadius;
140 ieResRef SoundRes; //used for areapro.2da explosion sound
141 ieWord Delay;
142 ieWord FragAnimID;
143 ieWord FragProjIdx;
144 ieByte ExplosionCount;
145 ieByte ExplType;
146 ieWord ExplColor;
147 ieWord ExplProjIdx;
148 ieResRef VVCRes; //used for areapro.2da second resref (center animation)
149 ieWord ConeWidth;
150 //these are GemRB specific (from areapro.2da)
151 ieDword APFlags; //areapro.2da flags
152 ieResRef Spread; //areapro.2da first resref
153 ieResRef Secondary; //areapro.2da third resref
154 ieResRef AreaSound; //areapro.2da second sound resource
157 class GEM_EXPORT Projectile
159 public:
160 Projectile();
161 ~Projectile();
162 void InitExtension();
164 ieWord Speed;
165 ieDword SFlags;
166 ieResRef SoundRes1;
167 ieResRef SoundRes2;
168 ieResRef SoundRes3;
169 ieDword SparkColor;
170 ieDword ExtFlags;
171 ieDword StrRef;
172 ieDword RGB;
173 ieWord ColorSpeed;
174 ieWord Shake;
175 ////// gap
176 ieDword TFlags;
177 ieResRef BAMRes1;
178 ieResRef BAMRes2;
179 ieByte Seq1, Seq2;
180 ieWord LightX;
181 ieWord LightY;
182 ieWord LightZ;
183 ieResRef PaletteRes;
184 ieByte Gradients[7];
185 ieByte SmokeSpeed;
186 ieByte SmokeGrad[7];
187 ieByte Aim;
188 ieWord SmokeAnimID;
189 ieResRef TrailBAM[3];
190 ieWord TrailSpeed[3];
191 //these are public but not in the .pro file
192 ProjectileExtension* Extension;
193 bool autofree;
194 Palette* palette;
195 //internals
196 protected:
197 ieResRef smokebam;
198 ieDword timeStartStep;
199 //attributes from moveable object
200 unsigned char Orientation, NewOrientation;
201 PathNode* path; //whole path
202 PathNode* step; //actual step
203 //similar to normal actors
204 Map *area;
205 Point Pos;
206 Point Destination;
207 Point Origin;
208 ieDword Caster; //the globalID of the caster actor
209 ieDword Target; //the globalID of target actor
210 int phase;
211 //saved in area
212 ieResRef name;
213 ieWord type;
214 //these come from the extension area
215 int extension_delay;
216 int extension_explosioncount;
217 Color tint;
219 //special (not using char animations)
220 Animation* travel[MAX_ORIENT];
221 Animation* shadow[MAX_ORIENT];
222 Sprite2D* light;//this is just a round/halftrans sprite, has no animation
223 EffectQueue* effects;
224 Projectile **children;
225 int child_size;
226 int pathcounter;
227 public:
228 void SetCaster(ieDword t);
229 ieDword GetCaster() const;
230 void SetTarget(ieDword t);
231 void SetTarget(const Point &p);
232 bool PointInRadius(const Point &p) const;
233 void Cleanup();
235 //inliners to protect data consistency
236 inline PathNode * GetNextStep() {
237 if (!step) {
238 DoStep((unsigned int) ~0);
240 return step;
243 inline Point GetDestination() const { return Destination; }
244 inline const char * GetName() const { return name; }
245 inline ieWord GetType() const { return type; }
246 //This assumes that the effect queue cannot be bigger than 65535
247 //which is a sane expectation
248 inline EffectQueue *GetEffects() const {
249 return effects;
252 inline unsigned char GetOrientation() const {
253 return Orientation;
255 //no idea if projectiles got height, using y
256 inline int GetHeight() const {
257 //if projectile is drawn behind target
258 if (ExtFlags&PEF_BACKGROUND) {
259 return Pos.y-BACK_DEPTH;
262 //if projectile is flying
263 if (SFlags&PSF_FLYING) {
264 return Pos.y+FLY_HEIGHT;
266 return Pos.y;
269 void SetIdentifiers(const char *name, ieWord type);
271 void SetEffectsCopy(EffectQueue *eq);
273 //don't forget to set effects to NULL when the projectile discharges
274 //unexploded projectiles are responsible to destruct their payload
276 inline void SetEffects(EffectQueue *fx) {
277 effects = fx;
280 inline unsigned char GetNextFace() {
281 //slow turning
282 if (Orientation != NewOrientation) {
283 if ( ( (NewOrientation-Orientation) & (MAX_ORIENT-1) ) <= MAX_ORIENT/2) {
284 Orientation++;
285 } else {
286 Orientation--;
288 Orientation = Orientation&(MAX_ORIENT-1);
291 return Orientation;
294 inline void SetOrientation(int value, bool slow) {
295 //MAX_ORIENT == 16, so we can do this
296 NewOrientation = (unsigned char) (value&(MAX_ORIENT-1));
297 if (!slow) {
298 Orientation = NewOrientation;
302 void Setup();
303 //sets how long a created travel projectile will hover over a spot
304 //before vanishing (without the need of area extension)
305 void SetDelay(int delay);
306 void MoveTo(Map *map, const Point &Des);
307 void ClearPath();
308 //handle phases, return 0 when expired
309 int Update();
310 //draw object
311 void Draw(const Region &screen);
312 void SetGradient(int gradient, bool tint);
313 void StaticTint(const Color &newtint);
314 private:
315 //creates a child projectile with current_projectile_id - 1
316 void CreateIteration();
317 void CreateAnimations(Animation **anims, const ieResRef bam, int Seq);
318 //pillar type animations
319 void CreateCompositeAnimation(Animation **anims, AnimationFactory *af, int Seq);
320 //oriented animations (also simple ones)
321 void CreateOrientedAnimations(Animation **anims, AnimationFactory *af, int Seq);
322 void GetPaletteCopy(Animation *anim[], Palette *&pal);
323 void GetSmokeAnim();
324 void SetBlend();
325 void Payload();
326 void EndTravel();
327 void ChangePhase();
328 void AddTrail(ieResRef BAM, const ieByte *pal);
329 void DoStep(unsigned int walk_speed);
330 void LineTarget(); //line projectiles (walls, scorchers)
331 void SecondaryTarget(); //area projectiles (circles, cones)
332 void CheckTrigger(unsigned int radius);
333 void SetupWall();
334 void DrawLine(const Region &screen, int face, ieDword flag);
335 void DrawTravel(const Region &screen);
336 bool DrawChildren(const Region &screen);
337 void DrawExplosion(const Region &screen);
338 void DrawExploded(const Region &screen);
339 int GetTravelPos(int face);
340 int GetShadowPos(int face);
341 void SetPos(int face, int frame1, int frame2);
343 //logic to resolve target when single projectile hit destination
344 int CalculateTargetFlag();
345 //logic to resolve the explosion count (may be based on caster level)
346 int CalculateExplosionCount();
348 Actor *GetTarget();
349 void NextTarget(const Point &p);
350 void SetupPalette(Animation *anim[], Palette *&pal, const ieByte *gradients);
353 #endif // PROJECTILE_H