1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 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 #include "ie_feats.h" //cannot avoid declaring these
22 #include "opcode_params.h"
28 #include "DisplayMessage.h"
29 #include "EffectQueue.h"
32 #include "Interface.h"
33 #include "Projectile.h" //needs for clearair
34 #include "TileMap.h" //needs for knock!
36 #include "GameScript/GSUtils.h" //needs for MoveBetweenAreasCore
37 #include "GUI/GameControl.h"
38 #include "Scriptable/Actor.h"
40 //FIXME: find a way to handle portrait icons better
51 #define PI_HOPELESS 44
52 #define PI_LEVELDRAIN 53
53 #define PI_FEEBLEMIND 54
60 #define PI_BLOODRAGE 76 //iwd2
63 #define PI_STONESKIN 80
64 #define PI_DEAFNESS 83 //iwd2
65 #define PI_SEQUENCER 92
67 #define PI_IMPROVEDHASTE 110
68 #define PI_SPELLTRAP 117
69 #define PI_CSHIELD 162
70 #define PI_CSHIELD2 163
72 static ieResRef
*casting_glows
= NULL
;
73 static int cgcount
= -1;
74 static ieResRef
*spell_hits
= NULL
;
75 static bool enhanced_effects
= false;
76 static int shcount
= -1;
77 static int *spell_abilities
= NULL
;
78 static ieDword splabcount
= 0;
79 static int *polymorph_stats
= NULL
;
80 static int polystatcount
= 0;
82 //the original engine stores the colors in sprklclr.2da in a different order
84 #define SPARK_COUNT 13
86 static int spark_color_indices
[SPARK_COUNT
]={12,5,0,6,1,8,2,7,9,3,4,10,11};
88 static ScriptedAnimation default_spell_hit
;
90 int fx_ac_vs_damage_type_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//00
91 int fx_attacks_per_round_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//01
92 int fx_cure_sleep_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//02
93 int fx_set_berserk_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//03
94 int fx_cure_berserk_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//04
95 int fx_set_charmed_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//05
96 int fx_charisma_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//06
97 int fx_set_color_gradient (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//07
98 int fx_set_color_rgb (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//08
99 int fx_set_color_rgb_global (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//08
100 int fx_set_color_pulse_rgb (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//09
101 int fx_set_color_pulse_rgb_global (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//09
102 int fx_constitution_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//0a
103 int fx_cure_poisoned_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//0b
104 int fx_damage (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//0c
105 int fx_death (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//0d
106 int fx_cure_frozen_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//0e
107 int fx_dexterity_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//0f
108 int fx_set_hasted_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//10
109 int fx_current_hp_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//11
110 int fx_maximum_hp_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//12
111 int fx_intelligence_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//13
112 int fx_set_invisible_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//14
113 int fx_lore_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//15
114 int fx_luck_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//16
115 int fx_morale_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//17
116 int fx_set_panic_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//18
117 int fx_set_poisoned_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//19
118 int fx_remove_curse (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//1a
119 int fx_acid_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//1b
120 int fx_cold_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//1c
121 int fx_electricity_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//1d
122 int fx_fire_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//1e
123 int fx_magic_damage_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//1f
124 int fx_cure_dead_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//20
125 int fx_save_vs_death_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//21
126 int fx_save_vs_wands_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//22
127 int fx_save_vs_poly_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//23
128 int fx_save_vs_breath_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//24
129 int fx_save_vs_spell_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//25
130 int fx_set_silenced_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//26
131 int fx_set_unconscious_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//27
132 int fx_set_slowed_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//28
133 int fx_sparkle(Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//29
134 int fx_bonus_wizard_spells (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//2a
135 int fx_cure_petrified_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//2b
136 int fx_strength_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//2c
137 int fx_set_stun_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//2d
138 int fx_cure_stun_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//2e
139 int fx_cure_invisible_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//2f
140 int fx_cure_silenced_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//30
141 int fx_wisdom_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//31
142 int fx_brief_rgb (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//32
143 int fx_darken_rgb (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//33
144 int fx_glow_rgb (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//34
145 int fx_animation_id_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//35
146 int fx_to_hit_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//36
147 int fx_kill_creature_type (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//37
148 int fx_alignment_invert (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//38
149 int fx_alignment_change (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//39
150 int fx_dispel_effects (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//3a
151 int fx_stealth_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//3b
152 int fx_miscast_magic_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//3c
153 int fx_alchemy_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//3d
154 int fx_bonus_priest_spells (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//3e
155 int fx_set_infravision_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//3f
156 int fx_cure_infravision_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//40
157 int fx_set_blur_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//41
158 int fx_transparency_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//42
159 int fx_summon_creature (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//43
160 int fx_unsummon_creature (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//44
161 int fx_set_nondetection_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//45
162 int fx_cure_nondetection_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//46
163 int fx_sex_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//47
164 int fx_ids_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//48
165 int fx_damage_bonus_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//49
166 int fx_set_blind_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//4a
167 int fx_cure_blind_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//4b
168 int fx_set_feebleminded_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//4c
169 int fx_cure_feebleminded_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//4d
170 int fx_set_diseased_state (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//4e
171 int fx_cure_diseased_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//4f
172 int fx_set_deaf_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
); //50
173 int fx_set_deaf_state_iwd2 (Scriptable
* Owner
, Actor
* target
, Effect
* fx
); //50
174 int fx_cure_deaf_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//51
175 int fx_set_ai_script (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//52
176 int fx_protection_from_projectile (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//53
177 int fx_magical_fire_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//54
178 int fx_magical_cold_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//55
179 int fx_slashing_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//56
180 int fx_crushing_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//57
181 int fx_piercing_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//58
182 int fx_missiles_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//59
183 int fx_open_locks_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//5a
184 int fx_find_traps_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//5b
185 int fx_pick_pockets_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//5c
186 int fx_fatigue_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//5d
187 int fx_intoxication_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//5e
188 int fx_tracking_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//5f
189 int fx_level_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//60
190 int fx_strength_bonus_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//61
191 int fx_set_regenerating_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//62
192 int fx_spell_duration_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);///63
193 int fx_generic_effect (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//64 protection from creature is a generic effect
194 int fx_protection_opcode(Scriptable
* Owner
, Actor
* target
, Effect
* fx
); //65
195 int fx_protection_spelllevel (Scriptable
* Owner
, Actor
* target
, Effect
* fx
); //66
196 int fx_change_name (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//67
197 int fx_experience_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//68
198 int fx_gold_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//69
199 int fx_morale_break_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//6a
200 int fx_portrait_change (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//6b
201 int fx_reputation_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//6c
202 int fx_hold_creature_no_icon (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//6d
203 //int fx_retreat_from (Scriptable* Owner, Actor* target, Effect* fx);//6e reused
204 int fx_create_magic_item (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//6f
205 int fx_remove_item (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//70
206 int fx_equip_item (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//71
207 int fx_dither (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//72
208 int fx_detect_alignment (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//73
209 //int fx_cure_improved_invisible_state (Scriptable* Owner, Actor* target, Effect* fx);//74 (2f)
210 int fx_reveal_area (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//75
211 int fx_reveal_creatures (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//76
212 int fx_mirror_image (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//77
213 int fx_immune_to_weapon (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//78
214 int fx_visual_animation_effect (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//79 unknown
215 int fx_create_inventory_item (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//7a
216 int fx_remove_inventory_item (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//7b
217 int fx_dimension_door (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//7c
218 int fx_knock (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//7d
219 int fx_movement_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//7e
220 int fx_monster_summoning (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//7f
221 int fx_set_confused_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//80
222 int fx_set_aid_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//81
223 int fx_set_bless_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//82
224 int fx_set_chant_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//83
225 int fx_set_holy_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//84
226 int fx_luck_non_cumulative (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//85
227 int fx_luck_cumulative (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//85
228 int fx_set_petrified_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//86
229 int fx_polymorph (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//87
230 int fx_force_visible (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//88
231 int fx_set_chantbad_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//89
232 int fx_animation_stance (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//8a
233 int fx_display_string (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//8b
234 int fx_casting_glow (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//8c
235 int fx_visual_spell_hit (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//8d
236 int fx_display_portrait_icon (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//8e
237 int fx_create_item_in_slot (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//8f
238 int fx_disable_button (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//90
239 int fx_disable_spellcasting (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//91
240 int fx_cast_spell (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//92
241 int fx_learn_spell (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//93
242 int fx_cast_spell_point (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//94
243 int fx_identify (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//95
244 int fx_find_traps (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//96
245 int fx_replace_creature (Scriptable
* Owner
, Actor
* target
, Effect
*fx
);//97
246 int fx_play_movie (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//98
247 int fx_set_sanctuary_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//99
248 int fx_set_entangle_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//9a
249 int fx_set_minorglobe_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//9b
250 int fx_set_shieldglobe_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//9c
251 int fx_set_web_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//9d
252 int fx_set_grease_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//9e
253 int fx_mirror_image_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//9f
254 int fx_cure_sanctuary_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a0
255 int fx_cure_panic_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a1
256 int fx_cure_hold_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a2 //cures 175
257 int fx_cure_slow_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a3
258 int fx_cure_intoxication (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a4
259 int fx_pause_target (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a5
260 int fx_magic_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a6
261 int fx_missile_to_hit_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a7
262 int fx_remove_creature (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a8
263 int fx_disable_portrait_icon (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//a9
264 int fx_damage_animation (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//aa
265 int fx_add_innate (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ab
266 int fx_remove_spell (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ac
267 int fx_poison_resistance_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ad
268 int fx_playsound (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ae
269 int fx_hold_creature (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//af
270 // this function is exactly the same as 0x7e fx_movement_modifier (in bg2 at least)//b0
271 int fx_apply_effect (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//b1
272 //b2 //hitbonus against creature (generic_effect)
273 //b3 //damagebonus against creature (generic effect)
278 int fx_dontjump_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//b8
279 // this function is exactly the same as 0xaf hold_creature (in bg2 at least) //b9
280 int fx_move_to_area (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ba
281 int fx_local_variable (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//bb
282 int fx_auracleansing_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//bc
283 int fx_castingspeed_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//bd
284 int fx_attackspeed_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//be
285 int fx_castinglevel_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//bf
286 int fx_find_familiar (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c0
287 int fx_see_invisible_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c1
288 int fx_ignore_dialogpause_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c2
289 int fx_familiar_constitution_loss (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c3
290 int fx_familiar_marker (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c4
291 int fx_bounce_projectile (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c5
292 int fx_bounce_opcode (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c6
293 int fx_bounce_spelllevel (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c7
294 int fx_bounce_spelllevel_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c8
295 int fx_protection_spelllevel_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//c9
296 int fx_bounce_school (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ca
297 int fx_bounce_secondary_type (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//cb
298 int fx_protection_school (Scriptable
* Owner
, Actor
* target
, Effect
* fx
); //cc
299 int fx_protection_secondary_type (Scriptable
* Owner
, Actor
* target
, Effect
* fx
); //cd
300 int fx_resist_spell (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ce
301 int fx_resist_spell_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//??
302 int fx_bounce_spell (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//cf
303 int fx_bounce_spell_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//??
304 int fx_minimum_hp_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d0
305 int fx_power_word_kill (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d1
306 int fx_power_word_stun (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d2
307 int fx_imprisonment (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d3
308 int fx_freedom (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d4
309 int fx_maze (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d5
310 int fx_select_spell (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d6
311 int fx_play_visual_effect (Scriptable
* Owner
, Actor
* target
, Effect
* fx
); //d7
312 int fx_leveldrain_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d8
313 int fx_power_word_sleep (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//d9
314 int fx_stoneskin_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//da
315 //db ac vs creature type (general effect)
316 int fx_dispel_school (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//dc
317 int fx_dispel_secondary_type (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//dd
318 int fx_teleport_field (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//de
319 int fx_protection_school_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//df
320 int fx_cure_leveldrain (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e0
321 int fx_reveal_magic (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e1
322 int fx_protection_secondary_type_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e2
323 int fx_bounce_school_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e3
324 int fx_bounce_secondary_type_dec (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e4
325 int fx_dispel_school_one (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e5
326 int fx_dispel_secondary_type_one (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e6
327 int fx_timestop (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e7
328 int fx_cast_spell_on_condition (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e8
329 int fx_proficiency (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//e9
330 int fx_create_contingency (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ea
331 int fx_wing_buffet (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//eb
332 int fx_puppet_master (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ec
333 int fx_puppet_marker (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ed
334 int fx_disintegrate (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ee
335 int fx_farsee (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ef
336 int fx_remove_portrait_icon (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//f0
337 //f1 control creature (see charm)
338 int fx_cure_confused_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//f2
339 int fx_drain_items (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//f3
340 int fx_drain_spells (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//f4
341 int fx_checkforberserk_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//f5
342 int fx_berserkstage1_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//f6
343 int fx_berserkstage2_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//f7
344 //f8 melee effect (general effect?)
345 //f9 ranged effect (general effect?)
346 int fx_damageluck_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//fa
347 int fx_change_bardsong (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//fb
348 int fx_set_area_effect (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//fc (set trap)
349 int fx_set_map_note (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//fd
350 int fx_remove_map_note (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//fe
351 int fx_create_item_days (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//ff
352 int fx_store_spell_sequencer (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//0x100
353 int fx_create_spell_sequencer (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//101
354 int fx_activate_spell_sequencer (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//102
355 int fx_spelltrap (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//103
356 int fx_crash (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//104, disabled
357 int fx_restore_spell_level (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//105
358 int fx_visual_range_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//106
359 int fx_backstab_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//107
360 int fx_drop_weapon (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//108
361 int fx_modify_global_variable (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//109
362 int fx_remove_immunity (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//10a
363 int fx_protection_from_string (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//10b
364 int fx_explore_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//10c
365 int fx_screenshake (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//10d
366 int fx_unpause_caster (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//10e
367 int fx_avatar_removal (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//10f
368 int fx_apply_effect_repeat (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//110
369 int fx_remove_projectile (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//111
370 int fx_teleport_to_target (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//112
371 int fx_hide_in_shadows_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//113
372 int fx_detect_illusion_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//114
373 int fx_set_traps_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//115
374 int fx_to_hit_bonus_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//116
375 int fx_renable_button (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//117
376 int fx_force_surge_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//118
377 int fx_wild_surge_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//119
378 int fx_scripting_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//11a
379 int fx_apply_effect_curse (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//11b
380 int fx_melee_to_hit_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//11c
381 int fx_melee_damage_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//11d
382 int fx_missile_damage_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//11e
383 int fx_no_circle_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//11f
384 int fx_fist_to_hit_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//120
385 int fx_fist_damage_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//121
386 int fx_title_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//122
387 int fx_disable_overlay_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//123
388 int fx_no_backstab_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//124
389 int fx_offscreenai_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//125
390 int fx_existance_delay_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//126
391 int fx_disable_chunk_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//127
392 int fx_protection_from_animation (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//128
393 int fx_protection_from_turn (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//129
394 int fx_cutscene2 (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//12a
395 int fx_chaos_shield_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//12b
396 int fx_npc_bump (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//12c
397 int fx_critical_hit_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//12d
398 int fx_can_use_any_item_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//12e
399 int fx_always_backstab_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//12f
400 int fx_mass_raise_dead (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//130
401 int fx_left_to_hit_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//131
402 int fx_right_to_hit_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//132
403 int fx_reveal_tracks (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//133
404 int fx_protection_from_tracking (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//134
405 int fx_modify_local_variable (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//135
406 int fx_timeless_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//136
407 int fx_generate_wish (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//137
409 //139 HLA generic effect
410 int fx_golem_stoneskin_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//13a
411 int fx_avatar_removal_modifier (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//13b
412 int fx_magical_rest (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//13c
413 //int fx_improved_haste_state (Scriptable* Owner, Actor* target, Effect* fx);//13d same as haste
415 int fx_unknown (Scriptable
* Owner
, Actor
* target
, Effect
* fx
);//???
417 // FIXME: Make this an ordered list, so we could use bsearch!
418 static EffectRef effectnames
[] = {
419 { "*Crash*", fx_crash
, -1 },
420 { "AcidResistanceModifier", fx_acid_resistance_modifier
, -1 },
421 { "ACVsCreatureType", fx_generic_effect
, -1 }, //0xdb
422 { "ACVsDamageTypeModifier", fx_ac_vs_damage_type_modifier
, -1 },
423 { "ACVsDamageTypeModifier2", fx_ac_vs_damage_type_modifier
, -1 }, // used in IWD
424 { "AidNonCumulative", fx_set_aid_state
, -1 },
425 { "AIIdentifierModifier", fx_ids_modifier
, -1 },
426 { "AlchemyModifier", fx_alchemy_modifier
, -1 },
427 { "Alignment:Change", fx_alignment_change
, -1 },
428 { "Alignment:Invert", fx_alignment_invert
, -1 },
429 { "AlwaysBackstab", fx_always_backstab_modifier
, -1 },
430 { "AnimationIDModifier", fx_animation_id_modifier
, -1 },
431 { "AnimationStateChange", fx_animation_stance
, -1 },
432 { "ApplyEffect", fx_apply_effect
, -1 },
433 { "ApplyEffectCurse", fx_apply_effect_curse
, -1 },
434 { "ApplyEffectItemType", fx_generic_effect
, -1 }, //apply effect when itemtype is equipped
435 { "ApplyEffectRepeat", fx_apply_effect_repeat
, -1 },
436 { "CutScene2", fx_cutscene2
, -1 },
437 { "AttackSpeedModifier", fx_attackspeed_modifier
, -1 },
438 { "AttacksPerRoundModifier", fx_attacks_per_round_modifier
, -1 },
439 { "AuraCleansingModifier", fx_auracleansing_modifier
, -1 },
440 { "AvatarRemoval", fx_avatar_removal
, -1 }, //unknown
441 { "AvatarRemovalModifier", fx_avatar_removal_modifier
, -1 },
442 { "BackstabModifier", fx_backstab_modifier
, -1 },
443 { "BerserkStage1Modifier", fx_berserkstage1_modifier
, -1},
444 { "BerserkStage2Modifier", fx_berserkstage2_modifier
, -1},
445 { "BlessNonCumulative", fx_set_bless_state
, -1 },
446 { "Bounce:School", fx_bounce_school
, -1 },
447 { "Bounce:SchoolDec", fx_bounce_school_dec
, -1 },
448 { "Bounce:SecondaryType", fx_bounce_secondary_type
, -1 },
449 { "Bounce:SecondaryTypeDec", fx_bounce_secondary_type_dec
, -1 },
450 { "Bounce:Spell", fx_bounce_spell
, -1 },
451 { "Bounce:SpellDec", fx_bounce_spell_dec
, -1 },
452 { "Bounce:SpellLevel", fx_bounce_spelllevel
, -1},
453 { "Bounce:SpellLevelDec", fx_bounce_spelllevel_dec
, -1},
454 { "Bounce:Opcode", fx_bounce_opcode
, -1 },
455 { "Bounce:Projectile", fx_bounce_projectile
, -1 },
456 { "CantUseItem", fx_generic_effect
, -1 },
457 { "CantUseItemType", fx_generic_effect
, -1 },
458 { "CanUseAnyItem", fx_can_use_any_item_modifier
, -1 },
459 { "CastFromList", fx_select_spell
, -1 },
460 { "CastingGlow", fx_casting_glow
, -1 },
461 { "CastingGlow2", fx_casting_glow
, -1 }, //used in iwd
462 { "CastingLevelModifier", fx_castinglevel_modifier
, -1 },
463 { "CastingSpeedModifier", fx_castingspeed_modifier
, -1 },
464 { "CastSpellOnCondition", fx_cast_spell_on_condition
, -1 },
465 { "ChangeBardSong", fx_generic_effect
, -1 },
466 { "ChangeName", fx_change_name
, -1 },
467 { "ChantBadNonCumulative", fx_set_chantbad_state
, -1 },
468 { "ChantNonCumulative", fx_set_chant_state
, -1 },
469 { "ChaosShieldModifier", fx_chaos_shield_modifier
, -1 },
470 { "CharismaModifier", fx_charisma_modifier
, -1 },
471 { "CheckForBerserkModifier", fx_checkforberserk_modifier
, -1},
472 { "ColdResistanceModifier", fx_cold_resistance_modifier
, -1 },
473 { "Color:BriefRGB", fx_brief_rgb
, -1},
474 { "Color:GlowRGB", fx_glow_rgb
, -1},
475 { "Color:DarkenRGB", fx_darken_rgb
, -1},
476 { "Color:SetPalette", fx_set_color_gradient
, -1 },
477 { "Color:SetRGB", fx_set_color_rgb
, -1 },
478 { "Color:SetRGBGlobal", fx_set_color_rgb_global
, -1 }, //08
479 { "Color:PulseRGB", fx_set_color_pulse_rgb
, -1 }, //9
480 { "Color:PulseRGBGlobal", fx_set_color_pulse_rgb_global
, -1 }, //9
481 { "ConstitutionModifier", fx_constitution_modifier
, -1 },
482 { "ControlCreature", fx_set_charmed_state
, -1 }, //0xf1 same as charm
483 { "CreateContingency", fx_create_contingency
, -1 },
484 { "CriticalHitModifier", fx_critical_hit_modifier
, -1 },
485 { "CrushingResistanceModifier", fx_crushing_resistance_modifier
, -1 },
486 { "Cure:Berserk", fx_cure_berserk_state
, -1 },
487 { "Cure:Blind", fx_cure_blind_state
, -1 },
488 { "Cure:CasterHold", fx_unpause_caster
, -1 },
489 { "Cure:Confusion", fx_cure_confused_state
, -1 },
490 { "Cure:Deafness", fx_cure_deaf_state
, -1 },
491 { "Cure:Death", fx_cure_dead_state
, -1 },
492 { "Cure:Defrost", fx_cure_frozen_state
, -1 },
493 { "Cure:Disease", fx_cure_diseased_state
, -1 },
494 { "Cure:Feeblemind", fx_cure_feebleminded_state
, -1 },
495 { "Cure:Hold", fx_cure_hold_state
, -1 },
496 { "Cure:Imprisonment", fx_freedom
, -1 },
497 { "Cure:Infravision", fx_cure_infravision_state
, -1 },
498 { "Cure:Intoxication", fx_cure_intoxication
, -1 }, //0xa4 (iwd2 has this working)
499 { "Cure:Invisible", fx_cure_invisible_state
, -1 }, //0x2f
500 { "Cure:Invisible2", fx_cure_invisible_state
, -1 }, //0x74
501 //{ "Cure:ImprovedInvisible", fx_cure_improved_invisible_state, -1 },
502 { "Cure:LevelDrain", fx_cure_leveldrain
, -1}, //restoration
503 { "Cure:Nondetection", fx_cure_nondetection_state
, -1 },
504 { "Cure:Panic", fx_cure_panic_state
, -1 },
505 { "Cure:Petrification", fx_cure_petrified_state
, -1 },
506 { "Cure:Poison", fx_cure_poisoned_state
, -1 },
507 { "Cure:Sanctuary", fx_cure_sanctuary_state
, -1 },
508 { "Cure:Silence", fx_cure_silenced_state
, -1 },
509 { "Cure:Sleep", fx_cure_sleep_state
, -1 },
510 { "Cure:Stun", fx_cure_stun_state
, -1 },
511 { "CurrentHPModifier", fx_current_hp_modifier
, -1 },
512 { "Damage", fx_damage
, -1 },
513 { "DamageAnimation", fx_damage_animation
, -1 },
514 { "DamageBonusModifier", fx_damage_bonus_modifier
, -1 },
515 { "DamageLuckModifier", fx_damageluck_modifier
, -1 },
516 { "DamageVsCreature", fx_generic_effect
, -1 },
517 { "Death", fx_death
, -1 },
518 { "Death2", fx_death
, -1 }, //(iwd2 effect)
519 { "Death3", fx_death
, -1 }, //(iwd2 effect too, Banish)
520 { "DetectAlignment", fx_detect_alignment
, -1 },
521 { "DetectIllusionsModifier", fx_detect_illusion_modifier
, -1 },
522 { "DexterityModifier", fx_dexterity_modifier
, -1 },
523 { "DimensionDoor", fx_dimension_door
, -1 },
524 { "DisableButton", fx_disable_button
, -1 }, //sets disable button flag
525 { "DisableChunk", fx_disable_chunk_modifier
, -1 },
526 { "DisableOverlay", fx_disable_overlay_modifier
, -1 },
527 { "DisableCasting", fx_disable_spellcasting
, -1 },
528 { "Disintegrate", fx_disintegrate
, -1 },
529 { "DispelEffects", fx_dispel_effects
, -1 },
530 { "DispelSchool", fx_dispel_school
, -1 },
531 { "DispelSchoolOne", fx_dispel_school_one
, -1 },
532 { "DispelSecondaryType", fx_dispel_secondary_type
, -1 },
533 { "DispelSecondaryTypeOne", fx_dispel_secondary_type_one
, -1 },
534 { "DisplayString", fx_display_string
, -1 },
535 { "Dither", fx_dither
, -1 },
536 { "DontJumpModifier", fx_dontjump_modifier
, -1 },
537 { "DrainItems", fx_drain_items
, -1 },
538 { "DrainSpells", fx_drain_spells
, -1 },
539 { "DropWeapon", fx_drop_weapon
, -1 },
540 { "ElectricityResistanceModifier", fx_electricity_resistance_modifier
, -1 },
541 { "ExistanceDelayModifier", fx_existance_delay_modifier
, -1 }, //unknown
542 { "ExperienceModifier", fx_experience_modifier
, -1 },
543 { "ExploreModifier", fx_explore_modifier
, -1 },
544 { "FamiliarBond", fx_familiar_constitution_loss
, -1 },
545 { "FamiliarMarker", fx_familiar_marker
, -1},
546 { "Farsee", fx_farsee
, -1},
547 { "FatigueModifier", fx_fatigue_modifier
, -1 },
548 { "FindFamiliar", fx_find_familiar
, -1 },
549 { "FindTraps", fx_find_traps
, -1 },
550 { "FindTrapsModifier", fx_find_traps_modifier
, -1 },
551 { "FireResistanceModifier", fx_fire_resistance_modifier
, -1 },
552 { "FistDamageModifier", fx_fist_damage_modifier
, -1 },
553 { "FistHitModifier", fx_fist_to_hit_modifier
, -1 },
554 { "ForceSurgeModifier", fx_force_surge_modifier
, -1 },
555 { "ForceVisible", fx_force_visible
, -1 }, //not invisible but improved invisible
556 { "FreeAction", fx_cure_slow_state
, -1},
557 { "GenerateWish", fx_generate_wish
, -1},
558 { "GoldModifier", fx_gold_modifier
, -1 },
559 { "HideInShadowsModifier", fx_hide_in_shadows_modifier
, -1},
560 { "HLA", fx_generic_effect
, -1},
561 { "HolyNonCumulative", fx_set_holy_state
, -1 },
562 { "Icon:Disable", fx_disable_portrait_icon
, -1 },
563 { "Icon:Display", fx_display_portrait_icon
, -1 },
564 { "Icon:Remove", fx_remove_portrait_icon
, -1 },
565 { "Identify", fx_identify
, -1 },
566 { "IgnoreDialogPause", fx_ignore_dialogpause_modifier
, -1 },
567 { "IntelligenceModifier", fx_intelligence_modifier
, -1 },
568 { "IntoxicationModifier", fx_intoxication_modifier
, -1 },
569 { "InvisibleDetection", fx_see_invisible_modifier
, -1 },
570 { "Item:CreateDays", fx_create_item_days
, -1 },
571 { "Item:CreateInSlot", fx_create_item_in_slot
, -1 },
572 { "Item:CreateInventory", fx_create_inventory_item
, -1 },
573 { "Item:CreateMagic", fx_create_magic_item
, -1 },
574 { "Item:Equip", fx_equip_item
, -1 }, //71
575 { "Item:Remove", fx_remove_item
, -1 }, //70
576 { "Item:RemoveInventory", fx_remove_inventory_item
, -1 },
577 { "KillCreatureType", fx_kill_creature_type
, -1 },
578 { "LevelModifier", fx_level_modifier
, -1 },
579 { "LevelDrainModifier", fx_leveldrain_modifier
, -1 },
580 { "LoreModifier", fx_lore_modifier
, -1 },
581 { "LuckModifier", fx_luck_modifier
, -1 },
582 { "LuckCumulative", fx_luck_cumulative
, -1 },
583 { "LuckNonCumulative", fx_luck_non_cumulative
, -1 },
584 { "MagicalColdResistanceModifier", fx_magical_cold_resistance_modifier
, -1 },
585 { "MagicalFireResistanceModifier", fx_magical_fire_resistance_modifier
, -1 },
586 { "MagicalRest", fx_magical_rest
, -1 },
587 { "MagicDamageResistanceModifier", fx_magic_damage_resistance_modifier
, -1 },
588 { "MagicResistanceModifier", fx_magic_resistance_modifier
, -1 },
589 { "MassRaiseDead", fx_mass_raise_dead
, -1 },
590 { "MaximumHPModifier", fx_maximum_hp_modifier
, -1 },
591 { "Maze", fx_maze
, -1},
592 { "MeleeDamageModifier", fx_melee_damage_modifier
, -1 },
593 { "MeleeHitModifier", fx_melee_to_hit_modifier
, -1 },
594 { "MinimumHPModifier", fx_minimum_hp_modifier
, -1 },
595 { "MiscastMagicModifier", fx_miscast_magic_modifier
, -1 },
596 { "MissileDamageModifier", fx_missile_damage_modifier
, -1 },
597 { "MissileHitModifier", fx_missile_to_hit_modifier
, -1 },
598 { "MissilesResistanceModifier", fx_missiles_resistance_modifier
, -1 },
599 { "MirrorImage", fx_mirror_image
, -1 },
600 { "MirrorImageModifier", fx_mirror_image_modifier
, -1 },
601 { "ModifyGlobalVariable", fx_modify_global_variable
, -1 },
602 { "ModifyLocalVariable", fx_modify_local_variable
, -1 },
603 { "MonsterSummoning", fx_monster_summoning
, -1 },
604 { "MoraleBreakModifier", fx_morale_break_modifier
, -1 },
605 { "MoraleModifier", fx_morale_modifier
, -1 },
606 { "MovementRateModifier", fx_movement_modifier
, -1 }, //fast (7e)
607 { "MovementRateModifier2", fx_movement_modifier
, -1 },//slow (b0)
608 { "MovementRateModifier3", fx_movement_modifier
, -1 },//forced (IWD - 10a)
609 { "MovementRateModifier4", fx_movement_modifier
, -1 },//slow (IWD2 - 1b9)
610 { "MoveToArea", fx_move_to_area
, -1 }, //0xba
611 { "NoCircleState", fx_no_circle_state
, -1 },
612 { "NPCBump", fx_npc_bump
, -1 },
613 { "OffscreenAIModifier", fx_offscreenai_modifier
, -1 },
614 { "OffhandHitModifier", fx_left_to_hit_modifier
, -1 },
615 { "OpenLocksModifier", fx_open_locks_modifier
, -1 },
616 { "Overlay:Entangle", fx_set_entangle_state
, -1 },
617 { "Overlay:Grease", fx_set_grease_state
, -1 },
618 { "Overlay:MinorGlobe", fx_set_minorglobe_state
, -1 },
619 { "Overlay:Sanctuary", fx_set_sanctuary_state
, -1 },
620 { "Overlay:ShieldGlobe", fx_set_shieldglobe_state
, -1 },
621 { "Overlay:Web", fx_set_web_state
, -1 },
622 { "PauseTarget", fx_pause_target
, -1 }, //also known as casterhold
623 { "PickPocketsModifier", fx_pick_pockets_modifier
, -1 },
624 { "PiercingResistanceModifier", fx_piercing_resistance_modifier
, -1 },
625 { "PlayMovie", fx_play_movie
, -1 },
626 { "PlaySound", fx_playsound
, -1 },
627 { "PlayVisualEffect", fx_play_visual_effect
, -1 },
628 { "PoisonResistanceModifier", fx_poison_resistance_modifier
, -1 },
629 { "Polymorph", fx_polymorph
, -1},
630 { "PortraitChange", fx_portrait_change
, -1 },
631 { "PowerWordKill", fx_power_word_kill
, -1 },
632 { "PowerWordSleep", fx_power_word_sleep
, -1 },
633 { "PowerWordStun", fx_power_word_stun
, -1 },
634 { "PriestSpellSlotsModifier", fx_bonus_priest_spells
, -1 },
635 { "Proficiency", fx_proficiency
, -1 },
636 { "Protection:Animation", fx_generic_effect
, -1 },
637 { "Protection:Backstab", fx_no_backstab_modifier
, -1 },
638 { "Protection:Creature", fx_generic_effect
, -1 },
639 { "Protection:Opcode", fx_protection_opcode
, -1 },
640 { "Protection:Opcode2", fx_protection_opcode
, -1 },
641 { "Protection:Projectile",fx_protection_from_projectile
, -1},
642 { "Protection:School",fx_generic_effect
,-1},//overlay?
643 { "Protection:SchoolDec",fx_protection_school_dec
,-1},//overlay?
644 { "Protection:SecondaryType",fx_protection_secondary_type
,-1},//overlay?
645 { "Protection:SecondaryTypeDec",fx_protection_secondary_type_dec
,-1},//overlay?
646 { "Protection:Spell",fx_resist_spell
,-1},//overlay?
647 { "Protection:SpellDec",fx_resist_spell_dec
,-1},//overlay?
648 { "Protection:SpellLevel",fx_protection_spelllevel
,-1},//overlay?
649 { "Protection:SpellLevelDec",fx_protection_spelllevel_dec
,-1},//overlay?
650 { "Protection:String", fx_generic_effect
, -1 },
651 { "Protection:Tracking", fx_protection_from_tracking
, -1 },
652 { "Protection:Turn", fx_protection_from_turn
, -1},
653 { "Protection:Weapons", fx_immune_to_weapon
, -1},
654 { "PuppetMarker", fx_puppet_marker
, -1},
655 { "ProjectImage", fx_puppet_master
, -1},
656 { "Reveal:Area", fx_reveal_area
, -1 },
657 { "Reveal:Creatures", fx_reveal_creatures
, -1 },
658 { "Reveal:Magic", fx_reveal_magic
, -1 },
659 { "Reveal:Tracks", fx_reveal_tracks
, -1 },
660 { "RemoveCurse", fx_remove_curse
, -1 },
661 { "RemoveImmunity", fx_remove_immunity
, -1 },
662 { "RemoveMapNote", fx_remove_map_note
, -1 },
663 { "RemoveProjectile", fx_remove_projectile
, -1 }, //removes effects from actor and area
664 { "RenableButton", fx_renable_button
, -1 }, //removes disable button flag
665 { "RemoveCreature", fx_remove_creature
, -1 },
666 { "ReplaceCreature", fx_replace_creature
, -1 },
667 { "ReputationModifier", fx_reputation_modifier
, -1 },
668 { "RestoreSpells", fx_restore_spell_level
, -1 },
669 { "RightHitModifier", fx_right_to_hit_modifier
, -1 },
670 { "SaveVsBreathModifier", fx_save_vs_breath_modifier
, -1 },
671 { "SaveVsDeathModifier", fx_save_vs_death_modifier
, -1 },
672 { "SaveVsPolyModifier", fx_save_vs_poly_modifier
, -1 },
673 { "SaveVsSpellsModifier", fx_save_vs_spell_modifier
, -1 },
674 { "SaveVsWandsModifier", fx_save_vs_wands_modifier
, -1 },
675 { "ScreenShake", fx_screenshake
, -1 },
676 { "ScriptingState", fx_scripting_state
, -1 },
677 { "Sequencer:Activate", fx_activate_spell_sequencer
, -1 },
678 { "Sequencer:Create", fx_create_spell_sequencer
, -1 },
679 { "Sequencer:Store", fx_store_spell_sequencer
, -1 },
680 { "SetAIScript", fx_set_ai_script
, -1 },
681 { "SetMapNote", fx_set_map_note
, -1 },
682 { "SetMeleeEffect", fx_generic_effect
, -1 },
683 { "SetRangedEffect", fx_generic_effect
, -1 },
684 { "SetTrap", fx_set_area_effect
, -1 },
685 { "SetTrapsModifier", fx_set_traps_modifier
, -1 },
686 { "SexModifier", fx_sex_modifier
, -1 },
687 { "SlashingResistanceModifier", fx_slashing_resistance_modifier
, -1 },
688 { "SlowPoisonDamageRate", fx_generic_effect
, -1 }, //slow poison effect
689 { "Sparkle", fx_sparkle
, -1 },
690 { "SpellDurationModifier", fx_spell_duration_modifier
, -1 },
691 { "Spell:Add", fx_add_innate
, -1 },
692 { "Spell:Cast", fx_cast_spell
, -1 },
693 { "Spell:CastPoint", fx_cast_spell_point
, -1 },
694 { "Spell:Learn", fx_learn_spell
, -1 },
695 { "Spell:Remove", fx_remove_spell
, -1 },
696 { "Spelltrap",fx_spelltrap
, -1 }, //overlay: spmagglo
697 { "State:Berserk", fx_set_berserk_state
, -1 },
698 { "State:Blind", fx_set_blind_state
, -1 },
699 { "State:Blur", fx_set_blur_state
, -1 },
700 { "State:Charmed", fx_set_charmed_state
, -1 }, //0x05
701 { "State:Confused", fx_set_confused_state
, -1 },
702 { "State:Deafness", fx_set_deaf_state
, -1 },
703 { "State:DeafnessIWD2", fx_set_deaf_state_iwd2
, -1 }, //this is a modified version
704 { "State:Diseased", fx_set_diseased_state
, -1 },
705 { "State:Feeblemind", fx_set_feebleminded_state
, -1 },
706 { "State:Hasted", fx_set_hasted_state
, -1 },
707 { "State:Haste2", fx_set_hasted_state
, -1 },
708 { "State:Hold", fx_hold_creature
, -1 }, //175 (doesn't work in original iwd2)
709 { "State:Hold2", fx_hold_creature
, -1 },//185 (doesn't work in original iwd2)
710 { "State:Hold3", fx_hold_creature
, -1 },//109 iwd2
711 { "State:HoldNoIcon", fx_hold_creature_no_icon
, -1 }, //109
712 { "State:HoldNoIcon2", fx_hold_creature_no_icon
, -1 }, //0xfb (iwd/iwd2)
713 { "State:HoldNoIcon3", fx_hold_creature_no_icon
, -1 }, //0x1a8 (iwd2)
714 { "State:Imprisonment", fx_imprisonment
, -1 },
715 { "State:Infravision", fx_set_infravision_state
, -1 },
716 { "State:Invisible", fx_set_invisible_state
, -1 }, //both invis or improved invis
717 { "State:Nondetection", fx_set_nondetection_state
, -1 },
718 { "State:Panic", fx_set_panic_state
, -1 },
719 { "State:Petrification", fx_set_petrified_state
, -1 },
720 { "State:Poisoned", fx_set_poisoned_state
, -1 },
721 { "State:Regenerating", fx_set_regenerating_state
, -1 },
722 { "State:Silenced", fx_set_silenced_state
, -1 },
723 { "State:Helpless", fx_set_unconscious_state
, -1 },
724 { "State:Sleep", fx_set_unconscious_state
, -1},
725 { "State:Slowed", fx_set_slowed_state
, -1 },
726 { "State:Stun", fx_set_stun_state
, -1 },
727 { "StealthModifier", fx_stealth_modifier
, -1 },
728 { "StoneSkinModifier", fx_stoneskin_modifier
, -1 },
729 { "StoneSkin2Modifier", fx_golem_stoneskin_modifier
, -1 },
730 { "StrengthModifier", fx_strength_modifier
, -1 },
731 { "StrengthBonusModifier", fx_strength_bonus_modifier
, -1 },
732 { "SummonCreature", fx_summon_creature
, -1 },
733 { "RandomTeleport", fx_teleport_field
, -1 },
734 { "TeleportToTarget", fx_teleport_to_target
, -1 },
735 { "TimelessState", fx_timeless_modifier
, -1 },
736 { "Timestop", fx_timestop
, -1},
737 { "TitleModifier", fx_title_modifier
, -1 },
738 { "ToHitModifier", fx_to_hit_modifier
, -1 },
739 { "ToHitBonusModifier", fx_to_hit_bonus_modifier
, -1 },
740 { "ToHitVsCreature", fx_generic_effect
, -1 },
741 { "TrackingModifier", fx_tracking_modifier
, -1 },
742 { "TransparencyModifier", fx_transparency_modifier
, -1 },
743 { "Unknown", fx_unknown
, -1},
744 { "Unlock", fx_knock
, -1 }, //open doors/containers
745 { "UnsummonCreature", fx_unsummon_creature
, -1 },
746 { "Variable:StoreLocalVariable", fx_local_variable
, -1 },
747 { "VisualAnimationEffect", fx_visual_animation_effect
, -1 }, //unknown
748 { "VisualRangeModifier", fx_visual_range_modifier
, -1 },
749 { "VisualSpellHit", fx_visual_spell_hit
, -1 },
750 { "WildSurgeModifier", fx_wild_surge_modifier
, -1 },
751 { "WingBuffet", fx_wing_buffet
, -1 },
752 { "WisdomModifier", fx_wisdom_modifier
, -1 },
753 { "WizardSpellSlotsModifier", fx_bonus_wizard_spells
, -1 },
757 static void Cleanup()
759 core
->FreeResRefTable(casting_glows
, cgcount
);
760 core
->FreeResRefTable(spell_hits
, shcount
);
761 if(spell_abilities
) free(spell_abilities
);
762 spell_abilities
=NULL
;
763 if(polymorph_stats
) free(polymorph_stats
);
764 polymorph_stats
=NULL
;
767 void RegisterCoreOpcodes()
769 core
->RegisterOpcodes( sizeof( effectnames
) / sizeof( EffectRef
) - 1, effectnames
);
770 enhanced_effects
=!!core
->HasFeature(GF_ENHANCED_EFFECTS
);
771 default_spell_hit
.SequenceFlags
|=IE_VVC_BAM
;
775 static inline void SetGradient(Actor
*target
, ieDword gradient
)
777 gradient
|= (gradient
<<16);
778 gradient
|= (gradient
<<8);
779 for(int i
=0;i
<7;i
++) {
780 STAT_SET(IE_COLORS
+i
, gradient
);
784 static inline void HandleBonus(Actor
*target
, int stat
, int mod
, int mode
)
786 if (mode
==FX_DURATION_INSTANT_PERMANENT
) {
787 if (target
->IsReverseToHit()) {
788 BASE_SUB( stat
, mod
);
790 BASE_ADD( stat
, mod
);
794 if (target
->IsReverseToHit()) {
795 STAT_SUB( stat
, mod
);
797 STAT_ADD( stat
, mod
);
802 #define ENEMY_SEES_ORIGIN 1
803 #define ORIGIN_SEES_ENEMY 2
805 inline Actor
*GetNearestEnemyOf(Map
*map
, Actor
*origin
, int whoseeswho
)
807 //determining the allegiance of the origin
808 int type
= GetGroup(origin
);
810 //neutral has no enemies
815 Targets
*tgts
= new Targets();
817 int i
= map
->GetActorCount(true);
820 ac
=map
->GetActor(i
,true);
821 int distance
= Distance(ac
, origin
);
822 if (whoseeswho
&ENEMY_SEES_ORIGIN
) {
823 if (!CanSee(ac
, origin
, true, GA_NO_DEAD
)) {
827 if (whoseeswho
&ORIGIN_SEES_ENEMY
) {
828 if (!CanSee(ac
, origin
, true, GA_NO_DEAD
)) {
833 if (type
) { //origin is PC
834 if (ac
->GetStat(IE_EA
) >= EA_EVILCUTOFF
) {
835 tgts
->AddTarget(ac
, distance
, GA_NO_DEAD
);
839 if (ac
->GetStat(IE_EA
) <= EA_GOODCUTOFF
) {
840 tgts
->AddTarget(ac
, distance
, GA_NO_DEAD
);
844 ac
= (Actor
*) tgts
->GetTarget(0, ST_ACTOR
);
849 inline Scriptable
*GetCaster(Scriptable
*Owner
, Effect
*fx
) {
850 if (fx
->FirstApply
) {
851 fx
->CasterID
= Owner
? Owner
->GetGlobalID() : 0;
854 return core
->GetGame()->GetActorByGlobalID(fx
->CasterID
);
859 // handles the percentage damage spread over time by converting it to absolute damage
860 inline void HandlePercentageDamage(Effect
*fx
, Actor
*target
) {
861 if (fx
->Parameter2
== RPD_PERCENT
&& fx
->FirstApply
) {
862 // distribute the damage to one second intervals
863 int seconds
= (fx
->Duration
- core
->GetGame()->GameTime
) / AI_UPDATE_TIME
;
864 fx
->Parameter1
= target
->GetStat(IE_MAXHITPOINTS
) * fx
->Parameter1
/ 100 / seconds
;
869 // 0x00 ACVsDamageTypeModifier
870 int fx_ac_vs_damage_type_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
872 if (0) printf( "fx_ac_vs_damage_type_modifier (%2d): AC Modif: %d ; Type: %d ; MinLevel: %d ; MaxLevel: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
, (int) fx
->DiceSides
, (int) fx
->DiceThrown
);
873 //check level was pulled outside as a common functionality
877 int type
= fx
->Parameter2
;
879 HandleBonus(target
, IE_ARMORCLASS
, fx
->Parameter1
, fx
->TimingMode
);
883 //convert to signed so -1 doesn't turn to an astronomical number
885 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
886 if ((signed)BASE_GET( IE_ARMORCLASS
) > (signed)fx
->Parameter1
) {
887 BASE_SET( IE_ARMORCLASS
, fx
->Parameter1
);
890 if ((signed)STAT_GET( IE_ARMORCLASS
) > (signed)fx
->Parameter1
) {
891 STAT_SET( IE_ARMORCLASS
, fx
->Parameter1
);
897 //the original engine did work with the combination of these bits
898 //but since it crashed, we are not bound to the same rules
900 HandleBonus(target
, IE_ACCRUSHINGMOD
, fx
->Parameter1
, fx
->TimingMode
);
903 HandleBonus(target
, IE_ACMISSILEMOD
, fx
->Parameter1
, fx
->TimingMode
);
906 HandleBonus(target
, IE_ACPIERCINGMOD
, fx
->Parameter1
, fx
->TimingMode
);
909 HandleBonus(target
, IE_ACSLASHINGMOD
, fx
->Parameter1
, fx
->TimingMode
);
915 // 0x01 AttacksPerRoundModifier
916 int fx_attacks_per_round_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
918 if (0) printf( "fx_attacks_per_round_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
919 int tmp
= (signed) fx
->Parameter1
;
920 if (fx
->Parameter2
!=2) {
922 else if (tmp
<-10) tmp
=-10;
925 else if (tmp
<-10) tmp
+=11;
928 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
929 BASE_MOD_VAR(IE_NUMBEROFATTACKS
, tmp
);
931 STAT_MOD_VAR(IE_NUMBEROFATTACKS
, tmp
);
936 // 0x02 Cure:Sleep (Awaken)
937 // this effect clears the STATE_SLEEP (1) bit, but clearing it alone wouldn't remove the
938 // unconscious effect, which is combined with STATE_HELPLESS (0x20+1)
939 static EffectRef fx_set_sleep_state_ref
={"State:Helpless",NULL
,-1};
940 //this reference is used by many other effects
941 static EffectRef fx_display_portrait_icon_ref
={"Icon:Display",NULL
,-1};
943 int fx_cure_sleep_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
945 if (0) printf( "fx_cure_sleep_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
946 BASE_STATE_CURE( STATE_SLEEP
);
947 target
->fxqueue
.RemoveAllEffects(fx_set_sleep_state_ref
);
948 target
->fxqueue
.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref
, PI_SLEEP
);
949 return FX_NOT_APPLIED
;
953 // this effect clears the STATE_BERSERK (2) bit, but bg2 actually ignores the bit
954 // it also removes effect 04
955 static EffectRef fx_set_berserk_state_ref
={"State:Berserk",NULL
,-1};
957 int fx_cure_berserk_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
959 if (0) printf( "fx_cure_berserk_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
960 BASE_STATE_CURE( STATE_BERSERK
);
961 target
->fxqueue
.RemoveAllEffects(fx_set_berserk_state_ref
);
962 return FX_NOT_APPLIED
;
965 // 0x04 State:Berserk
966 // this effect sets the STATE_BERSERK bit, but bg2 actually ignores the bit
967 int fx_set_berserk_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
969 if (0) printf( "fx_set_berserk_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
971 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
972 BASE_STATE_SET( STATE_BERSERK
);
974 STATE_SET( STATE_BERSERK
);
977 switch(fx
->Parameter2
) {
978 case 1: //always berserk
979 target
->SetSpellState(SS_BERSERK
);
981 target
->AddPortraitIcon(PI_BERSERK
);
984 target
->SetSpellState(SS_BERSERK
);
985 //immunity to effects:
995 target
->SetSpellState(SS_BLOODRAGE
);
996 target
->SetSpellState(SS_NOHPINFO
);
997 target
->SetColorMod(0xff, RGBModifier::ADD
, 15, 128, 0, 0);
998 target
->AddPortraitIcon(PI_BLOODRAGE
);
1001 return FX_PERMANENT
;
1004 // 0x05 State:Charmed
1005 // 0xf1 ControlCreature (iwd2)
1006 int fx_set_charmed_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
1008 if (0) printf( "fx_set_charmed_state (%2d): General: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1010 //blood rage berserking gives immunity to charm (in iwd2)
1011 if (target
->HasSpellState(SS_BLOODRAGE
)) {
1012 return FX_NOT_APPLIED
;
1015 //protection from evil gives immunity to charm (in iwd2)
1016 if (target
->HasSpellState(SS_PROTFROMEVIL
)) {
1017 return FX_NOT_APPLIED
;
1020 if (fx
->Parameter1
&& (STAT_GET(IE_GENERAL
)!=fx
->Parameter1
)) {
1021 return FX_NOT_APPLIED
;
1023 bool enemyally
= true;
1024 if (Owner
->Type
==ST_ACTOR
) {
1025 enemyally
= ((Actor
*) Owner
)->GetStat(IE_EA
)>EA_GOODCUTOFF
; //or evilcutoff?
1028 switch (fx
->Parameter2
) {
1029 case 0: //charmed (target neutral after charm)
1030 displaymsg
->DisplayConstantStringName(STR_CHARMED
, 0xf0f0f0, target
);
1033 case 1: //charmed (target hostile after charm)
1034 displaymsg
->DisplayConstantStringName(STR_CHARMED
, 0xf0f0f0, target
);
1036 if (!target
->InParty
) {
1037 target
->SetBaseNoPCF(IE_EA
, EA_ENEMY
);
1040 case 2: //dire charmed (target neutral after charm)
1041 displaymsg
->DisplayConstantStringName(STR_DIRECHARMED
, 0xf0f0f0, target
);
1044 case 3: //dire charmed (target hostile after charm)
1045 displaymsg
->DisplayConstantStringName(STR_DIRECHARMED
, 0xf0f0f0, target
);
1047 if (!target
->InParty
) {
1048 target
->SetBaseNoPCF(IE_EA
, EA_ENEMY
);
1051 case 4: //controlled by cleric
1052 displaymsg
->DisplayConstantStringName(STR_CONTROLLED
, 0xf0f0f0, target
);
1054 if (!target
->InParty
) {
1055 target
->SetBaseNoPCF(IE_EA
, EA_ENEMY
);
1058 case 5: //thrall (typo comes from original engine doc)
1059 displaymsg
->DisplayConstantStringName(STR_CHARMED
, 0xf0f0f0, target
);
1061 STAT_SET(IE_EA
, EA_ENEMY
);
1062 STAT_SET(IE_THRULLCHARM
, 1);
1063 return FX_PERMANENT
;
1066 STATE_SET( STATE_CHARMED
);
1067 STAT_SET_PCF( IE_EA
, enemyally
?EA_ENEMY
:EA_CHARMED
);
1068 //don't stick if permanent
1069 return FX_PERMANENT
;
1072 // 0x06 CharismaModifier
1073 int fx_charisma_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1075 if (0) printf( "fx_charisma_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1077 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1082 return FX_PERMANENT
;
1085 // 0x07 Color:SetPalette
1086 // this effect might not work in pst, they don't have separate weapon slots
1087 int fx_set_color_gradient (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1089 if (0) printf( "fx_set_color_gradient (%2d): Gradient: %d, Location: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1090 EffectQueue::HackColorEffects(target
, fx
);
1091 target
->SetColor( fx
->Parameter2
, fx
->Parameter1
);
1096 int fx_set_color_rgb (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1098 if (0) printf( "fx_set_color_rgb (%2d): RGB: %x, Location: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1099 EffectQueue::HackColorEffects(target
, fx
);
1100 ieDword location
= fx
->Parameter2
& 0xff;
1101 target
->SetColorMod(location
, RGBModifier::ADD
, -1, fx
->Parameter1
>> 8,
1102 fx
->Parameter1
>> 16, fx
->Parameter1
>> 24);
1106 // 08 Color:SetRGBGlobal
1107 int fx_set_color_rgb_global (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1109 if (0) printf( "fx_set_color_rgb_global (%2d): RGB: %x, Location: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1111 target
->SetColorMod(0xff, RGBModifier::ADD
, -1, fx
->Parameter1
>> 8,
1112 fx
->Parameter1
>> 16, fx
->Parameter1
>> 24);
1117 // 09 Color:PulseRGB
1118 int fx_set_color_pulse_rgb (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1120 if (0) printf( "fx_set_color_pulse_rgb (%2d): RGB: %x, Location: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1121 EffectQueue::HackColorEffects(target
, fx
);
1122 ieDword location
= fx
->Parameter2
& 0xff;
1123 int speed
= (fx
->Parameter2
>> 16) & 0xFF;
1124 target
->SetColorMod(location
, RGBModifier::ADD
, speed
,
1125 fx
->Parameter1
>> 8, fx
->Parameter1
>> 16,
1126 fx
->Parameter1
>> 24);
1131 // 09 Color:PulseRGBGlobal (pst variant)
1132 int fx_set_color_pulse_rgb_global (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1134 if (0) printf( "fx_set_color_pulse_rgb_global (%2d): RGB: %x, Location: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1136 int speed
= (fx
->Parameter2
>> 16) & 0xFF;
1137 target
->SetColorMod(0xff, RGBModifier::ADD
, speed
,
1138 fx
->Parameter1
>> 8, fx
->Parameter1
>> 16,
1139 fx
->Parameter1
>> 24);
1144 // 0x0A ConstitutionModifier
1145 int fx_constitution_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1147 if (0) printf( "fx_constitution_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1149 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1154 return FX_PERMANENT
;
1158 static EffectRef fx_poisoned_state_ref
={"State:Poisoned",NULL
,-1};
1160 int fx_cure_poisoned_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1162 if (0) printf( "fx_cure_poisoned_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1163 //all three steps are present in bg2 and iwd2
1164 BASE_STATE_CURE( STATE_POISONED
);
1165 target
->fxqueue
.RemoveAllEffects( fx_poisoned_state_ref
);
1166 target
->fxqueue
.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref
, PI_POISONED
);
1167 return FX_NOT_APPLIED
;
1171 // this is a very important effect
1172 int fx_damage (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
1174 if (0) printf( "fx_damage (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1175 //save for half damage type
1176 ieDword damagetype
= fx
->Parameter2
>>16;
1177 ieDword modtype
= fx
->Parameter2
&3;
1181 Scriptable
*caster
= GetCaster(Owner
, fx
);
1183 target
->Damage(fx
->Parameter1
, damagetype
, caster
, modtype
);
1184 //this effect doesn't stick
1185 return FX_NOT_APPLIED
;
1189 int fx_death (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
1191 if (0) printf( "fx_death (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1192 STAT_SET(IE_MINHITPOINTS
,0); //the die opcode seems to override minhp
1193 ieDword damagetype
= 0;
1194 switch (fx
->Parameter2
) {
1196 BASE_STATE_SET(STATE_D4
); //not sure, should be charred
1197 damagetype
= DAMAGE_FIRE
;
1200 damagetype
= DAMAGE_CRUSHING
;
1203 damagetype
= DAMAGE_CRUSHING
;
1206 damagetype
= DAMAGE_CRUSHING
|DAMAGE_CHUNKING
;
1209 BASE_STATE_SET(STATE_PETRIFIED
);
1210 damagetype
= DAMAGE_CRUSHING
;
1213 BASE_STATE_SET(STATE_FROZEN
);
1214 damagetype
= DAMAGE_COLD
;
1217 BASE_STATE_SET(STATE_PETRIFIED
);
1218 damagetype
= DAMAGE_CRUSHING
|DAMAGE_CHUNKING
;
1221 BASE_STATE_SET(STATE_FROZEN
);
1222 damagetype
= DAMAGE_COLD
|DAMAGE_CHUNKING
;
1225 damagetype
= DAMAGE_ELECTRICITY
;
1230 damagetype
= DAMAGE_ACID
;
1232 target
->Damage(0, damagetype
, Owner
);
1233 //death has damage type too
1235 //this effect doesn't stick
1236 return FX_NOT_APPLIED
;
1240 int fx_cure_frozen_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1242 if (0) printf( "fx_cure_frozen_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1243 BASE_STATE_CURE( STATE_FROZEN
);
1244 return FX_NOT_APPLIED
;
1247 // 0x0F DexterityModifier
1252 int SpellAbilityDieRoll(Actor
*target
, int which
)
1254 if (which
>=CSA_CNT
) return 6;
1256 ieDword cls
= STAT_GET(IE_CLASS
);
1257 if (!spell_abilities
) {
1258 AutoTable
tab("clssplab");
1260 spell_abilities
= (int *) malloc(sizeof(int)*CSA_CNT
);
1261 for (int ab
=0;ab
<CSA_CNT
;ab
++) {
1262 spell_abilities
[ab
*splabcount
]=6;
1267 splabcount
= tab
->GetRowCount();
1268 spell_abilities
=(int *) malloc(sizeof(int)*splabcount
*CSA_CNT
);
1269 for (int ab
=0;ab
<CSA_CNT
;ab
++) {
1270 for (ieDword i
=0;i
<splabcount
;i
++) {
1271 spell_abilities
[ab
*splabcount
+i
]=atoi(tab
->QueryField(i
,ab
));
1275 if (cls
>=splabcount
) cls
=0;
1276 return spell_abilities
[which
*splabcount
+cls
];
1279 int fx_dexterity_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1281 if (0) printf( "fx_dexterity_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1283 ////how cat's grace: value is based on class
1284 if (fx
->Parameter2
==3) {
1285 fx
->Parameter1
= core
->Roll(1,SpellAbilityDieRoll(target
,0),0);
1289 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1294 return FX_PERMANENT
;
1297 static EffectRef fx_set_slow_state_ref
={"State:Slowed",NULL
,-1};
1298 // 0x10 State:Hasted
1299 // this function removes slowed state, or sets hasted state
1300 int fx_set_hasted_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1302 if (0) printf( "fx_set_hasted_state (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
1303 target
->fxqueue
.RemoveAllEffects(fx_set_slow_state_ref
);
1304 target
->fxqueue
.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref
, PI_SLOWED
);
1305 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1306 BASE_STATE_CURE( STATE_SLOWED
);
1307 BASE_STATE_SET( STATE_HASTED
);
1309 STATE_CURE( STATE_SLOWED
);
1310 STATE_SET( STATE_HASTED
);
1312 target
->NewStat(IE_MOVEMENTRATE
, 200, MOD_PERCENT
);
1313 switch (fx
->Parameter2
) {
1314 case 0: //normal haste
1315 target
->AddPortraitIcon(PI_HASTED
);
1316 STAT_SET(IE_IMPROVEDHASTE
,0);
1317 STAT_SET(IE_ATTACKNUMBERDOUBLE
,0);
1318 STAT_ADD(IE_NUMBEROFATTACKS
, 2);
1319 // -2 initiative bonus
1320 STAT_ADD(IE_PHYSICALSPEED
, 2);
1322 case 1://improved haste
1323 target
->AddPortraitIcon(PI_IMPROVEDHASTE
);
1324 STAT_SET(IE_IMPROVEDHASTE
,1);
1325 STAT_SET(IE_ATTACKNUMBERDOUBLE
,0);
1326 target
->NewStat(IE_NUMBEROFATTACKS
, 200, MOD_PERCENT
);
1327 // -2 initiative bonus
1328 STAT_ADD(IE_PHYSICALSPEED
, 2);
1330 case 2://speed haste only
1331 target
->AddPortraitIcon(PI_HASTED
);
1332 STAT_SET(IE_IMPROVEDHASTE
,0);
1333 STAT_SET(IE_ATTACKNUMBERDOUBLE
,1);
1337 return FX_PERMANENT
;
1340 // 0x11 CurrentHPModifier
1341 int fx_current_hp_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1343 if (0) printf( "fx_current_hp_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1345 if (fx
->Parameter2
&0x10000) {
1346 target
->Resurrect();
1348 if (fx
->Parameter2
&0x20000) {
1349 target
->fxqueue
.RemoveAllNonPermanentEffects();
1351 //Cannot heal bloodrage
1352 if (target
->HasSpellState(SS_BLOODRAGE
)) {
1353 return FX_NOT_APPLIED
;
1356 target
->NewBase( IE_HITPOINTS
, fx
->Parameter1
, fx
->Parameter2
&0xffff);
1357 //never stay permanent
1358 return FX_NOT_APPLIED
;
1361 // 0x12 MaximumHPModifier
1362 // 0 and 3 differ in that 3 doesn't modify current hitpoints
1365 int fx_maximum_hp_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1367 if (0) printf( "fx_maximum_hp_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1369 bool base
= fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
;
1371 switch (fx
->Parameter2
) {
1373 // random value Parameter1 is set by level_check in EffectQueue
1375 BASE_ADD( IE_MAXHITPOINTS
, fx
->Parameter1
);
1376 BASE_ADD( IE_HITPOINTS
, fx
->Parameter1
);
1378 STAT_ADD( IE_MAXHITPOINTS
, fx
->Parameter1
);
1379 if (fx
->FirstApply
) {
1380 BASE_ADD( IE_HITPOINTS
, fx
->Parameter1
);
1385 // random value Parameter1 is set by level_check in EffectQueue
1387 BASE_ADD( IE_MAXHITPOINTS
, fx
->Parameter1
);
1389 STAT_ADD( IE_MAXHITPOINTS
, fx
->Parameter1
);
1394 BASE_SET( IE_MAXHITPOINTS
, fx
->Parameter1
);
1396 STAT_SET( IE_MAXHITPOINTS
, fx
->Parameter1
);
1401 BASE_MUL( IE_MAXHITPOINTS
, fx
->Parameter1
);
1403 STAT_MUL( IE_MAXHITPOINTS
, fx
->Parameter1
);
1407 return FX_PERMANENT
;
1410 // 0x13 IntelligenceModifier
1411 int fx_intelligence_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1413 if (0) printf( "fx_intelligence_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1415 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1420 return FX_PERMANENT
;
1423 // 0x14 State:Invisible
1424 // this is more complex, there is a half-invisibility state
1425 // and there is a hidden state
1426 int fx_set_invisible_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1428 switch (fx
->Parameter2
) {
1430 STATE_SET( STATE_INVISIBLE
);
1431 STAT_ADD(IE_TOHIT
, 4);
1434 STATE_SET( STATE_INVIS2
);
1435 HandleBonus(target
, IE_ARMORCLASS
, 4, fx
->TimingMode
);
1440 ieDword Trans
= fx
->Parameter4
;
1441 if (fx
->Parameter3
) {
1454 fx
->Parameter4
=Trans
;
1455 STAT_SET( IE_TRANSLUCENT
, Trans
);
1459 // 0x15 LoreModifier
1460 int fx_lore_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1462 if (0) printf( "fx_lore_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1464 STAT_MOD( IE_LORE
);
1468 // 0x16 LuckModifier
1469 int fx_luck_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1471 if (0) printf( "fx_luck_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1473 STAT_MOD( IE_LUCK
);
1474 STAT_MOD( IE_DAMAGELUCK
);
1478 // 0x17 MoraleModifier
1479 int fx_morale_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1481 if (0) printf( "fx_morale_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1483 STAT_MOD( IE_MORALE
);
1488 int fx_set_panic_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1490 if (0) printf( "fx_set_panic_state (%2d)\n", fx
->Opcode
);
1492 if (target
->HasSpellState(SS_BLOODRAGE
)) {
1493 return FX_NOT_APPLIED
;
1496 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1497 BASE_STATE_SET( STATE_PANIC
);
1499 STATE_SET( STATE_PANIC
);
1501 if (enhanced_effects
) {
1502 target
->AddPortraitIcon(PI_PANIC
);
1504 return FX_PERMANENT
;
1507 // 0x19 State:Poisoned
1508 int fx_set_poisoned_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
1510 if (0) printf( "fx_set_poisoned_state (%2d): Damage: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1511 //apparently this bit isn't set, but then why is it here
1512 //this requires a little research
1513 STATE_SET( STATE_POISONED
);
1514 //also this effect is executed every update
1516 int tmp
= fx
->Parameter1
;
1518 HandlePercentageDamage(fx
, target
);
1520 switch(fx
->Parameter2
) {
1522 tmp
*= ROUND_SECONDS
;
1526 tmp
*= ROUND_PER_TURN
*ROUND_SECONDS
;
1532 case RPD_PERCENT
: // handled in HandlePercentageDamage
1534 tmp
= 1; // hit points per second
1535 damage
= fx
->Parameter1
;
1543 // all damage is at most per-second
1544 tmp
*= AI_UPDATE_TIME
;
1545 if (tmp
&& (core
->GetGame()->GameTime
%tmp
)) {
1549 Scriptable
*caster
= GetCaster(Owner
, fx
);
1552 target
->Damage(damage
, DAMAGE_POISON
, caster
);
1557 static EffectRef fx_apply_effect_curse_ref
={"ApplyEffectCurse",NULL
,-1};
1558 static EffectRef fx_pst_jumble_curse_ref
={"JumbleCurse",NULL
,-1};
1560 // gemrb extension: if the resource field is filled, it will remove curse only from the specified item
1561 int fx_remove_curse (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1563 if (0) printf( "fx_remove_curse (%2d): Resource: %s Type: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
1565 switch(fx
->Parameter2
)
1568 //this is pst specific
1569 target
->fxqueue
.RemoveAllEffects(fx_pst_jumble_curse_ref
);
1572 Inventory
*inv
= &target
->inventory
;
1573 int i
= target
->inventory
.GetSlotCount();
1575 //does this slot need unequipping
1576 if (core
->QuerySlotEffects(i
) ) {
1577 if (fx
->Resource
[0] && strnicmp(inv
->GetSlotItem(i
)->ItemResRef
, fx
->Resource
,8) ) {
1580 if (!(inv
->GetItemFlag(i
)&IE_INV_ITEM_CURSED
)) {
1583 inv
->ChangeItemFlag(i
, IE_INV_ITEM_CURSED
, BM_NAND
);
1584 if (inv
->UnEquipItem(i
,true)) {
1585 CREItem
*tmp
= inv
->RemoveItem(i
);
1586 if(inv
->AddSlotItem(tmp
,-3)!=ASI_SUCCESS
) {
1587 //if the item couldn't be placed in the inventory, then put it back to the original slot
1588 inv
->SetSlotItem(tmp
,i
);
1589 //and drop it in the area. (If there is no area, then the item will stay in the inventory)
1590 target
->DropItem(i
,0);
1595 target
->fxqueue
.RemoveAllEffects(fx_apply_effect_curse_ref
);
1598 //this is an instant effect
1599 return FX_NOT_APPLIED
;
1602 // 0x1b AcidResistanceModifier
1603 int fx_acid_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1605 if (0) printf( "fx_acid_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1607 STAT_MOD( IE_RESISTACID
);
1611 // 0x1c ColdResistanceModifier
1612 int fx_cold_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1614 if (0) printf( "fx_cold_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1616 STAT_MOD( IE_RESISTCOLD
);
1620 // 0x1d ElectricityResistanceModifier
1621 int fx_electricity_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1623 if (0) printf( "fx_electricity_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1625 STAT_MOD( IE_RESISTELECTRICITY
);
1629 // 0x1e FireResistanceModifier
1630 int fx_fire_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1632 if (0) printf( "fx_fire_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1634 STAT_MOD( IE_RESISTFIRE
);
1638 // 0x1f MagicDamageResistanceModifier
1639 int fx_magic_damage_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1641 if (0) printf( "fx_magic_damage_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1643 STAT_MOD( IE_MAGICDAMAGERESISTANCE
);
1648 int fx_cure_dead_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1650 if (0) printf( "fx_cure_dead_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1651 //someone should clear the internal flags related to death
1652 target
->Resurrect();
1653 return FX_NOT_APPLIED
;
1656 // 0x21 SaveVsDeathModifier
1657 int fx_save_vs_death_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1659 if (0) printf( "fx_save_vs_death_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1661 HandleBonus( target
, IE_SAVEVSDEATH
, fx
->Parameter1
, fx
->TimingMode
);
1665 // 0x22 SaveVsWandsModifier
1666 int fx_save_vs_wands_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1668 if (0) printf( "fx_save_vs_wands_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1670 HandleBonus( target
, IE_SAVEVSWANDS
, fx
->Parameter1
, fx
->TimingMode
);
1674 // 0x23 SaveVsPolyModifier
1675 int fx_save_vs_poly_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1677 if (0) printf( "fx_save_vs_poly_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1679 HandleBonus( target
, IE_SAVEVSPOLY
, fx
->Parameter1
, fx
->TimingMode
);
1683 // 0x24 SaveVsBreathModifier
1684 int fx_save_vs_breath_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1686 if (0) printf( "fx_save_vs_breath_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1688 HandleBonus( target
, IE_SAVEVSBREATH
, fx
->Parameter1
, fx
->TimingMode
);
1692 // 0x25 SaveVsSpellsModifier
1693 int fx_save_vs_spell_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1695 if (0) printf( "fx_save_vs_spell_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1697 HandleBonus( target
, IE_SAVEVSSPELL
, fx
->Parameter1
, fx
->TimingMode
);
1701 // 0x26 State:Silenced
1702 int fx_set_silenced_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1704 if (0) printf( "fx_set_silenced_state (%2d)\n", fx
->Opcode
);
1705 STATE_SET( STATE_SILENCED
);
1709 static EffectRef fx_animation_stance_ref
= {"AnimationStateChange",NULL
,-1};
1711 // 0x27 State:Helpless
1712 // this effect sets both bits, but 'awaken' only removes the sleep bit
1713 // FIXME: this is probably a persistent effect
1714 int fx_set_unconscious_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
1716 if (0) printf( "fx_set_unconscious_state (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
1718 if (target
->HasSpellState(SS_BLOODRAGE
)) {
1719 return FX_NOT_APPLIED
;
1722 if (fx
->FirstApply
) {
1725 newfx
= EffectQueue::CreateEffectCopy(fx
, fx_animation_stance_ref
, 0, IE_ANI_SLEEP
);
1726 core
->ApplyEffect(newfx
, target
, Owner
);
1731 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1732 BASE_STATE_SET( STATE_HELPLESS
| STATE_SLEEP
); //don't awaken on damage
1734 STATE_SET( STATE_HELPLESS
| STATE_SLEEP
); //don't awaken on damage
1735 if (fx
->Parameter2
) {
1736 target
->SetSpellState(SS_NOAWAKE
);
1738 target
->AddPortraitIcon(PI_SLEEP
);
1740 return FX_PERMANENT
;
1743 // 0x28 State:Slowed
1744 // this function removes hasted state, or sets slowed state
1745 static EffectRef fx_set_haste_state_ref
={"State:Hasted",NULL
,-1};
1747 int fx_set_slowed_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1749 if (0) printf( "fx_set_slowed_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1751 //iwd2 free action or aegis disables this effect
1752 if (target
->HasSpellState(SS_FREEACTION
)) return FX_NOT_APPLIED
;
1753 if (target
->HasSpellState(SS_AEGIS
)) return FX_NOT_APPLIED
;
1755 if (STATE_GET(STATE_HASTED
) ) {
1756 BASE_STATE_CURE( STATE_HASTED
);
1757 target
->fxqueue
.RemoveAllEffects( fx_set_haste_state_ref
);
1758 target
->fxqueue
.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref
, PI_HASTED
);
1760 STATE_SET( STATE_SLOWED
);
1761 target
->AddPortraitIcon(PI_SLOWED
);
1762 // halve apr and speed
1763 STAT_MUL(IE_NUMBEROFATTACKS
, 50);
1764 STAT_MUL(IE_MOVEMENTRATE
, 50);
1766 return FX_PERMANENT
;
1770 int fx_sparkle (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1772 if (0) printf( "fx_sparkle (%2d): Sparkle colour: %d ; Sparkle type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1774 return FX_NOT_APPLIED
;
1777 Map
*map
= target
->GetCurrentArea();
1781 Point
p(fx
->PosX
, fx
->PosY
);
1783 //the IE programmers did something unexpected, again, a permutation!
1786 if (fx
->Parameter1
<SPARK_COUNT
) {
1787 idx
= spark_color_indices
[fx
->Parameter1
];
1792 map
->Sparkle( idx
, fx
->Parameter2
, p
, fx
->Parameter3
);
1793 return FX_NOT_APPLIED
;
1796 // 0x2A WizardSpellSlotsModifier
1797 int fx_bonus_wizard_spells (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1799 if (0) printf( "fx_bonus_wizard_spells (%2d): Spell Add: %d ; Spell Level: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1802 //if param2 is 0, then double spells up to param1
1803 if(!fx
->Parameter2
) {
1804 for (unsigned int j
=0;j
<fx
->Parameter1
&& j
<MAX_SPELL_LEVEL
;j
++) {
1805 target
->spellbook
.SetMemorizableSpellsCount(0, IE_SPELL_TYPE_WIZARD
, j
, true);
1810 //if param2 is 0x200, then double spells at param1
1811 if (fx
->Parameter2
==0x200) {
1812 unsigned int j
= fx
->Parameter1
-1;
1813 if (j
<MAX_SPELL_LEVEL
) {
1814 target
->spellbook
.SetMemorizableSpellsCount(0, IE_SPELL_TYPE_WIZARD
, j
, true);
1818 for(unsigned int j
=0;j
<MAX_SPELL_LEVEL
;j
++) {
1819 if (fx
->Parameter2
&i
) {
1820 target
->spellbook
.SetMemorizableSpellsCount(fx
->Parameter1
, IE_SPELL_TYPE_WIZARD
, j
, true);
1827 // 0x2B Cure:Petrification
1828 int fx_cure_petrified_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1830 if (0) printf( "fx_cure_petrified_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1831 BASE_STATE_CURE( STATE_PETRIFIED
);
1832 return FX_NOT_APPLIED
;
1835 // 0x2C StrengthModifier
1836 int fx_strength_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1838 if (0) printf( "fx_strength_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1840 ////how strength: value is based on class
1841 if (fx
->Parameter2
==3) {
1842 fx
->Parameter1
= core
->Roll(1,SpellAbilityDieRoll(target
,1),0);
1846 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1851 return FX_PERMANENT
;
1855 int power_word_stun_iwd2(Actor
*target
, Effect
*fx
)
1857 int hp
= BASE_GET(IE_HITPOINTS
);
1858 if (hp
>150) return FX_NOT_APPLIED
;
1860 if (hp
>100) stuntime
= core
->Roll(1,4,0);
1861 else if (hp
>50) stuntime
= core
->Roll(2,4,0);
1862 else stuntime
= core
->Roll(4,4,0);
1864 fx
->TimingMode
= FX_DURATION_ABSOLUTE
;
1865 fx
->Duration
= stuntime
*6*ROUND_SIZE
+ core
->GetGame()->GameTime
;
1866 STATE_SET( STATE_STUNNED
);
1867 target
->AddPortraitIcon(PI_STUN
);
1871 int fx_set_stun_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1873 if (0) printf( "fx_set_stun_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1875 if ( STATE_GET(STATE_DEAD
) ) {
1876 return FX_NOT_APPLIED
;
1879 if (target
->HasSpellState(SS_BLOODRAGE
)) {
1880 return FX_NOT_APPLIED
;
1883 if (fx
->Parameter2
==2) {
1884 return power_word_stun_iwd2(target
, fx
);
1886 STATE_SET( STATE_STUNNED
);
1887 target
->AddPortraitIcon(PI_STUN
);
1888 if (fx
->Parameter2
==1) {
1889 target
->SetSpellState(SS_AWAKE
);
1895 static EffectRef fx_set_stun_state_ref
={"State:Stun",NULL
,-1};
1896 static EffectRef fx_hold_creature_no_icon_ref
={"State:Hold3",NULL
,-1};
1898 int fx_cure_stun_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1900 if (0) printf( "fx_cure_stun_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1901 BASE_STATE_CURE( STATE_STUNNED
);
1902 target
->fxqueue
.RemoveAllEffects(fx_set_stun_state_ref
);
1903 target
->fxqueue
.RemoveAllEffects(fx_hold_creature_no_icon_ref
);
1904 target
->fxqueue
.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref
, PI_HELD
);
1905 target
->fxqueue
.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref
, PI_HOPELESS
);
1906 return FX_NOT_APPLIED
;
1909 // 0x2F Cure:Invisible
1910 // 0x74 Cure:Invisible2
1911 static EffectRef fx_set_invisible_state_ref
={"State:Invisible",NULL
,-1};
1913 int fx_cure_invisible_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1915 if (0) printf( "fx_cure_invisible_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1916 if (!STATE_GET(STATE_NONDET
)) {
1917 BASE_STATE_CURE( STATE_INVISIBLE
| STATE_INVIS2
);
1918 target
->fxqueue
.RemoveAllEffects(fx_set_invisible_state_ref
);
1920 return FX_NOT_APPLIED
;
1923 // 0x30 Cure:Silence
1924 static EffectRef fx_set_silenced_state_ref
={"State:Silenced",NULL
,-1};
1926 int fx_cure_silenced_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1928 if (0) printf( "fx_cure_silenced_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1929 BASE_STATE_CURE( STATE_SILENCED
);
1930 target
->fxqueue
.RemoveAllEffects(fx_set_silenced_state_ref
);
1931 return FX_NOT_APPLIED
;
1934 // 0x31 WisdomModifier
1935 int fx_wisdom_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1937 if (0) printf( "fx_wisdom_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1939 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
1944 return FX_PERMANENT
;
1947 // 0x32 Color:BriefRGB
1948 int fx_brief_rgb (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1950 if (0) printf( "fx_brief_rgb (%2d): RGB: %d, Location and speed: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1952 int speed
= (fx
->Parameter2
>> 16) & 0xff;
1953 target
->SetColorMod(0xff, RGBModifier::ADD
, speed
,
1954 fx
->Parameter1
>> 8, fx
->Parameter1
>> 16,
1955 fx
->Parameter1
>> 24, 0);
1957 return FX_NOT_APPLIED
;
1960 // 0x33 Color:DarkenRGB
1961 int fx_darken_rgb (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1963 if (0) printf( "fx_darken_rgb (%2d): RGB: %d, Location and speed: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1964 EffectQueue::HackColorEffects(target
, fx
);
1965 ieDword location
= fx
->Parameter2
& 0xff;
1966 target
->SetColorMod(location
, RGBModifier::TINT
, -1, fx
->Parameter1
>> 8,
1967 fx
->Parameter1
>> 16, fx
->Parameter1
>> 24);
1971 // 0x34 Color:GlowRGB
1972 int fx_glow_rgb (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1974 if (0) printf( "fx_glow_rgb (%2d): RGB: %d, Location and speed: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1975 EffectQueue::HackColorEffects(target
, fx
);
1976 ieDword location
= fx
->Parameter2
& 0xff;
1977 target
->SetColorMod(location
, RGBModifier::BRIGHTEN
, -1,
1978 fx
->Parameter1
>> 8, fx
->Parameter1
>> 16,
1979 fx
->Parameter1
>> 24);
1984 // 0x35 AnimationIDModifier
1985 static EffectRef fx_animation_id_modifier_ref
={"AnimationIDModifier",NULL
,-1};
1987 int fx_animation_id_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
1989 if (0) printf( "fx_animation_id_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
1991 switch (fx
->Parameter2
) {
1992 case 0: //non permanent animation change
1994 STAT_SET( IE_ANIMATION_ID
, fx
->Parameter1
);
1996 case 1: //remove any non permanent change
1997 target
->fxqueue
.RemoveAllEffects(fx_animation_id_modifier_ref
);
1998 //return FX_NOT_APPLIED;
1999 //intentionally passing through (perma change removes previous changes)
2000 case 2: //permanent animation id change
2001 target
->SetBaseNoPCF(IE_ANIMATION_ID
, fx
->Parameter1
);
2002 return FX_NOT_APPLIED
;
2006 // 0x36 ToHitModifier
2007 int fx_to_hit_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2009 if (0) printf( "fx_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2011 HandleBonus( target
, IE_TOHIT
, fx
->Parameter1
, fx
->TimingMode
);
2015 // 0x37 KillCreatureType
2016 static EffectRef fx_death_ref
={"Death",NULL
,-1};
2018 int fx_kill_creature_type (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2020 if (0) printf( "fx_kill_creature_type (%2d): Value: %d, IDS: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2021 if (EffectQueue::match_ids( target
, fx
->Parameter2
, fx
->Parameter1
) ) {
2022 //convert it to a death opcode or apply the new effect?
2023 fx
->Opcode
= EffectQueue::ResolveEffect(fx_death_ref
);
2024 fx
->TimingMode
= FX_DURATION_INSTANT_PERMANENT
;
2030 return FX_NOT_APPLIED
;
2033 // 0x38 Alignment:Invert
2034 //switch good to evil and evil to good
2035 //also switch chaotic to lawful and vice versa
2036 //gemrb extension: param2 actually controls which parts should be reversed
2037 // 0 - switch both (as original)
2038 // 1 - switch good and evil
2039 // 2 - switch lawful and chaotic
2041 static int al_switch_both
[16]={0,0x33,0x32,0x31,0,0x23,0x22,0x21,0,0x13,0x12,0x11};
2042 static int al_switch_law
[16]={0,0x31,0x32,0x33,0,0x21,0x22,0x23,0,0x11,0x12,0x13};
2043 static int al_switch_good
[16]={0,0x13,0x12,0x11,0,0x23,0x22,0x21,0,0x33,0x32,0x31};
2044 int fx_alignment_invert (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2046 if (0) printf( "fx_alignment_invert (%2d)\n", fx
->Opcode
);
2047 register ieDword newalign
= target
->GetStat( IE_ALIGNMENT
);
2048 //compress the values. GNE is the first 2 bits originally
2049 //LNC is the 4/5. bits.
2050 newalign
= (newalign
& AL_GE_MASK
) | ((newalign
& AL_LC_MASK
)>>2);
2051 switch (fx
->Parameter2
) {
2053 newalign
= al_switch_both
[newalign
];
2055 case 1: //switch good/evil
2056 newalign
= al_switch_good
[newalign
];
2059 newalign
= al_switch_law
[newalign
];
2062 STAT_SET( IE_ALIGNMENT
, newalign
);
2066 // 0x39 Alignment:Change
2067 int fx_alignment_change (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2069 if (0) printf( "fx_alignment_change (%2d): Value: %d\n", fx
->Opcode
, fx
->Parameter2
);
2070 STAT_SET( IE_ALIGNMENT
, fx
->Parameter2
);
2074 // 0x3a DispelEffects
2075 int fx_dispel_effects (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2077 if (0) printf( "fx_dispel_effects (%2d): Value: %d, IDS: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2080 switch (fx
->Parameter2
) {
2086 //same level: 50% success, each diff modifies it by 5%
2087 level
= core
->Roll(1,20,fx
->Power
-10);
2088 if (level
>=0x80000000) level
= 0;
2091 //same level: 50% success, each diff modifies it by 5%
2092 level
= core
->Roll(1,20,fx
->Parameter1
-10);
2093 if (level
>=0x80000000) level
= 0;
2096 //if signed would it be negative?
2097 target
->fxqueue
.RemoveLevelEffects(level
, RL_DISPELLABLE
, 0);
2098 return FX_NOT_APPLIED
;
2101 // 0x3B StealthModifier
2102 int fx_stealth_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2104 if (0) printf( "fx_stealth_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2106 STAT_MOD( IE_STEALTH
);
2110 // 0x3C MiscastMagicModifier
2111 int fx_miscast_magic_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2113 if (0) printf( "fx_miscast_magic_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2115 switch (fx
->Parameter2
) {
2117 STAT_SET( IE_DEADMAGIC
, 1);
2119 STAT_SET( IE_SPELLFAILUREMAGE
, fx
->Parameter1
);
2122 STAT_SET( IE_DEADMAGIC
, 1);
2124 STAT_SET( IE_SPELLFAILUREPRIEST
, fx
->Parameter1
);
2127 STAT_SET( IE_DEADMAGIC
, 1);
2129 STAT_SET( IE_SPELLFAILUREINNATE
, fx
->Parameter1
);
2132 return FX_NOT_APPLIED
;
2137 // 0x3D AlchemyModifier
2138 // this crashes in bg2 due to assertion failure (disabled intentionally)
2139 // and in iwd it doesn't really follow the stat_mod convention (quite lame)
2140 int fx_alchemy_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2142 if (0) printf( "fx_alchemy_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2144 switch(fx
->Parameter2
) {
2146 STAT_ADD( IE_ALCHEMY
, fx
->Parameter1
);
2149 STAT_SET( IE_ALCHEMY
, fx
->Parameter1
);
2152 STAT_SET( IE_ALCHEMY
, 100 );
2158 // 0x3E PriestSpellSlotsModifier
2159 int fx_bonus_priest_spells (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2161 if (0) printf( "fx_bonus_priest_spells (%2d): Spell Add: %d ; Spell Level: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2164 //if param2 is 0, then double spells up to param1
2165 if(!fx
->Parameter2
) {
2166 for (unsigned int j
=0;j
<fx
->Parameter1
&& j
<MAX_SPELL_LEVEL
;j
++) {
2167 target
->spellbook
.SetMemorizableSpellsCount(0, IE_SPELL_TYPE_PRIEST
, j
, true);
2173 //if param2 is 0x200, then double spells at param1
2174 if (fx
->Parameter2
==0x200) {
2175 unsigned int j
= fx
->Parameter1
-1;
2176 target
->spellbook
.SetMemorizableSpellsCount(fx
->Parameter1
, IE_SPELL_TYPE_PRIEST
, j
, true);
2180 for(unsigned int j
=0;j
<MAX_SPELL_LEVEL
;j
++) {
2181 if (fx
->Parameter2
&i
) {
2182 target
->spellbook
.SetMemorizableSpellsCount(fx
->Parameter1
, IE_SPELL_TYPE_PRIEST
, j
, true);
2189 // 0x3F State:Infravision
2190 int fx_set_infravision_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2192 if (0) printf( "fx_set_infravision_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2193 STATE_SET( STATE_INFRA
);
2197 // 0x40 Cure:Infravision
2198 static EffectRef fx_set_infravision_state_ref
={"State:Infravision",NULL
,-1};
2200 int fx_cure_infravision_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2202 if (0) printf( "fx_cure_infravision_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2203 BASE_STATE_CURE( STATE_INFRA
);
2204 target
->fxqueue
.RemoveAllEffects(fx_set_infravision_state_ref
);
2205 return FX_NOT_APPLIED
;
2209 int fx_set_blur_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2211 if (0) printf( "fx_set_blur_state (%2d)\n", fx
->Opcode
);
2212 if (STATE_GET( STATE_DEAD
) ) {
2213 return FX_NOT_APPLIED
;
2215 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
2216 BASE_STATE_SET( STATE_BLUR
);
2218 STATE_SET( STATE_BLUR
);
2221 if (enhanced_effects
) {
2222 target
->AddPortraitIcon(PI_BLUR
);
2224 return FX_PERMANENT
;
2227 // 0x42 TransparencyModifier
2228 int fx_transparency_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2230 if (0) printf( "fx_transparency_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2232 //maybe this needs some timing
2233 switch (fx
->Parameter2
) {
2235 if (fx
->Parameter1
<255) {
2236 if (core
->GetGame()->GameTime
%2) {
2242 if (fx
->Parameter1
) {
2243 if (core
->GetGame()->GameTime
%2) {
2249 STAT_MOD( IE_TRANSLUCENT
);
2253 // 0x43 SummonCreature
2255 static int eamods
[]={EAM_ALLY
,EAM_ALLY
,EAM_DEFAULT
,EAM_ALLY
,EAM_DEFAULT
,EAM_ENEMY
,EAM_ALLY
};
2257 int fx_summon_creature (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
2259 if (0) printf( "fx_summon_creature (%2d): ResRef:%s Anim:%s Type: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Resource2
, fx
->Parameter2
);
2261 return FX_NOT_APPLIED
;
2264 if (!target
->GetCurrentArea()) {
2268 //summon creature (resource), play vvc (resource2)
2269 //creature's lastsummoner is Owner
2270 //creature's target is target
2271 //position of appearance is target's pos
2273 if (fx
->Parameter2
<6){
2274 eamod
= eamods
[fx
->Parameter2
];
2277 //the monster should appear near the effect position
2278 Point
p(fx
->PosX
, fx
->PosY
);
2280 Effect
*newfx
= EffectQueue::CreateUnsummonEffect(fx
);
2281 core
->SummonCreature(fx
->Resource
, fx
->Resource2
, Owner
, target
, p
, eamod
, 0, newfx
);
2283 return FX_NOT_APPLIED
;
2286 // 0x44 UnsummonCreature
2287 int fx_unsummon_creature (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2289 if (0) printf( "fx_unsummon_creature (%2d)\n", fx
->Opcode
);
2291 //to be compatible with the original engine, unsummon doesn't work with PC's
2292 //but it works on anything else
2293 if (!target
->InParty
) {
2294 //play the vanish animation
2295 ScriptedAnimation
* sca
= gamedata
->GetScriptedAnimation(fx
->Resource
, false);
2297 sca
->XPos
+=target
->Pos
.x
;
2298 sca
->YPos
+=target
->Pos
.y
;
2299 target
->GetCurrentArea()->AddVVCell(sca
);
2301 //remove the creature
2302 target
->DestroySelf();
2304 return FX_NOT_APPLIED
;
2307 // 0x45 State:Nondetection
2308 int fx_set_nondetection_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2310 if (0) printf( "fx_set_nondetection_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2311 STATE_SET( STATE_NONDET
);
2315 // 0x46 Cure:Nondetection
2316 static EffectRef fx_set_nondetection_state_ref
={"State:Nondetection",NULL
,-1};
2318 int fx_cure_nondetection_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2320 if (0) printf( "fx_cure_nondetection_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2321 BASE_STATE_CURE( STATE_NONDET
);
2322 target
->fxqueue
.RemoveAllEffects(fx_set_nondetection_state_ref
);
2323 return FX_NOT_APPLIED
;
2327 int fx_sex_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2329 if (0) printf( "fx_sex_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2331 if (fx
->Parameter2
) {
2332 value
= fx
->Parameter1
;
2334 if (STAT_GET(IE_SEX_CHANGED
)) {
2335 return FX_NOT_APPLIED
;
2337 STAT_SET( IE_SEX_CHANGED
, 1);
2338 value
= STAT_GET(IE_SEX
);
2339 if (value
==SEX_MALE
) {
2345 STAT_SET( IE_SEX
, value
);
2349 // 0x48 AIIdentifierModifier
2350 int fx_ids_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2352 if (0) printf( "fx_ids_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2353 switch (fx
->Parameter2
) {
2355 STAT_SET(IE_EA
, fx
->Parameter1
);
2358 STAT_SET(IE_GENERAL
, fx
->Parameter1
);
2361 STAT_SET(IE_RACE
, fx
->Parameter1
);
2364 STAT_SET(IE_CLASS
, fx
->Parameter1
);
2367 STAT_SET(IE_SPECIFIC
, fx
->Parameter1
);
2370 STAT_SET(IE_SEX
, fx
->Parameter1
);
2373 STAT_SET(IE_ALIGNMENT
, fx
->Parameter1
);
2376 return FX_NOT_APPLIED
;
2378 //not sure, need a check if this action could be permanent
2382 // 0x49 DamageBonusModifier
2383 int fx_damage_bonus_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2385 if (0) printf( "fx_damage_bonus_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2387 STAT_MOD( IE_DAMAGEBONUS
);
2392 int fx_set_blind_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2394 if (0) printf( "fx_set_blind_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2396 //don't do this effect twice (bug exists in BG2, but fixed in IWD2)
2397 if (!STATE_GET(STATE_BLIND
)) {
2398 STATE_SET( STATE_BLIND
);
2399 //the feat normally exists only in IWD2, but won't hurt
2400 if (!target
->GetFeat(FEAT_BLIND_FIGHT
)) {
2401 STAT_SUB (IE_TOHIT
, 10); // all other tohit stats are treated as bonuses
2408 static EffectRef fx_set_blind_state_ref
={"State:Blind",NULL
,-1};
2410 int fx_cure_blind_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2412 if (0) printf( "fx_cure_blind_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2413 BASE_STATE_CURE( STATE_BLIND
);
2414 target
->fxqueue
.RemoveAllEffects(fx_set_blind_state_ref
);
2415 return FX_NOT_APPLIED
;
2418 // 0x4c State:Feeblemind
2419 int fx_set_feebleminded_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2421 if (0) printf( "fx_set_feebleminded_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2422 STATE_SET( STATE_FEEBLE
);
2423 STAT_SET( IE_INT
, 3);
2424 if (enhanced_effects
) {
2425 target
->AddPortraitIcon(PI_FEEBLEMIND
);
2430 // 0x4d Cure:Feeblemind
2431 static EffectRef fx_set_feebleminded_state_ref
={"State:Feeblemind",NULL
,-1};
2433 int fx_cure_feebleminded_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2435 if (0) printf( "fx_cure_feebleminded_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2436 BASE_STATE_CURE( STATE_FEEBLE
);
2437 target
->fxqueue
.RemoveAllEffects(fx_set_feebleminded_state_ref
);
2438 target
->fxqueue
.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref
, PI_FEEBLEMIND
);
2439 return FX_NOT_APPLIED
;
2442 // 0x4e State:Diseased
2443 int fx_set_diseased_state (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
2445 if (0) printf( "fx_set_diseased_state (%2d): Damage: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2446 //STATE_SET( STATE_DISEASED ); //no this we don't want
2448 //setting damage to 0 because not all types do damage
2451 HandlePercentageDamage(fx
, target
);
2453 switch(fx
->Parameter2
) {
2456 if (fx
->Parameter1
&& (core
->GetGame()->GameTime
%(fx
->Parameter1
*AI_UPDATE_TIME
))) {
2460 case RPD_PERCENT
: // handled in HandlePercentageDamage
2462 damage
= fx
->Parameter1
;
2464 if (core
->GetGame()->GameTime
%AI_UPDATE_TIME
) {
2468 case RPD_STR
: //strength
2469 STAT_ADD(IE_STR
, fx
->Parameter1
);
2472 STAT_ADD(IE_DEX
, fx
->Parameter1
);
2475 STAT_ADD(IE_CON
, fx
->Parameter1
);
2478 STAT_ADD(IE_INT
, fx
->Parameter1
);
2481 STAT_ADD(IE_WIS
, fx
->Parameter1
);
2484 STAT_ADD(IE_CHR
, fx
->Parameter1
);
2486 case RPD_SLOW
: //slow
2493 Scriptable
*caster
= GetCaster(Owner
, fx
);
2496 target
->Damage(damage
, DAMAGE_POISON
, caster
);
2502 // 0x4f Cure:Disease
2503 static EffectRef fx_diseased_state_ref
={"State:Diseased",NULL
,-1};
2505 int fx_cure_diseased_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2507 if (0) printf( "fx_cure_diseased_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2508 //STATE_CURE( STATE_DISEASED ); //the bit flagged as disease is actually the active state. so this is even more unlikely to be used as advertised
2509 target
->fxqueue
.RemoveAllEffects( fx_diseased_state_ref
); //this is what actually happens in bg2
2510 return FX_NOT_APPLIED
;
2513 // 0x50 State:Deafness
2514 // gemrb extension: modifiable amount
2515 // none of the engines care about stacking
2516 int fx_set_deaf_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2518 if (0) printf( "fx_set_deaf_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2521 if (target
->SetSpellState(SS_DEAF
)) return FX_APPLIED
;
2523 if (!fx
->Parameter1
) {
2524 fx
->Parameter1
= 50;
2526 STAT_ADD(IE_SPELLFAILUREMAGE
, fx
->Parameter1
);
2527 if (!fx
->Parameter2
) {
2528 fx
->Parameter1
= 50;
2530 STAT_ADD(IE_SPELLFAILUREPRIEST
, fx
->Parameter2
);
2531 EXTSTATE_SET(EXTSTATE_DEAF
); //iwd1/how needs this
2532 if (enhanced_effects
) {
2533 target
->AddPortraitIcon(PI_DEAFNESS
);
2538 int fx_set_deaf_state_iwd2 (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2540 if (0) printf( "fx_set_deaf_state_iwd2 (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2543 if (target
->SetSpellState(SS_DEAF
)) return FX_APPLIED
;
2545 if (!fx
->Parameter1
) {
2546 //this is a bad hack
2547 fx
->Parameter1
= 20;
2549 STAT_ADD(IE_SPELLFAILUREMAGE
, fx
->Parameter1
);
2550 if (!fx
->Parameter2
) {
2551 fx
->Parameter1
= 20;
2553 STAT_ADD(IE_SPELLFAILUREPRIEST
, fx
->Parameter2
);
2554 EXTSTATE_SET(EXTSTATE_DEAF
); //iwd1/how needs this
2555 target
->AddPortraitIcon(PI_DEAFNESS
); //iwd2 specific
2559 // 0x51 Cure:Deafness
2560 static EffectRef fx_deaf_state_ref
={"State:Deafness",NULL
,-1};
2561 static EffectRef fx_deaf_state_iwd2_ref
={"State:DeafnessIWD2",NULL
,-1};
2563 //removes the deafness effect
2564 int fx_cure_deaf_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2566 if (0) printf( "fx_cure_deaf_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2568 target
->fxqueue
.RemoveAllEffects(fx_deaf_state_ref
);
2569 target
->fxqueue
.RemoveAllEffects(fx_deaf_state_iwd2_ref
);
2570 return FX_NOT_APPLIED
;
2574 int fx_set_ai_script (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2576 if (0) printf( "fx_set_ai_state (%2d): Resource: %s, Type: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
2577 target
->SetScript (fx
->Resource
, fx
->Parameter2
);
2578 return FX_NOT_APPLIED
;
2581 // 0x53 Protection:Projectile
2582 int fx_protection_from_projectile (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2584 if (0) printf( "fx_protection_from_projectile (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
2585 STAT_BIT_OR( IE_IMMUNITY
, IMM_PROJECTILE
);
2589 // 0x54 MagicalFireResistanceModifier
2590 int fx_magical_fire_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2592 if (0) printf( "fx_magical_fire_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2594 STAT_MOD( IE_RESISTMAGICFIRE
);
2598 // 0x55 MagicalColdResistanceModifier
2599 int fx_magical_cold_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2601 if (0) printf( "fx_magical_cold_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2603 STAT_MOD( IE_RESISTMAGICCOLD
);
2607 // 0x56 SlashingResistanceModifier
2608 int fx_slashing_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2610 if (0) printf( "fx_slashing_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2612 STAT_MOD( IE_RESISTSLASHING
);
2616 // 0x57 CrushingResistanceModifier
2617 int fx_crushing_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2619 if (0) printf( "fx_crushing_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2621 STAT_MOD( IE_RESISTCRUSHING
);
2625 // 0x58 PiercingResistanceModifier
2626 int fx_piercing_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2628 if (0) printf( "fx_piercing_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2630 STAT_MOD( IE_RESISTPIERCING
);
2634 // 0x59 MissilesResistanceModifier
2635 int fx_missiles_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2637 if (0) printf( "fx_missiles_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2639 STAT_MOD( IE_RESISTMISSILE
);
2643 // 0x5A OpenLocksModifier
2644 int fx_open_locks_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2646 if (0) printf( "fx_open_locks_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2648 STAT_MOD( IE_LOCKPICKING
);
2652 // 0x5B FindTrapsModifier
2653 int fx_find_traps_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2655 if (0) printf( "fx_find_traps_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2657 STAT_MOD( IE_TRAPS
);
2661 // 0x5C PickPocketsModifier
2662 int fx_pick_pockets_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2664 if (0) printf( "fx_pick_pockets_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2666 STAT_MOD( IE_PICKPOCKET
);
2670 // 0x5D FatigueModifier
2671 int fx_fatigue_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2673 if (0) printf( "fx_fatigue_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2675 STAT_MOD( IE_FATIGUE
);
2676 // TODO: fatigue has a negative effect on luck -> add fatigmod.2da support
2680 // 0x5E IntoxicationModifier
2681 int fx_intoxication_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2683 if (0) printf( "fx_intoxication_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2685 STAT_MOD( IE_INTOXICATION
);
2689 // 0x5F TrackingModifier
2690 int fx_tracking_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2692 if (0) printf( "fx_tracking_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2694 STAT_MOD( IE_TRACKING
);
2698 // 0x60 LevelModifier
2699 int fx_level_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2701 if (0) printf( "fx_level_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2703 STAT_MOD( IE_LEVEL
);
2707 // 0x61 StrengthBonusModifier
2708 int fx_strength_bonus_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2710 if (0) printf( "fx_strength_bonus_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2712 STAT_MOD( IE_STREXTRA
);
2716 // 0x62 State:Regenerating
2717 int fx_set_regenerating_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2719 if (0) printf( "fx_set_regenerating_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2721 int tmp
= fx
->Parameter1
;
2722 ieDword gameTime
= core
->GetGame()->GameTime
;
2725 if (!fx
->Parameter3
) {
2726 //hack to ensure our first call gets through
2727 nextHeal
= gameTime
-1;
2729 nextHeal
= fx
->Parameter3
;
2732 //we can have multiple calls at the same gameTime, so we
2733 //just go to gameTime+1 to ensure one call
2734 if (nextHeal
>=gameTime
) return FX_APPLIED
;
2736 HandlePercentageDamage(fx
, target
);
2738 switch(fx
->Parameter2
) {
2739 case RPD_TURNS
: //restore param3 hp every param1 turns
2740 //assuming 1 turn = 10 rounds
2741 tmp
*= ROUND_PER_TURN
;
2743 case RPD_ROUNDS
: //restore param3 hp every param1 rounds
2744 tmp
*= ROUND_SECONDS
;
2746 case RPD_SECONDS
: //restore param3 hp every param1 seconds
2747 fx
->Parameter3
= nextHeal
+ tmp
*AI_UPDATE_TIME
;
2750 case RPD_PERCENT
: // handled in HandlePercentageDamage
2751 case RPD_POINTS
: //restore param1 hp every second? that's crazy!
2752 damage
= fx
->Parameter1
;
2753 fx
->Parameter3
= nextHeal
+ AI_UPDATE_TIME
;
2756 fx
->Parameter3
= nextHeal
+ AI_UPDATE_TIME
;
2761 //This should take care of the change of the modified stat
2762 //So there is no need to do anything else here other than increasing
2763 //the base current hp
2764 target
->NewBase(IE_HITPOINTS
, damage
, MOD_ADDITIVE
);
2767 // 0x63 SpellDurationModifier
2768 int fx_spell_duration_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2770 if (0) printf( "fx_spell_duration_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2772 switch (fx
->Parameter2
) {
2774 STAT_SET( IE_SPELLDURATIONMODMAGE
, fx
->Parameter1
);
2777 STAT_SET( IE_SPELLDURATIONMODPRIEST
, fx
->Parameter1
);
2780 return FX_NOT_APPLIED
;
2784 // 0x64 Protection:Creature
2785 int fx_generic_effect (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
2787 if (0) printf( "fx_generic_effect (%2d): Param1: %d, Param2: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2791 // 0x65 Protection:Opcode
2792 int fx_protection_opcode (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2794 if (0) printf( "fx_protection_opcode (%2d): Opcode: %d\n", fx
->Opcode
, fx
->Parameter2
);
2795 STAT_BIT_OR(IE_IMMUNITY
, IMM_OPCODE
);
2799 // 0x66 Protection:SpellLevel
2800 int fx_protection_spelllevel (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2802 if (0) printf( "fx_protection_spelllevel (%2d) Level: %d\n", fx
->Opcode
, fx
->Parameter1
);
2804 int value
= fx
->Parameter1
;
2806 STAT_BIT_OR(IE_MINORGLOBE
, 1<<value
);
2807 STAT_BIT_OR(IE_IMMUNITY
, IMM_LEVEL
);
2810 return FX_NOT_APPLIED
;
2814 int fx_change_name (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2816 if (0) printf( "fx_change_name_modifier (%2d): StrRef: %d\n", fx
->Opcode
, fx
->Parameter1
);
2817 target
->SetName(fx
->Parameter1
, 0);
2818 return FX_NOT_APPLIED
;
2821 // 0x68 ExperienceModifier
2822 int fx_experience_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2824 if (0) printf( "fx_experience_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2825 //i believe this has mode too
2826 target
->AddExperience (fx
->Parameter1
);
2827 return FX_NOT_APPLIED
;
2830 // 0x69 GoldModifier
2831 //in BG2 this effect subtracts gold when type is MOD_ADDITIVE
2832 //no one uses it, though. To keep the function, the default branch will do the subtraction
2833 int fx_gold_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2835 if (0) printf( "fx_gold_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2836 if (!target
->InParty
) {
2837 STAT_MOD( IE_GOLD
);
2838 return FX_NOT_APPLIED
;
2841 Game
*game
= core
->GetGame();
2842 //for party members, the gold is stored in the game object
2843 switch( fx
->Parameter2
) {
2845 gold
= fx
->Parameter1
;
2848 gold
= fx
->Parameter1
-game
->PartyGold
;
2851 gold
= game
->PartyGold
*fx
->Parameter1
/100-game
->PartyGold
;
2854 gold
= (ieDword
) -fx
->Parameter1
;
2857 game
->AddGold (gold
);
2858 return FX_NOT_APPLIED
;
2861 // 0x6a MoraleBreakModifier
2862 int fx_morale_break_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2864 if (0) printf( "fx_morale_break_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2865 STAT_MOD(IE_MORALEBREAK
);
2866 return FX_PERMANENT
; //permanent morale break doesn't stick
2869 // 0x6b PortraitChange
2870 int fx_portrait_change (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2872 if (0) printf( "fx_portrait_change (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2873 target
->SetPortrait( fx
->Resource
, fx
->Parameter2
);
2874 return FX_NOT_APPLIED
;
2877 // 0x6c ReputationModifier
2878 int fx_reputation_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2880 if (0) printf( "fx_reputation_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2881 STAT_MOD(IE_REPUTATION
);
2882 return FX_NOT_APPLIED
; //needs testing
2885 // 0x6d --> see later
2887 // 0x6e works only in PST, reused for turning undead
2889 // 0x6f Item:CreateMagic
2891 static EffectRef fx_remove_item_ref
={"Item:Remove",NULL
,-1};
2893 int fx_create_magic_item (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2895 //charge count is incorrect
2896 target
->inventory
.SetSlotItemRes(fx
->Resource
, target
->inventory
.GetMagicSlot(),fx
->Parameter1
,fx
->Parameter3
,fx
->Parameter4
);
2898 target
->inventory
.SetEquippedSlot(target
->inventory
.GetMagicSlot()-target
->inventory
.GetWeaponSlot(), 0);
2899 if ((fx
->TimingMode
&0xff) == FX_DURATION_INSTANT_LIMITED
) {
2900 //if this effect has expiration, then it will remain as a remove_item
2901 //on the effect queue, inheriting all the parameters
2902 fx
->Opcode
=EffectQueue::ResolveEffect(fx_remove_item_ref
);
2903 fx
->TimingMode
=FX_DURATION_DELAY_PERMANENT
;
2906 return FX_NOT_APPLIED
;
2910 int fx_remove_item (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2912 //will destroy the first item
2913 if (target
->inventory
.DestroyItem(fx
->Resource
,0,1)) {
2914 target
->ReinitQuickSlots();
2916 return FX_NOT_APPLIED
;
2920 int fx_equip_item (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2922 int eff
= core
->QuerySlotEffects( fx
->Parameter2
);
2924 case SLOT_EFFECT_NONE
:
2925 case SLOT_EFFECT_MELEE
:
2926 target
->inventory
.SetEquippedSlot( fx
->Parameter2
, fx
->Parameter1
);
2929 target
->inventory
.EquipItem( fx
->Parameter2
);
2932 target
->ReinitQuickSlots();
2933 return FX_NOT_APPLIED
;
2937 int fx_dither (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
2939 if (0) printf( "fx_dither (%2d): Value: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
2940 //this effect doesn't work in any engine versions
2941 return FX_NOT_APPLIED
;
2944 // 0x73 DetectAlignment
2945 //gemrb extension: chaotic/lawful detection
2946 int fx_detect_alignment (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
2951 if (fx
->Parameter2
<3) {
2953 msk
= fx
->Parameter2
+1;
2954 stat
= target
->GetStat(IE_ALIGNMENT
)&AL_GE_MASK
;
2957 //3,4,5 -> 0x10, 0x20, 0x30
2958 msk
= (fx
->Parameter2
-2)<<4;
2959 stat
= target
->GetStat(IE_ALIGNMENT
)&AL_LC_MASK
;
2961 if (stat
!= msk
) return FX_NOT_APPLIED
;
2963 ieDword color
= fx
->Parameter1
;
2966 if (!color
) color
= 0xff0000;
2967 displaymsg
->DisplayConstantStringName(STR_EVIL
, color
, target
);
2969 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0xff, 0, 0, 0);
2972 if (!color
) color
= 0xff00;
2973 displaymsg
->DisplayConstantStringName(STR_GOOD
, color
, target
);
2975 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0, 0xff, 0, 0);
2978 if (!color
) color
= 0xff;
2979 displaymsg
->DisplayConstantStringName(STR_GE_NEUTRAL
, color
, target
);
2981 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0, 0, 0xff, 0);
2984 if (!color
) color
= 0xff00ff;
2985 displaymsg
->DisplayConstantStringName(STR_CHAOTIC
, color
, target
);
2987 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0xff, 0, 0xff, 0);
2990 if (!color
) color
= 0xffffff;
2991 displaymsg
->DisplayConstantStringName(STR_LAWFUL
, color
, target
);
2993 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0xff, 0xff, 0xff, 0);
2996 if (!color
) color
= 0xff;
2997 displaymsg
->DisplayConstantStringName(STR_LC_NEUTRAL
, color
, target
);
2999 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0, 0, 0xff, 0);
3002 return FX_NOT_APPLIED
;
3005 // 0x74 Cure:Invisible2 (see 0x2f)
3008 // 0 reveal whole area
3009 // 1 reveal area in pattern
3010 int fx_reveal_area (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3012 if (0) printf( "fx_reveal_area (%2d): Value: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3013 Map
*map
= target
->GetCurrentArea();
3018 if (fx
->Parameter2
) {
3019 map
->Explore(fx
->Parameter1
);
3023 return FX_NOT_APPLIED
;
3026 // 0x76 Reveal:Creatures
3027 int fx_reveal_creatures (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
3029 if (0) printf( "fx_reveal_creatures (%2d): Value: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3030 //reveals creatures (not working in original IE)
3031 return FX_NOT_APPLIED
;
3035 static EffectRef fx_mirror_image_modifier_ref
={"MirrorImageModifier",NULL
,-1};
3037 int fx_mirror_image (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
3039 if (0) printf( "fx_mirror_image (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3042 if (fx
->Parameter2
) {
3043 images
= 1; //reflection
3046 images
= core
->Roll(1, fx
->Parameter1
, 0); //mirror image
3049 Effect
*fx2
= target
->fxqueue
.HasEffect(fx_mirror_image_modifier_ref
);
3051 //update old effect with our numbers if our numbers are more
3052 if (fx2
->Parameter1
<images
) {
3053 fx2
->Parameter1
=images
;
3055 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
) {
3056 fx2
->TimingMode
= FX_DURATION_INSTANT_PERMANENT
;
3058 return FX_NOT_APPLIED
;
3060 fx
->Opcode
= EffectQueue::ResolveEffect(fx_mirror_image_modifier_ref
);
3061 fx
->Parameter1
=images
;
3062 //parameter2 could be 0 or 1 (mirror image or reflection)
3063 //execute the translated effect
3064 return fx_mirror_image_modifier(Owner
, target
, fx
);
3067 // 0x78 Protection:Weapons
3068 int fx_immune_to_weapon (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
3070 if (0) printf( "fx_immune_to_weapon (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3071 if (!fx
->FirstApply
) return FX_APPLIED
;
3074 ieDword mask
, value
;
3079 switch(fx
->Parameter2
) {
3080 case 0: //enchantment level
3081 level
= fx
->Parameter1
;
3083 case 1: //all magical weapons
3084 value
= IE_INV_ITEM_MAGICAL
;
3086 case 2: //all nonmagical weapons
3087 mask
= IE_INV_ITEM_MAGICAL
;
3089 case 3: //all silver weapons
3090 value
= IE_INV_ITEM_SILVER
;
3092 case 4: //all non silver weapons
3093 mask
= IE_INV_ITEM_SILVER
;
3096 value
= IE_INV_ITEM_SILVER
;
3097 mask
= IE_INV_ITEM_SILVER
;
3100 case 6: //all twohanded
3101 value
= IE_INV_ITEM_TWOHANDED
;
3103 case 7: //all not twohanded
3104 mask
= IE_INV_ITEM_TWOHANDED
;
3106 case 8: //all twohanded
3107 value
= IE_INV_ITEM_CURSED
;
3109 case 9: //all not twohanded
3110 mask
= IE_INV_ITEM_CURSED
;
3112 case 10: //all twohanded
3113 value
= IE_INV_ITEM_COLDIRON
;
3115 case 11: //all not twohanded
3116 mask
= IE_INV_ITEM_COLDIRON
;
3119 mask
= fx
->Parameter1
;
3121 value
= fx
->Parameter1
;
3126 fx
->Parameter1
= (ieDword
) level
; //putting the corrected value back
3127 fx
->Parameter3
= mask
;
3128 fx
->Parameter4
= value
;
3132 // 0x79 VisualAnimationEffect (unknown)
3133 int fx_visual_animation_effect (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
3135 //this is an unknown effect
3136 if (0) printf( "fx_visual_animation_effect (%2d)\n", fx
->Opcode
);
3137 return FX_NOT_APPLIED
;
3140 // 0x7a Item:CreateInventory
3141 static EffectRef fx_remove_inventory_item_ref
={"Item:RemoveInventory",NULL
,-1};
3143 int fx_create_inventory_item (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3145 if (0) printf( "fx_create_inventory_item (%2d)\n", fx
->Opcode
);
3146 target
->inventory
.AddSlotItemRes( fx
->Resource
, SLOT_ONLYINVENTORY
, fx
->Parameter1
, fx
->Parameter3
, fx
->Parameter4
);
3147 if ((fx
->TimingMode
&0xff) == FX_DURATION_INSTANT_LIMITED
) {
3148 //if this effect has expiration, then it will remain as a remove_item
3149 //on the effect queue, inheriting all the parameters
3150 fx
->Opcode
=EffectQueue::ResolveEffect(fx_remove_inventory_item_ref
);
3151 fx
->TimingMode
=FX_DURATION_DELAY_PERMANENT
;
3154 return FX_NOT_APPLIED
;
3157 // 0x7b Item:RemoveInventory
3158 int fx_remove_inventory_item (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3160 if (0) printf( "fx_remove_inventory_item (%2d)\n", fx
->Opcode
);
3161 //FIXME: now equipped items are only wielded weapons
3162 //why would it not let equipped items to be destructed?
3163 target
->inventory
.DestroyItem(fx
->Resource
,IE_INV_ITEM_EQUIPPED
,1);
3164 return FX_NOT_APPLIED
;
3167 // 0x7c DimensionDoor
3168 // iwd2 has several options
3169 int fx_dimension_door (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
3171 if (0) printf( "fx_dimension_door (%2d) Type:%d\n", fx
->Opcode
, fx
->Parameter2
);
3174 switch(fx
->Parameter2
)
3176 case 0: //target to point
3180 case 1: //owner to target
3181 if (Owner
->Type
!=ST_ACTOR
) {
3182 return FX_NOT_APPLIED
;
3185 target
= (Actor
*) Owner
;
3187 case 2: //target to saved location
3188 p
.x
=STAT_GET(IE_SAVEDXPOS
);
3189 p
.x
=STAT_GET(IE_SAVEDYPOS
);
3190 target
->SetOrientation(STAT_GET(IE_SAVEDFACE
), false);
3192 case 3: //owner swapped with target
3193 if (Owner
->Type
!=ST_ACTOR
) {
3194 return FX_NOT_APPLIED
;
3197 target
->SetPosition(Owner
->Pos
, true, 0);
3198 target
= (Actor
*) Owner
;
3201 target
->SetPosition(p
, true, 0 );
3202 return FX_NOT_APPLIED
;
3206 int fx_knock (Scriptable
* Owner
, Actor
* /*target*/, Effect
* fx
)
3208 if (0) printf( "fx_knock (%2d) [%d.%d]\n", fx
->Opcode
, fx
->PosX
, fx
->PosY
);
3209 Map
*map
= Owner
->GetCurrentArea();
3210 Point
p(fx
->PosX
, fx
->PosY
);
3211 Door
*door
= map
->TMap
->GetDoorByPosition(p
);
3213 if (door
->LockDifficulty
<100) {
3214 door
->SetDoorLocked(false, true);
3216 return FX_NOT_APPLIED
;
3218 Container
*container
= map
->TMap
->GetContainerByPosition(p
);
3220 if(container
->LockDifficulty
<100) {
3221 container
->SetContainerLocked(false);
3223 return FX_NOT_APPLIED
;
3225 return FX_NOT_APPLIED
;
3228 // 0x7e MovementRateModifier
3229 // 0xb0 MovementRateModifier2
3230 int fx_movement_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3232 if (0) printf( "fx_movement_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3234 //iwd2 freeaction disables only 0xb0, who cares
3235 if (target
->HasSpellState(SS_FREEACTION
)) return FX_NOT_APPLIED
;
3236 //iwd2 aegis doesn't protect against grease/acid fog slowness, but that is
3238 if (target
->HasSpellState(SS_AEGIS
)) return FX_NOT_APPLIED
;
3240 STAT_MOD(IE_MOVEMENTRATE
);
3245 static const ieResRef monster_summoning_2da
[FX_MS
]={"MONSUM01","MONSUM02","MONSUM03",
3246 "ANISUM01","ANISUM02", "MONSUM01", "MONSUM02","MONSUM03","ANISUM01","ANISUM02"};
3248 // 0x7f MonsterSummoning
3249 int fx_monster_summoning (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
3251 if (0) printf( "fx_monster_summoning (%2d): Number: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3252 //check the summoning limit?
3254 return FX_NOT_APPLIED
;
3257 if (!Owner
->GetCurrentArea()) {
3261 //get monster resref from 2da determined by fx->Resource or fx->Parameter2
3265 int level
= fx
->Parameter1
;
3267 if (fx
->Parameter2
>=FX_MS
) {
3268 strnuprcpy(monster
,fx
->Resource
,8);
3269 strnuprcpy(hit
,fx
->Resource2
,8);
3270 strnuprcpy(areahit
,fx
->Resource3
,8);
3272 core
->GetResRefFrom2DA(monster_summoning_2da
[fx
->Parameter2
], monster
, hit
, areahit
);
3275 strnuprcpy(hit
,fx
->Resource2
,8);
3278 strnuprcpy(areahit
,fx
->Resource3
,8);
3282 //the monster should appear near the effect position
3283 Point
p(fx
->PosX
, fx
->PosY
);
3285 Effect
*newfx
= EffectQueue::CreateUnsummonEffect(fx
);
3286 core
->SummonCreature(monster
, hit
, Owner
, target
, p
, fx
->Parameter2
/5, level
, newfx
);
3288 return FX_NOT_APPLIED
;
3291 // 0x80 State:Confused
3292 int fx_set_confused_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3294 if (0) printf( "fx_set_confused_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3296 if (target
->HasSpellState(SS_BLOODRAGE
)) {
3297 return FX_NOT_APPLIED
;
3300 if (fx
->TimingMode
==FX_DURATION_DELAY_PERMANENT
) {
3301 BASE_STATE_SET( STATE_CONFUSED
);
3303 STATE_SET( STATE_CONFUSED
);
3305 //NOTE: iwd2 is also unable to display the portrait icon
3306 //for permanent confusion
3307 if (enhanced_effects
) {
3308 target
->AddPortraitIcon(PI_CONFUSED
);
3310 return FX_PERMANENT
;
3313 // 0x81 AidNonCumulative
3314 int fx_set_aid_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3316 if (0) printf( "fx_set_aid_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3317 if (!fx
->Parameter2
) {
3318 fx
->Parameter2
=core
->Roll(fx
->Parameter1
,8,0);
3320 if (STATE_GET (STATE_AID
) ) //aid is non cumulative
3321 return FX_NOT_APPLIED
;
3322 STATE_SET( STATE_AID
);
3323 target
->SetSpellState(SS_AID
);
3324 STAT_ADD( IE_MAXHITPOINTS
, fx
->Parameter2
);
3325 //This better happens after increasing maxhitpoints
3326 if (fx
->FirstApply
) {
3327 BASE_ADD( IE_HITPOINTS
, fx
->Parameter1
);
3329 STAT_ADD( IE_SAVEVSDEATH
, fx
->Parameter1
);
3330 STAT_ADD( IE_SAVEVSWANDS
, fx
->Parameter1
);
3331 STAT_ADD( IE_SAVEVSPOLY
, fx
->Parameter1
);
3332 STAT_ADD( IE_SAVEVSBREATH
, fx
->Parameter1
);
3333 STAT_ADD( IE_SAVEVSSPELL
, fx
->Parameter1
);
3335 STAT_ADD( IE_TOHIT
, fx
->Parameter1
);
3336 STAT_ADD( IE_MORALEBREAK
, fx
->Parameter1
);
3337 if (enhanced_effects
) {
3338 target
->AddPortraitIcon(PI_AID
);
3339 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 50, 50, 50);
3344 // 0x82 BlessNonCumulative
3346 static EffectRef fx_bane_ref
={"Bane",NULL
,-1};
3348 int fx_set_bless_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3350 if (0) printf( "fx_set_bless_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3352 if (STATE_GET (STATE_BLESS
) ) //bless is non cumulative
3353 return FX_NOT_APPLIED
;
3356 target
->fxqueue
.RemoveAllEffects(fx_bane_ref
);
3358 STATE_SET( STATE_BLESS
);
3359 target
->SetSpellState(SS_BLESS
);
3360 STAT_ADD( IE_TOHIT
, fx
->Parameter1
);
3361 STAT_ADD( IE_MORALEBREAK
, fx
->Parameter1
);
3362 if (enhanced_effects
) {
3363 target
->AddPortraitIcon(PI_BLESS
);
3364 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0xc0, 0x80, 0);
3368 // 0x83 ChantNonCumulative
3369 int fx_set_chant_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3371 if (0) printf( "fx_set_chant_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3373 if (STATE_GET (STATE_CHANT
) ) //chant is non cumulative
3374 return FX_NOT_APPLIED
;
3375 STATE_SET( STATE_CHANT
);
3376 target
->SetSpellState(SS_GOODCHANT
);
3377 STAT_ADD( IE_LUCK
, fx
->Parameter1
);
3381 // 0x84 HolyNonCumulative
3382 int fx_set_holy_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3384 if (0) printf( "fx_set_holy_state (%2d): Modifier: %d\n", fx
->Opcode
, fx
->Parameter1
);
3386 if (STATE_GET (STATE_HOLY
) ) //holy power is non cumulative
3387 return FX_NOT_APPLIED
;
3388 STATE_SET( STATE_HOLY
);
3389 //setting the spell state to be compatible with iwd2
3390 target
->SetSpellState(SS_HOLYMIGHT
);
3391 STAT_ADD( IE_STR
, fx
->Parameter1
);
3392 STAT_ADD( IE_CON
, fx
->Parameter1
);
3393 STAT_ADD( IE_DEX
, fx
->Parameter1
);
3394 if (enhanced_effects
) {
3395 target
->AddPortraitIcon(PI_HOLY
);
3396 target
->SetColorMod(0xff, RGBModifier::ADD
, 30, 0x80, 0x80, 0x80);
3401 // 0x85 LuckNonCumulative
3402 int fx_luck_non_cumulative (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3404 if (0) printf( "fx_luck_non_cumulative (%2d): Modifier: %d\n", fx
->Opcode
, fx
->Parameter1
);
3406 if (STATE_GET (STATE_LUCK
) ) //this luck is non cumulative
3407 return FX_NOT_APPLIED
;
3408 STATE_SET( STATE_LUCK
);
3409 target
->SetSpellState(SS_LUCK
);
3410 STAT_ADD( IE_LUCK
, fx
->Parameter1
);
3411 STAT_ADD( IE_DAMAGELUCK
, fx
->Parameter1
);
3415 // 0x85 LuckCumulative (iwd2)
3416 int fx_luck_cumulative (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3418 if (0) printf( "fx_luck_cumulative (%2d): Modifier: %d\n", fx
->Opcode
, fx
->Parameter1
);
3420 target
->SetSpellState(SS_LUCK
);
3421 STAT_ADD( IE_LUCK
, fx
->Parameter1
);
3422 STAT_ADD( IE_DAMAGELUCK
, fx
->Parameter1
);
3426 // 0x86 State:Petrification
3427 int fx_set_petrified_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3429 if (0) printf( "fx_set_petrified_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3431 BASE_STATE_SET( STATE_PETRIFIED
);
3432 return FX_NOT_APPLIED
; //permanent effect
3436 static EffectRef fx_polymorph_ref
={"Polymorph",NULL
,-1};
3438 void CopyPolymorphStats(Actor
*source
, Actor
*target
)
3442 if(!polymorph_stats
) {
3443 AutoTable
tab("polystat");
3445 polymorph_stats
= (int *) malloc(0);
3449 polystatcount
= tab
->GetRowCount();
3450 polymorph_stats
=(int *) malloc(sizeof(int)*polystatcount
);
3451 for (i
=0;i
<polystatcount
;i
++) {
3452 polymorph_stats
[i
]=core
->TranslateStat(tab
->QueryField(i
,0));
3456 //copy polymorphed stats, no need of using STAT_SET, because the stats
3457 //are copied from a consistent state
3458 for(i
=0;i
<polystatcount
;i
++) {
3459 target
->Modified
[polymorph_stats
[i
]]=source
->Modified
[polymorph_stats
[i
]];
3463 int fx_polymorph (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3465 if (0) printf( "fx_set_polymorph_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3467 if (!gamedata
->Exists(fx
->Resource
,IE_CRE_CLASS_ID
)) {
3468 //kill all polymorph effects
3469 target
->fxqueue
.RemoveAllEffectsWithParam(fx_polymorph_ref
, fx
->Parameter2
);
3470 //destroy the magic item slot
3471 target
->inventory
.RemoveItem(target
->inventory
.GetMagicSlot() );
3472 return FX_NOT_APPLIED
;
3476 //This pointer should be cached, or we are in deep trouble
3477 Actor
*newCreature
= gamedata
->GetCreature(fx
->Resource
,0);
3479 //I don't know how could this happen, existance of the resource was already checked
3481 return FX_NOT_APPLIED
;
3484 //copy the animation ID; never resets back! shapeshift to natural doesn't work either
3485 //target->SetAnimationID( newCreature->GetStat(IE_ANIMATION_ID) );
3486 //TODO: also change the inventory paper doll
3488 //copy all polymorphed stats
3489 if(fx
->Parameter2
) {
3490 STAT_SET( IE_POLYMORPHED
, 1 );
3491 //FIXME: of course, the first parameter should be the creature we copy
3492 CopyPolymorphStats(newCreature
, target
);
3496 //Be careful when this became a cached pointer
3501 // 0x88 ForceVisible
3502 int fx_force_visible (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3504 if (0) printf( "fx_force_visible (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3506 BASE_STATE_CURE(STATE_INVISIBLE
);
3507 target
->fxqueue
.RemoveAllEffectsWithParam(fx_set_invisible_state_ref
,0);
3508 target
->fxqueue
.RemoveAllEffectsWithParam(fx_set_invisible_state_ref
,2);
3509 return FX_NOT_APPLIED
;
3512 // 0x89 ChantBadNonCumulative
3513 int fx_set_chantbad_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3515 if (0) printf( "fx_set_chantbad_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3517 if (STATE_GET (STATE_CHANTBAD
) ) //chant is non cumulative
3518 return FX_NOT_APPLIED
;
3519 STATE_SET( STATE_CHANTBAD
);
3520 target
->SetSpellState(SS_BADCHANT
);
3521 STAT_SUB( IE_LUCK
, fx
->Parameter1
);
3525 // 0x8A AnimationStateChange
3526 int fx_animation_stance (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3528 if (0) printf( "fx_animation_stance (%2d): Stance: %d\n", fx
->Opcode
, fx
->Parameter2
);
3530 //this effect works only on living actors
3531 if ( !STATE_GET(STATE_DEAD
) ) {
3532 target
->SetStance(fx
->Parameter2
);
3534 return FX_NOT_APPLIED
;
3537 // 0x8B DisplayString
3538 // gemrb extension: rgb colour for displaystring
3539 static EffectRef fx_protection_from_display_string_ref
={"Protection:String",NULL
,-1};
3541 int fx_display_string (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3543 if (0) printf( "fx_display_string (%2d): StrRef: %d\n", fx
->Opcode
, fx
->Parameter1
);
3544 if (!target
->fxqueue
.HasEffectWithParamPair(fx_protection_from_display_string_ref
, fx
->Parameter1
, 0) ) {
3545 displaymsg
->DisplayStringName(fx
->Parameter1
, fx
->Parameter2
?fx
->Parameter2
:0xffffff, target
, IE_STR_SOUND
|IE_STR_SPEECH
);
3547 return FX_NOT_APPLIED
;
3551 static const int ypos_by_direction
[16]={10,10,10,0,-10,-10,-10,-10,-10,-10,-10,-10,0,10,10,10};
3552 static const int xpos_by_direction
[16]={0,-10,-12,-14,-16,-14,-12,-10,0,10,12,14,16,14,12,10};
3554 int fx_casting_glow (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3556 if (0) printf( "fx_casting_glow (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
3558 cgcount
= core
->ReadResRefTable("cgtable",casting_glows
);
3560 //remove effect if map is not loaded
3561 Map
*map
= target
->GetCurrentArea();
3563 return FX_NOT_APPLIED
;
3566 if (fx
->Parameter2
<(ieDword
) cgcount
) {
3567 ScriptedAnimation
*sca
= gamedata
->GetScriptedAnimation(casting_glows
[fx
->Parameter2
], false);
3568 //remove effect if animation doesn't exist
3570 return FX_NOT_APPLIED
;
3572 //12 is just an approximate value to set the height of the casting glow
3573 //based on the avatar's size
3574 int heightmod
= target
->GetAnims()->GetCircleSize()*12;
3575 sca
->XPos
+=fx
->PosX
+xpos_by_direction
[target
->GetOrientation()];
3576 sca
->YPos
+=fx
->PosY
+ypos_by_direction
[target
->GetOrientation()];
3577 sca
->ZPos
+=heightmod
;
3580 sca
->SetDefaultDuration(fx
->Duration
-core
->GetGame()->GameTime
);
3582 sca
->SetDefaultDuration(10000);
3584 map
->AddVVCell(sca
);
3586 return FX_NOT_APPLIED
;
3589 //0x8d VisualSpellHit
3590 int fx_visual_spell_hit (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3592 if (0) printf( "fx_visual_spell_hit (%2d): Target: %d Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3594 shcount
= core
->ReadResRefTable("shtable",spell_hits
);
3596 //remove effect if map is not loaded
3597 Map
*map
= target
->GetCurrentArea();
3599 return FX_NOT_APPLIED
;
3601 if (fx
->Parameter2
<(ieDword
) shcount
) {
3602 ScriptedAnimation
*sca
= gamedata
->GetScriptedAnimation(spell_hits
[fx
->Parameter2
], false);
3603 //remove effect if animation doesn't exist
3605 return FX_NOT_APPLIED
;
3607 if (fx
->Parameter1
) {
3608 sca
->XPos
+=target
->Pos
.x
;
3609 sca
->YPos
+=target
->Pos
.y
;
3611 sca
->XPos
+=fx
->PosX
;
3612 sca
->YPos
+=fx
->PosY
;
3614 if (fx
->Parameter2
<32) {
3615 int tmp
= fx
->Parameter2
>>2;
3617 sca
->SetFullPalette(tmp
);
3622 map
->AddVVCell(sca
);
3624 printf("fx_visual_spell_hit: Unhandled Type: %d\n", fx
->Parameter2
);
3626 return FX_NOT_APPLIED
;
3630 int fx_display_portrait_icon (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3632 if (0) printf( "fx_display_string (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
3633 target
->AddPortraitIcon(fx
->Parameter2
);
3637 //0x8f Item:CreateInSlot
3638 int fx_create_item_in_slot (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3640 if (0) printf( "fx_create_item_in_slot (%2d): Button: %d\n", fx
->Opcode
, fx
->Parameter2
);
3641 //create item and set it in target's slot
3642 target
->inventory
.SetSlotItemRes( fx
->Resource
, core
->QuerySlot(fx
->Parameter2
), fx
->Parameter1
, fx
->Parameter3
, fx
->Parameter4
);
3643 if ((fx
->TimingMode
&0xff) == FX_DURATION_INSTANT_LIMITED
) {
3644 //convert it to a destroy item
3645 fx
->Opcode
=EffectQueue::ResolveEffect(fx_remove_item_ref
);
3646 fx
->TimingMode
=FX_DURATION_DELAY_PERMANENT
;
3649 return FX_NOT_APPLIED
;
3652 // 0x90 DisableButton
3653 // different in iwd2 and the rest (maybe also in how: 0-7?)
3654 int fx_disable_button (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3656 if (0) printf( "fx_disable_button (%2d): Button: %d\n", fx
->Opcode
, fx
->Parameter2
);
3658 // iwd2 has a flexible action bar, so there are more possible parameter values
3659 // only values 0-5 match the bg2 constants (which map to ACT_*)
3660 // FIXME: support disabling all iwd2 buttons
3661 if (target
->spellbook
.IsIWDSpellBook()) {
3662 if (fx
->Parameter2
< 6) STAT_BIT_OR( IE_DISABLEDBUTTON
, 1<<fx
->Parameter2
);
3664 STAT_BIT_OR( IE_DISABLEDBUTTON
, 1<<fx
->Parameter2
);
3667 if (target
->InParty
&& fx
->FirstApply
) {
3668 core
->SetEventFlag(EF_ACTION
);
3673 //0x91 DisableSpellCasting
3674 //bg2: 0 - mage, 1 - cleric, 2 - innate
3675 //iwd2: 0 - all, 1 - mage+cleric, 2 - mage, 3 - cleric , 4 - innate
3676 int fx_disable_spellcasting (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3678 if (0) printf( "fx_disable_spellcasting (%2d): Button: %d\n", fx
->Opcode
, fx
->Parameter2
);
3680 if (!fx
->FirstApply
) {
3683 bool display_warning
= false;
3685 //IWD2 Style spellbook
3686 if (target
->spellbook
.IsIWDSpellBook()) {
3687 switch(fx
->Parameter2
) {
3689 case 1: // mage and cleric
3691 if (target
->spellbook
.GetKnownSpellsCount(IE_IWD2_SPELL_BARD
, 0)) display_warning
= true;
3692 if (target
->spellbook
.GetKnownSpellsCount(IE_IWD2_SPELL_SORCEROR
, 0)) display_warning
= true;
3693 if (target
->spellbook
.GetKnownSpellsCount(IE_IWD2_SPELL_WIZARD
, 0)) display_warning
= true;
3697 if (fx
->Parameter2
== 0)
3698 if (target
->spellbook
.GetKnownSpellsCount(IE_SPELL_TYPE_WIZARD
, 0)) display_warning
= true;
3700 if (target
->InParty
&& display_warning
) {
3701 displaymsg
->DisplayConstantStringName(STR_DISABLEDMAGE
, 0xff0000, target
);
3702 core
->SetEventFlag(EF_ACTION
);
3708 int fx_cast_spell (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
3710 if (0) printf( "fx_cast_spell (%2d): Resource:%s Mode: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
3711 if (fx
->Parameter2
) {
3712 //apply spell on target
3713 core
->ApplySpell(fx
->Resource
, target
, Owner
, fx
->Power
);
3715 //cast spell on target
3716 Owner
->CastSpell(fx
->Resource
, target
, false);
3717 //actually finish casting (if this is not good enough, use an action???)
3718 Owner
->CastSpellEnd(fx
->Resource
);
3720 return FX_NOT_APPLIED
;
3724 int fx_learn_spell (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3726 if (0) printf( "fx_learn_spell (%2d): Resource:%s Mode: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
3727 //parameter1 is unused, gemrb lets you to make it not give XP
3728 //probably we should also let this via a game flag if we want
3729 //full compatibility with bg1
3730 target
->LearnSpell(fx
->Resource
, fx
->Parameter2
^LS_ADDXP
);
3731 return FX_NOT_APPLIED
;
3733 // 0x94 Spell:CastSpellPoint
3734 int fx_cast_spell_point (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
3736 if (0) printf( "fx_cast_spell_point (%2d): Resource:%s Mode: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
3737 Owner
->CastSpellPoint(fx
->Resource
, target
->Pos
, false);
3738 //actually finish casting (if this is not good enough, use an action???)
3739 Owner
->CastSpellPointEnd(fx
->Resource
);
3740 return FX_NOT_APPLIED
;
3744 int fx_identify (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3746 if (0) printf( "fx_identify (%2d): Resource:%s Mode: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
3747 if (target
->InParty
) {
3748 BASE_SET (IE_IDENTIFYMODE
, 1);
3749 core
->SetEventFlag(EF_IDENTIFY
);
3751 return FX_NOT_APPLIED
;
3754 // (actually, in bg2 the effect targets area objects and the range is implemented
3755 // by the inareans projectile) - inanimate, area, no sprite
3756 // TODO: effects should target inanimates using different code
3757 int fx_find_traps (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3759 if (0) printf( "fx_find_traps (%2d)\n", fx
->Opcode
);
3760 //reveal trapped containers, doors, triggers that are in the visible range
3761 ieDword range
= target
->GetStat(IE_VISUALRANGE
)*10;
3764 if (fx
->Parameter2
== 0)
3765 skill
= 256; //always works
3767 skill
= target
->GetStat(IE_TRAPS
); //based on skill
3769 TileMap
*TMap
= target
->GetCurrentArea()->TMap
;
3773 Door
* door
= TMap
->GetDoor( Count
++ );
3778 if (!door->Scripts[0]) {
3782 if (!(door->Flags&DOOR_DETECTABLE)) {
3786 if (Distance(door
->Pos
, target
->Pos
)<range
) {
3787 //when was door trap noticed
3788 door
->DetectTrap(skill
);
3789 // door->TrapDetected = 1;
3795 Container
* container
= TMap
->GetContainer( Count
++ );
3798 if (Distance(container
->Pos
, target
->Pos
)<range
) {
3799 //when was door trap noticed
3800 container
->DetectTrap(skill
);
3807 InfoPoint
* trap
= TMap
->GetInfoPoint( Count
++ );
3810 if (Distance(trap
->Pos
, target
->Pos
)<range
) {
3811 //when was door trap noticed
3812 trap
->DetectTrap(skill
);
3816 return FX_NOT_APPLIED
;
3818 // 0x97 ReplaceCreature
3819 int fx_replace_creature (Scriptable
* Owner
, Actor
* target
, Effect
*fx
)
3821 if (0) printf( "fx_replace_creature (%2d): Resource: %s\n", fx
->Opcode
, fx
->Resource
);
3823 //this safeguard exists in the original engine too
3824 if (!gamedata
->Exists(fx
->Resource
,IE_CRE_CLASS_ID
)) {
3825 return FX_NOT_APPLIED
;
3828 //the monster should appear near the effect position? (unsure)
3829 Point
p(fx
->PosX
, fx
->PosY
);
3831 //remove old creature
3832 switch(fx
->Parameter2
) {
3833 case 0: //remove silently
3834 target
->DestroySelf();
3836 case 1: //chunky death
3837 target
->NewBase(IE_HITPOINTS
,(ieDword
) -100, MOD_ABSOLUTE
);
3840 case 2: //normal death
3845 //create replacement; should we be passing the target instead of NULL?
3846 //noooo, don't unsummon replacement creatures! - fuzzie
3847 //Effect *newfx = EffectQueue::CreateUnsummonEffect(fx);
3848 core
->SummonCreature(fx
->Resource
, fx
->Resource2
, Owner
, NULL
,p
, EAM_DEFAULT
,-1, NULL
, 0);
3850 return FX_NOT_APPLIED
;
3854 int fx_play_movie (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
3856 if (0) printf( "fx_play_movie (%2d): Resource: %s\n", fx
->Opcode
, fx
->Resource
);
3857 core
->PlayMovie (fx
->Resource
);
3858 return FX_NOT_APPLIED
;
3860 // 0x99 Overlay:Sanctuary
3861 #define ICE_GRADIENT 71
3863 static const ieDword fullwhite
[7]={ICE_GRADIENT
,ICE_GRADIENT
,ICE_GRADIENT
,ICE_GRADIENT
,ICE_GRADIENT
,ICE_GRADIENT
,ICE_GRADIENT
};
3865 int fx_set_sanctuary_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3867 //iwd and bg are a bit different, but we solve the whole stuff in a single opcode
3868 if (0) printf( "fx_set_sanctuary_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3869 if (!fx
->Parameter2
) {
3872 //this effect needs the pcf run immediately
3873 STAT_SET_PCF( IE_SANCTUARY
, fx
->Parameter2
);
3874 //a rare event, but this effect gives more in bg2 than in iwd2
3875 //so we use this flag
3876 if (!enhanced_effects
)
3878 target
->SetLockedPalette(fullwhite
);
3883 // 0x9a Overlay:Entangle
3884 int fx_set_entangle_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3886 if (0) printf( "fx_set_entangle_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3888 //iwd2 effects that disable entangle
3889 if (target
->HasSpellState(SS_FREEACTION
)) return FX_NOT_APPLIED
;
3890 if (target
->HasSpellState(SS_AEGIS
)) return FX_NOT_APPLIED
;
3892 if (!fx
->Parameter2
) {
3895 STAT_SET_PCF( IE_ENTANGLE
, fx
->Parameter2
);
3899 // 0x9b Overlay:MinorGlobe
3900 int fx_set_minorglobe_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3902 if (0) printf( "fx_set_minorglobe_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3903 //the resisted levels are stored in minor globe (bit 2-)
3904 //the globe effect is stored in the first bit
3905 STAT_BIT_OR_PCF( IE_MINORGLOBE
, 1);
3909 // 0x9c Overlay:ShieldGlobe
3910 int fx_set_shieldglobe_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3912 if (0) printf( "fx_set_shieldglobe_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3913 STAT_SET_PCF( IE_SHIELDGLOBE
, 1);
3918 int fx_set_web_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3920 if (0) printf( "fx_set_web_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3922 //iwd2 effects that disable web
3923 if (target
->HasSpellState(SS_FREEACTION
)) return FX_NOT_APPLIED
;
3924 if (target
->HasSpellState(SS_AEGIS
)) return FX_NOT_APPLIED
;
3926 target
->SetSpellState(SS_WEB
);
3927 //attack penalty in IWD2
3928 STAT_SET_PCF( IE_WEB
, 1);
3929 STAT_SET(IE_MOVEMENTRATE
, 0); //
3933 // 0x9e Overlay:Grease
3934 int fx_set_grease_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3936 if (0) printf( "fx_set_grease_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3938 //iwd2 effects that disable grease
3939 if (target
->HasSpellState(SS_FREEACTION
)) return FX_NOT_APPLIED
;
3940 if (target
->HasSpellState(SS_AEGIS
)) return FX_NOT_APPLIED
;
3942 target
->SetSpellState(SS_GREASE
);
3943 STAT_SET_PCF( IE_GREASE
, 1);
3944 //the movement rate is set by separate opcodes in all engines
3948 // 0x9f MirrorImageModifier
3949 int fx_mirror_image_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3951 if (0) printf( "fx_mirror_image_modifier (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter1
);
3952 if (STATE_GET(STATE_DEAD
) ) {
3953 return FX_NOT_APPLIED
;
3955 if (!fx
->Parameter1
) {
3956 return FX_NOT_APPLIED
;
3958 STATE_SET( STATE_MIRROR
);
3959 if (fx
->Parameter2
) {
3960 target
->SetSpellState(SS_REFLECTION
);
3962 target
->SetSpellState(SS_MIRRORIMAGE
);
3964 //actually, there is no such stat in the original IE
3965 STAT_SET( IE_MIRRORIMAGES
, fx
->Parameter1
);
3969 // 0xa0 Cure:Sanctuary
3970 static EffectRef fx_sanctuary_state_ref
={"Overlay:Sanctuary",NULL
,-1};
3972 int fx_cure_sanctuary_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3974 if (0) printf( "fx_cure_sanctuary_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3975 STAT_SET( IE_SANCTUARY
, 0);
3976 target
->fxqueue
.RemoveAllEffects(fx_sanctuary_state_ref
);
3977 return FX_NOT_APPLIED
;
3981 static EffectRef fx_set_panic_state_ref
={"State:Panic",NULL
,-1};
3983 int fx_cure_panic_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3985 if (0) printf( "fx_cure_panic_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3986 BASE_STATE_CURE( STATE_PANIC
);
3987 target
->fxqueue
.RemoveAllEffects(fx_set_panic_state_ref
);
3988 return FX_NOT_APPLIED
;
3992 static EffectRef fx_hold_creature_ref
={"State:Hold",NULL
,-1};
3994 int fx_cure_hold_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
3996 if (0) printf( "fx_cure_hold_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
3997 //note that this effect doesn't remove 185 (another hold effect)
3998 target
->fxqueue
.RemoveAllEffects( fx_hold_creature_ref
);
3999 target
->fxqueue
.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref
, PI_HELD
);
4000 return FX_NOT_APPLIED
;
4004 static EffectRef fx_movement_modifier_ref
={"MovementRateModifier2",NULL
,-1};
4006 int fx_cure_slow_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4008 if (0) printf( "fx_cure_slow_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4009 target
->fxqueue
.RemoveAllEffects( fx_movement_modifier_ref
);
4010 // STATE_CURE( STATE_SLOWED );
4011 return FX_NOT_APPLIED
;
4014 // 0xa4 Cure:Intoxication
4015 static EffectRef fx_intoxication_ref
={"IntoxicationModifier",NULL
,-1};
4017 int fx_cure_intoxication (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4019 if (0) printf( "fx_cure_intoxication (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4020 target
->fxqueue
.RemoveAllEffects( fx_intoxication_ref
);
4021 BASE_SET(IE_INTOXICATION
,0);
4022 return FX_NOT_APPLIED
;
4026 int fx_pause_target (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4028 if (0) printf( "fx_pause_target (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4030 STAT_MOD( IE_CASTERHOLD
);
4031 return FX_PERMANENT
;
4034 // 0xa6 MagicResistanceModifier
4035 int fx_magic_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4037 if (0) printf( "fx_magic_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4039 STAT_MOD( IE_RESISTMAGIC
);
4043 // 0xa7 MissileHitModifier
4044 int fx_missile_to_hit_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4046 if (0) printf( "fx_missile_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4048 STAT_MOD( IE_MISSILEHITBONUS
);
4052 // 0xa8 RemoveCreature
4053 // removes targeted creature
4054 // removes creature specified by resource key (gemrb extension)
4055 int fx_remove_creature (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4057 if (0) printf( "fx_remove_creature (%2d)\n", fx
->Opcode
);
4058 Map
*map
= target
->GetCurrentArea();
4059 Actor
*actor
= target
;
4061 if (fx
->Resource
[0]) {
4062 actor
= map
->GetActorByResource(fx
->Resource
);
4066 //play vvc effect over actor?
4067 actor
->DestroySelf();
4069 return FX_NOT_APPLIED
;
4072 // 0xa9 Icon:Disable
4073 int fx_disable_portrait_icon (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4075 if (0) printf( "fx_disable_portrait_icon (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4076 target
->DisablePortraitIcon(fx
->Parameter2
);
4080 // 0xaa DamageAnimation
4081 int fx_damage_animation (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4083 if (0) printf( "fx_damage_animation (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4085 //Parameter1 is a gemrb extension
4086 target
->PlayDamageAnimation(fx
->Parameter2
, !fx
->Parameter1
);
4087 return FX_NOT_APPLIED
;
4091 int fx_add_innate (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4093 if (0) printf( "fx_add_innate (%2d): Resource: %s Mode: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
4094 target
->LearnSpell(fx
->Resource
, fx
->Parameter2
^LS_MEMO
);
4095 //this is an instant, so it shouldn't stick
4096 return FX_NOT_APPLIED
;
4099 // 0xac Spell:Remove
4100 //gemrb extension: deplete spell by resref
4101 int fx_remove_spell (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4103 if (0) printf( "fx_remove_spell (%2d): Resource: %s Type:%d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
4104 switch (fx
->Parameter2
) {
4106 target
->spellbook
.RemoveSpell(fx
->Resource
);
4108 case 1: //forget all spells of Resource
4109 do {} while(target
->spellbook
.HaveSpell( fx
->Resource
, HS_DEPLETE
));
4111 case 2: //forget x spells of resource
4112 while( fx
->Parameter1
--) {
4113 target
->spellbook
.HaveSpell( fx
->Resource
, HS_DEPLETE
);
4117 //this is an instant, so it shouldn't stick
4118 return FX_NOT_APPLIED
;
4121 // 0xad PoisonResistanceModifier
4122 int fx_poison_resistance_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4124 if (0) printf( "fx_poison_resistance_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4126 STAT_MOD( IE_RESISTPOISON
);
4131 int fx_playsound (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4133 if (0) printf( "fx_playsound (%s)", fx
->Resource
);
4134 //this is probably inaccurate
4136 core
->GetAudioDrv()->Play(fx
->Resource
, target
->Pos
.x
, target
->Pos
.y
);
4138 core
->GetAudioDrv()->Play(fx
->Resource
);
4140 //this is an instant, it shouldn't stick
4141 return FX_NOT_APPLIED
;
4146 int fx_hold_creature_no_icon (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4148 if (0) printf( "fx_hold_creature_no_icon (%2d): Value: %d, IDS: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4150 //actually the original engine just skips this effect if the target is dead
4151 if ( STATE_GET(STATE_DEAD
) ) {
4152 return FX_NOT_APPLIED
;
4155 if (!EffectQueue::match_ids( target
, fx
->Parameter2
, fx
->Parameter1
) ) {
4156 //if the ids don't match, the effect doesn't stick
4157 return FX_NOT_APPLIED
;
4159 target
->SetSpellState(SS_HELD
);
4160 STAT_SET( IE_HELD
, 1);
4166 //(0x6d/0x1a8 for iwd2)
4167 int fx_hold_creature (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4169 if (0) printf( "fx_hold_creature (%2d): Value: %d, IDS: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4171 //actually the original engine just skips this effect if the target is dead
4172 if ( STATE_GET(STATE_DEAD
) ) {
4173 return FX_NOT_APPLIED
;
4176 //iwd2 free action or blood rage disables this effect
4177 if (target
->HasSpellState(SS_FREEACTION
)) return FX_NOT_APPLIED
;
4178 if (target
->HasSpellState(SS_BLOODRAGE
)) return FX_NOT_APPLIED
;
4179 if (target
->HasSpellState(SS_AEGIS
)) return FX_NOT_APPLIED
;
4181 if (!EffectQueue::match_ids( target
, fx
->Parameter2
, fx
->Parameter1
) ) {
4182 //if the ids don't match, the effect doesn't stick
4183 return FX_NOT_APPLIED
;
4185 target
->SetSpellState(SS_HELD
);
4186 STAT_SET( IE_HELD
, 1);
4187 target
->AddPortraitIcon(PI_HELD
);
4190 //0xb0 see: fx_movement_modifier
4193 int fx_apply_effect (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4195 if (0) printf( "fx_apply_effect (%2d) %s", fx
->Opcode
, fx
->Resource
);
4197 //this effect executes a file effect in place of this effect
4198 //the file effect inherits the target and the timingmode, but gets
4199 //a new chance to roll percents
4200 int ret
= FX_NOT_APPLIED
;
4204 if (EffectQueue::match_ids( target
, fx
->Parameter2
, fx
->Parameter1
) ) {
4205 Point
p(fx
->PosX
, fx
->PosY
);
4207 //apply effect, if the effect is a goner, then kill
4209 Effect
*newfx
= core
->GetEffect(fx
->Resource
, fx
->Power
, p
);
4211 Effect
*myfx
= new Effect
;
4212 memcpy(myfx
, newfx
, sizeof(Effect
));
4213 myfx
->random_value
= core
->Roll(1,100,0);
4214 myfx
->Target
= FX_TARGET_PRESET
;
4215 myfx
->TimingMode
= fx
->TimingMode
;
4216 myfx
->Duration
= fx
->Duration
;
4217 ret
= target
->fxqueue
.ApplyEffect(target
, myfx
, fx
->FirstApply
);
4220 //newfx is a borrowed reference don't delete it
4225 //0xb2 hitbonus generic effect ToHitVsCreature
4226 //0xb3 damagebonus generic effect DamageVsCreature
4227 // b4 can't use item (resource) generic effect CantUseItem
4228 // b5 can't use itemtype (resource) generic effect CantUseItemType
4229 // b6 generic effect ApplyEffectItem
4230 // b7 generic effect ApplyEffectItemType
4231 // b8 DontJumpModifier
4232 int fx_dontjump_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4234 if (0) printf( "fx_dontjump_modifier (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4235 STAT_SET( IE_DONOTJUMP
, fx
->Parameter2
);
4239 //0xb9 see above: fx_hold_creature
4242 int fx_move_to_area (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4244 if (0) printf( "fx_move_to_area (%2d) %s", fx
->Opcode
, fx
->Resource
);
4245 //delay effect until the target has finished the previous move to an area
4246 //hopefully this fixes an evil bug
4247 Map
*map
= target
->GetCurrentArea();
4248 if (!map
|| !map
->HasActor(target
)) {
4249 //stay around for the next evaluation
4252 Point
p(fx
->PosX
,fx
->PosY
);
4253 MoveBetweenAreasCore(target
, fx
->Resource
, p
, fx
->Parameter2
, true);
4254 //this effect doesn't stick
4255 return FX_NOT_APPLIED
;
4258 // 0xbb Variable:StoreLocalVariable
4259 int fx_local_variable (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4261 //this is a hack, the variable name spreads across the resources
4262 if (0) printf( "fx_local_variable (%2d) %s=%d", fx
->Opcode
, fx
->Resource
, fx
->Parameter1
);
4263 target
->locals
->SetAt(fx
->Resource
, fx
->Parameter1
);
4264 //local variable effects are not applied, they will be resaved though
4265 return FX_NOT_APPLIED
;
4268 // 0xbc AuraCleansingModifier
4269 int fx_auracleansing_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4271 if (0) printf( "fx_auracleansing_modifier (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4272 STAT_SET( IE_AURACLEANSING
, fx
->Parameter2
);
4276 // 0xbd CastingSpeedModifier
4277 int fx_castingspeed_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4279 if (0) printf( "fx_castingspeed_modifier (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4280 STAT_MOD( IE_MENTALSPEED
);
4284 // 0xbe PhysicalSpeedModifier
4285 int fx_attackspeed_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4287 if (0) printf( "fx_attackspeed_modifier (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4288 STAT_MOD( IE_PHYSICALSPEED
);
4292 // 0xbf CastingLevelModifier
4293 int fx_castinglevel_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4295 if (0) printf( "fx_castinglevel_modifier (%2d) Value:%d Type:%d", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4296 switch (fx
->Parameter2
) {
4298 STAT_SET( IE_CASTINGLEVELBONUSMAGE
, fx
->Parameter1
);
4301 STAT_SET( IE_CASTINGLEVELBONUSCLERIC
, fx
->Parameter1
);
4304 return FX_NOT_APPLIED
;
4309 // 0xc0 FindFamiliar
4310 // param2 = 1 alignment is in param1
4311 // param2 = 2 resource used
4312 #define FAMILIAR_NORMAL 0
4313 #define FAMILIAR_ALIGNMENT 1
4314 #define FAMILIAR_RESOURCE 2
4316 static EffectRef fx_familiar_constitution_loss_ref
={"FamiliarBond",NULL
,-1};
4317 static EffectRef fx_familiar_marker_ref
={"FamiliarMarker",NULL
,-1};
4319 int fx_find_familiar (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
4321 if (0) printf( "fx_find_familiar (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4324 return FX_NOT_APPLIED
;
4327 if (!target
->GetCurrentArea()) {
4331 if (fx
->Parameter2
!=FAMILIAR_RESOURCE
) {
4334 if (fx
->Parameter2
==FAMILIAR_ALIGNMENT
) {
4335 alignment
= fx
->Parameter1
;
4337 alignment
= target
->GetStat(IE_ALIGNMENT
);
4338 alignment
= ((alignment
&AL_LC_MASK
)>>4)*3+(alignment
&AL_GE_MASK
)-4;
4341 return FX_NOT_APPLIED
;
4343 memcpy(fx
->Resource
, core
->GetGame()->Familiars
[alignment
],sizeof(ieResRef
) );
4344 fx
->Parameter2
=FAMILIAR_RESOURCE
;
4347 //summon familiar with fx->Resource
4348 Point
p(fx
->PosX
, fx
->PosY
);
4349 Effect
*newfx
= EffectQueue::CreateUnsummonEffect(fx
);
4350 Actor
*fam
= core
->SummonCreature(fx
->Resource
, fx
->Resource2
, Owner
, target
, p
, EAM_DEFAULT
, 0, newfx
, 0);
4354 //Make the familiar an NPC (MoveGlobal needs this)
4355 core
->GetGame()->AddNPC(fam
);
4357 //Add some essential effects
4358 newfx
= EffectQueue::CreateEffect(fx_familiar_constitution_loss_ref
, (ieDword
) -10, 0, FX_DURATION_INSTANT_PERMANENT
);
4359 core
->ApplyEffect(newfx
, fam
, fam
);
4362 newfx
= EffectQueue::CreateEffect(fx_familiar_marker_ref
, 0, 0, FX_DURATION_INSTANT_PERMANENT
);
4363 core
->ApplyEffect(newfx
, fam
, fam
);
4366 return FX_NOT_APPLIED
;
4369 // 0xc1 InvisibleDetection
4370 int fx_see_invisible_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4372 if (0) printf( "fx_see_invisible_modifier (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4373 STAT_SET( IE_SEEINVISIBLE
, fx
->Parameter2
);
4377 // 0xc2 IgnoreDialogPause
4378 int fx_ignore_dialogpause_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4380 if (0) printf( "fx_ignore_dialogpause_modifier (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4381 STAT_SET( IE_IGNOREDIALOGPAUSE
, fx
->Parameter2
);
4386 //when this effect's target dies it should incur damage on protagonist
4387 static EffectRef fx_damage_opcode_ref
={"Damage",NULL
,-1};
4388 static EffectRef fx_maximum_hp_modifier_ref
={"MaximumHPModifier",NULL
,-1};
4390 int fx_familiar_constitution_loss (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4392 if (0) printf( "fx_familiar_constitution_loss (%2d): Loss: %d\n", fx
->Opcode
,(signed) fx
->Parameter1
);
4393 if (! (STAT_GET(IE_STATE_ID
)&STATE_NOSAVE
)) {
4398 Actor
*master
= core
->GetGame()->FindPC(1);
4399 if (!master
) return FX_NOT_APPLIED
;
4400 //maximum hp (param1 is a negative value)
4401 newfx
= EffectQueue::CreateEffect(fx_maximum_hp_modifier_ref
, fx
->Parameter1
, 0, FX_DURATION_INSTANT_PERMANENT
);
4402 core
->ApplyEffect(newfx
, master
, master
);
4406 newfx
= EffectQueue::CreateEffect(fx_damage_opcode_ref
, 0, 0, FX_DURATION_INSTANT_PERMANENT
);
4407 core
->ApplyEffect(newfx
, master
, master
);
4410 return FX_NOT_APPLIED
;
4413 //0xc4 FamiliarMarker
4414 int fx_familiar_marker (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4416 if (0) printf( "fx_familiar_marker (%2d)\n", fx
->Opcode
);
4417 if (! (STAT_GET(IE_STATE_ID
)&STATE_NOSAVE
)) {
4418 //TODO: where to disable familiar?
4419 //core->GetGame()->WeatherBits|=1;
4422 //TODO: enable familiar?
4423 //core->GetGame()->WeatherBits&=~1;
4424 return FX_NOT_APPLIED
;
4427 // 0xc5 Bounce:Projectile
4428 int fx_bounce_projectile (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4430 if (0) printf( "fx_bounce_projectile (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4431 STAT_BIT_OR( IE_BOUNCE
, BNC_PROJECTILE
);
4435 // 0xc6 Bounce:Opcode
4436 int fx_bounce_opcode (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4438 if (0) printf( "fx_bounce_opcode (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4439 STAT_BIT_OR( IE_BOUNCE
, BNC_OPCODE
);
4440 target
->AddPortraitIcon(PI_BOUNCE2
);
4444 // 0xc7 Bounce:SpellLevel
4445 int fx_bounce_spelllevel (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4447 if (0) printf( "fx_bounce_spellevel (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4448 STAT_BIT_OR( IE_BOUNCE
, BNC_LEVEL
);
4449 target
->AddPortraitIcon(PI_BOUNCE2
);
4453 // 0xc8 Bounce:SpellLevelDec
4454 int fx_bounce_spelllevel_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4456 if (0) printf( "fx_bounce_spellevel_dec (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4457 STAT_BIT_OR( IE_BOUNCE
, BNC_LEVEL_DEC
);
4458 target
->AddPortraitIcon(PI_BOUNCE
);
4462 //0xc9 Protection:SpellLevelDec
4463 int fx_protection_spelllevel_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4465 if (0) printf( "fx_protection_spelllevel_dec (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4466 STAT_BIT_OR( IE_IMMUNITY
, IMM_LEVEL_DEC
);
4467 target
->AddPortraitIcon(PI_BOUNCE2
);
4471 //0xca Bounce:School
4472 int fx_bounce_school (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4474 if (0) printf( "fx_bounce_school (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4475 STAT_BIT_OR( IE_BOUNCE
, BNC_SCHOOL
);
4476 target
->AddPortraitIcon(PI_BOUNCE2
);
4480 // 0xcb Bounce:SecondaryType
4481 int fx_bounce_secondary_type (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4483 if (0) printf( "fx_bounce_secondary_type (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4484 STAT_BIT_OR( IE_BOUNCE
, BNC_SECTYPE
);
4485 target
->AddPortraitIcon(PI_BOUNCE2
);
4489 // 0xcc //resist school
4490 int fx_protection_school (Scriptable
* /*Owner*/, Actor
* target
, Effect
*fx
)
4492 if (0) printf( "fx_protection_school (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4493 STAT_BIT_OR( IE_IMMUNITY
, IMM_SCHOOL
);
4497 // 0xcd //resist sectype
4498 int fx_protection_secondary_type (Scriptable
* /*Owner*/, Actor
* target
, Effect
*fx
)
4500 if (0) printf( "fx_protection_secondary_type (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4501 STAT_BIT_OR( IE_IMMUNITY
, IMM_SECTYPE
);
4505 //0xce Protection:Spell
4506 int fx_resist_spell (Scriptable
* /*Owner*/, Actor
* target
, Effect
*fx
)
4508 if (0) printf( "fx_resist_spell (%2d): Resource: %s\n", fx
->Opcode
, fx
->Resource
);
4509 if (strnicmp(fx
->Resource
,fx
->Source
,sizeof(fx
->Resource
)) ) {
4510 STAT_BIT_OR( IE_IMMUNITY
, IMM_RESOURCE
);
4513 //this has effect only on first apply, it will stop applying the spell
4517 // ??? Protection:SpellDec
4518 int fx_resist_spell_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
*fx
)
4520 if (0) printf( "fx_resist_spell_dec (%2d): Resource: %s\n", fx
->Opcode
, fx
->Resource
);
4521 if (strnicmp(fx
->Resource
,fx
->Source
,sizeof(fx
->Resource
)) ) {
4522 STAT_BIT_OR( IE_IMMUNITY
, IMM_RESOURCE_DEC
);
4525 //this has effect only on first apply, it will stop applying the spell
4529 // 0xcf Bounce:Spell
4530 int fx_bounce_spell (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4532 if (0) printf( "fx_bounce_spell (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4533 STAT_BIT_OR( IE_BOUNCE
, BNC_RESOURCE
);
4537 // ??? Bounce:SpellDec
4538 int fx_bounce_spell_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4540 if (0) printf( "fx_bounce_spell (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4541 STAT_BIT_OR( IE_BOUNCE
, BNC_RESOURCE_DEC
);
4545 // 0xd0 MinimumHPModifier
4546 // the original engine didn't allow modifying of this stat
4547 // it allowed only setting it, and only by one instance
4548 int fx_minimum_hp_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4550 if (0) printf( "fx_minimum_hp_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4552 STAT_MOD( IE_MINHITPOINTS
);
4556 //0xd1 PowerWordKill
4557 int fx_power_word_kill (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
4559 if (0) printf( "fx_power_word_kill (%2d): HP: %d Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4562 if (fx
->Parameter1
) {
4563 limit
= fx
->Parameter1
;
4565 //normally this would work only with hitpoints
4566 //but why not add some extra features
4567 ieDword stat
= target
->GetStat (fx
->Parameter2
&0xffff);
4570 target
->Die( Owner
);
4572 return FX_NOT_APPLIED
;
4575 //0xd2 PowerWordStun
4576 int fx_power_word_stun (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
4578 if (0) printf( "fx_power_word_stun (%2d): HP: %d Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4581 if (fx
->Parameter1
) {
4582 limit
= fx
->Parameter1
;
4584 //normally this would work only with hitpoints
4585 //but why not add some extra features
4586 ieDword stat
= target
->GetStat (fx
->Parameter2
&0xffff);
4587 ieDword x
= fx
->Parameter2
>>16; //dice sides
4590 return FX_NOT_APPLIED
;
4593 stat
= (stat
* 3 + limit
- 1) / limit
;
4594 //delay will be calculated as 1dx/2dx/3dx
4595 //depending on the current hitpoints (or the stat in param2)
4596 stat
= core
->Roll(stat
,x
?x
:4,0) * ROUND_SIZE
;
4597 fx
->Duration
= core
->GetGame()->GameTime
+stat
;
4598 fx
->TimingMode
= FX_DURATION_ABSOLUTE
;
4599 fx
->Opcode
= EffectQueue::ResolveEffect(fx_set_stun_state_ref
);
4600 return fx_set_stun_state(Owner
,target
,fx
);
4603 //0xd3 State:Imprisonment (avatar removal plus portrait icon)
4604 int fx_imprisonment (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4606 if (0) printf( "fx_inprisonment (%2d)\n", fx
->Opcode
);
4607 target
->SetMCFlag(MC_HIDDEN
, BM_OR
);
4608 target
->AddPortraitIcon(PI_PRISON
);
4612 //0xd4 Cure:Imprisonment
4613 static EffectRef fx_imprisonment_ref
={"Imprisonment",NULL
,-1};
4614 static EffectRef fx_maze_ref
={"Maze",NULL
,-1};
4616 int fx_freedom (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4618 if (0) printf( "fx_freedom (%2d)\n", fx
->Opcode
);
4619 target
->fxqueue
.RemoveAllEffects( fx_imprisonment_ref
);
4620 target
->fxqueue
.RemoveAllEffects( fx_maze_ref
);
4621 return FX_NOT_APPLIED
;
4625 int fx_maze (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4627 if (0) printf( "fx_maze (%2d)\n", fx
->Opcode
);
4628 target
->SetMCFlag(MC_HIDDEN
, BM_OR
);
4629 target
->AddPortraitIcon(PI_MAZE
);
4634 int fx_select_spell (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
4636 if (0) printf( "fx_select_spell (%2d) %d\n", fx
->Opcode
, fx
->Parameter2
);
4637 //if parameter2==0 -> cast spells from 2da (all spells listed in 2da)
4638 //if parameter2==1 -> cast spells from book (all known spells, no need of memorize)
4639 return FX_NOT_APPLIED
;
4642 // 0xd7 PlayVisualEffect
4643 int fx_play_visual_effect (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4645 if (0) printf( "fx_play_visual_effect (%2d): Resource: %s Type: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
4647 //this is in the original engine (dead actors lose this effect)
4648 if (STATE_GET( STATE_DEAD
) ) {
4649 return FX_NOT_APPLIED
;
4652 //delay action until area is loaded to avoid crash
4653 Map
*map
= target
->GetCurrentArea();
4654 if (!map
) return FX_APPLIED
;
4656 //if it is sticky, don't add it if it is already played
4657 if (fx
->Parameter2
) {
4658 if (!target
->HasVVCCell(fx
->Resource
) ) {
4659 return FX_NOT_APPLIED
;
4663 ScriptedAnimation
* sca
= gamedata
->GetScriptedAnimation(fx
->Resource
, false);
4665 //don't crash on nonexistent resources
4667 return FX_NOT_APPLIED
;
4670 if (fx
->TimingMode
!=FX_DURATION_INSTANT_PERMANENT
) {
4671 sca
->SetDefaultDuration(fx
->Duration
-core
->GetGame()->GameTime
);
4673 if (fx
->Parameter2
) {
4674 //play over target (sticky)
4675 target
->AddVVCell( sca
);
4682 map
->AddVVCell( sca
);
4683 return FX_NOT_APPLIED
;
4686 //d8 LevelDrainModifier
4688 static EffectRef fx_leveldrain_ref
={"LevelDrainModifier",NULL
,-1};
4690 int fx_leveldrain_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4692 if (0) printf( "fx_leveldrain_modifier (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter1
);
4694 //never subtract more than the maximum hitpoints
4695 ieDword x
= STAT_GET(IE_MAXHITPOINTS
)-1;
4696 if (fx
->Parameter1
*4<x
) {
4699 STAT_ADD(IE_LEVELDRAIN
, fx
->Parameter1
);
4700 STAT_SUB(IE_MAXHITPOINTS
, x
);
4701 STAT_SUB(IE_SAVEVSDEATH
, fx
->Parameter1
);
4702 STAT_SUB(IE_SAVEVSWANDS
, fx
->Parameter1
);
4703 STAT_SUB(IE_SAVEVSPOLY
, fx
->Parameter1
);
4704 STAT_SUB(IE_SAVEVSBREATH
, fx
->Parameter1
);
4705 STAT_SUB(IE_SAVEVSSPELL
, fx
->Parameter1
);
4706 target
->AddPortraitIcon(PI_LEVELDRAIN
);
4707 //decrease current hitpoints on first apply
4708 if (fx
->FirstApply
) {
4709 //current hitpoints don't have base/modified, only current
4710 BASE_SUB(IE_HITPOINTS
, x
);
4716 static EffectRef fx_sleep_ref
={"State:Sleep",NULL
,-1};
4718 int fx_power_word_sleep (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
4720 if (0) printf( "fx_power_word_sleep (%2d): HP: %d Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4723 if (fx
->Parameter1
) {
4724 limit
= fx
->Parameter1
;
4727 ieDword stat
= target
->GetStat (fx
->Parameter2
&0xffff);
4728 ieDword x
= fx
->Parameter2
>>16; //rounds
4732 return FX_NOT_APPLIED
;
4734 //translate this effect to a normal sleep effect
4736 fx
->Duration
= core
->GetGame()->GameTime
+x
*ROUND_SIZE
;
4737 fx
->TimingMode
= FX_DURATION_ABSOLUTE
;
4738 fx
->Opcode
= EffectQueue::ResolveEffect(fx_sleep_ref
);
4740 return fx_set_unconscious_state(Owner
,target
,fx
);
4743 // 0xda StoneSkinModifier
4744 int fx_stoneskin_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4746 if (0) printf( "fx_stoneskin_modifier (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter1
);
4747 if (!fx
->Parameter1
) {
4748 return FX_NOT_APPLIED
;
4751 //dead actors lose this effect
4752 if (STATE_GET( STATE_DEAD
) ) {
4753 return FX_NOT_APPLIED
;
4756 //this is the bg2 style stoneskin, not normally using spell states
4757 //but this way we can support hybrid games
4758 if (fx
->Parameter2
) {
4759 target
->SetSpellState(SS_IRONSKIN
);
4760 //gradient for iron skins?
4762 target
->SetSpellState(SS_STONESKIN
);
4763 SetGradient(target
, 14);
4765 STAT_SET(IE_STONESKINS
, fx
->Parameter1
);
4766 target
->AddPortraitIcon(PI_STONESKIN
);
4770 //0xdb ac vs creature type (general effect)
4772 int fx_dispel_school (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4774 if (0) printf( "fx_dispel_school (%2d): Level: %d Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4775 target
->fxqueue
.RemoveLevelEffects(fx
->Parameter1
, RL_MATCHSCHOOL
, fx
->Parameter2
);
4776 return FX_NOT_APPLIED
;
4778 //0xdd DispelSecondaryType
4779 int fx_dispel_secondary_type (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4781 if (0) printf( "fx_dispel_secondary_type (%2d): Level: %d Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4782 target
->fxqueue
.RemoveLevelEffects(fx
->Parameter1
, RL_MATCHSECTYPE
, fx
->Parameter2
);
4783 return FX_NOT_APPLIED
;
4786 //0xde RandomTeleport
4787 int fx_teleport_field (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4789 if (0) printf( "fx_teleport_field (%2d): Distance: %d\n", fx
->Opcode
, fx
->Parameter1
);
4791 Map
*map
= target
->GetCurrentArea();
4793 return FX_NOT_APPLIED
;
4795 //this should be the target's position, i think
4796 Point p
= target
->Pos
;
4797 p
.x
+=core
->Roll(1,fx
->Parameter1
*2,-(signed) (fx
->Parameter1
));
4798 p
.y
+=core
->Roll(1,fx
->Parameter1
*2,-(signed) (fx
->Parameter1
));
4799 target
->SetPosition( p
, true, 0);
4800 return FX_NOT_APPLIED
;
4803 //0xdf //Protection:SchoolDec
4804 int fx_protection_school_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4806 if (0) printf( "fx_protection_school_dec (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4807 if (fx
->Parameter1
) {
4808 STAT_BIT_OR( IE_IMMUNITY
, IMM_SCHOOL_DEC
);
4811 return FX_NOT_APPLIED
;
4814 //0xe0 Cure:LevelDrain
4816 int fx_cure_leveldrain (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4818 if (0) printf( "fx_cure_leveldrain (%2d)\n", fx
->Opcode
);
4819 //all level drain removed at once???
4820 //if not, then find old effect, remove a number
4821 target
->fxqueue
.RemoveAllEffects( fx_leveldrain_ref
);
4822 return FX_NOT_APPLIED
;
4826 //gemrb special: speed and color are custom
4827 int fx_reveal_magic (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4829 if (0) printf( "fx_reveal_magic (%2d)\n", fx
->Opcode
);
4830 if (target
->fxqueue
.HasAnyDispellableEffect()) {
4831 if (!fx
->Parameter1
) {
4832 fx
->Parameter1
=0xff00; //blue
4835 int speed
= (fx
->Parameter2
>> 16) & 0xFF;
4836 if (!speed
) speed
=30;
4837 target
->SetColorMod(0xff, RGBModifier::ADD
, speed
,
4838 fx
->Parameter1
>> 8, fx
->Parameter1
>> 16,
4839 fx
->Parameter1
>> 24, 0);
4841 return FX_NOT_APPLIED
;
4844 //0xe2 Protection:SecondaryTypeDec
4845 int fx_protection_secondary_type_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4847 if (0) printf( "fx_protection_secondary_type_dec (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4848 if (fx
->Parameter1
) {
4849 STAT_BIT_OR( IE_IMMUNITY
, IMM_SECTYPE_DEC
);
4852 return FX_NOT_APPLIED
;
4855 //0xe3 Bounce:SchoolDecrement
4856 int fx_bounce_school_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4858 if (0) printf( "fx_bounce_school_dec (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4859 STAT_BIT_OR( IE_BOUNCE
, BNC_SCHOOL_DEC
);
4860 target
->AddPortraitIcon(PI_BOUNCE2
);
4864 //0xe4 Bounce:SecondaryTypeDecrement
4865 int fx_bounce_secondary_type_dec (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4867 if (0) printf( "fx_bounce_secondary_type_dec (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
4868 STAT_BIT_OR( IE_BOUNCE
, BNC_SECTYPE_DEC
);
4869 target
->AddPortraitIcon(PI_BOUNCE2
);
4873 //0xe5 DispelSchoolOne
4874 int fx_dispel_school_one (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4876 if (0) printf( "fx_dispel_school_one (%2d): Level: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4877 target
->fxqueue
.RemoveLevelEffects(fx
->Parameter1
, RL_MATCHSCHOOL
|RL_REMOVEFIRST
, fx
->Parameter2
);
4878 return FX_NOT_APPLIED
;
4881 //0xe6 DispelSecondaryTypeOne
4882 int fx_dispel_secondary_type_one (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4884 if (0) printf( "fx_dispel_secondary_type_one (%2d): Level: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4885 target
->fxqueue
.RemoveLevelEffects(fx
->Parameter1
,RL_MATCHSECTYPE
|RL_REMOVEFIRST
, fx
->Parameter2
);
4886 return FX_NOT_APPLIED
;
4890 int fx_timestop (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4892 if (0) printf( "fx_timestop (%2d)\n", fx
->Opcode
);
4893 core
->GetGame()->TimeStop(target
, fx
->Duration
);
4894 return FX_NOT_APPLIED
;
4897 //0xe8 CastSpellOnCondition
4898 int fx_cast_spell_on_condition (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
4900 if (0) printf( "fx_cast_spell_on_condition (%2d): Target: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4902 if (fx
->FirstApply
&& fx
->Parameter3
) {
4903 target
->spellbook
.HaveSpell( fx
->Resource
, HS_DEPLETE
);
4904 target
->spellbook
.HaveSpell( fx
->Resource2
, HS_DEPLETE
);
4905 target
->spellbook
.HaveSpell( fx
->Resource3
, HS_DEPLETE
);
4906 target
->spellbook
.HaveSpell( fx
->Resource4
, HS_DEPLETE
);
4909 //get subject of check
4910 Actor
*actor
= NULL
;
4911 Map
*map
= target
->GetCurrentArea();
4912 switch(fx
->Parameter1
) {
4914 case 0: actor
= target
; break;
4916 case 1: actor
= map
->GetActorByGlobalID(target
->LastHitter
); break;
4919 //case 2: actor = map->GetActorByGlobalID(target->LastSeen); break;
4920 case 2: actor
= GetNearestEnemyOf(map
, target
, 0); break;
4922 case 3: actor
= map
->GetActorByGlobalID(target
->LastSeen
); break;
4929 switch(fx
->Parameter2
) {
4930 case COND_GOTHIT
: //on hit
4931 condition
= target
->LastDamage
;
4934 condition
= PersonalDistance(actor
, target
)<30;
4937 condition
= actor
->GetBase(IE_HITPOINTS
)<actor
->GetStat(IE_MAXHITPOINTS
)/2;
4940 condition
= actor
->GetBase(IE_HITPOINTS
)<actor
->GetStat(IE_MAXHITPOINTS
)/4;
4943 condition
= actor
->GetBase(IE_HITPOINTS
)<actor
->GetStat(IE_MAXHITPOINTS
)/10;
4946 condition
= actor
->GetStat(IE_STATE_ID
) & STATE_CANTMOVE
;
4949 condition
= actor
->GetStat(IE_STATE_ID
) & STATE_POISONED
;
4952 condition
= actor
->LastHitter
;
4955 condition
= actor
->LastDamage
;
4965 core
->ApplySpell(fx
->Resource
, actor
, Owner
, fx
->Power
);
4966 core
->ApplySpell(fx
->Resource2
, actor
, Owner
, fx
->Power
);
4967 core
->ApplySpell(fx
->Resource3
, actor
, Owner
, fx
->Power
);
4968 core
->ApplySpell(fx
->Resource4
, actor
, Owner
, fx
->Power
);
4969 if (fx
->Parameter3
) {
4970 return FX_NOT_APPLIED
;
4977 int fx_proficiency (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4979 if (0) printf( "fx_proficiency (%2d): Value: %d, Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4981 if (fx
->Parameter2
>=MAX_STATS
) return FX_NOT_APPLIED
;
4983 //this opcode works only if the previous value was smaller
4984 if (STAT_GET(fx
->Parameter2
)<fx
->Parameter1
) {
4985 STAT_SET (fx
->Parameter2
, fx
->Parameter1
);
4990 // 0xea CreateContingency
4991 static EffectRef fx_contingency_ref
={"CastSpellOnCondition",NULL
,-1};
4993 int fx_create_contingency (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
4995 if (0) printf( "fx_create_contingency (%2d): Level: %d, Count: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
4997 printf("Check source:%s\n", fx
->Source
);
4998 if (target
->fxqueue
.HasEffectWithSource(fx_contingency_ref
, fx
->Source
)) {
4999 displaymsg
->DisplayConstantStringName(STR_CONTDUP
, 0xf0f0f0, target
);
5000 return FX_NOT_APPLIED
;
5003 if (target
->InParty
) {
5004 Variables
*dict
= core
->GetDictionary();
5006 dict
->SetAt( "P0", target
->InParty
);
5007 dict
->SetAt( "P1", fx
->Parameter1
);
5008 dict
->SetAt( "P2", fx
->Parameter2
);
5009 core
->SetEventFlag(EF_SEQUENCER
);
5011 return FX_NOT_APPLIED
;
5015 #define WB_TOWARDS 1
5018 #define WB_AWAYOWNDIR 4
5021 int fx_wing_buffet (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
5023 if (0) printf( "fx_wing_buffet (%2d): Value: %d, Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5024 //create movement in actor
5027 switch(fx
->Parameter2
) {
5030 dir
= GetOrient(Owner
->Pos
, target
->Pos
);
5033 dir
= GetOrient(target
->Pos
, Owner
->Pos
);
5036 dir
= fx
->Parameter3
;
5039 dir
= target
->GetOrientation();
5042 dir
= target
->GetOrientation()^8;
5045 //could be GL_REBOUND too :)
5046 //add effect to alter target's stance
5047 target
->MoveLine( fx
->Parameter1
, GL_NORMAL
, dir
);
5048 return FX_NOT_APPLIED
;
5051 // 0xec ProjectImage
5053 static EffectRef fx_puppetmarker_ref
={"PuppetMarker",NULL
,-1};
5055 int fx_puppet_master (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5057 const char * resref
= NULL
;
5059 if (0) printf( "fx_puppet_master (%2d): Value: %d, Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5060 STAT_SET (IE_PUPPETMASTERTYPE
, fx
->Parameter1
);
5062 //copyself doesn't copy scripts, so the script clearing code is not needed
5063 Actor
*copy
= target
->CopySelf();
5065 Effect
*newfx
= EffectQueue::CreateUnsummonEffect(fx
);
5067 core
->ApplyEffect(newfx
, copy
, copy
);
5073 //intentionally 7, to leave room for the last letter
5074 strnlwrcpy(script
,target
->GetScript(SCR_CLASS
),7);
5075 //no need of buffer defense as long as you don't mess with the 7 above
5077 //if the caster is inparty, the script is turned off by the AI disable flag
5078 copy
->SetScript(script
, SCR_CLASS
, target
->InParty
!=0);
5080 switch(fx
->Parameter2
)
5089 resref
= "simulacr";
5092 resref
= fx
->Resource
;
5096 core
->ApplySpell(resref
,copy
,copy
,0);
5099 //FIXME: parameter1 is unsure, but something similar to what the original engine has there
5100 newfx
= EffectQueue::CreateEffectCopy(fx
, fx_puppetmarker_ref
, target
->InParty
-1, fx
->Parameter2
);
5102 core
->ApplyEffect(newfx
, copy
, copy
);
5105 return FX_NOT_APPLIED
;
5108 // 0xed PuppetMarker
5109 int fx_puppet_marker (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5111 if (0) printf( "fx_puppet_marker (%2d): Value: %d, Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5112 //actually the Type is in parameter2 and the ID is in parameter1
5113 //but for some reason the defines are in the opposite order
5114 STAT_SET (IE_PUPPETTYPE
, fx
->Parameter1
); //cb4 - the ID of the controller
5115 STAT_SET (IE_PUPPETID
, fx
->Parameter2
); //cb8 - the control type
5119 // 0xee Disintegrate
5120 int fx_disintegrate (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5122 if (0) printf( "fx_disintegrate (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5123 if (EffectQueue::match_ids( target
, fx
->Parameter2
, fx
->Parameter1
) ) {
5124 //convert it to a death opcode or apply the new effect?
5125 fx
->Opcode
= EffectQueue::ResolveEffect(fx_death_ref
);
5126 fx
->TimingMode
= FX_DURATION_INSTANT_PERMANENT
;
5128 fx
->Parameter2
= 0x200;
5131 return FX_NOT_APPLIED
;
5135 // 1 view not explored sections too
5136 // 2 param1=range (otherwise visualrange)
5137 // 4 point already set (otherwise use gui)
5138 // 8 use line of sight
5139 #define FS_UNEXPLORED 1
5140 #define FS_VISUALRANGE 2
5141 #define FS_HASPOINT 4
5144 int fx_farsee (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5146 if (0) printf( "fx_farsee (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5147 Map
*map
= target
->GetCurrentArea();
5152 if (!(fx
->Parameter2
&FS_VISUALRANGE
)) {
5153 fx
->Parameter1
=STAT_GET(IE_VISUALRANGE
);
5154 fx
->Parameter2
|=FS_VISUALRANGE
;
5157 if (target
->InParty
) {
5158 //don't start graphical interface if actor isn't in party
5159 if (!(fx
->Parameter2
&FS_HASPOINT
)) {
5160 //start graphical interface
5161 //it will do all the rest of the opcode
5162 //using RevealMap guiscript action
5163 core
->EventFlag
|=EF_SHOWMAP
;
5164 return FX_NOT_APPLIED
;
5168 Point
p(fx
->PosX
, fx
->PosY
);
5170 //don't explore unexplored points
5171 if (!(fx
->Parameter2
&FS_UNEXPLORED
)) {
5172 if (!map
->IsVisible(p
, 1)) {
5173 return FX_NOT_APPLIED
;
5176 map
->ExploreMapChunk(p
, fx
->Parameter1
, fx
->Parameter2
&FS_LOS
);
5177 return FX_NOT_APPLIED
;
5181 int fx_remove_portrait_icon (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5183 if (0) printf( "fx_remove_portrait_icon (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
5184 target
->fxqueue
.RemoveAllEffectsWithParam( fx_display_portrait_icon_ref
, fx
->Parameter2
);
5185 return FX_NOT_APPLIED
;
5187 // 0xf1 control creature (same as charm)
5189 // 0xF2 Cure:Confusion
5190 static EffectRef fx_confused_state_ref
={"State:Confused",NULL
,-1};
5192 int fx_cure_confused_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5194 if (0) printf( "fx_cure_confused_state (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5195 BASE_STATE_CURE( STATE_CONFUSED
);
5196 target
->fxqueue
.RemoveAllEffects(fx_confused_state_ref
);
5197 return FX_NOT_APPLIED
;
5200 // 0xf3 DrainItems (this is disabled in ToB)
5201 int fx_drain_items (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5203 if (0) printf( "fx_drain_items (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5204 ieDword i
=fx
->Parameter1
;
5206 //deplete magic item = 0
5207 //deplete weapon = 1
5208 target
->inventory
.DepleteItem(fx
->Parameter2
);
5210 return FX_NOT_APPLIED
;
5213 int fx_drain_spells (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5215 if (0) printf( "fx_drain_spells (%2d): Count: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5216 ieDword i
=fx
->Parameter1
;
5217 if (fx
->Parameter2
) {
5219 if (!target
->spellbook
.DepleteSpell(IE_SPELL_TYPE_PRIEST
)) {
5223 return FX_NOT_APPLIED
;
5226 if (!target
->spellbook
.DepleteSpell(IE_SPELL_TYPE_WIZARD
)) {
5230 return FX_NOT_APPLIED
;
5232 // 0xf5 CheckForBerserk
5233 int fx_checkforberserk_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5235 if (0) printf( "fx_checkforberserk_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5236 STAT_SET( IE_CHECKFORBERSERK
, fx
->Parameter2
);
5239 // 0xf6 BerserkStage1Modifier
5240 int fx_berserkstage1_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5242 if (0) printf( "fx_berserkstage1_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5243 STAT_SET( IE_BERSERKSTAGE1
, fx
->Parameter2
);
5246 // 0xf7 BerserkStage2Modifier
5247 int fx_berserkstage2_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5249 if (0) printf( "fx_berserkstage2_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5250 STAT_SET( IE_BERSERKSTAGE2
, fx
->Parameter2
);
5251 STATE_SET (STATE_BERSERK
);
5254 // 0xf8 set melee effect generic effect?
5255 // 0xf9 set missile effect generic effect?
5256 // 0xfa DamageLuckModifier
5257 int fx_damageluck_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5259 if (0) printf( "fx_damageluck_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5260 STAT_MOD( IE_DAMAGELUCK
);
5264 // 0xfb bardsong (generic effect)
5267 int fx_set_area_effect (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
5269 if (0) printf( "fx_set_trap (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5270 ieDword skill
, roll
;
5273 map
= target
->GetCurrentArea();
5274 if (!map
) return FX_NOT_APPLIED
;
5278 //check if trap count is over an amount (only saved traps count)
5279 //actually, only projectiles in trigger phase should count here
5280 if (map
->GetTrapCount(iter
)>6) {
5281 displaymsg
->DisplayConstantStringName(STR_NOMORETRAP
, 0xf0f0f0, target
);
5282 return FX_NOT_APPLIED
;
5285 //check if we are under attack
5286 if (GetNearestEnemyOf(map
, target
, ORIGIN_SEES_ENEMY
|ENEMY_SEES_ORIGIN
)) {
5287 displaymsg
->DisplayConstantStringName(STR_MAYNOTSETTRAP
, 0xf0f0f0, target
);
5288 return FX_NOT_APPLIED
;
5291 if (Owner
->Type
==ST_ACTOR
) {
5292 skill
= ((Actor
*)Owner
)->GetStat(IE_SETTRAPS
);
5293 roll
= core
->Roll(1,100,0);
5301 displaymsg
->DisplayConstantStringName(STR_SNAREFAILED
, 0xf0f0f0, target
);
5302 //TODO check luck and do some damage effect on target
5303 return FX_NOT_APPLIED
;
5306 displaymsg
->DisplayConstantStringName(STR_SNARESUCCEED
, 0xf0f0f0, target
);
5307 Owner
->CastSpellPoint(fx
->Resource
, target
->Pos
, false);
5308 return FX_NOT_APPLIED
;
5312 int fx_set_map_note (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
5314 if (0) printf( "fx_set_map_note (%2d): StrRef: %d Color: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5315 Scriptable
*marker
= target
?target
:Owner
;
5316 Map
*map
= marker
->GetCurrentArea();
5317 if (!map
) return FX_APPLIED
; //delay effect
5318 Point
p(fx
->PosX
, fx
->PosY
);
5319 char *text
= core
->GetString(fx
->Parameter1
, 0);
5320 map
->AddMapNote(p
, fx
->Parameter2
, text
, fx
->Parameter1
);
5321 return FX_NOT_APPLIED
;
5324 // 0xfe RemoveMapNote
5325 int fx_remove_map_note (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
5327 if (0) printf( "fx_remove_map_note (%2d)\n", fx
->Opcode
);
5328 Scriptable
*marker
= target
?target
:Owner
;
5329 Map
*map
= marker
->GetCurrentArea();
5330 if (!map
) return FX_APPLIED
; //delay effect
5331 Point
p(fx
->PosX
, fx
->PosY
);
5332 map
->RemoveMapNote(p
);
5333 return FX_NOT_APPLIED
;
5336 // 0xff Item:CreateDays
5337 int fx_create_item_days (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5339 if (0) printf( "fx_create_item_days (%2d)\n", fx
->Opcode
);
5340 target
->inventory
.AddSlotItemRes( fx
->Resource
, SLOT_ONLYINVENTORY
, fx
->Parameter1
, fx
->Parameter3
, fx
->Parameter4
);
5341 if ((fx
->TimingMode
&0xff) == FX_DURATION_INSTANT_LIMITED
) {
5342 //if this effect has expiration, then it will remain as a remove_item
5343 //on the effect queue, inheriting all the parameters
5344 //duration needs a hack (recalculate it for days)
5345 //no idea if this multiplier is ok
5346 fx
->Duration
+=(fx
->Duration
-core
->GetGame()->GameTime
)*2400;
5347 fx
->Opcode
=EffectQueue::ResolveEffect(fx_remove_inventory_item_ref
);
5348 fx
->TimingMode
=FX_DURATION_DELAY_PERMANENT
;
5351 return FX_NOT_APPLIED
;
5354 // 0x100 Sequencer:Store
5355 int fx_store_spell_sequencer(Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5357 if (0) printf( "fx_store_spell_sequencer (%2d)\n", fx
->Opcode
);
5358 //just display the spell sequencer portrait icon
5359 target
->AddPortraitIcon(PI_SEQUENCER
);
5360 if (fx
->FirstApply
&& fx
->Parameter3
) {
5361 target
->spellbook
.HaveSpell( fx
->Resource
, HS_DEPLETE
);
5362 target
->spellbook
.HaveSpell( fx
->Resource2
, HS_DEPLETE
);
5363 target
->spellbook
.HaveSpell( fx
->Resource3
, HS_DEPLETE
);
5364 target
->spellbook
.HaveSpell( fx
->Resource4
, HS_DEPLETE
);
5369 // 0x101 Sequencer:Create
5370 static EffectRef fx_spell_sequencer_active_ref
={"Sequencer:Store",NULL
,-1};
5372 int fx_create_spell_sequencer(Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5374 if (0) printf( "fx_create_spell_sequencer (%2d): Level: %d, Count: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5375 printf("Check source:%s\n", fx
->Source
);
5376 if (target
->fxqueue
.HasEffectWithSource(fx_spell_sequencer_active_ref
, fx
->Source
)) {
5377 displaymsg
->DisplayConstantStringName(STR_SEQDUP
, 0xf0f0f0, target
);
5378 return FX_NOT_APPLIED
;
5380 //just a call to activate the spell sequencer creation gui
5381 if (target
->InParty
) {
5382 Variables
*dict
= core
->GetDictionary();
5384 dict
->SetAt( "P0", target
->InParty
);
5385 dict
->SetAt( "P1", fx
->Parameter1
); //maximum level
5386 dict
->SetAt( "P2", fx
->Parameter2
| (2<<16) ); //count and target type
5387 core
->SetEventFlag(EF_SEQUENCER
);
5389 return FX_NOT_APPLIED
;
5392 // 0x102 Sequencer:Activate
5394 int fx_activate_spell_sequencer(Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
5396 if (0) printf( "fx_activate_spell_sequencer (%2d): Resource: %s\n", fx
->Opcode
, fx
->Resource
);
5397 if (Owner
->Type
!=ST_ACTOR
) {
5398 return FX_NOT_APPLIED
;
5401 Effect
*sequencer
= ((Actor
*) Owner
)->fxqueue
.HasEffect(fx_spell_sequencer_active_ref
);
5403 //cast 1-4 spells stored in the spell sequencer
5404 core
->ApplySpell(sequencer
->Resource
, target
, Owner
, fx
->Power
);
5405 core
->ApplySpell(sequencer
->Resource2
, target
, Owner
, fx
->Power
);
5406 core
->ApplySpell(sequencer
->Resource3
, target
, Owner
, fx
->Power
);
5407 core
->ApplySpell(sequencer
->Resource4
, target
, Owner
, fx
->Power
);
5408 //remove the spell sequencer store effect
5409 sequencer
->TimingMode
=FX_DURATION_JUST_EXPIRED
;
5411 return FX_NOT_APPLIED
;
5414 // 0x103 SpellTrap (Protection:SpellLevelDec + recall spells)
5415 int fx_spelltrap(Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5417 if (0) printf( "fx_spelltrap (%2d): Count: %d, Level: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5418 if (fx
->Parameter3
) {
5419 target
->RestoreSpellLevel(fx
->Parameter3
, 0);
5422 if (fx
->Parameter1
<=0) {
5424 return FX_NOT_APPLIED
;
5426 target
->SetOverlay(OV_SPELLTRAP
);
5427 target
->AddPortraitIcon(PI_SPELLTRAP
);
5433 int fx_crash (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
5435 if (0) printf( "fx_crash (%2d): Param1: %d, Param2: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5436 return FX_NOT_APPLIED
;
5439 // 0x105 RestoreSpells
5440 int fx_restore_spell_level(Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5442 if (0) printf( "fx_restore_spell_level (%2d): Level: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5443 target
->RestoreSpellLevel(fx
->Parameter1
, fx
->Parameter2
);
5444 return FX_NOT_APPLIED
;
5446 // 0x106 VisualRangeModifier
5447 int fx_visual_range_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5449 if (0) printf( "fx_visual_range_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5450 STAT_MOD( IE_VISUALRANGE
);
5454 // 0x107 BackstabModifier
5455 int fx_backstab_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5457 if (0) printf( "fx_visual_range_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5458 //this is how it is done in the original engine, i don't know why they would do this
5459 //ctrl-r would probably remove it otherwise
5460 //Why they didn't fix it in the spell/item is beyond me
5461 if (fx
->TimingMode
==FX_DURATION_INSTANT_PERMANENT
)
5462 fx
->TimingMode
=FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES
;
5463 STAT_MOD( IE_BACKSTABDAMAGEMULTIPLIER
);
5468 int fx_drop_weapon (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5470 if (fx
->Resource
[0]) {
5471 target
->DropItem(fx
->Resource
, 0);
5472 return FX_NOT_APPLIED
;
5474 switch (fx
->Parameter2
) {
5476 target
->DropItem(-1, 0);
5479 target
->DropItem(target
->inventory
.GetEquippedSlot(), 0);
5482 target
->DropItem(fx
->Parameter1
, 0);
5485 return FX_NOT_APPLIED
;
5487 // 0x109 ModifyGlobalVariable
5488 int fx_modify_global_variable (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
5490 Game
*game
= core
->GetGame();
5491 //convert it to internal variable format
5492 if (!fx
->IsVariable
) {
5493 char *poi
=fx
->Resource
+8;
5494 memmove(poi
, fx
->Resource2
,8);
5496 memmove(poi
, fx
->Resource3
,8);
5498 memmove(poi
, fx
->Resource4
,8);
5503 if (!fx
->Resource
[0]) {
5504 strnuprcpy(fx
->Resource
,"RETURN_TO_LONELYWOOD",32);
5507 if (0) printf( "fx_modify_global_variable (%2d): Variable: %s Value: %d Type: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter1
, fx
->Parameter2
);
5508 if (fx
->Parameter2
) {
5510 //use resource memory area as variable name
5511 game
->locals
->Lookup(fx
->Resource
, var
);
5512 game
->locals
->SetAt(fx
->Resource
, var
+fx
->Parameter1
);
5514 game
->locals
->SetAt(fx
->Resource
, fx
->Parameter1
);
5516 return FX_NOT_APPLIED
;
5518 // 0x10a RemoveImmunity
5519 EffectRef immunity_effect_ref
={"Protection:Spell",NULL
,-1};
5521 int fx_remove_immunity(Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5523 if (0) printf( "fx_remove_immunity (%2d): %s\n", fx
->Opcode
, fx
->Resource
);
5524 target
->fxqueue
.RemoveAllEffectsWithResource(immunity_effect_ref
, fx
->Resource
);
5525 return FX_NOT_APPLIED
;
5528 // 0x10b protection from display string is a generic effect
5529 // 0x10c ExploreModifier
5530 int fx_explore_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5532 if (0) printf( "fx_explore_modifier (%2d)\n", fx
->Opcode
);
5533 if (fx
->Parameter2
) {
5535 STAT_SET (IE_EXPLORE
, fx
->Parameter1
);
5537 STAT_SET (IE_EXPLORE
, 1);
5541 // 0x10d ScreenShake
5542 int fx_screenshake (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
5544 if (0) printf( "fx_screenshake (%2d): Strength: %d\n", fx
->Opcode
, fx
->Parameter1
);
5545 core
->timer
->SetScreenShake( fx
->Parameter1
, fx
->Parameter1
, 1);
5549 // 0x10e Cure:CasterHold
5550 static EffectRef fx_pause_caster_modifier_ref
={"PauseTarget",NULL
,-1};
5552 int fx_unpause_caster (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5554 if (0) printf( "fx_unpause_caster (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5555 Effect
*eff
= target
->fxqueue
.HasEffect(fx_pause_caster_modifier_ref
);
5557 eff
->Parameter1
-=fx
->Parameter2
;
5559 return FX_NOT_APPLIED
;
5561 // 0x10f AvatarRemoval
5562 // 0x104 AvatarRemoval (iwd)
5563 int fx_avatar_removal (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5565 if (0) printf( "fx_avatar_removal (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5566 //FIXME: this is a permanent irreversible effect in IWD
5567 //if it is different in bg2, then create another effect
5568 //bg2 calls this SummonDisable
5569 BASE_SET(IE_AVATARREMOVAL
, 1);
5570 return FX_NOT_APPLIED
;
5572 // 0x110 ApplyEffectRepeat
5573 int fx_apply_effect_repeat (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
5575 ieDword i
; //moved here because msvc6 cannot handle it otherwise
5577 if (0) printf( "fx_apply_effect_repeat (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5579 Point
p(fx
->PosX
, fx
->PosY
);
5580 Effect
*newfx
= core
->GetEffect(fx
->Resource
, fx
->Power
, p
);
5581 //core->GetEffect is a borrowed reference, don't delete it
5583 return FX_NOT_APPLIED
;
5586 switch (fx
->Parameter2
) {
5587 case 0: //once per second
5589 core
->ApplyEffect(newfx
, target
, Owner
);
5591 case 2://param1 times every second
5592 for (i
=0;i
<fx
->Parameter1
;i
++) {
5593 core
->ApplyEffect(newfx
, target
, Owner
);
5596 case 3: //once every Param1 second
5597 if (fx
->Parameter1
&& (core
->GetGame()->GameTime
%fx
->Parameter1
)) {
5598 core
->ApplyEffect(newfx
, target
, Owner
);
5601 case 4: //param3 times every Param1 second
5602 if (fx
->Parameter1
&& (core
->GetGame()->GameTime
%fx
->Parameter1
)) {
5603 for (i
=0;i
<fx
->Parameter3
;i
++) {
5604 core
->ApplyEffect(newfx
, target
, Owner
);
5612 // 0x111 RemoveProjectile
5613 int fx_remove_projectile (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5615 ieDword
*projectilelist
;
5618 if (0) printf( "fx_remove_projectile (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5620 if (!target
) return FX_NOT_APPLIED
;
5621 Map
*area
= target
->GetCurrentArea();
5622 if (!area
) return FX_NOT_APPLIED
;
5624 switch (fx
->Parameter2
) {
5625 case 0: //standard bg2
5626 projectilelist
= core
->GetListFrom2DA("clearair");
5628 case 1: //you can give a 2da for projectile list (gemrb)
5629 projectilelist
= core
->GetListFrom2DA(fx
->Resource
);
5631 case 2: //or you can give one single projectile in param1 (gemrb)
5632 projectilelist
= (ieDword
*) malloc(2*sizeof(ieDword
));
5633 projectilelist
[0]=1;
5634 projectilelist
[1]=fx
->Parameter1
;
5637 return FX_NOT_APPLIED
;
5639 //The first element is the counter, so don't decrease the counter here
5640 Point
p(fx
->PosX
, fx
->PosY
);
5642 while(projectilelist
[0]) {
5643 ieDword projectile
= projectilelist
[projectilelist
[0]];
5646 size_t cnt
= area
->GetProjectileCount(piter
);
5648 Projectile
*pro
= *piter
;
5649 if ((pro
->GetType()==projectile
) && pro
->PointInRadius(p
) ) {
5654 target
->fxqueue
.RemoveAllEffectsWithProjectile(projectile
);
5656 projectilelist
[0]--;
5658 free(projectilelist
);
5659 return FX_NOT_APPLIED
;
5662 // 0x112 TeleportToTarget
5663 int fx_teleport_to_target (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5665 if (0) printf( "fx_teleport_to_target (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5666 Map
*map
= target
->GetCurrentArea();
5668 Actor
*victim
= map
->GetActorByGlobalID(target
->LastAttacker
);
5670 target
->SetPosition( victim
->Pos
, true, 0 );
5673 return FX_NOT_APPLIED
;
5675 // 0x113 HideInShadowsModifier
5676 int fx_hide_in_shadows_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5678 if (0) printf( "fx_hide_in_shadows_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5679 STAT_MOD( IE_HIDEINSHADOWS
);
5682 // 0x114 DetectIllusionsModifier
5683 int fx_detect_illusion_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5685 if (0) printf( "fx_detect_illusion_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5686 STAT_MOD( IE_DETECTILLUSIONS
);
5689 // 0x115 SetTrapsModifier
5690 int fx_set_traps_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5692 if (0) printf( "fx_set_traps_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5693 STAT_MOD( IE_SETTRAPS
);
5696 // 0x116 ToHitBonusModifier
5697 int fx_to_hit_bonus_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5699 if (0) printf( "fx_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5700 HandleBonus( target
, IE_HITBONUS
, fx
->Parameter1
, fx
->TimingMode
);
5704 // 0x117 RenableButton
5705 static EffectRef fx_disable_button_ref
={"DisableButton",NULL
,-1};
5707 int fx_renable_button (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5709 //removes the disable button effect
5710 if (0) printf( "fx_renable_button (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
5711 target
->fxqueue
.RemoveAllEffectsWithParam( fx_disable_button_ref
, fx
->Parameter2
);
5712 return FX_NOT_APPLIED
;
5714 // 0x118 ForceSurgeModifier
5715 int fx_force_surge_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5717 if (0) printf( "fx_force_surge_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5718 STAT_MOD( IE_FORCESURGE
);
5722 // 0x119 WildSurgeModifier
5723 int fx_wild_surge_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5725 if (0) printf( "fx_wild_surge_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5726 STAT_MOD( IE_SURGEMOD
);
5730 // 0x11a ScriptingState
5731 int fx_scripting_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5733 if (0) printf( "fx_scripting_state (%2d): Value: %d, Stat: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5735 //original engine didn't check boundaries, causing crashes
5736 //we allow only positive indices (some extra stats are still addressable)
5737 if (fx
->Parameter2
>100) {
5738 return FX_NOT_APPLIED
;
5740 //original engine used only single byte value, we allow full dword
5741 STAT_SET( IE_SCRIPTINGSTATE1
+fx
->Parameter2
, fx
->Parameter1
);
5745 // 0x11b ApplyEffectCurse
5746 int fx_apply_effect_curse (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5748 if (0) printf( "fx_apply_effect_curse (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5750 //this effect executes a file effect in place of this effect
5751 //the file effect inherits the target and the timingmode, but gets
5752 //a new chance to roll percents
5753 int ret
= FX_NOT_APPLIED
;
5758 if (EffectQueue::match_ids( target
, fx
->Parameter2
, fx
->Parameter1
) ) {
5759 Point
p(fx
->PosX
, fx
->PosY
);
5761 //apply effect, if the effect is a goner, then kill
5763 Effect
*newfx
= core
->GetEffect(fx
->Resource
, fx
->Power
, p
);
5765 Effect
*myfx
= new Effect
;
5766 memcpy(myfx
, newfx
, sizeof(Effect
));
5767 myfx
->random_value
= core
->Roll(1,100,0);
5768 myfx
->TimingMode
=fx
->TimingMode
;
5769 myfx
->Duration
=fx
->Duration
;
5770 myfx
->Target
= FX_TARGET_PRESET
;
5771 ret
= target
->fxqueue
.ApplyEffect(target
, myfx
, fx
->FirstApply
);
5774 //newfx is a borrowed reference don't delete it
5779 // 0x11c MeleeHitModifier
5780 int fx_melee_to_hit_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5782 if (0) printf( "fx_melee_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5783 STAT_MOD( IE_MELEETOHIT
);
5787 // 0x11d MeleeDamageModifier
5788 int fx_melee_damage_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5790 if (0) printf( "fx_melee_damage_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5791 STAT_MOD( IE_MELEEDAMAGE
);
5795 // 0x11e MissileDamageModifier
5796 int fx_missile_damage_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5798 if (0) printf( "fx_missile_damage_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5799 STAT_MOD( IE_MISSILEDAMAGE
);
5803 // 0x11f NoCircleState
5804 int fx_no_circle_state (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5806 if (0) printf( "fx_missile_damage_modifier (%2d)\n", fx
->Opcode
);
5807 STAT_SET( IE_NOCIRCLE
, 1 );
5811 // 0x120 FistHitModifier
5812 int fx_fist_to_hit_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5814 if (0) printf( "fx_fist_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5815 STAT_MOD( IE_FISTHIT
);
5819 // 0x121 FistDamageModifier
5820 int fx_fist_damage_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5822 if (0) printf( "fx_fist_damage_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5823 STAT_MOD( IE_FISTDAMAGE
);
5826 //0x122 TitleModifier
5827 int fx_title_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5829 if (0) printf( "fx_fist_damage_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5830 if (fx
->Parameter2
) {
5831 STAT_SET( IE_TITLE2
, fx
->Parameter1
);
5833 STAT_SET( IE_TITLE1
, fx
->Parameter1
);
5837 //0x123 DisableOverlay
5838 //FIXME: which overlay is disabled?
5839 //if one of the overlays marked by sanctuary, then
5840 //make the bit correspond to it
5841 int fx_disable_overlay_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5843 if (0) printf( "fx_disable_overlay_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5844 STAT_SET( IE_DISABLEOVERLAY
, fx
->Parameter1
);
5847 //0x124 Protection:Backstab (bg2)
5848 //0x11f Protection:Backstab (how, iwd2)
5849 //3 different games, 3 different methods of flagging this
5850 int fx_no_backstab_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5852 if (0) printf( "fx_no_backstab_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5854 STAT_SET( IE_DISABLEBACKSTAB
, fx
->Parameter1
);
5856 EXTSTATE_SET(EXTSTATE_NO_BACKSTAB
);
5858 target
->SetSpellState(SS_NOBACKSTAB
);
5861 //0x125 OffscreenAIModifier
5862 int fx_offscreenai_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5864 if (0) printf( "fx_offscreenai_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5865 STAT_SET( IE_ENABLEOFFSCREENAI
, fx
->Parameter1
);
5869 //0x126 ExistanceDelayModifier
5870 int fx_existance_delay_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5872 if (0) printf( "fx_existance_delay_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5873 STAT_SET( IE_EXISTANCEDELAY
, fx
->Parameter1
);
5876 //0x127 DisableChunk
5877 int fx_disable_chunk_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5879 if (0) printf( "fx_disable_chunk_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5880 STAT_SET( IE_DISABLECHUNKING
, fx
->Parameter1
);
5883 //0x128 Protection:Animation
5884 int fx_protection_from_animation (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5886 if (0) printf( "fx_protection_from_animation (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5887 //remove vvc from actor if active
5888 target
->RemoveVVCell(fx
->Resource
, false);
5891 //0x129 Protection:Turn
5892 int fx_protection_from_turn (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5894 if (0) printf( "fx_non_interruptible_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5895 STAT_SET( IE_NOTURNABLE
, fx
->Parameter1
);
5899 //runs a predetermined script in cutscene mode
5900 int fx_cutscene2 (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
5905 if (0) printf( "fx_cutscene2 (%2d): Type: %d\n", fx
->Opcode
, fx
->Parameter2
);
5906 if (core
->InCutSceneMode()) return FX_NOT_APPLIED
;
5907 game
= core
->GetGame();
5908 if (!game
) return FX_NOT_APPLIED
;
5910 for (int i
= 0; i
< game
->GetPartySize(false); i
++) {
5911 Actor
* act
= game
->GetPC( i
, false );
5912 GAMLocationEntry
*gle
= game
->GetPlaneLocationEntry(i
);
5914 gle
->Pos
= act
->Pos
;
5915 memcpy(gle
->AreaResRef
, act
->Area
, 9);
5919 core
->SetCutSceneMode(true);
5921 //GemRB enhancement: allow a custom resource
5922 if (fx
->Parameter2
) {
5923 strnlwrcpy(resref
,fx
->Resource
, 8);
5925 strnlwrcpy(resref
,"cut250a",8);
5928 GameScript
* gs
= new GameScript( resref
, game
);
5929 gs
->EvaluateAllBlocks();
5931 //for safety reasons, i get this pointer again
5932 game
= core
->GetGame();
5934 game
->ClearCutsceneID();
5936 return FX_NOT_APPLIED
;
5938 //0x12b ChaosShieldModifier
5939 int fx_chaos_shield_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5941 if (0) printf( "fx_chaos_shield_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5942 STAT_MOD( IE_CHAOSSHIELD
);
5943 if (fx
->Parameter2
) {
5944 target
->AddPortraitIcon(PI_CSHIELD
); //162
5946 target
->AddPortraitIcon(PI_CSHIELD2
); //163
5951 int fx_npc_bump (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5953 if (0) printf( "fx_npc_bump (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5954 //unknown effect, but known stat position
5955 STAT_MOD( IE_NPCBUMP
);
5958 //0x12d CriticalHitModifier
5959 int fx_critical_hit_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5961 if (0) printf( "fx_critical_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
5962 STAT_MOD( IE_CRITICALHITBONUS
);
5965 // 0x12e CanUseAnyItem
5966 int fx_can_use_any_item_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5968 if (0) printf( "fx_can_use_any_item_modifier (%2d): Value: %d\n", fx
->Opcode
, fx
->Parameter2
);
5970 STAT_SET( IE_CANUSEANYITEM
, fx
->Parameter2
);
5974 // 0x12f AlwaysBackstab
5975 int fx_always_backstab_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
5977 if (0) printf( "fx_always_backstab_modifier (%2d): Value: %d\n", fx
->Opcode
, fx
->Parameter2
);
5979 STAT_SET( IE_ALWAYSBACKSTAB
, fx
->Parameter2
);
5983 // 0x130 MassRaiseDead
5984 int fx_mass_raise_dead (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
5986 if (0) printf( "fx_mass_raise_dead (%2d)\n", fx
->Opcode
);
5988 Game
*game
=core
->GetGame();
5990 int i
=game
->GetPartySize(false);
5992 Actor
*actor
=game
->GetPC(i
,false);
5995 return FX_NOT_APPLIED
;
5998 // 0x131 OffhandHitModifier
5999 int fx_left_to_hit_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6001 if (0) printf( "fx_left_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
6003 STAT_MOD( IE_HITBONUSLEFT
);
6007 // 0x132 RightHitModifier
6008 int fx_right_to_hit_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6010 if (0) printf( "fx_right_to_hit_modifier (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
6012 STAT_MOD( IE_HITBONUSRIGHT
);
6016 // 0x133 Reveal:Tracks
6017 int fx_reveal_tracks (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6019 if (0) printf( "fx_reveal_tracks (%2d): Distance: %d\n", fx
->Opcode
, fx
->Parameter1
);
6020 Map
*map
= target
->GetCurrentArea();
6021 if (!map
) return FX_APPLIED
;
6022 if (!fx
->Parameter2
) {
6024 //write tracks.2da entry
6025 if (map
->DisplayTrackString(target
)) {
6026 return FX_NOT_APPLIED
;
6029 GameControl
*gc
= core
->GetGameControl();
6031 //highlight all living creatures (not in party, but within range)
6032 gc
->SetTracker(target
, fx
->Parameter1
);
6037 // 0x134 Protection:Tracking
6038 int fx_protection_from_tracking (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6040 if (0) printf( "fx_protection_from_tracking (%2d): Mod: %d, Type: %d\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
);
6042 STAT_MOD( IE_NOTRACKING
); //highlight creature???
6045 // 0x135 ModifyLocalVariable
6046 int fx_modify_local_variable (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6048 //convert it to internal variable format
6049 if (!fx
->IsVariable
) {
6050 char *poi
= fx
->Resource
+8;
6051 memmove(poi
, fx
->Resource2
, 8);
6053 memmove(poi
, fx
->Resource3
, 8);
6055 memmove(poi
, fx
->Resource4
, 8);
6058 if (0) printf( "fx_modify_local_variable (%2d): %s, Mod: %d\n", fx
->Opcode
, fx
->Resource
, fx
->Parameter2
);
6059 if (fx
->Parameter2
) {
6061 //use resource memory area as variable name
6062 target
->locals
->Lookup(fx
->Resource
, var
);
6063 target
->locals
->SetAt(fx
->Resource
, var
+fx
->Parameter1
);
6065 target
->locals
->SetAt(fx
->Resource
, fx
->Parameter1
);
6067 return FX_NOT_APPLIED
;
6070 // 0x136 TimelessState
6071 int fx_timeless_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6073 if (0) printf( "fx_timeless_modifier (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter2
);
6074 STAT_SET(IE_DISABLETIMESTOP
, fx
->Parameter2
);
6078 //0x137 GenerateWish
6079 #define WISHCOUNT 25
6080 static int wishlevels
[WISHCOUNT
]={10,10,10,10,0,10,0,15,0,0,0,0,0,0,15,0,0,
6081 17,9,17,17,9,9,9,0};
6083 int fx_generate_wish (Scriptable
* Owner
, Actor
* target
, Effect
* fx
)
6087 if (0) printf( "fx_generate_wish (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter2
);
6088 int tmp
= core
->Roll(1,WISHCOUNT
,0);
6089 sprintf(spl
,"SPWISH%02d",tmp
);
6090 core
->ApplySpell(spl
, target
, Owner
, wishlevels
[tmp
-1]);
6091 return FX_NOT_APPLIED
;
6093 //0x138 //see fx_crash, this effect is not fully enabled in original bg2/tob
6094 int fx_immunity_sequester (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6096 if (0) printf( "fx_immunity_sequester (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter2
);
6097 //this effect is supposed to provide immunity against sequester (maze/etc?)
6098 STAT_SET(IE_NOSEQUESTER
, fx
->Parameter2
);
6102 //0x139 //HLA generic effect
6103 //0x13a StoneSkin2Modifier
6104 int fx_golem_stoneskin_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6106 if (0) printf( "fx_golem_stoneskin_modifier (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter1
);
6107 if (!fx
->Parameter1
) {
6108 return FX_NOT_APPLIED
;
6110 //dead actors lose this effect
6111 if (STATE_GET( STATE_DEAD
) ) {
6112 return FX_NOT_APPLIED
;
6115 STAT_SET(IE_STONESKINSGOLEM
, fx
->Parameter1
);
6116 SetGradient(target
, 14);
6120 // 0x13b AvatarRemovalModifier (also 0x104 iwd)
6121 int fx_avatar_removal_modifier (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6123 if (0) printf( "fx_avatar_removal_modifier (%2d): Mod: %d\n", fx
->Opcode
, fx
->Parameter2
);
6124 STAT_SET(IE_AVATARREMOVAL
, fx
->Parameter2
);
6127 // 0x13c MagicalRest (also 0x124 iwd)
6128 int fx_magical_rest (Scriptable
* /*Owner*/, Actor
* target
, Effect
* fx
)
6130 if (0) printf( "fx_magical_rest (%2d)\n", fx
->Opcode
);
6131 //instant, full rest
6133 target
->fxqueue
.RemoveAllEffectsWithParam(fx_display_portrait_icon_ref
, PI_FATIGUE
);
6134 return FX_NOT_APPLIED
;
6137 // 0x13d ImprovedHaste (See 0x10 Haste)
6139 int fx_unknown (Scriptable
* /*Owner*/, Actor
* /*target*/, Effect
* fx
)
6141 printf( "fx_unknown (%2d): P1: %d P2: %d ResRef: %s\n", fx
->Opcode
, fx
->Parameter1
, fx
->Parameter2
, fx
->Resource
);
6142 return FX_NOT_APPLIED
;
6145 #include "plugindef.h"
6147 GEMRB_PLUGIN(0x1AAA040A, "Effect opcodes for core games")
6148 PLUGIN_INITIALIZER(RegisterCoreOpcodes
)
6149 PLUGIN_CLEANUP(Cleanup
)