예제 #1
0
        public ExplosionPreset(
            ProtoObjectCharredGround protoObjectCharredGround,
            double serverDamageApplyDelay,
            TextureAtlasResource[] spriteAtlasResources,
            ReadOnlySoundResourceSet soundSet,
            Color?spriteColorAdditive,
            Color?spriteColorMultiplicative,
            double spriteBrightness,
            double spriteAnimationDuration,
            Size2F spriteSize,
            DrawOrder spriteDrawOrder,
            double blastwaveDelay,
            double blastwaveAnimationDuration,
            Color blastWaveColor,
            Size2F blastwaveSizeFrom,
            Size2F blastwaveSizeTo,
            double lightWorldSize,
            double lightDuration,
            Color lightColor,
            float screenShakesDuration,
            float screenShakesWorldDistanceMin,
            float screenShakesWorldDistanceMax,
            byte soundsCuesNumber)
        {
            this.ServerDamageApplyDelay = serverDamageApplyDelay;
            this.SpriteAtlasResources   = spriteAtlasResources;
            this.SoundSet                  = soundSet;
            this.SpriteColorAdditive       = spriteColorAdditive;
            this.SpriteColorMultiplicative = spriteColorMultiplicative ?? Colors.White;
            this.SpriteBrightness          = (float)spriteBrightness;
            this.SpriteAnimationDuration   = spriteAnimationDuration;
            this.SpriteSize                = spriteSize;

            this.BlastwaveDelay             = blastwaveDelay;
            this.BlastwaveAnimationDuration = blastwaveAnimationDuration;
            this.BlastWaveColor             = blastWaveColor;
            this.BlastwaveSizeFrom          = blastwaveSizeFrom;
            this.BlastwaveSizeTo            = blastwaveSizeTo;

            this.LightWorldSize = lightWorldSize;
            this.LightDuration  = lightDuration;
            this.LightColor     = lightColor;

            this.ScreenShakesDuration         = screenShakesDuration;
            this.ScreenShakesWorldDistanceMin = screenShakesWorldDistanceMin;
            this.ScreenShakesWorldDistanceMax = screenShakesWorldDistanceMax;
            this.SoundsCuesNumber             = soundsCuesNumber;
            this.SpriteDrawOrder          = spriteDrawOrder;
            this.ProtoObjectCharredGround = protoObjectCharredGround;

            if (this.SoundSet.Count == 0)
            {
                Api.Logger.Warning("No sounds in the explosion sounds preset - please check the sounds path");
            }
        }
예제 #2
0
        // helper method to create and setup the explosion preset
        public static ExplosionPreset CreatePreset(
            ProtoObjectCharredGround protoObjectCharredGround,
            double serverDamageApplyDelay,
            string soundSetPath,
            double spriteAnimationDuration,
            string spriteSetPath,
            byte spriteAtlasColumns,
            byte spriteAtlasRows,
            Size2F spriteWorldSize,
            double blastwaveDelay,
            double blastwaveAnimationDuration,
            Color blastWaveColor,
            Size2F blastwaveWorldSizeFrom,
            Size2F blastwaveWorldSizeTo,
            double lightDuration,
            double lightWorldSize,
            Color lightColor,
            double screenShakesDuration,
            double screenShakesWorldDistanceMin,
            double screenShakesWorldDistanceMax,
            Color?spriteColorAdditive       = null,
            Color?spriteColorMultiplicative = null,
            double spriteBrightness         = 1,
            DrawOrder spriteDrawOrder       = DrawOrder.Explosion,
            byte soundsCuesNumber           = 17)
        {
            var sounds = new SoundResourceSet()
                         .Add(soundSetPath)
                         .ToReadOnly();

            using var tempFilePaths = Api.Shared.FindFilesWithTrailingNumbers(
                      ContentPaths.Textures + spriteSetPath);
            var filePaths = tempFilePaths.AsList();

            if (filePaths.Count == 0)
            {
                Api.Logger.Error("The explosion preset is empty - no explosion textures found at "
                                 + spriteSetPath);
            }

            var spriteAtlasResources = new TextureAtlasResource[filePaths.Count];

            for (var index = 0; index < filePaths.Count; index++)
            {
                var filePath = filePaths[index];
                spriteAtlasResources[index] = new TextureAtlasResource(filePath,
                                                                       spriteAtlasColumns,
                                                                       spriteAtlasRows,
                                                                       isTransparent: true);
            }

            return(new ExplosionPreset(protoObjectCharredGround,
                                       serverDamageApplyDelay,
                                       spriteAtlasResources,
                                       sounds,
                                       spriteColorAdditive,
                                       spriteColorMultiplicative,
                                       spriteBrightness,
                                       spriteAnimationDuration,
                                       spriteWorldSize * ScriptingConstants.TileSizeRealPixels,
                                       spriteDrawOrder,
                                       blastwaveDelay,
                                       blastwaveAnimationDuration,
                                       blastWaveColor,
                                       blastwaveWorldSizeFrom * ScriptingConstants.TileSizeRealPixels,
                                       blastwaveWorldSizeTo * ScriptingConstants.TileSizeRealPixels,
                                       lightWorldSize,
                                       lightDuration,
                                       lightColor,
                                       (float)screenShakesDuration,
                                       (float)screenShakesWorldDistanceMin,
                                       (float)screenShakesWorldDistanceMax,
                                       soundsCuesNumber));
        }
예제 #3
0
        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);
            });
        }