예제 #1
0
    public void Explode(Vector3 Position)
    {
        foreach (Node Body in AffectedBodies)
        {
            if (Body is IPushable Pushable)
            {
                PhysicsDirectSpaceState      State   = GetWorld().DirectSpaceState;
                Godot.Collections.Dictionary Results = State.IntersectRay(Position, Pushable.Translation, new Godot.Collections.Array()
                {
                    Pushable
                }, 1);
                if (Results.Count > 0)
                {
                    continue;
                }

                float Distance = Clamp(Position.DistanceTo(Pushable.Translation), 1, MaxRocketDistance);
                float Power    =
                    LogBase(-Distance + MaxRocketDistance + 1, 2)
                    / LogBase(MaxRocketDistance + 1, 2);

                Vector3 Push = ((Pushable.Translation - Position) / MaxRocketDistance).Normalized()
                               * MaxRocketPush * Power;
                {
                    Vector3 Flat = Push.Flattened();
                    Flat  *= RocketHorizontalMultiplyer;
                    Push.x = Flat.x;
                    Push.z = Flat.z;
                }
                Push.y *= RocketVerticalMultiplyer;
                Pushable.ApplyPush(Push);
            }
        }
        AffectedBodies.Clear();

        var ExplodeSfxInstance = (AudioStreamPlayer3D)ExplodeSfx.Instance();

        ExplodeSfxInstance.Play();
        ExplodeSfxInstance.Translation = Position;
        World.EntitiesRoot.AddChild(ExplodeSfxInstance);

        var ParticleSystem = (CPUParticles)ExplodeParticles.Instance();

        ParticleSystem.Translation = Position;
        ParticleSystem.Emitting    = true;
        World.EntitiesRoot.AddChild(ParticleSystem);

        QueueFree();
    }
예제 #2
0
    public void ServerExplode(Vector3 Position)
    {
        Assert.ActualAssert(Net.Work.IsNetworkServer());

        var WithinArea = World.GetEntitiesWithinArea(Position, MaxRocketDistance);

        foreach (Node Body in WithinArea)
        {
            if (Body is IPushable Pushable)
            {
                PhysicsDirectSpaceState      State   = GetWorld().DirectSpaceState;
                Godot.Collections.Dictionary Results = State.IntersectRay(Position, Pushable.Translation, new Godot.Collections.Array()
                {
                    Pushable
                }, 1);
                if (Results.Count > 0)
                {
                    continue;
                }

                Vector3 Push = CalculatePush(Pushable, Position);

                if (Pushable is Player Plr &&
                    Game.PossessedPlayer.HasValue &&
                    Plr != Game.PossessedPlayer.ValueOrFailure())
                {
                    continue;
                }

                Pushable.ApplyPush(Push);
                Entities.SendPush(Pushable, Push);
            }
        }

        ExplodeSoundVisual(Position);

        Entities.SendDestroy(Name, Position);
        QueueFree();
    }