public static ClientZoneProvider Get(IProtoZone protoZone)
        {
            if (Providers.TryGetValue(protoZone, out var provider))
            {
                return(provider);
            }

            provider             = new ClientZoneProvider(protoZone);
            Providers[protoZone] = provider;
            return(provider);
        }
Exemple #2
0
        public EditorToolZoneRenderer(ClientZoneProvider zoneProvider)
        {
            this.material = RenderingMaterial.Create(new EffectResource("SolidColor"));

            this.sceneObject = Api.Client.Scene.CreateSceneObject(
                "EditorToolZones / Zone renderer - " + zoneProvider.ProtoZone.ShortId);

            this.ZoneProvider = zoneProvider;
            this.ZoneProvider.ZoneModified             += this.ZoneModifiedHandler;
            this.ZoneProvider.ZoneReset                += this.ZoneResetHandler;
            ClientComponentUpdateHelper.UpdateCallback += this.Update;

            this.RebuildAllRenderers();
        }
Exemple #3
0
        public void ClientClearSelectedZone(IProtoZone zone)
        {
            Logger.Important("Cleaning zone completely: " + zone.ShortId);
            var zoneProvider = ClientZoneProvider.Get(zone);
            var root         = zoneProvider.GetQuadTree();

            if (root.IsEmpty)
            {
                // no need to clean
                return;
            }

            zoneProvider.ClearZone();
            zoneProvider.ApplyClientChanges(forcePushChangesImmediately: true);
        }
        public EditorToolZoneRenderer(ClientZoneProvider zoneProvider)
        {
            this.material = RenderingMaterial.Create(new EffectResource("LandClaimArea"));
            this.material.EffectParameters.Set("SpriteTexture",
                                               new TextureResource("FX/EditorZoneTile"));

            this.sceneObject = Api.Client.Scene.CreateSceneObject(
                "EditorToolZones / Zone renderer - " + zoneProvider.ProtoZone.ShortId);

            this.ZoneProvider = zoneProvider;
            this.ZoneProvider.ZoneModified    += this.ZoneModifiedHandler;
            this.ZoneProvider.ZoneReset       += this.ZoneResetHandler;
            ClientUpdateHelper.UpdateCallback += this.Update;

            this.RebuildAllRenderers();
        }
        public void ClientDeleteSelectedZoneObjects(IProtoZone zone)
        {
            var clientZoneProvider = ClientZoneProvider.Get(zone);
            var worldService       = Api.Client.World;
            var zoneQuadTree       = clientZoneProvider.GetQuadTree();
            var zoneBounds         = zoneQuadTree.Bounds;

            var worldBoundsToDeleteObjects =
                worldService.GetStaticObjectsAtBounds(zoneBounds)
                .Where(o => zoneQuadTree.IsPositionFilled(o.TilePosition))
                .ToList();

            EditorStaticObjectsRemovalHelper.ClientDelete(worldBoundsToDeleteObjects);

            this.CallServer(_ => _.ServerRemote_DeleteZoneMobs(zone));
        }
Exemple #6
0
        public void ClientDeleteSelectedZoneObjects(IProtoZone zone)
        {
            var clientZoneProvider = ClientZoneProvider.Get(zone);
            var worldService       = Api.Client.World;
            var zoneQuadTree       = clientZoneProvider.GetQuadTree();
            var zoneBounds         = zoneQuadTree.Bounds;

            // TODO: it would be great if we can make that it will delete the map objects
            // that were spawned only by spawn scripts and not by hand/during loading the map from the map file.
            // Unfortunately, it's not possible to determine.
            var worldBoundsToDeleteObjects =
                worldService.GetStaticObjectsAtBounds(zoneBounds)
                .Where(o => zoneQuadTree.IsPositionFilled(o.TilePosition))
                .ToList();

            EditorStaticObjectsRemovalHelper.ClientDelete(worldBoundsToDeleteObjects);

            this.CallServer(_ => _.ServerRemote_DeleteZoneMobs(zone));
        }
Exemple #7
0
        private void ClientOnPaintZone(List <Vector2Ushort> tilePositions, bool isRepeat)
        {
            var selectedZoneForBrush = this.settings.SelectedZoneForBrush;

            if (selectedZoneForBrush is null ||
                !selectedZoneForBrush.IsRendered)
            {
                // no zone selected for brush or zone is not visible
                return;
            }

            var protoZone    = selectedZoneForBrush.Zone;
            var zoneProvider = ClientZoneProvider.Get(protoZone);

            if (!zoneProvider.IsDataReceived)
            {
                return;
            }

            var world = Client.World;
            var onlyOnTheSameHeight = this.settings.IsAllowZoneChangeOnlyOnTheSameHeight;

            if (this.settings.IsFillZoneMode)
            {
                if (isRepeat)
                {
                    // fill doesn't support repeat
                    return;
                }

                tilePositions = EditorTileHelper.GatherAllTilePositionsOfTheSameProtoTile(
                    tilePositions[0],
                    onlyOnTheSameHeight,
                    ignoreCliffsAndSlopes: true);
            }

            this.lastUsedZoneProvider = zoneProvider;

            if (onlyOnTheSameHeight &&
                !isRepeat)
            {
                // capture height when starting painting the zone
                this.capturedHeight = this.settings.IsFillZoneMode
                                          ? world.GetTile(tilePositions[0]).Height
                                          : EditorTileHelper.CalculateAverageHeight(tilePositions);
            }

            var onlyOnTheSameTileProto = this.settings.IsAllowZoneChangeOnlyOnTheSameTileProto;

            if (onlyOnTheSameTileProto &&
                !isRepeat)
            {
                // capture tile proto when starting painting the zone
                this.capturedTileProto = this.settings.IsFillZoneMode
                                             ? world.GetTile(tilePositions[0]).ProtoTile
                                             : EditorTileHelper.CalculateMostFrequentTileProto(tilePositions);
            }

            // determine the mode - adding points to zone or removing them
            var isAddMode = ClientInputManager.IsButtonHeld(GameButton.ActionUseCurrentItem, evenIfHandled: true) ||
                            ClientInputManager.IsButtonUp(GameButton.ActionUseCurrentItem, evenIfHandled: true);

            if (isAddMode)
            {
                // remove points which are already added to the zone
                tilePositions.RemoveAll(tilePosition => zoneProvider.IsFilledPosition(tilePosition));
            }
            else
            {
                // remove points which are not presented in the zone
                tilePositions.RemoveAll(tilePosition => !zoneProvider.IsFilledPosition(tilePosition));
            }

            if (tilePositions.Count == 0)
            {
                // nothing to add/remove
                return;
            }

            if (onlyOnTheSameHeight)
            {
                // remove tiles with different height
                tilePositions.RemoveAll(
                    tilePosition =>
                {
                    var tile = world.GetTile(tilePosition);
                    return(tile.Height != this.capturedHeight
                           // also do not allow painting on cliffs and slopes
                           || tile.IsCliff ||
                           tile.IsSlope);
                });
                if (tilePositions.Count == 0)
                {
                    // nothing to add/remove
                    return;
                }
            }

            if (onlyOnTheSameTileProto)
            {
                // remove tiles with different proto
                var worldService = Client.World;
                tilePositions.RemoveAll(
                    tilePosition => worldService.GetTile(tilePosition).ProtoTile
                    != this.capturedTileProto);

                if (tilePositions.Count == 0)
                {
                    // nothing to add/remove
                    return;
                }
            }

            foreach (var tilePosition in tilePositions)
            {
                if (isAddMode)
                {
                    // add point to the zone
                    zoneProvider.SetFilledPosition(tilePosition);
                }
                else
                {
                    // remove point from the zone
                    zoneProvider.ResetFilledPosition(tilePosition);
                }
            }

            this.lastUsedZoneProvider.ApplyClientChanges(forcePushChangesImmediately: tilePositions.Count > 10000);
        }
        public void RefreshZoneRenderers(List <ViewModelProtoZone> renderedZones)
        {
            var addList    = renderedZones.Except(this.zoneRenderers.Keys).ToList();
            var removeList = this.zoneRenderers.Keys.Except(renderedZones).ToList();

            // remove not rendered anymore zones
            foreach (var protoZone in removeList)
            {
                this.zoneRenderers[protoZone].Dispose();
                this.zoneRenderers.Remove(protoZone);
            }

            // add renderers for new zones
            foreach (var viewModelProtoZone in addList)
            {
                var zoneProvider = ClientZoneProvider.Get(viewModelProtoZone.Zone);
                this.zoneRenderers[viewModelProtoZone] = new EditorToolZoneRenderer(zoneProvider);
            }

            // establish the zone indexes (determines the draw order)
            var usedIndexes = this.zoneRenderers.Values.Select(zr => zr.ZoneIndex).Where(zi => zi >= 0).ToList();

            usedIndexes.Sort();

            foreach (var protoZone in renderedZones)
            {
                var zoneRenderer = this.zoneRenderers[protoZone];
                if (zoneRenderer.ZoneIndex != -1)
                {
                    // zone index is already assigned - do not change
                    continue;
                }

                sbyte selectedZoneIndex = 0;
                var   isIndexSelected   = false;
                sbyte previousIndex     = -1;

                for (var i = 0; i < usedIndexes.Count; i++)
                {
                    // iterate over all the used indexes and find "holes"
                    var zoneIndex = usedIndexes[i];
                    if (zoneIndex - previousIndex > 1)
                    {
                        selectedZoneIndex = (sbyte)(previousIndex + 1);
                        usedIndexes.Insert(i + 1, selectedZoneIndex);
                        isIndexSelected = true;
                        break;
                    }

                    previousIndex = zoneIndex;
                }

                if (!isIndexSelected)
                {
                    selectedZoneIndex = usedIndexes.Count > 0
                                            ? (sbyte)(usedIndexes.Last() + 1)
                                            : (sbyte)0;

                    usedIndexes.Add(selectedZoneIndex);
                }

                zoneRenderer.ZoneIndex = selectedZoneIndex;
            }

            foreach (var pair in this.zoneRenderers)
            {
                pair.Key.Color = pair.Value.Color;
            }
        }