1 /* GemRB - Infinity Engine Emulator
2  * Copyright (C) 2003 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 Effect.h
23  * Declares Effect class implementing spell and spell-like effects
24  * and related defines
25  */
26 
27 #ifndef EFFECT_H
28 #define EFFECT_H
29 
30 #include "ie_types.h"
31 
32 #include "Region.h"
33 
34 namespace GemRB {
35 
36 class Actor;
37 
38 //local variables in creatures are stored in fake opcodes
39 #define FAKE_VARIABLE_OPCODE 187
40 #define FAKE_VARIABLE_MARKER 1
41 
42 // Effect target types
43 #define FX_TARGET_UNKNOWN    0
44 #define FX_TARGET_SELF       1
45 #define FX_TARGET_PRESET     2
46 #define FX_TARGET_PARTY      3
47 #define FX_TARGET_ALL        4
48 #define FX_TARGET_ALL_BUT_PARTY   5
49 #define FX_TARGET_OWN_SIDE   6
50 #define FX_TARGET_OTHER_SIDE 7
51 #define FX_TARGET_ALL_BUT_SELF 8
52 #define FX_TARGET_ORIGINAL   9
53 
54 // Effect duration/timing types
55 #define FX_DURATION_INSTANT_LIMITED          0
56 #define FX_DURATION_INSTANT_PERMANENT        1
57 #define FX_DURATION_INSTANT_WHILE_EQUIPPED   2
58 #define FX_DURATION_DELAY_LIMITED            3 //this contains a relative onset time (delay) also used as duration, transforms to 0 when applied
59 #define FX_DURATION_DELAY_PERMANENT          4 //this transforms to 9 (i guess)
60 #define FX_DURATION_DELAY_UNSAVED            5 //this transforms to 8
61 #define FX_DURATION_DELAY_LIMITED_PENDING    6 //this contains an absolute onset time and a duration
62 #define FX_DURATION_AFTER_EXPIRES            7 //this is a delayed non permanent effect (resolves to JUST_EXPIRED)
63 #define FX_DURATION_PERMANENT_UNSAVED        8
64 #define FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES   9//this is a special permanent
65 #define FX_DURATION_INSTANT_LIMITED_TICKS    10 // same as 0, but in ticks instead of seconds
66 #define FX_DURATION_JUST_EXPIRED             (FX_DURATION_INSTANT_LIMITED_TICKS + 1) // internal
67 #define MAX_TIMING_MODE                      (FX_DURATION_JUST_EXPIRED + 1)
68 #define FX_DURATION_ABSOLUTE                 0x1000
69 
70 // Effect resistance types
71 #define FX_NO_RESIST_NO_DISPEL      0
72 #define FX_CAN_DISPEL               1
73 #define FX_CAN_RESIST_CAN_DISPEL     1
74 //#define FX_CAN_RESIST_NO_DISPEL     2   //same as 0 (not resistable, not dispellable)
75 #define FX_NO_RESIST_CAN_DISPEL    3
76 #define FX_NO_RESIST_BYPASS_BOUNCE 4 // TODO: EE bit to bypass deflection/reflection/trap opcodes
77 #define FX_NO_RESIST_SELF_TARGETED 8 // TODO: EE bit to fix an exploit, see IESDP
78 // unused gap
79 #define FX_SET_BY_ITEM 0x80000000 // TODO: EE bit for opcode 324, perhaps not needed (use SourceType?)
80 
81 // Effect save flags (ToBEx)
82 #define SF_BYPASS_MIRROR_IMAGE 0x1000000
83 #define SF_IGNORE_DIFFICULTY   0x2000000
84 
85 /**
86  * @class Effect
87  * Structure holding information about single spell or spell-like effect.
88  */
89 
90 // the same as ITMFeature and SPLFeature
91 struct Effect {
92 	ieDword Opcode;
93 	ieDword Target;
94 	ieDword Power;
95 	ieDword Parameter1;
96 	ieDword Parameter2;
97 	ieWord TimingMode;   //0x1000 -- no need of conversion
98 	ieWord unknown2;
99 	ieDword Resistance;
100 	ieDword Duration;
101 	ieWord ProbabilityRangeMax;
102 	ieWord ProbabilityRangeMin;
103 	//keep these four in one bunch, VariableName will
104 	//spread across them
105 	ieResRef Resource;
106 	ieResRef Resource2; //vvc in a lot of effects
107 	ieResRef Resource3;
108 	ieResRef Resource4;
109 	ieDword DiceThrown;
110 	ieDword DiceSides;
111 	ieDword SavingThrowType;
112 	ieDword SavingThrowBonus;
113 	ieWord IsVariable;
114 	ieWord IsSaveForHalfDamage;
115 
116 	// EFF V2.0 fields:
117 	ieDword PrimaryType; //school
118 	ieDword MinAffectedLevel;
119 	ieDword MaxAffectedLevel;
120 	ieDword Parameter3;
121 	ieDword Parameter4;
122 	ieDword Parameter5;
123 	ieDword Parameter6;
124 	ieDword SourceX, SourceY;
125 	ieDword PosX, PosY;
126 	ieDword SourceType; //1-item, 2-spell
127 	ieResRef Source;
128 	ieDword SourceFlags;
129 	ieDword Projectile;          //9c
130 	ieDwordSigned InventorySlot; //a0
131 	//Original engine had a VariableName here, but it is stored in the resource fields
132 	ieDword CasterLevel;  //c4 in both
133 	ieDword FirstApply;   //c8 in bg2, cc in iwd2
134 	ieDword SecondaryType;
135 	ieDword SecondaryDelay; //still not sure about this
136 	ieDword CasterID;       //10c in bg2 (not saved?)
137 	// These are not in the IE files, but are our precomputed values
138 	ieDword random_value;
139 
140 	ieDword SpellLevel; // Power does not always contain the Source level, which is needed in iwd2; items will be left at 0
141 public:
142 	//don't modify position in case it was already set
SetPositionEffect143 	void SetPosition(const Point &p) {
144 		if(PosX==0xffffffff && PosY==0xffffffff) {
145 			PosX=p.x;
146 			PosY=p.y;
147 		}
148 	}
SetSourcePositionEffect149 	void SetSourcePosition(const Point &p) {
150 		if(SourceX==0xffffffff && SourceY==0xffffffff) {
151 			SourceX=p.x;
152 			SourceY=p.y;
153 		}
154 	}
155 };
156 
157 }
158 
159 #endif  // ! EFFECT_H
160