Add copy/paste to the map editor.
This commit is contained in:
174
OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs
Normal file
174
OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation. For more information,
|
||||||
|
* see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.FileFormats;
|
||||||
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Mods.Common;
|
||||||
|
using OpenRA.Mods.Common.Graphics;
|
||||||
|
using OpenRA.Mods.Common.Traits;
|
||||||
|
using OpenRA.Orders;
|
||||||
|
using OpenRA.Primitives;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Widgets
|
||||||
|
{
|
||||||
|
public sealed class EditorCopyPasteBrush : IEditorBrush
|
||||||
|
{
|
||||||
|
enum State { SelectFirst, SelectSecond, Paste }
|
||||||
|
|
||||||
|
readonly WorldRenderer worldRenderer;
|
||||||
|
readonly EditorViewportControllerWidget editorWidget;
|
||||||
|
readonly EditorSelectionLayer selectionLayer;
|
||||||
|
readonly EditorActorLayer editorLayer;
|
||||||
|
|
||||||
|
State state;
|
||||||
|
CPos start;
|
||||||
|
CPos end;
|
||||||
|
|
||||||
|
public EditorCopyPasteBrush(EditorViewportControllerWidget editorWidget, WorldRenderer wr)
|
||||||
|
{
|
||||||
|
this.editorWidget = editorWidget;
|
||||||
|
worldRenderer = wr;
|
||||||
|
|
||||||
|
selectionLayer = wr.World.WorldActor.Trait<EditorSelectionLayer>();
|
||||||
|
editorLayer = wr.World.WorldActor.Trait<EditorActorLayer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HandleMouseInput(MouseInput mi)
|
||||||
|
{
|
||||||
|
// Exclusively uses left and right mouse buttons, but nothing else
|
||||||
|
if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mi.Button == MouseButton.Right)
|
||||||
|
{
|
||||||
|
if (mi.Event == MouseInputEvent.Up)
|
||||||
|
{
|
||||||
|
editorWidget.ClearBrush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mi.Button == MouseButton.Left && (mi.Event == MouseInputEvent.Up || mi.Event == MouseInputEvent.Down))
|
||||||
|
{
|
||||||
|
var cell = worldRenderer.Viewport.ViewToWorld(mi.Location);
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case State.SelectFirst:
|
||||||
|
if (mi.Event != MouseInputEvent.Down)
|
||||||
|
break;
|
||||||
|
start = cell;
|
||||||
|
selectionLayer.SetCopyRegion(start, end);
|
||||||
|
state = State.SelectSecond;
|
||||||
|
break;
|
||||||
|
case State.SelectSecond:
|
||||||
|
if (mi.Event != MouseInputEvent.Up)
|
||||||
|
break;
|
||||||
|
end = cell;
|
||||||
|
selectionLayer.SetCopyRegion(start, end);
|
||||||
|
state = State.Paste;
|
||||||
|
break;
|
||||||
|
case State.Paste:
|
||||||
|
{
|
||||||
|
var gridType = worldRenderer.World.Map.Grid.Type;
|
||||||
|
var source = CellRegion.BoundingRegion(gridType, new[] { start, end });
|
||||||
|
Copy(source, cell - end);
|
||||||
|
editorWidget.ClearBrush();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Copy(CellRegion source, CVec offset)
|
||||||
|
{
|
||||||
|
var gridType = worldRenderer.World.Map.Grid.Type;
|
||||||
|
var mapTiles = worldRenderer.World.Map.MapTiles.Value;
|
||||||
|
var mapHeight = worldRenderer.World.Map.MapHeight.Value;
|
||||||
|
var mapResources = worldRenderer.World.Map.MapResources.Value;
|
||||||
|
|
||||||
|
var dest = new CellRegion(gridType, source.TopLeft + offset, source.BottomRight + offset);
|
||||||
|
|
||||||
|
var previews = new Dictionary<string, ActorReference>();
|
||||||
|
var tiles = new Dictionary<CPos, Tuple<TerrainTile, ResourceTile, byte>>();
|
||||||
|
|
||||||
|
foreach (var cell in source)
|
||||||
|
{
|
||||||
|
if (!mapTiles.Contains(cell) || !mapTiles.Contains(cell + offset))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tiles.Add(cell + offset, Tuple.Create(mapTiles[cell], mapResources[cell], mapHeight[cell]));
|
||||||
|
|
||||||
|
foreach (var preview in editorLayer.PreviewsAt(cell))
|
||||||
|
{
|
||||||
|
if (previews.ContainsKey(preview.ID))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var copy = preview.Export();
|
||||||
|
if (copy.InitDict.Contains<LocationInit>())
|
||||||
|
{
|
||||||
|
var location = copy.InitDict.Get<LocationInit>();
|
||||||
|
copy.InitDict.Remove(location);
|
||||||
|
copy.InitDict.Add(new LocationInit(location.Value(worldRenderer.World) + offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
previews.Add(preview.ID, copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var kv in tiles)
|
||||||
|
{
|
||||||
|
mapTiles[kv.Key] = kv.Value.Item1;
|
||||||
|
mapResources[kv.Key] = kv.Value.Item2;
|
||||||
|
mapHeight[kv.Key] = kv.Value.Item3;
|
||||||
|
}
|
||||||
|
|
||||||
|
var removeActors = dest.SelectMany(editorLayer.PreviewsAt).Distinct().ToList();
|
||||||
|
foreach (var preview in removeActors)
|
||||||
|
editorLayer.Remove(preview);
|
||||||
|
|
||||||
|
foreach (var kv in previews)
|
||||||
|
editorLayer.Add(kv.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick()
|
||||||
|
{
|
||||||
|
var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
|
||||||
|
if (state == State.Paste)
|
||||||
|
{
|
||||||
|
selectionLayer.SetPasteRegion(cell + (start - end), cell);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == State.SelectFirst)
|
||||||
|
start = end = cell;
|
||||||
|
else if (state == State.SelectSecond)
|
||||||
|
end = cell;
|
||||||
|
|
||||||
|
selectionLayer.SetCopyRegion(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
selectionLayer.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -708,6 +708,8 @@
|
|||||||
<Compile Include="Lint\CheckChromeLogic.cs" />
|
<Compile Include="Lint\CheckChromeLogic.cs" />
|
||||||
<Compile Include="Lint\CheckMapMetadata.cs" />
|
<Compile Include="Lint\CheckMapMetadata.cs" />
|
||||||
<Compile Include="Widgets\Logic\MultiplayerLogic.cs" />
|
<Compile Include="Widgets\Logic\MultiplayerLogic.cs" />
|
||||||
|
<Compile Include="EditorBrushes\EditorCopyPasteBrush.cs" />
|
||||||
|
<Compile Include="Traits\World\EditorSelectionLayer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -161,5 +161,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
.SelectMany(rpi => rpi.RenderPreview(init))
|
.SelectMany(rpi => rpi.RenderPreview(init))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ActorReference Export()
|
||||||
|
{
|
||||||
|
return new ActorReference(actor.Type, actor.Save().ToDictionary());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
105
OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs
Normal file
105
OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation. For more information,
|
||||||
|
* see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Mods.Common.Graphics;
|
||||||
|
using OpenRA.Primitives;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Traits
|
||||||
|
{
|
||||||
|
[Desc("Required for the map editor to work. Attach this to the world actor.")]
|
||||||
|
public class EditorSelectionLayerInfo : ITraitInfo
|
||||||
|
{
|
||||||
|
[PaletteReference]
|
||||||
|
[Desc("Palette to use for rendering the placement sprite.")]
|
||||||
|
public readonly string Palette = "terrain";
|
||||||
|
|
||||||
|
[Desc("Sequence image where the selection overlay types are defined.")]
|
||||||
|
public readonly string Image = "editor-overlay";
|
||||||
|
|
||||||
|
[SequenceReference("Image")]
|
||||||
|
[Desc("Sequence to use for the copy overlay.")]
|
||||||
|
public readonly string CopySequence = "copy";
|
||||||
|
|
||||||
|
[SequenceReference("Image")]
|
||||||
|
[Desc("Sequence to use for the paste overlay.")]
|
||||||
|
public readonly string PasteSequence = "paste";
|
||||||
|
|
||||||
|
public virtual object Create(ActorInitializer init) { return new EditorSelectionLayer(init.Self, this); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EditorSelectionLayer : IWorldLoaded, IPostRender
|
||||||
|
{
|
||||||
|
readonly EditorSelectionLayerInfo info;
|
||||||
|
readonly Map map;
|
||||||
|
readonly Sprite copySprite;
|
||||||
|
readonly Sprite pasteSprite;
|
||||||
|
PaletteReference palette;
|
||||||
|
|
||||||
|
public CellRegion CopyRegion { get; private set; }
|
||||||
|
public CellRegion PasteRegion { get; private set; }
|
||||||
|
|
||||||
|
public EditorSelectionLayer(Actor self, EditorSelectionLayerInfo info)
|
||||||
|
{
|
||||||
|
if (self.World.Type != WorldType.Editor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.info = info;
|
||||||
|
map = self.World.Map;
|
||||||
|
copySprite = map.SequenceProvider.GetSequence(info.Image, info.CopySequence).GetSprite(0);
|
||||||
|
pasteSprite = map.SequenceProvider.GetSequence(info.Image, info.PasteSequence).GetSprite(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WorldLoaded(World w, WorldRenderer wr)
|
||||||
|
{
|
||||||
|
if (w.Type != WorldType.Editor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
palette = wr.Palette(info.Palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCopyRegion(CPos start, CPos end)
|
||||||
|
{
|
||||||
|
CopyRegion = CellRegion.BoundingRegion(map.Grid.Type, new[] { start, end });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPasteRegion(CPos start, CPos end)
|
||||||
|
{
|
||||||
|
PasteRegion = CellRegion.BoundingRegion(map.Grid.Type, new[] { start, end });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
CopyRegion = PasteRegion = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RenderAfterWorld(WorldRenderer wr, Actor self)
|
||||||
|
{
|
||||||
|
if (wr.World.Type != WorldType.Editor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (CopyRegion != null)
|
||||||
|
foreach (var c in CopyRegion)
|
||||||
|
new SpriteRenderable(copySprite, wr.World.Map.CenterOfCell(c),
|
||||||
|
WVec.Zero, -511, palette, 1f, true).PrepareRender(wr).Render(wr);
|
||||||
|
|
||||||
|
if (PasteRegion != null)
|
||||||
|
foreach (var c in PasteRegion)
|
||||||
|
new SpriteRenderable(pasteSprite, wr.World.Map.CenterOfCell(c),
|
||||||
|
WVec.Zero, -511, palette, 1f, true).PrepareRender(wr).Render(wr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
public MapEditorLogic(Widget widget, World world, WorldRenderer worldRenderer)
|
public MapEditorLogic(Widget widget, World world, WorldRenderer worldRenderer)
|
||||||
{
|
{
|
||||||
|
var editorViewport = widget.Get<EditorViewportControllerWidget>("MAP_EDITOR");
|
||||||
|
|
||||||
var gridButton = widget.GetOrNull<ButtonWidget>("GRID_BUTTON");
|
var gridButton = widget.GetOrNull<ButtonWidget>("GRID_BUTTON");
|
||||||
var terrainGeometryTrait = world.WorldActor.Trait<TerrainGeometryOverlay>();
|
var terrainGeometryTrait = world.WorldActor.Trait<TerrainGeometryOverlay>();
|
||||||
|
|
||||||
@@ -63,6 +65,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var copypasteButton = widget.GetOrNull<ButtonWidget>("COPYPASTE_BUTTON");
|
||||||
|
if (copypasteButton != null)
|
||||||
|
{
|
||||||
|
copypasteButton.OnClick = () => editorViewport.SetBrush(new EditorCopyPasteBrush(editorViewport, worldRenderer));
|
||||||
|
copypasteButton.IsHighlighted = () => editorViewport.CurrentBrush is EditorCopyPasteBrush;
|
||||||
|
}
|
||||||
|
|
||||||
var coordinateLabel = widget.GetOrNull<LabelWidget>("COORDINATE_LABEL");
|
var coordinateLabel = widget.GetOrNull<LabelWidget>("COORDINATE_LABEL");
|
||||||
if (coordinateLabel != null)
|
if (coordinateLabel != null)
|
||||||
coordinateLabel.GetText = () => worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos).ToString();
|
coordinateLabel.GetText = () => worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos).ToString();
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ Container@EDITOR_WORLD_ROOT:
|
|||||||
Text: Actors
|
Text: Actors
|
||||||
Font: Bold
|
Font: Bold
|
||||||
Button@GRID_BUTTON:
|
Button@GRID_BUTTON:
|
||||||
X: WINDOW_RIGHT - 420
|
X: WINDOW_RIGHT - 500
|
||||||
Y: 5
|
Y: 5
|
||||||
Width: 100
|
Width: 100
|
||||||
Height: 25
|
Height: 25
|
||||||
@@ -373,7 +373,7 @@ Container@EDITOR_WORLD_ROOT:
|
|||||||
TooltipText: Toggle the terrain grid
|
TooltipText: Toggle the terrain grid
|
||||||
TooltipContainer: TOOLTIP_CONTAINER
|
TooltipContainer: TOOLTIP_CONTAINER
|
||||||
Label@ZOOM_LABEL:
|
Label@ZOOM_LABEL:
|
||||||
X: WINDOW_RIGHT - 500 - 55
|
X: WINDOW_RIGHT - 580 - 55
|
||||||
Y: 5
|
Y: 5
|
||||||
Width: 50
|
Width: 50
|
||||||
Height: 25
|
Height: 25
|
||||||
@@ -382,11 +382,17 @@ Container@EDITOR_WORLD_ROOT:
|
|||||||
Font: Bold
|
Font: Bold
|
||||||
Contrast: true
|
Contrast: true
|
||||||
DropDownButton@ZOOM_BUTTON:
|
DropDownButton@ZOOM_BUTTON:
|
||||||
X: WINDOW_RIGHT - 500
|
X: WINDOW_RIGHT - 580
|
||||||
Y: 5
|
Y: 5
|
||||||
Width: 70
|
Width: 70
|
||||||
Height: 25
|
Height: 25
|
||||||
Font: Bold
|
Font: Bold
|
||||||
|
Button@COPYPASTE_BUTTON:
|
||||||
|
X: WINDOW_RIGHT-390
|
||||||
|
Y: 5
|
||||||
|
Width: 96
|
||||||
|
Height: 25
|
||||||
|
Text: Copy/Paste
|
||||||
Label@COORDINATE_LABEL:
|
Label@COORDINATE_LABEL:
|
||||||
X: 10
|
X: 10
|
||||||
Width: 50
|
Width: 50
|
||||||
|
|||||||
@@ -154,4 +154,5 @@ EditorWorld:
|
|||||||
Inherits: ^BaseWorld
|
Inherits: ^BaseWorld
|
||||||
EditorActorLayer:
|
EditorActorLayer:
|
||||||
EditorResourceLayer:
|
EditorResourceLayer:
|
||||||
|
EditorSelectionLayer:
|
||||||
|
|
||||||
|
|||||||
@@ -240,6 +240,12 @@ overlay:
|
|||||||
target-invalid:
|
target-invalid:
|
||||||
Start: 1
|
Start: 1
|
||||||
|
|
||||||
|
editor-overlay:
|
||||||
|
copy: overlay
|
||||||
|
Start: 0
|
||||||
|
paste: overlay
|
||||||
|
Start: 1
|
||||||
|
|
||||||
poweroff:
|
poweroff:
|
||||||
offline:
|
offline:
|
||||||
Length: *
|
Length: *
|
||||||
|
|||||||
@@ -148,4 +148,5 @@ EditorWorld:
|
|||||||
Inherits: ^BaseWorld
|
Inherits: ^BaseWorld
|
||||||
EditorActorLayer:
|
EditorActorLayer:
|
||||||
D2kEditorResourceLayer:
|
D2kEditorResourceLayer:
|
||||||
|
EditorSelectionLayer:
|
||||||
|
|
||||||
|
|||||||
@@ -126,19 +126,23 @@ rank:
|
|||||||
Length: *
|
Length: *
|
||||||
|
|
||||||
overlay:
|
overlay:
|
||||||
build-valid-arrakis: DATA.R8
|
Defaults: DATA.R8
|
||||||
Offset: -16,-16
|
Offset: -16,-16
|
||||||
build-invalid: DATA.R8
|
build-valid-arrakis:
|
||||||
|
build-invalid:
|
||||||
Start: 1
|
Start: 1
|
||||||
Offset: -16,-16
|
target-select:
|
||||||
target-select: DATA.R8
|
|
||||||
Start: 2
|
Start: 2
|
||||||
Offset: -16,-16
|
target-valid-arrakis:
|
||||||
target-valid-arrakis: DATA.R8
|
target-invalid:
|
||||||
Offset: -16,-16
|
|
||||||
target-invalid: DATA.R8
|
|
||||||
Start: 1
|
Start: 1
|
||||||
|
|
||||||
|
editor-overlay:
|
||||||
|
Defaults: DATA.R8
|
||||||
Offset: -16,-16
|
Offset: -16,-16
|
||||||
|
copy:
|
||||||
|
paste:
|
||||||
|
Start: 1
|
||||||
|
|
||||||
rallypoint:
|
rallypoint:
|
||||||
flag: flagfly.shp
|
flag: flagfly.shp
|
||||||
|
|||||||
@@ -351,9 +351,15 @@ Container@EDITOR_WORLD_ROOT:
|
|||||||
TooltipContainer: TOOLTIP_CONTAINER
|
TooltipContainer: TOOLTIP_CONTAINER
|
||||||
Font: Bold
|
Font: Bold
|
||||||
Key: escape
|
Key: escape
|
||||||
|
Button@COPYPASTE_BUTTON:
|
||||||
|
X: 170
|
||||||
|
Width: 90
|
||||||
|
Height: 25
|
||||||
|
Text: Copy/Paste
|
||||||
|
Font: Bold
|
||||||
Button@GRID_BUTTON:
|
Button@GRID_BUTTON:
|
||||||
X: 180
|
X: 270
|
||||||
Width: 160
|
Width: 70
|
||||||
Height: 25
|
Height: 25
|
||||||
Text: Grid
|
Text: Grid
|
||||||
TooltipTemplate: BUTTON_TOOLTIP
|
TooltipTemplate: BUTTON_TOOLTIP
|
||||||
|
|||||||
@@ -173,4 +173,5 @@ EditorWorld:
|
|||||||
Inherits: ^BaseWorld
|
Inherits: ^BaseWorld
|
||||||
EditorActorLayer:
|
EditorActorLayer:
|
||||||
EditorResourceLayer:
|
EditorResourceLayer:
|
||||||
|
EditorSelectionLayer:
|
||||||
|
|
||||||
|
|||||||
@@ -474,6 +474,12 @@ overlay:
|
|||||||
target-invalid:
|
target-invalid:
|
||||||
Start: 1
|
Start: 1
|
||||||
|
|
||||||
|
editor-overlay:
|
||||||
|
copy: overlay
|
||||||
|
Start: 0
|
||||||
|
paste: overlay
|
||||||
|
Start: 1
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
Defaults:
|
Defaults:
|
||||||
Length: *
|
Length: *
|
||||||
|
|||||||
@@ -175,4 +175,6 @@ EditorWorld:
|
|||||||
Inherits: ^BaseWorld
|
Inherits: ^BaseWorld
|
||||||
EditorActorLayer:
|
EditorActorLayer:
|
||||||
EditorResourceLayer:
|
EditorResourceLayer:
|
||||||
|
EditorSelectionLayer:
|
||||||
|
Palette: placebuilding
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ overlay:
|
|||||||
Start: 1
|
Start: 1
|
||||||
target-select:
|
target-select:
|
||||||
|
|
||||||
|
editor-overlay:
|
||||||
|
Defaults: place
|
||||||
|
Offset: 0, -12
|
||||||
|
copy:
|
||||||
|
paste:
|
||||||
|
Start: 1
|
||||||
|
|
||||||
poweroff:
|
poweroff:
|
||||||
offline:
|
offline:
|
||||||
Length: *
|
Length: *
|
||||||
|
|||||||
Reference in New Issue
Block a user