#region ================== Copyright (c) 2021 Boris Iwanski /* * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program.If not, see. */ #endregion #region ================== Namespaces using System; using System.Collections.Generic; using System.ComponentModel; using System.Dynamic; using System.Linq; using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Map; #endregion namespace CodeImp.DoomBuilder.UDBScript.Wrapper { class VertexWrapper : MapElementWrapper, IEquatable { #region ================== Variables Vertex vertex; #endregion #region IEquatable members public bool Equals(VertexWrapper other) { return vertex == other.vertex; } public override bool Equals(object obj) { return Equals((VertexWrapper)obj); } public override int GetHashCode() { return vertex.GetHashCode(); } #endregion #region ================== Properties internal Vertex Vertex { get { return vertex; } } /// /// The vertex index. Read-only. /// public int index { get { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the index property can not be accessed."); return vertex.Index; } } /// /// Position of the `Vertex`. It's an object with `x` and `y` properties. /// The `x` and `y` accept numbers: /// ``` /// v.position.x = 32; /// v.position.y = 64; /// ``` /// It's also possible to set all fields immediately by assigning either a `Vector2D`, or an array of numbers: /// ``` /// v.position = new UDB.Vector2D(32, 64); /// v.position = [ 32, 64 ]; /// ``` /// public object position { get { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the position property can not be accessed."); return new Vector2DWrapper(vertex.Position, vertex); } set { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the position property can not be accessed."); try { object v = BuilderPlug.Me.GetVectorFromObject(value, false); if (v is Vector2D) vertex.Move((Vector2D)v); else vertex.Move((Vector3D)v); } catch (CantConvertToVectorException e) { throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException(e.Message); } } } /// /// If the `Vertex` is selected or not. /// public bool selected { get { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the selected property can not be accessed."); return vertex.Selected; } set { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the selected property can not be accessed."); vertex.Selected = value; } } /// /// If the `Vertex` is marked or not. It is used to mark map elements that were created or changed (for example after drawing new geometry). /// public bool marked { get { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the marked property can not be accessed."); return vertex.Marked; } set { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the marked property can not be accessed."); vertex.Marked = value; } } /// /// The ceiling z position of the `Vertex`. Only available in UDMF. Only available for supported game configurations. /// public double ceilingZ { get { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the ceilingZ property can not be accessed."); return vertex.ZCeiling; } set { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the ceilingZ property can not be accessed."); vertex.ZCeiling = value; } } /// /// The floor z position of the `Vertex`. Only available in UDMF. Only available for supported game configurations. /// public double floorZ { get { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the floorZ property can not be accessed."); return vertex.ZFloor; } set { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the floorZ property can not be accessed."); vertex.ZFloor = value; } } #endregion #region ================== Constructors internal VertexWrapper(Vertex vertex) : base(vertex) { this.vertex = vertex; } #endregion #region ================== Update internal override void AfterFieldsUpdate() { } #endregion #region ================== Methods public override string ToString() { return vertex.ToString(); } /// /// Gets all `Linedefs` that are connected to this `Vertex`. /// /// Array of linedefs public LinedefWrapper[] getLinedefs() { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the getLinedefs method can not be accessed."); List linedefs = new List(vertex.Linedefs.Count); foreach (Linedef ld in vertex.Linedefs) if (!ld.IsDisposed) linedefs.Add(new LinedefWrapper(ld)); return linedefs.ToArray(); } /// /// Copies the properties from this `Vertex` to another. /// /// the vertex to copy the properties to public void copyPropertiesTo(VertexWrapper v) { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the copyPropertiesTo method can not be accessed."); vertex.CopyPropertiesTo(v.vertex); } /// /// Gets the squared distance between this `Vertex` and the given point. /// The point can be either a `Vector2D` or an array of numbers. /// ``` /// v.distanceToSq(new UDB.Vector2D(32, 64)); /// v.distanceToSq([ 32, 64 ]); /// ``` /// /// Point to calculate the squared distance to. /// Squared distance to `pos` public double distanceToSq(object pos) { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the distanceToSq method can not be accessed."); try { Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false); return vertex.DistanceToSq(v); } catch(CantConvertToVectorException e) { throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException(e.Message); } } /// /// Gets the distance between this `Vertex` and the given point. /// The point can be either a `Vector2D` or an array of numbers. /// ``` /// v.distanceTo(new UDB.Vector2D(32, 64)); /// v.distanceTo([ 32, 64 ]); /// ``` /// /// Point to calculate the distance to. /// Distance to `pos` public double distanceTo(object pos) { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the distanceTo method can not be accessed."); try { Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false); return vertex.DistanceTo(v); } catch (CantConvertToVectorException e) { throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException(e.Message); } } /// /// Returns the `Linedef` that is connected to this `Vertex` that is closest to the given point. /// /// Point to get the nearest `Linedef` connected to this `Vertex` from /// public LinedefWrapper nearestLinedef(object pos) { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the nearestLinedef method can not be accessed."); try { Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false); return new LinedefWrapper(vertex.NearestLinedef(v)); } catch (CantConvertToVectorException e) { throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException(e.Message); } } /// /// Snaps the `Vertex`'s position to the map format's accuracy. /// public void snapToAccuracy() { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the snapToAccuracy method can not be accessed."); vertex.SnapToAccuracy(); } /// /// Snaps the `Vertex`'s position to the grid. /// public void snapToGrid() { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the snapToGrid method can not be accessed."); vertex.SnapToGrid(); } /// /// Joins this `Vertex` with another `Vertex`, deleting this `Vertex` and keeping the other. /// /// `Vertex` to join with public void join(VertexWrapper other) { if (vertex.IsDisposed) throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Vertex is disposed, the join method can not be accessed."); vertex.Join(other.vertex); } /// /// Deletes the `Vertex`. Note that this can result in unclosed sectors. /// public void delete() { if (vertex.IsDisposed) return; vertex.Dispose(); } #endregion } }