Sort include order.
[gemrb.git] / gemrb / plugins / PSTOpcodes / PSTOpcodes.cpp
blob00af9f02a408478ecc55015b95b9e0655b67b0c8
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 "strrefs.h"
22 #include "win32def.h"
24 #include "Actor.h"
25 #include "EffectQueue.h"
26 #include "Game.h"
27 #include "GameData.h"
28 #include "Interface.h"
29 #include "TileMap.h"
30 #include "Video.h" //for tints
32 int fx_retreat_from (Scriptable* Owner, Actor* target, Effect* fx);//6e
33 int fx_set_status (Scriptable* Owner, Actor* target, Effect* fx);//ba
34 int fx_play_bam_blended (Scriptable* Owner, Actor* target, Effect* fx);//bb
35 int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx);//bc
36 int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx);//c0
37 //int fx_shake_screen (Scriptable* Owner, Actor* target, Effect* fx);//c1 already implemented
38 int fx_flash_screen (Scriptable* Owner, Actor* target, Effect* fx);//c2
39 int fx_tint_screen (Scriptable* Owner, Actor* target, Effect* fx);//c3
40 int fx_special_effect (Scriptable* Owner, Actor* target, Effect* fx);//c4
41 //unknown 0xc5-c8
42 int fx_overlay (Scriptable* Owner, Actor* target, Effect* fx);//c9
43 //unknown 0xca
44 int fx_bless (Scriptable* Owner, Actor* target, Effect* fx);//82 (this is a modified effect)
45 int fx_curse (Scriptable* Owner, Actor* target, Effect* fx);//cb
46 int fx_prayer (Scriptable* Owner, Actor* target, Effect* fx);//cc
47 int fx_move_view (Scriptable* Owner, Actor* target, Effect* fx);//cd
48 int fx_embalm (Scriptable* Owner, Actor* target, Effect* fx);//ce
49 int fx_stop_all_action (Scriptable* Owner, Actor* target, Effect* fx);//cf
50 int fx_iron_fist (Scriptable* Owner, Actor* target, Effect* fx);//d0
51 int fx_hostile_image(Scriptable* Owner, Actor* target, Effect* fx);//d1
52 int fx_detect_evil (Scriptable* Owner, Actor* target, Effect* fx);//d2
53 int fx_jumble_curse (Scriptable* Owner, Actor* target, Effect* fx);//d3
54 //int fx_unknown (Scriptable* Owner, Actor* target, Effect* fx);//d4
56 // FIXME: Make this an ordered list, so we could use bsearch!
57 static EffectRef effectnames[] = {
58 { "RetreatFrom", fx_retreat_from, -1 },//6e
59 { "Bless", fx_bless, -1},//82
60 { "Curse", fx_curse, -1},//cb
61 { "DetectEvil", fx_detect_evil, -1}, //d2
62 { "Embalm", fx_embalm, -1}, //0xce
63 { "FlashScreen", fx_flash_screen, -1}, //c2
64 { "HostileImage", fx_hostile_image, -1},//d1
65 { "IronFist", fx_iron_fist, -1}, //d0
66 { "JumbleCurse", fx_jumble_curse, -1}, //d3
67 { "MoveView", fx_move_view, -1},//cd
68 { "Overlay", fx_overlay, -1}, //c9
69 { "PlayBAM1", fx_play_bam_blended, -1}, //bb
70 { "PlayBAM2", fx_play_bam_not_blended, -1},//bc
71 { "PlayBAM3", fx_play_bam_not_blended, -1}, //bd
72 { "PlayBAM4", fx_play_bam_not_blended, -1}, //be
73 { "PlayBAM5", fx_play_bam_not_blended, -1}, //bf
74 { "Prayer", fx_prayer, -1},//cc
75 { "SetStatus", fx_set_status, -1}, //ba
76 { "SpecialEffect", fx_special_effect, -1},//c4
77 { "StopAllAction", fx_stop_all_action, -1}, //cf
78 { "TintScreen", fx_tint_screen, -1}, //c3
79 { "TransferHP", fx_transfer_hp, -1}, //c0
80 { NULL, NULL, 0 },
83 void RegisterTormentOpcodes()
85 core->RegisterOpcodes( sizeof( effectnames ) / sizeof( EffectRef ) - 1, effectnames );
88 //retreat_from (works only in PST) - forces target to run away/walk away from Owner
89 int fx_retreat_from (Scriptable* Owner, Actor* target, Effect* fx)
91 if (0) printf( "fx_retreat_from (%2d): Mod: %d, Type: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
93 if (!Owner) {
94 return FX_NOT_APPLIED;
97 //distance to run
98 if (!fx->Parameter3) {
99 fx->Parameter3=100;
102 if (fx->Parameter2==8) {
103 //backs away from owner
104 target->RunAwayFrom(Owner->Pos, fx->Parameter3, false);
105 //one shot
106 return FX_NOT_APPLIED;
109 //walks (7) or runs away (all others) from owner
110 target->RunAwayFrom(Owner->Pos, fx->Parameter3, true);
111 if (fx->Parameter2!=7) {
112 target->SetRunFlags(IF_RUNNING);
115 //has a duration
116 return FX_APPLIED;
119 //0xba fx_set_status
120 int fx_set_status (Scriptable* /*Owner*/, Actor* target, Effect* fx)
122 if (0) printf( "fx_set_status (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
123 if (fx->Parameter1) {
124 if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
125 BASE_STATE_SET (fx->Parameter2);
126 } else {
127 STATE_SET (fx->Parameter2);
129 } else {
130 if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
131 BASE_STATE_CURE (fx->Parameter2);
132 } else {
133 STATE_CURE (fx->Parameter2);
136 return FX_PERMANENT;
139 //bb fx_play_bam_bb (play multi-part blended sticky animation)
140 // 1 repeats
141 // 2 not sticky (override default)
142 int fx_play_bam_blended (Scriptable* Owner, Actor* target, Effect* fx)
144 bool playonce;
146 if (0) printf( "fx_play_bam_blended (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
147 //play once set to true
148 //check tearring.itm (0xbb effect)
149 ScriptedAnimation *sca = gamedata->GetScriptedAnimation(fx->Resource, true);
150 if (!sca)
151 return FX_NOT_APPLIED;
153 sca->SetBlend();
154 //the transparency is based on the original palette
155 if (fx->Parameter1) {
156 RGBModifier rgb;
158 rgb.speed=-1;
159 rgb.phase=0;
160 rgb.rgb.r=fx->Parameter1;
161 rgb.rgb.g=fx->Parameter1 >> 8;
162 rgb.rgb.b=fx->Parameter1 >> 16;
163 rgb.rgb.a=0;
164 rgb.type=RGBModifier::TINT;
165 sca->AlterPalette(rgb);
167 if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
168 playonce=true;
169 } else {
170 playonce=false;
172 if (fx->Parameter2&1) {
173 //four cycles, duration is in millisecond
174 sca->SetDefaultDuration(sca->GetSequenceDuration(4000));
175 } else {
176 if (playonce) {
177 sca->PlayOnce();
178 } else {
179 sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks);
182 if (fx->Parameter2&2) {
183 sca->XPos+=fx->PosX;
184 sca->YPos+=fx->PosY;
185 Owner->GetCurrentArea()->AddVVCell(sca);
186 } else {
187 ScriptedAnimation *twin = sca->DetachTwin();
188 if (twin) {
189 target->AddVVCell(twin);
191 target->AddVVCell(sca);
193 return FX_NOT_APPLIED;
196 //bc-bf play_bam_not_blended (play not blended single animation)
197 //random placement (if not sticky): 1
198 //sticky bit: 4096
199 //transparency instead of rgb tint: 0x100000, fade off is in dice size
200 //blend: 0x300000
201 //twin animation: 0x30000
202 //background animation: 0x10000
203 //foreground animation: 0x20000
204 int fx_play_bam_not_blended (Scriptable* Owner, Actor* target, Effect* fx)
206 bool playonce;
207 bool doublehint;
209 if (0) printf( "fx_play_bam_not_blended (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
210 //play once set to true
211 //check tearring.itm (0xbb effect)
212 if ((fx->Parameter2&0x30000)==0x30000) {
213 doublehint = true;
214 } else {
215 doublehint = false;
217 ScriptedAnimation *sca = gamedata->GetScriptedAnimation(fx->Resource, doublehint);
218 if (!sca)
219 return FX_NOT_APPLIED;
221 switch (fx->Parameter2&0x300000) {
222 case 0x300000:
223 sca->SetBlend(); //per pixel transparency
224 break;
225 case 0x200000: //this is an insane combo
226 sca->SetBlend(); //per pixel transparency
227 sca->SetFade((ieByte) fx->Parameter1, fx->DiceSides); //per surface transparency
228 break;
229 case 0x100000: //per surface transparency
230 sca->SetFade((ieByte) fx->Parameter1, fx->DiceSides);
231 break;
232 default:
233 if (fx->Parameter1) {
234 RGBModifier rgb;
236 rgb.speed=-1;
237 rgb.phase=0;
238 rgb.rgb.r=fx->Parameter1;
239 rgb.rgb.g=fx->Parameter1 >> 8;
240 rgb.rgb.b=fx->Parameter1 >> 16;
241 rgb.rgb.a=fx->Parameter1 >> 24;
242 rgb.type=RGBModifier::TINT;
243 sca->AlterPalette(rgb);
246 if (fx->TimingMode==FX_DURATION_INSTANT_PERMANENT) {
247 playonce=true;
248 } else {
249 playonce=false;
251 switch (fx->Parameter2&0x30000) {
252 case 0x20000://foreground
253 sca->ZPos+=9999;
254 break;
255 case 0x30000: //both
256 sca->ZPos+=9999;
257 if (sca->twin) {
258 sca->twin->ZPos-=9999;
260 break;
261 default: //background
262 sca->ZPos-=9999;
263 break;
265 if (playonce) {
266 sca->PlayOnce();
267 } else {
268 sca->SetDefaultDuration(fx->Duration-core->GetGame()->Ticks);
270 ScriptedAnimation *twin = sca->DetachTwin();
271 if (fx->Parameter2&4096) {
272 if (twin) {
273 target->AddVVCell(twin);
275 target->AddVVCell(sca);
276 } else {
277 //the random placement works only when it is not sticky
278 int x = 0;
279 int y = 0;
280 if (fx->Parameter2&1) {
281 ieWord tmp =(ieWord) rand();
282 x = tmp&31;
283 y = (tmp>>5)&31;
286 sca->XPos+=fx->PosX-x;
287 sca->YPos+=fx->PosY+sca->ZPos-y;
288 if (twin) {
289 twin->XPos+=fx->PosX-x;
290 twin->YPos+=fx->PosY+twin->ZPos-y;
291 Owner->GetCurrentArea()->AddVVCell(twin);
293 Owner->GetCurrentArea()->AddVVCell(sca);
295 return FX_NOT_APPLIED;
298 //0xc0 fx_transfer_hp
299 int fx_transfer_hp (Scriptable* Owner, Actor* target, Effect* fx)
301 if (0) printf( "fx_transfer_hp (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
302 if (Owner->Type!=ST_ACTOR) {
303 return FX_NOT_APPLIED;
306 Actor *owner = (Actor *) Owner;
308 if (owner==target) {
309 return FX_NOT_APPLIED;
312 Actor *receiver;
313 Actor *donor;
314 int a,b;
316 switch(fx->Parameter2) {
317 case 3:
318 case 0: receiver = target; donor = owner; break;
319 case 4:
320 case 1: receiver = owner; donor = target; break;
321 case 2:
322 a = owner->GetBase(IE_HITPOINTS);
323 b = target->GetBase(IE_HITPOINTS);
324 owner->SetBase(IE_HITPOINTS, a);
325 target->SetBase(IE_HITPOINTS, b);
326 //fallthrough
327 default:
328 return FX_NOT_APPLIED;
330 int damage = donor->Damage(fx->Parameter1, fx->Parameter2, owner);
331 receiver->SetBase( IE_HITPOINTS, BASE_GET( IE_HITPOINTS ) + ( damage ) );
332 return FX_NOT_APPLIED;
335 //0xc1 fx_shake_screen this is already implemented in BG2
337 //0xc2 fx_flash_screen
338 int fx_flash_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
340 if (0) printf( "fx_flash_screen (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
341 core->GetVideoDriver()->SetFadeColor(((char *) &fx->Parameter1)[0],((char *) &fx->Parameter1)[1],((char *) &fx->Parameter1)[2]);
342 core->timer->SetFadeFromColor(1);
343 core->timer->SetFadeToColor(1);
344 return FX_NOT_APPLIED;
347 //0xc3 fx_tint_screen
348 int fx_tint_screen (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
350 if (0) printf( "fx_tint_screen (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
351 core->timer->SetFadeFromColor(10);
352 core->timer->SetFadeToColor(10);
353 return FX_NOT_APPLIED;
356 //0xc4 fx_special_effect
357 int fx_special_effect (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
359 if (0) printf( "fx_special_effect (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
361 return FX_NOT_APPLIED;
363 //0xc5-c8 fx_unknown
364 //0xc9 fx_overlay
365 int fx_overlay (Scriptable* /*Owner*/, Actor* target, Effect* fx)
367 if (0) printf( "fx_overlay (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
368 target->AddAnimation(fx->Resource,-1,0,true);
369 //special effects based on fx_param2
370 return FX_NOT_APPLIED;
372 //0xca fx_unknown
374 //0x82 fx_bless
375 //static EffectRef fx_glow_ref ={"Color:PulseRGBGlobal",NULL,-1};
376 //pst bless effect spawns a color glow automatically
377 //but i would rather use the IWD2 method
378 int fx_bless (Scriptable* /*Owner*/, Actor* target, Effect* fx)
380 if (0) printf( "fx_curse (%2d): Par1: %d\n", fx->Opcode, fx->Parameter1 );
381 //this bit is the same as the invisibility bit in other games
382 //it should be considered what if we replace the pst invis bit
383 //with this one (losing binary compatibility, gaining easier
384 //invis checks at core level)
385 if (STATE_GET (STATE_BLESS) ) //curse is non-cumulative
386 return FX_NOT_APPLIED;
388 target->SetColorMod(255, RGBModifier::ADD, 0x18, 0xc8, 0xc8, 0xc8);
390 STATE_SET( STATE_BLESS );
391 STAT_SUB( IE_TOHIT, fx->Parameter1);
392 STAT_SUB( IE_SAVEVSDEATH, fx->Parameter1);
393 STAT_SUB( IE_SAVEVSWANDS, fx->Parameter1);
394 STAT_SUB( IE_SAVEVSPOLY, fx->Parameter1);
395 STAT_SUB( IE_SAVEVSBREATH, fx->Parameter1);
396 STAT_SUB( IE_SAVEVSSPELL, fx->Parameter1);
397 return FX_APPLIED;
400 //0xcb fx_curse
401 int fx_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
403 if (0) printf( "fx_curse (%2d): Par1: %d\n", fx->Opcode, fx->Parameter1 );
404 //this bit is the same as the invisibility bit in other games
405 //it should be considered what if we replace the pst invis bit
406 //with this one (losing binary compatibility, gaining easier
407 //invis checks at core level)
408 if (STATE_GET (STATE_PST_CURSE) ) //curse is non cumulative
409 return FX_NOT_APPLIED;
410 STATE_SET( STATE_PST_CURSE );
411 STAT_SUB( IE_TOHIT, fx->Parameter1);
412 STAT_SUB( IE_SAVEVSDEATH, fx->Parameter1);
413 STAT_SUB( IE_SAVEVSWANDS, fx->Parameter1);
414 STAT_SUB( IE_SAVEVSPOLY, fx->Parameter1);
415 STAT_SUB( IE_SAVEVSBREATH, fx->Parameter1);
416 STAT_SUB( IE_SAVEVSSPELL, fx->Parameter1);
417 return FX_APPLIED;
420 //0xcc fx_prayer
421 static EffectRef fx_curse_ref={"Curse",NULL,-1};
422 static EffectRef fx_bless_ref={"Bless",NULL,-1};
424 int fx_prayer (Scriptable* Owner, Actor* target, Effect* fx)
426 if (0) printf( "fx_prayer (%2d): Par1: %d\n", fx->Opcode, fx->Parameter1 );
427 int ea = target->GetStat(IE_EA);
428 int type;
429 if (ea>EA_EVILCUTOFF) type = 1;
430 else if (ea<EA_GOODCUTOFF) type = 0;
431 else return FX_NOT_APPLIED; //what happens if the target goes neutral during the effect? if the effect remains, make this FX_APPLIED
433 Map *map = target->GetCurrentArea();
434 int i = map->GetActorCount(true);
435 Effect *newfx = EffectQueue::CreateEffect(type?fx_curse_ref:fx_bless_ref, fx->Parameter1, fx->Parameter2, FX_DURATION_INSTANT_LIMITED);
436 memcpy(newfx, fx->Source,sizeof(ieResRef));
437 newfx->Duration=60;
438 while(i--) {
439 Actor *tar=map->GetActor(i,true);
440 ea = tar->GetStat(IE_EA);
441 if (ea>EA_EVILCUTOFF) type^=1;
442 else if (ea>EA_GOODCUTOFF) continue;
443 //this isn't a real perma effect, just applying the effect now
444 //no idea how this should work with spell resistances, etc
445 //lets assume it is never resisted
446 //the effect will be destructed by ApplyEffect (not anymore)
447 //the effect is copied to a new memory area
448 core->ApplyEffect(newfx, tar, Owner);
450 delete newfx;
451 return FX_APPLIED;
454 //0xcd fx_move_view
455 int fx_move_view (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
457 if (0) printf( "fx_move_view (%2d): Speed: %d\n", fx->Opcode, fx->Parameter1 );
458 Map *map = core->GetGame()->GetCurrentArea();
459 if (map) {
460 core->timer->SetMoveViewPort( fx->PosX, fx->PosY, fx->Parameter1, true);
462 return FX_NOT_APPLIED;
465 //0xce fx_embalm
466 int fx_embalm (Scriptable* /*Owner*/, Actor* target, Effect* fx)
468 if (0) printf( "fx_embalm (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
469 if (STATE_GET (STATE_EMBALM) ) //embalm is non cumulative
470 return FX_NOT_APPLIED;
471 STATE_SET( STATE_EMBALM );
472 if (!fx->Parameter1) {
473 if (fx->Parameter2) {
474 fx->Parameter1=fx->CasterLevel*2;
475 } else {
476 fx->Parameter1=core->Roll(1,6,1);
478 BASE_ADD( IE_HITPOINTS, fx->Parameter1 );
480 STAT_ADD( IE_MAXHITPOINTS, fx->Parameter1);
481 if (fx->Parameter2) {
482 STAT_ADD( IE_ARMORCLASS,2 );
483 } else {
484 STAT_ADD( IE_ARMORCLASS,1 );
486 return FX_APPLIED;
488 //0xcf fx_stop_all_action
489 int fx_stop_all_action (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
491 if (0) printf( "fx_stop_all_action (%2d): Par2: %d\n", fx->Opcode, fx->Parameter2 );
492 if (fx->Parameter2) {
493 core->GetGame()->TimeStop(NULL, 0xffffffff);
494 } else {
495 core->GetGame()->TimeStop(NULL, 0);
497 return FX_NOT_APPLIED;
500 //0xd0 fx_iron_fist
501 //GemRB extension: lets you specify not hardcoded values
502 int fx_iron_fist (Scriptable* /*Owner*/, Actor* target, Effect* fx)
504 ieDword p1,p2;
506 if (0) printf( "fx_iron_fist (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
507 switch (fx->Parameter2)
509 case 0: p1 = 3; p2 = 6; break;
510 default:
511 p1 = ieWord (fx->Parameter1&0xffff);
512 p2 = ieWord (fx->Parameter1>>16);
514 STAT_ADD(IE_FISTHIT, p1);
515 STAT_ADD(IE_FISTDAMAGE, p2);
516 return FX_APPLIED;
519 //0xd1 fx_hostile_image
520 int fx_hostile_image (Scriptable* /*Owner*/, Actor* /*target*/, Effect* fx)
522 if (0) printf( "fx_hostile_image (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
523 return FX_NOT_APPLIED;
526 //0xd2 fx_detect_evil
527 static EffectRef fx_single_color_pulse_ref={"Color:BriefRGB",NULL,-1};
529 int fx_detect_evil (Scriptable* Owner, Actor* target, Effect* fx)
531 if (0) printf( "fx_detect_evil (%2d): Par1: %d Par2: %d\n", fx->Opcode, fx->Parameter1, fx->Parameter2 );
532 ieDword type = fx->Parameter2;
533 //default is alignment/evil/speed 30/range 10
534 if (!type) type = 0x08031e0a;
535 int speed = (type&0xff00)>>8;
536 if (!speed) speed=30;
537 if (!(core->GetGame()->GameTime%speed)) {
538 ieDword color = fx->Parameter1;
539 //default is magenta (rgba)
540 if (!color) color = 0xff00ff00;
541 Effect *newfx = EffectQueue::CreateEffect(fx_single_color_pulse_ref, color, speed<<16, FX_DURATION_INSTANT_PERMANENT_AFTER_BONUSES);
542 newfx->Target=FX_TARGET_PRESET;
543 EffectQueue *fxqueue = new EffectQueue();
544 fxqueue->SetOwner(Owner);
545 fxqueue->AddEffect(newfx);
546 delete newfx;
548 //don't detect self? if yes, then use NULL as last parameter
549 fxqueue->AffectAllInRange(target->GetCurrentArea(), target->Pos, (type&0xff000000)>>24, (type&0xff0000)>>16, (type&0xff)*10, target);
550 delete fxqueue;
552 return FX_APPLIED;
555 //0xd3 fx_jumble_curse
556 int fx_jumble_curse (Scriptable* /*Owner*/, Actor* target, Effect* fx)
558 if (0) printf( "fx_jumble_curse (%2d)\n", fx->Opcode );
560 if (STATE_GET( STATE_DEAD) ) {
561 return FX_NOT_APPLIED;
563 Game *game = core->GetGame();
564 //do a hiccup every 75th refresh
565 if (fx->Parameter3/75!=fx->Parameter4/75) {
566 //hiccups
567 //PST has this hardcoded deep in the engine
568 //gemrb lets you specify the strref in P#1
569 ieStrRef tmp = fx->Parameter1;
570 if (!tmp) tmp = 46633;
571 char *tmpstr = core->GetString(tmp, IE_STR_SPEECH|IE_STR_SOUND);
572 target->DisplayHeadText(tmpstr);
573 //tmpstr shouldn't be freed, it is taken care by Actor
574 target->GetHit();
576 fx->Parameter4=fx->Parameter3;
577 fx->Parameter3=game->GameTime;
578 STAT_SET( IE_DEADMAGIC, 1);
579 STAT_SET( IE_SPELLFAILUREMAGE, 100);
580 STAT_SET( IE_SPELLFAILUREPRIEST, 100);
581 STAT_SET( IE_SPELLFAILUREINNATE, 100);
582 return FX_APPLIED;
585 #include "plugindef.h"
587 GEMRB_PLUGIN(0x115A670, "Effect opcodes for the torment branch of the games")
588 PLUGIN_INITIALIZER(RegisterTormentOpcodes)
589 END_PLUGIN()