public async Task Invoke(IContext context, CommandParameters parameters) { var md = context.Get <MapDocument>("ActiveDocument"); if (md == null || md.Selection.IsEmpty) { return; } var at = md.Map.Data.GetOne <ActiveTexture>(); if (String.IsNullOrWhiteSpace(at?.Name)) { return; } var edit = new Transaction(); foreach (var solid in md.Selection.OfType <Solid>()) { foreach (var face in solid.Faces) { var clone = (Face)face.Clone(); clone.Texture.Name = at.Name; edit.Add(new RemoveMapObjectData(solid.ID, face)); edit.Add(new AddMapObjectData(solid.ID, clone)); } } if (!edit.IsEmpty) { await MapDocumentOperation.Perform(md, edit); } }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var selBox = document.Selection.GetSelectionBoundingBox(); var tl = document.Map.Data.GetOne <TransformationFlags>() ?? new TransformationFlags(); var transaction = new Transaction(); var tform = Matrix4x4.CreateTranslation(-selBox.Center) * Matrix4x4.CreateScale(GetScale()) * Matrix4x4.CreateTranslation(selBox.Center); var transformOperation = new BspEditor.Modification.Operations.Mutation.Transform(tform, document.Selection.GetSelectedParents()); transaction.Add(transformOperation); transaction.Add(new FlipFaces(document.Selection)); // Check for texture transform if (tl.TextureLock) { transaction.Add(new TransformTexturesUniform(tform, document.Selection)); } await MapDocumentOperation.Perform(document, transaction); }
public async Task Fix(MapDocument document, Problem problem) { var tc = await document.Environment.GetTextureCollection(); // Get the default texture to apply var first = tc.GetBrowsableTextures() .OrderBy(t => t, StringComparer.CurrentCultureIgnoreCase) .Where(item => item.Length > 0) .Select(item => new { item, c = Char.ToLower(item[0]) }) .Where(t => t.c >= 'a' && t.c <= 'z') .Select(t => t.item) .FirstOrDefault(); var transaction = new Transaction(); foreach (var obj in problem.Objects) { foreach (var face in obj.Data.Intersect(problem.ObjectData).OfType <Face>()) { var clone = (Face)face.Clone(); clone.Texture.Name = first; transaction.Add(new RemoveMapObjectData(obj.ID, face)); transaction.Add(new AddMapObjectData(obj.ID, clone)); } } await MapDocumentOperation.Perform(document, transaction); }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { if (_clipboard.Value.CanPaste()) { // Work out a random offset to offset duplicate ids var step = Vector3.One * 16; // If there's a grid, use the grid spacing instead of the box dimensions var grid = document.Map.Data.GetOne <GridData>(); if (grid?.Grid != null && grid.Grid.Spacing > 1) { step = grid.Grid.AddStep(Vector3.Zero, Vector3.One); } // Get the pasted values, moving objects that have an id already in the map var content = _clipboard.Value.GetPastedContent(document, (d, o) => CopyAndMove(d, o, step)).ToList(); var transaction = new Transaction( new Deselect(document.Selection), new Attach(document.Map.Root.ID, content), new Select(content) ); await MapDocumentOperation.Perform(document, transaction); } }
public Task Fix(MapDocument document, Problem problem) { // This error should only come from external sources (map loading, etc) as the EditEntityDataProperties // simply doesn't allow adding duplicate keys at all. var transaction = new Transaction(); foreach (var obj in problem.Objects) { var data = obj.Data.GetOne <EntityData>(); if (data == null) { continue; } var vals = new Dictionary <string, string>(); // Set the key to the first found value var groups = data.Properties.GroupBy(x => x.Key.ToLowerInvariant()).Where(x => x.Count() > 1); foreach (var g in groups) { vals[g.Key] = g.First().Value; } transaction.Add(new EditEntityDataProperties(obj.ID, vals)); } return(MapDocumentOperation.Perform(document, transaction)); }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { if (_clipboard.Value.CanPaste()) { var content = _clipboard.Value.GetPastedContent(document).ToList(); if (!content.Any()) { return; } using (var psd = new PasteSpecialDialog(new Box(content.Select(x => x.BoundingBox)))) { _translator.Value.Translate(psd); if (psd.ShowDialog() == DialogResult.OK) { var objs = GetPastedContent(document, content, psd); if (objs.Any()) { var op = new Attach(document.Map.Root.ID, objs); await MapDocumentOperation.Perform(document, op); } } } } }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { // Get the carving objects (whatever's selected) var carvers = document.Selection.OfType <Solid>().ToList(); if (!carvers.Any()) { return; } // Get the carve set. This set doesn't have to explicitly intersect with a carver, // it's only a list of candidates. The carve operation does a more precise filter. var carvees = document.Map.Root .Find(x => x is Solid && carvers.Any(c => x.BoundingBox.IntersectsWith(c.BoundingBox))) .OfType <Solid>() .Where(x => !carvers.Contains(x)); // Perform the carve var tns = CarveObjects(document, carvers, carvees); if (tns.IsEmpty) { return; } // Commit changes await MapDocumentOperation.Perform(document, tns); }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var selBox = document.Selection.GetSelectionBoundingBox(); var tl = document.Map.Data.GetOne <TransformationFlags>() ?? new TransformationFlags(); var transaction = new Transaction(); foreach (var mo in document.Selection.GetSelectedParents().ToList()) { var objBox = mo.BoundingBox; var translation = GetTranslation(selBox, objBox); if (translation == Vector3.Zero) { continue; } var tform = Matrix4x4.CreateTranslation(translation); var transformOperation = new BspEditor.Modification.Operations.Mutation.Transform(tform, mo); transaction.Add(transformOperation); // Check for texture transform if (tl.TextureLock) { transaction.Add(new TransformTexturesUniform(tform, mo.FindAll())); } } if (!transaction.IsEmpty) { await MapDocumentOperation.Perform(document, transaction); } }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var selBox = document.Selection.GetSelectionBoundingBox(); var axis = parameters.Get <Vector3>("Axis"); var amount = parameters.Get <float>("Angle"); var radians = (float)MathHelper.DegreesToRadians(amount); var tl = document.Map.Data.GetOne <TransformationFlags>() ?? new TransformationFlags(); var transaction = new Transaction(); var tform = Matrix4x4.CreateTranslation(-selBox.Center) * Matrix4x4.CreateFromAxisAngle(axis, radians) * Matrix4x4.CreateTranslation(selBox.Center); var transformOperation = new BspEditor.Modification.Operations.Mutation.Transform(tform, document.Selection.GetSelectedParents()); transaction.Add(transformOperation); // Check for texture transform if (tl.TextureLock) { transaction.Add(new TransformTexturesUniform(tform, document.Selection)); } await MapDocumentOperation.Perform(document, transaction); }
private void SelectObject(Solid closestObject) { // Nothing was clicked, don't change the selection if (closestObject == null) { return; } var operation = new Transaction(); // Ctrl doesn't toggle selection, only adds to it. // Ctrl+clicking a selected solid will do nothing. if (!KeyboardState.Ctrl) { // Ctrl isn't down, so we want to clear the selection operation.Add(new Deselect(Document.Selection.Where(x => !ReferenceEquals(x, closestObject)).ToList())); } if (!closestObject.IsSelected) { // The clicked object isn't selected yet, select it. operation.Add(new Select(closestObject)); } if (!operation.IsEmpty) { MapDocumentOperation.Perform(Document, operation); } }
public async Task Fix(MapDocument document, Problem problem) { var gamedata = await document.Environment.GetGameData(); var transaction = new Transaction(); foreach (var obj in problem.Objects) { var data = obj.Data.GetOne <EntityData>(); if (data == null) { continue; } var vals = new Dictionary <string, string>(); foreach (var key in GetInvalidKeys(gamedata, data)) { vals[key] = null; } transaction.Add(new EditEntityDataProperties(obj.ID, vals)); } await MapDocumentOperation.Perform(document, transaction); }
private async void GoToError(object sender, EventArgs e) { var doc = _context.Get <MapDocument>("ActiveDocument"); if (doc == null) { return; } var sel = ProblemsList.SelectedItem as ProblemWrapper; if (sel == null || !sel.Problem.Objects.Any()) { return; } var op = new Transaction( new Deselect(doc.Selection.Except(sel.Problem.Objects)), new Select(sel.Problem.Objects) ); await MapDocumentOperation.Perform(doc, op); var bb = doc.Selection.GetSelectionBoundingBox(); await Oy.Publish("MapDocument:Viewport:Focus2D", bb); await Oy.Publish("MapDocument:Viewport:Focus3D", bb); }
private async Task ApplyChanges(Func <IMapObject, Face, Task <bool> > apply) { var sel = GetFaceSelection(); var edit = new Transaction(); var found = false; foreach (var it in sel.GetSelectedFaces()) { var clone = (Face)it.Value.Clone(); var result = await apply(it.Key, clone); if (!result) { continue; } found = true; edit.Add(new RemoveMapObjectData(it.Key.ID, it.Value)); edit.Add(new AddMapObjectData(it.Key.ID, clone)); } if (found) { await MapDocumentOperation.Perform(Document, edit); await FaceSelectionChanged(); } }
private async Task LoadPointfile(MapDocument document, string file) { if (file != null && File.Exists(file)) { var text = File.ReadAllLines(file); Pointfile point; try { point = Pointfile.Parse(text); } catch { MessageBox.Show(String.Format(InvalidPointfile, Path.GetFileName(file))); return; } await MapDocumentOperation.Perform(document, new TrivialOperation( d => d.Map.Data.Replace(point), c => c.Add(c.Document.Map.Root) )); if (point.Lines.Any()) { var start = point.Lines[0].Start; await Oy.Publish("MapDocument:Viewport:Focus2D", start); await Oy.Publish("MapDocument:Viewport:Focus3D", start); } } }
protected override Task Invoke(MapDocument document, CommandParameters parameters) { var opt = document.Map.Data.GetOne <SelectionOptions>() ?? new SelectionOptions(); opt.IgnoreGrouping = !opt.IgnoreGrouping; MapDocumentOperation.Perform(document, new TrivialOperation(x => x.Map.Data.Replace(opt), x => x.Update(opt))); return(Task.CompletedTask); }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var tl = document.Map.Data.GetOne <TransformationFlags>() ?? new TransformationFlags(); tl.TextureScaleLock = !tl.TextureScaleLock; await MapDocumentOperation.Perform(document, new TrivialOperation(x => x.Map.Data.Replace(tl), x => x.Update(tl))); }
private async Task Reversed(MapDocumentOperation operation) { var stack = operation.Document.Map.Data.GetOne <HistoryStack>(); stack?.Remove(operation.Operation); Oy.Publish("MapDocument:HistoryChanged", operation.Document); }
private async void TextureListHighlightedTexturesChanged(object sender, IEnumerable <string> sel) { if (_freeze) { return; } _freeze = true; var selection = sel.ToList(); var item = selection.FirstOrDefault(); if (selection.Any()) { if (sender == SelectedTexturesList) { RecentTexturesList.SetHighlightedTextures(new string[0]); } if (sender == RecentTexturesList) { SelectedTexturesList.SetHighlightedTextures(new string[0]); } } else { item = RecentTexturesList .GetHighlightedTextures() .Union(SelectedTexturesList.GetHighlightedTextures()) .FirstOrDefault(); } var label = ""; var d = Document; if (item != null && d != null) { var tex = await d.Environment.GetTextureCollection(); var ti = await tex.GetTextureItem(item); if (ti != null) { label = $"{ti.Name} ({ti.Width} x {ti.Height})"; } var at = new ActiveTexture { Name = item }; await MapDocumentOperation.Perform(Document, new TrivialOperation(x => x.Map.Data.Replace(at), x => x.Update(at))); } TextureDetailsLabel.InvokeLater(() => { TextureDetailsLabel.Text = label; }); _freeze = false; }
private void SelectButtonClicked(object sender, EventArgs e) { var sv = VisgroupPanel.SelectedVisgroup; if (sv != null && _activeDocument.TryGetTarget(out MapDocument md)) { MapDocumentOperation.Perform(md, new Transaction(new Deselect(md.Selection), new Select(GetVisgroupObjects(sv)))); } }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { if (_clipboard.Value.CanPaste()) { var content = _clipboard.Value.GetPastedContent(document); var op = new Attach(document.Map.Root.ID, content); await MapDocumentOperation.Perform(document, op); } }
private void ApplyPropertyChanges(bool trivial) { var edit = new Transaction(); var sel = GetFaceSelection(); if (trivial) { // Remember the state before the last change if (_memoTextures == null) { _memoTextures = sel.ToDictionary(x => x, x => x.Texture.Clone()); } // Once a trivial change is started we know that there will definitely be a matching nontrivial task // We aggregate changes so they don't spam the undo stack edit.Add(new TrivialOperation( x => { foreach (var it in sel.GetSelectedFaces()) { ApplyFaceValues(it.Value); } }, x => { foreach (var p in sel.GetSelectedParents()) { x.Update(p); } } )); } else { foreach (var it in sel.GetSelectedFaces()) { // Restore the last committed values if (_memoTextures != null && _memoTextures.ContainsKey(it.Value)) { var k = _memoTextures[it.Value]; it.Value.Texture.Unclone(k); } var clone = (Face)it.Value.Clone(); ApplyFaceValues(clone); edit.Add(new RemoveMapObjectData(it.Key.ID, it.Value)); edit.Add(new AddMapObjectData(it.Key.ID, clone)); } // Reset the memory _memoTextures = null; } MapDocumentOperation.Perform(Document, edit); }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var sel = document.Selection.GetSelectedParents().ToList(); if (sel.Any()) { var t = new Transaction(sel.GroupBy(x => x.Hierarchy.Parent.ID).Select(x => new Detatch(x.Key, x))); await MapDocumentOperation.Perform(document, t); } }
public Task Fix(MapDocument document, Problem problem) { var delete = new Transaction(); foreach (var g in problem.Objects.GroupBy(x => x.Hierarchy.Parent.ID)) { delete.Add(new Detatch(g.Key, g)); } return(MapDocumentOperation.Perform(document, delete)); }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var transaction = new Transaction(); foreach (var mo in document.Map.Root.Find(x => x.Data.Get <QuickHidden>().Any())) { transaction.Add(new RemoveMapObjectData(mo.ID, mo.Data.GetOne <QuickHidden>())); } await MapDocumentOperation.Perform(document, transaction); }
public async Task Invoke(IContext context, CommandParameters parameters) { if (context.TryGet("ActiveDocument", out MapDocument doc)) { var cordon = doc.Map.Data.GetOne <CordonBounds>() ?? new CordonBounds { Enabled = false }; cordon.Enabled = !cordon.Enabled; await MapDocumentOperation.Perform(doc, new TrivialOperation(x => x.Map.Data.Replace(cordon), x => x.Update(cordon).UpdateRange(doc.Map.Root.FindAll()))); } }
public Task Fix(MapDocument document, Problem problem) { var transaction = new Transaction(); foreach (var obj in problem.Objects) { transaction.Add(new Detatch(obj.Hierarchy.Parent.ID, obj)); } return(MapDocumentOperation.Perform(document, transaction)); }
public Task Fix(MapDocument document, Problem problem) { var transaction = new Transaction(); foreach (var obj in problem.Objects.SelectMany(x => x.Find(f => f is Entity)).Distinct()) { transaction.Add(new Detatch(obj.Hierarchy.Parent.ID, obj)); transaction.Add(new Attach(document.Map.Root.ID, obj)); } return(MapDocumentOperation.Perform(document, transaction)); }
public async Task Invoke(IContext context, CommandParameters parameters) { if (context.TryGet("ActiveDocument", out MapDocument doc)) { var activeGrid = doc.Map.Data.GetOne <GridData>(); if (activeGrid != null) { var operation = new TrivialOperation(x => activeGrid.SnapToGrid = !activeGrid.SnapToGrid, x => x.Update(activeGrid)); await MapDocumentOperation.Perform(doc, operation); } } }
public async Task Invoke(IContext context) { if (context.TryGet("ActiveDocument", out MapDocument doc)) { var grid = await GridFactory.Create(doc.Environment); var gd = new GridData(grid); var operation = new TrivialOperation(x => doc.Map.Data.Replace(gd), x => x.Update(gd)); await MapDocumentOperation.Perform(doc, operation); } }
protected override async Task Invoke(MapDocument document, CommandParameters parameters) { var stack = document.Map.Data.GetOne <HistoryStack>(); if (stack == null) { return; } if (stack.CanUndo()) { await MapDocumentOperation.Reverse(document, stack.UndoOperation()); } }