File: effects.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (558 lines) | stat: -rw-r--r-- 17,565 bytes parent folder | download | duplicates (2)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Based on the original sources
 *   Faery Tale II -- The Halls of the Dead
 *   (c) 1993-1996 The Wyrmkeep Entertainment Co.
 */

#ifndef SAGA2_EFFECTS_H
#define SAGA2_EFFECTS_H

#include "saga2/dice.h"

namespace Saga2 {

class Actor;
class GameObject;

// ------------------------------------------------------------------
// Effects of spells and other things

//
// 1 Enchantments
//   A Object (non-Actor) Enchantments
//       Object : There aren't a lot of these
//   B Actor Enchantments
//       Attrib : affects attributes of actors
//       Resist : Enable resistance to various things
//       Immune : Enable immunity to various things
//       Others : Misc flags
//	 C Player Enchantments
//       Player : Flags that really only affect players
// 2 Effects
//   A General effects
//       Damage : does damage of various types
//   B Actor only effects
//       Drains : mana drains, money drains, food drains
//       Special : must be handled manually
//   C TAG effects : There aren't many of these
//   D Global Effects : Effects that have significant effect on the game engine
//

enum effectTypes {
	kEffectNone          = 0, // no functional effect
	kEffectAttrib,            // (enchant) affects attributes of actors
	kEffectResist,            // (enchant) Enable resistance to various things
	kEffectImmune,            // (enchant) Enable immunity to various things
	kEffectOthers,            // (enchant) Enable immunity to various things
	kEffectNonActor,          // (enchant) change an object
	kEffectPoison,            // (enchant) change an object
//  Effect types greater than 8 cannot be enchantments
	kEffectDamage        = 8,   // does damage of various types
	kEffectDrains,            // mana drain, money drain
	kEffectTAG,               // mana drain, money drain
	kEffectLocation,          // mana drain, money drain
	kEffectSpecial,
	kEffectStrike            // weapon strike effect
};


//
// Resistance Effects - these correspond exactly to the Damage types
//   A separate enum is defined to permit differentiation between
//   damage, resistance, and immunity effects
//

enum effectResistTypes {
	kResistOther     = kDamageOther,
	// Combat resist
	kResistImpact    = kDamageImpact,
	kResistSlash     = kDamageSlash,
	kResistProjectile = kDamageProjectile,
	// Magic resist
	kResistFire      = kDamageFire,
	kResistAcid      = kDamageAcid,
	kResistHeat      = kDamageHeat,
	kResistCold      = kDamageCold,
	kResistLightning = kDamageLightning,
	kResistPoison    = kDamagePoison,
	// Other magic resist
	kResistMental    = kDamageMental,
	kResistToUndead  = kDamageToUndead,
	kResistDirMagic  = kDamageDirMagic,
	// Physiological Damage
	kResistStarve    = kDamageStarve,
	// other
	kResistEnergy    = kDamageEnergy
};

//
// Immunity Effects - See the notes for resistance effects
//

// Types of damage an effect can give immunity to
enum effectImmuneTypes {
	kImmuneOther     = kResistOther,
	// Combat imm
	kImmuneImpact    = kResistImpact,
	kImmuneSlash     = kResistSlash,
	kImmuneProjectile = kResistProjectile,
	// Magic immu
	kImmuneFire      = kResistFire,
	kImmuneAcid      = kResistAcid,
	kImmuneHeat      = kResistHeat,
	kImmuneCold      = kResistCold,
	kImmuneLightning = kResistLightning,
	kImmunePoison    = kResistPoison,
	// Other magimune
	kImmuneMental    = kResistMental,
	kImmuneToUndead  = kResistToUndead,
	kImmuneDirMagic  = kResistDirMagic,
	// PhysiologiDamage
	kImmuneStarve    = kResistStarve,
	// other
	kImmuneEnergy    = kResistEnergy
};

//
// Other Effects - general flags in the actor structure most of which
//   aren't hooked up to anything.
//

enum effectOthersTypes {
	// Movement flags
	kActorNoncorporeal   = 1,    // The creature can walk through things
	kActorWaterBreathe   = 2,    // death spell
	kActorSlowFall       = 3,    // the creature is not harmed by falling (but falls none the less)
	kActorLevitate       = 4,    // flying with no height control ?
	kActorFlying         = 5,    // the creature flys
	// speed flags
	kActorFastMove       = 6,    //
	kActorFastAttack     = 7,    //
	kActorSlowAttack     = 8,    // come... back... here... lit... tle... bun... ny...

	kActorImmobile       = 9,    // I thought I told you to leave the piano at home
	// ill effects
	kActorAsleep         = 10,   // Zzzzzzzzzzz
	kActorParalyzed      = 11,   // the creature can't move an inch
	kActorFear           = 12,   // run away! run away
	kActorDiseased       = 13,   // cannot heal
	kActorPoisoned       = 14,   // death spell
	// perception & perceivability flags
	kActorBlind          = 15,   // can't see
	kActorSeeInvis       = 16,   // can see invisible
	kActorClairvoyant    = 17,  // unknown effects
	kActorInvisible      = 18,   // is invisible
	kActorUndetectable   = 19,   // can't be seen, smelled
	kActorDetPoison      = 20,   // poison things glow green
	// flags preventing changes to other flags
	kActorNoEnchant      = 21,   // no bad enchantments
	kActorNoDrain        = 22,   // no mana / food drains
	// flags that make things run away
	kActorRepelEvil      = 23,   // death spell
	kActorRepelGood      = 24,   // death spell
	kActorRepelUndead    = 25,   // death spell
	// miscellaneous
	kActorNotDefenseless = 26,   // forgo defenselessness check
	kActorDisappearOnDeath = 27, // gets deleted on death and spews inventory
	// dead or moved flags
	kActorWaterWalk           // can walk on water (same as float ?)
};

//
// Drains Effects - these correspond to values in the actor that are
//   drained & replenished
//

enum effectDrainsTypes {
	// mana pools
	kDrainsManaRed       = 1,
	kDrainsManaOrange,
	kDrainsManaYellow,
	kDrainsManaGreen,
	kDrainsManaBlue,
	kDrainsManaViolet,
	kDrainsLifeLevel,
	kDrainsVitality,
	kDrainsMoney
};


//
// TAG Effects - effects that apply when a TAG is the target
//

enum effectTAGTypes {
	kSettagLocked        = 1,
	kSettagOpen          = 2
};


//
// Location Effects - effects that apply when a Location is the target
//

enum kEffectLocationTypes {
	kLocateDummy         = 1
};

enum objectFlags {
	kObjectOpen          = (1 << 0),     // object is in the "open" state
	kObjectLocked        = (1 << 1),     // object cannot be opened
	kObjectImportant     = (1 << 2),     // object must be recycled when trashed
	kObjectGhosted       = (1 << 3),     // object drawn translucent
	kObjectInvisible     = (1 << 4),     // object cannot be seen
	kObjectObscured      = (1 << 5),     // object obscured by terrain
	kObjectMoving        = (1 << 6),     // object has attached motion task
	kObjectScavengable   = (1 << 7),     // object can be deleted
	kObjectFloating      = (1 << 8),     // object not affected by Gravity
	kObjectNoRecycle     = (1 << 9),     // object is referred to by script, don't delete
	kObjectActivated     = (1 << 10),    // object is activated
	kObjectAlias         = (1 << 11),    // object is not real, just a copy of another object
	kObjectTriggeringTAG = (1 << 12),    // object has triggerred TAG upon which it rests
	kObjectOnScreen      = (1 << 13),    // object is on display list
	kObjectSightedByCenter = (1 << 14)   // there is a line of sight to center actor
};


//
// Special Effects - these are spells that need to be handled manually
//

enum effectSpecialTypes {
	kSpecialDispellHelpfulEnch = 1,   // clears helpful enchantments
	kSpecialDispellHarmfulEnch,       // clears harmful enchantments
	kSpecialKill,                     // death spell
	kSpecialRessurect,                // raise dead spell
	kSpecialTeleport,                 // Teleportation
	kSpecialCreateActor,              // Create an actor or wall
	kSpecialSagaFunc,                 // calls a saga function
	kSpecialCreateWWisp,              // calls a saga function
	kSpecialCreateFWisp,              // calls a saga function
	kSpecialCreateWraith,             // calls a saga function
	kSpecialCreateFood,               // calls a saga function
	kSpecialRejoin
};

// ------------------------------------------------------------------
// ENCHANTMENT IDs
// It is necessary to combine all these possibilities into a 16 bit integer
// Here's how its mapped
//   3 bits - general effect type
//   5 bits - sub class enum value
//   8 bits - damage amount, boolean on/off etc.
//

inline uint16 makeEnchantmentID(uint16 type, uint16 damtyp, int16 damamt) {
	assert(type < 8);
	assert(damtyp < 32);
	assert(damamt < 128 && damamt > -128);
	return ((type << 13) | (damtyp << 8)) + (damamt + 128);
}

/* skill*  are now in the spellid enum ;AS;
inline uint16 makeEnchantmentID(effectAttribTypes atttyp, int16 damamt)
    {   return (kEffectAttrib << 13) | (atttyp << 8) + (damamt+128); }
*/

inline uint16 makeEnchantmentID(effectResistTypes restyp, bool damamt) {
	return ((kEffectResist << 13) | (restyp << 8)) + (damamt + 128);
}

inline uint16 makeEnchantmentID(effectImmuneTypes immtyp, bool damamt) {
	return ((kEffectImmune << 13) | (immtyp << 8)) + (damamt + 128);
}

inline uint16 makeEnchantmentID(effectOthersTypes othtyp, bool damamt) {
	return ((kEffectOthers << 13) | (othtyp << 8)) + (damamt + 128);
}

inline uint16 makeEnchantmentID(objectFlags othtyp, bool damamt) {
	return ((kEffectNonActor << 13) | (othtyp << 8)) + (damamt + 128);
}

inline uint16 makeEnchantmentID(uint8 damamt) {
	return ((kEffectPoison << 13) | (0 << 8)) + damamt;
}

inline effectTypes getEnchantmentType(uint16 eID) {
	return (effectTypes)(eID >> 13);
}

inline uint16 getEnchantmentSubType(uint16 eID) {
	return (eID >> 8) & 0x1F;
}

inline int16 getEnchantmentAmount(uint16 eID) {
	return (eID & 0xFF) - 128;
}

// ------------------------------------------------------------------
// Determine whether an enchantment is harmful

inline bool isHarmful(uint16 enchID) {
	int16 typ = getEnchantmentType(enchID);
	int16 sub = getEnchantmentSubType(enchID);
	int16 amt = getEnchantmentAmount(enchID);
	if (typ == kEffectAttrib)  return amt < 0;
	if (typ == kEffectOthers)
		return (sub >= kActorSlowAttack && sub <= kActorBlind);
	return false;
}

// ------------------------------------------------------------------
// Determine whether an enchantment can fail

inline bool isSaveable(uint16 enchID) {
	int16 typ = getEnchantmentType(enchID);
	return (typ == kEffectOthers && isHarmful(enchID));
}

// ------------------------------------------------------------------
//  Determine whether a damage type is magical

inline bool isMagicDamage(effectDamageTypes t) {
	return t >= kDamageFire && t <= kDamageDirMagic;
}

#define Forever (255)

class SpellTarget;

//-------------------------------------------------------------------
// ProtoEffects

//   This is the base class of several spell effect prototype classes
//     The implement routine carries out the instantiation of a
//     particular effect on a given target (doing damage or whatever)


class ProtoEffect {
	//protected:
	//int imp;                // enchant or immediate

public:
	ProtoEffect *_next;                      // pointer to additional effects

	ProtoEffect() {
		_next = NULL;
	}
	virtual ~ProtoEffect() {
		if (_next) delete _next;
		_next = NULL;
	}
	//int implementation( void ) { return imp; }
	virtual bool applicable(SpellTarget &) {
		return false;
	}
	virtual void implement(GameObject *, SpellTarget *, int8 = 0) {}
};


//-------------------------------------------------------------------
// ProtoDamage
//   This class of effects does a range of damage to the target

class ProtoDamage: public ProtoEffect {
	effectDamageTypes   _type;               // damage type
	int8                _dice,               // # of dice to roll
	                    _sides,              // # of sides on dice
	                    _skillDice,          // multiply by spellcraft to get additional dice
	                    _base,               // absolute damage amount
	                    _skillBase;          // absolute damage amount
	int8                _self;               // casts at self

public:

	ProtoDamage(int8 d, int8 s, int8 sd, int8 b, effectDamageTypes t, int, bool afSelf = false, int8 sb = 0) {
		_type = t;
		_dice = d;
		_sides = s;
		_skillDice = sd;
		_base = b;
		_self = afSelf;
		_skillBase = sb;
	}

	bool applicable(SpellTarget &trg);

	void implement(GameObject *cst, SpellTarget *trg, int8 deltaDamage = 0);

	static int16 getRelevantStat(effectDamageTypes dt, Actor *a);
};

//-------------------------------------------------------------------
// ProtoDrainage
//   This class of effects does a range of damage to the target's
//   mana, money or food supply

class ProtoDrainage: public ProtoEffect {
	effectDrainsTypes   _type;               // damage type
	int8                _dice,               // # of dice to roll
	                    _sides,              // # of sides on dice
	                    _skillDice,          // multiply by spellcraft to get additional dice
	                    _base;               // absolute damage amount
	int8                _self;               // casts at self

public:

	ProtoDrainage(int8 d, int8 s, int8 sd, int8 b, effectDrainsTypes t, int, bool afSelf = false) {
		_type = t;
		_dice = d;
		_sides = s;
		_skillDice = sd;
		_base = b;
		_self = afSelf;
	}

	bool applicable(SpellTarget &trg);

	void implement(GameObject *cst, SpellTarget *trg, int8 deltaDamage = 0);

	static int16 currentLevel(Actor *a, effectDrainsTypes edt);
	static void drainLevel(GameObject *cst, Actor *a, effectDrainsTypes edt, int16 amt);
};

//-------------------------------------------------------------------
// ProtoEnchantment
//   This can be any of several types of enchantments (see EFFECTS.H)
//

class ProtoEnchantment: public ProtoEffect {
	uint16              _enchID;
	uint32              _minEnch;
	RandomDice          _dice;               // enchantment time

public:
	ProtoEnchantment(uint16 e, uint32 loTime, uint32 hiTime) {
		_enchID = e;
		_dice = RandomDice(1, hiTime - loTime);
		_minEnch = loTime;
	}

	bool applicable(SpellTarget &trg);

	void implement(GameObject *, SpellTarget *trg, int8 deltaDamage = 0);

	bool canFail() {
		return isSaveable(_enchID);
	}

	static bool realSavingThrow(Actor *a);
};

//-------------------------------------------------------------------
// ProtoTAGEffect
//   this type of spell sets up spells that are used to alter tags

class ProtoTAGEffect: public ProtoEffect {
	effectTAGTypes      _affectBit;
	int16               _onOff;       // lock/unlock or trigger ID
	ObjectID            _trigger;

public:
	ProtoTAGEffect(effectTAGTypes ett, int16 v, ObjectID t) {
		_affectBit = ett;
		_onOff = v;
		_trigger = t;
	}

	bool applicable(SpellTarget &trg);

	void implement(GameObject *, SpellTarget *trg, int8 deltaDamage = 0);
};

//-------------------------------------------------------------------
// ProtoObjectEffect
//   These effects are used only on non-actor objects.

class ProtoObjectEffect: public ProtoEffect {
	uint16              _affectBit;
	int16               _onOff;
	RandomDice          _dice;               // enchantment time

public:
	ProtoObjectEffect(uint16 e, int16 v, uint32 loT, uint32 hiT) {
		_affectBit = e;
		_onOff = v;
		_dice = RandomDice(loT, hiT);
	}

	bool applicable(SpellTarget &trg);

	void implement(GameObject *, SpellTarget *trg, int8 deltaDamage = 0);
};

//-------------------------------------------------------------------
// If spells ever need to do things to Locations this
// is where they'll be

class ProtoLocationEffect: public ProtoEffect {
	kEffectLocationTypes _affectBit;
	int16               _value;

public:
	ProtoLocationEffect(kEffectLocationTypes elt, int16 v) {
		_affectBit = elt;
		_value = v;
	}

	bool applicable(SpellTarget &)  {
		return (true);
	}

	void implement(GameObject *, SpellTarget *trg, int8 deltaDamage = 0);
};

//-------------------------------------------------------------------
// ProtoSpecialEffects
//   As always there are spells that just don't fit any of the other
//   molds. These protoEffects allow customized spell handlers to be
//   implemented.
//

typedef void SPELLIMPLEMENTATION(GameObject *, SpellTarget *);

#define SPECIALSPELL(name) void name(GameObject *cst, SpellTarget *trg)

class ProtoSpecialEffect: public ProtoEffect {
	int16 _routineID;
	SPELLIMPLEMENTATION *_handler;

public:
	ProtoSpecialEffect(SPELLIMPLEMENTATION *newHandler, int16 callID = 0) {
		_handler = newHandler;
		_routineID = callID;
	}

	bool applicable(SpellTarget &) {
		return true;
		//return (trg.getType()==SpellTarget::kSpellTargetObject ||
		//       trg.getType()==SpellTarget::kSpellTargetObjectPoint) &&
		//     isActor(trg.getObject());
	}

	void implement(GameObject *, SpellTarget *trg, int8 deltaDamage = 0);
};

} // end of namespace Saga2

#endif