484 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			484 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| #include maps\mp\_utility;
 | |
| #include common_scripts\utility;
 | |
| 
 | |
| main()
 | |
| {
 | |
| 	maps\mp\mp_flooded_precache::main();
 | |
| 	maps\createart\mp_flooded_art::main();
 | |
| 	maps\mp\mp_flooded_fx::main();
 | |
| 	maps\mp\_water::waterShallowFx();
 | |
| 	
 | |
| 	maps\mp\_load::main();
 | |
| 	
 | |
| 	maps\mp\_compass::setupMiniMap( "compass_map_mp_flooded" );
 | |
| 	
 | |
| 	setdvar( "r_lightGridEnableTweaks", 1 );
 | |
| 	setdvar( "r_lightGridIntensity", 1.33 );
 | |
| 
 | |
| 	// SimonT Fixed this script and commented it out as we don't know if we need it
 | |
| //	//Set bilinear mip for CurrentGen
 | |
| 	if ( !is_gen4() )
 | |
| 	{
 | |
| 		setdvar( "r_texFilterProbeBilinear", 1 );
 | |
| 	}
 | |
| 	
 | |
| 	if ( level.ps3 )
 | |
| 	{
 | |
| 		SetDvar( "sm_sunShadowScale", "0.55" ); // ps3 optimization
 | |
| 		SetDvar( "sm_sunsamplesizenear", ".15" );
 | |
| 	}
 | |
| 	else if ( level.xenon )
 | |
| 	{
 | |
| 		SetDvar( "sm_sunShadowScale", "0.85" ); //  optimization
 | |
| 		SetDvar( "sm_sunsamplesizenear", ".22" );
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		SetDvar( "sm_sunShadowScale", "0.9" ); // optimization
 | |
| 		SetDvar( "sm_sunsamplesizenear", ".27" );
 | |
| 	}
 | |
| 	
 | |
| 	setdvar( "r_lightGridEnableTweaks", 1 );
 | |
| 	setdvar( "r_lightGridIntensity", 1.33 );
 | |
| 	
 | |
| 	setdvar( "r_reactiveMotionWindAmplitudeScale", 1 );
 | |
| 	setdvar( "r_reactiveMotionWindAreaScale", 10);
 | |
| 	setdvar( "r_reactiveMotionWindDir", (0.3, -1, -.5) );
 | |
| 	setdvar( "r_reactiveMotionWindFrequencyScale", .25 );
 | |
| 	setdvar( "r_reactiveMotionWindStrength", 1 );
 | |
| 	
 | |
| 	game["attackers"] = "allies";
 | |
| 	game["defenders"] = "axis";
 | |
| 	
 | |
| 	maps\mp\_water::waterShallowInit( 205, 212 );
 | |
| 	
 | |
| 	movers = GetEntArray( "vehicle_movers", "targetname" );
 | |
| 	foreach ( moverTrigger in movers )
 | |
| 	{
 | |
| 		sinkingPlatform_Create( moverTrigger, 12, 12 );
 | |
| 	}
 | |
| 	
 | |
| 	level thread initExtraCollision();
 | |
| 	
 | |
| 	// moverCreate( "vehicle_floating" );
 | |
| }
 | |
| 
 | |
| initExtraCollision()
 | |
| {
 | |
| 	collision1 = GetEnt( "clip128x128x8", "targetname" );
 | |
| 	collision1Ent = spawn( "script_model", (1392, -584, 386) );
 | |
| 	collision1Ent.angles = ( 336, 0, 90);
 | |
| 	collision1Ent CloneBrushmodelToScriptmodel( collision1 );
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------
 | |
| // Sinking Platforms
 | |
| // A platform that lowers when a player stands on it;
 | |
| // returns to rest position when no one is on it.
 | |
| // trigger -> clip -> vehicle ent -> struct
 | |
| // todo: make sink rate proportional to # of people on the platform
 | |
| // ---------------------------------------------------------
 | |
| sinkingPlatform_Create( triggerEnt, sinkTime, riseTime )
 | |
| {
 | |
| 	// get the collision
 | |
| 	clip = GetEnt( triggerEnt.target, "targetname" );
 | |
| 	if ( !IsDefined( clip ) )
 | |
| 	{
 | |
| 		print( "Could not find clip named " + triggerEnt.target + "\n" );
 | |
| 		return;
 | |
| 	}
 | |
| 	
 | |
| 	// get the entity
 | |
| 	entName = clip.target;
 | |
| 	ent = GetEnt( entName, "targetname" );
 | |
| 	if ( !IsDefined( ent ) )
 | |
| 	{
 | |
| 		print( "Could not find entity named " + entName + "\n" );
 | |
| 		return;
 | |
| 	}
 | |
| 	
 | |
| 	ent.clip = clip;
 | |
| 	ent.trigger = triggerEnt;
 | |
| 	ent.clip.unresolved_collision_func = ::handleUnreslovedCollision;	// this prevents the bus from killing the player if you try to mantle onto th ebridge
 | |
| 	
 | |
| 	clip LinkTo( ent );
 | |
| 	
 | |
| 	// get path blockers
 | |
| 	pathBlock = GetEnt( ent.script_noteworthy, "targetname" );
 | |
| 	ent.pathBlock = pathBlock;
 | |
| 	ent thread sinkingPlatformEnablePathsOnStart();
 | |
| 	
 | |
| 	endStruct = getstruct( ent.target, "targetname" );
 | |
| 	if ( !IsDefined( endStruct ) )
 | |
| 	{
 | |
| 		print( "Could not find target struct named " + ent.target + "\n" );
 | |
| 		return;
 | |
| 	}
 | |
| 	ent.startPos = ent.origin;
 | |
| 	ent.startRot = ent.angles;
 | |
| 	
 | |
| 	ent.endPos = endStruct.origin;
 | |
| 	ent.endRot = endStruct.angles;
 | |
| 	
 | |
| 	moveDist = Distance( ent.endPos, ent.startPos);
 | |
| 	
 | |
| 	// these values are 1 / velocity so I can multiply future distances to derive moveTo times
 | |
| 	if ( IsDefined( endStruct.script_duration ) )
 | |
| 	{
 | |
| 		sinkTime = endStruct.script_duration;
 | |
| 	}
 | |
| 	
 | |
| 	if ( IsDefined( triggerEnt.script_duration ) )
 | |
| 	{
 | |
| 		riseTime = triggerEnt.script_duration;
 | |
| 	}
 | |
| 	
 | |
| 	ent.sinkRate = sinkTime / moveDist;
 | |
| 	ent.riseRate = riseTime / moveDist;
 | |
| 	
 | |
| 	// this array will track entities that enter the trigger
 | |
| 	ent.entsInTrigger = [];
 | |
| 	
 | |
| 	ent thread sinkingPlatform_WaitForEnter();
 | |
| 	
 | |
| 	return ent;
 | |
| }
 | |
| 
 | |
| sinkingPlatform_WaitForEnter()	// self == platform
 | |
| {
 | |
| 	level endon ( "game_ended" );
 | |
| 	
 | |
| 	while ( true )
 | |
| 	{
 | |
| 		self.trigger waittill( "trigger", other );
 | |
| 		
 | |
| 		if ( self canEntTriggerPlatform( other ) && isReallyAlive( other ) )
 | |
| 		{
 | |
| 			self.entsInTrigger[ other GetEntityNumber() ] = other;
 | |
| 			
 | |
| 			// update sink rate
 | |
| 			
 | |
| 			curSize = self.entsInTrigger.size;
 | |
| 			if ( curSize == 1 )
 | |
| 			{
 | |
| 				self sinkingPlatform_Start();
 | |
| 			}
 | |
| 			else if ( !IsDefined( self.reachedBottom ) )
 | |
| 			{
 | |
| 				// print( " ~* Extra body, increasing speed! " + curSize );
 | |
| 				self updateSinkRate( curSize );
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| kMIN_ACCEL = 0.5;
 | |
| sinkingPlatform_Start()	// self == platform
 | |
| {
 | |
| 	self notify("platform_sink");
 | |
| 	
 | |
| 	t = Distance( self.endPos, self.origin ) * self.sinkRate;
 | |
| 	
 | |
| 	minAccel = min( 0.5 * t, kMIN_ACCEL );
 | |
| 	
 | |
| 	self MoveTo( self.endPos, t, minAccel, minAccel );
 | |
| 	self RotateTo( self.endRot, t, minAccel, minAccel );
 | |
| 	
 | |
| 	// self sinkingPlatformDisablePaths();
 | |
| 	
 | |
| 	self thread sinkingPlatformPlaySfxSequence( "scn_car_sinking_down_start",
 | |
| 				  "scn_car_sinking_down_loop",
 | |
| 				  "scn_car_sinking_down_end",
 | |
| 				  1,
 | |
| 				  0.25,
 | |
| 				  t
 | |
| 				 );
 | |
| 	
 | |
| 	self thread sinkingPlatform_WaitForExit();
 | |
| 	self thread sinkingPlatform_WaitForReachedBottom();
 | |
| }
 | |
| 
 | |
| sinkingPlatform_WaitForExit()	// self == platform
 | |
| {
 | |
| 	level endon ( "game_ended" );
 | |
| 	
 | |
| 	while ( self.entsInTrigger.size > 0 )
 | |
| 	{
 | |
| 		wait ( 0.1 );
 | |
| 		
 | |
| 		startSize = self.entsInTrigger.size;
 | |
| 		
 | |
| 		foreach ( index, player in self.entsInTrigger )
 | |
| 		{
 | |
| 			if	(	!IsDefined( player )
 | |
| 			    ||	!(player IsTouching( self.trigger ) )
 | |
| 			    ||	!isReallyAlive( player )
 | |
| 				)
 | |
| 			{
 | |
| 				self.entsInTrigger[ index ] = undefined;
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		if ( !IsDefined( self.reachedBottom ) )
 | |
| 		{
 | |
| 			curSize = self.entsInTrigger.size;
 | |
| 			if ( curSize > 0 && curSize != startSize )
 | |
| 			{
 | |
| 				self updateSinkRate( curSize );
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	self sinkingPlatform_Return();
 | |
| }
 | |
| 
 | |
| sinkingPlatform_WaitForReachedBottom()	// self == platform
 | |
| {
 | |
| 	level endon ( "game_ended" );
 | |
| 	self endon ( "platform_return" );
 | |
| 	
 | |
| 	self waittill( "movedone" );
 | |
| 	
 | |
| 	self.reachedBottom = true;
 | |
| 	
 | |
| 	// self sinkingPlatformEnablePaths();
 | |
| }
 | |
| 
 | |
| sinkingPlatform_WaitForReachedTop()
 | |
| {
 | |
| 	level endon ( "game_ended" );
 | |
| 	self endon ( "platform_sink" );
 | |
| 	
 | |
| 	self waittill( "movedone" );
 | |
| 	
 | |
| 	//self sinkingPlatformEnablePaths();	
 | |
| }
 | |
| 
 | |
| sinkingPlatform_Return()	// self == platform
 | |
| {
 | |
| 	self notify ( "platform_return" );
 | |
| 	self.reachedBottom = undefined;
 | |
| 	
 | |
| 	//self sinkingPlatformDisablePaths();
 | |
| 	
 | |
| 	t = Distance( self.startPos, self.origin ) * self.riseRate;
 | |
| 	
 | |
| 	minAccel = min( 0.5 * t, kMIN_ACCEL );
 | |
| 	
 | |
| 	self MoveTo( self.startPos, t, minAccel, minAccel );
 | |
| 	self RotateTo( self.startRot, t, minAccel, minAccel );
 | |
| 	
 | |
| 	// self thread sinkingPlatform_WaitForEnter();
 | |
| 	
 | |
| 	self thread sinkingPlatformPlaySfxSequence( "scn_car_floating_up_start",
 | |
| 				  "scn_car_floating_up_loop",
 | |
| 				  "scn_car_floating_up_end",
 | |
| 				  .5,
 | |
| 				  0.25,
 | |
| 				  t
 | |
| 				 );
 | |
| 	
 | |
| 	self thread sinkingPlatform_WaitForReachedTop();
 | |
| }
 | |
| 
 | |
| canEntTriggerPlatform( other )	// self == platform
 | |
| {
 | |
| 	// we only want humans
 | |
| 	return ( (IsPlayer( other ) || ( IsAgent( other ) && IsDefined( other.agent_type ) && other.agent_type != "dog" ))
 | |
| 		    && !IsDefined( self.entsInTrigger[ other GetEntityNumber() ] )
 | |
| 		   );
 | |
| }
 | |
| 
 | |
| updateSinkRate( numBodies )	// self == platform
 | |
| {
 | |
| 	t = Distance( self.endPos, self.origin ) * self.sinkRate;
 | |
| 	t /= numBodies;
 | |
| 	
 | |
| 	if ( t > 0 )
 | |
| 	{
 | |
| 		minAccel = min( 0.5 * t, kMIN_ACCEL );
 | |
| 	
 | |
| 		self.clip MoveTo( self.endPos, t, minAccel, minAccel );
 | |
| 		self.clip RotateTo( self.endRot, t, minAccel, minAccel );
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		print( "Error! t = " + t * numBodies + " bodies: " + numBodies + "\n" );
 | |
| 	}
 | |
| }
 | |
| 
 | |
| sinkingPlatformPlaySfxSequence( startSfx, loopSfx, endSfx, startTime, endTime, totalTime )
 | |
| {
 | |
| 	// clean up previous sounds
 | |
| 	self notify("stopSinkingSfx");
 | |
| 	self StopSounds();
 | |
| 	self StopLoopSound();
 | |
| 	
 | |
| 	self endon("stopSinkingSfx");
 | |
| 	
 | |
| 	self PlaySound(startSfx);
 | |
| 	wait (startTime);
 | |
| 	
 | |
| 	actualLoopTime = totalTime - startTime - endTime;
 | |
| 	
 | |
| 	if (actualLoopTime > 0)
 | |
| 	{
 | |
| 		self PlayLoopSound(loopSfx);
 | |
| 		wait (actualLoopTime);
 | |
| 		self StopLoopSound();
 | |
| 	}
 | |
| 	
 | |
| 	self PlaySound( endSfx );
 | |
| }
 | |
| 
 | |
| sinkingPlatformEnablePathsOnStart()
 | |
| {
 | |
| 	wait (0.1);
 | |
| 	self sinkingPlatformEnablePaths();
 | |
| }
 | |
| 
 | |
| sinkingPlatformEnablePaths()
 | |
| {
 | |
| 	if ( IsDefined( self.pathBlock ) )
 | |
| 	{
 | |
| 		self.pathBlock ConnectPaths();
 | |
| 		self.pathBlock Hide();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| sinkingPlatformDisablePaths()
 | |
| {
 | |
| 	if ( IsDefined( self.pathBlock ) )
 | |
| 	{
 | |
| 		self.pathBlock Show();
 | |
| 		self.pathBlock DisconnectPaths();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // ---------------------------------------------------------
 | |
| // Movers
 | |
| // One-off moving platforms that players can use
 | |
| // ex: the truck that players can kick and let drift downstream
 | |
| // ---------------------------------------------------------
 | |
| moverCreate( triggerName )
 | |
| {
 | |
| 	// get trigger
 | |
| 	trigger = GetEnt( triggerName, "targetname" );
 | |
| 	if ( !IsDefined( trigger ) )
 | |
| 	{
 | |
| 		print( "Could not find trigger named " + triggerName + "\n" );
 | |
| 		return;
 | |
| 	}
 | |
| 	
 | |
| 	// get the brush
 | |
| 	clip = GetEnt( trigger.target, "targetname" );
 | |
| 	if ( !IsDefined( clip ) )
 | |
| 	{
 | |
| 		print( "Could not find brush named " + trigger.target + "\n" );
 | |
| 		return;
 | |
| 	}
 | |
| 	
 | |
| 	// get the model
 | |
| 	ent = GetEnt( clip.target, "targetname" );
 | |
| 	if ( !IsDefined( ent ) )
 | |
| 	{
 | |
| 		print( "Could not find entity named " + clip.target + "\n" );
 | |
| 		return;
 | |
| 	}
 | |
| 	ent.trigger = trigger;
 | |
| 	ent.clip = clip;
 | |
| 	
 | |
| 	clip LinkTo( ent );
 | |
| 	
 | |
| 	// get the positions
 | |
| 	ent.keyframes = [];
 | |
| 	keyframeName = ent.target;
 | |
| 	i = 0;
 | |
| 	while ( IsDefined( keyframeName ) )
 | |
| 	{
 | |
| 		struct = getstruct( keyframeName, "targetname" );
 | |
| 		if ( IsDefined( struct ) )
 | |
| 		{
 | |
| 			if ( !IsDefined( struct.script_duration ) )
 | |
| 			{
 | |
| 				print( "Keyframe " + keyframeName + " is missing a script_duration value!\n" );
 | |
| 				struct.script_duration = 6;
 | |
| 			}
 | |
| 			
 | |
| 			if ( !IsDefined( struct.script_accel) )
 | |
| 			{
 | |
| 				struct.script_accel = 0.5 * struct.script_duration;
 | |
| 			}
 | |
| 			
 | |
| 			if ( !IsDefined( struct.script_decel ) )
 | |
| 			{
 | |
| 				struct.script_decel = 0.25 * struct.script_duration;
 | |
| 			}
 | |
| 			
 | |
| 			struct.clipAngles = struct.angles - ent.angles + clip.angles;
 | |
| 			
 | |
| 			ent.keyframes[i] = struct;
 | |
| 			
 | |
| 			i++;
 | |
| 			keyframeName = struct.target;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	// setup trigger
 | |
| 	ent.trigger SetHintString( &"PLATFORM_HOLD_TO_USE" );
 | |
| 	ent.trigger MakeUsable();
 | |
| 	ent thread moverWaitForUse();
 | |
| 	
 | |
| 	return ent;
 | |
| }
 | |
| 
 | |
| moverWaitForUse()	// self == mover entity
 | |
| {
 | |
| 	level endon ( "game_ended" );
 | |
| 	
 | |
| 	self.trigger waittill( "trigger" );
 | |
| 	
 | |
| 	self.trigger MakeUnusable();
 | |
| 	
 | |
| 	// trigger has been used
 | |
| 	
 | |
| 	// play sound
 | |
| 	
 | |
| 	// play animation
 | |
| 	self moverDoMove();
 | |
| }
 | |
| 
 | |
| moverDoMove()	// self == mover entity
 | |
| {
 | |
| 	level endon ( "game_ended" );
 | |
| 	
 | |
| 	for ( i = 0; i < self.keyframes.size; i++ )
 | |
| 	{
 | |
| 		kf = self.keyframes[i];
 | |
| 		
 | |
| 		self MoveTo( kf.origin, kf.script_duration, kf.script_accel, kf.script_decel );
 | |
| 		self RotateTo( kf.angles, kf.script_duration, kf.script_accel, kf.script_decel );
 | |
| 		
 | |
| 		self waittill( "movedone" );
 | |
| 		
 | |
| 		if ( IsDefined( kf.script_delay ) )
 | |
| 		{
 | |
| 			wait( kf.script_delay );
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	// play another sound?
 | |
| 	
 | |
| 	// shake?
 | |
| }
 | |
| 
 | |
| handleUnreslovedCollision( hitEnt )	// self == mover, hitEnt == player (usually)
 | |
| {
 | |
| 	// return;
 | |
| 	
 | |
| 	// hitEnt DoDamage( 1000, hitEnt.origin, self, self, "MOD_CRUSH" );
 | |
| } |