]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/d3xp/Target.cpp
hello world
[icculus/iodoom3.git] / neo / d3xp / Target.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28 /*
29
30 Invisible entities that affect other entities or the world when activated.
31
32 */
33
34 #include "../idlib/precompiled.h"
35 #pragma hdrstop
36
37 #include "Game_local.h"
38
39 /*
40 ===============================================================================
41
42 idTarget
43
44 ===============================================================================
45 */
46
47 CLASS_DECLARATION( idEntity, idTarget )
48 END_CLASS
49
50
51 /*
52 ===============================================================================
53
54 idTarget_Remove
55
56 ===============================================================================
57 */
58
59 CLASS_DECLARATION( idTarget, idTarget_Remove )
60         EVENT( EV_Activate, idTarget_Remove::Event_Activate )
61 END_CLASS
62
63 /*
64 ================
65 idTarget_Remove::Event_Activate
66 ================
67 */
68 void idTarget_Remove::Event_Activate( idEntity *activator ) {
69         int                     i;
70         idEntity        *ent;
71
72         for( i = 0; i < targets.Num(); i++ ) {
73                 ent = targets[ i ].GetEntity();
74                 if ( ent ) {
75                         ent->PostEventMS( &EV_Remove, 0 );
76                 }
77         }
78
79         // delete our self when done
80         PostEventMS( &EV_Remove, 0 );
81 }
82
83
84 /*
85 ===============================================================================
86
87 idTarget_Show
88
89 ===============================================================================
90 */
91
92 CLASS_DECLARATION( idTarget, idTarget_Show )
93         EVENT( EV_Activate, idTarget_Show::Event_Activate )
94 END_CLASS
95
96 /*
97 ================
98 idTarget_Show::Event_Activate
99 ================
100 */
101 void idTarget_Show::Event_Activate( idEntity *activator ) {
102         int                     i;
103         idEntity        *ent;
104
105         for( i = 0; i < targets.Num(); i++ ) {
106                 ent = targets[ i ].GetEntity();
107                 if ( ent ) {
108                         ent->Show();
109                 }
110         }
111
112         // delete our self when done
113         PostEventMS( &EV_Remove, 0 );
114 }
115
116
117 /*
118 ===============================================================================
119
120 idTarget_Damage
121
122 ===============================================================================
123 */
124
125 CLASS_DECLARATION( idTarget, idTarget_Damage )
126         EVENT( EV_Activate, idTarget_Damage::Event_Activate )
127 END_CLASS
128
129 /*
130 ================
131 idTarget_Damage::Event_Activate
132 ================
133 */
134 void idTarget_Damage::Event_Activate( idEntity *activator ) {
135         int                     i;
136         const char *damage;
137         idEntity *      ent;
138
139         damage = spawnArgs.GetString( "def_damage", "damage_generic" );
140         for( i = 0; i < targets.Num(); i++ ) {
141                 ent = targets[ i ].GetEntity();
142                 if ( ent ) {
143                         ent->Damage( this, this, vec3_origin, damage, 1.0f, INVALID_JOINT );
144                 }
145         }
146 }
147
148
149 /*
150 ===============================================================================
151
152 idTarget_SessionCommand
153
154 ===============================================================================
155 */
156
157 CLASS_DECLARATION( idTarget, idTarget_SessionCommand )
158         EVENT( EV_Activate, idTarget_SessionCommand::Event_Activate )
159 END_CLASS
160
161 /*
162 ================
163 idTarget_SessionCommand::Event_Activate
164 ================
165 */
166 void idTarget_SessionCommand::Event_Activate( idEntity *activator ) {
167         gameLocal.sessionCommand = spawnArgs.GetString( "command" );
168 }
169
170
171 /*
172 ===============================================================================
173
174 idTarget_EndLevel
175
176 Just a modified form of idTarget_SessionCommand
177 ===============================================================================
178 */
179
180 CLASS_DECLARATION( idTarget, idTarget_EndLevel )
181         EVENT( EV_Activate,             idTarget_EndLevel::Event_Activate )
182 END_CLASS
183
184 /*
185 ================
186 idTarget_EndLevel::Event_Activate
187 ================
188 */
189 void idTarget_EndLevel::Event_Activate( idEntity *activator ) {
190         idStr nextMap;
191
192 #ifdef ID_DEMO_BUILD
193         if ( spawnArgs.GetBool( "endOfGame" ) ) {
194                 cvarSystem->SetCVarBool( "g_nightmare", true );
195                 gameLocal.sessionCommand = "endofDemo";
196                 return;
197         }
198 #else
199         if ( spawnArgs.GetBool( "endOfGame" ) ) {
200                 cvarSystem->SetCVarBool( "g_nightmare", true );
201                 gameLocal.sessionCommand = "disconnect";
202                 return;
203         }
204 #endif
205         if ( !spawnArgs.GetString( "nextMap", "", nextMap ) ) {
206                 gameLocal.Printf( "idTarget_SessionCommand::Event_Activate: no nextMap key\n" );
207                 return;
208         }
209
210         if ( spawnArgs.GetInt( "devmap", "0" ) ) {
211                 gameLocal.sessionCommand = "devmap ";   // only for special demos
212         } else {
213                 gameLocal.sessionCommand = "map ";
214         }
215
216         gameLocal.sessionCommand += nextMap;
217 }
218
219
220 /*
221 ===============================================================================
222
223 idTarget_WaitForButton
224
225 ===============================================================================
226 */
227
228 CLASS_DECLARATION( idTarget, idTarget_WaitForButton )
229         EVENT( EV_Activate, idTarget_WaitForButton::Event_Activate )
230 END_CLASS
231
232 /*
233 ================
234 idTarget_WaitForButton::Event_Activate
235 ================
236 */
237 void idTarget_WaitForButton::Event_Activate( idEntity *activator ) {
238         if ( thinkFlags & TH_THINK ) {
239                 BecomeInactive( TH_THINK );
240         } else {
241                 // always allow during cinematics
242                 cinematic = true;
243                 BecomeActive( TH_THINK );
244         }
245 }
246
247 /*
248 ================
249 idTarget_WaitForButton::Think
250 ================
251 */
252 void idTarget_WaitForButton::Think( void ) {
253         idPlayer *player;
254
255         if ( thinkFlags & TH_THINK ) {
256                 player = gameLocal.GetLocalPlayer();
257                 if ( player && ( !player->oldButtons & BUTTON_ATTACK ) && ( player->usercmd.buttons & BUTTON_ATTACK ) ) {
258                         player->usercmd.buttons &= ~BUTTON_ATTACK;
259                         BecomeInactive( TH_THINK );
260                         ActivateTargets( player );
261                 }
262         } else {
263                 BecomeInactive( TH_ALL );
264         }
265 }
266
267
268 /*
269 ===============================================================================
270
271 idTarget_SetGlobalShaderParm
272
273 ===============================================================================
274 */
275
276 CLASS_DECLARATION( idTarget, idTarget_SetGlobalShaderTime )
277 EVENT( EV_Activate,     idTarget_SetGlobalShaderTime::Event_Activate )
278 END_CLASS
279
280 /*
281 ================
282 idTarget_SetGlobalShaderTime::Event_Activate
283 ================
284 */
285 void idTarget_SetGlobalShaderTime::Event_Activate( idEntity *activator ) {
286         int parm = spawnArgs.GetInt( "globalParm" );
287         float time = -MS2SEC( gameLocal.time );
288         if ( parm >= 0 && parm < MAX_GLOBAL_SHADER_PARMS ) {
289                 gameLocal.globalShaderParms[parm] = time;
290         }
291 }
292
293 /*
294 ===============================================================================
295
296 idTarget_SetShaderParm
297
298 ===============================================================================
299 */
300
301 CLASS_DECLARATION( idTarget, idTarget_SetShaderParm )
302         EVENT( EV_Activate,     idTarget_SetShaderParm::Event_Activate )
303 END_CLASS
304
305 /*
306 ================
307 idTarget_SetShaderParm::Event_Activate
308 ================
309 */
310 void idTarget_SetShaderParm::Event_Activate( idEntity *activator ) {
311         int                     i;
312         idEntity *      ent;
313         float           value;
314         idVec3          color;
315         int                     parmnum;
316
317         // set the color on the targets
318         if ( spawnArgs.GetVector( "_color", "1 1 1", color ) ) {
319                 for( i = 0; i < targets.Num(); i++ ) {
320                         ent = targets[ i ].GetEntity();
321                         if ( ent ) {
322                                 ent->SetColor( color[ 0 ], color[ 1 ], color[ 2 ] );
323                         }
324                 }
325         }
326
327         // set any shader parms on the targets
328         for( parmnum = 0; parmnum < MAX_ENTITY_SHADER_PARMS; parmnum++ ) {
329                 if ( spawnArgs.GetFloat( va( "shaderParm%d", parmnum ), "0", value ) ) {
330                         for( i = 0; i < targets.Num(); i++ ) {
331                                 ent = targets[ i ].GetEntity();
332                                 if ( ent ) {
333                                         ent->SetShaderParm( parmnum, value );
334                                 }
335                         }
336                         if (spawnArgs.GetBool("toggle") && (value == 0 || value == 1)) {
337                                 int val = value;
338                                 val ^= 1;
339                                 value = val;
340                                 spawnArgs.SetFloat(va("shaderParm%d", parmnum), value);
341                         }
342                 }
343         }
344 }
345
346
347 /*
348 ===============================================================================
349
350 idTarget_SetShaderTime
351
352 ===============================================================================
353 */
354
355 CLASS_DECLARATION( idTarget, idTarget_SetShaderTime )
356         EVENT( EV_Activate,     idTarget_SetShaderTime::Event_Activate )
357 END_CLASS
358
359 /*
360 ================
361 idTarget_SetShaderTime::Event_Activate
362 ================
363 */
364 void idTarget_SetShaderTime::Event_Activate( idEntity *activator ) {
365         int                     i;
366         idEntity *      ent;
367         float           time;
368
369         time = -MS2SEC( gameLocal.time );
370         for( i = 0; i < targets.Num(); i++ ) {
371                 ent = targets[ i ].GetEntity();
372                 if ( ent ) {
373                         ent->SetShaderParm( SHADERPARM_TIMEOFFSET, time );
374                         if ( ent->IsType( idLight::Type ) ) {
375                                 static_cast<idLight *>(ent)->SetLightParm( SHADERPARM_TIMEOFFSET, time );
376                         }
377                 }
378         }
379 }
380
381 /*
382 ===============================================================================
383
384 idTarget_FadeEntity
385
386 ===============================================================================
387 */
388
389 CLASS_DECLARATION( idTarget, idTarget_FadeEntity )
390         EVENT( EV_Activate,                             idTarget_FadeEntity::Event_Activate )
391 END_CLASS
392
393 /*
394 ================
395 idTarget_FadeEntity::idTarget_FadeEntity
396 ================
397 */
398 idTarget_FadeEntity::idTarget_FadeEntity( void ) {
399         fadeFrom.Zero();
400         fadeStart = 0;
401         fadeEnd = 0;
402 }
403
404 /*
405 ================
406 idTarget_FadeEntity::Save
407 ================
408 */
409 void idTarget_FadeEntity::Save( idSaveGame *savefile ) const {
410         savefile->WriteVec4( fadeFrom );
411         savefile->WriteInt( fadeStart );
412         savefile->WriteInt( fadeEnd );
413 }
414
415 /*
416 ================
417 idTarget_FadeEntity::Restore
418 ================
419 */
420 void idTarget_FadeEntity::Restore( idRestoreGame *savefile ) {
421         savefile->ReadVec4( fadeFrom );
422         savefile->ReadInt( fadeStart );
423         savefile->ReadInt( fadeEnd );
424 }
425
426 /*
427 ================
428 idTarget_FadeEntity::Event_Activate
429 ================
430 */
431 void idTarget_FadeEntity::Event_Activate( idEntity *activator ) {
432         idEntity *ent;
433         int i;
434
435         if ( !targets.Num() ) {
436                 return;
437         }
438
439         // always allow during cinematics
440         cinematic = true;
441         BecomeActive( TH_THINK );
442
443         ent = this;
444         for( i = 0; i < targets.Num(); i++ ) {
445                 ent = targets[ i ].GetEntity();
446                 if ( ent ) {
447                         ent->GetColor( fadeFrom );
448                         break;
449                 }
450         }
451
452         fadeStart = gameLocal.time;
453         fadeEnd = gameLocal.time + SEC2MS( spawnArgs.GetFloat( "fadetime" ) );
454 }
455
456 /*
457 ================
458 idTarget_FadeEntity::Think
459 ================
460 */
461 void idTarget_FadeEntity::Think( void ) {
462         int                     i;
463         idEntity        *ent;
464         idVec4          color;
465         idVec4          fadeTo;
466         float           frac;
467
468         if ( thinkFlags & TH_THINK ) {
469                 GetColor( fadeTo );
470                 if ( gameLocal.time >= fadeEnd ) {
471                         color = fadeTo;
472                         BecomeInactive( TH_THINK );
473                 } else {
474                         frac = ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart );
475                         color.Lerp( fadeFrom, fadeTo, frac );
476                 }
477
478                 // set the color on the targets
479                 for( i = 0; i < targets.Num(); i++ ) {
480                         ent = targets[ i ].GetEntity();
481                         if ( ent ) {
482                                 ent->SetColor( color );
483                         }
484                 }
485         } else {
486                 BecomeInactive( TH_ALL );
487         }
488 }
489
490 /*
491 ===============================================================================
492
493 idTarget_LightFadeIn
494
495 ===============================================================================
496 */
497
498 CLASS_DECLARATION( idTarget, idTarget_LightFadeIn )
499         EVENT( EV_Activate,                             idTarget_LightFadeIn::Event_Activate )
500 END_CLASS
501
502 /*
503 ================
504 idTarget_LightFadeIn::Event_Activate
505 ================
506 */
507 void idTarget_LightFadeIn::Event_Activate( idEntity *activator ) {
508         idEntity *ent;
509         idLight *light;
510         int i;
511         float time;
512
513         if ( !targets.Num() ) {
514                 return;
515         }
516
517         time = spawnArgs.GetFloat( "fadetime" );
518         ent = this;
519         for( i = 0; i < targets.Num(); i++ ) {
520                 ent = targets[ i ].GetEntity();
521                 if ( !ent ) {
522                         continue;
523                 }
524                 if ( ent->IsType( idLight::Type ) ) {
525                         light = static_cast<idLight *>( ent );
526                         light->FadeIn( time );
527                 } else {
528                         gameLocal.Printf( "'%s' targets non-light '%s'", name.c_str(), ent->GetName() );
529                 }
530         }
531 }
532
533 /*
534 ===============================================================================
535
536 idTarget_LightFadeOut
537
538 ===============================================================================
539 */
540
541 CLASS_DECLARATION( idTarget, idTarget_LightFadeOut )
542         EVENT( EV_Activate,                             idTarget_LightFadeOut::Event_Activate )
543 END_CLASS
544
545 /*
546 ================
547 idTarget_LightFadeOut::Event_Activate
548 ================
549 */
550 void idTarget_LightFadeOut::Event_Activate( idEntity *activator ) {
551         idEntity *ent;
552         idLight *light;
553         int i;
554         float time;
555
556         if ( !targets.Num() ) {
557                 return;
558         }
559
560         time = spawnArgs.GetFloat( "fadetime" );
561         ent = this;
562         for( i = 0; i < targets.Num(); i++ ) {
563                 ent = targets[ i ].GetEntity();
564                 if ( !ent ) {
565                         continue;
566                 }
567                 if ( ent->IsType( idLight::Type ) ) {
568                         light = static_cast<idLight *>( ent );
569                         light->FadeOut( time );
570                 } else {
571                         gameLocal.Printf( "'%s' targets non-light '%s'", name.c_str(), ent->GetName() );
572                 }
573         }
574 }
575
576 /*
577 ===============================================================================
578
579 idTarget_Give
580
581 ===============================================================================
582 */
583
584 CLASS_DECLARATION( idTarget, idTarget_Give )
585         EVENT( EV_Activate,                             idTarget_Give::Event_Activate )
586 END_CLASS
587
588 /*
589 ================
590 idTarget_Give::Spawn
591 ================
592 */
593 void idTarget_Give::Spawn( void ) {
594         if ( spawnArgs.GetBool( "onSpawn" ) ) {
595                 PostEventMS( &EV_Activate, 50 );
596         }
597 }
598
599 /*
600 ================
601 idTarget_Give::Event_Activate
602 ================
603 */
604 void idTarget_Give::Event_Activate( idEntity *activator ) {
605         
606         if ( spawnArgs.GetBool( "development" ) && developer.GetInteger() == 0 ) {
607                 return;
608         }
609
610         static int giveNum = 0;
611         idPlayer *player = gameLocal.GetLocalPlayer();
612         if ( player ) {
613                 const idKeyValue *kv = spawnArgs.MatchPrefix( "item", NULL );
614                 while ( kv ) {
615                         const idDict *dict = gameLocal.FindEntityDefDict( kv->GetValue(), false );
616                         if ( dict ) {
617                                 idDict d2;
618                                 d2.Copy( *dict );
619                                 d2.Set( "name", va( "givenitem_%i", giveNum++ ) );
620                                 idEntity *ent = NULL;
621                                 if ( gameLocal.SpawnEntityDef( d2, &ent ) && ent && ent->IsType( idItem::Type ) ) {
622                                         idItem *item = static_cast<idItem*>(ent);
623                                         item->GiveToPlayer( gameLocal.GetLocalPlayer() );
624                                 }
625                         }
626                         kv = spawnArgs.MatchPrefix( "item", kv );
627                 }
628         }
629 }
630
631 /*
632 ===============================================================================
633
634 idTarget_GiveEmail
635
636 ===============================================================================
637 */
638
639 CLASS_DECLARATION( idTarget, idTarget_GiveEmail )
640 EVENT( EV_Activate,                             idTarget_GiveEmail::Event_Activate )
641 END_CLASS
642
643 /*
644 ================
645 idTarget_GiveEmail::Spawn
646 ================
647 */
648 void idTarget_GiveEmail::Spawn( void ) {
649 }
650
651 /*
652 ================
653 idTarget_GiveEmail::Event_Activate
654 ================
655 */
656 void idTarget_GiveEmail::Event_Activate( idEntity *activator ) {
657         idPlayer *player = gameLocal.GetLocalPlayer();
658         const idDeclPDA *pda = player->GetPDA();
659         if ( pda ) {
660                 player->GiveEmail( spawnArgs.GetString( "email" ) );
661         } else {
662                 player->ShowTip( spawnArgs.GetString( "text_infoTitle" ), spawnArgs.GetString( "text_PDANeeded" ), true );
663         }
664 }
665
666
667 /*
668 ===============================================================================
669
670 idTarget_SetModel
671
672 ===============================================================================
673 */
674
675 CLASS_DECLARATION( idTarget, idTarget_SetModel )
676         EVENT( EV_Activate,     idTarget_SetModel::Event_Activate )
677 END_CLASS
678
679 /*
680 ================
681 idTarget_SetModel::Spawn
682 ================
683 */
684 void idTarget_SetModel::Spawn( void ) {
685         const char *model;
686
687         model = spawnArgs.GetString( "newmodel" );
688         if ( declManager->FindType( DECL_MODELDEF, model, false ) == NULL ) {
689                 // precache the render model
690                 renderModelManager->FindModel( model );
691                 // precache .cm files only
692                 collisionModelManager->LoadModel( model, true );
693         }
694 }
695
696 /*
697 ================
698 idTarget_SetModel::Event_Activate
699 ================
700 */
701 void idTarget_SetModel::Event_Activate( idEntity *activator ) {
702         for( int i = 0; i < targets.Num(); i++ ) {
703                 idEntity *ent = targets[ i ].GetEntity();
704                 if ( ent ) {
705                         ent->SetModel( spawnArgs.GetString( "newmodel" ) );
706                 }
707         }
708 }
709
710
711 /*
712 ===============================================================================
713
714 idTarget_SetInfluence
715
716 ===============================================================================
717 */
718
719 const idEventDef EV_RestoreInfluence( "<RestoreInfluece>" );
720 const idEventDef EV_GatherEntities( "<GatherEntities>" );
721 const idEventDef EV_Flash( "<Flash>", "fd" );
722 const idEventDef EV_ClearFlash( "<ClearFlash>", "f" );
723
724 CLASS_DECLARATION( idTarget, idTarget_SetInfluence )
725         EVENT( EV_Activate,     idTarget_SetInfluence::Event_Activate )
726         EVENT( EV_RestoreInfluence,     idTarget_SetInfluence::Event_RestoreInfluence )
727         EVENT( EV_GatherEntities, idTarget_SetInfluence::Event_GatherEntities )
728         EVENT( EV_Flash, idTarget_SetInfluence::Event_Flash )
729         EVENT( EV_ClearFlash, idTarget_SetInfluence::Event_ClearFlash )
730 END_CLASS
731
732 /*
733 ================
734 idTarget_SetInfluence::idTarget_SetInfluence
735 ================
736 */
737 idTarget_SetInfluence::idTarget_SetInfluence( void ) {
738         flashIn = 0.0f;
739         flashOut = 0.0f;
740         delay = 0.0f;
741         switchToCamera = NULL;
742         soundFaded = false;
743         restoreOnTrigger = false;
744 }
745
746 /*
747 ================
748 idTarget_SetInfluence::Save
749 ================
750 */
751 void idTarget_SetInfluence::Save( idSaveGame *savefile ) const {
752         int i;
753
754         savefile->WriteInt( lightList.Num() );
755         for( i = 0; i < lightList.Num(); i++ ) {
756                 savefile->WriteInt( lightList[ i ] );
757         }
758
759         savefile->WriteInt( guiList.Num() );
760         for( i = 0; i < guiList.Num(); i++ ) {
761                 savefile->WriteInt( guiList[ i ] );
762         }
763
764         savefile->WriteInt( soundList.Num() );
765         for( i = 0; i < soundList.Num(); i++ ) {
766                 savefile->WriteInt( soundList[ i ] );
767         }
768
769         savefile->WriteInt( genericList.Num() );
770         for( i = 0; i < genericList.Num(); i++ ) {
771                 savefile->WriteInt( genericList[ i ] );
772         }
773
774         savefile->WriteFloat( flashIn );
775         savefile->WriteFloat( flashOut );
776
777         savefile->WriteFloat( delay );
778
779         savefile->WriteString( flashInSound );
780         savefile->WriteString( flashOutSound );
781
782         savefile->WriteObject( switchToCamera );
783
784         savefile->WriteFloat( fovSetting.GetStartTime() );
785         savefile->WriteFloat( fovSetting.GetDuration() );
786         savefile->WriteFloat( fovSetting.GetStartValue() );
787         savefile->WriteFloat( fovSetting.GetEndValue() );
788
789         savefile->WriteBool( soundFaded );
790         savefile->WriteBool( restoreOnTrigger );
791
792 #ifdef _D3XP
793         savefile->WriteInt( savedGuiList.Num() );
794         for( i = 0; i < savedGuiList.Num(); i++ ) {
795                 for(int j = 0; j < MAX_RENDERENTITY_GUI; j++) {
796                         savefile->WriteUserInterface(savedGuiList[i].gui[j], savedGuiList[i].gui[j] ? savedGuiList[i].gui[j]->IsUniqued() : false);
797                 }
798         }
799 #endif
800 }
801
802 /*
803 ================
804 idTarget_SetInfluence::Restore
805 ================
806 */
807 void idTarget_SetInfluence::Restore( idRestoreGame *savefile ) {
808         int i, num;
809         int itemNum;
810         float set;
811
812         savefile->ReadInt( num );
813         for( i = 0; i < num; i++ ) {
814                 savefile->ReadInt( itemNum );
815                 lightList.Append( itemNum );
816         }
817
818         savefile->ReadInt( num );
819         for( i = 0; i < num; i++ ) {
820                 savefile->ReadInt( itemNum );
821                 guiList.Append( itemNum );
822         }
823
824         savefile->ReadInt( num );
825         for( i = 0; i < num; i++ ) {
826                 savefile->ReadInt( itemNum );
827                 soundList.Append( itemNum );
828         }
829
830         savefile->ReadInt( num );
831         for ( i = 0; i < num; i++ ) {
832                 savefile->ReadInt( itemNum );
833                 genericList.Append( itemNum );
834         }
835
836         savefile->ReadFloat( flashIn );
837         savefile->ReadFloat( flashOut );
838
839         savefile->ReadFloat( delay );
840
841         savefile->ReadString( flashInSound );
842         savefile->ReadString( flashOutSound );
843
844         savefile->ReadObject( reinterpret_cast<idClass *&>( switchToCamera ) );
845
846         savefile->ReadFloat( set );
847         fovSetting.SetStartTime( set );
848         savefile->ReadFloat( set );
849         fovSetting.SetDuration( set );
850         savefile->ReadFloat( set );
851         fovSetting.SetStartValue( set );
852         savefile->ReadFloat( set );
853         fovSetting.SetEndValue( set );
854
855         savefile->ReadBool( soundFaded );
856         savefile->ReadBool( restoreOnTrigger );
857
858 #ifdef _D3XP
859         savefile->ReadInt( num );
860         for( i = 0; i < num; i++ ) {
861                 SavedGui_t temp;
862                 for(int j = 0; j < MAX_RENDERENTITY_GUI; j++) {
863                         savefile->ReadUserInterface(temp.gui[j]);
864                 }
865                 savedGuiList.Append( temp );
866         }
867 #endif
868 }
869
870 /*
871 ================
872 idTarget_SetInfluence::Spawn
873 ================
874 */
875 void idTarget_SetInfluence::Spawn() {
876         PostEventMS( &EV_GatherEntities, 0 );
877         flashIn = spawnArgs.GetFloat( "flashIn", "0" );
878         flashOut = spawnArgs.GetFloat( "flashOut", "0" );
879         flashInSound = spawnArgs.GetString( "snd_flashin" );
880         flashOutSound = spawnArgs.GetString( "snd_flashout" );
881         delay = spawnArgs.GetFloat( "delay" );
882         soundFaded = false;
883         restoreOnTrigger = false;
884
885         // always allow during cinematics
886         cinematic = true;
887 }
888
889 /*
890 ================
891 idTarget_SetInfluence::Event_Flash
892 ================
893 */
894 void idTarget_SetInfluence::Event_Flash( float flash, int out ) {
895         idPlayer *player = gameLocal.GetLocalPlayer();
896         player->playerView.Fade( idVec4( 1, 1, 1, 1 ), flash );
897         const idSoundShader *shader = NULL;
898         if ( !out && flashInSound.Length() ){
899                 shader = declManager->FindSound( flashInSound );
900                 player->StartSoundShader( shader, SND_CHANNEL_VOICE, 0, false, NULL );
901         } else if ( out && ( flashOutSound.Length() || flashInSound.Length() ) ) {
902                 shader = declManager->FindSound( flashOutSound.Length() ? flashOutSound : flashInSound );
903                 player->StartSoundShader( shader, SND_CHANNEL_VOICE, 0, false, NULL );
904         }
905         PostEventSec( &EV_ClearFlash, flash, flash );
906 }
907
908
909 /*
910 ================
911 idTarget_SetInfluence::Event_ClearFlash
912 ================
913 */
914 void idTarget_SetInfluence::Event_ClearFlash( float flash ) {
915         idPlayer *player = gameLocal.GetLocalPlayer();
916         player->playerView.Fade( vec4_zero , flash );           
917 }
918 /*
919 ================
920 idTarget_SetInfluence::Event_GatherEntities
921 ================
922 */
923 void idTarget_SetInfluence::Event_GatherEntities() {
924         int i, listedEntities;
925         idEntity *entityList[ MAX_GENTITIES ];
926
927         bool demonicOnly = spawnArgs.GetBool( "effect_demonic" );
928         bool lights = spawnArgs.GetBool( "effect_lights" );
929         bool sounds = spawnArgs.GetBool( "effect_sounds" );
930         bool guis = spawnArgs.GetBool( "effect_guis" );
931         bool models = spawnArgs.GetBool( "effect_models" );
932         bool vision = spawnArgs.GetBool( "effect_vision" );
933         bool targetsOnly = spawnArgs.GetBool( "targetsOnly" );
934
935         lightList.Clear();
936         guiList.Clear();
937         soundList.Clear();
938 #ifdef _D3XP
939         savedGuiList.Clear();
940 #endif
941
942         if ( spawnArgs.GetBool( "effect_all" ) ) {
943                 lights = sounds = guis = models = vision = true;
944         }
945
946         if ( targetsOnly ) {
947                 listedEntities = targets.Num();
948                 for ( i = 0; i < listedEntities; i++ ) {
949                         entityList[i] = targets[i].GetEntity();
950                 }
951         } else {
952                 float radius = spawnArgs.GetFloat( "radius" );
953                 listedEntities = gameLocal.EntitiesWithinRadius( GetPhysics()->GetOrigin(), radius, entityList, MAX_GENTITIES );
954         }
955
956         for( i = 0; i < listedEntities; i++ ) {
957                 idEntity *ent = entityList[ i ];
958                 if ( ent ) {
959                         if ( lights && ent->IsType( idLight::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) {
960                                 lightList.Append( ent->entityNumber );
961                                 continue;
962                         }
963                         if ( sounds && ent->IsType( idSound::Type ) && ent->spawnArgs.FindKey( "snd_demonic" ) ) {
964                                 soundList.Append( ent->entityNumber );
965                                 continue;
966                         }
967                         if ( guis && ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ 0 ] && ent->spawnArgs.FindKey( "gui_demonic" ) ) {
968                                 guiList.Append( ent->entityNumber );
969 #ifdef _D3XP
970                                 SavedGui_t temp;
971                                 savedGuiList.Append(temp);
972 #endif
973                                 continue;
974                         }
975                         if ( ent->IsType( idStaticEntity::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) {
976                                 genericList.Append( ent->entityNumber );
977                                 continue;
978                         }
979                 }
980         }
981         idStr temp;
982         temp = spawnArgs.GetString( "switchToView" );
983         switchToCamera = ( temp.Length() ) ? gameLocal.FindEntity( temp ) : NULL;
984
985 }
986
987 /*
988 ================
989 idTarget_SetInfluence::Event_Activate
990 ================
991 */
992 void idTarget_SetInfluence::Event_Activate( idEntity *activator ) {
993         int i, j;
994         idEntity *ent;
995         idLight *light;
996         idSound *sound;
997         idStaticEntity *generic;
998         const char *parm;
999         const char *skin;
1000         bool update;
1001         idVec3 color;
1002         idVec4 colorTo;
1003         idPlayer *player;
1004
1005         player = gameLocal.GetLocalPlayer();
1006
1007         if ( spawnArgs.GetBool( "triggerActivate" ) ) {
1008                 if ( restoreOnTrigger ) {
1009                         ProcessEvent( &EV_RestoreInfluence );
1010                         restoreOnTrigger = false;
1011                         return;
1012                 }
1013                 restoreOnTrigger = true;
1014         }
1015
1016         float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" );
1017
1018         if ( delay > 0.0f ) {
1019                 PostEventSec( &EV_Activate, delay, activator );
1020                 delay = 0.0f;
1021                 // start any sound fading now
1022                 if ( fadeTime ) {
1023                         gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime );
1024                         soundFaded = true;
1025                 }
1026                 return;
1027         } else if ( fadeTime && !soundFaded ) {
1028                 gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime );
1029                 soundFaded = true;
1030         }
1031
1032         if ( spawnArgs.GetBool( "triggerTargets" ) ) {
1033                 ActivateTargets( activator );
1034         }
1035
1036         if ( flashIn ) {
1037                 PostEventSec( &EV_Flash, 0.0f, flashIn, 0 );
1038         }
1039
1040         parm = spawnArgs.GetString( "snd_influence" );
1041         if ( parm && *parm ) {
1042                 PostEventSec( &EV_StartSoundShader, flashIn, parm, SND_CHANNEL_ANY );
1043         }
1044
1045         if ( switchToCamera ) {
1046                 switchToCamera->PostEventSec( &EV_Activate, flashIn + 0.05f, this );
1047         }
1048
1049         int fov = spawnArgs.GetInt( "fov" );
1050         if ( fov ) {
1051                 fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "fovTime" ) ), player->DefaultFov(), fov );
1052                 BecomeActive( TH_THINK );
1053         }
1054
1055         for ( i = 0; i < genericList.Num(); i++ ) {
1056                 ent = gameLocal.entities[genericList[i]];
1057                 if ( ent == NULL ) {
1058                         continue;
1059                 }
1060                 generic = static_cast<idStaticEntity*>( ent );
1061                 color = generic->spawnArgs.GetVector( "color_demonic" );
1062                 colorTo.Set( color.x, color.y, color.z, 1.0f );
1063                 generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1064         }
1065
1066         for ( i = 0; i < lightList.Num(); i++ ) {
1067                 ent = gameLocal.entities[lightList[i]];
1068                 if ( ent == NULL || !ent->IsType( idLight::Type ) ) {
1069                         continue;
1070                 }
1071                 light = static_cast<idLight *>(ent);
1072                 parm = light->spawnArgs.GetString( "mat_demonic" );
1073                 if ( parm && *parm ) {
1074                         light->SetShader( parm );
1075                 }
1076                 
1077                 color = light->spawnArgs.GetVector( "_color" );
1078                 color = light->spawnArgs.GetVector( "color_demonic", color.ToString() );
1079                 colorTo.Set( color.x, color.y, color.z, 1.0f );
1080                 light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1081         }
1082
1083         for ( i = 0; i < soundList.Num(); i++ ) {
1084                 ent = gameLocal.entities[soundList[i]];
1085                 if ( ent == NULL || !ent->IsType( idSound::Type ) ) {
1086                         continue;
1087                 }
1088                 sound = static_cast<idSound *>(ent);
1089                 parm = sound->spawnArgs.GetString( "snd_demonic" );
1090                 if ( parm && *parm ) {
1091                         if ( sound->spawnArgs.GetBool( "overlayDemonic" ) ) {
1092                                 sound->StartSound( "snd_demonic", SND_CHANNEL_DEMONIC, 0, false, NULL );
1093                         } else {
1094                                 sound->StopSound( SND_CHANNEL_ANY, false );
1095                                 sound->SetSound( parm );
1096                         }
1097                 }
1098         }
1099
1100         for ( i = 0; i < guiList.Num(); i++ ) {
1101                 ent = gameLocal.entities[guiList[i]];
1102                 if ( ent == NULL || ent->GetRenderEntity() == NULL ) {
1103                         continue;
1104                 }
1105                 update = false;
1106
1107                 for ( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
1108                         if ( ent->GetRenderEntity()->gui[ j ] && ent->spawnArgs.FindKey( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ) ) {
1109 #ifdef _D3XP
1110                                 //Backup the old one
1111                                 savedGuiList[i].gui[j] = ent->GetRenderEntity()->gui[ j ];
1112 #endif
1113                                 ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ), true );
1114                                 update = true;
1115                         }
1116                 }
1117
1118                 if ( update ) {
1119                         ent->UpdateVisuals();
1120                         ent->Present();
1121                 }
1122         }
1123
1124         player->SetInfluenceLevel( spawnArgs.GetInt( "influenceLevel" ) );
1125
1126         int snapAngle = spawnArgs.GetInt( "snapAngle" );
1127         if ( snapAngle ) {
1128                 idAngles ang( 0, snapAngle, 0 );
1129                 player->SetViewAngles( ang );
1130                 player->SetAngles( ang );
1131         }
1132
1133         if ( spawnArgs.GetBool( "effect_vision" ) ) {
1134                 parm = spawnArgs.GetString( "mtrVision" );
1135                 skin = spawnArgs.GetString( "skinVision" );
1136                 player->SetInfluenceView( parm, skin, spawnArgs.GetInt( "visionRadius" ), this ); 
1137         }
1138
1139         parm = spawnArgs.GetString( "mtrWorld" );
1140         if ( parm && *parm ) {
1141                 gameLocal.SetGlobalMaterial( declManager->FindMaterial( parm ) );
1142         }
1143
1144         if ( !restoreOnTrigger ) {
1145                 PostEventMS( &EV_RestoreInfluence, SEC2MS( spawnArgs.GetFloat( "time" ) ) );
1146         }
1147 }
1148
1149 /*
1150 ================
1151 idTarget_SetInfluence::Think
1152 ================
1153 */
1154 void idTarget_SetInfluence::Think( void ) {
1155         if ( thinkFlags & TH_THINK ) {
1156                 idPlayer *player = gameLocal.GetLocalPlayer();
1157                 player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) );
1158                 if ( fovSetting.IsDone( gameLocal.time ) ) {
1159                         if ( !spawnArgs.GetBool( "leaveFOV" ) ) {
1160                                 player->SetInfluenceFov( 0 );
1161                         }
1162                         BecomeInactive( TH_THINK );
1163                 }
1164         } else {
1165                 BecomeInactive( TH_ALL );
1166         }
1167 }
1168
1169
1170 /*
1171 ================
1172 idTarget_SetInfluence::Event_RestoreInfluence
1173 ================
1174 */
1175 void idTarget_SetInfluence::Event_RestoreInfluence() {
1176         int i, j;
1177         idEntity *ent;
1178         idLight *light;
1179         idSound *sound;
1180         idStaticEntity *generic;
1181         bool update;
1182         idVec3 color;
1183         idVec4 colorTo;
1184
1185         if ( flashOut ) {
1186                 PostEventSec( &EV_Flash, 0.0f, flashOut, 1 );
1187         }
1188
1189         if ( switchToCamera ) {
1190                 switchToCamera->PostEventMS( &EV_Activate, 0.0f, this );
1191         }
1192
1193         for ( i = 0; i < genericList.Num(); i++ ) {
1194                 ent = gameLocal.entities[genericList[i]];
1195                 if ( ent == NULL ) {
1196                         continue;
1197                 }
1198                 generic = static_cast<idStaticEntity*>( ent );
1199                 colorTo.Set( 1.0f, 1.0f, 1.0f, 1.0f );
1200                 generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1201         }
1202
1203         for ( i = 0; i < lightList.Num(); i++ ) {
1204                 ent = gameLocal.entities[lightList[i]];
1205                 if ( ent == NULL || !ent->IsType( idLight::Type ) ) {
1206                         continue;
1207                 }
1208                 light = static_cast<idLight *>(ent);
1209                 if ( !light->spawnArgs.GetBool( "leave_demonic_mat" ) ) {
1210                         const char *texture = light->spawnArgs.GetString( "texture", "lights/squarelight1" );
1211                         light->SetShader( texture );
1212                 }
1213                 color = light->spawnArgs.GetVector( "_color" );
1214                 colorTo.Set( color.x, color.y, color.z, 1.0f );
1215                 light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1216         }
1217
1218         for ( i = 0; i < soundList.Num(); i++ ) {
1219                 ent = gameLocal.entities[soundList[i]];
1220                 if ( ent == NULL || !ent->IsType( idSound::Type ) ) {
1221                         continue;
1222                 }
1223                 sound = static_cast<idSound *>(ent);
1224                 sound->StopSound( SND_CHANNEL_ANY, false );
1225                 sound->SetSound( sound->spawnArgs.GetString( "s_shader" ) );
1226         }
1227
1228         for ( i = 0; i < guiList.Num(); i++ ) {
1229                 ent = gameLocal.entities[guiList[i]];
1230                 if ( ent == NULL || GetRenderEntity() == NULL ) {
1231                         continue;
1232                 }
1233                 update = false;
1234                 for( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
1235                         if ( ent->GetRenderEntity()->gui[ j ] ) {
1236 #ifdef _D3XP
1237                                 ent->GetRenderEntity()->gui[ j ] = savedGuiList[i].gui[j];
1238 #else
1239                                 ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui" : va( "gui%d", j+1 ) ) );
1240 #endif
1241                                 update = true;
1242                         }
1243                 }
1244                 if ( update ) {
1245                         ent->UpdateVisuals();
1246                         ent->Present();
1247                 }
1248         }
1249
1250         idPlayer *player = gameLocal.GetLocalPlayer();
1251         player->SetInfluenceLevel( 0 );
1252         player->SetInfluenceView( NULL, NULL, 0.0f, NULL );
1253         player->SetInfluenceFov( 0 );
1254         gameLocal.SetGlobalMaterial( NULL );
1255         float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" );
1256         if ( fadeTime ) {
1257                 gameSoundWorld->FadeSoundClasses( 0, 0.0f, fadeTime / 2.0f );
1258         }
1259
1260 }
1261
1262 /*
1263 ===============================================================================
1264
1265 idTarget_SetKeyVal
1266
1267 ===============================================================================
1268 */
1269
1270 CLASS_DECLARATION( idTarget, idTarget_SetKeyVal )
1271         EVENT( EV_Activate,     idTarget_SetKeyVal::Event_Activate )
1272 END_CLASS
1273
1274 /*
1275 ================
1276 idTarget_SetKeyVal::Event_Activate
1277 ================
1278 */
1279 void idTarget_SetKeyVal::Event_Activate( idEntity *activator ) {
1280         int i;
1281         idStr key, val;
1282         idEntity *ent;
1283         const idKeyValue *kv;
1284         int n;
1285
1286         for( i = 0; i < targets.Num(); i++ ) {
1287                 ent = targets[ i ].GetEntity();
1288                 if ( ent ) {
1289                         kv = spawnArgs.MatchPrefix("keyval");
1290                         while ( kv ) {
1291                                 n = kv->GetValue().Find( ";" );
1292                                 if ( n > 0 ) {
1293                                         key = kv->GetValue().Left( n );
1294                                         val = kv->GetValue().Right( kv->GetValue().Length() - n - 1 );
1295                                         ent->spawnArgs.Set( key, val );
1296                                         for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
1297                                                 if ( ent->GetRenderEntity()->gui[ j ] ) {
1298                                                         if ( idStr::Icmpn( key, "gui_", 4 ) == 0 ) {
1299                                                                 ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val );
1300                                                                 ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time );
1301                                                         }
1302                                                 }
1303                                         }
1304                                 }
1305                                 kv = spawnArgs.MatchPrefix( "keyval", kv );
1306                         }
1307                         ent->UpdateChangeableSpawnArgs( NULL );
1308                         ent->UpdateVisuals();
1309                         ent->Present();
1310                 }
1311         }
1312 }
1313
1314 /*
1315 ===============================================================================
1316
1317 idTarget_SetFov
1318
1319 ===============================================================================
1320 */
1321
1322 CLASS_DECLARATION( idTarget, idTarget_SetFov )
1323         EVENT( EV_Activate,     idTarget_SetFov::Event_Activate )
1324 END_CLASS
1325
1326
1327 /*
1328 ================
1329 idTarget_SetFov::Save
1330 ================
1331 */
1332 void idTarget_SetFov::Save( idSaveGame *savefile ) const {
1333
1334         savefile->WriteFloat( fovSetting.GetStartTime() );
1335         savefile->WriteFloat( fovSetting.GetDuration() );
1336         savefile->WriteFloat( fovSetting.GetStartValue() );
1337         savefile->WriteFloat( fovSetting.GetEndValue() );
1338 }
1339
1340 /*
1341 ================
1342 idTarget_SetFov::Restore
1343 ================
1344 */
1345 void idTarget_SetFov::Restore( idRestoreGame *savefile ) {
1346         float setting;
1347
1348         savefile->ReadFloat( setting );
1349         fovSetting.SetStartTime( setting );
1350         savefile->ReadFloat( setting );
1351         fovSetting.SetDuration( setting );
1352         savefile->ReadFloat( setting );
1353         fovSetting.SetStartValue( setting );
1354         savefile->ReadFloat( setting );
1355         fovSetting.SetEndValue( setting );
1356
1357         fovSetting.GetCurrentValue( gameLocal.time );
1358 }
1359
1360 /*
1361 ================
1362 idTarget_SetFov::Event_Activate
1363 ================
1364 */
1365 void idTarget_SetFov::Event_Activate( idEntity *activator ) {
1366         // always allow during cinematics
1367         cinematic = true;
1368
1369         idPlayer *player = gameLocal.GetLocalPlayer();
1370         fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "time" ) ), player ? player->DefaultFov() : g_fov.GetFloat(), spawnArgs.GetFloat( "fov" ) );
1371         BecomeActive( TH_THINK );
1372 }
1373
1374 /*
1375 ================
1376 idTarget_SetFov::Think
1377 ================
1378 */
1379 void idTarget_SetFov::Think( void ) {
1380         if ( thinkFlags & TH_THINK ) {
1381                 idPlayer *player = gameLocal.GetLocalPlayer();
1382                 player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) );
1383                 if ( fovSetting.IsDone( gameLocal.time ) ) {
1384                         player->SetInfluenceFov( 0.0f );
1385                         BecomeInactive( TH_THINK );
1386                 }
1387         } else {
1388                 BecomeInactive( TH_ALL );
1389         }
1390 }
1391
1392
1393 /*
1394 ===============================================================================
1395
1396 idTarget_SetPrimaryObjective
1397
1398 ===============================================================================
1399 */
1400
1401 CLASS_DECLARATION( idTarget, idTarget_SetPrimaryObjective )
1402         EVENT( EV_Activate,     idTarget_SetPrimaryObjective::Event_Activate )
1403 END_CLASS
1404
1405 /*
1406 ================
1407 idTarget_SetPrimaryObjective::Event_Activate
1408 ================
1409 */
1410 void idTarget_SetPrimaryObjective::Event_Activate( idEntity *activator ) {
1411         idPlayer *player = gameLocal.GetLocalPlayer();
1412         if ( player && player->objectiveSystem ) {
1413                 player->objectiveSystem->SetStateString( "missionobjective", spawnArgs.GetString( "text", common->GetLanguageDict()->GetString( "#str_04253" ) ) );
1414         }
1415 }
1416
1417 /*
1418 ===============================================================================
1419
1420 idTarget_LockDoor
1421
1422 ===============================================================================
1423 */
1424
1425 CLASS_DECLARATION( idTarget, idTarget_LockDoor )
1426         EVENT( EV_Activate,     idTarget_LockDoor::Event_Activate )
1427 END_CLASS
1428
1429 /*
1430 ================
1431 idTarget_LockDoor::Event_Activate
1432 ================
1433 */
1434 void idTarget_LockDoor::Event_Activate( idEntity *activator ) {
1435         int i;
1436         idEntity *ent;
1437         int lock;
1438
1439         lock = spawnArgs.GetInt( "locked", "1" );
1440         for( i = 0; i < targets.Num(); i++ ) {
1441                 ent = targets[ i ].GetEntity();
1442                 if ( ent && ent->IsType( idDoor::Type ) ) {
1443                         if ( static_cast<idDoor *>( ent )->IsLocked() ) {
1444                                 static_cast<idDoor *>( ent )->Lock( 0 );
1445                         } else {
1446                                 static_cast<idDoor *>( ent )->Lock( lock );
1447                         }
1448                 }
1449         }
1450 }
1451
1452 /*
1453 ===============================================================================
1454
1455 idTarget_CallObjectFunction
1456
1457 ===============================================================================
1458 */
1459
1460 CLASS_DECLARATION( idTarget, idTarget_CallObjectFunction )
1461         EVENT( EV_Activate,     idTarget_CallObjectFunction::Event_Activate )
1462 END_CLASS
1463
1464 /*
1465 ================
1466 idTarget_CallObjectFunction::Event_Activate
1467 ================
1468 */
1469 void idTarget_CallObjectFunction::Event_Activate( idEntity *activator ) {
1470         int                                     i;
1471         idEntity                        *ent;
1472         const function_t        *func;
1473         const char                      *funcName;
1474         idThread                        *thread;
1475
1476         funcName = spawnArgs.GetString( "call" );
1477         for( i = 0; i < targets.Num(); i++ ) {
1478                 ent = targets[ i ].GetEntity();
1479                 if ( ent && ent->scriptObject.HasObject() ) {
1480                         func = ent->scriptObject.GetFunction( funcName );
1481                         if ( !func ) {
1482                                 gameLocal.Error( "Function '%s' not found on entity '%s' for function call from '%s'", funcName, ent->name.c_str(), name.c_str() );
1483                         }
1484                         if ( func->type->NumParameters() != 1 ) {
1485                                 gameLocal.Error( "Function '%s' on entity '%s' has the wrong number of parameters for function call from '%s'", funcName, ent->name.c_str(), name.c_str() );
1486                         }
1487                         if ( !ent->scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) {
1488                                 gameLocal.Error( "Function '%s' on entity '%s' is the wrong type for function call from '%s'", funcName, ent->name.c_str(), name.c_str() );
1489                         }
1490                         // create a thread and call the function
1491                         thread = new idThread();
1492                         thread->CallFunction( ent, func, true );
1493                         thread->Start();
1494                 }
1495         }
1496 }
1497
1498
1499 /*
1500 ===============================================================================
1501
1502 idTarget_EnableLevelWeapons
1503
1504 ===============================================================================
1505 */
1506
1507 CLASS_DECLARATION( idTarget, idTarget_EnableLevelWeapons )
1508         EVENT( EV_Activate,     idTarget_EnableLevelWeapons::Event_Activate )
1509 END_CLASS
1510
1511 /*
1512 ================
1513 idTarget_EnableLevelWeapons::Event_Activate
1514 ================
1515 */
1516 void idTarget_EnableLevelWeapons::Event_Activate( idEntity *activator ) {
1517         int i;
1518         const char *weap;
1519
1520         gameLocal.world->spawnArgs.SetBool( "no_Weapons", spawnArgs.GetBool( "disable" ) );
1521
1522         if ( spawnArgs.GetBool( "disable" ) ) {
1523                 for( i = 0; i < gameLocal.numClients; i++ ) {
1524                         if ( gameLocal.entities[ i ] ) {
1525                                 gameLocal.entities[ i ]->ProcessEvent( &EV_Player_DisableWeapon );
1526                         }
1527                 }
1528         } else {
1529                 weap = spawnArgs.GetString( "weapon" );
1530                 for( i = 0; i < gameLocal.numClients; i++ ) {
1531                         if ( gameLocal.entities[ i ] ) {
1532                                 gameLocal.entities[ i ]->ProcessEvent( &EV_Player_EnableWeapon );
1533                                 if ( weap && weap[ 0 ] ) {
1534                                         gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, weap );
1535                                 }
1536                         }
1537                 }
1538         }
1539 }
1540
1541 /*
1542 ===============================================================================
1543
1544 idTarget_Tip
1545
1546 ===============================================================================
1547 */
1548
1549 const idEventDef EV_TipOff( "<TipOff>" );
1550 extern const idEventDef EV_GetPlayerPos( "<getplayerpos>" );
1551
1552 CLASS_DECLARATION( idTarget, idTarget_Tip )
1553         EVENT( EV_Activate,             idTarget_Tip::Event_Activate )
1554         EVENT( EV_TipOff,               idTarget_Tip::Event_TipOff )
1555         EVENT( EV_GetPlayerPos, idTarget_Tip::Event_GetPlayerPos )
1556 END_CLASS
1557
1558
1559 /*
1560 ================
1561 idTarget_Tip::idTarget_Tip
1562 ================
1563 */
1564 idTarget_Tip::idTarget_Tip( void ) {
1565         playerPos.Zero();
1566 }
1567
1568 /*
1569 ================
1570 idTarget_Tip::Spawn
1571 ================
1572 */
1573 void idTarget_Tip::Spawn( void ) {
1574 }
1575
1576 /*
1577 ================
1578 idTarget_Tip::Save
1579 ================
1580 */
1581 void idTarget_Tip::Save( idSaveGame *savefile ) const {
1582         savefile->WriteVec3( playerPos );
1583 }
1584
1585 /*
1586 ================
1587 idTarget_Tip::Restore
1588 ================
1589 */
1590 void idTarget_Tip::Restore( idRestoreGame *savefile ) {
1591         savefile->ReadVec3( playerPos );
1592 }
1593
1594 /*
1595 ================
1596 idTarget_Tip::Event_Activate
1597 ================
1598 */
1599 void idTarget_Tip::Event_GetPlayerPos( void ) {
1600         idPlayer *player = gameLocal.GetLocalPlayer();
1601         if ( player ) {
1602                 playerPos = player->GetPhysics()->GetOrigin();
1603                 PostEventMS( &EV_TipOff, 100 );
1604         }
1605 }
1606
1607 /*
1608 ================
1609 idTarget_Tip::Event_Activate
1610 ================
1611 */
1612 void idTarget_Tip::Event_Activate( idEntity *activator ) {
1613         idPlayer *player = gameLocal.GetLocalPlayer();
1614         if ( player ) {
1615                 if ( player->IsTipVisible() ) {
1616                         PostEventSec( &EV_Activate, 5.1f, activator );
1617                         return;
1618                 }
1619                 player->ShowTip( spawnArgs.GetString( "text_title" ), spawnArgs.GetString( "text_tip" ), false );
1620                 PostEventMS( &EV_GetPlayerPos, 2000 );
1621         }
1622 }
1623
1624 /*
1625 ================
1626 idTarget_Tip::Event_TipOff
1627 ================
1628 */
1629 void idTarget_Tip::Event_TipOff( void ) {
1630         idPlayer *player = gameLocal.GetLocalPlayer();
1631         if ( player ) {
1632                 idVec3 v = player->GetPhysics()->GetOrigin() - playerPos;
1633                 if ( v.Length() > 96.0f ) {
1634                         player->HideTip();
1635                 } else {
1636                         PostEventMS( &EV_TipOff, 100 );
1637                 }
1638         }
1639 }
1640
1641
1642 /*
1643 ===============================================================================
1644
1645 idTarget_GiveSecurity
1646
1647 ===============================================================================
1648 */
1649
1650 CLASS_DECLARATION( idTarget, idTarget_GiveSecurity )
1651 EVENT( EV_Activate,     idTarget_GiveSecurity::Event_Activate )
1652 END_CLASS
1653
1654 /*
1655 ================
1656 idTarget_GiveEmail::Event_Activate
1657 ================
1658 */
1659 void idTarget_GiveSecurity::Event_Activate( idEntity *activator ) {
1660         idPlayer *player = gameLocal.GetLocalPlayer();
1661         if ( player ) {
1662                 player->GiveSecurity( spawnArgs.GetString( "text_security" ) );
1663         }
1664 }
1665
1666
1667 /*
1668 ===============================================================================
1669
1670 idTarget_RemoveWeapons
1671
1672 ===============================================================================
1673 */
1674
1675 CLASS_DECLARATION( idTarget, idTarget_RemoveWeapons )
1676 EVENT( EV_Activate,     idTarget_RemoveWeapons::Event_Activate )
1677 END_CLASS
1678
1679 /*
1680 ================
1681 idTarget_RemoveWeapons::Event_Activate
1682 ================
1683 */
1684 void idTarget_RemoveWeapons::Event_Activate( idEntity *activator ) {
1685         for( int i = 0; i < gameLocal.numClients; i++ ) {
1686                 if ( gameLocal.entities[ i ] ) {
1687                         idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] );
1688                         const idKeyValue *kv = spawnArgs.MatchPrefix( "weapon", NULL );
1689                         while ( kv ) {
1690                                 player->RemoveWeapon( kv->GetValue() );
1691                                 kv = spawnArgs.MatchPrefix( "weapon", kv );
1692                         }
1693                         player->SelectWeapon( player->weapon_fists, true );
1694                 }
1695         }
1696 }
1697
1698
1699 /*
1700 ===============================================================================
1701
1702 idTarget_LevelTrigger
1703
1704 ===============================================================================
1705 */
1706
1707 CLASS_DECLARATION( idTarget, idTarget_LevelTrigger )
1708 EVENT( EV_Activate,     idTarget_LevelTrigger::Event_Activate )
1709 END_CLASS
1710
1711 /*
1712 ================
1713 idTarget_LevelTrigger::Event_Activate
1714 ================
1715 */
1716 void idTarget_LevelTrigger::Event_Activate( idEntity *activator ) {
1717         for( int i = 0; i < gameLocal.numClients; i++ ) {
1718                 if ( gameLocal.entities[ i ] ) {
1719                         idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] );
1720                         player->SetLevelTrigger( spawnArgs.GetString( "levelName" ), spawnArgs.GetString( "triggerName" ) );
1721                 }
1722         }
1723 }
1724
1725
1726 /*
1727 ===============================================================================
1728
1729 idTarget_EnableStamina
1730
1731 ===============================================================================
1732 */
1733
1734 CLASS_DECLARATION( idTarget, idTarget_EnableStamina )
1735 EVENT( EV_Activate,     idTarget_EnableStamina::Event_Activate )
1736 END_CLASS
1737
1738 /*
1739 ================
1740 idTarget_EnableStamina::Event_Activate
1741 ================
1742 */
1743 void idTarget_EnableStamina::Event_Activate( idEntity *activator ) {
1744         for( int i = 0; i < gameLocal.numClients; i++ ) {
1745                 if ( gameLocal.entities[ i ] ) {
1746                         idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] );
1747                         if ( spawnArgs.GetBool( "enable" ) ) {
1748                                 pm_stamina.SetFloat( player->spawnArgs.GetFloat( "pm_stamina" ) );
1749                         } else {
1750                                 pm_stamina.SetFloat( 0.0f );
1751                         }
1752                 }
1753         }
1754 }
1755
1756 /*
1757 ===============================================================================
1758
1759 idTarget_FadeSoundClass
1760
1761 ===============================================================================
1762 */
1763
1764 const idEventDef EV_RestoreVolume( "<RestoreVolume>" );
1765 CLASS_DECLARATION( idTarget, idTarget_FadeSoundClass )
1766 EVENT( EV_Activate,     idTarget_FadeSoundClass::Event_Activate )
1767 EVENT( EV_RestoreVolume, idTarget_FadeSoundClass::Event_RestoreVolume )
1768 END_CLASS
1769
1770 /*
1771 ================
1772 idTarget_FadeSoundClass::Event_Activate
1773 ================
1774 */
1775 void idTarget_FadeSoundClass::Event_Activate( idEntity *activator ) {
1776         float fadeTime = spawnArgs.GetFloat( "fadeTime" );
1777         float fadeDB = spawnArgs.GetFloat( "fadeDB" );
1778         float fadeDuration = spawnArgs.GetFloat( "fadeDuration" );
1779         int fadeClass = spawnArgs.GetInt( "fadeClass" );
1780         // start any sound fading now
1781         if ( fadeTime ) {
1782                 gameSoundWorld->FadeSoundClasses( fadeClass, spawnArgs.GetBool( "fadeIn" ) ? fadeDB : 0.0f - fadeDB, fadeTime );
1783                 if ( fadeDuration ) {
1784                         PostEventSec( &EV_RestoreVolume, fadeDuration );
1785                 }
1786         }
1787 }
1788
1789 /*
1790 ================
1791 idTarget_FadeSoundClass::Event_RestoreVolume
1792 ================
1793 */
1794 void idTarget_FadeSoundClass::Event_RestoreVolume() {
1795         float fadeTime = spawnArgs.GetFloat( "fadeTime" );
1796         float fadeDB = spawnArgs.GetFloat( "fadeDB" );
1797         int fadeClass = spawnArgs.GetInt( "fadeClass" );
1798         // restore volume
1799         gameSoundWorld->FadeSoundClasses( 0, fadeDB, fadeTime );
1800 }
1801