public virtual void ShootBullet(float spread, float force, float damage, float bulletSize) { var forward = Owner.EyeRot.Forward; forward += (Vector3.Random + Vector3.Random + Vector3.Random + Vector3.Random) * spread * 0.25f; forward = forward.Normal; foreach (var tr in TraceBullet(Owner.EyePos, Owner.EyePos + forward * 5000, bulletSize)) { tr.Surface.DoBulletImpact(tr); if (!IsServer) { continue; } if (!tr.Entity.IsValid()) { continue; } using (Prediction.Off()) { var damageInfo = DamageInfo.FromBullet(tr.EndPos, forward * 100 * force, damage) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damageInfo); } } }
public virtual void MeleeStrike(float damage, float force) { Vector3 forward = Owner.EyeRotation.Forward; forward = forward.Normal; foreach (TraceResult tr in TraceBullet(Owner.EyePosition, Owner.EyePosition + forward * MeleeDistance, 10f)) { if (!tr.Entity.IsValid()) { continue; } tr.Surface.DoBulletImpact(tr); if (!IsServer) { continue; } using (Prediction.Off()) { DamageInfo damageInfo = DamageInfo.FromBullet(tr.EndPosition, forward * 100 * force, damage) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damageInfo); } } }
public override void AttackPrimary(Sandbox.Player owner) { TimeSincePrimaryAttack = 0; TimeSinceSecondaryAttack = 0; ShootEffects(); foreach (var tr in TraceBullet(owner.EyePos, owner.EyePos + owner.EyeRot.Forward * 5000)) { tr.Surface.DoBulletImpact(tr); if (!IsServer) { continue; } if (!tr.Entity.IsValid()) { continue; } using (Prediction.Off()) { var damage = DamageInfo.FromBullet(tr.EndPos, owner.EyeRot.Forward * 100, 15) .UsingTraceResult(tr) .WithAttacker(owner) .WithWeapon(this); tr.Entity.TakeDamage(damage); } } }
public static void DamageMeCmd(int damage) { if (ConsoleSystem.Caller.Pawn is CCPlayer player) { float oldHealth = player.Health; player.TakeDamage(DamageInfo.FromBullet(player.Position, Vector3.Zero, damage)); Log.Info($"Old health: {oldHealth}, new health: {player.Health}"); } }
public virtual void Tick() { if (!IsServer) { return; } if (Stuck) { return; } float Speed = 10000.0f; var velocity = Rotation.Forward * Speed; var start = Position; var end = start + velocity * Time.Delta; var tr = Trace.Ray(start, end) .UseHitboxes() //.HitLayer( CollisionLayer.Water, !InWater ) .Ignore(Owner) .Ignore(this) .Size(1.0f) .Run(); if (tr.Hit) { // TODO: CLINK NOISE (unless flesh) // TODO: SPARKY PARTICLES (unless flesh) Stuck = true; Position = tr.EndPos + Rotation.Forward * -1; if (tr.Entity.IsValid()) { var damageInfo = DamageInfo.FromBullet(tr.EndPos, tr.Direction * 200, 60.0f) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damageInfo); } // TODO: Parent to bone so this will stick in the meaty heads SetParent(tr.Entity, tr.Bone); Owner = null; // // Surface impact effect // tr.Normal = Rotation.Forward * -1; tr.Surface.DoBulletImpact(tr); velocity = default; // delete self in 60 seconds _ = DeleteAsync(60.0f); } else { Position = end; } }
public override void OnHit(TraceResult trace) { if (trace.Entity.IsValid()) { DamageInfo info = DamageInfo.FromBullet(trace.EndPos, trace.Direction * 200, Damage) .UsingTraceResult(trace) .WithAttacker(Owner) .WithWeapon(this); trace.Entity.TakeDamage(info); } trace.Surface.DoBulletImpact(trace); }
public override void AttackPrimary() { TimeSincePrimaryAttack = 0; TimeSinceSuccessfulPrimaryAttack = 0; TimeSinceSecondaryAttack = 0; // // Tell the clients to play the shoot effects // ShootEffects(); // // Do recoil // PerformRecoil(); // // ShootBullet is coded in a way where we can have bullets pass through shit // or bounce off shit, in which case it'll return multiple results // foreach (var tr in TraceBullet(Owner.EyePos, Owner.EyePos + Owner.EyeRot.Forward * 5000)) { tr.Surface.DoBulletImpact(tr); if (!IsServer) { continue; } if (!tr.Entity.IsValid()) { continue; } // // We turn predictiuon off for this, so aany exploding effects don't get culled etc // using (Prediction.Off()) { var damage = DamageInfo.FromBullet(tr.EndPos, Owner.EyeRot.Forward * 100, 15) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damage); } } }
public override void AttackPrimary() { TimeSincePrimaryAttack = 0; TimeSinceSecondaryAttack = 0; // // Tell the clients to play the shoot effects // ShootEffects(); bool InWater = Physics.TestPointContents(Owner.EyePos, CollisionLayer.Water); var forward = Owner.EyeRot.Forward * (InWater ? 500 : 4000); // // ShootBullet is coded in a way where we can have bullets pass through shit // or bounce off shit, in which case it'll return multiple results // foreach (var tr in TraceBullet(Owner.EyePos, Owner.EyePos + Owner.EyeRot.Forward * 4000)) { tr.Surface.DoBulletImpact(tr); if (!IsServer) { continue; } if (!tr.Entity.IsValid()) { continue; } // // We turn predictiuon off for this, so aany exploding effects // using (Prediction.Off()) { var damage = DamageInfo.FromBullet(tr.EndPos, forward.Normal * 100, 15) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damage); } } }
private void Shoot(Vector3 pos, Vector3 dir) { // // Tell the clients to play the shoot effects // ShootEffects(); bool InWater = Physics.TestPointContents(pos, CollisionLayer.Water); var forward = dir * (InWater ? 500 : 4000); // // ShootBullet is coded in a way where we can have bullets pass through shit // or bounce off shit, in which case it'll return multiple results // foreach (var tr in TraceBullet(pos, pos + dir * 4000)) { tr.Surface.DoBulletImpact(tr); if (!IsServer) { continue; } if (!tr.Entity.IsValid()) { continue; } // // We turn predictiuon off for this, so aany exploding effects // using (Prediction.Off()) { var damage = DamageInfo.FromBullet(tr.EndPos, forward.Normal * 20, 60) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damage); } } }
/// <summary> /// Shoot a single bullet /// </summary> public virtual void ShootBullet(float spread, float force, float damage, float bulletSize, float BulletCount = 0) { var forward = Owner.EyeRot.Forward; forward += (RandVec3(BulletCount) * spread * 0.25f); forward = forward.Normal; // // ShootBullet is coded in a way where we can have bullets pass through shit // or bounce off shit, in which case it'll return multiple results // foreach (var tr in TraceBullet(Owner.EyePos, Owner.EyePos + forward * 5000, bulletSize)) { BulletImpact(tr); DebugOverlay.Line(tr.StartPos, tr.EndPos, Host.IsServer ? Color.Yellow : Color.Blue, 5f); if (!IsServer) { continue; } if (!tr.Entity.IsValid()) { continue; } // // We turn prediction off for this, so any exploding effects don't get culled etc // using (Prediction.Off()) { var damageInfo = DamageInfo.FromBullet(tr.EndPos, forward * 100 * force, damage) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damageInfo); } } }
/// <summary> /// Shoot a single bullet /// </summary> public virtual void ShootBullet(Vector3 pos, Vector3 dir, float spread, float force, float damage, float bulletSize) { var forward = dir; forward += (Vector3.Random + Vector3.Random + Vector3.Random + Vector3.Random) * spread * 0.25f; forward = forward.Normal; // // ShootBullet is coded in a way where we can have bullets pass through shit // or bounce off shit, in which case it'll return multiple results // foreach (var tr in TraceBullet(pos, pos + forward * 5000, bulletSize)) { tr.Surface.DoBulletImpact(tr); if (!IsServer) { continue; } if (!tr.Entity.IsValid()) { continue; } // // We turn predictiuon off for this, so any exploding effects don't get culled etc // using (Prediction.Off()) { var damageInfo = DamageInfo.FromBullet(tr.EndPosition, forward * 100 * force, damage) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damageInfo); } } }
private bool MeleeAttack() { var forward = Owner.EyeRotation.Forward; forward = forward.Normal; bool hit = false; foreach (var tr in TraceBullet(Owner.EyePosition, Owner.EyePosition + forward * 80, 20.0f)) { if (!tr.Entity.IsValid()) { continue; } tr.Surface.DoBulletImpact(tr); hit = true; if (!IsServer) { continue; } using (Prediction.Off()) { var damageInfo = DamageInfo.FromBullet(tr.EndPosition, forward * 100, 25) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damageInfo); } } return(hit); }
public virtual void OnPostPhysicsStep(float dt) { //DebugOverlay.Box( 0.1f, WorldPos, -0.1f, 1.1f, Host.Color ); if (!IsServer) { return; } if (Stuck) { return; } float Speed = 100.0f; var velocity = WorldRot.Forward * Speed; var start = WorldPos; var end = start + velocity; var tr = Trace.Ray(start, end) .UseHitboxes() //.HitLayer( CollisionLayer.Water, !InWater ) .Ignore(Owner) .Ignore(this) .Size(1.0f) .Run(); // DebugOverlay.Line( start, end, 10.0f ); // DebugOverlay.Box( 10.0f, WorldPos, -1, 1, Color.Red ); // DebugOverlay.Box( 10.0f, tr.EndPos, -1, 1, Color.Red ); if (tr.Hit) { // TODO: CLINK NOISE (unless flesh) // TODO: SPARKY PARTICLES (unless flesh) Stuck = true; WorldPos = tr.EndPos + WorldRot.Forward * -1; if (tr.Entity.IsValid()) { var damageInfo = DamageInfo.FromBullet(tr.EndPos, tr.Direction * 200, 60.0f) .UsingTraceResult(tr) .WithAttacker(Owner) .WithWeapon(this); tr.Entity.TakeDamage(damageInfo); } // TODO: Parent to bone so this will stick in the meaty heads SetParent(tr.Entity, tr.Bone); Owner = null; // // Surface impact effect // tr.Normal = WorldRot.Forward * -1; tr.Surface.DoBulletImpact(tr); velocity = default; // // BUG: without this the bolt stops short of the wall on the client. // need to make interp finish itself off even though it's not getting new positions? // ResetInterpolation(); // DebugOverlay.Box( 10.0f, WorldPos, -1, 1, Color.Red ); // DebugOverlay.Box( 10.0f, tr.EndPos, -1, 1, Color.Yellow ); // delete self in 30 seconds _ = DeleteAsync(30.0f); } else { WorldPos = end; } }