//=============================================================================
// WeaponCombatKnife.
//=============================================================================
class WeaponNinjaKnife extends NinjaWeapon;

var bool bNinj0rz;

replication
{
    reliable if ( Role == ROLE_Authority )
      SetClientHandTo;
}
//
// copied from Weapon.uc
//
simulated function Projectile ProjectileFire(class<projectile> ProjClass, float ProjSpeed, bool bWarn)
{
	local Vector Start, X, Y, Z;
	local DeusExProjectile proj;
	local float mult;
	local float volume, radius;
	local int i, numProj;
	local Pawn aPawn;

	// AugCombat increases our speed (distance) if hand to hand
	//MainMan; AUG NINJA, FOOL!
	mult = 1.0;
	if (bHandToHand && (DeusExPlayer(Owner) != None))
	{
		mult = DeusExPlayer(Owner).AugmentationSystem.GetAugLevelValue(class'AugNinja');
		if (mult == -1.0)
			mult = 1.0;
		ProjSpeed *= mult;
	}

	// skill also affects our damage
	// GetWeaponSkill returns 0.0 to -0.7 (max skill/aug)
	mult += -2.0 * GetWeaponSkill();

	// make noise if we are not silenced
	if (!bHasSilencer && !bHandToHand)
	{
		GetAIVolume(volume, radius);
		Owner.AISendEvent('WeaponFire', EAITYPE_Audio, volume, radius);
		Owner.AISendEvent('LoudNoise', EAITYPE_Audio, volume, radius);
		if (!Owner.IsA('PlayerPawn'))
			Owner.AISendEvent('Distress', EAITYPE_Audio, volume, radius);
	}

	// should we shoot multiple projectiles in a spread?
	if (AreaOfEffect == AOE_Cone)
		numProj = 3;
	else
		numProj = 1;

	GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
	Start = ComputeProjectileStart(X, Y, Z);

	for (i=0; i<numProj; i++)
	{
      // If we have multiple slugs, then lower our accuracy a bit after the first slug so the slugs DON'T all go to the same place
      if ((i > 0) && (Level.NetMode != NM_Standalone))
         if (currentAccuracy < MinProjSpreadAcc)
            currentAccuracy = MinProjSpreadAcc;
         
		AdjustedAim = pawn(owner).AdjustAim(ProjSpeed, Start, AimError, True, bWarn);
		AdjustedAim.Yaw += currentAccuracy * (Rand(1024) - 512);
		AdjustedAim.Pitch += currentAccuracy * (Rand(1024) - 512);


		if (( Level.NetMode == NM_Standalone ) || ( Owner.IsA('DeusExPlayer') && DeusExPlayer(Owner).PlayerIsListenClient()) )
		{
			proj = DeusExProjectile(Spawn(ProjClass, Owner,, Start, AdjustedAim));
			if (proj != None)
			{
				// AugCombat increases our damage as well
				proj.Damage *= mult;

				// send the targetting information to the projectile
				if (bCanTrack && (LockTarget != None) && (LockMode == LOCK_Locked))
				{
					proj.Target = LockTarget;
					proj.bTracking = True;
				}
			}
		}
		else
		{
			if (( Role == ROLE_Authority ) || (DeusExPlayer(Owner) == DeusExPlayer(GetPlayerPawn())) )
			{
				// Do it the old fashioned way if it can track, or if we are a projectile that we could pick up again
				if ( bCanTrack || Self.IsA('WeaponShuriken') || Self.IsA('WeaponMiniCrossbow') || Self.IsA('WeaponLAM') || Self.IsA('WeaponEMPGrenade') || Self.IsA('WeaponGasGrenade'))
				{
					if ( Role == ROLE_Authority )
					{
						proj = DeusExProjectile(Spawn(ProjClass, Owner,, Start, AdjustedAim));
						if (proj != None)
						{
							// AugCombat increases our damage as well
								proj.Damage *= mult;
							// send the targetting information to the projectile
							if (bCanTrack && (LockTarget != None) && (LockMode == LOCK_Locked))
							{
								proj.Target = LockTarget;
								proj.bTracking = True;
							}
						}
					}
				}
				else
				{
					proj = DeusExProjectile(Spawn(ProjClass, Owner,, Start, AdjustedAim));
					if (proj != None)
					{
						proj.RemoteRole = ROLE_None;
						// AugCombat increases our damage as well
						if ( Role == ROLE_Authority )
							proj.Damage *= mult;
						else
							proj.Damage = 0;
					}
					if ( Role == ROLE_Authority )
					{
						for ( aPawn = Level.PawnList; aPawn != None; aPawn = aPawn.nextPawn )
						{
							if ( aPawn.IsA('DeusExPlayer') && ( DeusExPlayer(aPawn) != DeusExPlayer(Owner) ))
								DeusExPlayer(aPawn).ClientSpawnProjectile( ProjClass, Owner, Start, AdjustedAim );
						}
					}
				}
			}
		}

	}
	return proj;
}


function bool NearWallCheck()
{
	bNearWall = False;
	return false;
}

simulated function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z)
{
	local float        mult;
	local name         damageType;
	local DeusExPlayer dxPlayer;

	if (Other != None)
	{
		// AugCombat increases our damage if hand to hand
		mult = 1.0;
		if (bHandToHand && (DeusExPlayer(Owner) != None))
		{
			mult = DeusExPlayer(Owner).AugmentationSystem.GetAugLevelValue(class'AugNinja');
			if (mult == -1.0)
				mult = 1.0;
		}

		// skill also affects our damage
		// GetWeaponSkill returns 0.0 to -0.7 (max skill/aug)
		mult += -2.0 * GetWeaponSkill();

		// Determine damage type
		damageType = WeaponDamageType();

		if (Other != None)
		{
			if (Other.bOwned)
			{
				dxPlayer = DeusExPlayer(Owner);
				if (dxPlayer != None)
					dxPlayer.AISendEvent('Futz', EAITYPE_Visual);
			}
		}
		if ((Other == Level) || (Other.IsA('Mover')))
		{
			if ( Role == ROLE_Authority )
				Other.TakeDamage(HitDamage * mult, Pawn(Owner), HitLocation, 1000.0*X, damageType);

			SelectiveSpawnEffects( HitLocation, HitNormal, Other, HitDamage * mult);
		}
		else if ((Other != self) && (Other != Owner))
		{
			if ( Role == ROLE_Authority )
				Other.TakeDamage(HitDamage * mult, Pawn(Owner), HitLocation, 1000.0*X, damageType);
			if (bHandToHand)
				SelectiveSpawnEffects( HitLocation, HitNormal, Other, HitDamage * mult);

			if (bPenetrating && Other.IsA('Pawn') && !Other.IsA('Robot'))
				SpawnBlood(HitLocation, HitNormal);
		}
	}
   if (DeusExMPGame(Level.Game) != None)
   {
      if (DeusExPlayer(Other) != None)
         DeusExMPGame(Level.Game).TrackWeapon(self,HitDamage * mult);
      else
         DeusExMPGame(Level.Game).TrackWeapon(self,0);
   }
}



state NormalFire
{
	function AnimEnd()
	{
		if (bAutomatic)
		{
			if ((Pawn(Owner).bFire != 0) && (AmmoType.AmmoAmount > 0))
			{
				if (PlayerPawn(Owner) != None)
					Global.Fire(0);
				else 
					GotoState('FinishFire');
			}
			else 
				GotoState('FinishFire');
		}
		else
		{
			// if we are a thrown weapon and we run out of ammo, destroy the weapon
			if (bHandToHand && (ReloadCount > 0) && (AmmoType.AmmoAmount <= 0))
				Destroy();
		}
	}
	function float GetShotTime()
	{
		local float mult, sTime;

		if (ScriptedPawn(Owner) != None)
			return ShotTime * (ScriptedPawn(Owner).BaseAccuracy*2+1);
		else
		{
			// AugCombat decreases shot time
			mult = 1.0;
			if (bHandToHand && DeusExPlayer(Owner) != None)
			{
				mult = 1.0 / DeusExPlayer(Owner).AugmentationSystem.GetAugLevelValue(class'AugNinja');
				if (mult == -1.0)
					mult = 1.0;
			}
			sTime = ShotTime * mult;
			return (sTime);
		}
	}

Begin:
	if ((ClipCount >= ReloadCount) && (ReloadCount != 0))
	{
		if (!bAutomatic)
		{
			bFiring = False;
			FinishAnim();
		}

		if (Owner != None)
		{
			if (Owner.IsA('DeusExPlayer'))
			{
				bFiring = False;

				// should we autoreload?
				if (DeusExPlayer(Owner).bAutoReload)
				{
					// auto switch ammo if we're out of ammo and
					// we're not using the primary ammo
					if ((AmmoType.AmmoAmount == 0) && (AmmoName != AmmoNames[0]))
						CycleAmmo();
					ReloadAmmo();
				}
				else
				{
					if (bHasMuzzleFlash)
						EraseMuzzleFlashTexture();
					GotoState('Idle');
				}
			}
			else if (Owner.IsA('ScriptedPawn'))
			{
				bFiring = False;
				ReloadAmmo();
			}
		}
		else
		{
			if (bHasMuzzleFlash)
				EraseMuzzleFlashTexture();
			GotoState('Idle');
		}
	}
	if ( bAutomatic && (( Level.NetMode == NM_DedicatedServer ) || ((Level.NetMode == NM_ListenServer) && Owner.IsA('DeusExPlayer') && !DeusExPlayer(Owner).PlayerIsListenClient())))
		GotoState('Idle');

	Sleep(GetShotTime());
	if (bAutomatic)
	{
		GenerateBullet();	// In multiplayer bullets are generated by the client which will let the server know when
		Goto('Begin');
	}
	bFiring = False;
	FinishAnim();

	// if ReloadCount is 0 and we're not hand to hand, then this is a
	// single-use weapon so destroy it after firing once
	if ((ReloadCount == 0) && !bHandToHand)
	{
		if (DeusExPlayer(Owner) != None)
			DeusExPlayer(Owner).RemoveItemFromSlot(Self);   // remove it from the inventory grid
		Destroy();
	}
	ReadyToFire();
Done:
	bFiring = False;
	Finish();
}




simulated function bool ClientFire( float value )
{
		if((Region.Zone.IsA('ArenaZoneSafe')) || (Region.Zone.IsA('MMRPGRoomArea')) || (Region.Zone.IsA('MMRPGSafeArea')))
		{
			return False;
		}

		if((!Region.Zone.IsA('ArenaZoneSafe')) && (!Region.Zone.IsA('MMRPGRoomArea')) && (!Region.Zone.IsA('MMRPGSafeArea')))
		{
			return Super.ClientFire(value);
		}
}

simulated state ClientFiring
{
	simulated function AnimEnd()
	{
		bInProcess = False;

		if (bAutomatic)
		{
			if ((Pawn(Owner).bFire != 0) && (AmmoType.AmmoAmount > 0))
			{
				if (PlayerPawn(Owner) != None)
					ClientReFire(0);
				else
					GotoState('SimFinishFire');
			}
			else 
				GotoState('SimFinishFire');
		}
	}
	simulated function float GetSimShotTime()
	{
		local float mult, sTime;

		if (ScriptedPawn(Owner) != None)
			return ShotTime * (ScriptedPawn(Owner).BaseAccuracy*2+1);
		else
		{
			// AugCombat decreases shot time
			mult = 1.0;
			if (bHandToHand && DeusExPlayer(Owner) != None)
			{
				mult = 1.0 / DeusExPlayer(Owner).AugmentationSystem.GetAugLevelValue(class'AugNinja');
				if (mult == -1.0)
					mult = 1.0;
			}
			sTime = ShotTime * mult;
			return (sTime);
		}
	}
Begin:
	if ((ClipCount >= ReloadCount) && (ReloadCount != 0))
	{
		if (!bAutomatic)
		{
			bFiring = False;
			FinishAnim();
		}
		if (Owner != None)
		{
			if (Owner.IsA('DeusExPlayer'))
			{
				bFiring = False;
				if (DeusExPlayer(Owner).bAutoReload)
				{
					bClientReadyToFire = False;
					bInProcess = False;
					if ((AmmoType.AmmoAmount == 0) && (AmmoName != AmmoNames[0]))
						CycleAmmo();
					ReloadAmmo();
					GotoState('SimQuickFinish');
				}
				else
				{
					if (bHasMuzzleFlash)
						EraseMuzzleFlashTexture();
					IdleFunction();
					GotoState('SimQuickFinish');
				}
			}
			else if (Owner.IsA('ScriptedPawn'))
			{
				bFiring = False;
			}
		}
		else
		{
			if (bHasMuzzleFlash)
				EraseMuzzleFlashTexture();
			IdleFunction();
			GotoState('SimQuickFinish');
		}
	}
	Sleep(GetSimShotTime());
	if (bAutomatic)
	{
		SimGenerateBullet();
		Goto('Begin');
	}
	bFiring = False;
	FinishAnim();
	bInProcess = False;
Done:
	bInProcess = False;
	bFiring = False;
	SimFinish();
}



simulated function SetClientHandTo( bool bHand, class<Ammo> AClass, int Relo )
{
	//bHandToHand = bHand;
	bHandToHand = True;
	AmmoName = AClass;
	ReloadCount = Relo;
}



function CycleAmmo()
{
	if(bNinj0rz)
	{
		SetClientAmmoParams(False, False, ShotTime, FireSound, Class'Contender.KnifeThrow', ProjectileSpeed );
		SetClientHandTo(False, Class'Contender.AmmoKnife', 1);
		AmmoName=Class'Contender.AmmoKnife';
		Pawn(Owner).ClientMessage("Throwing attack style selected.");
		bNinj0rz=False;
		return;
	}

	if(!bNinj0rz)
	{
		SetClientAmmoParams(True, False, ShotTime, FireSound, None, ProjectileSpeed );
		SetClientHandTo(True, Class'DeusEx.AmmoNone', 0);
		AmmoName=Class'DeusEx.AmmoNone';
		Pawn(Owner).ClientMessage("Standard attack style selected.");
		bNinj0rz=True;
		return;
	}
}



function GiveTo( pawn Other )
{	
	Super.GiveTo(Other);
	SetClientAmmoParams(True, False, ShotTime, FireSound, None, ProjectileSpeed );
	SetClientHandTo(True, Class'DeusEx.AmmoNone', 0);
	AmmoName=Class'DeusEx.AmmoNone';
}

simulated function bool TestMPBeltSpot(int BeltSpot)
{
   return ( (BeltSpot >= 1) && (BeltSpot <=9) );
}



//
// scope, laser, and targetting updates are done here
//
simulated function Tick(float deltaTime)
{
	local vector loc;
	local rotator rot;
	local float beepspeed, recoil;
	local DeusExPlayer player;
   local Actor RealTarget;
	local Pawn pawn;

	player = DeusExPlayer(Owner);
	pawn = Pawn(Owner);

	Super(Weapon).Tick(deltaTime);

	// don't do any of this if this weapon isn't currently in use
	if (pawn == None)
   {
      LockMode = LOCK_None;
      MaintainLockTimer = 0;
      LockTarget = None;
      LockTimer = 0;
		return;
   }

	if (pawn.Weapon != self)
   {
      LockMode = LOCK_None;
      MaintainLockTimer = 0;
      LockTarget = None;
      LockTimer = 0;
		return;
   }

	// all this should only happen IF you have ammo loaded
	if (ClipCount < ReloadCount)
	{
		// check for LAM or other placed mine placement
		if (bHandToHand && (ProjectileClass != None) && (!Self.IsA('WeaponShuriken')))
		{
			if (NearWallCheck())
			{
				if (( Level.NetMode != NM_Standalone ) && IsAnimating() && (AnimSequence == 'Select'))
				{
				}
				else
				{
					if (!bNearWall || (AnimSequence == 'Select'))
					{
						PlayAnim('PlaceBegin',, 0.1);
						bNearWall = True;
					}
				}
			}
			else
			{
				if (bNearWall)
				{
					PlayAnim('PlaceEnd',, 0.1);
					bNearWall = False;
				}
			}
		}


      SoundTimer += deltaTime;

      if ( (Level.Netmode == NM_Standalone) || ( (Player != None) && (Player.PlayerIsClient()) ) )
      {
         if (bCanTrack)
         {
            Target = AcquireTarget();
            RealTarget = Target;
            
            // calculate the range
            if (Target != None)
               TargetRange = Abs(VSize(Target.Location - Location));
            
            // update our timers
            //SoundTimer += deltaTime;
            MaintainLockTimer -= deltaTime;
            
            // check target and range info to see what our mode is
            if ((Target == None) || IsInState('Reload'))
            {
               if (MaintainLockTimer <= 0)
               {				
                  SetLockMode(LOCK_None);
                  MaintainLockTimer = 0;
                  LockTarget = None;
               }
               else if (LockMode == LOCK_Locked)
               {
                  Target = LockTarget;
               }
            }
            else if ((Target != LockTarget) && (Target.IsA('Pawn')) && (LockMode == LOCK_Locked))
            {
               SetLockMode(LOCK_None);
               LockTarget = None;
            }
            else if (!Target.IsA('Pawn'))
            {
               if (MaintainLockTimer <=0 )
               {
                  SetLockMode(LOCK_Invalid);
               }
            }
            else if ( (Target.IsA('DeusExPlayer')) && (Target.Style == STY_Translucent) )
            {
               //DEUS_EX AMSD Don't allow locks on cloaked targets.
               SetLockMode(LOCK_Invalid);
            }
            else if ( (Target.IsA('DeusExPlayer')) && (Player.DXGame.IsA('TeamDMGame')) && (TeamDMGame(Player.DXGame).ArePlayersAllied(Player,DeusExPlayer(Target))) )
            {
               //DEUS_EX AMSD Don't allow locks on allies.
               SetLockMode(LOCK_Invalid);
            }
            else
            {
               if (TargetRange > MaxRange)
               {
                  SetLockMode(LOCK_Range);
               }
               else
               {
                  // change LockTime based on skill
                  // -0.7 = max skill
                  // DEUS_EX AMSD Only do weaponskill check here when first checking.
                  if (LockTimer == 0)
                  {
                     LockTime = FMax(Default.LockTime + 3.0 * GetWeaponSkill(), 0.0);
                     if ((Level.Netmode != NM_Standalone) && (LockTime < 0.25))
                        LockTime = 0.25;
                  }
                  
                  LockTimer += deltaTime;
                  if (LockTimer >= LockTime)
                  {
                     SetLockMode(LOCK_Locked);
                  }
                  else
                  {
                     SetLockMode(LOCK_Acquire);
                  }
               }
            }
            
            // act on the lock mode
            switch (LockMode)
            {
            case LOCK_None:
               TargetMessage = msgNone;
               LockTimer -= deltaTime;
               break;
               
            case LOCK_Invalid:
               TargetMessage = msgLockInvalid;
               LockTimer -= deltaTime;
               break;
               
            case LOCK_Range:
               TargetMessage = msgLockRange @ Int(TargetRange/16) @ msgRangeUnit;
               LockTimer -= deltaTime;
               break;
               
            case LOCK_Acquire:
               TargetMessage = msgLockAcquire @ Left(String(LockTime-LockTimer), 4) @ msgTimeUnit;
               beepspeed = FClamp((LockTime - LockTimer) / Default.LockTime, 0.2, 1.0);
               if (SoundTimer > beepspeed)
               {
                  Owner.PlaySound(TrackingSound, SLOT_None);
                  SoundTimer = 0;
               }
               break;
               
            case LOCK_Locked:
               // If maintaining a lock, or getting a new one, increment maintainlocktimer
               if ((RealTarget != None) && ((RealTarget == LockTarget) || (LockTarget == None)))
               {
                  if (Level.NetMode != NM_Standalone)
                     MaintainLockTimer = default.MaintainLockTimer;
                  else
                     MaintainLockTimer = 0;
                  LockTarget = Target;
               }
               TargetMessage = msgLockLocked @ Int(TargetRange/16) @ msgRangeUnit;
               // DEUS_EX AMSD Moved out so server can play it so that client knows for sure when locked.
               /*if (SoundTimer > 0.1)
               {
                  Owner.PlaySound(LockedSound, SLOT_None);
                  SoundTimer = 0;
               }*/
               break;
            }
         }
         else
         {
            LockMode = LOCK_None;
            TargetMessage = msgNone;
            LockTimer = 0;
            MaintainLockTimer = 0;
            LockTarget = None;
         }
         
         if (LockTimer < 0)
            LockTimer = 0;
      }
   }
   else
   {
      LockMode = LOCK_None;
	  TargetMessage=msgNone;
      MaintainLockTimer = 0;
      LockTarget = None;
      LockTimer = 0;
   }

   if ((LockMode == LOCK_Locked) && (SoundTimer > 0.1) && (Role == ROLE_Authority))
   {
      PlayLockSound();
      SoundTimer = 0;
   }

	currentAccuracy = CalculateAccuracy();

	if (player != None)
	{
		// reduce the recoil based on skill
		recoil = recoilStrength + GetWeaponSkill() * 2.0;
		if (recoil < 0.0)
			recoil = 0.0;

		// simulate recoil while firing
		if (bFiring && IsAnimating() && (AnimSequence == 'Shoot') && (recoil > 0.0))
		{
			player.ViewRotation.Yaw += deltaTime * (Rand(4096) - 2048) * recoil;
			player.ViewRotation.Pitch += deltaTime * (Rand(4096) + 4096) * recoil;
			if ((player.ViewRotation.Pitch > 16384) && (player.ViewRotation.Pitch < 32768))
				player.ViewRotation.Pitch = 16384;
		}
	}

	// if were standing still, increase the timer
	if (VSize(Owner.Velocity) < 10)
		standingTimer += deltaTime;
	else	// otherwise, decrease it slowly based on velocity
		standingTimer = FMax(0, standingTimer - 0.03*deltaTime*VSize(Owner.Velocity));

	if (bLasing || bZoomed)
	{
		// shake our view to simulate poor aiming
		if (ShakeTimer > 0.25)
		{
			ShakeYaw = currentAccuracy * (Rand(4096) - 2048);
			ShakePitch = currentAccuracy * (Rand(4096) - 2048);
			ShakeTimer -= 0.25;
		}

		ShakeTimer += deltaTime;

		if (bLasing && (Emitter != None))
		{
			loc = Owner.Location;
			loc.Z += Pawn(Owner).BaseEyeHeight;

			// add a little random jitter - looks cool!
			rot = Pawn(Owner).ViewRotation;
			rot.Yaw += Rand(5) - 2;
			rot.Pitch += Rand(5) - 2;

			Emitter.SetLocation(loc);
			Emitter.SetRotation(rot);
		}

		if ((player != None) && bZoomed)
		{
			player.ViewRotation.Yaw += deltaTime * ShakeYaw;
			player.ViewRotation.Pitch += deltaTime * ShakePitch;
		}
	}
}









defaultproperties
{
     bNinj0rz=True
     LowAmmoWaterMark=0
     GoverningSkill=Class'DeusEx.SkillWeaponLowTech'
     NoiseLevel=0.050000
     EnemyEffective=ENMEFF_Organic
     Concealability=CONC_Visual
     reloadTime=0.000000
     HitDamage=25
     maxRange=80
     AccurateRange=80
     BaseAccuracy=0.800000
     bHasMuzzleFlash=False
     bHandToHand=True
     bFallbackWeapon=True
     mpHitDamage=25
     mpBaseAccuracy=0.800000
     mpAccurateRange=96
     mpMaxRange=96
	PickupAmmoCount=1
	ProjectileClass=Class'Contender.KnifeThrow'
     AmmoName=Class'Contender.AmmoKnife'
     ReloadCount=1
     bInstantHit=False
     FireOffset=(X=-5.000000,Y=8.000000,Z=14.000000)
     shakemag=20.000000
     FireSound=Sound'DeusExSounds.Weapons.CombatKnifeFire'
     SelectSound=Sound'DeusExSounds.Weapons.CombatKnifeSelect'
     Misc1Sound=Sound'DeusExSounds.Weapons.CombatKnifeHitFlesh'
     Misc2Sound=Sound'DeusExSounds.Weapons.CombatKnifeHitHard'
     Misc3Sound=Sound'DeusExSounds.Weapons.CombatKnifeHitSoft'
     InventoryGroup=122
     ItemName="Ninja Knife"
     PlayerViewOffset=(X=5.000000,Y=-8.000000,Z=-14.000000)
     PlayerViewMesh=LodMesh'DeusExItems.CombatKnife'
     PickupViewMesh=LodMesh'DeusExItems.CombatKnifePickup'
     ThirdPersonMesh=LodMesh'DeusExItems.CombatKnife3rd'
     Icon=Texture'DeusExUI.Icons.BeltIconCombatKnife'
     largeIcon=Texture'DeusExUI.Icons.LargeIconCombatKnife'
     largeIconWidth=49
     largeIconHeight=45
     Description="An ultra-high carbon stainless steel knife."
     beltDescription="NINJA KNF"
     Mesh=LodMesh'DeusExItems.CombatKnifePickup'
     CollisionRadius=12.650000
     CollisionHeight=0.800000
}
