public static void ServerExplode( [CanBeNull] ICharacter character, [CanBeNull] IProtoObjectExplosive protoObjectExplosive, ExplosionPreset explosionPreset, Vector2D epicenterPosition, DamageDescription damageDescriptionCharacters, IPhysicsSpace physicsSpace, ExecuteExplosionDelegate executeExplosionCallback) { ValidateIsServer(); // schedule explosion charred ground spawning ServerTimersSystem.AddAction( // the delay is quite small and just needed to ensure // that the charred ground spawned some time after this object is destroyed delaySeconds: explosionPreset.SpriteAnimationDuration * 0.5, () => { var tilePosition = (Vector2Ushort)epicenterPosition; if (!Server.World.GetTile(tilePosition) .StaticObjects .Any(so => so.ProtoStaticWorldObject is ObjectCharredGround)) { // spawn charred ground var objectCharredGround = Server.World.CreateStaticWorldObject <ObjectCharredGround>(tilePosition); var objectCharredGroundOffset = epicenterPosition - tilePosition.ToVector2D(); if (objectCharredGroundOffset != Vector2D.Zero) { ObjectCharredGround.ServerSetWorldOffset(objectCharredGround, objectCharredGroundOffset.ToVector2F()); } } }); // schedule explosion damage ServerTimersSystem.AddAction( delaySeconds: explosionPreset.ServerDamageApplyDelay, () => { // prepare weapon caches var characterFinalStatsCache = character != null ? character.SharedGetFinalStatsCache() : FinalStatsCache.Empty; var weaponFinalCache = new WeaponFinalCache(character, characterFinalStatsCache, weapon: null, protoWeapon: null, protoObjectExplosive: protoObjectExplosive, damageDescription: damageDescriptionCharacters); // execute explosion executeExplosionCallback( positionEpicenter: epicenterPosition, physicsSpace: physicsSpace, weaponFinalCache: weaponFinalCache); }); }
protected override void PrepareProtoVehicleDestroyedExplosionPreset( out double damageRadius, out ExplosionPreset explosionPreset, out DamageDescription damageDescriptionCharacters) { damageRadius = 2.1; explosionPreset = ExplosionPresets.VeryLarge; damageDescriptionCharacters = new DamageDescription( damageValue: 75, armorPiercingCoef: 0.25, finalDamageMultiplier: 1, rangeMax: damageRadius, damageDistribution: new DamageDistribution(DamageType.Explosion, 1)); }
protected override void PrepareExplosionPreset(out ExplosionPreset explosionPreset) { explosionPreset = ExplosionPresets.Grenade; }
protected override void PrepareProtoObjectExplosive(out ExplosionPreset explosionPresets) { explosionPresets = ExplosionPresets.Large; }
protected override void PrepareProtoObjectExplosive(out ExplosionPreset explosionPresets) { explosionPresets = ExplosionPresets.SpecialPragmiumSourceExplosion; }
protected abstract void PrepareProtoVehicleDestroyedExplosionPreset( out double damageRadius, out ExplosionPreset explosionPreset, out DamageDescription damageDescriptionCharacters);
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); }
public static void ServerExplode( [CanBeNull] ICharacter character, [CanBeNull] IProtoObjectExplosive protoObjectExplosive, ExplosionPreset explosionPreset, Vector2D epicenterPosition, DamageDescription damageDescriptionCharacters, IPhysicsSpace physicsSpace, ExecuteExplosionDelegate executeExplosionCallback) { ValidateIsServer(); // schedule explosion charred ground spawning ServerTimersSystem.AddAction( delaySeconds: explosionPreset.SpriteAnimationDuration * 0.5, () => { var tilePosition = (Vector2Ushort)epicenterPosition; // remove existing charred ground objects at the same tile foreach (var staticWorldObject in Shared.WrapInTempList( Server.World.GetTile(tilePosition).StaticObjects)) { if (staticWorldObject.ProtoStaticWorldObject is ObjectCharredGround) { Server.World.DestroyObject(staticWorldObject); } } // spawn charred ground var objectCharredGround = Server.World .CreateStaticWorldObject <ObjectCharredGround>(tilePosition); var objectCharredGroundOffset = epicenterPosition - tilePosition.ToVector2D(); if (objectCharredGroundOffset != Vector2D.Zero) { ObjectCharredGround.ServerSetWorldOffset(objectCharredGround, (Vector2F)objectCharredGroundOffset); } }); // schedule explosion damage ServerTimersSystem.AddAction( delaySeconds: explosionPreset.ServerDamageApplyDelay, () => { // prepare weapon caches var characterFinalStatsCache = character?.SharedGetFinalStatsCache() ?? FinalStatsCache.Empty; var weaponFinalCache = new WeaponFinalCache(character, characterFinalStatsCache, weapon: null, protoWeapon: null, protoObjectExplosive: protoObjectExplosive, damageDescription: damageDescriptionCharacters); // execute explosion executeExplosionCallback( positionEpicenter: epicenterPosition, physicsSpace: physicsSpace, weaponFinalCache: weaponFinalCache); }); }
protected override void PrepareProtoObjectExplosive(out ExplosionPreset explosionPresets) { explosionPresets = ExplosionPresets.ExtraLargePragmiumResonanceBomb; }
protected abstract void PrepareExplosionPreset(out ExplosionPreset explosionPreset);
protected override void PrepareProtoObjectExplosive(out ExplosionPreset explosionPresets) { explosionPresets = ExplosionPresets.PragmiumResonanceBomb_Center; }
public static void ServerExplode( [CanBeNull] ICharacter character, [CanBeNull] IProtoExplosive protoExplosive, [CanBeNull] IProtoItemWeapon protoWeapon, ExplosionPreset explosionPreset, Vector2D epicenterPosition, DamageDescription damageDescriptionCharacters, IPhysicsSpace physicsSpace, ExecuteExplosionDelegate executeExplosionCallback) { ValidateIsServer(); // schedule explosion charred ground spawning var protoObjectCharredGround = explosionPreset.ProtoObjectCharredGround; if (protoObjectCharredGround is not null) { ServerTimersSystem.AddAction( delaySeconds: explosionPreset.SpriteAnimationDuration * 0.5, () => { var tilePosition = (Vector2Ushort)(epicenterPosition - protoObjectCharredGround.Layout.Center); var canSpawnCharredGround = true; var tile = Server.World.GetTile(tilePosition); if (tile.ProtoTile.Kind != TileKind.Solid || tile.EightNeighborTiles.Any(t => t.ProtoTile.Kind != TileKind.Solid)) { // allow charred ground only on solid ground canSpawnCharredGround = false; } if (canSpawnCharredGround) { // remove existing charred ground objects at the same tile foreach (var staticWorldObject in Shared.WrapInTempList( tile.StaticObjects) .EnumerateAndDispose()) { switch (staticWorldObject.ProtoStaticWorldObject) { case ProtoObjectCharredGround _: Server.World.DestroyObject(staticWorldObject); break; case IProtoObjectDeposit _: // don't show charred ground over resource deposits (it looks wrong) canSpawnCharredGround = false; break; } } } if (canSpawnCharredGround && PveSystem.ServerIsPvE) { var bounds = protoObjectCharredGround.Layout.Bounds; if (LandClaimSystem.SharedIsLandClaimedByAnyone( new RectangleInt(tilePosition, bounds.Size + (1, 1)))) { // ensure that it's not possible to create charred ground in a land claim area in PvE canSpawnCharredGround = false; } } if (canSpawnCharredGround) { // spawn charred ground var objectCharredGround = Server.World.CreateStaticWorldObject(protoObjectCharredGround, tilePosition); var objectCharredGroundOffset = epicenterPosition - tilePosition.ToVector2D(); if (objectCharredGroundOffset != Vector2D.Zero) { ProtoObjectCharredGround.ServerSetWorldOffset(objectCharredGround, (Vector2F)objectCharredGroundOffset); } } }); } // schedule explosion damage ServerTimersSystem.AddAction( delaySeconds: explosionPreset.ServerDamageApplyDelay, () => { // prepare weapon caches var characterFinalStatsCache = character?.SharedGetFinalStatsCache() ?? FinalStatsCache.Empty; var weaponFinalCache = new WeaponFinalCache(character, characterFinalStatsCache, weapon: null, protoWeapon: protoWeapon, protoAmmo: null, damageDescription: damageDescriptionCharacters, protoExplosive: protoExplosive); // execute explosion executeExplosionCallback( positionEpicenter: epicenterPosition, physicsSpace: physicsSpace, weaponFinalCache: weaponFinalCache); }); }
private void PrepareExplosionPreset(out ExplosionPreset explosionPreset) { explosionPreset = ExplosionPresets.KeiniteSmall; }