## Engine
Class PhysicsVolume

source: C:\XIII\Engine\Classes\PhysicsVolume.uc

    Core.Object
       |
       +--Engine.Actor
          |
          +--Engine.Brush
             |
             +--Engine.Volume
                |
                +--Engine.PhysicsVolume

Direct Known Subclasses:DefaultPhysicsVolume, LadderVolume, WaterVolume

class PhysicsVolume
extends Engine.Volume

    //=============================================================================
    // PhysicsVolume:  a bounding volume which affects actor physics
    // Each Actor is affected at any time by one PhysicsVolume
    // This is a built-in Unreal class and it shouldn't be modified.
    //=============================================================================

Variables
`float` | `DamagePerSec` Zone causes pain.
`class` | `DamageType` Zone causes pain.
`class` | `EntryActor` e.g. a splash (only if water zone)
`class` | `EntryNonPawnActor` e.g. a splash (only if water zone)
`sound` | `EntrySound` only if waterzone
`class` | `ExitActor` e.g. a splash (only if water zone)
`sound` | `ExitSound` only if waterzone
`float` | `FluidFriction` e.g. a splash (only if water zone)
`vector` | `Gravity` Zone causes pain.
`float` | `GroundFriction` Zone causes pain.
`int` | `Priority` determines which PhysicsVolume takes precedence if they overlap
`float` | `TerminalVelocity` Zone causes pain.
`ViewFlash,` | `ViewFog` e.g. a splash (only if water zone)
`float` | `WaterEffectIntensity` Activate the water effect.
`vector` | `ZoneVelocity` Zone causes pain.
`bool` | `bBounceVelocity` this velocity zone should bounce actors that land in it
`bool` | `bDestructive` Destroys most actors which enter it.
`bool` | `bMoveProjectiles` this velocity zone should impart velocity to projectiles and effects
`bool` | `bNeutralZone` Players can't take damage in this zone.
`bool` | `bNoInventory` Destroys most actors which enter it.
`bool` | `bPainCausing` Zone causes pain.
`bool` | `bSkipWaterRepulsion` Activate the water effect.
`bool` | `bWaterEffectIsOn` Activate the water effect.

Function Summary
`Emitter` | `BeingHitByBullets(vector HitLocation, rotator Orientation, int HitSoundType)`
`simulated` | `BeingHitByProjectile(vector HitLocation)`
    //FAB
`void` | `CausePainTo(Actor Other)`
`void` | `PlayEntrySplash(Actor Other)`
`void` | `PlayExitSplash(Actor Other)`
`void` | `PostBeginPlay()`
`void` | `TimerPop(VolumeTimer T)`
    /*
    TimerPop
    damage touched actors if pain causing.
    since PhysicsVolume is static, this function is actually called by a volumetimer
    */
`void` | `Trigger(Actor Other, Pawn EventInstigator)`

Source Code

    00001	//=============================================================================
    00002	// PhysicsVolume:  a bounding volume which affects actor physics
    00003	// Each Actor is affected at any time by one PhysicsVolume
    00004	// This is a built-in Unreal class and it shouldn't be modified.
    00005	//=============================================================================
    00006	class PhysicsVolume extends Volume
    00007		native
    00008		nativereplication;
    00009
    00010	var()		bool		bPainCausing;	 // Zone causes pain.
    00011	var()		vector		ZoneVelocity;
    00012	var()		vector		Gravity;
    00013	var()		float		GroundFriction;
    00014	var()		float		TerminalVelocity;
    00015	var()		float		DamagePerSec;
    00016	var() class<DamageType>	DamageType;
    00017	var()		int			Priority;	// determines which PhysicsVolume takes precedence if they overlap
    00018	var() sound  EntrySound;	//only if waterzone
    00019	var() sound  ExitSound;		// only if waterzone
    00020	var() class<actor> EntryActor;	// e.g. a splash (only if water zone)
    00021	var() class<actor> EntryNonPawnActor;	// e.g. a splash (only if water zone)
    00022	var() class<actor> ExitActor;	// e.g. a splash (only if water zone)
    00023	var() float  FluidFriction;
    00024	var() vector ViewFlash, ViewFog;
    00025
    00026	var()		bool	bDestructive; // Destroys most actors which enter it.
    00027	var()		bool	bNoInventory;
    00028	var()		bool	bMoveProjectiles;// this velocity zone should impart velocity to projectiles and effects
    00029	var()		bool	bBounceVelocity;	// this velocity zone should bounce actors that land in it
    00030	var()		bool	bNeutralZone; // Players can't take damage in this zone.
    00031	var			bool	bWaterVolume;
    00032	var()		bool	bWaterEffectIsOn; // Activate the water effect.
    00033	var()		bool	bSkipWaterRepulsion; // Activate the water effect.
    00034	var	Info PainTimer;
    00035
    00036	// Distance Fog
    00037	var(VolumeFog) bool   bDistanceFog;	// There is distance fog in this physicsvolume.
    00038	var(VolumeFog) color DistanceFogColor;
    00039	var(VolumeFog) float DistanceFogStart;
    00040	var(VolumeFog) float DistanceFogEnd;
    00041
    00042	var()		float WaterEffectIntensity;
    00043
    00044	function PostBeginPlay()
    00045	{
    00046		Super.PostBeginPlay();
    00047		if ( bPainCausing )
    00048			PainTimer = Spawn(class'VolumeTimer', self);
    00049	}
    00050
    00051	event ActorEnteredVolume(Actor Other);
    00052	event ActorLeavingVolume(Actor Other);
    00053
    00054	event PawnEnteredVolume(Pawn Other)
    00055	{
    00056		if ( Other.IsPlayerPawn() )
    00057			TriggerEvent(Event,Other, Other);
    00058	}
    00059
    00060	event PawnLeavingVolume(Pawn Other)
    00061	{
    00062		if ( Other.IsPlayerPawn() )
    00063			UntriggerEvent(Event,Other, Other);
    00064	}
    00065
    00066	/*
    00067	TimerPop
    00068	damage touched actors if pain causing.
    00069	since PhysicsVolume is static, this function is actually called by a volumetimer
    00070	*/
    00071	function TimerPop(VolumeTimer T)
    00072	{
    00073		local actor A;
    00074
    00075		if ( T == PainTimer )
    00076		{
    00077			if ( !bPainCausing )
    00078				return;
    00079
    00080			ForEach TouchingActors(class'Actor', A)
    00081				CausePainTo(A);
    00082		}
    00083	}
    00084
    00085	function Trigger( actor Other, pawn EventInstigator )
    00086	{
    00087		// turn zone damage on and off
    00088		if (DamagePerSec != 0)
    00089		{
    00090			bPainCausing = !bPainCausing;
    00091			if ( bPainCausing && (PainTimer == None) )
    00092				PainTimer = spawn(class'VolumeTimer', self);
    00093		}
    00094	}
    00095
    00096	event touch(Actor Other)
    00097	{
    00098	//    Log("VOLUME touched "$other);
    00099	    Super.Touch(Other);
    00100	    if ( bNoInventory && Other.IsA('Inventory') && (Other.Owner == None) )
    00101	    {
    00102	      Other.LifeSpan = 1.5;
    00103	      return;
    00104	    }
    00105	    if ( bMoveProjectiles && (ZoneVelocity != vect(0,0,0)) )
    00106	    {
    00107	      if ( Other.Physics == PHYS_Projectile )
    00108	        Other.Velocity += ZoneVelocity;
    00109	      else if ( Other.IsA('Effects') && (Other.Physics == PHYS_None) )
    00110	      {
    00111	        Other.SetPhysics(PHYS_Projectile);
    00112	        Other.Velocity += ZoneVelocity;
    00113	      }
    00114	    }
    00115	    if ( bPainCausing )
    00116	    {
    00117	      if ( Other.bDestroyInPainVolume )
    00118	      {
    00119	        Other.Destroy();
    00120	        return;
    00121	      }
    00122	      CausePainTo(Other);
    00123	    }
    00124	    if ( bWaterVolume && Other.CanSplash() )
    00125	    {
    00126	//      Log("Calling PlayEntrySplash EntryActor="$EntryActor);
    00127	      PlayEntrySplash(Other);
    00128	    }
    00129	}
    00130
    00131	function PlayEntrySplash(Actor Other)
    00132	{
    00133	    local float SplashSize;
    00134	    local actor splash;
    00135	    local vector HitLoc, HitNorm;
    00136	    local material HitMat;
    00137	    local Actor A;
    00138
    00139	    splashSize = FClamp(0.00003 * Other.Mass * (250 - 0.5 * FMax(-600,Other.Velocity.Z)), 0.1, 1.0 );
    00140	    if( EntrySound != None )
    00141	    {
    00142	      Other.PlaySound(EntrySound, vSize(Other.Velocity));
    00143	      if ( Other.Instigator != None )
    00144	        MakeNoise(SplashSize);
    00145	    }
    00146	//    Log("Splash other="$Other@"splashSize="$splashSize);
    00147	    if( EntryActor != None )
    00148	    {
    00149	      A = IntersectWaterPlane( Other.Location + vect(0,0,1)*(10+Other.CollisionHeight), Other.Location - vect(0,0,1)*(10+Other.CollisionHeight), HitLoc );
    00150	      if (A == self )
    00151	      {
    00152	        if ( Pawn(other) != none )
    00153	          splash = Spawn(EntryActor,,,HitLoc+vect(0,0,1), Other.rotation);
    00154	        else
    00155	          splash = Spawn(EntryNonPawnActor,,,HitLoc+vect(0,0,1), Other.rotation);
    00156	      }
    00157	/*
    00158	      ForEach Other.TraceActors(class'Actor', A, HitLoc, HitNorm, Other.Location - vect(0,0,1)*(10+Other.CollisionHeight), Other.Location + vect(0,0,1)*(10+Other.CollisionHeight))
    00159	      {
    00160	//      A = Other.trace(HitLoc, HitNorm, Other.Location - vect(0,0,1)*(10+Other.CollisionHeight), Other.Location + vect(0,0,1)*(10+Other.CollisionHeight), false, vect(0,0,0), HitMat, 0x008);
    00161	//        Log("Trace A="$A);
    00162	        if (A == self )
    00163	        {
    00164	          if ( pawn(other) != none )
    00165	          { // ::E3:: MOD, because we don't want splashes on SubMariners when they are generated
    00166	            if ( Pawn(Other).IsPlayerPawn() )
    00167	              splash = Spawn(EntryActor,,,HitLoc, Other.rotation);
    00168	          }
    00169	          else
    00170	            splash = Spawn(EntryNonPawnActor,,,HitLoc, Other.rotation);
    00171	//          Log("Splash spawning at HITLOC");
    00172	          break;
    00173	        }
    00174	*/
    00175	/*
    00176	        else
    00177	        {
    00178	          if ( pawn(other) != none )
    00179	            splash = Spawn(EntryActor,,,other.Location, Other.rotation);
    00180	          else
    00181	            splash = Spawn(EntryNonPawnActor,,,other.Location, Other.rotation);
    00182	//          Log("Splash spawning at ACTOR LOCATION");
    00183	        }
    00184	      }
    00185	*/
    00186	      if ( splash != None )
    00187	        splash.SetDrawScale(Other.CollisionRadius / 34);
    00188	    }
    00189	}
    00190
    00191	event untouch(Actor Other)
    00192	{
    00193		if ( bWaterVolume && Other.CanSplash() )
    00194			PlayExitSplash(Other);
    00195	}
    00196
    00197	function PlayExitSplash(Actor Other)
    00198	{
    00199	    local float SplashSize;
    00200	    local actor splash;
    00201	    local vector HitLoc, HitNorm;
    00202	    local material HitMat;
    00203	    local Actor A;
    00204
    00205	    splashSize = FClamp(0.003 * Other.Mass, 0.1, 1.0 );
    00206	    if( ExitSound != None )
    00207	      Other.PlaySound(ExitSound);
    00208	    if( ExitActor != None )
    00209	    {
    00210	      A = IntersectWaterPlane( Other.Location + vect(0,0,1)*(10+Other.CollisionHeight), Other.Location - vect(0,0,1)*(10+Other.CollisionHeight), HitLoc );
    00211	      if ( A == self )
    00212	        splash = Spawn(ExitActor,,,HitLoc+vect(0,0,1), Other.rotation);
    00213	/*
    00214	      ForEach Other.TraceActors(class'Actor', A, HitLoc, HitNorm, Other.Location - vect(0,0,1)*(10+Other.CollisionHeight), Other.Location + vect(0,0,1)*(10+Other.CollisionHeight))
    00215	      {
    00216	      //      A = Other.trace(HitLoc, HitNorm, Other.Location - vect(0,0,100)*(1+Other.CollisionHeight), Other.Location + vect(0,0,100)*(1+Other.CollisionHeight), false, vect(0,0,0), HitMat, 0x008);
    00217	      //      Log("Trace A="$A);
    00218	        if (A == self )
    00219	        {
    00220	          splash = Spawn(ExitActor,,,HitLoc, Other.rotation);
    00221	      //        Log("ExitSplash spawning at HITLOC");
    00222	        }
    00223	      }
    00224	*/
    00225	      if ( splash != None )
    00226	        splash.SetDrawScale(splashSize);
    00227	    }
    00228	}
    00229
    00230	function CausePainTo(Actor Other)
    00231	{
    00232		local float depth;
    00233		local Pawn P;
    00234
    00235		// FIXMEZONE figure out depth of actor, and base pain on that!!!
    00236		depth = 1;
    00237		P = Pawn(Other);
    00238
    00239		if ( DamagePerSec > 0 )
    00240		{
    00241			if ( (P != None) && (P.Controller != None) )
    00242				P.TakeDamage(int(DamagePerSec * depth), P, Location, vect(0,0,0), DamageType);
    00243			else
    00244			   Other.TakeDamage(int(DamagePerSec * depth), None, Location, vect(0,0,0), DamageType);
    00245
} 00246 else 00247 { 00248 if ( (P != None) && (P.Health < P.Default.Health) ) 00249 P.Health = Min(P.Default.Health, P.Health - depth * DamagePerSec); 00250 } 00251 } 00252 00253 /* Called when an actor in this PhysicsVolume changes its physics mode */ 00254 event PhysicsChangedFor(Actor Other); //FAB 00255 00256 00257 simulated function BeingHitByProjectile(vector HitLocation) 00258 { 00259 } 00260 00261 00262 function Emitter BeingHitByBullets(vector HitLocation, rotator Orientation, int HitSoundType) 00263 { 00264 return none; 00265 } 00266 00267 defaultproperties 00268 { 00269 Gravity=(Z=-950.000000) 00270 GroundFriction=8.000000 00271 TerminalVelocity=2500.000000 00272 FluidFriction=0.300000 00273 WaterEffectIntensity=1.000000 00274 bAlwaysRelevant=True 00275 }

End Source Code