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 #include "sys/platform.h"
30 #include "idlib/LangDict.h"
31 #include "renderer/ModelManager.h"
32 
33 #include "gamesys/SysCvar.h"
34 #include "script/Script_Thread.h"
35 #include "Light.h"
36 #include "Player.h"
37 #include "Mover.h"
38 #include "Misc.h"
39 #include "WorldSpawn.h"
40 #include "Sound.h"
41 
42 #include "Target.h"
43 
44 /*
45 ===============================================================================
46 
47 idTarget
48 
49 Invisible entities that affect other entities or the world when activated.
50 
51 ===============================================================================
52 */
53 
CLASS_DECLARATION(idEntity,idTarget)54 CLASS_DECLARATION( idEntity, idTarget )
55 END_CLASS
56 
57 
58 /*
59 ===============================================================================
60 
61 idTarget_Remove
62 
63 ===============================================================================
64 */
65 
66 CLASS_DECLARATION( idTarget, idTarget_Remove )
67 	EVENT( EV_Activate, idTarget_Remove::Event_Activate )
68 END_CLASS
69 
70 /*
71 ================
72 idTarget_Remove::Event_Activate
73 ================
74 */
75 void idTarget_Remove::Event_Activate( idEntity *activator ) {
76 	int			i;
77 	idEntity	*ent;
78 
79 	for( i = 0; i < targets.Num(); i++ ) {
80 		ent = targets[ i ].GetEntity();
81 		if ( ent ) {
82 			ent->PostEventMS( &EV_Remove, 0 );
83 		}
84 	}
85 
86 	// delete our self when done
87 	PostEventMS( &EV_Remove, 0 );
88 }
89 
90 
91 /*
92 ===============================================================================
93 
94 idTarget_Show
95 
96 ===============================================================================
97 */
98 
CLASS_DECLARATION(idTarget,idTarget_Show)99 CLASS_DECLARATION( idTarget, idTarget_Show )
100 	EVENT( EV_Activate, idTarget_Show::Event_Activate )
101 END_CLASS
102 
103 /*
104 ================
105 idTarget_Show::Event_Activate
106 ================
107 */
108 void idTarget_Show::Event_Activate( idEntity *activator ) {
109 	int			i;
110 	idEntity	*ent;
111 
112 	for( i = 0; i < targets.Num(); i++ ) {
113 		ent = targets[ i ].GetEntity();
114 		if ( ent ) {
115 			ent->Show();
116 		}
117 	}
118 
119 	// delete our self when done
120 	PostEventMS( &EV_Remove, 0 );
121 }
122 
123 
124 /*
125 ===============================================================================
126 
127 idTarget_Damage
128 
129 ===============================================================================
130 */
131 
CLASS_DECLARATION(idTarget,idTarget_Damage)132 CLASS_DECLARATION( idTarget, idTarget_Damage )
133 	EVENT( EV_Activate, idTarget_Damage::Event_Activate )
134 END_CLASS
135 
136 /*
137 ================
138 idTarget_Damage::Event_Activate
139 ================
140 */
141 void idTarget_Damage::Event_Activate( idEntity *activator ) {
142 	int			i;
143 	const char *damage;
144 	idEntity *	ent;
145 
146 	damage = spawnArgs.GetString( "def_damage", "damage_generic" );
147 	for( i = 0; i < targets.Num(); i++ ) {
148 		ent = targets[ i ].GetEntity();
149 		if ( ent ) {
150 			ent->Damage( this, this, vec3_origin, damage, 1.0f, INVALID_JOINT );
151 		}
152 	}
153 }
154 
155 
156 /*
157 ===============================================================================
158 
159 idTarget_SessionCommand
160 
161 ===============================================================================
162 */
163 
CLASS_DECLARATION(idTarget,idTarget_SessionCommand)164 CLASS_DECLARATION( idTarget, idTarget_SessionCommand )
165 	EVENT( EV_Activate, idTarget_SessionCommand::Event_Activate )
166 END_CLASS
167 
168 /*
169 ================
170 idTarget_SessionCommand::Event_Activate
171 ================
172 */
173 void idTarget_SessionCommand::Event_Activate( idEntity *activator ) {
174 	gameLocal.sessionCommand = spawnArgs.GetString( "command" );
175 }
176 
177 
178 /*
179 ===============================================================================
180 
181 idTarget_EndLevel
182 
183 Just a modified form of idTarget_SessionCommand
184 ===============================================================================
185 */
186 
CLASS_DECLARATION(idTarget,idTarget_EndLevel)187 CLASS_DECLARATION( idTarget, idTarget_EndLevel )
188 	EVENT( EV_Activate,		idTarget_EndLevel::Event_Activate )
189 END_CLASS
190 
191 /*
192 ================
193 idTarget_EndLevel::Event_Activate
194 ================
195 */
196 void idTarget_EndLevel::Event_Activate( idEntity *activator ) {
197 	idStr nextMap;
198 
199 	if ( spawnArgs.GetBool( "endOfGame" ) ) {
200 		cvarSystem->SetCVarBool( "g_nightmare", true );
201 		gameLocal.sessionCommand = "disconnect";
202 		return;
203 	}
204 
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 
CLASS_DECLARATION(idTarget,idTarget_WaitForButton)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 */
Think(void)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 
CLASS_DECLARATION(idTarget,idTarget_SetGlobalShaderTime)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 
CLASS_DECLARATION(idTarget,idTarget_SetShaderParm)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 
CLASS_DECLARATION(idTarget,idTarget_SetShaderTime)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 
CLASS_DECLARATION(idTarget,idTarget_FadeEntity)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 */
Save(idSaveGame * savefile) const409 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 */
Restore(idRestoreGame * savefile)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 */
Event_Activate(idEntity * activator)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 */
Think(void)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 
CLASS_DECLARATION(idTarget,idTarget_LightFadeIn)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 
CLASS_DECLARATION(idTarget,idTarget_LightFadeOut)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 
CLASS_DECLARATION(idTarget,idTarget_Give)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 */
Event_Activate(idEntity * activator)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 
CLASS_DECLARATION(idTarget,idTarget_GiveEmail)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 */
Event_Activate(idEntity * activator)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 
CLASS_DECLARATION(idTarget,idTarget_SetModel)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 */
Event_Activate(idEntity * activator)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 
CLASS_DECLARATION(idTarget,idTarget_SetInfluence)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 */
Save(idSaveGame * savefile) const751 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 */
Restore(idRestoreGame * savefile)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 */
Spawn()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 */
Event_Flash(float flash,int out)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 */
Event_ClearFlash(float flash)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 */
Event_GatherEntities()923 void idTarget_SetInfluence::Event_GatherEntities() {
924 	int i, listedEntities;
925 	idEntity *entityList[ MAX_GENTITIES ];
926 
927 	bool lights = spawnArgs.GetBool( "effect_lights" );
928 	bool sounds = spawnArgs.GetBool( "effect_sounds" );
929 	bool guis = spawnArgs.GetBool( "effect_guis" );
930 	bool models = spawnArgs.GetBool( "effect_models" );
931 	bool vision = spawnArgs.GetBool( "effect_vision" );
932 	bool targetsOnly = spawnArgs.GetBool( "targetsOnly" );
933 
934 	lightList.Clear();
935 	guiList.Clear();
936 	soundList.Clear();
937 #ifdef _D3XP
938 	savedGuiList.Clear();
939 #endif
940 
941 	if ( spawnArgs.GetBool( "effect_all" ) ) {
942 		lights = sounds = guis = models = vision = true;
943 	}
944 
945 	if ( targetsOnly ) {
946 		listedEntities = targets.Num();
947 		for ( i = 0; i < listedEntities; i++ ) {
948 			entityList[i] = targets[i].GetEntity();
949 		}
950 	} else {
951 		float radius = spawnArgs.GetFloat( "radius" );
952 		listedEntities = gameLocal.EntitiesWithinRadius( GetPhysics()->GetOrigin(), radius, entityList, MAX_GENTITIES );
953 	}
954 
955 	for( i = 0; i < listedEntities; i++ ) {
956 		idEntity *ent = entityList[ i ];
957 		if ( ent ) {
958 			if ( lights && ent->IsType( idLight::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) {
959 				lightList.Append( ent->entityNumber );
960 				continue;
961 			}
962 			if ( sounds && ent->IsType( idSound::Type ) && ent->spawnArgs.FindKey( "snd_demonic" ) ) {
963 				soundList.Append( ent->entityNumber );
964 				continue;
965 			}
966 			if ( guis && ent->GetRenderEntity() && ent->GetRenderEntity()->gui[ 0 ] && ent->spawnArgs.FindKey( "gui_demonic" ) ) {
967 				guiList.Append( ent->entityNumber );
968 #ifdef _D3XP
969 				SavedGui_t temp;
970 				savedGuiList.Append(temp);
971 #endif
972 				continue;
973 			}
974 			if ( ent->IsType( idStaticEntity::Type ) && ent->spawnArgs.FindKey( "color_demonic" ) ) {
975 				genericList.Append( ent->entityNumber );
976 				continue;
977 			}
978 		}
979 	}
980 	idStr temp;
981 	temp = spawnArgs.GetString( "switchToView" );
982 	switchToCamera = ( temp.Length() ) ? gameLocal.FindEntity( temp ) : NULL;
983 
984 }
985 
986 /*
987 ================
988 idTarget_SetInfluence::Event_Activate
989 ================
990 */
Event_Activate(idEntity * activator)991 void idTarget_SetInfluence::Event_Activate( idEntity *activator ) {
992 	int i, j;
993 	idEntity *ent;
994 	idLight *light;
995 	idSound *sound;
996 	idStaticEntity *generic;
997 	const char *parm;
998 	const char *skin;
999 	bool update;
1000 	idVec3 color;
1001 	idVec4 colorTo;
1002 	idPlayer *player;
1003 
1004 	player = gameLocal.GetLocalPlayer();
1005 
1006 	if ( spawnArgs.GetBool( "triggerActivate" ) ) {
1007 		if ( restoreOnTrigger ) {
1008 			ProcessEvent( &EV_RestoreInfluence );
1009 			restoreOnTrigger = false;
1010 			return;
1011 		}
1012 		restoreOnTrigger = true;
1013 	}
1014 
1015 	float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" );
1016 
1017 	if ( delay > 0.0f ) {
1018 		PostEventSec( &EV_Activate, delay, activator );
1019 		delay = 0.0f;
1020 		// start any sound fading now
1021 		if ( fadeTime ) {
1022 			gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime );
1023 			soundFaded = true;
1024 		}
1025 		return;
1026 	} else if ( fadeTime && !soundFaded ) {
1027 		gameSoundWorld->FadeSoundClasses( 0, -40.0f, fadeTime );
1028 		soundFaded = true;
1029 	}
1030 
1031 	if ( spawnArgs.GetBool( "triggerTargets" ) ) {
1032 		ActivateTargets( activator );
1033 	}
1034 
1035 	if ( flashIn ) {
1036 		PostEventSec( &EV_Flash, 0.0f, flashIn, 0 );
1037 	}
1038 
1039 	parm = spawnArgs.GetString( "snd_influence" );
1040 	if ( parm && *parm ) {
1041 		PostEventSec( &EV_StartSoundShader, flashIn, parm, SND_CHANNEL_ANY );
1042 	}
1043 
1044 	if ( switchToCamera ) {
1045 		switchToCamera->PostEventSec( &EV_Activate, flashIn + 0.05f, this );
1046 	}
1047 
1048 	int fov = spawnArgs.GetInt( "fov" );
1049 	if ( fov ) {
1050 		fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "fovTime" ) ), player->DefaultFov(), fov );
1051 		BecomeActive( TH_THINK );
1052 	}
1053 
1054 	for ( i = 0; i < genericList.Num(); i++ ) {
1055 		ent = gameLocal.entities[genericList[i]];
1056 		if ( ent == NULL ) {
1057 			continue;
1058 		}
1059 		generic = static_cast<idStaticEntity*>( ent );
1060 		color = generic->spawnArgs.GetVector( "color_demonic" );
1061 		colorTo.Set( color.x, color.y, color.z, 1.0f );
1062 		generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1063 	}
1064 
1065 	for ( i = 0; i < lightList.Num(); i++ ) {
1066 		ent = gameLocal.entities[lightList[i]];
1067 		if ( ent == NULL || !ent->IsType( idLight::Type ) ) {
1068 			continue;
1069 		}
1070 		light = static_cast<idLight *>(ent);
1071 		parm = light->spawnArgs.GetString( "mat_demonic" );
1072 		if ( parm && *parm ) {
1073 			light->SetShader( parm );
1074 		}
1075 
1076 		color = light->spawnArgs.GetVector( "_color" );
1077 		color = light->spawnArgs.GetVector( "color_demonic", color.ToString() );
1078 		colorTo.Set( color.x, color.y, color.z, 1.0f );
1079 		light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1080 	}
1081 
1082 	for ( i = 0; i < soundList.Num(); i++ ) {
1083 		ent = gameLocal.entities[soundList[i]];
1084 		if ( ent == NULL || !ent->IsType( idSound::Type ) ) {
1085 			continue;
1086 		}
1087 		sound = static_cast<idSound *>(ent);
1088 		parm = sound->spawnArgs.GetString( "snd_demonic" );
1089 		if ( parm && *parm ) {
1090 			if ( sound->spawnArgs.GetBool( "overlayDemonic" ) ) {
1091 				sound->StartSound( "snd_demonic", SND_CHANNEL_DEMONIC, 0, false, NULL );
1092 			} else {
1093 				sound->StopSound( SND_CHANNEL_ANY, false );
1094 				sound->SetSound( parm );
1095 			}
1096 		}
1097 	}
1098 
1099 	for ( i = 0; i < guiList.Num(); i++ ) {
1100 		ent = gameLocal.entities[guiList[i]];
1101 		if ( ent == NULL || ent->GetRenderEntity() == NULL ) {
1102 			continue;
1103 		}
1104 		update = false;
1105 
1106 		for ( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
1107 			if ( ent->GetRenderEntity()->gui[ j ] && ent->spawnArgs.FindKey( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ) ) {
1108 #ifdef _D3XP
1109 				//Backup the old one
1110 				savedGuiList[i].gui[j] = ent->GetRenderEntity()->gui[ j ];
1111 #endif
1112 				ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui_demonic" : va( "gui_demonic%d", j+1 ) ), true );
1113 				update = true;
1114 			}
1115 		}
1116 
1117 		if ( update ) {
1118 			ent->UpdateVisuals();
1119 			ent->Present();
1120 		}
1121 	}
1122 
1123 	player->SetInfluenceLevel( spawnArgs.GetInt( "influenceLevel" ) );
1124 
1125 	int snapAngle = spawnArgs.GetInt( "snapAngle" );
1126 	if ( snapAngle ) {
1127 		idAngles ang( 0, snapAngle, 0 );
1128 		player->SetViewAngles( ang );
1129 		player->SetAngles( ang );
1130 	}
1131 
1132 	if ( spawnArgs.GetBool( "effect_vision" ) ) {
1133 		parm = spawnArgs.GetString( "mtrVision" );
1134 		skin = spawnArgs.GetString( "skinVision" );
1135 		player->SetInfluenceView( parm, skin, spawnArgs.GetInt( "visionRadius" ), this );
1136 	}
1137 
1138 	parm = spawnArgs.GetString( "mtrWorld" );
1139 	if ( parm && *parm ) {
1140 		gameLocal.SetGlobalMaterial( declManager->FindMaterial( parm ) );
1141 	}
1142 
1143 	if ( !restoreOnTrigger ) {
1144 		PostEventMS( &EV_RestoreInfluence, SEC2MS( spawnArgs.GetFloat( "time" ) ) );
1145 	}
1146 }
1147 
1148 /*
1149 ================
1150 idTarget_SetInfluence::Think
1151 ================
1152 */
Think(void)1153 void idTarget_SetInfluence::Think( void ) {
1154 	if ( thinkFlags & TH_THINK ) {
1155 		idPlayer *player = gameLocal.GetLocalPlayer();
1156 		player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) );
1157 		if ( fovSetting.IsDone( gameLocal.time ) ) {
1158 			if ( !spawnArgs.GetBool( "leaveFOV" ) ) {
1159 				player->SetInfluenceFov( 0 );
1160 			}
1161 			BecomeInactive( TH_THINK );
1162 		}
1163 	} else {
1164 		BecomeInactive( TH_ALL );
1165 	}
1166 }
1167 
1168 
1169 /*
1170 ================
1171 idTarget_SetInfluence::Event_RestoreInfluence
1172 ================
1173 */
Event_RestoreInfluence()1174 void idTarget_SetInfluence::Event_RestoreInfluence() {
1175 	int i, j;
1176 	idEntity *ent;
1177 	idLight *light;
1178 	idSound *sound;
1179 	idStaticEntity *generic;
1180 	bool update;
1181 	idVec3 color;
1182 	idVec4 colorTo;
1183 
1184 	if ( flashOut ) {
1185 		PostEventSec( &EV_Flash, 0.0f, flashOut, 1 );
1186 	}
1187 
1188 	if ( switchToCamera ) {
1189 		switchToCamera->PostEventMS( &EV_Activate, 0.0f, this );
1190 	}
1191 
1192 	for ( i = 0; i < genericList.Num(); i++ ) {
1193 		ent = gameLocal.entities[genericList[i]];
1194 		if ( ent == NULL ) {
1195 			continue;
1196 		}
1197 		generic = static_cast<idStaticEntity*>( ent );
1198 		colorTo.Set( 1.0f, 1.0f, 1.0f, 1.0f );
1199 		generic->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1200 	}
1201 
1202 	for ( i = 0; i < lightList.Num(); i++ ) {
1203 		ent = gameLocal.entities[lightList[i]];
1204 		if ( ent == NULL || !ent->IsType( idLight::Type ) ) {
1205 			continue;
1206 		}
1207 		light = static_cast<idLight *>(ent);
1208 		if ( !light->spawnArgs.GetBool( "leave_demonic_mat" ) ) {
1209 			const char *texture = light->spawnArgs.GetString( "texture", "lights/squarelight1" );
1210 			light->SetShader( texture );
1211 		}
1212 		color = light->spawnArgs.GetVector( "_color" );
1213 		colorTo.Set( color.x, color.y, color.z, 1.0f );
1214 		light->Fade( colorTo, spawnArgs.GetFloat( "fade_time", "0.25" ) );
1215 	}
1216 
1217 	for ( i = 0; i < soundList.Num(); i++ ) {
1218 		ent = gameLocal.entities[soundList[i]];
1219 		if ( ent == NULL || !ent->IsType( idSound::Type ) ) {
1220 			continue;
1221 		}
1222 		sound = static_cast<idSound *>(ent);
1223 		sound->StopSound( SND_CHANNEL_ANY, false );
1224 		sound->SetSound( sound->spawnArgs.GetString( "s_shader" ) );
1225 	}
1226 
1227 	for ( i = 0; i < guiList.Num(); i++ ) {
1228 		ent = gameLocal.entities[guiList[i]];
1229 		if ( ent == NULL || GetRenderEntity() == NULL ) {
1230 			continue;
1231 		}
1232 		update = false;
1233 		for( j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
1234 			if ( ent->GetRenderEntity()->gui[ j ] ) {
1235 #ifdef _D3XP
1236 				ent->GetRenderEntity()->gui[ j ] = savedGuiList[i].gui[j];
1237 #else
1238 				ent->GetRenderEntity()->gui[ j ] = uiManager->FindGui( ent->spawnArgs.GetString( j == 0 ? "gui" : va( "gui%d", j+1 ) ) );
1239 #endif
1240 				update = true;
1241 			}
1242 		}
1243 		if ( update ) {
1244 			ent->UpdateVisuals();
1245 			ent->Present();
1246 		}
1247 	}
1248 
1249 	idPlayer *player = gameLocal.GetLocalPlayer();
1250 	player->SetInfluenceLevel( 0 );
1251 	player->SetInfluenceView( NULL, NULL, 0.0f, NULL );
1252 	player->SetInfluenceFov( 0 );
1253 	gameLocal.SetGlobalMaterial( NULL );
1254 	float fadeTime = spawnArgs.GetFloat( "fadeWorldSounds" );
1255 	if ( fadeTime ) {
1256 		gameSoundWorld->FadeSoundClasses( 0, 0.0f, fadeTime / 2.0f );
1257 	}
1258 
1259 }
1260 
1261 /*
1262 ===============================================================================
1263 
1264 idTarget_SetKeyVal
1265 
1266 ===============================================================================
1267 */
1268 
CLASS_DECLARATION(idTarget,idTarget_SetKeyVal)1269 CLASS_DECLARATION( idTarget, idTarget_SetKeyVal )
1270 	EVENT( EV_Activate,	idTarget_SetKeyVal::Event_Activate )
1271 END_CLASS
1272 
1273 /*
1274 ================
1275 idTarget_SetKeyVal::Event_Activate
1276 ================
1277 */
1278 void idTarget_SetKeyVal::Event_Activate( idEntity *activator ) {
1279 	int i;
1280 	idStr key, val;
1281 	idEntity *ent;
1282 	const idKeyValue *kv;
1283 	int n;
1284 
1285 	for( i = 0; i < targets.Num(); i++ ) {
1286 		ent = targets[ i ].GetEntity();
1287 		if ( ent ) {
1288 			kv = spawnArgs.MatchPrefix("keyval");
1289 			while ( kv ) {
1290 				n = kv->GetValue().Find( ";" );
1291 				if ( n > 0 ) {
1292 					key = kv->GetValue().Left( n );
1293 					val = kv->GetValue().Right( kv->GetValue().Length() - n - 1 );
1294 					ent->spawnArgs.Set( key, val );
1295 					for ( int j = 0; j < MAX_RENDERENTITY_GUI; j++ ) {
1296 						if ( ent->GetRenderEntity()->gui[ j ] ) {
1297 							if ( idStr::Icmpn( key, "gui_", 4 ) == 0 ) {
1298 								ent->GetRenderEntity()->gui[ j ]->SetStateString( key, val );
1299 								ent->GetRenderEntity()->gui[ j ]->StateChanged( gameLocal.time );
1300 							}
1301 						}
1302 					}
1303 				}
1304 				kv = spawnArgs.MatchPrefix( "keyval", kv );
1305 			}
1306 			ent->UpdateChangeableSpawnArgs( NULL );
1307 			ent->UpdateVisuals();
1308 			ent->Present();
1309 		}
1310 	}
1311 }
1312 
1313 /*
1314 ===============================================================================
1315 
1316 idTarget_SetFov
1317 
1318 ===============================================================================
1319 */
1320 
CLASS_DECLARATION(idTarget,idTarget_SetFov)1321 CLASS_DECLARATION( idTarget, idTarget_SetFov )
1322 	EVENT( EV_Activate,	idTarget_SetFov::Event_Activate )
1323 END_CLASS
1324 
1325 
1326 /*
1327 ================
1328 idTarget_SetFov::Save
1329 ================
1330 */
1331 void idTarget_SetFov::Save( idSaveGame *savefile ) const {
1332 
1333 	savefile->WriteFloat( fovSetting.GetStartTime() );
1334 	savefile->WriteFloat( fovSetting.GetDuration() );
1335 	savefile->WriteFloat( fovSetting.GetStartValue() );
1336 	savefile->WriteFloat( fovSetting.GetEndValue() );
1337 }
1338 
1339 /*
1340 ================
1341 idTarget_SetFov::Restore
1342 ================
1343 */
Restore(idRestoreGame * savefile)1344 void idTarget_SetFov::Restore( idRestoreGame *savefile ) {
1345 	float setting;
1346 
1347 	savefile->ReadFloat( setting );
1348 	fovSetting.SetStartTime( setting );
1349 	savefile->ReadFloat( setting );
1350 	fovSetting.SetDuration( setting );
1351 	savefile->ReadFloat( setting );
1352 	fovSetting.SetStartValue( setting );
1353 	savefile->ReadFloat( setting );
1354 	fovSetting.SetEndValue( setting );
1355 
1356 	fovSetting.GetCurrentValue( gameLocal.time );
1357 }
1358 
1359 /*
1360 ================
1361 idTarget_SetFov::Event_Activate
1362 ================
1363 */
Event_Activate(idEntity * activator)1364 void idTarget_SetFov::Event_Activate( idEntity *activator ) {
1365 	// always allow during cinematics
1366 	cinematic = true;
1367 
1368 	idPlayer *player = gameLocal.GetLocalPlayer();
1369 	fovSetting.Init( gameLocal.time, SEC2MS( spawnArgs.GetFloat( "time" ) ), player ? player->DefaultFov() : g_fov.GetFloat(), spawnArgs.GetFloat( "fov" ) );
1370 	BecomeActive( TH_THINK );
1371 }
1372 
1373 /*
1374 ================
1375 idTarget_SetFov::Think
1376 ================
1377 */
Think(void)1378 void idTarget_SetFov::Think( void ) {
1379 	if ( thinkFlags & TH_THINK ) {
1380 		idPlayer *player = gameLocal.GetLocalPlayer();
1381 		player->SetInfluenceFov( fovSetting.GetCurrentValue( gameLocal.time ) );
1382 		if ( fovSetting.IsDone( gameLocal.time ) ) {
1383 			player->SetInfluenceFov( 0.0f );
1384 			BecomeInactive( TH_THINK );
1385 		}
1386 	} else {
1387 		BecomeInactive( TH_ALL );
1388 	}
1389 }
1390 
1391 
1392 /*
1393 ===============================================================================
1394 
1395 idTarget_SetPrimaryObjective
1396 
1397 ===============================================================================
1398 */
1399 
CLASS_DECLARATION(idTarget,idTarget_SetPrimaryObjective)1400 CLASS_DECLARATION( idTarget, idTarget_SetPrimaryObjective )
1401 	EVENT( EV_Activate,	idTarget_SetPrimaryObjective::Event_Activate )
1402 END_CLASS
1403 
1404 /*
1405 ================
1406 idTarget_SetPrimaryObjective::Event_Activate
1407 ================
1408 */
1409 void idTarget_SetPrimaryObjective::Event_Activate( idEntity *activator ) {
1410 	idPlayer *player = gameLocal.GetLocalPlayer();
1411 	if ( player && player->objectiveSystem ) {
1412 		player->objectiveSystem->SetStateString( "missionobjective", spawnArgs.GetString( "text", common->GetLanguageDict()->GetString( "#str_04253" ) ) );
1413 	}
1414 }
1415 
1416 /*
1417 ===============================================================================
1418 
1419 idTarget_LockDoor
1420 
1421 ===============================================================================
1422 */
1423 
CLASS_DECLARATION(idTarget,idTarget_LockDoor)1424 CLASS_DECLARATION( idTarget, idTarget_LockDoor )
1425 	EVENT( EV_Activate,	idTarget_LockDoor::Event_Activate )
1426 END_CLASS
1427 
1428 /*
1429 ================
1430 idTarget_LockDoor::Event_Activate
1431 ================
1432 */
1433 void idTarget_LockDoor::Event_Activate( idEntity *activator ) {
1434 	int i;
1435 	idEntity *ent;
1436 	int lock;
1437 
1438 	lock = spawnArgs.GetInt( "locked", "1" );
1439 	for( i = 0; i < targets.Num(); i++ ) {
1440 		ent = targets[ i ].GetEntity();
1441 		if ( ent && ent->IsType( idDoor::Type ) ) {
1442 			if ( static_cast<idDoor *>( ent )->IsLocked() ) {
1443 				static_cast<idDoor *>( ent )->Lock( 0 );
1444 			} else {
1445 				static_cast<idDoor *>( ent )->Lock( lock );
1446 			}
1447 		}
1448 	}
1449 }
1450 
1451 /*
1452 ===============================================================================
1453 
1454 idTarget_CallObjectFunction
1455 
1456 ===============================================================================
1457 */
1458 
CLASS_DECLARATION(idTarget,idTarget_CallObjectFunction)1459 CLASS_DECLARATION( idTarget, idTarget_CallObjectFunction )
1460 	EVENT( EV_Activate,	idTarget_CallObjectFunction::Event_Activate )
1461 END_CLASS
1462 
1463 /*
1464 ================
1465 idTarget_CallObjectFunction::Event_Activate
1466 ================
1467 */
1468 void idTarget_CallObjectFunction::Event_Activate( idEntity *activator ) {
1469 	int					i;
1470 	idEntity			*ent;
1471 	const function_t	*func;
1472 	const char			*funcName;
1473 	idThread			*thread;
1474 
1475 	funcName = spawnArgs.GetString( "call" );
1476 	for( i = 0; i < targets.Num(); i++ ) {
1477 		ent = targets[ i ].GetEntity();
1478 		if ( ent && ent->scriptObject.HasObject() ) {
1479 			func = ent->scriptObject.GetFunction( funcName );
1480 			if ( !func ) {
1481 				gameLocal.Error( "Function '%s' not found on entity '%s' for function call from '%s'", funcName, ent->name.c_str(), name.c_str() );
1482 			}
1483 			if ( func->type->NumParameters() != 1 ) {
1484 				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() );
1485 			}
1486 			if ( !ent->scriptObject.GetTypeDef()->Inherits( func->type->GetParmType( 0 ) ) ) {
1487 				gameLocal.Error( "Function '%s' on entity '%s' is the wrong type for function call from '%s'", funcName, ent->name.c_str(), name.c_str() );
1488 			}
1489 			// create a thread and call the function
1490 			thread = new idThread();
1491 			thread->CallFunction( ent, func, true );
1492 			thread->Start();
1493 		}
1494 	}
1495 }
1496 
1497 
1498 /*
1499 ===============================================================================
1500 
1501 idTarget_EnableLevelWeapons
1502 
1503 ===============================================================================
1504 */
1505 
CLASS_DECLARATION(idTarget,idTarget_EnableLevelWeapons)1506 CLASS_DECLARATION( idTarget, idTarget_EnableLevelWeapons )
1507 	EVENT( EV_Activate,	idTarget_EnableLevelWeapons::Event_Activate )
1508 END_CLASS
1509 
1510 /*
1511 ================
1512 idTarget_EnableLevelWeapons::Event_Activate
1513 ================
1514 */
1515 void idTarget_EnableLevelWeapons::Event_Activate( idEntity *activator ) {
1516 	int i;
1517 	const char *weap;
1518 
1519 	gameLocal.world->spawnArgs.SetBool( "no_Weapons", spawnArgs.GetBool( "disable" ) );
1520 
1521 	if ( spawnArgs.GetBool( "disable" ) ) {
1522 		for( i = 0; i < gameLocal.numClients; i++ ) {
1523 			if ( gameLocal.entities[ i ] ) {
1524 				gameLocal.entities[ i ]->ProcessEvent( &EV_Player_DisableWeapon );
1525 			}
1526 		}
1527 	} else {
1528 		weap = spawnArgs.GetString( "weapon" );
1529 		for( i = 0; i < gameLocal.numClients; i++ ) {
1530 			if ( gameLocal.entities[ i ] ) {
1531 				gameLocal.entities[ i ]->ProcessEvent( &EV_Player_EnableWeapon );
1532 				if ( weap && weap[ 0 ] ) {
1533 					gameLocal.entities[ i ]->PostEventSec( &EV_Player_SelectWeapon, 0.5f, weap );
1534 				}
1535 			}
1536 		}
1537 	}
1538 }
1539 
1540 /*
1541 ===============================================================================
1542 
1543 idTarget_Tip
1544 
1545 ===============================================================================
1546 */
1547 
1548 const idEventDef EV_TipOff( "<TipOff>" );
1549 extern const idEventDef EV_GetPlayerPos( "<getplayerpos>" );
1550 
CLASS_DECLARATION(idTarget,idTarget_Tip)1551 CLASS_DECLARATION( idTarget, idTarget_Tip )
1552 	EVENT( EV_Activate,		idTarget_Tip::Event_Activate )
1553 	EVENT( EV_TipOff,		idTarget_Tip::Event_TipOff )
1554 	EVENT( EV_GetPlayerPos,	idTarget_Tip::Event_GetPlayerPos )
1555 END_CLASS
1556 
1557 
1558 /*
1559 ================
1560 idTarget_Tip::idTarget_Tip
1561 ================
1562 */
1563 idTarget_Tip::idTarget_Tip( void ) {
1564 	playerPos.Zero();
1565 }
1566 
1567 /*
1568 ================
1569 idTarget_Tip::Spawn
1570 ================
1571 */
Spawn(void)1572 void idTarget_Tip::Spawn( void ) {
1573 }
1574 
1575 /*
1576 ================
1577 idTarget_Tip::Save
1578 ================
1579 */
Save(idSaveGame * savefile) const1580 void idTarget_Tip::Save( idSaveGame *savefile ) const {
1581 	savefile->WriteVec3( playerPos );
1582 }
1583 
1584 /*
1585 ================
1586 idTarget_Tip::Restore
1587 ================
1588 */
Restore(idRestoreGame * savefile)1589 void idTarget_Tip::Restore( idRestoreGame *savefile ) {
1590 	savefile->ReadVec3( playerPos );
1591 }
1592 
1593 /*
1594 ================
1595 idTarget_Tip::Event_Activate
1596 ================
1597 */
Event_GetPlayerPos(void)1598 void idTarget_Tip::Event_GetPlayerPos( void ) {
1599 	idPlayer *player = gameLocal.GetLocalPlayer();
1600 	if ( player ) {
1601 		playerPos = player->GetPhysics()->GetOrigin();
1602 		PostEventMS( &EV_TipOff, 100 );
1603 	}
1604 }
1605 
1606 /*
1607 ================
1608 idTarget_Tip::Event_Activate
1609 ================
1610 */
Event_Activate(idEntity * activator)1611 void idTarget_Tip::Event_Activate( idEntity *activator ) {
1612 	idPlayer *player = gameLocal.GetLocalPlayer();
1613 	if ( player ) {
1614 		if ( player->IsTipVisible() ) {
1615 			PostEventSec( &EV_Activate, 5.1f, activator );
1616 			return;
1617 		}
1618 		player->ShowTip( spawnArgs.GetString( "text_title" ), spawnArgs.GetString( "text_tip" ), false );
1619 		PostEventMS( &EV_GetPlayerPos, 2000 );
1620 	}
1621 }
1622 
1623 /*
1624 ================
1625 idTarget_Tip::Event_TipOff
1626 ================
1627 */
Event_TipOff(void)1628 void idTarget_Tip::Event_TipOff( void ) {
1629 	idPlayer *player = gameLocal.GetLocalPlayer();
1630 	if ( player ) {
1631 		idVec3 v = player->GetPhysics()->GetOrigin() - playerPos;
1632 		if ( v.Length() > 96.0f ) {
1633 			player->HideTip();
1634 		} else {
1635 			PostEventMS( &EV_TipOff, 100 );
1636 		}
1637 	}
1638 }
1639 
1640 
1641 /*
1642 ===============================================================================
1643 
1644 idTarget_GiveSecurity
1645 
1646 ===============================================================================
1647 */
1648 
CLASS_DECLARATION(idTarget,idTarget_GiveSecurity)1649 CLASS_DECLARATION( idTarget, idTarget_GiveSecurity )
1650 EVENT( EV_Activate,	idTarget_GiveSecurity::Event_Activate )
1651 END_CLASS
1652 
1653 /*
1654 ================
1655 idTarget_GiveEmail::Event_Activate
1656 ================
1657 */
1658 void idTarget_GiveSecurity::Event_Activate( idEntity *activator ) {
1659 	idPlayer *player = gameLocal.GetLocalPlayer();
1660 	if ( player ) {
1661 		player->GiveSecurity( spawnArgs.GetString( "text_security" ) );
1662 	}
1663 }
1664 
1665 
1666 /*
1667 ===============================================================================
1668 
1669 idTarget_RemoveWeapons
1670 
1671 ===============================================================================
1672 */
1673 
CLASS_DECLARATION(idTarget,idTarget_RemoveWeapons)1674 CLASS_DECLARATION( idTarget, idTarget_RemoveWeapons )
1675 EVENT( EV_Activate,	idTarget_RemoveWeapons::Event_Activate )
1676 END_CLASS
1677 
1678 /*
1679 ================
1680 idTarget_RemoveWeapons::Event_Activate
1681 ================
1682 */
1683 void idTarget_RemoveWeapons::Event_Activate( idEntity *activator ) {
1684 	for( int i = 0; i < gameLocal.numClients; i++ ) {
1685 		if ( gameLocal.entities[ i ] ) {
1686 			idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] );
1687 			const idKeyValue *kv = spawnArgs.MatchPrefix( "weapon", NULL );
1688 			while ( kv ) {
1689 				player->RemoveWeapon( kv->GetValue() );
1690 				kv = spawnArgs.MatchPrefix( "weapon", kv );
1691 			}
1692 			player->SelectWeapon( player->weapon_fists, true );
1693 		}
1694 	}
1695 }
1696 
1697 
1698 /*
1699 ===============================================================================
1700 
1701 idTarget_LevelTrigger
1702 
1703 ===============================================================================
1704 */
1705 
CLASS_DECLARATION(idTarget,idTarget_LevelTrigger)1706 CLASS_DECLARATION( idTarget, idTarget_LevelTrigger )
1707 EVENT( EV_Activate,	idTarget_LevelTrigger::Event_Activate )
1708 END_CLASS
1709 
1710 /*
1711 ================
1712 idTarget_LevelTrigger::Event_Activate
1713 ================
1714 */
1715 void idTarget_LevelTrigger::Event_Activate( idEntity *activator ) {
1716 	for( int i = 0; i < gameLocal.numClients; i++ ) {
1717 		if ( gameLocal.entities[ i ] ) {
1718 			idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] );
1719 			player->SetLevelTrigger( spawnArgs.GetString( "levelName" ), spawnArgs.GetString( "triggerName" ) );
1720 		}
1721 	}
1722 }
1723 
1724 
1725 /*
1726 ===============================================================================
1727 
1728 idTarget_EnableStamina
1729 
1730 ===============================================================================
1731 */
1732 
CLASS_DECLARATION(idTarget,idTarget_EnableStamina)1733 CLASS_DECLARATION( idTarget, idTarget_EnableStamina )
1734 EVENT( EV_Activate,	idTarget_EnableStamina::Event_Activate )
1735 END_CLASS
1736 
1737 /*
1738 ================
1739 idTarget_EnableStamina::Event_Activate
1740 ================
1741 */
1742 void idTarget_EnableStamina::Event_Activate( idEntity *activator ) {
1743 	for( int i = 0; i < gameLocal.numClients; i++ ) {
1744 		if ( gameLocal.entities[ i ] ) {
1745 			idPlayer *player = static_cast< idPlayer* >( gameLocal.entities[i] );
1746 			if ( spawnArgs.GetBool( "enable" ) ) {
1747 				pm_stamina.SetFloat( player->spawnArgs.GetFloat( "pm_stamina" ) );
1748 			} else {
1749 				pm_stamina.SetFloat( 0.0f );
1750 			}
1751 		}
1752 	}
1753 }
1754 
1755 /*
1756 ===============================================================================
1757 
1758 idTarget_FadeSoundClass
1759 
1760 ===============================================================================
1761 */
1762 
1763 const idEventDef EV_RestoreVolume( "<RestoreVolume>" );
CLASS_DECLARATION(idTarget,idTarget_FadeSoundClass)1764 CLASS_DECLARATION( idTarget, idTarget_FadeSoundClass )
1765 EVENT( EV_Activate,	idTarget_FadeSoundClass::Event_Activate )
1766 EVENT( EV_RestoreVolume, idTarget_FadeSoundClass::Event_RestoreVolume )
1767 END_CLASS
1768 
1769 /*
1770 ================
1771 idTarget_FadeSoundClass::Event_Activate
1772 ================
1773 */
1774 void idTarget_FadeSoundClass::Event_Activate( idEntity *activator ) {
1775 	float fadeTime = spawnArgs.GetFloat( "fadeTime" );
1776 	float fadeDB = spawnArgs.GetFloat( "fadeDB" );
1777 	float fadeDuration = spawnArgs.GetFloat( "fadeDuration" );
1778 	int fadeClass = spawnArgs.GetInt( "fadeClass" );
1779 	// start any sound fading now
1780 	if ( fadeTime ) {
1781 		gameSoundWorld->FadeSoundClasses( fadeClass, spawnArgs.GetBool( "fadeIn" ) ? fadeDB : 0.0f - fadeDB, fadeTime );
1782 		if ( fadeDuration ) {
1783 			PostEventSec( &EV_RestoreVolume, fadeDuration );
1784 		}
1785 	}
1786 }
1787 
1788 /*
1789 ================
1790 idTarget_FadeSoundClass::Event_RestoreVolume
1791 ================
1792 */
Event_RestoreVolume()1793 void idTarget_FadeSoundClass::Event_RestoreVolume() {
1794 	float fadeTime = spawnArgs.GetFloat( "fadeTime" );
1795 	float fadeDB = spawnArgs.GetFloat( "fadeDB" );
1796 	// restore volume
1797 	gameSoundWorld->FadeSoundClasses( 0, fadeDB, fadeTime );
1798 }
1799