protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); var publicState = data.PublicState; var clientState = data.ClientState; var sceneObject = data.GameObject.ClientSceneObject; clientState.RendererLight = ClientLighting.CreateLightSourceSpot( sceneObject, color: LightColors.BioLuminescencePink, size: 12, logicalSize: 5.5, positionOffset: (0.5, 0.7)); void RefreshLightSourceSpot() { // display light only if the bush has fruit clientState.RendererLight.IsEnabled = publicState.HasHarvest; } publicState.ClientSubscribe( _ => _.HasHarvest, _ => RefreshLightSourceSpot(), data.ClientState); RefreshLightSourceSpot(); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); var worldObject = data.GameObject; // setup light source var lightSource = ClientLighting.CreateLightSourceSpot( worldObject.ClientSceneObject, color: Color.FromArgb(0x99, 0xFF, 0xFF, 0xFF), size: 1, spritePivotPoint: (0.5, 0.5), positionOffset: (1.47, 0.78)); var animatedSpritePositionOffset = (277 / (double)ScriptingConstants.TileSizeRealPixels, 171 / (double)ScriptingConstants.TileSizeRealPixels); this.ClientSetupManufacturerActiveAnimation( worldObject, data.PublicState, this.textureAtlasOilPumpActive, animatedSpritePositionOffset, frameDurationSeconds: 0.3, autoInverseAnimation: true, randomizeInitialFrame: true, onRefresh: isActive => lightSource.IsEnabled = isActive); data.ClientState.SoundEmitter.CustomMaxDistance = 10f; data.ClientState.SoundEmitter.Volume = 0.5f; }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); // add sprite sheet animation var sceneObject = data.GameObject.ClientSceneObject; sceneObject.AddComponent <ClientComponentSpriteSheetAnimator>() .Setup(data.ClientState.Renderer, ClientComponentSpriteSheetAnimator.CreateAnimationFrames(this.atlasTexture), isLooped: true, frameDurationSeconds: 3 / 60.0); // add light source at the firing fuse var lightSource = ClientLighting.CreateLightSourceSpot( sceneObject, LightColors.WoodFiring, size: (3, 3), logicalSize: 0, positionOffset: (0.31, 0.31)); // add light flickering sceneObject.AddComponent <ClientComponentLightSourceEffectFlickering>() .Setup(lightSource, flickeringPercents: 10, flickeringChangePercentsPerSecond: 70); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); // setup light source var lightSource = ClientLighting.CreateLightSourceSpot( Client.Scene.GetSceneObject(data.GameObject), color: LightColors.WoodFiring, size: 1.25f, spritePivotPoint: (0.5, 0.5), positionOffset: (1, 1)); // add light flickering lightSource.SceneObject .AddComponent <ClientComponentLightSourceEffectFlickering>() .Setup(lightSource, flickeringPercents: 5, flickeringChangePercentsPerSecond: 50); var animatedSpritePositionOffset = (85 / 128.0, 111 / 128.0); this.ClientSetupManufacturerActiveAnimation( data.GameObject, data.SyncPublicState, this.textureAtlasOvenActive, animatedSpritePositionOffset, frameDurationSeconds: 0.08, autoInverseAnimation: false, onRefresh: isActive => { lightSource.IsEnabled = isActive; }); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); var worldObject = data.GameObject; // setup light source var lightSource = ClientLighting.CreateLightSourceSpot( Client.Scene.GetSceneObject(worldObject), color: LightColors.WoodFiring, size: 1, spritePivotPoint: (0.5, 0.5), positionOffset: (2.3, 0.9)); var animatedSpritePositionOffset = (541 / 256.0, 171 / 256.0); this.ClientSetupManufacturerActiveAnimation( worldObject, data.PublicState, this.textureAtlasActive, animatedSpritePositionOffset, frameDurationSeconds: 1 / 12f, autoInverseAnimation: false, randomizeInitialFrame: true, onRefresh: isActive => { lightSource.IsEnabled = isActive; }); }
protected virtual BaseClientComponentLightSource ClientCreateLightSource( IItem item, ICharacter character) { return(ClientLighting.CreateLightSourceSpot( character.ClientSceneObject, this.ItemLightConfig)); }
protected BaseClientComponentLightSource ClientCreateLightSource(IClientSceneObject sceneObject) { return(ClientLighting.CreateLightSourceSpot( sceneObject, color: LightColors.PragmiumLuminescenceSource.WithAlpha(0xAA), size: (5, 11), positionOffset: (0.5, 1.3))); }
protected override BaseClientComponentLightSource ClientCreateLightSource(IClientSceneObject sceneObject) { return(ClientLighting.CreateLightSourceSpot( sceneObject, color: LightColors.ElectricCold, size: (4, 8), positionOffset: (0.95, 1.3))); }
/// <summary> /// This is a special client method which is invoked for current player character only /// to add a very faint light around it in case the character doesn't have any active light item /// (otherwise nights will be too dark). /// </summary> public static BaseClientComponentLightSource ClientCreateDefaultLightSource(ICharacter character) { return(ClientLighting.CreateLightSourceSpot( Client.Scene.GetSceneObject(character), color: Colors.White.WithAlpha(0x28), size: 10, spritePivotPoint: (0.5, 0.5), positionOffset: (0, 0.5))); }
protected virtual BaseClientComponentLightSource ClientCreateLightSource(IClientSceneObject sceneObject) { return(ClientLighting.CreateLightSourceSpot( sceneObject, color: this.LightColor, size: (float)this.LightSize, spritePivotPoint: this.LightWorldSpritePivotPoint, positionOffset: this.LightWorldOffset)); }
public static ClientComponentSpriteLightSource ClientInitializeLightForNode(IStaticWorldObject worldObject) { return(ClientLighting.CreateLightSourceSpot( worldObject.ClientSceneObject, color: LightColors.PragmiumLuminescenceNode, size: 5, spritePivotPoint: (0.5, 0.5), positionOffset: (0.5, 0.55))); }
public static ClientComponentSpriteLightSource ClientInitializeLightForSource(IClientSceneObject sceneObject) { return(ClientLighting.CreateLightSourceSpot( sceneObject, color: LightColors.PragmiumLuminescenceSource, size: 14, spritePivotPoint: (0.5, 0.5), positionOffset: (1, 1.35))); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); ClientLighting.CreateLightSourceSpot( data.GameObject.ClientSceneObject, color: LightColors.PragmiumLuminescenceNode.WithAlpha(0x66), size: (3, 4), positionOffset: (0.5, 0.5)); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); ClientLighting.CreateLightSourceSpot( Client.Scene.GetSceneObject(data.GameObject), color: LightColors.Lava, size: (12, 10), positionOffset: (1.5, 1)); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); ClientLighting.CreateLightSourceSpot( data.GameObject.ClientSceneObject, color: LightColors.Lava, size: (10.5, 15), positionOffset: (1, 1.5)); }
protected virtual BaseClientComponentLightSource ClientCreateActiveEngineLightSource( IDynamicWorldObject vehicle) { return(ClientLighting.CreateLightSourceSpot( vehicle.ClientSceneObject, color: this.LightColor, size: this.LightSize, logicalSize: this.LightLogicalSize, spritePivotPoint: (0.5, 0.5), positionOffset: this.LightPositionOffset)); }
/// <summary> /// This is a special client method which is invoked for current player character only /// to add a very faint light around it in case the character doesn't have any active light item /// (otherwise nights will be too dark). /// </summary> public static BaseClientComponentLightSource ClientCreateDefaultLightSource(ICharacter character) { return(ClientLighting.CreateLightSourceSpot( character.ClientSceneObject, color: Colors.White.WithAlpha(0x28), size: 10, // the light is very faint so we're using a smaller logical size logicalSize: 6, spritePivotPoint: (0.5, 0.5), positionOffset: (0, 0.5))); }
protected override void ClientInitialize(ClientInitializeData data) { var worldObject = data.GameObject; var clientState = data.ClientState; this.ClientAddAutoStructurePointsBar(data); clientState.Renderer = Client.Rendering.CreateSpriteRenderer( worldObject, this.DefaultTexture); var spriteRenderer = data.ClientState.Renderer; var drawOrderOffsetY = 0.5; spriteRenderer.DrawOrderOffsetY = drawOrderOffsetY; // setup light source var lightSource = ClientLighting.CreateLightSourceSpot( worldObject.ClientSceneObject, color: LightColors.WoodFiring, size: 11, spritePivotPoint: (0.5, 0.5), positionOffset: (0.5, 0.5)); // add light flickering lightSource.SceneObject .AddComponent <ClientComponentLightSourceEffectFlickering>() .Setup(lightSource, flickeringPercents: 10, flickeringChangePercentsPerSecond: 50); // setup active animation this.ClientSetupManufacturerActiveAnimation( worldObject, data.PublicState, this.textureAtlasCampfireActive, positionOffset: (0, 0), drawOrderOffsetY: drawOrderOffsetY, frameDurationSeconds: 1 / 12.5, autoInverseAnimation: false, randomizeInitialFrame: true, onRefresh: isActive => { // refresh primary sprite spriteRenderer.TextureResource = this.GetTextureResource(worldObject); // enable the light renderer when the fire animation is active lightSource.IsEnabled = isActive; }); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); var publicState = data.PublicState; var worldObject = data.GameObject; var sceneObject = Client.Scene.GetSceneObject(worldObject); // setup light source var lightSource = ClientLighting.CreateLightSourceSpot( Client.Scene.GetSceneObject(worldObject), color: LightColors.WoodFiring, size: 3.5, spritePivotPoint: (0.5, 0.5), positionOffset: (1.12, 0.51 + VerticalOffset)); Vector2D animatedSpritePositionOffset = (195 / 256.0, VerticalOffset + 83 / 256.0); var clientState = worldObject.GetClientState <StaticObjectClientState>(); var overlayRenderer = Client.Rendering.CreateSpriteRenderer( sceneObject, this.textureFurnaceActive, DrawOrder.Default, positionOffset: animatedSpritePositionOffset, spritePivotPoint: Vector2D.Zero); overlayRenderer.DrawOrderOffsetY = VerticalOffset - animatedSpritePositionOffset.Y - 0.01; var soundEmitter = this.ClientCreateActiveStateSoundEmitterComponent(worldObject); soundEmitter.Volume = 0.7f; publicState.ClientSubscribe( s => s.IsActive, callback: RefreshActiveState, subscriptionOwner: clientState); RefreshActiveState(publicState.IsActive); void RefreshActiveState(bool isActive) { overlayRenderer.IsEnabled = isActive; lightSource.IsEnabled = isActive; soundEmitter.IsEnabled = isActive; } }
public void Setup( ICharacter character, IComponentSkeleton skeletonRenderer, IProtoItemWeaponRanged protoWeapon) { byte flashAtlasRow = 0, smokeAtlasRow = 1; this.character = character; this.skeletonRenderer = skeletonRenderer; this.protoWeapon = protoWeapon; this.description = protoWeapon.MuzzleFlashDescription; var muzzleFlashTextureAtlas = this.description.TextureAtlas; this.animationDuration = this.description.TextureAnimationDurationSeconds; this.lightDuration = this.description.LightDurationSeconds; // create light renderer this.lightSource = ClientLighting.CreateLightSourceSpot( this.SceneObject, color: this.description.LightColor, spritePivotPoint: (0.5, 0.5), size: (float)this.description.LightPower); this.CreateSpriteRendererAndAnimator( out this.spriteRendererSmoke, out var componentAnimatorSmoke, smokeAtlasRow, protoWeapon, muzzleFlashTextureAtlas); this.CreateSpriteRendererAndAnimator( out this.spriteRendererFlash, out var componentAnimatorFlash, flashAtlasRow, protoWeapon, muzzleFlashTextureAtlas); this.Destroy(this.animationDuration); this.lightSource.Destroy(this.animationDuration); this.spriteRendererFlash.Destroy(this.animationDuration); this.spriteRendererSmoke.Destroy(this.animationDuration); componentAnimatorFlash.Destroy(this.animationDuration); componentAnimatorSmoke.Destroy(this.animationDuration); this.Update(deltaTime: 0); }
protected override ITextureResource ClientSetupTileRendering(Tile tile, IClientSceneObject sceneObject) { var position = tile.Position; if (position.X % 2 == 0 && position.Y % 2 == 0) { // add light source ClientLighting.CreateLightSourceSpot( sceneObject, color: LightColors.Lava, size: (12, 12 * 1.5), positionOffset: (0.5, 0.5)); } return(base.ClientSetupTileRendering(tile, sceneObject)); }
public void Setup( IComponentSpriteRenderer rocketRenderer, IComponentSpriteRenderer mast1Renderer, IComponentSpriteRenderer mast2Renderer, double timePassedSinceLaunch) { this.rocketRenderer = rocketRenderer; this.time = timePassedSinceLaunch - RocketLaunchAnimationStartDelay; this.mast1Renderer = mast1Renderer; this.mast2Renderer = mast2Renderer; this.defaultRocketRendererPositionOffset = rocketRenderer.PositionOffset; this.defaultRocketRendererDrawOrderOffsetY = rocketRenderer.DrawOrderOffsetY; this.defaultMast1RendererPositionOffset = mast1Renderer.PositionOffset; this.defaultMast2RendererPositionOffset = mast2Renderer.PositionOffset; var sceneObject = rocketRenderer.SceneObject; this.fireAnimators = new ClientComponentSpriteSheetAnimator[RocketFireOffsets.Length]; this.lightRenderers = new BaseClientComponentLightSource[RocketFireOffsets.Length]; for (var index = 0; index < this.fireAnimators.Length; index++) { var fireRenderer = Client.Rendering.CreateSpriteRenderer(sceneObject, TextureResourceRocketFireAnimation); this.fireAnimators[index] = sceneObject.AddComponent <ClientComponentSpriteSheetAnimator>(); this.fireAnimators[index].Setup(fireRenderer, ClientComponentSpriteSheetAnimator.CreateAnimationFrames( TextureResourceRocketFireAnimation), isLooped: true, frameDurationSeconds: 1 / 30.0, randomizeInitialFrame: true); var lightRender = ClientLighting.CreateLightSourceSpot(sceneObject, EngineLightSourceConfig); this.lightRenderers[index] = lightRender; } // toggle rocket renderer to ensure it's drawn on front rocketRenderer.IsEnabled = false; rocketRenderer.IsEnabled = true; this.Update(0); }
public void Setup( ICharacter character, IComponentSkeleton skeletonRenderer, IProtoItemWeaponRanged protoWeapon) { byte flashAtlasRow = 0, smokeAtlasRow = 1; this.character = character; this.skeletonRenderer = skeletonRenderer; this.protoWeapon = protoWeapon; this.description = protoWeapon.MuzzleFlashDescription; var muzzleFlashTextureAtlas = this.description.TextureAtlas; this.animationDuration = this.description.TextureAnimationDurationSeconds; this.lightDuration = this.description.LightDurationSeconds; // create light renderer this.lightSource = ClientLighting.CreateLightSourceSpot( this.SceneObject, color: this.description.LightColor, spritePivotPoint: (0.5, 0.5), size: (float)this.description.LightPower, // we don't want to display nickname/healthbar for the firing character, it's too quick anyway logicalSize: 0); this.CreateSpriteRendererAndAnimator( out this.spriteRendererSmoke, out this.componentAnimatorSmoke, smokeAtlasRow, protoWeapon, muzzleFlashTextureAtlas); this.CreateSpriteRendererAndAnimator( out this.spriteRendererFlash, out this.componentAnimatorFlash, flashAtlasRow, protoWeapon, muzzleFlashTextureAtlas); this.Update(deltaTime: 0); }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); data.ClientState.Renderer.DrawOrderOffsetY = 0.355; // add sprite sheet animation var sceneObject = Client.Scene.GetSceneObject(data.GameObject); sceneObject .AddComponent <ClientComponentSpriteSheetAnimator>() .Setup(data.ClientState.Renderer, ClientComponentSpriteSheetAnimator.CreateAnimationFrames(this.atlasTexture), frameDurationSeconds: 0.15f); // add light source at the firing fuse ClientLighting.CreateLightSourceSpot( sceneObject, Color.FromRgb(0xFF, 0x55, 0x22), size: (3, 3), positionOffset: (0.4, 0.4)); }
public override void OnSkeletonCreated(IComponentSkeleton skeleton) { base.OnSkeletonCreated(skeleton); skeleton.DrawOrderOffsetY = -0.2; skeleton.AnimationEvent += SkeletonOnAnimationEventFootstep; // setup attack animations { var mixIn = 0.033333f; var mixOut = 0.15f; var mixInStatic = 0.15f; // fast mix-in into attacks, slower mix-out skeleton.SetMixDuration(null, "AttackRangedHorizontal", mixIn, mixOut); skeleton.SetMixDuration(null, "AttackRangedHorizontal_Static", mixInStatic, mixOut); skeleton.SetMixDuration(null, "AttackRangedVertical", mixIn, mixOut); skeleton.SetMixDuration(null, "AttackRangedVertical_Static", mixInStatic, mixOut); // fast mix between attacks skeleton.SetMixDuration("AttackRangedHorizontal", "AttackRangedVertical", mixIn, mixIn); skeleton.SetMixDuration("AttackRangedHorizontal_Static", "AttackRangedVertical_Static", mixIn, mixIn); // fast attack animation skeleton.SetMixDuration(null, "AttackAOE", 0.0333f, 0.1f); } var sceneObject = skeleton.SceneObject; if (sceneObject.AttachedWorldObject is not null) { ClientLighting.CreateLightSourceSpot( sceneObject, color: LightColors.PragmiumLuminescenceSource, size: 25, spritePivotPoint: (0.5, 0.5), positionOffset: (0, 0)); } }
protected override void ClientInitialize(ClientInitializeData data) { base.ClientInitialize(data); var worldObject = data.GameObject; // setup light source var lightSource = ClientLighting.CreateLightSourceSpot( Client.Scene.GetSceneObject(worldObject), color: LightColors.WoodFiring, size: 3, spritePivotPoint: (0.5, 0.5), positionOffset: (1, 0.51f + VerticalOffset)); // add light flickering lightSource.SceneObject .AddComponent <ClientComponentLightSourceEffectFlickering>() .Setup(lightSource, flickeringPercents: 5, flickeringChangePercentsPerSecond: 50); var animatedSpritePositionOffset = (81 / 128.0, VerticalOffset + 29 / 128.0); this.ClientSetupManufacturerActiveAnimation( worldObject, data.PublicState, this.textureAtlasFurnaceActive, animatedSpritePositionOffset, frameDurationSeconds: 0.08, autoInverseAnimation: false, drawOrderOffsetY: VerticalOffset, randomizeInitialFrame: true, onRefresh: isActive => { lightSource.IsEnabled = isActive; }); data.ClientState.SoundEmitter.Volume = 0.7f; }
public static void ClientAddHitSparks( IReadOnlyWeaponHitSparksPreset hitSparksPreset, WeaponHitData hitData, IWorldObject hitWorldObject, IProtoWorldObject protoWorldObject, Vector2D worldObjectPosition, int projectilesCount, ObjectMaterial objectMaterial, bool randomizeHitPointOffset, bool randomRotation, DrawOrder drawOrder, double scale = 1.0, double animationFrameDuration = 2 / 60.0) { var sceneObject = Api.Client.Scene.CreateSceneObject("Temp_HitSparks"); sceneObject.Position = worldObjectPosition; var hitPoint = hitData.HitPoint.ToVector2D(); if (!hitData.IsCliffsHit) { // move hitpoint a bit closer to the center of the object hitPoint = WeaponSystem.SharedOffsetHitWorldPositionCloserToObjectCenter( hitWorldObject, protoWorldObject, hitPoint, isRangedWeapon: randomizeHitPointOffset); } var sparksEntry = hitSparksPreset.GetForMaterial(objectMaterial); if (projectilesCount == 1 && randomizeHitPointOffset && sparksEntry.AllowRandomizedHitPointOffset) { // randomize hitpoint a bit by adding a little random offset var maxOffsetDistance = 0.2; var range = maxOffsetDistance * RandomHelper.NextDouble(); var angleRad = 2 * Math.PI * RandomHelper.NextDouble(); var randomOffset = new Vector2D(range * Math.Cos(angleRad), range * Math.Sin(angleRad)); hitPoint += randomOffset; } var componentSpriteRender = Api.Client.Rendering.CreateSpriteRenderer( sceneObject, positionOffset: hitPoint, spritePivotPoint: (0.5, sparksEntry.PivotY), drawOrder: drawOrder); componentSpriteRender.DrawOrderOffsetY = -hitPoint.Y; componentSpriteRender.Scale = (float)scale * Math.Pow(1.0 / projectilesCount, 0.35); if (sparksEntry.UseScreenBlending) { componentSpriteRender.BlendMode = BlendMode.Screen; } if (randomRotation) { componentSpriteRender.RotationAngleRad = (float)(RandomHelper.NextDouble() * 2 * Math.PI); } var componentAnimator = sceneObject.AddComponent <ClientComponentSpriteSheetAnimator>(); var hitSparksEntry = sparksEntry; componentAnimator.Setup( componentSpriteRender, hitSparksEntry.SpriteSheetAnimationFrames, frameDurationSeconds: animationFrameDuration, isLooped: false); var totalAnimationDuration = animationFrameDuration * componentAnimator.FramesCount; var totalDurationWithLight = 0.15 + totalAnimationDuration; if (hitSparksEntry.LightColor.HasValue) { // create light spot (even for melee weapons) var lightSource = ClientLighting.CreateLightSourceSpot( sceneObject, color: hitSparksEntry.LightColor.Value, spritePivotPoint: (0.5, 0.5), size: 7, // we don't want to display nickname/healthbar for the firing character, it's too quick anyway logicalSize: 0, positionOffset: hitPoint); ClientComponentOneShotLightAnimation.Setup(lightSource, totalDurationWithLight); } componentSpriteRender.Destroy(totalAnimationDuration); componentAnimator.Destroy(totalAnimationDuration); sceneObject.Destroy(totalDurationWithLight); }
public static void ClientExplode( Vector2D position, ExplosionPreset explosionPreset, float volume = 1.0f) { // add screen shakes ClientComponentCameraScreenShakes.AddRandomShakes( duration: explosionPreset.ScreenShakesDuration, worldDistanceMin: explosionPreset.ScreenShakesWorldDistanceMin, worldDistanceMax: explosionPreset.ScreenShakesWorldDistanceMax); // play sound 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; // 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: DrawOrder.Explosion, 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 var explosionLight = ClientLighting.CreateLightSourceSpot( explosionSceneObject, 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 = new Size2F(sizeX, sizeY); }); }); } ClientGroundExplosionAnimationHelper.OnExplode( delaySeconds: explosionSpriteAnimationDuration / 2, position: position); }