XIII
Class XIIIProjectile

source: C:\XIII\XIII\Classes\XIIIProjectile.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Projectile
         |
         +--XIII.XIIIProjectile
Direct Known Subclasses:USA02HelicoMissile, AshTrayFlying, BazookRocket, Bolt, BottleFlying, BrikFlying, BulletTraces, DartFlying, GrenadFlying, HarponFlying, HookProjectile, M16GrenadFlying, PhoneFlying, ShardFlying, TKnifeFlying, WBallFlying, FlashBangFlying, MPBombFlying

class XIIIProjectile
extends Engine.Projectile

//----------------------------------------------------------- // //-----------------------------------------------------------
Variables
 class ExplosionEmitterClass
           Memorize water entry to (maybe) spawn water surface explosion
 int HitSoundType
           Type of sound vs type of impact
 class ImpactEmitterMem
           Should be spawned & init() in child classes (because spec inits needed).
 float ImpactNoise
           Noise made by the Projectile when hitting something
 class InHeadClass
           Type of sound vs type of impact
 Trail MyTrail
           Should be spawned & init() in child classes (because spec inits needed).
 class MyTrailClass
           Type of sound vs type of impact
 vector OrgFrom
           used for shakes on blowup
 float ShakeCycles
           used for shakes on blowup
 float ShakeMag
           used for shakes on blowup
 vector ShakeSpeed
           used for shakes on blowup
 float ShakeTime
           used for shakes on blowup
 vector ShakeVert
           used for shakes on blowup
 float SoftImpactNoise
           Noise made by the Projectile when hitting someone
 string StaticMeshName
           to dynamicload it
 class aVisualImpact
           Type of sound vs type of impact
 bool bHaveBlownUp
           if true spawn ExplosionDecal else spawn VisualImpact
 bool bSpawnDecal
           if true spawn ExplosionDecal else spawn VisualImpact
 bool bSplashed
           if true spawn ExplosionDecal else spawn VisualImpact
 sound hExploSound
           Type of sound vs type of impact
 int iStunning
           projectile stun if HeadShot, no damage else (not bool because bool don't work as function params on GC)
 vector vWaterEntry
           Memorize water entry to (maybe) spawn water surface explosion


Function Summary
 
simulated
BlowUp(vector HitLocation)
     
//_____________________________________________________________________________
 bool CanSplash()
     
//_____________________________________________________________________________
 DamageLocations GetPotentialDamageLocation(XIIIPawn P, vector HitLoc, vector HitDir)
     
//_____________________________________________________________________________
// ELR CheckDamageLocation, used by projectiles
 
simulated
HitWall(vector HitNormal, Actor Wall)
     
//_____________________________________________________________________________
 
simulated
PlayImpactSound(vector Normal, Actor Wall)
     
//_____________________________________________________________________________
 
simulated
ProcessTouch(Actor Other, Vector HitLocation)
     
//_____________________________________________________________________________
// Override ProcessTouch
 void SetImpactNoise(float IN1, float IN2)
     
//_____________________________________________________________________________
 
simulated
SetUpImpactEmitter(Sound S)
     
//_____________________________________________________________________________
 
simulated
SpawnWaterExplo(vector HitLocation)
     
//_____________________________________________________________________________
// Generic water surface explosion SFX
 void StaticParseDynamicLoading(LevelInfo MyLI)
     
//_____________________________________________________________________________
 void Touch(Actor Other)
     
//_____________________________________________________________________________
// Touching



Source Code


00001	//-----------------------------------------------------------
00002	//
00003	//-----------------------------------------------------------
00004	class XIIIProjectile extends Projectile;
00005	
00006	var bool bSpawnDecal;         // if true spawn ExplosionDecal else spawn VisualImpact
00007	var bool bHaveBlownUp;
00008	var bool bSplashed;
00009	
00010	enum DamageLocations
00011	{
00012	    LOC_Head,
00013	    LOC_Body,
00014	    LOC_HeadSide,
00015	};
00016	
00017	var float ImpactNoise;        // Noise made by the Projectile when hitting something
00018	var float SoftImpactNoise;    // Noise made by the Projectile when hitting someone
00019	var int HitSoundType;         // Type of sound vs type of impact
00020	// 0 = bullet
00021	// 1 = Fists
00022	// 2 = CommandoKnife UNUSED
00023	// 3 = Bolt/Harpon
00024	// 4 = Grenade bounce
00025	// 5 = TKnife
00026	var class<Effects> aVisualImpact;
00027	var sound hExploSound;
00028	var class<ProjectileInHead> InHeadClass;
00029	var class<Trail> MyTrailClass;
00030	var Trail MyTrail;            // Should be spawned & init() in child classes (because spec inits needed).
00031	var class<ImpactEmitter> ImpactEmitterMem;
00032	var string StaticMeshName;    // to dynamicload it
00033	
00034	var float ShakeMag;           // used for shakes on blowup
00035	var float ShakeTime;
00036	var vector ShakeVert;
00037	var vector ShakeSpeed;
00038	var float ShakeCycles;
00039	var vector OrgFrom;
00040	var vector vWaterEntry;       // Memorize water entry to (maybe) spawn water surface explosion
00041	
00042	var config class<Emitter> ExplosionEmitterClass;
00043	
00044	var int iStunning;            // projectile stun if HeadShot, no damage else (not bool because bool don't work as function params on GC)
00045	
00046	CONST DBProj=false;
00047	
00048	//_____________________________________________________________________________
00049	Static function StaticParseDynamicLoading(LevelInfo MyLI)
00050	{
00051	    Log("XIIIProjectile StaticParseDynamicLoading class="$default.class);
00052	    if ( default.StaticMeshName != "" )
00053	      MyLI.ForcedStaticMeshes[MyLI.ForcedStaticMeshes.Length] =
00054	        StaticMesh(DynamicLoadObject(default.StaticMeshName, class'StaticMesh'));
00055	}
00056	
00057	//_____________________________________________________________________________
00058	simulated event PostBeginPlay()
00059	{
00060	    Super.PostBeginPlay();
00061	    if ( (StaticMesh == none) && (StaticMeshName != "") )
00062	    {
00063	      StaticMesh = StaticMesh(dynamicloadobject(StaticMeshName, class'StaticMesh'));
00064	      default.StaticMesh = StaticMesh;
00065	      SetDrawType(DT_StaticMesh);
00066	//      Log("PostBeginPlay DYNAMICLOAD StaticMesh "$StaticMeshName@"result "$StaticMesh);
00067	    }
00068	    vWaterEntry = Location;
00069	    OrgFrom = Location;
00070	    if ( (Instigator != none) && (Instigator.Base != none) && (Instigator.Base.Velocity != vect(0,0,0)) )
00071	      SetBase(Instigator.Base);
00072	}
00073	
00074	//_____________________________________________________________________________
00075	event Timer2()
00076	{ // FIXME cheat to make complex staticmesh movers (like elevators) work
00077	    Touching.Length = 0;
00078	}
00079	
00080	//_____________________________________________________________________________
00081	// Touching
00082	simulated singular function Touch(Actor Other)
00083	{
00084	    local actor HitActor;
00085	    local vector HitLocation, HitNormal, VelDir;
00086	    local bool bBeyondOther;
00087	    local float BackDist, DirZ;
00088	    local material HitMat;
00089	    local staticMeshActor SMA;
00090	    local VehicleDeco VHD;
00091	    local Mover Mov;
00092	    local int i;
00093	
00094	    if ( Other == Instigator )
00095	      return;
00096	    if ( DBProj ) Log("PROJ"@self@"Touched "$Other);
00097	    if ( Velocity == vect(0,0,0) )
00098	    {
00099	      if ( DBProj ) Log("  Touched cancelled because null velocity");
00100	      return;
00101	    }
00102	
00103	    if ( StaticMeshActor(Other) != none )
00104	    { // touching a staticmeshactor that is not bWorldGeometry, Get exact hit location
00105	      if ( DBProj ) Log("  Is StaticMeshActor");
00106	      SetTimer2(0.02, false); // to clean touching list later;
00107	      foreach TraceActors(class'StaticMeshActor', SMA, HitLocation, HitNormal, Location + Velocity*0.1, Location - Velocity*0.1, vect(0,0,0), TRACETYPE_DiscardIfCanShootThroughWithProjectileWeapon)
00108	      {
00109	        if (SMA == Other)
00110	        {
00111	          SetLocation(HitLocation);
00112	//          Log("--> proj Other="$other$" HitActor="$SMA$" Location="$Location@"hitLocation="$HitLocation);
00113	          HitWall(HitNormal, Other);
00114	          return;
00115	        }
00116	      }
00117	      HitWall(-vector(rotation), other);
00118	      // Remove other from touching list ::TODO:: Hum Hum check if this is not too dirty & may cause crash for a reason or another
00119	      return;
00120	    }
00121	    else if ( VehicleDeco(Other) != none )
00122	    { // touching a staticmeshactor that is not bWorldGeometry, Get exact hit location
00123	      if ( DBProj ) Log("  Is VehicleDeco");
00124	      SetTimer2(0.02, false); // to clean touching list later;
00125	      foreach TraceActors(class'VehicleDeco', VHD, HitLocation, HitNormal, Location + Velocity*0.1, Location - Velocity*0.1, vect(0,0,0), TRACETYPE_DiscardIfCanShootThroughWithProjectileWeapon)
00126	      {
00127	        if (VHD == Other)
00128	        {
00129	          SetLocation(HitLocation);
00130	//          Log("--> proj Other="$other$" HitActor="$VHD$" Location="$Location@"hitLocation="$HitLocation@"Normal="@HitNormal);
00131	          HitWall(HitNormal, Other);
00132	          return;
00133	        }
00134	      }
00135	      HitWall(-vector(rotation), other);
00136	      // Remove other from touching list ::TODO:: Hum Hum check if this is not too dirty & may cause crash for a reason or another
00137	      return;
00138	    }
00139	    else if ( Mover(Other) != none )
00140	    {
00141	      if ( DBProj ) Log("  Is Mover");
00142	      SetTimer2(0.02, false); // to clean touching list later;
00143	      foreach TraceActors(class'Mover', Mov, HitLocation, HitNormal, Location + Velocity*0.1, Location - Velocity*0.1, vect(0,0,0), TRACETYPE_DiscardIfCanShootThroughWithProjectileWeapon)
00144	      {
00145	        if ( (Mov == Other) && (HitNormal dot Velocity < 0.0) )
00146	        {
00147	//          Log("--> proj Other="$other$" HitActor="$SMA$" Location="$Location@"hitLocation="$HitLocation);
00148	          SetLocation(HitLocation + HitNormal*2.0);
00149	          HitWall(HitNormal, Other);
00150	          return;
00151	        }
00152	      }
00153	      HitWall(-vector(rotation), other);
00154	      // Remove other from touching list ::TODO:: Hum Hum check if this is not too dirty & may cause crash for a reason or another
00155	      return;
00156	    }
00157	
00158	    if ( Other.bProjTarget || (Other.bBlockActors && Other.bBlockPlayers) )
00159	    {
00160	      if ( Velocity == vect(0,0,0) )
00161	      {
00162	        ProcessTouch(Other,Location);
00163	        return;
00164	      }
00165	
00166	      //get exact hitlocation - trace back along velocity vector
00167	      bBeyondOther = ( (Velocity dot (Location - Other.Location)) > 0 );
00168	//      Log("--> proj bBeyondOther="$bBeyondOther);
00169	      VelDir = Normal(Velocity);
00170	      DirZ = sqrt(abs(VelDir.Z));
00171	//      Log("-->  Other="$other@"ColRad="$Other.CollisionRadius@"ColHei="$Other.CollisionHeight@"VelDir="$VelDir@"DirZ="$DirZ);
00172	      BackDist = Other.CollisionRadius * (1 - DirZ) + Other.CollisionHeight * DirZ;
00173	//      Log("-->  1rst BackDist="$BackDist);
00174	
00175	
00176	      if ( bBeyondOther )
00177	        BackDist += VSize(Location - Other.Location);
00178	      else
00179	        BackDist -= VSize(Location - Other.Location);
00180	//      Log("-->  2nd BackDist="$BackDist);
00181	
00182	      HitActor = Trace(HitLocation, HitNormal, Location, Location - 1.1 * BackDist * VelDir, true, vect(0,0,0), HitMat, TRACETYPE_DiscardIfCanShootThroughWithProjectileWeapon);
00183	//      Log("--> proj HitActor="$HitActor$" Location="$Location@"hitLocation="$HitLocation@"BackDist="$BackDist);
00184	      if (HitActor == Other)
00185	        ProcessTouch(Other, HitLocation);
00186	      else if ( bBeyondOther )
00187	// ELR It seem like this code mess up the hitLocation if bBeyondOther=true (as we do have localized damages)
00188	//        ProcessTouch(Other, Other.Location - Other.CollisionRadius * VelDir);
00189	        ProcessTouch(Other, Location - 2.0 * Other.CollisionRadius * VelDir);
00190	      else
00191	        ProcessTouch(Other, Location);
00192	    }
00193	}
00194	
00195	//_____________________________________________________________________________
00196	// Override ProcessTouch
00197	simulated function ProcessTouch(Actor Other, Vector HitLocation)
00198	{
00199	    local int Loc;
00200	    Local bool bSpawnHeadProj;
00201	    local ProjectileInHead PIH;
00202	
00203	    if ( DBProj ) Log("PROJ"@self@"ProcessTouch"@other@"iStunning="$iStunning);
00204	    if ( Other != Instigator )
00205	    {
00206	      if ( XIIIPawn(Other) != none )
00207	      {
00208	        if ( Velocity != vect(0,0,0) )
00209	          Loc = GetPotentialDamageLocation( XIIIPawn(Other), HitLocation, Velocity);
00210	        else
00211	          Loc = GetPotentialDamageLocation( XIIIPawn(Other), HitLocation, vector(rotation) );
00212	      }
00213	//      Log("  >"@self@"ProcessTouch LOC="@Loc);
00214	      if ( iStunning > 0 )
00215	      {
00216	        if ( Loc == 1 )
00217	        {
00218	//          Log("  >"@self@" No damages, Body hit");
00219	          Explode(HitLocation,Normal(HitLocation-Other.Location));
00220	          if ( Pawn(Other) != none )
00221	            MakeNoise(SoftImpactNoise);
00222	          else
00223	            MakeNoise(ImpactNoise);
00224	          return;
00225	        }
00226	//        else
00227	//          Log("  >"@self@" Damages, Head hit");
00228	      }
00229	      if ( DBProj ) Log("  > "$self$" ProcessTouch other="$other$" Loc="$Loc$" HitLocation="$HitLocation);
00230	      if ( Loc <= 1 )
00231	      {
00232	        if ( (Pawn(Other) != none) &&  !Pawn(Other).bIsDead )
00233	          bSpawnHeadProj = true; // Only spawn once & at first time
00234	        Other.TakeDamage(Damage, Instigator, HitLocation, -MomentumTransfer * normal(velocity), MyDamageType);
00235	        Explode(HitLocation,Normal(HitLocation-Other.Location));
00236	        if ( (Pawn(Other) != none) && (Level.Game != none) && (Level.Game.GoreLevel == 0) )
00237	        {
00238	          if ( (Loc == 0) && bSpawnHeadProj && Pawn(Other).bIsDead && (InHeadClass != none) )
00239	          {
00240	            PIH = Spawn(InHeadClass,Other,,HitLocation, Rotation);
00241	            PIH.StaticMesh = StaticMesh;
00242	          }
00243	          Spawn(class'XIIIDamageType'.default.BloodShotEmitterClass,,, HitLocation, Rotator(normal(HitLocation-Other.Location)));
00244	        }
00245	        if ( Pawn(Other) != none )
00246	          MakeNoise(SoftImpactNoise);
00247	        else
00248	          MakeNoise(ImpactNoise);
00249	      }
00250	      // else do nothing, keep the projectile going
00251	    }
00252	}
00253	
00254	//_____________________________________________________________________________
00255	// ELR CheckDamageLocation, used by projectiles
00256	function DamageLocations GetPotentialDamageLocation( XIIIPawn P, vector HitLoc , vector HitDir)
00257	{
00258	    // Inspired from DX (Thanx to the scripter that gave the offset formula to a newB:)
00259	    local Vector offset, HitLoc2, HitNorm2, StartTrace, EndTrace;
00260	    local float headOffsetZ;
00261	    local Actor A;
00262	    local material HitMat;
00263	
00264	    if ( P.bIsDead ) return LOC_Body;
00265	    P.LastBoneHit='';
00266	
00267	    // Use the hitlocation to determine where the pawn is hit
00268	    // Transform the worldspace hitlocation into objectspace
00269	    // In objectspace, X is front to back Y is side to side, and Z is top to bottom
00270	    offset = (HitLoc - P.Location) << P.Rotation;
00271	    headOffsetZ = P.CollisionHeight * 0.65;
00272	
00273	    if ( (iStunning > 0) || (P.IsPlayerPawn() && Level.bLonePlayer) )
00274	    { // ELR Cheat to optimize (no call to foreach trace) when several enemies
00275	      //  are shooting the player in solo game
00276	//      Log("GetPotentialDamageLocation Offset="$Offset.z / P.CollisionHeight);
00277	      if ( Offset.Z > P.CollisionHeight * 0.7 )
00278	        return LOC_Head;
00279	      else
00280	        return LOC_Body;
00281	    }
00282	
00283	    StartTrace = HitLoc - normal(HitDir)*P.CollisionRadius*2.0;
00284	    EndTrace = HitLoc + normal(HitDir)*P.CollisionRadius*2.0;
00285	//    Log("P.Location="$P.Location@"HitLoc="$HitLoc@"HitDir="$HitDir@"StartTRace="$StartTrace@"EndTrace="$EndTrace);
00286	    foreach TraceActors(class'Actor', A, HitLoc2, HitNorm2, EndTrace, StartTrace, vect(0,0,0), TRACETYPE_RequestBones)
00287	    {
00288	//      Log(P@"testing actor "$A);
00289	      if ( A == P )
00290	      {
00291	/*
00292	        StartTrace = HitLoc - normal(HitDir)*P.CollisionRadius*2.0;
00293	        EndTrace = HitLoc + normal(HitDir)*P.CollisionRadius*2.0;
00294	        A = Trace(HitLoc2, HitNorm2, HitLoc2 - HitNorm2*P.CollisionRadius*2, HitLoc2 + HitNorm2, True, vect(0,0,0), HitMat, TRACETYPE_RequestBones);
00295	*/
00296	        P.LastBoneHit = GetLastTraceBone();
00297	//        Log(">>> Potential Bone ="$P.LastBoneHit);
00298	        if ( P.LastBoneHit == 'X Head' )
00299	          return LOC_Head;
00300	      }
00301	    }
00302	
00303	    if ( Offset.Z > HeadOffsetZ )
00304	      return LOC_HeadSide;
00305	    else
00306	      return LOC_Body;
00307	}
00308	
00309	//_____________________________________________________________________________
00310	function SetImpactNoise(float IN1, float IN2)
00311	{
00312	    SoftImpactNoise = IN1;
00313	    ImpactNoise = IN2;
00314	}
00315	
00316	//_____________________________________________________________________________
00317	simulated function BlowUp(vector HitLocation)
00318	{
00319	    local XIIIPlayerPawn Victims;
00320	    local vector HitLoc;
00321	
00322	    if ( bHaveBlownUp )
00323	      return;
00324	
00325	    bHaveBlownUp=true;
00326	//    Log(self$" blowing up w/ MomentumTransfer="$MomentumTransfer);
00327	
00328	    if ( Instigator == none )
00329	      Instigator = Pawn(Owner);
00330	
00331	    HurtRadius(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation );
00332	    if ( ShakeTime != 0 )
00333	    {
00334	    	foreach RadiusActors( class 'XIIIPlayerPawn', Victims, DamageRadius*0.5, HitLoc )
00335	    	{
00336	        PlayerController(Victims.Controller).ShakeView(ShakeTime, ShakeMag, ShakeVert, 120000, ShakeSpeed, ShakeCycles);
00337	    	}
00338	    }
00339	
00340	    if ( Role == ROLE_Authority )
00341	      MakeNoise(ImpactNoise);
00342	    PlaySound(hExploSound,0,1,2);
00343	}
00344	
00345	//_____________________________________________________________________________
00346	simulated function HitWall(vector HitNormal, actor Wall)
00347	{
00348	    if ( DBProj ) Log("PROJ"@self@"HitWall"@Wall@"Normal="$HitNormal);
00349	
00350	    if ( Role == ROLE_Authority )
00351	    {
00352	      if ( Mover(Wall) != None )
00353	        Wall.TakeDamage( Damage, instigator, Location, MomentumTransfer * Normal(Velocity), MyDamageType);
00354	      MakeNoise(ImpactNoise);
00355	    }
00356	//    PlayImpactSound(HitNormal, Wall);
00357	    PlayImpactSound(-vector(rotation), Wall);
00358	
00359	    Explode(Location + ExploWallOut * HitNormal, HitNormal);
00360	
00361	    if ( (Mover(Wall) == None) && !Wall.bMovable )
00362	    {
00363	      if ( bSpawnDecal && (ExplosionDecal != None) && (Level.NetMode != NM_DedicatedServer) )
00364	        Spawn(ExplosionDecal,self,,Location, rotator(-HitNormal));
00365	      else if ( !bSpawnDecal && (aVisualImpact != None) && (Level.NetMode != NM_DedicatedServer) )
00366	        Spawn(aVisualImpact,self,,Location+0.1*HitNormal, rotator( (vector(rotation)*2.0-HitNormal)/3.0 ));
00367	    }
00368	}
00369	
00370	//_____________________________________________________________________________
00371	simulated function PlayImpactSound(vector Normal, actor Wall)
00372	{
00373	    local Material M;
00374	    local actor A;
00375	    local vector HitLoc, HitNorm;
00376	    local ImpactEmitter B;
00377	
00378	    if ( Level.NetMode == NM_DedicatedServer )
00379	      return;
00380	
00381	    A = Trace(HitLoc, HitNorm, Location - Normal*10, Location + Normal*10, true, vect(0,0,0), M);
00382	
00383	    if ( DBProj ) Log("PlayImpactSound A="$A@"M="$M);
00384	    if ( Wall.bWorldGeometry || (Mover(Wall) != none) || (StaticMeshActor(Wall) != none) || (VehicleDeco(Wall) != none))
00385	    {
00386	      if ( (M != none) && (M.HitSound != none) )
00387	        SetUpImpactEmitter(M.HitSound);
00388	      if ( ImpactEmitterMem != none )
00389	      {
00390	        B = Spawn(ImpactEmitterMem,,, HitLoc+HitNorm, Rotator(HitNorm));
00391	        if ( (B != none) && (HitSoundType >= 0) )
00392	        {
00393	          if ( (M != none) && (M.HitSound != none) )
00394	            B.PlaySound(M.HitSound, HitSoundType);
00395	        }
00396	      }
00397	    }
00398	}
00399	
00400	//_____________________________________________________________________________
00401	simulated function SetUpImpactEmitter(Sound S)
00402	{
00403	    local string Str;
00404	    local int i;
00405	
00406	    // First get rid of the beginning of the sound name just to keep whet is needed
00407	    Str = string(S);
00408	    i = InStr(S, 'hPlay');
00409	    Str = Right(Str, Len(Str) - i - 5);
00410	//    Log("--'"$Str$"'--");
00411	
00412	    // Then switch/case the result to setup the SFX class
00413	    switch (Str)
00414	    {
00415	      case "ImpBtE":
00416	      case "ImpBtI":
00417	      case "ImpCar":
00418	      case "ImpMar":
00419	      case "ImpTil":
00420	      case "ImpPie":
00421	        // Concrete type
00422	        ImpactEmitterMem = class'BulletDustEmitter';
00423	        break;
00424	      case "ImpGra":
00425	        // Gravel type
00426	        ImpactEmitterMem = class'GravelDustEmitter';
00427	        break;
00428	      case "ImpBoiC":
00429	      case "ImpBoiP":
00430	      case "ImpPar":
00431	      case "ImpFeu":
00432	        // Wood type
00433	        ImpactEmitterMem = class'WoodDustEmitter';
00434	        break;
00435	      case "ImpEau":
00436	        // Water type (should not happen but maybe....)
00437	        ImpactEmitterMem = class'BulletDustEmitter';
00438	        break;
00439	      case "ImpGla":
00440	      case "ImpVer":
00441	        // Glass type
00442	        ImpactEmitterMem = class'GlassImpactEmitter';
00443	        break;
00444	      case "ImpGri":
00445	      case "ImpMet":
00446	      case "ImpTol":
00447	        // Metal type
00448	        ImpactEmitterMem = class'BulletMetalEmitter';
00449	        break;
00450	      case "ImpHrb":
00451	        // Grass Type
00452	        ImpactEmitterMem = class'GrassDustEmitter';
00453	        break;
00454	      case "ImpTer":
00455	        // Earth type
00456	        ImpactEmitterMem = class'EarthDustEmitter';
00457	        break;
00458	      case "ImpNei":
00459	        // Snow Type
00460	        ImpactEmitterMem = class'SnowDustEmitter';
00461	        break;
00462	      case "ImpMol":
00463	      case "ImpMoq":
00464	        // Soft Types
00465	        ImpactEmitterMem = class'MoqDustEmitter';
00466	        break;
00467	      case "ImpCdvr":
00468	        ImpactEmitterMem = class'BloodShotEmitter';
00469	        break;
00470	      case "ImpLin":
00471	      default:
00472	        // other types, not spawn any SFX
00473	        ImpactEmitterMem = class'BulletDustEmitter';
00474	        break;
00475	    }
00476	/*
00477	handler hPlayImpBtE (int iWhichAmmo)	Béton exterieur
00478	handler hPlayImpBtI (int iWhichAmmo)	Béton interieur
00479	handler hPlayImpBoiC (int iWhichAmmo)	Bois Creux
00480	handler hPlayImpBoiP (int iWhichAmmo)	Bois plein
00481	handler hPlayImpCar (int iWhichAmmo)	Carrelage
00482	handler hPlayImpEau (int iWhichAmmo)	Eau
00483	handler hPlayImpFeu (int iWhichAmmo)	Feuilles
00484	handler hPlayImpFlesh (int iWhichAmmo)	Chair
00485	handler hPlayImpGla (int iWhichAmmo)	Glace
00486	handler hPlayImpGra (int iWhichAmmo)	Gravier
00487	handler hPlayImpGri (int iWhichAmmo)	Grille
00488	handler hPlayImpHrb (int iWhichAmmo)	Herbe
00489	handler hPlayImpLin (int iWhichAmmo)	Lino
00490	handler hPlayImpMar (int iWhichAmmo)	Marbre
00491	handler hPlayImpMet (int iWhichAmmo)	Métal
00492	handler hPlayImpMol (int iWhichAmmo)	diverses textures molles: matelas; fauteuille; liège.
00493	handler hPlayImpMoq (int iWhichAmmo)	Moquette
00494	handler hPlayImpNei (int iWhichAmmo)	Neige
00495	handler hPlayImpPar (int iWhichAmmo)	Parquet
00496	handler hPlayImpPie (int iWhichAmmo)	Pierre
00497	handler hPlayImpTer (int iWhichAmmo)	Terre
00498	handler hPlayImpTol (int iWhichAmmo)	Tôle
00499	handler hPlayImpTil (int iWhichAmmo)	Tuile
00500	handler hPlayImpVer (int iWhichAmmo)	Verre*/
00501	}
00502	
00503	//_____________________________________________________________________________
00504	simulated event Destroyed()
00505	{
00506	    if ( DBProj ) Log("PROJ"@self@"Destroyed ");
00507	    if ( MyTrail != none )
00508	      MyTrail.Destroy();
00509	    Super.Destroyed();
00510	}
00511	
00512	//_____________________________________________________________________________
00513	function bool CanSplash()
00514	{
00515	  if ( !bSplashed )
00516	  {
00517	    bSplashed = true;
00518	  	return true;
00519	  }
00520	}
00521	
00522	//_____________________________________________________________________________
00523	event PhysicsVolumeChange( PhysicsVolume NewVolume )
00524	{
00525	//    Log("PhysicsVolumeChange");
00526	    // no super so don't call
00527	    if ( NewVolume.bWaterVolume )
00528	      vWaterEntry = Location;
00529	}
00530	
00531	//_____________________________________________________________________________
00532	// Generic water surface explosion SFX
00533	simulated function SpawnWaterExplo(vector HitLocation)
00534	{
00535	    local vector HitLoc, HitNorm;
00536	    local vector StartTrace;
00537	    local actor other;
00538	    Local Material HitMat;
00539	
00540	    StartTrace = (HitLocation + vWaterEntry)/2.0;
00541	    StartTrace.z = vWaterEntry.z + 10;
00542	    Other = Trace(HitLoc, HitNorm, (HitLocation + vWaterEntry)/2.0, StartTrace, false, vect(0,0,0), HitMat, 0x008);
00543	    if ( Other.IsA('Watervolume') )
00544	      PhysicsVolume(Other).BeingHitByProjectile(HitLoc);
00545	}
00546	
00547	
00548	
00549	defaultproperties
00550	{
00551	     bSpawnDecal=True
00552	     HitSoundType=-1
00553	     hExploSound=Sound'XIIIsound.Explo__ExploGren.ExploGren__hExploGren'
00554	     bUnlit=False
00555	     SaturationDistance=100.000000
00556	     StabilisationDistance=794.000000
00557	}

End Source Code