Esempio n. 1
0
    public void shoot(float delta, bool isPuppet)
    {
        if (reloadWeapon)
        {
            return;
        }
        if (!isPuppet)
        {
            return;
        }

        // Get bullet ray.
        RayCast bulletRay = (RayCast)camera.GetNode("bullet_ray");

        if (bullets > 0)
        {
            bullets -= 1;

            // Notify bullet update
            GameState.instance.EmitSignal(nameof(GameState.updateWeapon), weaponName, bullets, ammo);

            if (camera != null)
            {
                // Recoil
                camera.Rotation = new Vector3(
                    Mathf.Lerp(camera.Rotation.x, (float)GD.RandRange(1, 2), delta),
                    Mathf.Lerp(camera.Rotation.y, (float)GD.RandRange(-1, 1), delta),
                    camera.Rotation.z
                    );

                // Shake
                camera.Set("shakeForce", 0.002);
                camera.Set("shakeTime", 0.2);
            }

            // Audio
            AudioStreamPlayer3D shoot = ((AudioStreamPlayer3D)audioNode.GetNode("shoot"));
            shoot.PitchScale = (float)GD.RandRange(0.9, 1.1);
            shoot.Play();

            // Update crosshair
            crosshair.RectScale = crosshair.RectScale.LinearInterpolate(new Vector2(4, 4), 10 * delta);

            if (bulletRay.IsColliding())
            {
                // Object collision
                CollisionObject collisionObject = (CollisionObject)bulletRay.GetCollider();

                // Add spark to props.
                if (collisionObject.IsInGroup("props"))
                {
                    // Add Spark
                    Particles spark = (Particles)sparkScene.Instance();
                    ((Node)bulletRay.GetCollider()).AddChild(spark);

                    spark.GlobalTransform = new Transform(spark.GlobalTransform.basis, bulletRay.GetCollisionPoint());
                    spark.Emitting        = true;
                }

                // Add Muzzle
                Particles muzzle = (Particles)muzzleScene.Instance();
                barrelNode.AddChild(muzzle);
                muzzle.Emitting = true;

                if (collisionObject is KinematicBody)
                {
                    // Add Blood splatter
                    Particles splatter = (Particles)splatterScene.Instance();
                    ((Node)bulletRay.GetCollider()).AddChild(splatter);

                    splatter.GlobalTransform = new Transform(splatter.GlobalTransform.basis, bulletRay.GetCollisionPoint());
                    splatter.Emitting        = true;

                    int localDamage = 0;
                    if (collisionObject.IsInGroup("head"))
                    {
                        localDamage = (int)GD.RandRange(damage / 2, damage);
                    }
                    else
                    {
                        localDamage = (int)GD.RandRange(damage / 3, damage / 2);
                    }

                    int colliderId = Convert.ToInt32(collisionObject.Name);

                    // Send damage report.
                    GameState.instance.EmitSignal(nameof(GameState.takeDamage), colliderId, localDamage);
                    return;
                }
                else if (collisionObject.IsInGroup("props") || collisionObject.IsInGroup("walls"))
                {
                    // Apply force to rigid body other than hitbox
                    if (bulletRay.GetCollider() is RigidBody)
                    {
                        int localDamage = (int)GD.RandRange(damage / 1.5f, damage);
                        ((RigidBody)bulletRay.GetCollider()).ApplyCentralImpulse(-bulletRay.GetCollisionNormal() * (localDamage * 0.3f));
                    }

                    // Apply decal
                    Spatial decal = (Spatial)decalScene.Instance();
                    ((Node)bulletRay.GetCollider()).AddChild(decal);
                    decal.GlobalTransform = new Transform(
                        decal.GlobalTransform.basis,
                        bulletRay.GetCollisionPoint()
                        );

                    decal.LookAt(bulletRay.GetCollisionPoint() + bulletRay.GetCollisionNormal(), new Vector3(1, 1, 0));
                    return;
                }
            }
        }
        else
        {
            AudioStreamPlayer3D empty = ((AudioStreamPlayer3D)audioNode.GetNode("empty"));
            if (!empty.Playing)
            {
                empty.PitchScale = (float)GD.RandRange(0.9, 1.1);
                empty.Play();
            }
        }
    }