Exemple #1
0
        public void Apply(
            long seed,
            double noiseProbability,
            BoundsUshort selectionBounds,
            IProtoTile protoTileTarget,
            IProtoTile protoTileNoise)
        {
            Api.Assert(protoTileTarget is not null, "Please select target tile proto");
            Api.Assert(protoTileNoise is not null, "Please select noise tile proto");
            Api.Assert(selectionBounds.Size.LengthSquared > 0, "Please select world area");
            Api.Assert(noiseProbability >= 0 || noiseProbability <= 1,
                       "Noise probability must be in range from 0 to 1 inclusive.");

            var random = new Random((int)seed);

            var world = Client.World;

            var tilesToModify = new List <Vector2Ushort>();

            for (var x = selectionBounds.MinX; x < selectionBounds.MaxX; x++)
            {
                for (var y = selectionBounds.MinY; y < selectionBounds.MaxY; y++)
                {
                    if (random.NextDouble() > noiseProbability)
                    {
                        // do not process this tile
                        continue;
                    }

                    // check tile type
                    var tilePosition = new Vector2Ushort(x, y);
                    var tile         = world.GetTile(tilePosition);
                    if (tile.ProtoTile == protoTileTarget)
                    {
                        tilesToModify.Add(tilePosition);
                    }
                }
            }

            if (tilesToModify.Count == 0)
            {
                return;
            }

            EditorClientActionsHistorySystem.DoAction(
                "Modify terrain tiles (noise)",
                onDo: () => tilesToModify.ChunkedInvoke(
                    5000,
                    chunk => this.CallServer(_ => _.ServerRemote_PlaceAt(chunk, protoTileNoise))),
                onUndo: () => tilesToModify.ChunkedInvoke(
                    5000,
                    chunk => this.CallServer(_ => _.ServerRemote_PlaceAt(chunk, protoTileTarget))),
                canGroupWithPreviousAction: false);
        }
Exemple #2
0
        /// <summary>
        /// Returns true if the location is used for the player corpses.
        /// </summary>
        public static bool IsCorpseIsland(Vector2Ushort chunkPosition, BoundsUshort worldBounds)
        {
            if (Api.IsEditor)
            {
                return(false);
            }

            var chunkPositionX = chunkPosition.X - worldBounds.Offset.X;
            var chunkPositionY = chunkPosition.Y - worldBounds.Offset.Y;

            // bottom right corner is the corpse island
            return(chunkPositionX > worldBounds.Size.X - ScriptingConstants.WorldChunkSize * 6 &&
                   chunkPositionY < ScriptingConstants.WorldChunkSize * 6);
        }
        private static BoundsUshort CalculateNewWorldBounds(BoundsUshort locationBounds, BoundsUshort oldWorldBounds)
        {
            var newSize        = oldWorldBounds.Size.ToVector2Int() + locationBounds.Size.ToVector2Int();
            var newMaxPosition = oldWorldBounds.Offset.ToVector2Int() + newSize;

            if (newMaxPosition.X > ushort.MaxValue ||
                newMaxPosition.Y > ushort.MaxValue)
            {
                throw new Exception(
                          $"Max world size exceeded: please ensure that the world size is not higher than {ushort.MaxValue}x{ushort.MaxValue} (including the world offset)");
            }

            return(new BoundsUshort(oldWorldBounds.Offset,
                                    newSize.ToVector2Ushort()));
        }
Exemple #4
0
 public void ClientGenerate(long seed, BoundsUshort worldBounds, byte startHeight)
 {
     DialogWindow.ShowDialog(
         "Generate",
         new TextBlock()
     {
         Text = "Selected world part will be DELETED!"
                + Environment.NewLine
                + "There is NO undo for this action. Are you sure?",
         TextAlignment = TextAlignment.Center
     },
         okAction: () => this.ClientGenerateMap(seed, worldBounds, startHeight),
         focusOnCancelButton: true,
         hideCancelButton: false);
 }
        private static Vector2Ushort ConvertPosition(
            BoundsUshort insertedArea,
            ushort oldX,
            ushort oldY)
        {
            var newX = oldX < insertedArea.Offset.X
                           ? oldX
                           : (ushort)(oldX + insertedArea.Size.X);

            var newY = oldY <= insertedArea.Offset.Y
                           ? oldY
                           : (ushort)(oldY + insertedArea.Size.Y);

            var newPosition = new Vector2Ushort(newX, newY);

            return(newPosition);
        }
        private void ClientApplyWorldSizeSliceExpansion()
        {
            var location     = this.settingsViewModel.ViewModelSelectWorldSizeSliceExpansionLocation;
            var insertedArea = new BoundsUshort(new Vector2Ushort(location.OffsetX, location.OffsetY),
                                                new Vector2Ushort(location.SizeX, location.SizeY));

            if (insertedArea.Size == Vector2Ushort.Zero)
            {
                NotificationSystem.ClientShowNotification("Please enter the size of expansion",
                                                          color: NotificationColor.Bad);
                return;
            }

            if (insertedArea.Size.X % ScriptingConstants.WorldChunkSize != 0 ||
                insertedArea.Size.Y % ScriptingConstants.WorldChunkSize != 0)
            {
                NotificationSystem.ClientShowNotification(
                    $"Please ensure that the size of expansion can be divided on the world chunk size ({ScriptingConstants.WorldChunkSize}) without the remainder",
                    color: NotificationColor.Bad);
                return;
            }

            this.CallServer(_ => _.ServerRemote_ApplyWorldSizeSliceExpansion(insertedArea));
        }
        private void ServerRemote_ApplyWorldSizeSliceExpansion(BoundsUshort insertedArea)
        {
            Logger.Info("Slice-expanding the world map - inserting an area: " + insertedArea);

            var oldWorldBounds = Server.World.WorldBounds;
            var oldOffset      = oldWorldBounds.Offset;
            var oldSize        = oldWorldBounds.Size;

            var oldMap = new Tile[oldSize.X, oldSize.Y];

            for (var x = 0; x < oldSize.X; x++)
            {
                for (var y = 0; y < oldSize.Y; y++)
                {
                    oldMap[x, y] = Server.World.GetTile(x + oldOffset.X,
                                                        y + oldOffset.Y);
                }
            }

            Logger.Info("Tile height data gathered");

            var oldStaticObjects = Server.World.EditorEnumerateAllStaticObjects()
                                   .Select(o => new EditorStaticObjectsRemovalHelper.RestoreObjectRequest(o))
                                   .ToList();

            Logger.Info("Static objects gathered");

            // gather zones
            var oldZones = (from protoZone in Api.FindProtoEntities <IProtoZone>()
                            select new { protoZone, snapshot = protoZone.ServerZoneInstance.QuadTree.SaveQuadTree() })
                           .ToList();

            // create new world
            var newWorldBounds = CalculateNewWorldBounds(insertedArea, oldWorldBounds);

            Server.World.CreateWorld(protoTile: Api.GetProtoEntity <TileWaterSea>(),
                                     newWorldBounds);

            Logger.Info("Server zones data gathered");

            // copy old map data to the new world
            for (var x = 0; x < oldSize.X; x++)
            {
                for (var y = 0; y < oldSize.Y; y++)
                {
                    var oldData = oldMap[x, y];
                    var oldX    = (ushort)(x + oldOffset.X);
                    var oldY    = (ushort)(y + oldOffset.Y);

                    var newPosition = ConvertPosition(insertedArea, oldX, oldY);
                    Server.World.SetTileData(newPosition,
                                             oldData.ProtoTile,
                                             oldData.Height,
                                             oldData.IsSlope,
                                             oldData.IsCliff);
                }
            }

            Server.World.FixMapTilesAll();

            Logger.Info("Map slice-expansion finished");

            // restore old static objects to the new world
            foreach (var request in oldStaticObjects)
            {
                var newPosition = ConvertPosition(insertedArea, request.TilePosition.X, request.TilePosition.Y);
                Server.World.CreateStaticWorldObject(
                    request.Prototype,
                    newPosition);
            }

            Logger.Info("Static objects restored after the slice-expansion");

            // restore zones
            foreach (var oldZoneSnapshot in oldZones)
            {
                var oldQuadTree = QuadTreeNodeFactory.Create(oldZoneSnapshot.snapshot);
                var newQuadTree = oldZoneSnapshot.protoZone.ServerZoneInstance.QuadTree;
                foreach (var oldPosition in oldQuadTree)
                {
                    var newPosition = ConvertPosition(insertedArea, oldPosition.X, oldPosition.Y);
                    newQuadTree.SetFilledPosition(newPosition);
                }
            }

            Logger.Info("Server zones data restored after the slice-expansion");
        }
Exemple #8
0
 protected abstract void ClientGenerateMap(long seed, BoundsUshort worldBounds, byte startHeight);
Exemple #9
0
            public override void Update(double deltaTime)
            {
                this.time += deltaTime;
                if (this.time > this.durationRocketAnimation)
                {
                    this.Destroy();
                    return;
                }

                var progress = this.time / this.durationRocketAnimation;

                if (this.time < 0)
                {
                    progress = 0;
                }

                // apply sine easy-in 1 - cos((x * PI) / 2)
                progress          = ApplySineEasyIn(progress);
                this.lastProgress = progress;

                var lightProgress = Math.Min(Math.Max(this.time - LightFadeInDelay, 0) / LightFadeInDuration,
                                             1);

                var rocketOffsetY = progress * RocketLaunchFinalOffsetY;

                this.rocketRenderer.PositionOffset      = this.defaultRocketRendererPositionOffset + (0, rocketOffsetY);
                this.rocketRenderer.DrawOrderOffsetY    = this.defaultRocketRendererDrawOrderOffsetY - rocketOffsetY;
                this.rocketRenderer.CustomTextureBounds = new BoundsUshort(
                    Vector2Ushort.Zero,
                    (RocketTextureCutSize.X,
                     (ushort)(RocketTextureCutSize.Y + rocketOffsetY * ScriptingConstants.TileSizeRealPixels)));

                for (var index = 0; index < this.fireAnimators.Length; index++)
                {
                    var fireOffset   = RocketFireOffsets[index];
                    var fireRenderer = this.fireAnimators[index].SpriteRenderer;
                    fireRenderer.PositionOffset   = this.rocketRenderer.PositionOffset + fireOffset;
                    fireRenderer.DrawOrderOffsetY = this.rocketRenderer.DrawOrderOffsetY - fireOffset.Y;
                    var cutProgress = MathHelper.Clamp((rocketOffsetY + fireOffset.Y + FireRendererTextureCutOffset)
                                                       / (FireRendererTextureCutSize.Y / 256.0),
                                                       0,
                                                       1);

                    fireRenderer.CustomTextureBounds = new BoundsUshort(
                        Vector2Ushort.Zero,
                        (FireRendererTextureCutSize.X,
                         (ushort)(FireRendererTextureCutSize.Y * cutProgress)));

                    var lightOffset   = RocketLightOffsets[index];
                    var lightRenderer = this.lightRenderers[index];
                    lightRenderer.PositionOffset = this.rocketRenderer.PositionOffset + lightOffset;
                    lightRenderer.Opacity        = lightProgress;
                }

                var mastProgress = (this.time + RocketLaunchAnimationStartDelay) / MastAnimationDuration;

                mastProgress = MathHelper.Clamp(mastProgress, 0, 1);
                mastProgress = ApplySineEasyIn(mastProgress);

                this.mast1Renderer.PositionOffset
                    = this.defaultMast1RendererPositionOffset
                      + (mastProgress * Mast1MaxWorldOffsetX, 0);

                this.mast2Renderer.PositionOffset
                    = this.defaultMast2RendererPositionOffset
                      + (mastProgress * Mast2MaxWorldOffsetX, 0);

                this.mast1Renderer.CustomTextureBounds = new BoundsUshort(
                    Vector2Ushort.Zero,
                    ((ushort)(Mast1TextureSize.X
                              - Mast1MaxWorldOffsetX * mastProgress * ScriptingConstants.TileSizeRealPixels),
                     Mast1TextureSize.Y));

                this.mast2Renderer.CustomTextureBounds = new BoundsUshort(
                    Vector2Ushort.Zero,
                    ((ushort)(Mast2TextureSize.X
                              - Mast2MaxWorldOffsetX * mastProgress * ScriptingConstants.TileSizeRealPixels),
                     Mast2TextureSize.Y));
            }
        public static void ClientDelete(BoundsUshort worldBoundsToDeleteObjects)
        {
            var staticObjects = Client.World.GetStaticObjectsAtBounds(worldBoundsToDeleteObjects);

            instance.ClientDeleteInternal(staticObjects);
        }
        private static ExtendMode CalculateExtendMode(ref Vector2Ushort position, BoundsUshort bounds)
        {
            var minX = bounds.MinX;
            var minY = bounds.MinY;
            // calculate max XY (inclusive margins)
            var maxX = (ushort)(bounds.MaxX - 1);
            var maxY = (ushort)(bounds.MaxY - 1);

            if (position.X == minX &&
                position.Y == minY)
            {
                return(ExtendMode.LeftDown);
            }

            if (position.X == minX &&
                position.Y == maxY)
            {
                return(ExtendMode.LeftUp);
            }

            if (position.X == maxX &&
                position.Y == minY)
            {
                return(ExtendMode.RightDown);
            }

            if (position.X == maxX &&
                position.Y == maxY)
            {
                return(ExtendMode.RightUp);
            }

            // detect which side is closest
            var distanceToLeft  = position.X - minX;
            var distanceToRight = maxX - position.X;
            var distanceToDown  = position.Y - minY;
            var distanceToUp    = maxY - position.Y;

            var minDistance = Math.Min(
                distanceToLeft,
                Math.Min(distanceToUp, Math.Min(distanceToRight, distanceToDown)));

            if (minDistance >= 1)
            {
                return(ExtendMode.Move);
            }

            if (distanceToLeft == minDistance)
            {
                position = (minX, position.Y);
                return(ExtendMode.Left);
            }

            if (distanceToRight == minDistance)
            {
                position = (maxX, position.Y);
                return(ExtendMode.Right);
            }

            if (distanceToUp == minDistance)
            {
                position = (position.X, maxY);
                return(ExtendMode.Up);
            }

            if (distanceToDown == minDistance)
            {
                position = (position.X, minY);
                return(ExtendMode.Down);
            }

            throw new Exception("Impossible");
        }
Exemple #12
0
        public static void ClientCopy(BoundsUshort worldBoundsToCopyObjects)
        {
            var staticObjects = Api.Client.World.GetStaticObjectsAtBounds(worldBoundsToCopyObjects);

            ClientCopyInternal(staticObjects);
        }
Exemple #13
0
 private static void ClientCopyCallback(BoundsUshort bounds)
 {
     EditorTerrainCopyPasteHelper.ClientCopy(bounds);
 }