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); }
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); } } }