1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 *
22 * Based on the original sources
23 * Faery Tale II -- The Halls of the Dead
24 * (c) 1993-1996 The Wyrmkeep Entertainment Co.
25 */
26
27 #ifndef SAGA2_SPELSHOW_H
28 #define SAGA2_SPELSHOW_H
29
30 #include "saga2/dispnode.h"
31 #include "saga2/speldefs.h"
32
33 namespace Saga2 {
34
35 //-----------------------------------------------------------------------
36 // Effectron List
37
38 typedef DisplayNodeList EffectronList;
39
40 //-----------------------------------------------------------------------
41 // Spell control functions
42 // Various instances of these can be used in different combinations to
43 // yield different shaped spells. Each spell will need one each of
44 // these types of functions:
45 //
46 // Effectron Status
47 // This returns the state of a given effectron as a function of time
48 //
49 // Spell Spritation
50 // Returns a sprite facing as a function of time.
51 //
52 // Spell Location
53 // Returns the position of the effectron as a function of time
54 //
55 // Spell Height
56 // This is NOT the effectron's Z coordinate. It is the height used
57 // for collision detection purposes
58 //
59 // Spell Breadth
60 // This is the effectron's cross section for collision detection
61 // purposes.
62 //
63
64 //-----------------------------------------------------------------------
65 // Spell Status
66
67 typedef EffectronFlags SpellStatusFunction(Effectron *);
68
69 #define SPELLSTATUSFUNCTION(fname) EffectronFlags fname( Effectron * effectron )
70
71 //-----------------------------------------------------------------------
72 // Spell Spritation
73
74 typedef SpellPoseID SpellSpritationFunction(const Effectron *const);
75
76 #define SPELLSPRITATIONFUNCTION(fname) SpellPoseID fname( const Effectron * const effectron )
77
78 //-----------------------------------------------------------------------
79 // Spell Location Calls
80
81 typedef TilePoint SpellLocationFunction(const Effectron *const);
82
83 #define SPELLLOCATIONFUNCTION(fname) TilePoint fname( const Effectron * const effectron )
84
85 //-----------------------------------------------------------------------
86 // Spell Height
87
88 typedef spellHeight SpellHeightFunction(const Effectron *const);
89
90 #define SPELLHEIGHTFUNCTION(fname) spellHeight fname( const Effectron * const effectron )
91
92 //-----------------------------------------------------------------------
93 // Spell width
94
95 typedef spellBreadth SpellBreadthFunction(const Effectron *const);
96
97 #define SPELLBREADTHFUNCTION(fname) spellBreadth fname( const Effectron * const effectron )
98
99 //-----------------------------------------------------------------------
100 // Spell init
101
102 typedef void SpellInitFunction(Effectron *);
103
104 #define SPELLINITFUNCTION(fname) void fname( Effectron * effectron )
105
106
107 //-----------------------------------------------------------------------
108 // EffectronDisplayPrototype
109 // This tracks the functions needed to display a particular type of
110 // spell on the screen. (Ball spells, bolt spells, etc)
111 //
112
113 class EffectDisplayPrototype {
SPELLLOCATIONFUNCTION(nullLocation)114 static SPELLLOCATIONFUNCTION(nullLocation) {
115 return TilePoint(0, 0, 0);
116 }
SPELLSPRITATIONFUNCTION(nullSpritation)117 static SPELLSPRITATIONFUNCTION(nullSpritation) {
118 return 0;
119 }
SPELLSTATUSFUNCTION(nullStatus)120 static SPELLSTATUSFUNCTION(nullStatus) {
121 return effectronDead;
122 }
SPELLHEIGHTFUNCTION(nullHeight)123 static SPELLHEIGHTFUNCTION(nullHeight) {
124 return 0;
125 }
SPELLBREADTHFUNCTION(nullBreadth)126 static SPELLBREADTHFUNCTION(nullBreadth) {
127 return 0;
128 }
SPELLINITFUNCTION(nullInit)129 static SPELLINITFUNCTION(nullInit) {
130 }
131
132 EffectID ID;
133 public:
134 int16 nodeCount;
135 EffectDisplayPrototype *next;
136
137 SpellLocationFunction *location;
138 SpellSpritationFunction *spriteno;
139 SpellStatusFunction *status;
140 SpellHeightFunction *height;
141 SpellBreadthFunction *breadth;
142 SpellInitFunction *init;
143
EffectDisplayPrototype()144 EffectDisplayPrototype() {
145 nodeCount = 0;
146 next = NULL;
147 location = &nullLocation;
148 spriteno = &nullSpritation;
149 status = &nullStatus;
150 height = &nullHeight;
151 breadth = &nullBreadth;
152 init = &nullInit;
153 }
154
155 EffectDisplayPrototype(
156 int16 nodes,
157 SpellLocationFunction *newLocation,
158 SpellSpritationFunction *newSpriteno,
159 SpellStatusFunction *newStatus,
160 SpellHeightFunction *newHeight,
161 SpellBreadthFunction *newBreadth,
162 SpellInitFunction *newInit);
~EffectDisplayPrototype()163 ~EffectDisplayPrototype() {
164 if (next) delete next;
165 next = NULL;
166 }
setID(EffectID i)167 void setID(EffectID i) {
168 ID = i;
169 }
thisID(void)170 EffectID thisID(void) {
171 return ID;
172 }
173 };
174
175 typedef EffectDisplayPrototype *pEffectDisplayPrototype;
176
177 //-----------------------------------------------------------------------
178 // Effect Display Prototype List
179 //
180 // This class embodies a global list of EDPs
181 //
182
183
184 class EffectDisplayPrototypeList {
185 pEffectDisplayPrototype *effects;
186 uint16 count;
187 uint16 maxCount;
188
189 public:
190 EffectDisplayPrototypeList(int32 c);
191 ~EffectDisplayPrototypeList();
192
193 int32 add(EffectDisplayPrototype *edp) ;
194 void cleanup(void);
195 void append(EffectDisplayPrototype *edp, int32 acount);
196 EffectDisplayPrototype *operator[](EffectID e);
197 };
198
199 //-----------------------------------------------------------------------
200 // Effectron collision flags
201 //
202 // need to track whether things
203 // bounce/die/stop/ignore
204 // when hitting
205 // actors/objects/terrain
206 //
207
208 enum effectCollisionCont {
209 ecFlagNone = 0,
210 ecFlagBounce,
211 ecFlagDie,
212 ecFlagStop
213 };
214
215 enum effectDirectionInit {
216 diFlagZero = 0,
217 diFlagInc = 1,
218 diFlagInc2 = 2,
219 diFlagInc3 = 3,
220 diFlagInc4 = 4,
221 diFlagRand = 5
222 };
223
224
225 //-----------------------------------------------------------------------
226 // SpellDisplayPrototype
227 // All the information needed to display a spell
228 // Combines a SpellEffectPrototype with the appropriate sprites
229
230 class SpellDisplayPrototype {
231 SpellID ID;
232 public:
233 EffectID effect; // Effect ID
234 int32 effParm1; // effect setting 1
235 int32 effParm2; // effect setting 1
236 int32 effParm3; // effect setting 1
237 int32 effParm4; // effect setting 1
238
239 effectDirectionInit scatter; // direction init mode
240 effectCollisionCont elasticity; // collision flags
241
242 SpellAge maxAge; // auto self-destruct age
243 SpellAge implementAge; // auto self-destruct age
244 uint32 primarySpriteID; // RES_ID(x, y, z, 0) to get sprites
245 uint8 primarySpriteNo; // sprites available
246 uint32 secondarySpriteID; // RES_ID(x, y, z, 0) to get sprites
247 uint8 secondarySpriteNo; // sprites available
248 //uint8 effCount; // effectrons to allocate
249
250 uint8 colorMap[4]; // indirect color map
251 // full init
252 SpellDisplayPrototype(
253 EffectID, int32, int32, int32, int32, effectDirectionInit,
254 effectCollisionCont, SpellAge, uint32, uint8, uint8);
255
256 SpellDisplayPrototype(ResourceSpellItem *rsi);
257
258 void getColorTranslation(ColorTable mainColors, Effectron *); // colors for effectrons
setID(SpellID i)259 void setID(SpellID i) {
260 ID = i;
261 }
thisID(void)262 SpellID thisID(void) {
263 return ID;
264 }
265 };
266
267 //-----------------------------------------------------------------------
268 // SpellDisplayPrototypeList
269 // A global list of sdp's
270
271 typedef SpellDisplayPrototype *pSpellDisplayPrototype;
272
273 class SpellDisplayPrototypeList {
274 pSpellDisplayPrototype *spells;
275 uint16 count;
276 uint16 maxCount;
277
278 public:
279 SpellDisplayPrototypeList(uint16 s);
280 ~SpellDisplayPrototypeList();
281
282 void init(void);
283 void cleanup(void);
284 int32 add(SpellDisplayPrototype *sdp);
285 SpellDisplayPrototype *operator[](SpellID s);
286 };
287
288 //-----------------------------------------------------------------------
289 // SpellInstance
290 // When a SpellDisplayPrototype is instantiated, one of these is created
291 // and the main display loop updates it till it dies
292
293 class SpellInstance {
294 friend struct StorageSpellInstance;
295
296 SpellAge implementAge; // age at which to implement the spell effects
297 public:
298 EffectDisplayPrototype *effect; // effect prototype of the current effect
299 SpellDisplayPrototype *dProto; // effect prototype of the current effect
300 SpellCaster *caster;
301 SpellTarget *target;
302 GameWorld *world;
303 SpellAge age;
304 EffectronList eList;
305 SpellID spell;
306 SpellAge maxAge;
307 int16 effSeq; // which effect in a sequence is being played
308
309 SpellInstance(SpellCaster *newCaster, SpellTarget *newTarget, SpellID);
310 SpellInstance(SpellCaster *newCaster, GameObject &newTarget, SpellID);
311 SpellInstance(SpellCaster *newCaster, GameObject *newTarget, SpellID);
312 SpellInstance(SpellCaster *newCaster, TilePoint &newTarget, SpellID);
313 SpellInstance(StorageSpellInstance &ssi);
314 ~SpellInstance();
315
316 void init(void);
317 void initEffect(TilePoint);
318 void readEffect(Common::InSaveFile *in, uint16 eListSize);
319 void writeEffect(Common::MemoryWriteStreamDynamic *out);
320 void termEffect(void);
321 size_t saveSize(void);
322
323 bool buildList(void);
324 bool updateStates(int32 deltaTime);
325 };
326
327 //-----------------------------------------------------------------------
328 // SpellDisplayList
329 // This class is used to keep track of all the spells currently
330 // displaying effectrons
331
332 typedef SpellInstance *pSpellInstance;
333
334 class SpellDisplayList {
335 uint16 count;
336 uint16 maxCount;
337 public :
338 pSpellInstance *spells;
339
340 void init(void);
341 void cleanup(void);
342 SpellDisplayList(uint16 s);
343 ~SpellDisplayList();
344
345 void add(SpellInstance *newSpell);
346
347 void tidyKill(uint16 spellNo);
348
349 void buildList(void);
350 void updateStates(int32 deltaTime);
351
352 void write(Common::OutSaveFile *outD);
353 void read(Common::InSaveFile *in);
354 void wipe(void);
355 size_t saveSize(void);
356 };
357
358
359 /* ===================================================================== *
360 Inlines
361 * ===================================================================== */
362
363 //-----------------------------------------------------------------------
364 // Some functions that require the above definitions to work
365
world(void)366 inline GameWorld *Effectron::world(void) const {
367 return parent->world;
368 }
getMapNum(void)369 inline int16 Effectron::getMapNum(void) const {
370 return parent->world->mapNum;
371 }
372
spellID(void)373 inline EffectID Effectron::spellID(void) {
374 return parent->spell;
375 }
spell(void)376 inline SpellDisplayPrototype *Effectron::spell(void) {
377 return (*g_vm->_sdpList)[(SpellID) spellID()];
378 }
effectID(void)379 inline EffectID Effectron::effectID(void) {
380 return spell()->effect;
381 }
effect(void)382 inline EffectDisplayPrototype *Effectron::effect(void) {
383 return parent->effect;
384 }
staCall(void)385 inline EffectronFlags Effectron::staCall(void) {
386 return parent->effect->status(this);
387 }
posCall(void)388 inline TilePoint Effectron::posCall(void) {
389 return parent->effect->location(this);
390 }
sprCall(void)391 inline SpellSpritationSeed Effectron::sprCall(void) {
392 return parent->effect->spriteno(this);
393 }
hgtCall(void)394 inline spellHeight Effectron::hgtCall(void) {
395 return parent->effect->height(this);
396 }
brdCall(void)397 inline spellBreadth Effectron::brdCall(void) {
398 return parent->effect->breadth(this);
399 }
initCall(int16 eno)400 inline void Effectron::initCall(int16 eno) {
401 partno = eno;
402 parent->effect->init(this);
403 }
404
405 /* ===================================================================== *
406 prototypes
407 * ===================================================================== */
408
409 int16 whichColorMap(EffectID eid, const Effectron *const effectron);
410
411 //-----------------------------------------------------------------------
412 // Spell building block functions
413 // These are the functions available to update various aspects
414 // of Effectrons
415
416 SPELLSTATUSFUNCTION(invisibleSpellSta);
417 SPELLSTATUSFUNCTION(auraSpellSta);
418 SPELLSTATUSFUNCTION(projectileSpellSta);
419 SPELLSTATUSFUNCTION(exchangeSpellSta);
420 SPELLSTATUSFUNCTION(boltSpellSta);
421 SPELLSTATUSFUNCTION(coneSpellSta);
422 SPELLSTATUSFUNCTION(ballSpellSta);
423 SPELLSTATUSFUNCTION(squareSpellSta);
424 SPELLSTATUSFUNCTION(waveSpellSta);
425 SPELLSTATUSFUNCTION(stormSpellSta);
426 SPELLSTATUSFUNCTION(beamSpellSta);
427 SPELLSTATUSFUNCTION(wallSpellSta);
428
429 SPELLLOCATIONFUNCTION(invisibleSpellPos);
430 SPELLLOCATIONFUNCTION(auraSpellPos);
431 SPELLLOCATIONFUNCTION(projectileSpellPos);
432 SPELLLOCATIONFUNCTION(exchangeSpellPos);
433 SPELLLOCATIONFUNCTION(boltSpellPos);
434 SPELLLOCATIONFUNCTION(coneSpellPos);
435 SPELLLOCATIONFUNCTION(ballSpellPos);
436 SPELLLOCATIONFUNCTION(squareSpellPos);
437 SPELLLOCATIONFUNCTION(waveSpellPos);
438 SPELLLOCATIONFUNCTION(stormSpellPos);
439 SPELLLOCATIONFUNCTION(beamSpellPos);
440 SPELLLOCATIONFUNCTION(wallSpellPos);
441 SPELLLOCATIONFUNCTION(glowSpellPos);
442
443 SPELLSPRITATIONFUNCTION(invisibleSprites);
444 SPELLSPRITATIONFUNCTION(auraSprites);
445 SPELLSPRITATIONFUNCTION(projectileSprites);
446 SPELLSPRITATIONFUNCTION(exchangeSprites);
447 SPELLSPRITATIONFUNCTION(boltSprites);
448 SPELLSPRITATIONFUNCTION(coneSprites);
449 SPELLSPRITATIONFUNCTION(ballSprites);
450 SPELLSPRITATIONFUNCTION(squareSprites);
451 SPELLSPRITATIONFUNCTION(waveSprites);
452 SPELLSPRITATIONFUNCTION(stormSprites);
453 SPELLSPRITATIONFUNCTION(beamSprites);
454 SPELLSPRITATIONFUNCTION(wallSprites);
455
456 SPELLHEIGHTFUNCTION(ShortTillThere);
457 SPELLHEIGHTFUNCTION(GrowLinear);
458 SPELLBREADTHFUNCTION(StaticHeight);
459
460 SPELLBREADTHFUNCTION(ThinTillThere);
461 SPELLBREADTHFUNCTION(BulkLinear);
462 SPELLBREADTHFUNCTION(StaticBreadth);
463
464 SPELLINITFUNCTION(invisibleSpellInit);
465 SPELLINITFUNCTION(auraSpellInit);
466 SPELLINITFUNCTION(projectileSpellInit);
467 SPELLINITFUNCTION(exchangeSpellInit);
468 SPELLINITFUNCTION(boltSpellInit);
469 SPELLINITFUNCTION(coneSpellInit);
470 SPELLINITFUNCTION(ballSpellInit);
471 SPELLINITFUNCTION(squareSpellInit);
472 SPELLINITFUNCTION(waveSpellInit);
473 SPELLINITFUNCTION(stormSpellInit);
474 SPELLINITFUNCTION(glowSpellInit);
475 SPELLINITFUNCTION(beamSpellInit);
476 SPELLINITFUNCTION(wallSpellInit);
477
478 } // end of namespace Saga2
479
480 #endif //SPELLBUK_H
481