public static ClientZoneProvider Get(IProtoZone protoZone) { if (Providers.TryGetValue(protoZone, out var provider)) { return(provider); } provider = new ClientZoneProvider(protoZone); Providers[protoZone] = provider; return(provider); }
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(); }
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)); }
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)); }
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; } }