UltimateZoneBuilder/Source/Plugins/UDBScript/API/SidedefWrapper.cs
biwa 634225b77b UDBScript: Exported the classes Linedef, Sector, Sidedef, Thing, and Vertex, so that they can be used with instanceof
UDBScript: Map class: the getSidedefsFromSelectedLinedefs() method now correctly only returns the Sidedefs of selected Linedefs in visual mode (and not also the highlighted one)
UDBScript: Map class: added a new getSidedefsFromSelectedOrHighlightedLinedefs() method as the equivalent to the other getSelectedOrHighlighted*() methods
UDBScript: Sector class: added new floorSelected, ceilingSelected, floorHighlighted, and ceilingHighlighted properties. Those are mostly useful in visual mode, since they always return true when the Sector is selected or highlighted in the classic modes. The properties are read-only
UDBScript: Sidedef class: added new upperSelected, middleSelected, lowerSelected, upperHighlighted, middleHighlighted, and lowerHighlighted properties. Those are mostly useful in visual mode, since they always return true when the parent Linedef is selected or highlighted in the classic modes. The properties are read-only
UDBScript: added new example to apply textures for floor/ceiling and upper/middle/lower texture for selected map elements
UDBScript: updated documentation
2021-12-25 14:43:56 +01:00

529 lines
14 KiB
C#

#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<http://www.gnu.org/licenses/>.
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.BuilderModes;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.VisualModes;
#endregion
namespace CodeImp.DoomBuilder.UDBScript.Wrapper
{
class SidedefWrapper : MapElementWrapper, IEquatable<SidedefWrapper>
{
#region ================== Variables
private Sidedef sidedef;
#endregion
#region IEquatable<SidedefWrapper> members
public bool Equals(SidedefWrapper other)
{
return sidedef == other.sidedef;
}
public override bool Equals(object obj)
{
return Equals((SidedefWrapper)obj);
}
public override int GetHashCode()
{
return sidedef.GetHashCode();
}
#endregion
#region ================== Properties
/// <summary>
/// The `Sidedef`'s index. Read-only.
/// </summary>
public int index
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the isFront property can not be accessed.");
return sidedef.Index;
}
}
/// <summary>
/// `true` if this `Sidedef` is the front of its `Linedef`, otherwise `false`. Read-only.
/// </summary>
public bool isFront
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the isFront property can not be accessed.");
return sidedef.IsFront;
}
}
/// <summary>
/// The `Sector` the `Sidedef` belongs to. Read-only.
/// </summary>
public SectorWrapper sector
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the sector property can not be accessed.");
return new SectorWrapper(sidedef.Sector);
}
}
/// <summary>
/// The `Linedef` the `Sidedef` belongs to. Read-only.
/// </summary>
public LinedefWrapper line
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the line property can not be accessed.");
return new LinedefWrapper(sidedef.Line);
}
}
/// <summary>
/// The `Sidedef` on the other side of this `Sidedef`'s `Linedef`. Returns `null` if there is no other. Read-only.
/// </summary>
public SidedefWrapper other
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the other property can not be accessed.");
if (sidedef.Other == null)
return null;
return new SidedefWrapper(sidedef.Other);
}
}
/// <summary>
/// The `Sidedef`'s angle in degrees. Read-only.
/// </summary>
public double angle
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the angle property can not be accessed.");
return Angle2D.RadToDeg(sidedef.Angle);
}
}
/// <summary>
/// The `Sidedef`'s angle in radians. Read-only.
/// </summary>
public double angleRad
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the angleRad property can not be accessed.");
return sidedef.Angle;
}
}
/// <summary>
/// The x offset of the `Sidedef`'s textures.
/// </summary>
public int offsetX
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the offsetX property can not be accessed.");
return sidedef.OffsetX;
}
set
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the offsetX property can not be accessed.");
sidedef.OffsetX = value;
}
}
/// <summary>
/// The y offset of the `Sidedef`'s textures.
/// </summary>
public int offsetY
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the offsetY property can not be accessed.");
return sidedef.OffsetY;
}
set
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the offsetY property can not be accessed.");
sidedef.OffsetY = value;
}
}
/// <summary>
/// `Sidedef` flags. It's an object with the flags as properties. Only available in UDMF.
///
/// ```
/// s.flags['noattack'] = true; // Monsters in this sector don't attack
/// s.flags.noattack = true; // Also works
/// ```
/// </summary>
public ExpandoObject flags
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the flags property can not be accessed.");
dynamic eo = new ExpandoObject();
IDictionary<string, object> o = eo as IDictionary<string, object>;
foreach (KeyValuePair<string, bool> kvp in sidedef.GetFlags())
{
o.Add(kvp.Key, kvp.Value);
}
// Create event that gets called when a property is changed. This sets the flag
((INotifyPropertyChanged)eo).PropertyChanged += new PropertyChangedEventHandler((sender, ea) => {
PropertyChangedEventArgs pcea = ea as PropertyChangedEventArgs;
IDictionary<string, object> so = sender as IDictionary<string, object>;
// Only allow known flags to be set
if (!General.Map.Config.SectorFlags.Keys.Contains(pcea.PropertyName))
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Flag name '" + pcea.PropertyName + "' is not valid.");
// New value must be bool
if (!(so[pcea.PropertyName] is bool))
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Flag values must be bool.");
sidedef.SetFlag(pcea.PropertyName, (bool)so[pcea.PropertyName]);
});
return eo;
}
}
/// <summary>
/// The `Sidedef`'s upper texture.
/// </summary>
public string upperTexture
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the upperTexture property can not be accessed.");
return sidedef.HighTexture;
}
set
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the upperTexture property can not be accessed.");
sidedef.SetTextureHigh(value);
// Make sure to update the used textures, so that they are shown immediately
General.Map.Data.UpdateUsedTextures();
}
}
/// <summary>
/// The `Sidedef`'s middle texture.
/// </summary>
public string middleTexture
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the middleTexture property can not be accessed.");
return sidedef.MiddleTexture;
}
set
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the middleTexture property can not be accessed.");
sidedef.SetTextureMid(value);
// Make sure to update the used textures, so that they are shown immediately
General.Map.Data.UpdateUsedTextures();
}
}
/// <summary>
/// The `Sidedef`'s lower texture.
/// </summary>
public string lowerTexture
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the lowerTexture property can not be accessed.");
return sidedef.LowTexture;
}
set
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the lowerTexture property can not be accessed.");
sidedef.SetTextureLow(value);
// Make sure to update the used textures, so that they are shown immediately
General.Map.Data.UpdateUsedTextures();
}
}
/// <summary>
/// If the `Sidedef`'s upper part is selected or not. Will always return `true` in classic modes if the parent `Linedef` is selected.
/// </summary>
/// <version>3</version>
public bool upperSelected
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the upperSelected property can not be accessed.");
if(General.Editing.Mode is BaseVisualMode)
{
bool u, m, l;
((BaseVisualMode)General.Editing.Mode).GetSelectedSurfaceTypesBySidedef(sidedef, out u, out m, out l);
return u;
}
else
{
return sidedef.Line.Selected;
}
}
}
/// <summary>
/// If the `Sidedef`'s upper part is highlighted or not. Will always return `true` in classic modes if the parent `Linedef` is selected.
/// </summary>
/// <version>3</version>
public bool upperHighlighted
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the upperHighlighted property can not be accessed.");
if (General.Editing.Mode is BaseVisualMode)
{
VisualGeometry vs = (VisualGeometry)((BaseVisualMode)General.Editing.Mode).Highlighted;
if (vs == null)
return false;
return (vs.Sidedef == sidedef && vs.GeometryType == VisualGeometryType.WALL_UPPER);
}
else
{
Linedef ld = ((ClassicMode)General.Editing.Mode).HighlightedObject as Linedef;
if (ld == null)
return false;
return (ld.Front == sidedef || (ld.Back != null && ld.Back == sidedef));
}
}
}
/// <summary>
/// If the `Sidedef`'s middle part is selected or not. Will always return `true` in classic modes if the parent `Linedef` is selected.
/// </summary>
/// <version>3</version>
public bool middleSelected
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the middleSelected property can not be accessed.");
if (General.Editing.Mode is BaseVisualMode)
{
bool u, m, l;
((BaseVisualMode)General.Editing.Mode).GetSelectedSurfaceTypesBySidedef(sidedef, out u, out m, out l);
return m;
}
else
{
return sidedef.Line.Selected;
}
}
}
/// <summary>
/// If the `Sidedef`'s middle part is highlighted or not. Will always return `true` in classic modes if the parent `Linedef` is selected.
/// </summary>
/// <version>3</version>
public bool middleHighlighted
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the middleHighlighted property can not be accessed.");
if (General.Editing.Mode is BaseVisualMode)
{
VisualGeometry vs = (VisualGeometry)((BaseVisualMode)General.Editing.Mode).Highlighted;
if (vs == null)
return false;
return (vs.Sidedef == sidedef && (vs.GeometryType == VisualGeometryType.WALL_MIDDLE || vs.GeometryType == VisualGeometryType.WALL_MIDDLE_3D));
}
else
{
Linedef ld = ((ClassicMode)General.Editing.Mode).HighlightedObject as Linedef;
if (ld == null)
return false;
return (ld.Front == sidedef || (ld.Back != null && ld.Back == sidedef));
}
}
}
/// <summary>
/// If the `Sidedef`'s lower part is selected or not. Will always return `true` in classic modes if the parent `Linedef` is selected.
/// </summary>
/// <version>3</version>
public bool lowerSelected
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the lowerSelected property can not be accessed.");
if (General.Editing.Mode is BaseVisualMode)
{
bool u, m, l;
((BaseVisualMode)General.Editing.Mode).GetSelectedSurfaceTypesBySidedef(sidedef, out u, out m, out l);
return l;
}
else
{
return sidedef.Line.Selected;
}
}
}
/// <summary>
/// If the `Sidedef`'s lower part is highlighted or not. Will always return `true` in classic modes if the parent `Linedef` is selected.
/// </summary>
/// <version>3</version>
public bool lowerHighlighted
{
get
{
if (sidedef.IsDisposed)
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Sidedef is disposed, the lowerHighlighted property can not be accessed.");
if (General.Editing.Mode is BaseVisualMode)
{
VisualGeometry vs = (VisualGeometry)((BaseVisualMode)General.Editing.Mode).Highlighted;
if (vs == null)
return false;
return (vs.Sidedef == sidedef && vs.GeometryType == VisualGeometryType.WALL_LOWER);
}
else
{
Linedef ld = ((ClassicMode)General.Editing.Mode).HighlightedObject as Linedef;
if (ld == null)
return false;
return (ld.Front == sidedef || (ld.Back != null && ld.Back == sidedef));
}
}
}
#endregion
#region ================== Constructors
internal SidedefWrapper(Sidedef sidedef) : base(sidedef)
{
this.sidedef = sidedef;
}
#endregion
#region ================== Update
internal override void AfterFieldsUpdate()
{
}
#endregion
#region ================== Methods
public override string ToString()
{
return sidedef.ToString();
}
#endregion
}
}