Exemple #1
0
        // Modified from Prop.cs to allow tweaking through code/cvar rather than having to go through model doc.
        private async Task Explode()
        {
            try
            {
                IsArmed = false;

                await Task.DelaySeconds(0.1f);

                Sound.FromWorld("rust_pumpshotgun.shootdouble", PhysicsBody.MassCenter);
                Particles.Create("particles/explosion_fireball.vpcf", PhysicsBody.MassCenter);

                Vector3 sourcePos             = PhysicsBody.MassCenter;
                IEnumerable <Entity> overlaps = FindInSphere(sourcePos, BOMB_RADIUS);

                foreach (Entity overlap in overlaps)
                {
                    if (overlap is not ModelEntity ent || !ent.IsValid() || ent.LifeState != LifeState.Alive || !ent.PhysicsBody.IsValid() || ent.IsWorld)
                    {
                        continue;
                    }

                    Vector3 targetPos = ent.PhysicsBody.MassCenter;
                    float   dist      = Vector3.DistanceBetween(sourcePos, targetPos);

                    if (dist > BOMB_RADIUS)
                    {
                        continue;
                    }

                    TraceResult tr = Trace.Ray(sourcePos, targetPos)
                                     .Ignore(this)
                                     .WorldOnly()
                                     .Run();

                    if (tr.Fraction < 1.0f)
                    {
                        continue;
                    }

                    float   distanceMul = 1.0f - Math.Clamp(dist / BOMB_RADIUS, 0.0f, 1.0f);
                    float   damage      = BOMB_DAMAGE * distanceMul;
                    float   force       = BOMB_FORCE * distanceMul * ent.PhysicsBody.Mass;
                    Vector3 forceDir    = (targetPos - sourcePos).Normal;

                    ent.TakeDamage(DamageInfo.Explosion(sourcePos, forceDir * force, damage)
                                   .WithAttacker(this));
                }
            }
            catch (Exception e)
            {
                if (e.Message.Trim() == "A task was canceled.")
                {
                    return;
                }

                Log.Error($"[TASK] {e.Message}: {e.StackTrace}");
            }

            base.OnKilled();
        }
Exemple #2
0
        private void Explode()
        {
            // TODO: Rework this effect and damage
            var explosionBehavior = new ModelExplosionBehavior()
            {
                Sound  = "",
                Effect = "particles/prophunt/explosion.vpcf",
                Damage = 100f,
                Radius = 100f,
                Force  = 20f
            };

            if (!string.IsNullOrWhiteSpace(explosionBehavior.Sound))
            {
                Sound.FromWorld(explosionBehavior.Sound, PhysicsBody.MassCenter);
            }

            if (!string.IsNullOrWhiteSpace(explosionBehavior.Effect))
            {
                Particles.Create(explosionBehavior.Effect, PhysicsBody.MassCenter);
            }

            if (explosionBehavior.Radius > 0.0f)
            {
                var sourcePos = PhysicsBody.MassCenter;
                var overlaps  = Physics.GetEntitiesInSphere(sourcePos, explosionBehavior.Radius);

                foreach (var overlap in overlaps)
                {
                    if (overlap is not ModelEntity ent || !ent.IsValid())
                    {
                        continue;
                    }

                    if (ent.LifeState != LifeState.Alive)
                    {
                        continue;
                    }

                    if (!ent.PhysicsBody.IsValid())
                    {
                        continue;
                    }

                    if (ent.IsWorld)
                    {
                        continue;
                    }

                    var targetPos = ent.PhysicsBody.MassCenter;

                    var dist = Vector3.DistanceBetween(sourcePos, targetPos);
                    if (dist > explosionBehavior.Radius)
                    {
                        continue;
                    }

                    var tr = Trace.Ray(sourcePos, targetPos)
                             .Ignore(this)
                             .WorldOnly()
                             .Run();

                    if (tr.Fraction < 1.0f)
                    {
                        continue;
                    }

                    var distanceMul = 1.0f - Math.Clamp(dist / explosionBehavior.Radius, 0.0f, 1.0f);
                    var damage      = explosionBehavior.Damage * distanceMul;
                    var force       = (explosionBehavior.Force * distanceMul) * ent.PhysicsBody.Mass;
                    var forceDir    = (targetPos - sourcePos).Normal;

                    ent.TakeDamage(DamageInfo.Explosion(sourcePos, forceDir * force, damage)
                                   .WithAttacker(Owner));
                }
            }
        }