Example #1
0
        private void ClientRemote_OnMiningSoundCue(
            IDynamicWorldObject objectDrone,
            uint ownerCharacterPartyId,
            Vector2Ushort fallbackPosition)
        {
            if (objectDrone is not null &&
                !objectDrone.IsInitialized)
            {
                objectDrone = null;
            }

            var position = objectDrone?.Position ?? fallbackPosition.ToVector2D();

            position += this.BeamOriginOffset;

            var isByPartyMember = ownerCharacterPartyId > 0 &&
                                  ownerCharacterPartyId == PartySystem.ClientCurrentParty?.Id;

            ClientSoundCueManager.OnSoundEvent(position,
                                               isPartyMember: isByPartyMember);
        }
Example #2
0
        public static void ClientExplode(
            Vector2D position,
            ExplosionPreset explosionPreset,
            float volume = 1.0f)
        {
            // add screen shakes
            if (explosionPreset.ScreenShakesDuration > 0)
            {
                ClientComponentCameraScreenShakes.AddRandomShakes(
                    duration: explosionPreset.ScreenShakesDuration,
                    worldDistanceMin: explosionPreset.ScreenShakesWorldDistanceMin,
                    worldDistanceMax: explosionPreset.ScreenShakesWorldDistanceMax);
            }

            // play sound
            if (volume > 0)
            {
                var explosionSoundEmitter = Client.Audio.PlayOneShot(explosionPreset.SoundSet.GetSound(),
                                                                     worldPosition: position,
                                                                     volume: volume,
                                                                     pitch: RandomHelper.Range(0.95f, 1.05f));

                // extend explosion sound distance
                explosionSoundEmitter.CustomMinDistance = (float)explosionPreset.LightWorldSize / 3;
                explosionSoundEmitter.CustomMaxDistance = (float)explosionPreset.LightWorldSize;

                // add sound cues
                for (var i = 0; i < explosionPreset.SoundsCuesNumber; i++)
                {
                    ClientTimersSystem.AddAction(delaySeconds: i * 0.1,
                                                 () => ClientSoundCueManager.OnSoundEvent(position,
                                                                                          isPartyMember: false));
                }
            }

            // create explosion renderer
            var explosionSpriteAnimationDuration = explosionPreset.SpriteAnimationDuration;
            var explosionSceneObject             = Client.Scene.CreateSceneObject("Temp explosion",
                                                                                  position);

            explosionSceneObject.Destroy(delay: explosionSpriteAnimationDuration);

            var explosionSpriteRenderer = Client.Rendering.CreateSpriteRenderer(
                explosionSceneObject,
                TextureResource.NoTexture,
                drawOrder: explosionPreset.SpriteDrawOrder,
                spritePivotPoint: (0.5, 0.5));

            explosionSpriteRenderer.Color = explosionPreset.SpriteColorMultiplicative;
            explosionSpriteRenderer.Size  = explosionPreset.SpriteSize;
            if (explosionPreset.SpriteColorAdditive.HasValue
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                || explosionPreset.SpriteBrightness != 1)
            {
                var renderingMaterial = RenderingMaterial.Create(EffectResourceAdditiveColorEffect);
                renderingMaterial.EffectParameters
                .Set("ColorAdditive", explosionPreset.SpriteColorAdditive ?? Colors.Black)
                .Set("Brightness", explosionPreset.SpriteBrightness);
                explosionSpriteRenderer.RenderingMaterial = renderingMaterial;
            }

            var isFlipped = 0
                            == PositionalRandom.Get(position.ToVector2Ushort(),
                                                    minInclusive: 0,
                                                    maxExclusive: 2,
                                                    seed: 893243289);

            if (isFlipped)
            {
                explosionSpriteRenderer.DrawMode = DrawMode.FlipHorizontally;
            }

            ClientComponentOneShotSpriteSheetAnimationHelper.Setup(
                explosionSpriteRenderer,
                explosionPreset.SpriteAtlasResources.TakeByRandom(),
                explosionSpriteAnimationDuration);

            // add light source for the explosion
            if (explosionPreset.LightDuration > 0)
            {
                var explosionLightSceneObject = Client.Scene.CreateSceneObject("Temp explosion light",
                                                                               position);

                explosionLightSceneObject.Destroy(delay: explosionPreset.LightDuration);

                var explosionLight = ClientLighting.CreateLightSourceSpot(
                    explosionLightSceneObject,
                    explosionPreset.LightColor,
                    size: explosionPreset.LightWorldSize,
                    positionOffset: (0, 0),
                    spritePivotPoint: (0.5, 0.5));

                ClientComponentOneShotLightAnimation.Setup(
                    explosionLight,
                    explosionPreset.LightDuration);
            }

            // add blast wave
            var blastAnimationDuration = explosionPreset.BlastwaveAnimationDuration;

            if (blastAnimationDuration > 0)
            {
                ClientTimersSystem.AddAction(
                    explosionPreset.BlastwaveDelay,
                    () =>
                {
                    var blastSceneObject = Client.Scene.CreateSceneObject("Temp explosion",
                                                                          position);

                    blastSceneObject.Destroy(delay: blastAnimationDuration);

                    var blastSpriteRenderer = Client.Rendering.CreateSpriteRenderer(
                        blastSceneObject,
                        new TextureResource("FX/ExplosionBlast"),
                        drawOrder: DrawOrder.Explosion - 1,
                        spritePivotPoint: (0.5, 0.5));

                    // animate blast wave
                    ClientComponentGenericAnimationHelper.Setup(
                        blastSceneObject,
                        blastAnimationDuration,
                        updateCallback: alpha =>
                    {
                        var blastwaveAlpha        = (byte)(byte.MaxValue * (1 - alpha));
                        blastSpriteRenderer.Color = explosionPreset.BlastWaveColor
                                                    .WithAlpha(blastwaveAlpha);

                        var sizeX = MathHelper.Lerp(explosionPreset.BlastwaveSizeFrom.X,
                                                    explosionPreset.BlastwaveSizeTo.X,
                                                    alpha);
                        var sizeY = MathHelper.Lerp(explosionPreset.BlastwaveSizeFrom.Y,
                                                    explosionPreset.BlastwaveSizeTo.Y,
                                                    alpha);
                        blastSpriteRenderer.Size = (sizeX, sizeY);
                    });
                });
            }

            ClientGroundExplosionAnimationHelper.OnExplode(
                delaySeconds: explosionSpriteAnimationDuration / 2,
                position: position);
        }
        public static void OnWeaponShot(
            ICharacter character,
            IProtoItemWeapon protoWeapon,
            IProtoCharacter fallbackProtoCharacter,
            Vector2D fallbackPosition)
        {
            var position = character?.Position ?? fallbackPosition;

            position += (0, fallbackProtoCharacter.CharacterWorldWeaponOffsetRanged);

            ClientSoundCueManager.OnSoundEvent(position);

            const float volume = SoundConstants.VolumeWeapon;
            var         pitch  = RandomHelper.Range(0.95f, 1.05f);

            IComponentSoundEmitter emitter;
            var soundPresetWeapon = protoWeapon.SoundPresetWeapon;

            if (soundPresetWeapon.HasSound(WeaponSound.Shot))
            {
                // play shot sound from weapon
                if (character != null)
                {
                    soundPresetWeapon.PlaySound(WeaponSound.Shot,
                                                character,
                                                out emitter,
                                                volume: volume,
                                                pitch: pitch);
                }
                else
                {
                    soundPresetWeapon.PlaySound(WeaponSound.Shot,
                                                protoWorldObject: fallbackProtoCharacter,
                                                worldPosition: position,
                                                out emitter,
                                                volume: volume,
                                                pitch: pitch);
                }
            }
            else
            {
                // play sounds from the skeleton instead
                ProtoCharacterSkeleton characterSkeleton = null;
                if (character != null)
                {
                    var clientState = character.GetClientState <BaseCharacterClientState>();
                    if (clientState.HasWeaponAnimationAssigned)
                    {
                        characterSkeleton = clientState.CurrentProtoSkeleton;
                    }
                }
                else
                {
                    fallbackProtoCharacter.SharedGetSkeletonProto(character: null,
                                                                  out var characterSkeleton1,
                                                                  out _);
                    characterSkeleton = (ProtoCharacterSkeleton)characterSkeleton1;
                }

                if (characterSkeleton == null)
                {
                    emitter = null;
                }
                else
                {
                    if (character != null)
                    {
                        if (!characterSkeleton.SoundPresetWeapon.PlaySound(WeaponSound.Shot,
                                                                           character,
                                                                           out emitter,
                                                                           volume))
                        {
                            // no method returned true
                            // fallback to the default weapon sound (if there is no, it will be logged into the audio log)
                            soundPresetWeapon.PlaySound(WeaponSound.Shot,
                                                        character,
                                                        out emitter,
                                                        volume: volume,
                                                        pitch: pitch);
                        }
                    }
                    else if (!characterSkeleton.SoundPresetWeapon.PlaySound(WeaponSound.Shot,
                                                                            protoWorldObject: fallbackProtoCharacter,
                                                                            worldPosition: position,
                                                                            out emitter,
                                                                            volume))
                    {
                        // no method returned true
                        // fallback to the default weapon sound (if there is no, it will be logged into the audio log)
                        soundPresetWeapon.PlaySound(WeaponSound.Shot,
                                                    protoWorldObject: fallbackProtoCharacter,
                                                    worldPosition: position,
                                                    out emitter,
                                                    volume: volume,
                                                    pitch: pitch);
                    }
                }
            }

            if (emitter != null)
            {
                var distance = protoWeapon.SoundPresetWeaponDistance;
                emitter.CustomMinDistance = distance.min;
                emitter.CustomMaxDistance = distance.max;
            }

            if (protoWeapon is IProtoItemWeaponRanged rangedWeapon &&
                character != null &&
                ReferenceEquals(protoWeapon, GetCharacterCurrentWeaponProto(character)))
            {
                // add muzzle flash
                var clientState = character.GetClientState <BaseCharacterClientState>();
                if (!clientState.HasWeaponAnimationAssigned)
                {
                    return;
                }

                var skeletonRenderer = clientState.SkeletonRenderer;
                CreateMuzzleFlash(rangedWeapon, character, skeletonRenderer);

                var recoilAnimationName = rangedWeapon.CharacterAnimationAimingRecoilName;
                if (recoilAnimationName != null &&
                    rangedWeapon.CharacterAnimationAimingRecoilPower > 0 &&
                    rangedWeapon.CharacterAnimationAimingRecoilDuration > 0)
                {
                    SetRecoilAnimation(
                        character,
                        rangedWeapon,
                        skeletonRenderer);
                }
            }
        }