mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-05-30 08:32:00 +00:00
GZDoom Builder 1.11a:
Things can now be cut, copied and pasted in Visual modes. Sector geometry was not updated properly after Undo/Redo in GZDoom Visual mode. Fixed an error when user selects multiple things and attempts to view their properties in Doom map format. Added Decorate and Modeldef syntax hilighting, autocompletion and item recognition to Script editor. Script Editor can now autodetect several script types when you open them (currently ACS, Decorate and Modeldef scripts are recognized). Tag Explorer: fixed a bug when Tag Explorer update can block keyboard keys release detection logic.
This commit is contained in:
parent
8891395b3a
commit
87731c9650
26 changed files with 1062 additions and 320 deletions
|
@ -33,6 +33,7 @@ using CodeImp.DoomBuilder.Editing;
|
|||
using CodeImp.DoomBuilder.Actions;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -84,6 +85,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// List of selected objects when an action is performed
|
||||
private List<IVisualEventReceiver> selectedobjects;
|
||||
//mxd. Used in Cut/PasteSelection actions
|
||||
private List<ThingCopyData> copyBuffer;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -133,6 +136,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Initialize
|
||||
this.gravity = new Vector3D(0.0f, 0.0f, 0.0f);
|
||||
this.selectedobjects = new List<IVisualEventReceiver>();
|
||||
//mxd
|
||||
this.copyBuffer = new List<ThingCopyData>();
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -427,57 +432,82 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
//mxd
|
||||
protected override void moveSelectedThings(Vector2D direction, bool absolutePosition) {
|
||||
List<VisualThing> things = GetSelectedVisualThings(true);
|
||||
List<VisualThing> visualThings = GetSelectedVisualThings(true);
|
||||
|
||||
if (things.Count == 0) {
|
||||
if (visualThings.Count == 0) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Select some Things first!");
|
||||
return;
|
||||
}
|
||||
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
|
||||
Vector3D[] coords = new Vector3D[visualThings.Count];
|
||||
for (int i = 0; i < visualThings.Count; i++)
|
||||
coords[i] = visualThings[i].Thing.Position;
|
||||
|
||||
//move things...
|
||||
Vector3D[] translatedCoords = translateCoordinates(coords, direction, absolutePosition);
|
||||
for (int i = 0; i < visualThings.Count; i++) {
|
||||
BaseVisualThing t = visualThings[i] as BaseVisualThing;
|
||||
t.OnMove(translatedCoords[i]);
|
||||
}
|
||||
|
||||
PostAction();
|
||||
}
|
||||
|
||||
//mxd
|
||||
private Vector3D[] translateCoordinates(Vector3D[] coordinates, Vector2D direction, bool absolutePosition) {
|
||||
if (coordinates.Length == 0) return null;
|
||||
|
||||
direction.x = (float)Math.Round(direction.x);
|
||||
direction.y = (float)Math.Round(direction.y);
|
||||
|
||||
Vector3D[] translatedCoords = new Vector3D[coordinates.Length];
|
||||
|
||||
//move things...
|
||||
if (!absolutePosition) { //...relatively (that's easy)
|
||||
int camAngle = (int)Math.Round(General.Map.VisualCamera.AngleXY * 180 / Math.PI);
|
||||
int sector = (int)(General.ClampAngle(camAngle - 45f) / 90f);
|
||||
direction = direction.GetRotated((float)(sector * Math.PI / 2f));
|
||||
|
||||
for (int i = 0; i < things.Count; i++) {
|
||||
BaseVisualThing t = things[i] as BaseVisualThing;
|
||||
t.OnMove(t.Thing.Position + new Vector3D(direction));
|
||||
}
|
||||
} else { //...to specified location preserving relative positioning (that's harder)
|
||||
if (things.Count == 1) {//just move it there
|
||||
BaseVisualThing t = things[0] as BaseVisualThing;
|
||||
t.OnMove(new Vector3D(direction.x, direction.y, t.Thing.Position.z));
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < coordinates.Length; i++)
|
||||
translatedCoords[i] = coordinates[i] + new Vector3D(direction);
|
||||
|
||||
//we need some reference
|
||||
float minX = things[0].Thing.Position.x;
|
||||
float maxX = minX;
|
||||
float minY = things[0].Thing.Position.y;
|
||||
float maxY = minY;
|
||||
|
||||
//get bounding coordinates for selected things
|
||||
for (int i = 1; i < things.Count; i++) {
|
||||
if (things[i].Thing.Position.x < minX)
|
||||
minX = things[i].Thing.Position.x;
|
||||
else if (things[i].Thing.Position.x > maxX)
|
||||
maxX = things[i].Thing.Position.x;
|
||||
|
||||
if (things[i].Thing.Position.y < minY)
|
||||
minY = things[i].Thing.Position.y;
|
||||
else if (things[i].Thing.Position.y > maxY)
|
||||
maxY = things[i].Thing.Position.y;
|
||||
}
|
||||
|
||||
Vector2D selectionCenter = new Vector2D(minX + (maxX - minX) / 2, minY + (maxY - minY) / 2);
|
||||
|
||||
//move them
|
||||
for (int i = 0; i < things.Count; i++) {
|
||||
BaseVisualThing t = things[i] as BaseVisualThing;
|
||||
t.OnMove(new Vector3D(direction.x - (selectionCenter.x - t.Thing.Position.x), direction.y - (selectionCenter.y - t.Thing.Position.y), t.Thing.Position.z));
|
||||
}
|
||||
return translatedCoords;
|
||||
}
|
||||
|
||||
//...to specified location preserving relative positioning (that's harder)
|
||||
if (coordinates.Length == 1) {//just move it there
|
||||
translatedCoords[0] = new Vector3D(direction.x, direction.y, coordinates[0].z);
|
||||
return translatedCoords;
|
||||
}
|
||||
|
||||
//we need some reference
|
||||
float minX = coordinates[0].x;
|
||||
float maxX = minX;
|
||||
float minY = coordinates[0].y;
|
||||
float maxY = minY;
|
||||
|
||||
//get bounding coordinates for selected things
|
||||
for (int i = 1; i < coordinates.Length; i++) {
|
||||
if (coordinates[i].x < minX)
|
||||
minX = coordinates[i].x;
|
||||
else if (coordinates[i].x > maxX)
|
||||
maxX = coordinates[i].x;
|
||||
|
||||
if (coordinates[i].y < minY)
|
||||
minY = coordinates[i].y;
|
||||
else if (coordinates[i].y > maxY)
|
||||
maxY = coordinates[i].y;
|
||||
}
|
||||
|
||||
Vector2D selectionCenter = new Vector2D(minX + (maxX - minX) / 2, minY + (maxY - minY) / 2);
|
||||
|
||||
//move them
|
||||
for (int i = 0; i < coordinates.Length; i++)
|
||||
translatedCoords[i] = new Vector3D((float)Math.Round(direction.x - (selectionCenter.x - coordinates[i].x)), (float)Math.Round(direction.y - (selectionCenter.y - coordinates[i].y)), (float)Math.Round(coordinates[i].z));
|
||||
|
||||
return translatedCoords;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -504,6 +534,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
public override void OnDisengage()
|
||||
{
|
||||
base.OnDisengage();
|
||||
copyBuffer.Clear(); //mxd
|
||||
General.Map.Map.Update();
|
||||
}
|
||||
|
||||
|
@ -962,7 +993,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
//mxd. Copied from BuilderModes.ThingsMode
|
||||
// This creates a new thing
|
||||
private Thing InsertThing(Vector2D pos) {
|
||||
private Thing CreateThing(Vector2D pos) {
|
||||
if (pos.x < General.Map.Config.LeftBoundary || pos.x > General.Map.Config.RightBoundary ||
|
||||
pos.y > General.Map.Config.TopBoundary || pos.y < General.Map.Config.BottomBoundary) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Failed to insert thing: outside of map boundaries.");
|
||||
|
@ -1345,7 +1376,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
//mxd. now we can actually insert things in Visual modes
|
||||
[BeginAction("insertitem", BaseAction = true)]
|
||||
public void Insert() {
|
||||
public void InsertThing() {
|
||||
Vector2D hitpos = getHitPosition();
|
||||
|
||||
if (!hitpos.IsFinite()) {
|
||||
|
@ -1358,7 +1389,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
General.Map.UndoRedo.CreateUndo("Insert thing");
|
||||
|
||||
Thing t = InsertThing(new Vector2D(hitpos.x, hitpos.y));
|
||||
Thing t = CreateThing(new Vector2D(hitpos.x, hitpos.y));
|
||||
|
||||
if (t == null) {
|
||||
General.Map.UndoRedo.WithdrawUndo();
|
||||
|
@ -1379,7 +1410,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
|
||||
[BeginAction("deleteitem", BaseAction = true)] //mxd. now we can actually delete things in Visual modes
|
||||
public void Delete() {
|
||||
public void DeleteSelectedThings() {
|
||||
List<IVisualEventReceiver> objs = GetSelectedObjects(false, false, true);
|
||||
if (objs.Count == 0) return;
|
||||
|
||||
|
@ -1398,6 +1429,73 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
PostAction();
|
||||
}
|
||||
|
||||
//mxd
|
||||
[BeginAction("copyselection", BaseAction = true)]
|
||||
public void CopySelection() {
|
||||
List<IVisualEventReceiver> objs = GetSelectedObjects(false, false, true);
|
||||
if (objs.Count == 0) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Nothing to copy, select some Things first!");
|
||||
return;
|
||||
}
|
||||
|
||||
copyBuffer.Clear();
|
||||
foreach (IVisualEventReceiver i in objs) {
|
||||
VisualThing vt = i as VisualThing;
|
||||
if (vt != null) copyBuffer.Add(new ThingCopyData(vt.Thing));
|
||||
}
|
||||
General.Interface.DisplayStatus(StatusType.Info, "Copied " + copyBuffer.Count + " Things");
|
||||
}
|
||||
|
||||
//mxd
|
||||
[BeginAction("cutselection", BaseAction = true)]
|
||||
public void CutSelection() {
|
||||
CopySelection();
|
||||
DeleteSelectedThings();
|
||||
}
|
||||
|
||||
//mxd. We'll just use currently selected objects
|
||||
[BeginAction("pasteselection", BaseAction = true)]
|
||||
public void PasteSelection() {
|
||||
if (copyBuffer.Count == 0) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Nothing to paste, cut or copy some Things first!");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2D hitpos = getHitPosition();
|
||||
|
||||
if (!hitpos.IsFinite()) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Cannot paste here!");
|
||||
return;
|
||||
}
|
||||
|
||||
General.Map.UndoRedo.ClearAllRedos();
|
||||
string rest = copyBuffer.Count + " thing" + (copyBuffer.Count > 1 ? "s." : ".");
|
||||
General.Map.UndoRedo.CreateUndo("Paste " + rest);
|
||||
General.Interface.DisplayStatus(StatusType.Info, "Pasted " + rest);
|
||||
|
||||
PreActionNoChange();
|
||||
ClearSelection();
|
||||
|
||||
//get translated positions
|
||||
Vector3D[] coords = new Vector3D[copyBuffer.Count];
|
||||
for (int i = 0; i < copyBuffer.Count; i++)
|
||||
coords[i] = copyBuffer[i].Position;
|
||||
|
||||
Vector3D[] translatedCoords = translateCoordinates(coords, hitpos, true);
|
||||
|
||||
//create things from copyBuffer
|
||||
for (int i = 0; i < copyBuffer.Count; i++) {
|
||||
Thing t = CreateThing(new Vector2D());
|
||||
if (t != null) {
|
||||
copyBuffer[i].ApplyTo(t);
|
||||
t.Move(translatedCoords[i]);
|
||||
//add thing to blockmap
|
||||
blockmap.AddThing(t);
|
||||
}
|
||||
}
|
||||
PostAction();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue