mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
UDBScript version 5 (#819)
Improved UDBScript to version 5: - Added Plane class - Added BlockMap, BlockEntry, and BlackMapQueryResult classes - Sector class - Added getLabelPositions method to get the position of sector labels (where tags, effects etc. are displayed) - Added support for JavaScript BigInt for UDMF fields. This means it's not necessary anymore to use UniValue to assign integers to new UDMF fields. Instead it can be done like this: sector.fields.my_int_field = 1n; - Added type information file (udbscript.d.ts)
This commit is contained in:
parent
204982e5f8
commit
5b2b149b40
76 changed files with 4093 additions and 783 deletions
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
// Inspired by ribbiks's DBX Lua script: https://github.com/ribbiks/doom_lua/
|
||||
|
||||
`#version 4`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Create Line Portal`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Create PolyObject`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
// Inspired by ribbiks's DBX Lua script: https://github.com/ribbiks/doom_lua/
|
||||
|
||||
`#version 4`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Jitter Vertices`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Make Door`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
`#name Triangulate Sectors`;
|
||||
`#description Triangulates the selected or highlighted sectors into new sectors. Note that the triangulation will not "be beautiful", and that the sectors with islands may cause problems.`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Draw Voodoo Doll Closet`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Logic assertions`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Show Map Squareness`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Calculate sector area`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Apply textures to selected surfaces`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Delete Sector Tag`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Flip Triangular Sectors`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Imps to Arch-Viles`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Randomize Selection Order`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Randomize Texture Offsets`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Reorder Things Indices`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference path="../../udbscript.d.ts" />
|
||||
|
||||
`#version 4`;
|
||||
|
||||
`#name Select Connected Linedefs`;
|
||||
|
|
1735
Build/UDBScript/udbscript.d.ts
vendored
Normal file
1735
Build/UDBScript/udbscript.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
URL http://devbuilds.drdteam.org/ultimatedoombuilder/
|
||||
FileName Builder.exe
|
||||
UpdateName UltimateDoomBuilder-r[REVNUM]-x64.7z
|
||||
InstallerName UltimateDoomBuilder-Setup-R[REVNUM]-x64.exe
|
||||
UpdaterName UDB_Updater-x64.7z
|
||||
UpdateName UltimateDoomBuilder-r[REVNUM]-x86.7z
|
||||
InstallerName UltimateDoomBuilder-Setup-R[REVNUM]-x86.exe
|
||||
UpdaterName UDB_Updater-x86.7z
|
|
@ -672,6 +672,7 @@
|
|||
<HintPath>..\..\Build\SharpCompress.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
|
@ -679,6 +680,9 @@
|
|||
<Reference Include="System.Design" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="TabControlEX, Version=0.0.3271.41578, Culture=neutral, PublicKeyToken=1db242dc828e4b4e">
|
||||
|
|
|
@ -31,12 +31,14 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
internal struct Angle2DWrapper
|
||||
{
|
||||
#region ================== Methods
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Doom angle (where 0° is east) to a real world angle (where 0° is north).
|
||||
/// </summary>
|
||||
/// <param name="doomangle">Doom angle in degrees</param>
|
||||
/// <returns>Doom angle in degrees</returns>
|
||||
public static double doomToReal(int doomangle)
|
||||
public double doomToReal(int doomangle)
|
||||
{
|
||||
return normalized(doomangle + 90);
|
||||
}
|
||||
|
@ -46,7 +48,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="doomangle">Doom angle in degrees</param>
|
||||
/// <returns>Doom angle in radians</returns>
|
||||
public static double doomToRealRad(int doomangle)
|
||||
public double doomToRealRad(int doomangle)
|
||||
{
|
||||
return Angle2D.DoomToReal(doomangle);
|
||||
}
|
||||
|
@ -56,17 +58,17 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="realangle">Real world angle in degrees</param>
|
||||
/// <returns>Doom angle in degrees</returns>
|
||||
public static int realToDoom(double realangle)
|
||||
public int realToDoom(double realangle)
|
||||
{
|
||||
return normalized((int)(realangle - 90));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a real world angle (where 0° is north) to a Doom angle (where 0° is east) in radians.
|
||||
/// Converts a real world angle (where 0° is north) to a Doom angle (where 0° is east) in radians.
|
||||
/// </summary>
|
||||
/// <param name="realangle">Real world angle in radians</param>
|
||||
/// <returns>Doom angle in degrees</returns>
|
||||
public static int realToDoomRad(double realangle)
|
||||
public int realToDoomRad(double realangle)
|
||||
{
|
||||
return Angle2D.RealToDoom(realangle);
|
||||
}
|
||||
|
@ -76,7 +78,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="rad">Angle in radians</param>
|
||||
/// <returns>Angle in degrees</returns>
|
||||
public static double radToDeg(double rad)
|
||||
public double radToDeg(double rad)
|
||||
{
|
||||
return Angle2D.RadToDeg(rad);
|
||||
}
|
||||
|
@ -86,7 +88,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="deg">Angle in degrees</param>
|
||||
/// <returns>Angle in radians</returns>
|
||||
public static double degToRad(double deg)
|
||||
public double degToRad(double deg)
|
||||
{
|
||||
return Angle2D.DegToRad(deg);
|
||||
}
|
||||
|
@ -96,7 +98,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="angle">Angle in degrees</param>
|
||||
/// <returns>Normalized angle in degrees</returns>
|
||||
public static int normalized(int angle)
|
||||
public int normalized(int angle)
|
||||
{
|
||||
while (angle < 0) angle += 360;
|
||||
while (angle >= 360) angle -= 360;
|
||||
|
@ -108,7 +110,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="angle">Angle in radians</param>
|
||||
/// <returns>Normalized angle in radians</returns>
|
||||
public static double normalizedRad(double angle)
|
||||
public double normalizedRad(double angle)
|
||||
{
|
||||
return Angle2D.Normalized(angle);
|
||||
}
|
||||
|
@ -120,13 +122,13 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// <param name="p2">Second position</param>
|
||||
/// <param name="p3">Third position</param>
|
||||
/// <returns>Angle in degrees</returns>
|
||||
public static double getAngle(object p1, object p2, object p3)
|
||||
public double getAngle(object p1, object p2, object p3)
|
||||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p1, false);
|
||||
Vector2D v2 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p2, false);
|
||||
Vector2D v3 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p3, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(p1);
|
||||
Vector2D v2 = BuilderPlug.Me.GetVector3DFromObject(p2);
|
||||
Vector2D v3 = BuilderPlug.Me.GetVector3DFromObject(p3);
|
||||
|
||||
return Angle2D.RadToDeg(Angle2D.GetAngle(v1, v2, v3));
|
||||
}
|
||||
|
@ -143,13 +145,13 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// <param name="p2">Second position</param>
|
||||
/// <param name="p3">Third position</param>
|
||||
/// <returns>Angle in radians</returns>
|
||||
public static double getAngleRad(object p1, object p2, object p3)
|
||||
public double getAngleRad(object p1, object p2, object p3)
|
||||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p1, false);
|
||||
Vector2D v2 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p2, false);
|
||||
Vector2D v3 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p3, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(p1);
|
||||
Vector2D v2 = BuilderPlug.Me.GetVector3DFromObject(p2);
|
||||
Vector2D v3 = BuilderPlug.Me.GetVector3DFromObject(p3);
|
||||
|
||||
return Angle2D.GetAngle(v1, v2, v3);
|
||||
}
|
||||
|
@ -158,5 +160,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
96
Source/Plugins/UDBScript/API/BlockEntryWrapper.cs
Normal file
96
Source/Plugins/UDBScript/API/BlockEntryWrapper.cs
Normal file
|
@ -0,0 +1,96 @@
|
|||
#region ================== Copyright (c) 2022 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 CodeImp.DoomBuilder.Map;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// A `BlockEntry` is a single block in a `BlockMap`. It has methods to retrieve the linedefs, things, sectors, and vertices that are in this block.
|
||||
/// </summary>
|
||||
class BlockEntryWrapper : BlockMapContentBase
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private BlockEntry entry;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructors
|
||||
|
||||
internal BlockEntryWrapper(BlockEntry entry)
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Linedef`s in the blockmap entry.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Linedef`s</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override LinedefWrapper[] getLinedefs()
|
||||
{
|
||||
return GetArray(entry.Lines, ref wrappedlines);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Thing`s in the blockmap entry.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Thing`s</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override ThingWrapper[] getThings()
|
||||
{
|
||||
return GetArray(entry.Things, ref wrappedthings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Sector`s in the blockmap entry.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Sector`s</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override SectorWrapper[] getSectors()
|
||||
{
|
||||
return GetArray(entry.Sectors, ref wrappedsectors);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Vertex` in the blockmap entry.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Vertex`</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override VertexWrapper[] getVertices()
|
||||
{
|
||||
return GetArray(entry.Vertices, ref wrappedvertices);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
76
Source/Plugins/UDBScript/API/BlockMapContentBase.cs
Normal file
76
Source/Plugins/UDBScript/API/BlockMapContentBase.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
#region ================== Copyright (c) 2022 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.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
||||
{
|
||||
abstract class BlockMapContentBase
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
protected LinedefWrapper[] wrappedlines;
|
||||
protected ThingWrapper[] wrappedthings;
|
||||
protected SectorWrapper[] wrappedsectors;
|
||||
protected VertexWrapper[] wrappedvertices;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
abstract public LinedefWrapper[] getLinedefs();
|
||||
abstract public ThingWrapper[] getThings();
|
||||
abstract public SectorWrapper[] getSectors();
|
||||
abstract public VertexWrapper[] getVertices();
|
||||
|
||||
/// <summary>
|
||||
/// Fills the container array with wrapped instances of the map elements in the given list.
|
||||
/// </summary>
|
||||
/// <typeparam name="W">Wrapped map element type</typeparam>
|
||||
/// <typeparam name="T">Regular map element type</typeparam>
|
||||
/// <param name="list">List of regular map elements</param>
|
||||
/// <param name="container">Array of wrapped map elements</param>
|
||||
/// <returns></returns>
|
||||
protected internal W[] GetArray<W, T>(IEnumerable<T> list, ref W[] container)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
if (list == null)
|
||||
container = new W[0];
|
||||
else
|
||||
container = list.Select(s => (W)Activator.CreateInstance(typeof(W), BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { s }, null)).ToArray();
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
145
Source/Plugins/UDBScript/API/BlockMapQueryResult.cs
Normal file
145
Source/Plugins/UDBScript/API/BlockMapQueryResult.cs
Normal file
|
@ -0,0 +1,145 @@
|
|||
#region ================== Copyright (c) 2022 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// A `BlockMapQueryResult` is an object returned by the `getLineBlocks` and `getRectangleBlocks` methods of the `BlockMap` class. It has methods It has methods to retrieve the linedefs, things, sectors, and vertices that are in the queried blocks. The object is also iterable, returning each block, in cases where more fine-grained control is needed.
|
||||
/// ```
|
||||
/// const blockmap = new UDB.BlockMap();
|
||||
/// const result = blockmap.getLineBlocks([ 0, 0 ], [ 512, 256 ]);
|
||||
///
|
||||
/// // Print all linedefs in the blocks
|
||||
/// result.getLinedefs().forEach(ld => UDB.log(ld));
|
||||
/// ```
|
||||
/// Looping over each block:
|
||||
/// ```
|
||||
/// const blockmap = new UDB.BlockMap();
|
||||
/// const result = blockmap.getLineBlocks([ 0, 0 ], [ 512, 256 ]);
|
||||
///
|
||||
/// for(const block of result)
|
||||
/// {
|
||||
/// UDB.log('--- New block ---');
|
||||
/// block.getLinedefs().forEach(ld => UDB.log(ld));
|
||||
/// }
|
||||
/// ```
|
||||
/// !!! note
|
||||
/// The methods to retrieve map elements from `BlockMapQueryResult` return arrays that only contain each map element once, since linedefs and sectors can be in multiple blocks, looping over a `BlockMapQueryResult` using `for...of` can return the same map elements multiple times.
|
||||
/// </summary>
|
||||
class BlockMapQueryResult : BlockMapContentBase, IEnumerable<BlockEntryWrapper>
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private BlockEntryWrapper[] wrappedentries;
|
||||
private IEnumerable<BlockEntry> entries;
|
||||
private HashSet<Linedef> lines;
|
||||
private HashSet<Thing> things;
|
||||
private HashSet<Sector> sectors;
|
||||
private HashSet<Vertex> vertices;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructors
|
||||
|
||||
internal BlockMapQueryResult(IEnumerable<BlockEntry> entries)
|
||||
{
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Linedef`s in the blockmap query result.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Linedef`s</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override LinedefWrapper[] getLinedefs()
|
||||
{
|
||||
if (lines == null)
|
||||
lines = new HashSet<Linedef>(entries.SelectMany(be => be.Lines));
|
||||
|
||||
return GetArray(lines, ref wrappedlines);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Thing`s in the blockmap query result.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Thing`s</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override ThingWrapper[] getThings()
|
||||
{
|
||||
if (things == null)
|
||||
things = new HashSet<Thing>(entries.SelectMany(be => be.Things));
|
||||
|
||||
return GetArray(things, ref wrappedthings);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Sector`s in the blockmap query result.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Sector`s</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override SectorWrapper[] getSectors()
|
||||
{
|
||||
if (sectors == null)
|
||||
sectors = new HashSet<Sector>(entries.SelectMany(be => be.Sectors));
|
||||
|
||||
return GetArray(sectors, ref wrappedsectors);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all `Vertex` in the blockmap query result.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Vertex`</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public override VertexWrapper[] getVertices()
|
||||
{
|
||||
if (vertices == null)
|
||||
vertices = new HashSet<Vertex>(entries.SelectMany(be => be.Vertices));
|
||||
|
||||
return GetArray(vertices, ref wrappedvertices);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Enumeration
|
||||
|
||||
public IEnumerator<BlockEntryWrapper> GetEnumerator() => ((IEnumerable<BlockEntryWrapper>)GetArray(entries, ref wrappedentries)).GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetArray(entries, ref wrappedentries).GetEnumerator();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
228
Source/Plugins/UDBScript/API/BlockMapWrapper.cs
Normal file
228
Source/Plugins/UDBScript/API/BlockMapWrapper.cs
Normal file
|
@ -0,0 +1,228 @@
|
|||
#region ================== Copyright (c) 2022 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.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Dynamic;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// A blockmap is used to retrieve a collection of localized map elements (things, linedefs, sectors, vertices). It can help to significantly speed up costly computations that would otherwise be applied to a large portion of the map elements. The blockmap divides the map into rectangular blocks and computes which map elements are fully or partially in each block. Then you can query the blockmap about only some of those blocks, and perform any further actions only on the map elements that are in those blocks.
|
||||
///
|
||||
/// If you for example wanted to find out which sector is at the (0, 0) position you could write something like this without using a blockmap:
|
||||
/// ```
|
||||
/// UDB.Map.getSectors().findIndex((s, i) => {
|
||||
/// if(s.intersect([ 0, 0 ]))
|
||||
/// {
|
||||
/// UDB.log(`Found ${s} after ${i} tries.`)
|
||||
/// return true;
|
||||
/// }
|
||||
/// });
|
||||
/// ```
|
||||
/// This loops through all sectors of the map and uses the `intersect` method to test if the point is inside the sector. While `intersect` is quite fast on its own, doing it potentially thousands of times adds up quickly, especially if you have to loop through all sectors multiple times.
|
||||
/// A pretty extreme example for this is the map Bastion of Chaos. The map contains nearly 32500 sectors, and the sector at (0, 0) is number 25499. That means that the above script has to run `intersect` on 25499 sectors, even on those that are not remotely near the (0, 0) position.
|
||||
///
|
||||
/// Using a blockmap the code could look like this:
|
||||
/// ```
|
||||
/// const blockmap = new UDB.BlockMap();
|
||||
///
|
||||
/// blockmap.getBlockAt([ 0, 0 ]).getSectors().findIndex((s, i) => {
|
||||
/// if (s.intersect([0, 0]))
|
||||
/// {
|
||||
/// UDB.log(`Found ${s} after ${i} tries.`)
|
||||
/// return true;
|
||||
/// }
|
||||
/// });
|
||||
/// ```
|
||||
/// As you can see the code is quite similar, the difference being that a blockmap is created, and `UDB.Map` is replaced by `blockmap.getBlockAt([ 0, 0 ])`, the latter only getting a single block from the blockmap, that only contains the map elements that are in this block. Taking Bastion of Chaos as an example again, this code finds the sector after only 20 checks, instead of the 25499 checks in the first code example.
|
||||
///
|
||||
/// !!! note
|
||||
/// Creating a blockmap has a small overhead, since it has to compute which map elements are in which blocks. This overhead, however, is quickly compensated by the time saved by not looping through irrelevant map elements. You can decrease this overhead by using a `BlockMap` constructor that only adds certain map element types to the blockmap.
|
||||
///
|
||||
/// </summary>
|
||||
class BlockMapWrapper
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private BlockMap<BlockEntry> blockmap;
|
||||
private Dictionary<BlockEntry, BlockEntryWrapper> blockentries;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Creates a blockmap that includes linedefs, things, sectors, and vertices.
|
||||
/// ```
|
||||
/// // Create a blockmap that includes all linedefs, things, sectors, and vertices
|
||||
/// const blockmap = new UDB.BlockMap();
|
||||
/// ```
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public BlockMapWrapper()
|
||||
{
|
||||
CreateBlockmap(true, true, true, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a blockmap that only includes certain map element types.
|
||||
/// ```
|
||||
/// // Create a blockmap that only includes sectors
|
||||
/// const blockmap = new UDB.BlockMap(false, false, true, false);
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="lines">If linedefs should be added or not</param>
|
||||
/// <param name="things">If thigs should be added or not</param>
|
||||
/// <param name="sectors">If sectors should be added or not</param>
|
||||
/// <param name="vertices">If vertices should be added or not</param>
|
||||
/// [UDBScriptSettings(MinVersion = 5)]
|
||||
public BlockMapWrapper(bool lines, bool things, bool sectors, bool vertices)
|
||||
{
|
||||
CreateBlockmap(lines, things, sectors, vertices);
|
||||
}
|
||||
|
||||
internal BlockMapWrapper(ExpandoObject options)
|
||||
{
|
||||
bool lines = IsOptionSet(options, "lines");
|
||||
bool things = IsOptionSet(options, "things");
|
||||
bool sectors = IsOptionSet(options, "sectors");
|
||||
bool vertices = IsOptionSet(options, "vertices");
|
||||
|
||||
CreateBlockmap(lines, things, sectors, vertices);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
/// <summary>
|
||||
/// Generates the blockmap and adds the wanted map elements.
|
||||
/// </summary>
|
||||
/// <param name="lines">If linedefs should be added or not</param>
|
||||
/// <param name="things">If thigs should be added or not</param>
|
||||
/// <param name="sectors">If sectors should be added or not</param>
|
||||
/// <param name="vertices">If vertices should be added or not</param>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
private void CreateBlockmap(bool lines, bool things, bool sectors, bool vertices)
|
||||
{
|
||||
RectangleF area = MapSet.CreateArea(General.Map.Map.Vertices);
|
||||
|
||||
if (things)
|
||||
area = MapSet.IncreaseArea(area, General.Map.Map.Things);
|
||||
|
||||
blockmap = new BlockMap<BlockEntry>(area);
|
||||
|
||||
if (lines)
|
||||
blockmap.AddLinedefsSet(General.Map.Map.Linedefs);
|
||||
|
||||
if (things)
|
||||
blockmap.AddThingsSet(General.Map.Map.Things);
|
||||
|
||||
if (sectors)
|
||||
blockmap.AddSectorsSet(General.Map.Map.Sectors);
|
||||
|
||||
if (vertices)
|
||||
blockmap.AddVerticesSet(General.Map.Map.Vertices);
|
||||
|
||||
blockentries = new Dictionary<BlockEntry, BlockEntryWrapper>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a dictionary contains a given key and if it's set to true or false.
|
||||
/// </summary>
|
||||
/// <param name="options">The dictionary to check</param>
|
||||
/// <param name="name">Name of the option to check</param>
|
||||
/// <returns>true if the option exists and is set to true, false if the option doesn't exist or is set to false</returns>
|
||||
private bool IsOptionSet(IDictionary<string, object> options, string name)
|
||||
{
|
||||
return options != null && options.ContainsKey(name) && options[name] is bool value && value == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the `BlockEntry` at a point. The given point can be a `Vector2D` or an `Array` of two numbers.
|
||||
/// ```
|
||||
/// const blockmap = new UDB.BlockMap();
|
||||
/// const blockentry = blockmap.getBlockAt([ 64, 128 ]);
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="pos">The point to get the `BlockEntry` of</param>
|
||||
/// <returns>The `BlockEntry` on the given point</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public BlockEntryWrapper getBlockAt(object pos)
|
||||
{
|
||||
Vector2D p = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
BlockEntry be = blockmap.GetBlockAt(p);
|
||||
|
||||
if (!blockentries.ContainsKey(be))
|
||||
blockentries[be] = new BlockEntryWrapper(be);
|
||||
|
||||
return blockentries[be];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a `BlockMapQueryResult` for the blockmap along a line between two points. The given points can be `Vector2D`s or an `Array`s of two numbers.
|
||||
/// ```
|
||||
/// const blockmap = new UDB.BlockMap();
|
||||
/// const result = blockmap.getLineBlocks([ 0, 0 ], [ 512, 256 ]);
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="v1">The first point</param>
|
||||
/// <param name="v2">The second point</param>
|
||||
/// <returns>The `BlockMapQueryResult` for the line between the two points</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public BlockMapQueryResult getLineBlocks(object v1, object v2)
|
||||
{
|
||||
Vector2D p1 = BuilderPlug.Me.GetVector3DFromObject(v1);
|
||||
Vector2D p2 = BuilderPlug.Me.GetVector3DFromObject(v2);
|
||||
|
||||
return new BlockMapQueryResult(blockmap.GetLineBlocks(p1, p2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a `BlockMapQueryResult` for the blockmap in a rectangle.
|
||||
/// ```
|
||||
/// const blockmap = new UDB.BlockMap();
|
||||
/// const result = blockmap.getRectangleBlocks(0, 0, 512, 256);
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="x">X position of the top-left corner of the rectangle</param>
|
||||
/// <param name="y">Y position of the top-left corner of the rectangle</param>
|
||||
/// <param name="width">Width of the rectangle</param>
|
||||
/// <param name="height">Height of the rectangle</param>
|
||||
/// <returns></returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public BlockMapQueryResult getRectangleBlocks(int x, int y, int width, int height)
|
||||
{
|
||||
return new BlockMapQueryResult(blockmap.GetSquareRange(new RectangleF(x, y, width, height)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -38,11 +38,19 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
class DataWrapper
|
||||
{
|
||||
#region ================== Constructors
|
||||
|
||||
internal DataWrapper() { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns an `Array` of all texture names.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of all texture names</returns>
|
||||
public static string[] getTextureNames()
|
||||
public string[] getTextureNames()
|
||||
{
|
||||
return General.Map.Data.TextureNames.ToArray();
|
||||
}
|
||||
|
@ -52,7 +60,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="name">Texture name to check</param>
|
||||
/// <returns>`true` if the texture exists, `false` if it doesn't</returns>
|
||||
public static bool textureExists(string name)
|
||||
public bool textureExists(string name)
|
||||
{
|
||||
return General.Map.Data.GetTextureExists(name);
|
||||
}
|
||||
|
@ -62,7 +70,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="name">Texture name to get the info for</param>
|
||||
/// <returns>`ImageInfo` object containing information about the texture</returns>
|
||||
public static ImageInfo getTextureInfo(string name)
|
||||
public ImageInfo getTextureInfo(string name)
|
||||
{
|
||||
return new ImageInfo(General.Map.Data.GetTextureImage(name));
|
||||
}
|
||||
|
@ -71,7 +79,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// Returns an `Array`of all flat names.
|
||||
/// </summary>
|
||||
/// <returns>`Array` of all flat names</returns>
|
||||
public static string[] getFlatNames()
|
||||
public string[] getFlatNames()
|
||||
{
|
||||
return General.Map.Data.FlatNames.ToArray();
|
||||
}
|
||||
|
@ -81,7 +89,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="name">Flat name to check</param>
|
||||
/// <returns>`true` if the flat exists, `false` if it doesn't</returns>
|
||||
public static bool flatExists(string name)
|
||||
public bool flatExists(string name)
|
||||
{
|
||||
return General.Map.Data.GetFlatExists(name);
|
||||
}
|
||||
|
@ -91,9 +99,11 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// </summary>
|
||||
/// <param name="name">Flat name to get the info for</param>
|
||||
/// <returns>`ImageInfo` object containing information about the flat</returns>
|
||||
public static ImageInfo getFlatInfo(string name)
|
||||
public ImageInfo getFlatInfo(string name)
|
||||
{
|
||||
return new ImageInfo(General.Map.Data.GetFlatImage(name));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,8 +66,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
this.v1 = new Vector2DWrapper((Vector2D)BuilderPlug.Me.GetVectorFromObject(v1, false));
|
||||
this.v2 = new Vector2DWrapper((Vector2D)BuilderPlug.Me.GetVectorFromObject(v2, false));
|
||||
this.v1 = new Vector2DWrapper(BuilderPlug.Me.GetVector3DFromObject(v1));
|
||||
this.v2 = new Vector2DWrapper(BuilderPlug.Me.GetVector3DFromObject(v2));
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -114,10 +114,10 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a1, false);
|
||||
Vector2D v2 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a2, false);
|
||||
Vector2D v3 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b1, false);
|
||||
Vector2D v4 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b2, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(a1);
|
||||
Vector2D v2 = BuilderPlug.Me.GetVector3DFromObject(a2);
|
||||
Vector2D v3 = BuilderPlug.Me.GetVector3DFromObject(b1);
|
||||
Vector2D v4 = BuilderPlug.Me.GetVector3DFromObject(b2);
|
||||
double u_ray;
|
||||
|
||||
return Line2D.GetIntersection(v1, v2, v3.x, v3.y, v4.x, v4.y, out u_ray, bounded);
|
||||
|
@ -141,10 +141,10 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a1, false);
|
||||
Vector2D v2 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a2, false);
|
||||
Vector2D v3 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b1, false);
|
||||
Vector2D v4 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b2, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(a1);
|
||||
Vector2D v2 = BuilderPlug.Me.GetVector3DFromObject(a2);
|
||||
Vector2D v3 = BuilderPlug.Me.GetVector3DFromObject(b1);
|
||||
Vector2D v4 = BuilderPlug.Me.GetVector3DFromObject(b2);
|
||||
|
||||
return new Vector2DWrapper(Line2D.GetIntersectionPoint(new Line2D(v1, v2), new Line2D(v3, v4), bounded));
|
||||
}
|
||||
|
@ -165,9 +165,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v11 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v1, false);
|
||||
Vector2D v21 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v2, false);
|
||||
Vector2D p1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p, false);
|
||||
Vector2D v11 = BuilderPlug.Me.GetVector3DFromObject(v1);
|
||||
Vector2D v21 = BuilderPlug.Me.GetVector3DFromObject(v2);
|
||||
Vector2D p1 = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return Line2D.GetSideOfLine(v11, v21, p1);
|
||||
}
|
||||
|
@ -189,9 +189,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v11 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v1, false);
|
||||
Vector2D v21 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v2, false);
|
||||
Vector2D p1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p, false);
|
||||
Vector2D v11 = BuilderPlug.Me.GetVector3DFromObject(v1);
|
||||
Vector2D v21 = BuilderPlug.Me.GetVector3DFromObject(v2);
|
||||
Vector2D p1 = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return Line2D.GetDistanceToLine(v11, v21, p1, bounded);
|
||||
}
|
||||
|
@ -213,9 +213,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v11 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v1, false);
|
||||
Vector2D v21 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v2, false);
|
||||
Vector2D p1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p, false);
|
||||
Vector2D v11 = BuilderPlug.Me.GetVector3DFromObject(v1);
|
||||
Vector2D v21 = BuilderPlug.Me.GetVector3DFromObject(v2);
|
||||
Vector2D p1 = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return Line2D.GetDistanceToLineSq(v11, v21, p1, bounded);
|
||||
}
|
||||
|
@ -236,9 +236,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v11 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v1, false);
|
||||
Vector2D v21 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v2, false);
|
||||
Vector2D p1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p, false);
|
||||
Vector2D v11 = BuilderPlug.Me.GetVector3DFromObject(v1);
|
||||
Vector2D v21 = BuilderPlug.Me.GetVector3DFromObject(v2);
|
||||
Vector2D p1 = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return Line2D.GetNearestOnLine(v11, v21, p1);
|
||||
}
|
||||
|
@ -259,8 +259,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v11 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v1, false);
|
||||
Vector2D v21 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v2, false);
|
||||
Vector2D v11 = BuilderPlug.Me.GetVector3DFromObject(v1);
|
||||
Vector2D v21 = BuilderPlug.Me.GetVector3DFromObject(v2);
|
||||
|
||||
return new Vector2DWrapper(Line2D.GetCoordinatesAt(v11, v21, u));
|
||||
}
|
||||
|
@ -343,8 +343,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v3 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a1, false);
|
||||
Vector2D v4 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a2, false);
|
||||
Vector2D v3 = BuilderPlug.Me.GetVector3DFromObject(a1);
|
||||
Vector2D v4 = BuilderPlug.Me.GetVector3DFromObject(a2);
|
||||
double u_ray;
|
||||
|
||||
return AsLine2D().GetIntersection(v3.x, v3.y, v4.x, v4.y, out u_ray, bounded);
|
||||
|
@ -366,8 +366,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v3 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a1, false);
|
||||
Vector2D v4 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a2, false);
|
||||
Vector2D v3 = BuilderPlug.Me.GetVector3DFromObject(a1);
|
||||
Vector2D v4 = BuilderPlug.Me.GetVector3DFromObject(a2);
|
||||
Line2D line = AsLine2D();
|
||||
double u_ray;
|
||||
line.GetIntersection(v3.x, v3.y, v4.x, v4.y, out u_ray, bounded);
|
||||
|
@ -405,7 +405,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D p1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p, false);
|
||||
Vector2D p1 = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return AsLine2D().GetSideOfLine(p1);
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// <summary>
|
||||
/// `Array` of arguments of the `Linedef`. Number of arguments depends on game config (usually 5). Hexen format and UDMF only.
|
||||
/// </summary>
|
||||
/// <fakedtstype>number[]</fakedtstype>
|
||||
public MapElementArgumentsWrapper args
|
||||
{
|
||||
get
|
||||
|
@ -527,7 +528,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return new Vector2DWrapper(linedef.NearestOnLine(v));
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -549,7 +550,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return linedef.SafeDistanceToSq(v, bounded);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -571,7 +572,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return linedef.SafeDistanceTo(v, bounded);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -593,7 +594,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return linedef.DistanceToSq(v, bounded);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -615,7 +616,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return linedef.DistanceTo(v, bounded);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -636,7 +637,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return linedef.SideOfLine(v);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -660,7 +661,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
Vertex nv = General.Map.Map.CreateVertex(v);
|
||||
nv.SnapToAccuracy();
|
||||
Linedef nld = linedef.Split(nv);
|
||||
|
|
|
@ -28,6 +28,7 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Types;
|
||||
|
@ -62,7 +63,13 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
///
|
||||
/// * it only works for fields that are not in the base UDMF standard, since those are handled directly in the respective class
|
||||
/// * it does not work for flags. While they are technically also UDMF fields, they are handled in the `flags` field of the respective class (where applicable)
|
||||
/// * JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation, using the `UniValue` class:
|
||||
/// * JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation:
|
||||
/// Version 5 and later:
|
||||
/// You can use a `BigInt`. This is done by appending a `n` to the number. Note that this is just a convenient way to define whole numbers, it still only supports 32 bit integers:
|
||||
/// ```
|
||||
/// s.fields.user_myintfield = 25n; // Sets the 'user_myintfield' field to an integer value of 25
|
||||
/// ```
|
||||
/// In version 4 and earlier you have to use the `UniValue` class:
|
||||
/// ```
|
||||
/// s.fields.user_myintfield = new UDB.UniValue(0, 25); // Sets the 'user_myintfield' field to an integer value of 25
|
||||
/// ```
|
||||
|
@ -116,21 +123,45 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
if (so[pname] != null)
|
||||
{
|
||||
object oldvalue = element.Fields[pname].Value;
|
||||
object proposedvalue;
|
||||
|
||||
if (so[pname] is double && ((oldvalue is int) || (oldvalue is double)))
|
||||
if (so[pname] is UniValue)
|
||||
proposedvalue = BuilderPlug.Me.GetConvertedUniValue((UniValue)so[pname]);
|
||||
else if(so[pname] is BigInteger pv)
|
||||
{
|
||||
// Manually check the range, so that we can show a more useful error
|
||||
if (pv > int.MaxValue)
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException($"Value {pv} for UDMF field \"{pname}\" is too big. Maximum value is {int.MaxValue}");
|
||||
|
||||
if (pv < int.MinValue)
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException($"Value {pv} for UDMF field \"{pname}\" is too small. Minimum value is {int.MinValue}");
|
||||
|
||||
proposedvalue = (int)pv;
|
||||
}
|
||||
else
|
||||
proposedvalue = so[pname];
|
||||
|
||||
if (proposedvalue is double && (oldvalue is int || oldvalue is double))
|
||||
{
|
||||
if (oldvalue is int)
|
||||
newvalue = Convert.ToInt32((double)so[pname]);
|
||||
else if (oldvalue is double)
|
||||
newvalue = (double)so[pname];
|
||||
newvalue = Convert.ToInt32((double)proposedvalue);
|
||||
else
|
||||
newvalue = (double)proposedvalue;
|
||||
}
|
||||
else if (so[pname] is string && oldvalue is string)
|
||||
else if(proposedvalue is int && (oldvalue is int || oldvalue is double))
|
||||
{
|
||||
newvalue = (string)so[pname];
|
||||
if (oldvalue is int)
|
||||
newvalue = (int)proposedvalue;
|
||||
else
|
||||
newvalue = Convert.ToDouble((int)proposedvalue);
|
||||
}
|
||||
else if (so[pname] is bool && oldvalue is bool)
|
||||
else if (proposedvalue is string && oldvalue is string)
|
||||
{
|
||||
newvalue = (bool)so[pname];
|
||||
newvalue = (string)proposedvalue;
|
||||
}
|
||||
else if (proposedvalue is bool && oldvalue is bool)
|
||||
{
|
||||
newvalue = (bool)proposedvalue;
|
||||
}
|
||||
else
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("UDMF field '" + pname + "' is of incompatible type for value " + so[pname]);
|
||||
|
@ -203,6 +234,17 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
UniFields.SetString(element.Fields, pname, (string)newvalue, string.Empty);
|
||||
else if (newvalue is bool)
|
||||
element.Fields[pname] = new UniValue(UniversalType.Boolean, (bool)newvalue);
|
||||
else if (newvalue is BigInteger nv)
|
||||
{
|
||||
// Manually check the range, so that we can show a more useful error
|
||||
if(nv > int.MaxValue)
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException($"Value {nv} for UDMF field \"{pname}\" is too big. Maximum value is {int.MaxValue}");
|
||||
|
||||
if (nv < int.MinValue)
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException($"Value {nv} for UDMF field \"{pname}\" is too small. Minimum value is {int.MinValue}");
|
||||
|
||||
UniFields.SetInteger(element.Fields, pname, (int)nv);
|
||||
}
|
||||
}
|
||||
|
||||
AfterFieldsUpdate();
|
||||
|
|
|
@ -38,6 +38,27 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
internal class MapWrapper
|
||||
{
|
||||
#region ================== Enums
|
||||
|
||||
/// <summary>
|
||||
/// How geometry should be merged when geometry is stitched.
|
||||
/// ```
|
||||
/// UDB.Map.stitchGeometry(UDB.Map.MergeometryMode.MERGE);
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <enum name="CLASSIC">Merge vertices only</enum>
|
||||
/// <enum name="MERGE">Merge vertices and lines</enum>
|
||||
/// <enum name="REPLACE">Merge vertices and lines, replacing sector geometry</enum>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public enum MergeGeometryMode
|
||||
{
|
||||
CLASSIC = Map.MergeGeometryMode.CLASSIC,
|
||||
MERGE = Map.MergeGeometryMode.MERGE,
|
||||
REPLACE = Map.MergeGeometryMode.REPLACE
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
private MapSet map;
|
||||
|
@ -135,7 +156,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
return new Vector2DWrapper(General.Map.Grid.SnappedToGrid((Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false)));
|
||||
return new Vector2DWrapper(General.Map.Grid.SnappedToGrid(BuilderPlug.Me.GetVector3DFromObject(pos)));
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -221,11 +242,18 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// <summary>
|
||||
/// Stitches marked geometry with non-marked geometry.
|
||||
/// </summary>
|
||||
/// <param name="mergemode">Mode to merge by</param>
|
||||
/// <param name="mergemode">Mode to merge by as `MergeGeometryMode`</param>
|
||||
/// <returns>`true` if successful, `false` if failed</returns>
|
||||
public bool stitchGeometry(MergeGeometryMode mergemode = MergeGeometryMode.CLASSIC)
|
||||
{
|
||||
return General.Map.Map.StitchGeometry(mergemode);
|
||||
if(mergemode == MergeGeometryMode.CLASSIC)
|
||||
return General.Map.Map.StitchGeometry(Map.MergeGeometryMode.CLASSIC);
|
||||
else if(mergemode == MergeGeometryMode.MERGE)
|
||||
return General.Map.Map.StitchGeometry(Map.MergeGeometryMode.MERGE);
|
||||
else if(mergemode == MergeGeometryMode.REPLACE)
|
||||
return General.Map.Map.StitchGeometry(Map.MergeGeometryMode.REPLACE);
|
||||
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Unknown MergeGeometryMode value");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -270,7 +298,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
Linedef nearest = null;
|
||||
|
||||
if (double.IsNaN(maxrange))
|
||||
|
@ -299,7 +327,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
Thing nearest = null;
|
||||
|
||||
if (double.IsNaN(maxrange))
|
||||
|
@ -328,7 +356,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
Vertex nearest = null;
|
||||
|
||||
if (double.IsNaN(maxrange))
|
||||
|
@ -357,7 +385,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
Sidedef nearest = MapSet.NearestSidedef(General.Map.Map.Sidedefs, v);
|
||||
|
||||
if (nearest == null)
|
||||
|
@ -404,7 +432,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(item, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(item);
|
||||
DrawnVertex dv = new DrawnVertex();
|
||||
dv.pos = v;
|
||||
dv.stitch = dv.stitchline = true;
|
||||
|
@ -1064,7 +1092,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
Vertex newvertex = General.Map.Map.CreateVertex(v);
|
||||
|
||||
if(newvertex == null)
|
||||
|
@ -1097,7 +1125,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
if(type < 0)
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException("Thing type can not be negative.");
|
||||
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(pos, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
Thing t = General.Map.Map.CreateThing();
|
||||
|
||||
if(t == null)
|
||||
|
@ -1105,10 +1133,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
General.Settings.ApplyCleanThingSettings(t, type);
|
||||
|
||||
if(v is Vector2D)
|
||||
t.Move((Vector2D)v);
|
||||
else if(v is Vector3D)
|
||||
t.Move((Vector3D)v);
|
||||
t.Move(v);
|
||||
|
||||
t.UpdateConfiguration();
|
||||
|
||||
|
|
285
Source/Plugins/UDBScript/API/PlaneWrapper.cs
Normal file
285
Source/Plugins/UDBScript/API/PlaneWrapper.cs
Normal file
|
@ -0,0 +1,285 @@
|
|||
#region ================== Copyright (c) 2022 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.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
||||
{
|
||||
class PlaneWrapper
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private Plane plane;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
/// <summary>
|
||||
/// The plane's normal vector.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public Vector3D normal
|
||||
{
|
||||
get
|
||||
{
|
||||
return plane.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The distance of the plane along the normal vector.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public double offset
|
||||
{
|
||||
get
|
||||
{
|
||||
return plane.Offset;
|
||||
}
|
||||
set
|
||||
{
|
||||
plane.Offset = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The `a` value of the plane equation. This is the `x` value of the normal vector.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public double a
|
||||
{
|
||||
get
|
||||
{
|
||||
return plane.Normal.x;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The `b` value of the plane equation. This is the `y` value of the normal vector.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public double b
|
||||
{
|
||||
get
|
||||
{
|
||||
return plane.Normal.y;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The `c` value of the plane equation. This is the `z` value of the normal vector.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public double c
|
||||
{
|
||||
get
|
||||
{
|
||||
return plane.Normal.z;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The `d` value of the plane equation. This is the same as the `offset` value.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public double d
|
||||
{
|
||||
get
|
||||
{
|
||||
return plane.Offset;
|
||||
}
|
||||
set
|
||||
{
|
||||
plane.Offset = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new `Plane` from a normal and an offset. The normal vector has to be `Vector3D`, `Array`s of 3 numbers, or an object with x, y, and z properties.
|
||||
/// ```
|
||||
/// let plane1 = new UDB.Plane(new Vector3D(0.0, -0.707, 0.707), 32);
|
||||
/// let plane2 = new UDB.Plane([ 0.0, -0.707, 0.707 ], 32);
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="normal">Normal vector of the plane</param>
|
||||
/// <param name="offset">Distance of the plane from the origin</param>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public PlaneWrapper(object normal, double offset)
|
||||
{
|
||||
plane = new Plane(BuilderPlug.Me.GetVector3DFromObject(normal), offset);
|
||||
}
|
||||
|
||||
private object bla()
|
||||
{
|
||||
return new Vector2D(1, 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new `Plane` from 3 points. The points have to be `Vector3D`, `Array`s of 3 numbers, or an object with x, y, and z properties.
|
||||
/// ```
|
||||
/// let plane1 = new UDB.Plane(new Vector3D(0, 0, 0), new Vector3D(64, 0, 0), new Vector3D(64, 64, 32), true);
|
||||
/// let plane2 = new UDB.Plane([ 0, 0, 0 ], [ 64, 0, 0 ], [ 64, 64, 32 ], true);
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="p1">First point</param>
|
||||
/// <param name="p2">Second point</param>
|
||||
/// <param name="p3">Thrid point</param>
|
||||
/// <param name="up">`true` if plane is pointing up, `false` if pointing down</param>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public PlaneWrapper(object p1, object p2, object p3, bool up)
|
||||
{
|
||||
//Vector2D a2 = new Vector2D(1, 2);
|
||||
Vector3D a3 = (Vector2D)bla();
|
||||
try
|
||||
{
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(p1);
|
||||
Vector3D v2 = BuilderPlug.Me.GetVector3DFromObject(p2);
|
||||
Vector3D v3 = BuilderPlug.Me.GetVector3DFromObject(p3);
|
||||
|
||||
plane = new Plane(v1, v2, v3, up);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the line between `from` and `to` intersects the plane.
|
||||
///
|
||||
/// It returns an `Array`, where the first element is a `bool` vaue indicating if there is an intersector, and the second element is the position of the intersection on the line between the two points.
|
||||
///
|
||||
/// ```
|
||||
/// const plane = new UDB.Plane([ 0, 0, 1 ], 0);
|
||||
/// const [intersecting, u] = plane.getIntersection([0, 0, 32], [0, 0, -32]);
|
||||
/// UDB.log(`${intersecting} / ${u}`); // Prints "true / 0.5"
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="from">`Vector3D` of the start of the line</param>
|
||||
/// <param name="to">`Vector3D` of the end of the line</param>
|
||||
/// <returns></returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public object[] getIntersection(object from, object to)
|
||||
{
|
||||
Vector3D f = BuilderPlug.Me.GetVector3DFromObject(from);
|
||||
Vector3D t = BuilderPlug.Me.GetVector3DFromObject(to);
|
||||
|
||||
double u_ray = double.NaN;
|
||||
|
||||
bool r = plane.GetIntersection(f, t, ref u_ray);
|
||||
|
||||
return new object[] { r, u_ray };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the distance between the `Plane` and a point. The given point can be a `Vector3D` or an `Array` of three numbers. A result greater than 0 means the point is on the front of the plane, less than 0 means the point is behind the plane.
|
||||
/// ```
|
||||
/// const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true);
|
||||
/// UDB.log(plane.distance([ 16, 16, 32 ])); // Prints '21.466252583998'
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="p">Point to compute the distnace to</param>
|
||||
/// <returns>Distance between the `Plane` and the point as `number`</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public double distance(object p)
|
||||
{
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return plane.Distance(v);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the point that's closest to the given point on the `Plane`. The given point can be a `Vector3D` or an `Array` of three numbers.
|
||||
/// ```
|
||||
/// const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true);
|
||||
/// UDB.log(plane.closestOnPlane([ 16, 16, 32 ])); // Prints '16, 25.6, 12.8'
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="p">Point to get the closest position from</param>
|
||||
/// <returns>Point as `Vector3D` on the plane closest to the given point</returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public Vector3DWrapper closestOnPlane(object p)
|
||||
{
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return new Vector3DWrapper(plane.ClosestOnPlane(v));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the position on the z axis of the plane for the given point. The given point can be a `Vector2D` or an `Array` of two numbers.
|
||||
/// ```
|
||||
/// const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true);
|
||||
/// UDB.log(plane.getZ([ 16, 16 ])); // Prints '8'
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <param name="p">Point to get the z position from</param>
|
||||
/// <returns></returns>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public double getZ(object p)
|
||||
{
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return plane.GetZ(v);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is PlaneWrapper other)) return false;
|
||||
|
||||
return plane.Equals(other.plane);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return plane.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Statics
|
||||
|
||||
public static bool operator ==(PlaneWrapper a, PlaneWrapper b) => a.plane == b.plane;
|
||||
|
||||
public static bool operator !=(PlaneWrapper a, PlaneWrapper b) => a.plane != b.plane;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using CodeImp.DoomBuilder.BuilderModes;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
|
@ -568,7 +569,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(p, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(p);
|
||||
|
||||
return sector.Intersect(v);
|
||||
}
|
||||
|
@ -709,7 +710,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
sector.FloorSlope = (Vector3D)BuilderPlug.Me.GetVectorFromObject(normal, true);
|
||||
sector.FloorSlope = BuilderPlug.Me.GetVector3DFromObject(normal);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -740,7 +741,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
sector.CeilSlope = (Vector3D)BuilderPlug.Me.GetVectorFromObject(normal, true);
|
||||
sector.CeilSlope = BuilderPlug.Me.GetVector3DFromObject(normal);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -748,6 +749,26 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an `Array` of `Vector2D` of label positions for the `Sector`. This are the positions where for example selection number or tags are shown.
|
||||
///
|
||||
/// This example adds an imp to the label position of each sector in the map:
|
||||
/// ```
|
||||
/// UDB.Map.getSectors().forEach(s => {
|
||||
/// const positions = s.getLabelPositions();
|
||||
/// if(positions.length > 0)
|
||||
/// UDB.Map.createThing(positions[0], 3001);
|
||||
/// });
|
||||
/// ```
|
||||
/// </summary>
|
||||
/// <returns>`Array` of `Vector2D` of all label positions</returns>
|
||||
/// <version>5</version>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public Vector2DWrapper[] getLabelPositions()
|
||||
{
|
||||
return Tools.FindLabelPositions(sector).Select(lpi => new Vector2DWrapper(lpi.position)).ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Interface implementations
|
||||
|
|
|
@ -146,6 +146,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// <summary>
|
||||
/// `Array` of arguments of the `Thing`. Number of arguments depends on game config (usually 5). Hexen format and UDMF only.
|
||||
/// </summary>
|
||||
/// <fakedtstype>number[]</fakedtstype>
|
||||
public MapElementArgumentsWrapper args
|
||||
{
|
||||
get
|
||||
|
@ -319,12 +320,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(value, true);
|
||||
|
||||
if (v is Vector2D)
|
||||
thing.Move((Vector2D)v);
|
||||
else
|
||||
thing.Move((Vector3D)v);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(value);
|
||||
thing.Move(v);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -465,7 +462,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return thing.DistanceToSq(v);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -490,7 +487,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return thing.DistanceTo(v);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
|
|
@ -45,8 +45,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
private TypeReference queryoptions;
|
||||
private ExpandoObject scriptoptions;
|
||||
|
||||
private TypeReference angle2d;
|
||||
private TypeReference data;
|
||||
private Angle2DWrapper angle2d;
|
||||
private DataWrapper data;
|
||||
private TypeReference line2d;
|
||||
private MapWrapper map;
|
||||
private TypeReference univalue;
|
||||
|
@ -59,6 +59,10 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
private TypeReference thing;
|
||||
private TypeReference vertex;
|
||||
|
||||
// Version 5
|
||||
private TypeReference plane;
|
||||
private TypeReference blockmap;
|
||||
|
||||
private IProgress<int> progress;
|
||||
private IProgress<string> status;
|
||||
private IProgress<string> logger;
|
||||
|
@ -106,7 +110,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// let rad = UDB.Angle2D.degToRad(46);
|
||||
/// ```
|
||||
/// </summary>
|
||||
public TypeReference Angle2D
|
||||
public Angle2DWrapper Angle2D
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -120,7 +124,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
/// let hasfireblu = UDB.Data.textureExists('FIREBLU1');
|
||||
/// ```
|
||||
/// </summary>
|
||||
public TypeReference Data
|
||||
public DataWrapper Data
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -186,10 +190,10 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
/// <summary>
|
||||
/// Instantiable class that contains methods related to three-dimensional vectors. See [Vector3D](Vector3D.md) for more information.
|
||||
/// </summary>
|
||||
/// ```js
|
||||
/// let v = new UDB.Vector3D(32, 64, 128);
|
||||
/// ```
|
||||
/// </summary>
|
||||
public TypeReference Vector3D
|
||||
{
|
||||
get
|
||||
|
@ -204,6 +208,30 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
public TypeReference Thing { get { return thing; } }
|
||||
public TypeReference Vertex { get { return vertex; } }
|
||||
|
||||
/// <summary>
|
||||
/// Instantiable class that contains methods related to a three-dimensional Plane. See [Plane](Plane.md) for more information.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public TypeReference Plane
|
||||
{
|
||||
get
|
||||
{
|
||||
return plane;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiable class that contains methods related to blockmaps. See [BlockMap][BlockMap.md) for more information.
|
||||
/// </summary>
|
||||
[UDBScriptSettings(MinVersion = 5)]
|
||||
public TypeReference BlockMap
|
||||
{
|
||||
get
|
||||
{
|
||||
return blockmap;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructors
|
||||
|
@ -214,8 +242,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
queryoptions = TypeReference.CreateTypeReference(engine, typeof(QueryOptions));
|
||||
scriptoptions = scriptinfo.GetScriptOptionsObject();
|
||||
|
||||
angle2d = TypeReference.CreateTypeReference(engine, typeof(Angle2DWrapper));
|
||||
data = TypeReference.CreateTypeReference(engine, typeof(DataWrapper));
|
||||
angle2d = new Angle2DWrapper();
|
||||
data = new DataWrapper();
|
||||
line2d = TypeReference.CreateTypeReference(engine, typeof(Line2DWrapper));
|
||||
map = new MapWrapper();
|
||||
univalue = TypeReference.CreateTypeReference(engine, typeof(CodeImp.DoomBuilder.Map.UniValue));
|
||||
|
@ -230,6 +258,10 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
thing = TypeReference.CreateTypeReference(engine, typeof(ThingWrapper));
|
||||
vertex = TypeReference.CreateTypeReference(engine, typeof(VertexWrapper));
|
||||
|
||||
// Version 5
|
||||
plane = TypeReference.CreateTypeReference(engine, typeof(PlaneWrapper));
|
||||
blockmap = TypeReference.CreateTypeReference(engine, typeof(BlockMapWrapper));
|
||||
|
||||
this.progress = progress;
|
||||
this.status = status;
|
||||
this.logger = logger;
|
||||
|
|
|
@ -127,7 +127,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(v);
|
||||
|
||||
_x = v1.x;
|
||||
_y = v1.y;
|
||||
|
@ -169,12 +169,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(lhs._x + ((Vector2D)v).x, lhs._y + ((Vector2D)v).y);
|
||||
else
|
||||
return new Vector2DWrapper(lhs._x + ((Vector3D)v).x, lhs._y + ((Vector3D)v).y);
|
||||
return new Vector2DWrapper(lhs._x + v.x, lhs._y + v.y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -197,12 +194,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(((Vector2D)v).x + rhs._x, ((Vector2D)v).y + rhs._y);
|
||||
else
|
||||
return new Vector2DWrapper(((Vector3D)v).x + rhs._x, ((Vector3D)v).y + rhs._y);
|
||||
return new Vector2DWrapper(v.x + rhs._x, v.y + rhs._y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -226,12 +220,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(lhs._x - ((Vector2D)v).x, lhs._y - ((Vector2D)v).y);
|
||||
else
|
||||
return new Vector2DWrapper(lhs._x - ((Vector3D)v).x, lhs._y - ((Vector3D)v).y);
|
||||
return new Vector2DWrapper(lhs._x - v.x, lhs._y - v.y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -246,12 +237,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(((Vector2D)v).x - rhs._x, ((Vector2D)v).y - rhs._y);
|
||||
else
|
||||
return new Vector2DWrapper(((Vector3D)v).x - rhs._x, ((Vector3D)v).y - rhs._y);
|
||||
return new Vector2DWrapper(v.x - rhs._x, v.y - rhs._y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -275,12 +263,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(lhs._x * ((Vector2D)v).x, lhs._y * ((Vector2D)v).y);
|
||||
else
|
||||
return new Vector2DWrapper(lhs._x * ((Vector3D)v).x, lhs._y * ((Vector3D)v).y);
|
||||
return new Vector2DWrapper(lhs._x * v.x, lhs._y * v.y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -295,12 +280,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(((Vector2D)v).x * rhs._x, ((Vector2D)v).y * rhs._y);
|
||||
else
|
||||
return new Vector2DWrapper(((Vector3D)v).x * rhs._x, ((Vector3D)v).y * rhs._y);
|
||||
return new Vector2DWrapper(v.x * rhs._x, v.y * rhs._y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -319,12 +301,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(lhs._x / ((Vector2D)v).x, lhs._y / ((Vector2D)v).y);
|
||||
else
|
||||
return new Vector2DWrapper(lhs._x / ((Vector3D)v).x, lhs._y / ((Vector3D)v).y);
|
||||
return new Vector2DWrapper(lhs._x / v.x, lhs._y / v.y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -339,12 +318,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector2DWrapper(((Vector2D)v).x / rhs._x, ((Vector2D)v).y / rhs._y);
|
||||
else
|
||||
return new Vector2DWrapper(((Vector3D)v).x / rhs._x, ((Vector3D)v).y / rhs._y);
|
||||
return new Vector2DWrapper(v.x / rhs._x, v.y / rhs._y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -360,7 +336,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(rhs, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
return (lhs._x == v1.x) && (lhs._y == v1.y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -373,7 +349,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(lhs, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
return (v1.x == rhs._x) && (v1.y == rhs._y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -386,7 +362,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(rhs, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
return (lhs._x != v1.x) || (lhs._y != v1.y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -399,7 +375,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(lhs, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
return (v1.x != rhs._x) || (v1.y != rhs._y);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -436,8 +412,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D a1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a, false);
|
||||
Vector2D b1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b, false);
|
||||
Vector2D a1 = BuilderPlug.Me.GetVector3DFromObject(a);
|
||||
Vector2D b1 = BuilderPlug.Me.GetVector3DFromObject(b);
|
||||
|
||||
return new Vector2DWrapper(a1.y * b1.x, a1.x * b1.y);
|
||||
}
|
||||
|
@ -457,8 +433,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v, false);
|
||||
Vector2D m1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(m, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(v);
|
||||
Vector2D m1 = BuilderPlug.Me.GetVector3DFromObject(m);
|
||||
|
||||
Vector2D mv = Vector2D.Reflect(v1, m1);
|
||||
|
||||
|
@ -479,7 +455,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D v1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(v, false);
|
||||
Vector2D v1 = BuilderPlug.Me.GetVector3DFromObject(v);
|
||||
|
||||
return new Vector2DWrapper(Vector2D.Reversed(v1));
|
||||
}
|
||||
|
@ -519,8 +495,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D a1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a, false);
|
||||
Vector2D b1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b, false);
|
||||
Vector2D a1 = BuilderPlug.Me.GetVector3DFromObject(a);
|
||||
Vector2D b1 = BuilderPlug.Me.GetVector3DFromObject(b);
|
||||
|
||||
return Vector2D.GetAngle(a1, b1);
|
||||
}
|
||||
|
@ -540,8 +516,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D a1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a, false);
|
||||
Vector2D b1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b, false);
|
||||
Vector2D a1 = BuilderPlug.Me.GetVector3DFromObject(a);
|
||||
Vector2D b1 = BuilderPlug.Me.GetVector3DFromObject(b);
|
||||
|
||||
return Angle2D.RadToDeg(Vector2D.GetAngle(a1, b1));
|
||||
}
|
||||
|
@ -561,8 +537,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D a1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a, false);
|
||||
Vector2D b1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b, false);
|
||||
Vector2D a1 = BuilderPlug.Me.GetVector3DFromObject(a);
|
||||
Vector2D b1 = BuilderPlug.Me.GetVector3DFromObject(b);
|
||||
|
||||
return Vector2D.DistanceSq(a1, b1);
|
||||
}
|
||||
|
@ -582,8 +558,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector2D a1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(a, false);
|
||||
Vector2D b1 = (Vector2D)BuilderPlug.Me.GetVectorFromObject(b, false);
|
||||
Vector2D a1 = BuilderPlug.Me.GetVector3DFromObject(a);
|
||||
Vector2D b1 = BuilderPlug.Me.GetVector3DFromObject(b);
|
||||
|
||||
return Vector2D.Distance(a1, b1);
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D v1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(v, true);
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(v);
|
||||
|
||||
_x = v1.x;
|
||||
_y = v1.y;
|
||||
|
@ -187,12 +187,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if(v is Vector2D)
|
||||
return new Vector3DWrapper(lhs._x + ((Vector2D)v).x, lhs._y + ((Vector2D)v).y, lhs._z);
|
||||
else
|
||||
return new Vector3DWrapper(lhs._x + ((Vector3D)v).x, lhs._y + ((Vector3D)v).y, lhs._z + ((Vector3D)v).z);
|
||||
return new Vector3DWrapper(lhs._x + v.x, lhs._y + v.y, lhs._z + v.z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -215,12 +212,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector3DWrapper(((Vector2D)v).x + rhs._x, ((Vector2D)v).y + rhs._y, rhs._z);
|
||||
else
|
||||
return new Vector3DWrapper(((Vector3D)v).x + rhs._x, ((Vector3D)v).y + rhs._y, ((Vector3D)v).z + rhs._z);
|
||||
return new Vector3DWrapper(v.x + rhs._x, v.y + rhs._y, v.z + rhs._z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -244,12 +238,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector3DWrapper(lhs._x - ((Vector2D)v).x, lhs._y - ((Vector2D)v).y, lhs._z);
|
||||
else
|
||||
return new Vector3DWrapper(lhs._x - ((Vector3D)v).x, lhs._y - ((Vector3D)v).y, lhs._z - ((Vector3D)v).z);
|
||||
return new Vector3DWrapper(lhs._x - v.x, lhs._y - v.y, lhs._z - v.z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -264,12 +255,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector3DWrapper(((Vector2D)v).x - rhs._x, ((Vector2D)v).y - rhs._y, -rhs._z);
|
||||
else
|
||||
return new Vector3DWrapper(((Vector3D)v).x - rhs._x, ((Vector3D)v).y - rhs._y, ((Vector3D)v).z - rhs._z);
|
||||
return new Vector3DWrapper(v.x - rhs._x, v.y - rhs._y, v.z - rhs._z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -288,12 +276,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector3DWrapper(lhs._x * ((Vector2D)v).x, lhs._y * ((Vector2D)v).y, 0);
|
||||
else
|
||||
return new Vector3DWrapper(lhs._x * ((Vector3D)v).x, lhs._y * ((Vector3D)v).y, lhs._z * ((Vector3D)v).z);
|
||||
return new Vector3DWrapper(lhs._x * v.x, lhs._y * v.y, lhs._z * v.z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -308,12 +293,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector3DWrapper(((Vector2D)v).x * rhs._x, ((Vector2D)v).y * rhs._y, 0);
|
||||
else
|
||||
return new Vector3DWrapper(((Vector3D)v).x * rhs._x, ((Vector3D)v).y * rhs._y, ((Vector3D)v).z * rhs._z);
|
||||
return new Vector3DWrapper(v.x * rhs._x, v.y * rhs._y, v.z * rhs._z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -332,12 +314,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector3DWrapper(lhs._x / ((Vector2D)v).x, lhs._y / ((Vector2D)v).y, lhs._z / 0);
|
||||
else
|
||||
return new Vector3DWrapper(lhs._x / ((Vector3D)v).x, lhs._y / ((Vector3D)v).y, lhs._z / ((Vector3D)v).z);
|
||||
return new Vector3DWrapper(lhs._x / v.x, lhs._y / v.y, lhs._z / v.z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -352,12 +331,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
|
||||
if (v is Vector2D)
|
||||
return new Vector3DWrapper(((Vector2D)v).x / rhs._x, ((Vector2D)v).y / rhs._y, 0 / rhs._z);
|
||||
else
|
||||
return new Vector3DWrapper(((Vector3D)v).x / rhs._x, ((Vector3D)v).y / rhs._y, ((Vector3D)v).z / rhs._z);
|
||||
return new Vector3DWrapper(v.x / rhs._x, v.y / rhs._y, v.z / rhs._z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -373,7 +349,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D v1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
return (lhs._x == v1.x) && (lhs._y == v1.y) && (lhs._z == v1.z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -386,7 +362,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D v1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
return (v1.x == rhs._x) && (v1.y == rhs._y) && (v1.z == rhs._z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -399,7 +375,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D v1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(rhs, true);
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(rhs);
|
||||
return (lhs._x != v1.x) || (lhs._y != v1.y) || (lhs._z != v1.z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -412,7 +388,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D v1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(lhs, true);
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(lhs);
|
||||
return (v1.x != rhs._x) || (v1.y != rhs._y) || (v1.z != rhs._z);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -449,8 +425,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D a1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(a, true);
|
||||
Vector3D b1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(b, true);
|
||||
Vector3D a1 = BuilderPlug.Me.GetVector3DFromObject(a);
|
||||
Vector3D b1 = BuilderPlug.Me.GetVector3DFromObject(b);
|
||||
|
||||
return new Vector3DWrapper(
|
||||
a1.y * b1.z - a1.z * b1.y,
|
||||
|
@ -474,8 +450,8 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D v1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(v, true);
|
||||
Vector3D m1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(m, true);
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(v);
|
||||
Vector3D m1 = BuilderPlug.Me.GetVector3DFromObject(m);
|
||||
|
||||
return new Vector3DWrapper(Vector3D.Reflect(v1, m1));
|
||||
}
|
||||
|
@ -494,7 +470,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
{
|
||||
try
|
||||
{
|
||||
Vector3D v1 = (Vector3D)BuilderPlug.Me.GetVectorFromObject(v, true);
|
||||
Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(v);
|
||||
|
||||
return new Vector3DWrapper(Vector3D.Reversed(v1));
|
||||
}
|
||||
|
|
|
@ -109,12 +109,9 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
object v = BuilderPlug.Me.GetVectorFromObject(value, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(value);
|
||||
|
||||
if (v is Vector2D)
|
||||
vertex.Move((Vector2D)v);
|
||||
else
|
||||
vertex.Move((Vector3D)v);
|
||||
vertex.Move(v);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
{
|
||||
|
@ -280,7 +277,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return vertex.DistanceToSq(v);
|
||||
}
|
||||
catch(CantConvertToVectorException e)
|
||||
|
@ -306,7 +303,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return vertex.DistanceTo(v);
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
@ -327,7 +324,7 @@ namespace CodeImp.DoomBuilder.UDBScript.Wrapper
|
|||
|
||||
try
|
||||
{
|
||||
Vector2D v = (Vector2D)BuilderPlug.Me.GetVectorFromObject(pos, false);
|
||||
Vector2D v = BuilderPlug.Me.GetVector3DFromObject(pos);
|
||||
return new LinedefWrapper(vertex.NearestLinedef(v));
|
||||
}
|
||||
catch (CantConvertToVectorException e)
|
||||
|
|
|
@ -30,6 +30,7 @@ using System.Dynamic;
|
|||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
|
@ -72,7 +73,7 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
#region ================== Constants
|
||||
|
||||
private static readonly string SCRIPT_FOLDER = "udbscript";
|
||||
public static readonly uint UDB_SCRIPT_VERSION = 4;
|
||||
public static readonly uint UDB_SCRIPT_VERSION = 5;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -465,41 +466,44 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
panel.EndEdit();
|
||||
}
|
||||
|
||||
internal object GetVectorFromObject(object data, bool allow3d)
|
||||
internal Vector3D GetVector3DFromObject(object data)
|
||||
{
|
||||
if (data is Vector2D)
|
||||
return (Vector2D)data;
|
||||
else if (data is Vector2DWrapper)
|
||||
return new Vector2D(((Vector2DWrapper)data)._x, ((Vector2DWrapper)data)._y);
|
||||
else if (data is Vector3D)
|
||||
return (Vector3D)data;
|
||||
else if (data is Vector3DWrapper)
|
||||
{
|
||||
if(allow3d)
|
||||
return new Vector3D(((Vector3DWrapper)data)._x, ((Vector3DWrapper)data)._y, ((Vector3DWrapper)data)._z);
|
||||
else
|
||||
return new Vector2D(((Vector3DWrapper)data)._x, ((Vector3DWrapper)data)._y);
|
||||
}
|
||||
return new Vector3D(((Vector3DWrapper)data)._x, ((Vector3DWrapper)data)._y, ((Vector3DWrapper)data)._z);
|
||||
else if (data.GetType().IsArray)
|
||||
//else if(data is double[])
|
||||
{
|
||||
object[] vals = (object[])data;
|
||||
//double[] vals = (double[])data;
|
||||
object[] rawvals = (object[])data;
|
||||
List<double> vals = new List<double>(rawvals.Length);
|
||||
|
||||
// Make sure all values in the array are doubles
|
||||
foreach (object v in vals)
|
||||
if (!(v is double))
|
||||
// Make sure all values in the array are doubles or BigIntegers
|
||||
foreach (object rv in rawvals)
|
||||
{
|
||||
if (!(rv is double || rv is BigInteger))
|
||||
throw new CantConvertToVectorException("Values in array must be numbers.");
|
||||
|
||||
if (vals.Length == 2)
|
||||
return new Vector2D((double)vals[0], (double)vals[1]);
|
||||
if (vals.Length == 3)
|
||||
return new Vector3D((double)vals[0], (double)vals[1], (double)vals[2]);
|
||||
if (rv is double d)
|
||||
vals.Add(d);
|
||||
else if(rv is BigInteger bi)
|
||||
vals.Add((double)bi);
|
||||
}
|
||||
|
||||
if (vals.Count == 2)
|
||||
return new Vector2D(vals[0], vals[1]);
|
||||
if (vals.Count == 3)
|
||||
return new Vector3D(vals[0], vals[1], vals[2]);
|
||||
}
|
||||
else if (data is ExpandoObject)
|
||||
{
|
||||
IDictionary<string, object> eo = data as IDictionary<string, object>;
|
||||
double x = double.NaN;
|
||||
double y = double.NaN;
|
||||
double z = double.NaN;
|
||||
double z = 0.0;
|
||||
|
||||
if (eo.ContainsKey("x"))
|
||||
{
|
||||
|
@ -537,24 +541,11 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
}
|
||||
}
|
||||
|
||||
if (allow3d)
|
||||
{
|
||||
if (!double.IsNaN(x) && !double.IsNaN(y) && double.IsNaN(z))
|
||||
return new Vector2D(x, y);
|
||||
else if (!double.IsNaN(x) && !double.IsNaN(y) && !double.IsNaN(z))
|
||||
return new Vector3D(x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x != double.NaN && y != double.NaN)
|
||||
return new Vector2D(x, y);
|
||||
}
|
||||
if (!double.IsNaN(x) && !double.IsNaN(y) && !double.IsNaN(z))
|
||||
return new Vector3D(x, y, z);
|
||||
}
|
||||
|
||||
if (allow3d)
|
||||
throw new CantConvertToVectorException("Data must be a Vector2D, Vector3D, or an array of numbers.");
|
||||
else
|
||||
throw new CantConvertToVectorException("Data must be a Vector2D, or an array of numbers.");
|
||||
throw new CantConvertToVectorException("Data must be a Vector2D, Vector3D, an array of numbers, or an object with (x, y, z) members.");
|
||||
}
|
||||
|
||||
internal object GetConvertedUniValue(UniValue uv)
|
||||
|
|
Binary file not shown.
|
@ -76,4 +76,16 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ScriptRuntimeException : Exception
|
||||
{
|
||||
public ScriptRuntimeException()
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptRuntimeException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -37,7 +37,7 @@ using Jint;
|
|||
|
||||
namespace CodeImp.DoomBuilder.UDBScript
|
||||
{
|
||||
class RuntimeConstraint : IConstraint
|
||||
class RuntimeConstraint : Constraint
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
@ -62,14 +62,14 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
public void Reset()
|
||||
public override void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks how long the script has been running and asks the user if it should abort or keep running
|
||||
/// </summary>
|
||||
public void Check()
|
||||
public override void Check()
|
||||
{
|
||||
if(stopwatch.ElapsedMilliseconds > CHECK_MILLISECONDS)
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
@ -35,6 +36,7 @@ using Jint;
|
|||
using Jint.Runtime;
|
||||
using Jint.Runtime.Interop;
|
||||
using Esprima;
|
||||
using Jint.Native;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -147,9 +149,9 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
throw new DieScriptException(s);
|
||||
}
|
||||
|
||||
public JavaScriptException CreateRuntimeException(string message)
|
||||
public ScriptRuntimeException CreateRuntimeException(string message)
|
||||
{
|
||||
return new JavaScriptException(engine.Realm.Intrinsics.Error, message);
|
||||
return new ScriptRuntimeException(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -169,8 +171,7 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
{
|
||||
try
|
||||
{
|
||||
ParserOptions po = new ParserOptions(file.Remove(0, General.AppPath.Length));
|
||||
engine.Execute(File.ReadAllText(file), po);
|
||||
engine.Execute(File.ReadAllText(file), file.Remove(0, General.AppPath.Length));
|
||||
}
|
||||
catch (ParserException e)
|
||||
{
|
||||
|
@ -182,7 +183,7 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
{
|
||||
if (e.Error.Type != Jint.Runtime.Types.String)
|
||||
{
|
||||
UDBScriptErrorForm sef = new UDBScriptErrorForm(e.Message, e.StackTrace);
|
||||
UDBScriptErrorForm sef = new UDBScriptErrorForm(e.Message, e.JavaScriptStackTrace, e.StackTrace);
|
||||
sef.ShowDialog();
|
||||
}
|
||||
else
|
||||
|
@ -213,15 +214,15 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
MessageBox.Show("There is an error while parsing the script:\n\n" + e.Message, "Script error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
abort = true;
|
||||
}
|
||||
else if(e is JavaScriptException)
|
||||
else if(e is JavaScriptException jse)
|
||||
{
|
||||
if (((JavaScriptException)e).Error.Type != Jint.Runtime.Types.String)
|
||||
if (jse.Error.Type != Jint.Runtime.Types.String)
|
||||
{
|
||||
UDBScriptErrorForm sef = new UDBScriptErrorForm(e.Message, e.StackTrace);
|
||||
UDBScriptErrorForm sef = new UDBScriptErrorForm(jse.Message, jse.JavaScriptStackTrace, jse.StackTrace);
|
||||
sef.ShowDialog();
|
||||
}
|
||||
else
|
||||
General.Interface.DisplayStatus(StatusType.Warning, e.Message); // We get here if "throw" is used in a script
|
||||
General.Interface.DisplayStatus(StatusType.Warning, jse.Message); // We get here if "throw" is used in a script
|
||||
|
||||
abort = true;
|
||||
}
|
||||
|
@ -243,7 +244,7 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
}
|
||||
else // Catch anything else we didn't think about
|
||||
{
|
||||
UDBScriptErrorForm sef = new UDBScriptErrorForm(e.Message, e.StackTrace);
|
||||
UDBScriptErrorForm sef = new UDBScriptErrorForm(e.Message, string.Empty, e.StackTrace);
|
||||
sef.ShowDialog();
|
||||
|
||||
abort = true;
|
||||
|
@ -253,6 +254,44 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
General.Map.UndoRedo.WithdrawUndo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes sure that only properties for the currect feature version are available to scripts.
|
||||
/// </summary>
|
||||
/// <param name="info">MemberInfo about the property that's being accessed</param>
|
||||
/// <returns>true if property can be accessed, false otherwise</returns>
|
||||
private bool MemberFilter(MemberInfo info)
|
||||
{
|
||||
if (info.Name == nameof(GetType))
|
||||
return false;
|
||||
|
||||
if (info.GetCustomAttribute(typeof(UDBScriptSettingsAttribute)) is UDBScriptSettingsAttribute sa)
|
||||
return sa.MinVersion <= scriptinfo.Version;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
private JsValue GetObjectMember(Engine engine, object target, string memberName)
|
||||
{
|
||||
Type t = target.GetType();
|
||||
MethodInfo mi = t.GetMethod(memberName);
|
||||
if (mi != null)
|
||||
{
|
||||
var attr = mi.GetCustomAttribute<UDBScriptSettingsAttribute>(false);
|
||||
if (attr != null && scriptinfo.Version < attr.MinVersion)
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException($"{t.Name} requires UDBScript version {attr.MinVersion} or higher.");
|
||||
|
||||
}
|
||||
if (t.GetCustomAttribute(typeof(UDBScriptSettingsAttribute)) is UDBScriptSettingsAttribute sa)
|
||||
{
|
||||
if (scriptinfo.Version < sa.MinVersion)
|
||||
throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException($"{t.Name} requires UDBScript version {sa.MinVersion} or higher.");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Sets everything up for running the script. This has to be done on the UI thread.
|
||||
/// </summary>
|
||||
|
@ -279,11 +318,28 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
Options options = new Options();
|
||||
options.CancellationToken(cancellationtoken);
|
||||
options.AllowOperatorOverloading();
|
||||
|
||||
options.SetTypeResolver(new TypeResolver
|
||||
{
|
||||
MemberFilter = member => member.Name != nameof(GetType)
|
||||
MemberFilter = MemberFilter// member => member.Name != nameof(GetType)
|
||||
});
|
||||
|
||||
//options.SetMemberAccessor(GetObjectMember);
|
||||
|
||||
/*
|
||||
options.SetWrapObjectHandler((eng, obj) =>
|
||||
{
|
||||
var wrapper = new ObjectWrapper(eng, obj);
|
||||
if (wrapper.IsArrayLike || obj is BlockMapQueryResult)
|
||||
{
|
||||
wrapper.SetPrototypeOf(eng.Realm.Intrinsics.Array.PrototypeObject);
|
||||
}
|
||||
return wrapper;
|
||||
});
|
||||
*/
|
||||
|
||||
options.CatchClrExceptions(e => e is ScriptRuntimeException || e is CantConvertToVectorException);
|
||||
|
||||
// Create the script engine
|
||||
engine = new Engine(options);
|
||||
|
||||
|
@ -352,10 +408,9 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
string script = File.ReadAllText(scriptinfo.ScriptFile);
|
||||
|
||||
// Run the script file
|
||||
ParserOptions po = new ParserOptions(scriptinfo.ScriptFile.Remove(0, General.AppPath.Length));
|
||||
|
||||
stopwatch.Reset();
|
||||
stopwatch.Start();
|
||||
engine.Execute(script, po);
|
||||
engine.Execute(script, scriptinfo.ScriptFile.Remove(0, General.AppPath.Length));
|
||||
stopwatch.Stop();
|
||||
}
|
||||
|
||||
|
@ -379,6 +434,11 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
General.Interface.EnableProcessing();
|
||||
}
|
||||
|
||||
public string GetRuntimeString()
|
||||
{
|
||||
return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D}", stopwatch.Elapsed.Hours, stopwatch.Elapsed.Minutes, stopwatch.Elapsed.Seconds, stopwatch.Elapsed.Milliseconds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>..\..\..\Build\Plugins\</OutputPath>
|
||||
|
@ -65,6 +67,10 @@
|
|||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
|
@ -75,12 +81,18 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="API\Angle2DWrapper.cs" />
|
||||
<Compile Include="API\BlockEntryWrapper.cs" />
|
||||
<Compile Include="API\BlockMapContentBase.cs" />
|
||||
<Compile Include="API\BlockMapQueryResult.cs" />
|
||||
<Compile Include="API\BlockMapWrapper.cs" />
|
||||
<Compile Include="API\DataWrapper.cs" />
|
||||
<Compile Include="API\GameConfigurationWrapper.cs" />
|
||||
<Compile Include="API\ImageInfo.cs" />
|
||||
<Compile Include="API\PlaneWrapper.cs" />
|
||||
<Compile Include="API\UDBWrapper.cs" />
|
||||
<Compile Include="API\Vector3DWrapper.cs" />
|
||||
<Compile Include="API\VisualCameraWrapper.cs" />
|
||||
<Compile Include="UDBScriptSettingsAttribute.cs" />
|
||||
<Compile Include="BuilderPlug.cs" />
|
||||
<Compile Include="Controls\ScriptDockerControl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
|
|
48
Source/Plugins/UDBScript/UDBScriptSettingsAttribute.cs
Normal file
48
Source/Plugins/UDBScript/UDBScriptSettingsAttribute.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
#region ================== Copyright (c) 2022 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;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.UDBScript
|
||||
{
|
||||
sealed internal class UDBScriptSettingsAttribute : Attribute
|
||||
{
|
||||
#region ================== Properties
|
||||
|
||||
public int MinVersion { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructors
|
||||
|
||||
public UDBScriptSettingsAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -205,9 +205,13 @@ namespace CodeImp.DoomBuilder.UDBScript
|
|||
|
||||
running = false;
|
||||
|
||||
Text = "Script finished";
|
||||
lbStatus.Text = "Script finished. Runtime: " + BuilderPlug.Me.ScriptRunner.GetRuntimeString();
|
||||
btnAction.Text = "Close";
|
||||
btnAction.Enabled = true;
|
||||
|
||||
SetProgress(0);
|
||||
|
||||
// Stop the progress bar from animating when the script finished
|
||||
if (progressbar.Style == ProgressBarStyle.Marquee)
|
||||
progressbar.Style = ProgressBarStyle.Continuous;
|
||||
|
|
|
@ -28,24 +28,18 @@
|
|||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tbStackTrace = new System.Windows.Forms.TextBox();
|
||||
this.btnOK = new System.Windows.Forms.Button();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||
this.tbStackTrace = new System.Windows.Forms.TextBox();
|
||||
this.tbInternalStackTrace = new System.Windows.Forms.TextBox();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.tabPage2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tbStackTrace
|
||||
//
|
||||
this.tbStackTrace.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tbStackTrace.Location = new System.Drawing.Point(6, 37);
|
||||
this.tbStackTrace.Multiline = true;
|
||||
this.tbStackTrace.Name = "tbStackTrace";
|
||||
this.tbStackTrace.ReadOnly = true;
|
||||
this.tbStackTrace.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.tbStackTrace.Size = new System.Drawing.Size(516, 183);
|
||||
this.tbStackTrace.TabIndex = 0;
|
||||
//
|
||||
// btnOK
|
||||
//
|
||||
this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
|
@ -66,6 +60,63 @@
|
|||
this.label1.TabIndex = 2;
|
||||
this.label1.Text = "There was an error while executing the script:";
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tabControl1.Controls.Add(this.tabPage1);
|
||||
this.tabControl1.Controls.Add(this.tabPage2);
|
||||
this.tabControl1.Location = new System.Drawing.Point(6, 38);
|
||||
this.tabControl1.Name = "tabControl1";
|
||||
this.tabControl1.SelectedIndex = 0;
|
||||
this.tabControl1.Size = new System.Drawing.Size(516, 182);
|
||||
this.tabControl1.TabIndex = 3;
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
this.tabPage1.Controls.Add(this.tbStackTrace);
|
||||
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage1.Name = "tabPage1";
|
||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage1.Size = new System.Drawing.Size(508, 156);
|
||||
this.tabPage1.TabIndex = 0;
|
||||
this.tabPage1.Text = "JavaScript stack trace";
|
||||
this.tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
this.tabPage2.Controls.Add(this.tbInternalStackTrace);
|
||||
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage2.Size = new System.Drawing.Size(508, 169);
|
||||
this.tabPage2.TabIndex = 1;
|
||||
this.tabPage2.Text = "Internal stack trace";
|
||||
this.tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tbStackTrace
|
||||
//
|
||||
this.tbStackTrace.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tbStackTrace.Location = new System.Drawing.Point(3, 3);
|
||||
this.tbStackTrace.Multiline = true;
|
||||
this.tbStackTrace.Name = "tbStackTrace";
|
||||
this.tbStackTrace.ReadOnly = true;
|
||||
this.tbStackTrace.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.tbStackTrace.Size = new System.Drawing.Size(502, 150);
|
||||
this.tbStackTrace.TabIndex = 1;
|
||||
//
|
||||
// tbInternalStackTrace
|
||||
//
|
||||
this.tbInternalStackTrace.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tbInternalStackTrace.Location = new System.Drawing.Point(3, 3);
|
||||
this.tbInternalStackTrace.Multiline = true;
|
||||
this.tbInternalStackTrace.Name = "tbInternalStackTrace";
|
||||
this.tbInternalStackTrace.ReadOnly = true;
|
||||
this.tbInternalStackTrace.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.tbInternalStackTrace.Size = new System.Drawing.Size(502, 163);
|
||||
this.tbInternalStackTrace.TabIndex = 2;
|
||||
//
|
||||
// UDBScriptErrorForm
|
||||
//
|
||||
this.AcceptButton = this.btnOK;
|
||||
|
@ -73,24 +124,32 @@
|
|||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnOK;
|
||||
this.ClientSize = new System.Drawing.Size(534, 261);
|
||||
this.Controls.Add(this.tabControl1);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.btnOK);
|
||||
this.Controls.Add(this.tbStackTrace);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(550, 300);
|
||||
this.Name = "UDBScriptErrorForm";
|
||||
this.ShowIcon = false;
|
||||
this.Text = "Scripr Error";
|
||||
this.Text = "Script Error";
|
||||
this.tabControl1.ResumeLayout(false);
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
this.tabPage2.ResumeLayout(false);
|
||||
this.tabPage2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox tbStackTrace;
|
||||
private System.Windows.Forms.Button btnOK;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TabControl tabControl1;
|
||||
private System.Windows.Forms.TabPage tabPage1;
|
||||
private System.Windows.Forms.TextBox tbStackTrace;
|
||||
private System.Windows.Forms.TabPage tabPage2;
|
||||
private System.Windows.Forms.TextBox tbInternalStackTrace;
|
||||
}
|
||||
}
|
|
@ -1,24 +1,52 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
#region ================== Copyright (c) 2022 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 CodeImp.DoomBuilder.Windows;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.UDBScript
|
||||
{
|
||||
public partial class UDBScriptErrorForm : DelayedForm
|
||||
{
|
||||
public UDBScriptErrorForm(string message, string stacktrace)
|
||||
#region ================== Constructors
|
||||
|
||||
public UDBScriptErrorForm(string message, string stacktrace, string internalstacktrace)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
tbStackTrace.Text = message + "\r\n" + stacktrace;
|
||||
tbStackTrace.Select(0, 0);
|
||||
|
||||
tbInternalStackTrace.Text = internalstacktrace;
|
||||
tbInternalStackTrace.Select(0, 0);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(stacktrace))
|
||||
tabControl1.SelectedIndex = 1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,137 @@
|
|||
from multiprocessing.forkserver import connect_to_new_process
|
||||
import xmltodict
|
||||
import glob
|
||||
import pprint
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
def get_param_text_from_xml(data, name):
|
||||
if isinstance(data['param'], list):
|
||||
for p in data['param']:
|
||||
if p['@name'] == name:
|
||||
return p['#text']
|
||||
else:
|
||||
return data['param']['#text']
|
||||
return '*missing*'
|
||||
|
||||
def gen_dts_function(data, isclass):
|
||||
outstr = f'\t\t/**\n'
|
||||
if 'summary' in data['xml']:
|
||||
summary = data['xml']['summary'].split('\n')[0]
|
||||
outstr += f'\t\t * {summary}\n'
|
||||
for p in data['parameters']:
|
||||
outstr += f'\t\t * @param {p["name"]} {get_param_text_from_xml(data["xml"], p["name"])}\n'
|
||||
if 'returns' in data['xml']:
|
||||
outstr += f'\t\t * @returns {data["xml"]["returns"]}\n'
|
||||
outstr += f'\t\t */\n'
|
||||
outstr += f'\t\t'
|
||||
if not isclass:
|
||||
outstr += 'function '
|
||||
outstr += f'{data["name"]}('
|
||||
for p in data['parameters']:
|
||||
outstr += f'{p["name"]}: {convert_type_to_js(p["type"])}'
|
||||
#if p['default'] is not None:
|
||||
# outstr += f' = {p["default"]}'
|
||||
outstr += ', '
|
||||
if outstr.endswith(', '):
|
||||
outstr = outstr[:-2]
|
||||
if data['returntype'] is None:
|
||||
outstr += ');'
|
||||
else:
|
||||
outstr += f'): {convert_type_to_js(data["returntype"])};'
|
||||
return outstr
|
||||
|
||||
def gen_dts_property(data, isclass):
|
||||
outstr = f'\t\t/**\n'
|
||||
if 'summary' in data['xml']:
|
||||
summary = data['xml']['summary'].split('\n')[0]
|
||||
outstr += f'\t\t * {summary}\n'
|
||||
outstr += f'\t\t */\n'
|
||||
outstr += f'\t\t'
|
||||
if 'fakedtstype' in data['xml']:
|
||||
returntype = data['xml']['fakedtstype']
|
||||
else:
|
||||
returntype = data['returntype']
|
||||
if not isclass:
|
||||
outstr += 'let '
|
||||
outstr += f'{data["name"]}: {convert_type_to_js(returntype)};'
|
||||
return outstr
|
||||
|
||||
def gen_dts_enum(data):
|
||||
outstr = f'\t\t/**\n'
|
||||
if 'summary' in data['xml']:
|
||||
summary = data['xml']['summary'].split('\n')[0]
|
||||
outstr += f'\t\t * {summary}\n'
|
||||
outstr += f'\t\t */\n'
|
||||
outstr += f'\t\tenum {data["name"]} {{\n'
|
||||
for e in data['xml']['enum']:
|
||||
outstr += f'\t\t\t/**\n'
|
||||
outstr += f'\t\t\t * {e["#text"]}\n'
|
||||
outstr += f'\t\t\t */\n'
|
||||
outstr += f'\t\t\t{e["@name"]},\n'
|
||||
outstr += '\t\t}\n'
|
||||
return outstr
|
||||
|
||||
def convert_type_to_js(text):
|
||||
if '[]' in text:
|
||||
arr = '[]'
|
||||
else:
|
||||
arr = ''
|
||||
|
||||
if text == 'double' or text == 'float' or 'int' in text:
|
||||
return 'number' + arr
|
||||
elif text == 'bool':
|
||||
return 'boolean' + arr
|
||||
elif text == 'object' or text == 'ExpandoObject':
|
||||
return 'any' + arr
|
||||
return text
|
||||
|
||||
def determine_text_type(text):
|
||||
signature = text.replace('public ', '').replace ('static ', '').replace('Wrapper', '')
|
||||
#print('----------')
|
||||
#print(f'text: {text}')
|
||||
signature = text.replace('public ', '').replace('static ', '').replace('override', '').replace('Wrapper', '')
|
||||
#print(f'signature: {signature}')
|
||||
parameters = []
|
||||
if 'internal' in signature:
|
||||
return 'internal', None, None, None
|
||||
if 'private' in signature:
|
||||
return 'private', None, None, None
|
||||
if 'class ' in text or 'struct ' in text:
|
||||
return 'global', None
|
||||
return 'global', None, None, None
|
||||
if signature.strip().startswith('enum'):
|
||||
return 'enums', re.sub(r'[^\s]+\s+', r'', signature), None, None
|
||||
if '(' not in text:
|
||||
return 'properties', re.sub(r'[^\s]+\s+', r'', signature).rstrip(';')
|
||||
returntype = signature.split(' ', 1)[0].strip()
|
||||
return 'properties', re.sub(r'[^\s]+\s+', r'', signature).rstrip(';'), None, returntype
|
||||
signaturefields = signature.split('(')
|
||||
if signaturefields[1] != ')':
|
||||
for sf in signaturefields[1].rstrip(')').split(','):
|
||||
#print(f'### {sf}')
|
||||
ptype, pname = sf.strip().split(' ', 1)
|
||||
if '=' in pname:
|
||||
defaultvalue = pname.split('=')[1].strip()
|
||||
pname = pname.split('=')[0].strip()
|
||||
else:
|
||||
defaultvalue = None
|
||||
parameters.append({ 'name': pname, 'type': ptype, 'default': defaultvalue })
|
||||
#print('parametertypes:')
|
||||
#for pt in parametertypes:
|
||||
# print(f'\t{pt}')
|
||||
returntype = signaturefields[0].strip().split(' ')[0]
|
||||
name = re.sub(r'[^\s]+\s+', r'', signaturefields[0].strip())
|
||||
#print(f'name: {name}')
|
||||
#for p in parameters:
|
||||
# print(f'pname: {p["name"]}, ptype: {p["type"]}')
|
||||
signature = re.sub(r'[^\s]+\s+', r'', signaturefields[0]) + '(' + re.sub(r'([^\s]+) ([^,]+)(,?\s*)', r'\2\3', signaturefields[1])
|
||||
#print(f'signature: {signature}')
|
||||
fields = text.split()
|
||||
if fields[0] == 'public' and ('Wrapper(' in fields[1] or 'QueryOptions(' in fields[1]):
|
||||
return 'constructors', signature
|
||||
return 'constructors', name, parameters, returntype
|
||||
elif fields[1] == 'static':
|
||||
return 'staticmethods', signature
|
||||
return 'methods', signature
|
||||
return 'staticmethods', name, parameters, returntype
|
||||
return 'methods', name, parameters, returntype
|
||||
|
||||
def get_sorted_comment_texts(texts):
|
||||
text = ''
|
||||
|
@ -26,34 +139,64 @@ def get_sorted_comment_texts(texts):
|
|||
text += texts[t]
|
||||
return text
|
||||
|
||||
def parse_attributes_line(line, attributes):
|
||||
mo = re.match(r'\[(.+?)\((.+?)\)\]', line)
|
||||
if mo is None:
|
||||
return
|
||||
attr_name = mo.group(1)
|
||||
attr_vals = mo.group(2)
|
||||
if attr_name not in attributes:
|
||||
attributes[attr_name] = {}
|
||||
for attr in attr_vals.split(','):
|
||||
mo = re.match(r'(.+)=(.+)', attr)
|
||||
if mo is None:
|
||||
return
|
||||
attributes[attr_name][mo.group(1).strip()] = mo.group(2).strip()
|
||||
|
||||
|
||||
topics = {
|
||||
'GameConfiguration': [ '../API/GameConfigurationWrapper.cs' ],
|
||||
'Angle2D': [ '../API/Angle2DWrapper.cs' ],
|
||||
'Data': [ '../API/DataWrapper.cs' ],
|
||||
'ImageInfo': [ '../API/ImageInfo.cs' ],
|
||||
'Line2D': [ '../API/Line2DWrapper.cs' ],
|
||||
'Linedef': [ '../API/LinedefWrapper.cs', '../API/MapElementWrapper.cs' ],
|
||||
'Map': [ '../API/MapWrapper.cs' ],
|
||||
'Sector': [ '../API/SectorWrapper.cs', '../API/MapElementWrapper.cs' ],
|
||||
'Sidedef': [ '../API/SidedefWrapper.cs', '../API/MapElementWrapper.cs' ],
|
||||
'Thing': [ '../API/ThingWrapper.cs', '../API/MapElementWrapper.cs' ],
|
||||
'UDB': [ '../API/UDBWrapper.cs' ],
|
||||
'Vector2D': [ '../API/Vector2DWrapper.cs' ],
|
||||
'Vector3D': [ '../API/Vector3DWrapper.cs' ],
|
||||
'Vertex': [ '../API/VertexWrapper.cs', '../API/MapElementWrapper.cs' ],
|
||||
'VisualCamera': [ '../API/VisualCameraWrapper.cs' ],
|
||||
'QueryOptions': [ '../QueryOptions.cs' ],
|
||||
'GameConfiguration': { 'files': [ '../API/GameConfigurationWrapper.cs' ], 'asnamespace': True },
|
||||
'Angle2D': { 'files': [ '../API/Angle2DWrapper.cs' ], 'asnamespace': True },
|
||||
'BlockEntry' : { 'files': [ '../API/BlockEntryWrapper.cs' ] },
|
||||
'BlockMapQueryResult' : { 'files': [ '../API/BlockMapQueryResult.cs' ] },
|
||||
'BlockMap' : { 'files': [ '../API/BlockMapWrapper.cs' ] },
|
||||
'Data': { 'files': [ '../API/DataWrapper.cs' ], 'asnamespace': True },
|
||||
'ImageInfo': { 'files': [ '../API/ImageInfo.cs' ] },
|
||||
'Line2D': { 'files': [ '../API/Line2DWrapper.cs' ] },
|
||||
'Linedef': { 'files': [ '../API/LinedefWrapper.cs', '../API/MapElementWrapper.cs' ] },
|
||||
'Map': { 'files': [ '../API/MapWrapper.cs' ], 'asnamespace': True },
|
||||
'Plane': { 'files': [ '../API/PlaneWrapper.cs' ]},
|
||||
'Sector': { 'files': [ '../API/SectorWrapper.cs', '../API/MapElementWrapper.cs' ] },
|
||||
'Sidedef': { 'files': [ '../API/SidedefWrapper.cs', '../API/MapElementWrapper.cs' ] },
|
||||
'Thing': { 'files': [ '../API/ThingWrapper.cs', '../API/MapElementWrapper.cs' ] },
|
||||
'UDB': { 'files': [ '../API/UDBWrapper.cs' ] },
|
||||
'Vector2D': { 'files': [ '../API/Vector2DWrapper.cs' ] },
|
||||
'Vector3D': { 'files': [ '../API/Vector3DWrapper.cs' ] },
|
||||
'Vertex': { 'files': [ '../API/VertexWrapper.cs', '../API/MapElementWrapper.cs' ] },
|
||||
'VisualCamera': { 'files': [ '../API/VisualCameraWrapper.cs' ] },
|
||||
'QueryOptions': { 'files': [ '../QueryOptions.cs' ] },
|
||||
}
|
||||
|
||||
dtsdata = {}
|
||||
|
||||
for topic in topics:
|
||||
dtsd = {
|
||||
'properties': [],
|
||||
'constructors': [],
|
||||
'methods': [],
|
||||
'staticmethods': [],
|
||||
'enums': []
|
||||
}
|
||||
texts = {
|
||||
'global': '',
|
||||
'properties': {},
|
||||
'constructors': {},
|
||||
'methods': {},
|
||||
'staticmethods': {}
|
||||
}
|
||||
for filename in topics[topic]:
|
||||
'staticmethods': {},
|
||||
'enums': {}
|
||||
}
|
||||
memberattributes = {}
|
||||
for filename in topics[topic]['files']:
|
||||
topicname = filename.split('\\')[-1].replace('Wrapper.cs', '')
|
||||
|
||||
with open(filename, 'r') as file:
|
||||
|
@ -62,9 +205,11 @@ for topic in topics:
|
|||
incodeblock = False
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
if line.startswith('///'):
|
||||
if line.startswith('['):
|
||||
parse_attributes_line(line, memberattributes)
|
||||
elif line.startswith('///'):
|
||||
parsingcomment = True
|
||||
line = re.sub(r'^\t', r'', line.lstrip('/').lstrip(' '))
|
||||
line = re.sub(r'^\s', r'', line.lstrip('/'))
|
||||
if line.startswith('```'):
|
||||
if incodeblock:
|
||||
xmltext += '```\n'
|
||||
|
@ -78,15 +223,56 @@ for topic in topics:
|
|||
commenttext = ''
|
||||
d = xmltodict.parse('<d>' + xmltext + '</d>')['d']
|
||||
summary = d['summary']
|
||||
texttype, signature = determine_text_type(line)
|
||||
texttype, signature, parameters, returntype = determine_text_type(line)
|
||||
if texttype == 'global':
|
||||
texts['global'] = f'{summary}\n'
|
||||
else:
|
||||
elif texttype != 'internal' and texttype != 'private':
|
||||
if texttype == 'properties':
|
||||
dtsd['properties'].append({
|
||||
'xml': d,
|
||||
'name': signature,
|
||||
'returntype': returntype
|
||||
})
|
||||
elif texttype == 'constructors':
|
||||
dtsd['constructors'].append({
|
||||
'xml': d,
|
||||
'name': 'constructor',
|
||||
'returntype': None,
|
||||
'parameters': parameters
|
||||
})
|
||||
elif texttype == 'methods':
|
||||
dtsd['methods'].append({
|
||||
'xml': d,
|
||||
'name': signature,
|
||||
'returntype': returntype,
|
||||
'parameters': parameters
|
||||
})
|
||||
elif texttype == 'staticmethods':
|
||||
dtsd['staticmethods'].append({
|
||||
'xml': d,
|
||||
'name': signature,
|
||||
'returntype': returntype,
|
||||
'parameters': parameters
|
||||
})
|
||||
elif texttype == 'enums':
|
||||
dtsd['enums'].append({
|
||||
'xml': d,
|
||||
'name': signature
|
||||
})
|
||||
commenttext += '\n---\n'
|
||||
if 'version' in d:
|
||||
commenttext += f'<span style="float:right;font-weight:normal;font-size:66%">Version: {d["version"]}</span>\n'
|
||||
commenttext += f'### {signature}\n'
|
||||
|
||||
if 'UDBScriptSettings' in memberattributes:
|
||||
commenttext += f'<span style="float:right;font-weight:normal;font-size:66%">Version: {memberattributes["UDBScriptSettings"]["MinVersion"]}</span>\n'
|
||||
commenttext += f'### {signature}'
|
||||
if parameters is not None:
|
||||
commenttext += '('
|
||||
for param in parameters:
|
||||
commenttext += f'{param["name"]}: {param["type"]}, '
|
||||
if commenttext.endswith(', '):
|
||||
commenttext = commenttext[:-2]
|
||||
commenttext += ')'
|
||||
commenttext += '\n'
|
||||
commenttext += f'{summary}\n'
|
||||
if 'param' in d:
|
||||
commenttext += '#### Parameters\n'
|
||||
|
@ -101,6 +287,19 @@ for topic in topics:
|
|||
if '#text' in d['param']:
|
||||
text = d['param']['#text'].replace('```', '\n```\n')
|
||||
commenttext += f'* {d["param"]["@name"]}: {text}\n'
|
||||
if 'enum' in d:
|
||||
commenttext += '#### Options\n'
|
||||
if isinstance(d['enum'], list):
|
||||
for p in d['enum']:
|
||||
text = '*missing*'
|
||||
if '#text' in p:
|
||||
text = p['#text']
|
||||
commenttext += f'* {p["@name"]}: {text}\n'
|
||||
else:
|
||||
text ='*missing*'
|
||||
if '#text' in d['enum']:
|
||||
text = d['enum']['#text'].replace('```', '\n```\n')
|
||||
commenttext += f'* {d["enum"]["@name"]}: {text}\n'
|
||||
if 'returns' in d:
|
||||
commenttext += '#### Return value\n'
|
||||
text = '*missing*'
|
||||
|
@ -112,8 +311,12 @@ for topic in topics:
|
|||
texts[texttype][signature] = ''
|
||||
texts[texttype][signature] += commenttext
|
||||
xmltext = ''
|
||||
memberattributes = {}
|
||||
parsingcomment = False
|
||||
|
||||
dtsdata[topic] = dtsd
|
||||
|
||||
|
||||
outfile = open(f'htmldoc/docs/{topic}.md', 'w')
|
||||
outfile.write(f'# {topic}\n\n')
|
||||
outfile.write(f'{texts["global"]}')
|
||||
|
@ -121,8 +324,61 @@ for topic in topics:
|
|||
outfile.write(f'## Constructors\n{get_sorted_comment_texts(texts["constructors"])}')
|
||||
if len(texts["staticmethods"]) > 0:
|
||||
outfile.write(f'## Static methods\n{get_sorted_comment_texts(texts["staticmethods"])}')
|
||||
if len(texts["properties"]) > 0:
|
||||
if len(texts["properties"]) > 0:
|
||||
outfile.write(f'## Properties\n{get_sorted_comment_texts(texts["properties"])}')
|
||||
if len(texts["methods"]) > 0:
|
||||
outfile.write(f'## Methods\n{get_sorted_comment_texts(texts["methods"])}')
|
||||
outfile.close()
|
||||
if len(texts['enums']) > 0:
|
||||
outfile.write(f'## Enums\n{get_sorted_comment_texts(texts["enums"])}')
|
||||
outfile.close()
|
||||
|
||||
|
||||
# Create the .d.ts file
|
||||
dtsoutstr = 'declare namespace UDB {\n'
|
||||
for key in dtsdata:
|
||||
if key == 'UDB':
|
||||
for m in dtsdata[key]['methods']:
|
||||
dtsoutstr += (gen_dts_function(m, False) + '\n')[1:]
|
||||
else:
|
||||
if 'asnamespace' in topics[key] and topics[key]['asnamespace'] is True:
|
||||
blocktype = 'namespace'
|
||||
isclass = False
|
||||
else:
|
||||
blocktype = 'class'
|
||||
isclass = True
|
||||
|
||||
if len(dtsdata[key]['constructors']) > 0 or len(dtsdata[key]['methods']) > 0 or len(dtsdata[key]['properties']) > 0:
|
||||
dtsoutstr += f'\t{blocktype} {key} {{\n'
|
||||
# constructors
|
||||
for c in dtsdata[key]['constructors']:
|
||||
dtsoutstr += gen_dts_function(c, isclass) + '\n'
|
||||
# methods
|
||||
for m in dtsdata[key]['methods']:
|
||||
dtsoutstr += gen_dts_function(m, isclass) + '\n'
|
||||
# properties
|
||||
for p in dtsdata[key]['properties']:
|
||||
if not (p['name'] in topics and p['name'] == p['returntype']):
|
||||
dtsoutstr += gen_dts_property(p, isclass) + '\n'
|
||||
else:
|
||||
print(f'ignoring {p["name"]} in {key} - returntype {p["returntype"]}')
|
||||
|
||||
dtsoutstr += '\t}\n'
|
||||
|
||||
# static methods and enums
|
||||
if len(dtsdata[key]['staticmethods']) > 0 or len(dtsdata[key]['enums']) > 0:
|
||||
dtsoutstr += f'\tnamespace {key} {{\n'
|
||||
if len(dtsdata[key]['staticmethods']) > 0:
|
||||
for m in dtsdata[key]['staticmethods']:
|
||||
dtsoutstr += gen_dts_function(m, False) + '\n'
|
||||
if len(dtsdata[key]['enums']) > 0:
|
||||
for e in dtsdata[key]['enums']:
|
||||
dtsoutstr += gen_dts_enum(e) + '\n'
|
||||
dtsoutstr += '\t}\n'
|
||||
dtsoutstr += '}\n'
|
||||
|
||||
dtsfile = Path('../../../../Build/UDBScript/udbscript.d.ts')
|
||||
|
||||
if not dtsfile.parent.exists():
|
||||
dtsfile.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
dtsfile.write_text(dtsoutstr)
|
|
@ -1,9 +1,9 @@
|
|||
# Angle2D
|
||||
|
||||
## Static methods
|
||||
## Methods
|
||||
|
||||
---
|
||||
### degToRad(deg)
|
||||
### degToRad(deg: double)
|
||||
Converts degrees to radians.
|
||||
#### Parameters
|
||||
* deg: Angle in degrees
|
||||
|
@ -11,7 +11,7 @@ Converts degrees to radians.
|
|||
Angle in radians
|
||||
|
||||
---
|
||||
### doomToReal(doomangle)
|
||||
### doomToReal(doomangle: int)
|
||||
Converts a Doom angle (where 0° is east) to a real world angle (where 0° is north).
|
||||
#### Parameters
|
||||
* doomangle: Doom angle in degrees
|
||||
|
@ -19,7 +19,7 @@ Converts a Doom angle (where 0° is east) to a real world angle (where 0° is no
|
|||
Doom angle in degrees
|
||||
|
||||
---
|
||||
### doomToRealRad(doomangle)
|
||||
### doomToRealRad(doomangle: int)
|
||||
Converts a Doom angle (where 0° is east) to a real world angle (where 0° is north) in radians.
|
||||
#### Parameters
|
||||
* doomangle: Doom angle in degrees
|
||||
|
@ -27,7 +27,7 @@ Converts a Doom angle (where 0° is east) to a real world angle (where 0° is no
|
|||
Doom angle in radians
|
||||
|
||||
---
|
||||
### getAngle(p1, p2, p3)
|
||||
### getAngle(p1: object, p2: object, p3: object)
|
||||
Returns the angle between three positions.
|
||||
#### Parameters
|
||||
* p1: First position
|
||||
|
@ -37,7 +37,7 @@ Returns the angle between three positions.
|
|||
Angle in degrees
|
||||
|
||||
---
|
||||
### getAngleRad(p1, p2, p3)
|
||||
### getAngleRad(p1: object, p2: object, p3: object)
|
||||
Returns the angle between three positions in radians.
|
||||
#### Parameters
|
||||
* p1: First position
|
||||
|
@ -47,7 +47,7 @@ Returns the angle between three positions in radians.
|
|||
Angle in radians
|
||||
|
||||
---
|
||||
### normalized(angle)
|
||||
### normalized(angle: int)
|
||||
Normalizes an angle in degrees so that it is bigger or equal to 0° and smaller than 360°.
|
||||
#### Parameters
|
||||
* angle: Angle in degrees
|
||||
|
@ -55,7 +55,7 @@ Normalizes an angle in degrees so that it is bigger or equal to 0° and smaller
|
|||
Normalized angle in degrees
|
||||
|
||||
---
|
||||
### normalizedRad(angle)
|
||||
### normalizedRad(angle: double)
|
||||
Normalizes an angle in radians so that it is bigger or equal to 0 and smaller than 2 Pi.
|
||||
#### Parameters
|
||||
* angle: Angle in radians
|
||||
|
@ -63,7 +63,7 @@ Normalizes an angle in radians so that it is bigger or equal to 0 and smaller th
|
|||
Normalized angle in radians
|
||||
|
||||
---
|
||||
### radToDeg(rad)
|
||||
### radToDeg(rad: double)
|
||||
Converts radians to degrees.
|
||||
#### Parameters
|
||||
* rad: Angle in radians
|
||||
|
@ -71,7 +71,7 @@ Converts radians to degrees.
|
|||
Angle in degrees
|
||||
|
||||
---
|
||||
### realToDoom(realangle)
|
||||
### realToDoom(realangle: double)
|
||||
Converts a real world angle (where 0° is north) to a Doom angle (where 0° is east).
|
||||
#### Parameters
|
||||
* realangle: Real world angle in degrees
|
||||
|
@ -79,8 +79,8 @@ Converts a real world angle (where 0° is north) to a Doom angle (where 0° is e
|
|||
Doom angle in degrees
|
||||
|
||||
---
|
||||
### realToDoomRad(realangle)
|
||||
Converts a real world angle (where 0° is north) to a Doom angle (where 0° is east) in radians.
|
||||
### realToDoomRad(realangle: double)
|
||||
Converts a real world angle (where 0° is north) to a Doom angle (where 0° is east) in radians.
|
||||
#### Parameters
|
||||
* realangle: Real world angle in radians
|
||||
#### Return value
|
||||
|
|
32
Source/Plugins/UDBScript/docs/htmldoc/docs/BlockEntry.md
Normal file
32
Source/Plugins/UDBScript/docs/htmldoc/docs/BlockEntry.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
# BlockEntry
|
||||
|
||||
A `BlockEntry` is a single block in a `BlockMap`. It has methods to retrieve the linedefs, things, sectors, and vertices that are in this block.
|
||||
## Methods
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getLinedefs()
|
||||
Gets all `Linedef`s in the blockmap entry.
|
||||
#### Return value
|
||||
`Array` of `Linedef`s
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getSectors()
|
||||
Gets all `Sector`s in the blockmap entry.
|
||||
#### Return value
|
||||
`Array` of `Sector`s
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getThings()
|
||||
Gets all `Thing`s in the blockmap entry.
|
||||
#### Return value
|
||||
`Array` of `Thing`s
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getVertices()
|
||||
Gets all `Vertex` in the blockmap entry.
|
||||
#### Return value
|
||||
`Array` of `Vertex`
|
107
Source/Plugins/UDBScript/docs/htmldoc/docs/BlockMap.md
Normal file
107
Source/Plugins/UDBScript/docs/htmldoc/docs/BlockMap.md
Normal file
|
@ -0,0 +1,107 @@
|
|||
# BlockMap
|
||||
|
||||
A blockmap is used to retrieve a collection of localized map elements (things, linedefs, sectors, vertices). It can help to significantly speed up costly computations that would otherwise be applied to a large portion of the map elements. The blockmap divides the map into rectangular blocks and computes which map elements are fully or partially in each block. Then you can query the blockmap about only some of those blocks, and perform any further actions only on the map elements that are in those blocks.
|
||||
|
||||
If you for example wanted to find out which sector is at the (0, 0) position you could write something like this without using a blockmap:
|
||||
|
||||
```js
|
||||
UDB.Map.getSectors().findIndex((s, i) => {
|
||||
if(s.intersect([ 0, 0 ]))
|
||||
{
|
||||
UDB.log(`Found ${s} after ${i} tries.`)
|
||||
return true;
|
||||
}
|
||||
});
|
||||
```
|
||||
This loops through all sectors of the map and uses the `intersect` method to test if the point is inside the sector. While `intersect` is quite fast on its own, doing it potentially thousands of times adds up quickly, especially if you have to loop through all sectors multiple times.
|
||||
A pretty extreme example for this is the map Bastion of Chaos. The map contains nearly 32500 sectors, and the sector at (0, 0) is number 25499. That means that the above script has to run `intersect` on 25499 sectors, even on those that are not remotely near the (0, 0) position.
|
||||
|
||||
Using a blockmap the code could look like this:
|
||||
|
||||
```js
|
||||
const blockmap = new UDB.BlockMap();
|
||||
|
||||
blockmap.getBlockAt([ 0, 0 ]).getSectors().findIndex((s, i) => {
|
||||
if (s.intersect([0, 0]))
|
||||
{
|
||||
UDB.log(`Found ${s} after ${i} tries.`)
|
||||
return true;
|
||||
}
|
||||
});
|
||||
```
|
||||
As you can see the code is quite similar, the difference being that a blockmap is created, and `UDB.Map` is replaced by `blockmap.getBlockAt([ 0, 0 ])`, the latter only getting a single block from the blockmap, that only contains the map elements that are in this block. Taking Bastion of Chaos as an example again, this code finds the sector after only 20 checks, instead of the 25499 checks in the first code example.
|
||||
|
||||
!!! note
|
||||
Creating a blockmap has a small overhead, since it has to compute which map elements are in which blocks. This overhead, however, is quickly compensated by the time saved by not looping through irrelevant map elements. You can decrease this overhead by using a `BlockMap` constructor that only adds certain map element types to the blockmap.
|
||||
## Constructors
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### BlockMap()
|
||||
Creates a blockmap that includes linedefs, things, sectors, and vertices.
|
||||
|
||||
```js
|
||||
// Create a blockmap that includes all linedefs, things, sectors, and vertices
|
||||
const blockmap = new UDB.BlockMap();
|
||||
```
|
||||
|
||||
---
|
||||
### BlockMap(lines: bool, things: bool, sectors: bool, vertices: bool)
|
||||
Creates a blockmap that only includes certain map element types.
|
||||
|
||||
```js
|
||||
// Create a blockmap that only includes sectors
|
||||
const blockmap = new UDB.BlockMap(false, false, true, false);
|
||||
```
|
||||
#### Parameters
|
||||
* lines: If linedefs should be added or not
|
||||
* things: If thigs should be added or not
|
||||
* sectors: If sectors should be added or not
|
||||
* vertices: If vertices should be added or not
|
||||
## Methods
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getBlockAt(pos: object)
|
||||
Gets the `BlockEntry` at a point. The given point can be a `Vector2D` or an `Array` of two numbers.
|
||||
|
||||
```js
|
||||
const blockmap = new UDB.BlockMap();
|
||||
const blockentry = blockmap.getBlockAt([ 64, 128 ]);
|
||||
```
|
||||
#### Parameters
|
||||
* pos: The point to get the `BlockEntry` of
|
||||
#### Return value
|
||||
The `BlockEntry` on the given point
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getLineBlocks(v1: object, v2: object)
|
||||
Gets a `BlockMapQueryResult` for the blockmap along a line between two points. The given points can be `Vector2D`s or an `Array`s of two numbers.
|
||||
|
||||
```js
|
||||
const blockmap = new UDB.BlockMap();
|
||||
const result = blockmap.getLineBlocks([ 0, 0 ], [ 512, 256 ]);
|
||||
```
|
||||
#### Parameters
|
||||
* v1: The first point
|
||||
* v2: The second point
|
||||
#### Return value
|
||||
The `BlockMapQueryResult` for the line between the two points
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getRectangleBlocks(x: int, y: int, width: int, height: int)
|
||||
Gets a `BlockMapQueryResult` for the blockmap in a rectangle.
|
||||
|
||||
```js
|
||||
const blockmap = new UDB.BlockMap();
|
||||
const result = blockmap.getRectangleBlocks(0, 0, 512, 256);
|
||||
```
|
||||
#### Parameters
|
||||
* x: X position of the top-left corner of the rectangle
|
||||
* y: Y position of the top-left corner of the rectangle
|
||||
* width: Width of the rectangle
|
||||
* height: Height of the rectangle
|
||||
#### Return value
|
||||
*missing*
|
|
@ -0,0 +1,54 @@
|
|||
# BlockMapQueryResult
|
||||
|
||||
A `BlockMapQueryResult` is an object returned by the `getLineBlocks` and `getRectangleBlocks` methods of the `BlockMap` class. It has methods It has methods to retrieve the linedefs, things, sectors, and vertices that are in the queried blocks. The object is also iterable, returning each block, in cases where more fine-grained control is needed.
|
||||
|
||||
```js
|
||||
const blockmap = new UDB.BlockMap();
|
||||
const result = blockmap.getLineBlocks([ 0, 0 ], [ 512, 256 ]);
|
||||
|
||||
// Print all linedefs in the blocks
|
||||
result.getLinedefs().forEach(ld => UDB.log(ld));
|
||||
```
|
||||
Looping over each block:
|
||||
|
||||
```js
|
||||
const blockmap = new UDB.BlockMap();
|
||||
const result = blockmap.getLineBlocks([ 0, 0 ], [ 512, 256 ]);
|
||||
|
||||
for(const block of result)
|
||||
{
|
||||
UDB.log('--- New block ---');
|
||||
block.getLinedefs().forEach(ld => UDB.log(ld));
|
||||
}
|
||||
```
|
||||
!!! note
|
||||
The methods to retrieve map elements from `BlockMapQueryResult` return arrays that only contain each map element once, since linedefs and sectors can be in multiple blocks, looping over a `BlockMapQueryResult` using `for...of` can return the same map elements multiple times.
|
||||
## Methods
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getLinedefs()
|
||||
Gets all `Linedef`s in the blockmap query result.
|
||||
#### Return value
|
||||
`Array` of `Linedef`s
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getSectors()
|
||||
Gets all `Sector`s in the blockmap query result.
|
||||
#### Return value
|
||||
`Array` of `Sector`s
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getThings()
|
||||
Gets all `Thing`s in the blockmap query result.
|
||||
#### Return value
|
||||
`Array` of `Thing`s
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getVertices()
|
||||
Gets all `Vertex` in the blockmap query result.
|
||||
#### Return value
|
||||
`Array` of `Vertex`
|
|
@ -1,9 +1,9 @@
|
|||
# Data
|
||||
|
||||
## Static methods
|
||||
## Methods
|
||||
|
||||
---
|
||||
### flatExists(name)
|
||||
### flatExists(name: string)
|
||||
Checks if a flat with the given name exists.
|
||||
#### Parameters
|
||||
* name: Flat name to check
|
||||
|
@ -11,7 +11,7 @@ Checks if a flat with the given name exists.
|
|||
`true` if the flat exists, `false` if it doesn't
|
||||
|
||||
---
|
||||
### getFlatInfo(name)
|
||||
### getFlatInfo(name: string)
|
||||
Returns an `ImageInfo` object for the given flat name.
|
||||
#### Parameters
|
||||
* name: Flat name to get the info for
|
||||
|
@ -25,7 +25,7 @@ Returns an `Array`of all flat names.
|
|||
`Array` of all flat names
|
||||
|
||||
---
|
||||
### getTextureInfo(name)
|
||||
### getTextureInfo(name: string)
|
||||
Returns an `ImageInfo` object for the given texture name.
|
||||
#### Parameters
|
||||
* name: Texture name to get the info for
|
||||
|
@ -39,7 +39,7 @@ Returns an `Array` of all texture names.
|
|||
`Array` of all texture names
|
||||
|
||||
---
|
||||
### textureExists(name)
|
||||
### textureExists(name: string)
|
||||
Checks if a texture with the given name exists.
|
||||
#### Parameters
|
||||
* name: Texture name to check
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Constructors
|
||||
|
||||
---
|
||||
### Line2D(v1, v2)
|
||||
### Line2D(v1: object, v2: object)
|
||||
Creates a new `Line2D` from two points.
|
||||
|
||||
```js
|
||||
|
@ -16,7 +16,17 @@ let line2 = new UDB.Line2D([ 32, 64 ], [ 96, 128 ]);
|
|||
## Static methods
|
||||
|
||||
---
|
||||
### areIntersecting(a1, a2, b1, b2, bounded=true)
|
||||
### areIntersecting(line1: Line2D, line2: Line2D, bounded: bool)
|
||||
Checks if two lines intersect. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* line1: First `Line2D`
|
||||
* line2: Second `Line2D`
|
||||
* bounded: `true` to use finite length of lines, `false` to use infinite length of lines
|
||||
#### Return value
|
||||
`true` if the lines intersect, `false` if they do not
|
||||
|
||||
---
|
||||
### areIntersecting(a1: object, a2: object, b1: object, b2: object, bounded: bool)
|
||||
Checks if two lines defined by their start and end points intersect. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* a1: First point of first line
|
||||
|
@ -28,17 +38,7 @@ Checks if two lines defined by their start and end points intersect. If `bounded
|
|||
`true` if the lines intersect, `false` if they do not
|
||||
|
||||
---
|
||||
### areIntersecting(line1, line2, bounded=true)
|
||||
Checks if two lines intersect. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* line1: First `Line2D`
|
||||
* line2: Second `Line2D`
|
||||
* bounded: `true` to use finite length of lines, `false` to use infinite length of lines
|
||||
#### Return value
|
||||
`true` if the lines intersect, `false` if they do not
|
||||
|
||||
---
|
||||
### getCoordinatesAt(v1, v2, u)
|
||||
### getCoordinatesAt(v1: object, v2: object, u: double)
|
||||
Returns the coordinate on a line defined by its start and end points as `Vector2D`.
|
||||
#### Parameters
|
||||
* v1: First point of the line
|
||||
|
@ -48,7 +48,7 @@ Returns the coordinate on a line defined by its start and end points as `Vector2
|
|||
Point on the line as `Vector2D`
|
||||
|
||||
---
|
||||
### getDistanceToLine(v1, v2, p, bounded=true)
|
||||
### getDistanceToLine(v1: object, v2: object, p: object, bounded: bool)
|
||||
Returns the shortest distance from point `p` to the line defined by its start and end points. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* v1: First point of the line
|
||||
|
@ -59,7 +59,7 @@ Returns the shortest distance from point `p` to the line defined by its start an
|
|||
The shortest distance to the line
|
||||
|
||||
---
|
||||
### getDistanceToLineSq(v1, v2, p, bounded = true)
|
||||
### getDistanceToLineSq(v1: object, v2: object, p: object, bounded: bool)
|
||||
Returns the shortest square distance from point `p` to the line defined by its start and end points. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* v1: First point of the line
|
||||
|
@ -70,7 +70,7 @@ Returns the shortest square distance from point `p` to the line defined by its s
|
|||
The shortest square distance to the line
|
||||
|
||||
---
|
||||
### getIntersectionPoint(a1, a2, b1, b2, bounded = true)
|
||||
### getIntersectionPoint(a1: object, a2: object, b1: object, b2: object, bounded: bool)
|
||||
Returns the intersection point of two lines as `Vector2D`. If the lines do not intersect the `x` and `y` properties of the `Vector2D` are `NaN`. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* a1: First point of first line
|
||||
|
@ -82,7 +82,7 @@ Returns the intersection point of two lines as `Vector2D`. If the lines do not i
|
|||
The intersection point as `Vector2D`
|
||||
|
||||
---
|
||||
### getNearestOnLine(v1, v2, p)
|
||||
### getNearestOnLine(v1: object, v2: object, p: object)
|
||||
Returns the offset coordinate on the line nearest to the given point. `0.0` being on the first point, `1.0` being on the second point, and `u = 0.5` being in the middle between the points.
|
||||
#### Parameters
|
||||
* v1: First point of the line
|
||||
|
@ -92,7 +92,7 @@ Returns the offset coordinate on the line nearest to the given point. `0.0` bein
|
|||
The offset value relative to the first point of the line.
|
||||
|
||||
---
|
||||
### getSideOfLine(v1, v2, p)
|
||||
### getSideOfLine(v1: object, v2: object, p: object)
|
||||
Returns which the of the line defined by its start and end point a given point is on.
|
||||
#### Parameters
|
||||
* v1: First point of the line
|
||||
|
@ -124,7 +124,7 @@ Returns the angle of the `Line2D` in radians.
|
|||
Angle of `Line2D` in radians
|
||||
|
||||
---
|
||||
### getCoordinatesAt(u)
|
||||
### getCoordinatesAt(u: double)
|
||||
Returns the coordinates on the line, where `u` is the position between the first and second point, `u = 0.0` being on the first point, `u = 1.0` being on the second point, and `u = 0.5` being in the middle between the points.
|
||||
#### Parameters
|
||||
* u: Position on the line, between 0.0 and 1.0
|
||||
|
@ -132,7 +132,7 @@ Returns the coordinates on the line, where `u` is the position between the first
|
|||
Position on the line as `Vector2D`
|
||||
|
||||
---
|
||||
### getIntersectionPoint(a1, a2, bounded = true)
|
||||
### getIntersectionPoint(a1: object, a2: object, bounded: bool)
|
||||
Returns the intersection point of of the given line defined by its start and end points with this line as `Vector2D`. If the lines do not intersect the `x` and `y` properties of the `Vector2D` are `NaN`. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* a1: First point of first line
|
||||
|
@ -142,7 +142,7 @@ Returns the intersection point of of the given line defined by its start and end
|
|||
The intersection point as `Vector2D`
|
||||
|
||||
---
|
||||
### getIntersectionPoint(ray, bounded=true)
|
||||
### getIntersectionPoint(ray: Line2D, bounded: bool)
|
||||
Returns the intersection point of of the given line with this line as `Vector2D`. If the lines do not intersect the `x` and `y` properties of the `Vector2D` are `NaN`. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* ray: Other `Line2D` to get the intersection point from
|
||||
|
@ -163,7 +163,7 @@ Returns the perpendicular of this line as `Vector2D`.
|
|||
Perpendicular of this line as `Vector2D`
|
||||
|
||||
---
|
||||
### getSideOfLine(p)
|
||||
### getSideOfLine(p: object)
|
||||
Returns which the of the line defined by its start and end point a given point is on.
|
||||
#### Parameters
|
||||
* p: Point to check
|
||||
|
@ -171,7 +171,16 @@ Returns which the of the line defined by its start and end point a given point i
|
|||
`< 0` if `p` is on the front (right) side, `> 0` if `p` is on the back (left) side, `== 0` if `p` in on the line
|
||||
|
||||
---
|
||||
### isIntersecting(a1, a2, bounded = true)
|
||||
### isIntersecting(ray: Line2D, bounded: bool)
|
||||
Checks if the given `Line2D` intersects this line. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* ray: `Line2D` to check against
|
||||
* bounded: `true` (default) to use finite length of lines, `false` to use infinite length of lines
|
||||
#### Return value
|
||||
`true` if lines intersect, `false` if they do not intersect
|
||||
|
||||
---
|
||||
### isIntersecting(a1: object, a2: object, bounded: bool)
|
||||
Checks if the given line intersects this line. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* a1: First point of the line to check against
|
||||
|
@ -179,12 +188,3 @@ Checks if the given line intersects this line. If `bounded` is set to `true` (de
|
|||
* bounded: `true` (default) to use finite length of lines, `false` to use infinite length of lines
|
||||
#### Return value
|
||||
`true` if the lines intersect, `false` if they do not
|
||||
|
||||
---
|
||||
### isIntersecting(ray, bounded=true)
|
||||
Checks if the given `Line2D` intersects this line. If `bounded` is set to `true` (default) the finite length of the lines is used, otherwise the infinite length of the lines is used.
|
||||
#### Parameters
|
||||
* ray: `Line2D` to check against
|
||||
* bounded: `true` (default) to use finite length of lines, `false` to use infinite length of lines
|
||||
#### Return value
|
||||
`true` if lines intersect, `false` if they do not intersect
|
||||
|
|
|
@ -49,7 +49,14 @@ There are some restrictions, though:
|
|||
|
||||
* it only works for fields that are not in the base UDMF standard, since those are handled directly in the respective class
|
||||
* it does not work for flags. While they are technically also UDMF fields, they are handled in the `flags` field of the respective class (where applicable)
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation, using the `UniValue` class:
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation:
|
||||
Version 5 and later:
|
||||
You can use a `BigInt`. This is done by appending a `n` to the number. Note that this is just a convenient way to define whole numbers, it still only supports 32 bit integers:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = 25n; // Sets the 'user_myintfield' field to an integer value of 25
|
||||
```
|
||||
In version 4 and earlier you have to use the `UniValue` class:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = new UDB.UniValue(0, 25); // Sets the 'user_myintfield' field to an integer value of 25
|
||||
|
@ -117,7 +124,7 @@ The linedef's start `Vertex`.
|
|||
## Methods
|
||||
|
||||
---
|
||||
### addTag(tag)
|
||||
### addTag(tag: int)
|
||||
Adds a tag to the `Linedef`. UDMF only. Supported game configurations only.
|
||||
#### Parameters
|
||||
* tag: Tag to add
|
||||
|
@ -133,7 +140,7 @@ Automatically sets the blocking and two-sided flags based on the existing `Sided
|
|||
Clears all flags.
|
||||
|
||||
---
|
||||
### copyPropertiesTo(other)
|
||||
### copyPropertiesTo(other: Linedef)
|
||||
Copies the properties of this `Linedef` to another `Linedef`.
|
||||
#### Parameters
|
||||
* other: The `Linedef` to copy the properties to
|
||||
|
@ -143,7 +150,7 @@ Copies the properties of this `Linedef` to another `Linedef`.
|
|||
Deletes the `Linedef`. Note that this will result in unclosed `Sector`s unless it has the same `Sector`s on both sides.
|
||||
|
||||
---
|
||||
### distanceTo(pos, bounded)
|
||||
### distanceTo(pos: object, bounded: bool)
|
||||
Gets the shortest distance from `pos` to the line.
|
||||
#### Parameters
|
||||
* pos: Point to check against
|
||||
|
@ -152,7 +159,7 @@ Gets the shortest distance from `pos` to the line.
|
|||
Distance to the line
|
||||
|
||||
---
|
||||
### distanceToSq(pos, bounded)
|
||||
### distanceToSq(pos: object, bounded: bool)
|
||||
Gets the shortest squared distance from `pos` to the line.
|
||||
#### Parameters
|
||||
* pos: Point to check against
|
||||
|
@ -179,7 +186,7 @@ Gets a `Vector2D` that's in the center of the `Linedef`.
|
|||
`Vector2D` in the center of the `Linedef`
|
||||
|
||||
---
|
||||
### getSidePoint(front)
|
||||
### getSidePoint(front: bool)
|
||||
Gets a `Vector2D` for testing on one side. The `Vector2D` is on the front when `true` is passed, otherwise on the back.
|
||||
#### Parameters
|
||||
* front: `true` for front, `false` for back
|
||||
|
@ -193,7 +200,7 @@ Returns an `Array` of the `Linedef`'s tags. UDMF only. Supported game configurat
|
|||
`Array` of tags
|
||||
|
||||
---
|
||||
### nearestOnLine(pos)
|
||||
### nearestOnLine(pos: object)
|
||||
Get a `Vector2D` that's *on* the line, closest to `pos`. `pos` can either be a `Vector2D`, or an array of numbers.
|
||||
|
||||
```js
|
||||
|
@ -206,7 +213,7 @@ var v2 = ld.nearestOnLine([ 32, 64 ]);
|
|||
`Vector2D` that's on the linedef
|
||||
|
||||
---
|
||||
### removeTag(tag)
|
||||
### removeTag(tag: int)
|
||||
Removes a tag from the `Linedef`. UDMF only. Supported game configurations only.
|
||||
#### Parameters
|
||||
* tag: Tag to remove
|
||||
|
@ -214,7 +221,7 @@ Removes a tag from the `Linedef`. UDMF only. Supported game configurations only.
|
|||
`true` when the tag was removed successfully, `false` when the tag did not exist
|
||||
|
||||
---
|
||||
### safeDistanceTo(pos, bounded)
|
||||
### safeDistanceTo(pos: object, bounded: bool)
|
||||
Gets the shortest "safe" distance from `pos` to the line. If `bounded` is `true` that means that the not the whole line's length will be used, but `lengthInv` less at the start and end.
|
||||
#### Parameters
|
||||
* pos: Point to check against
|
||||
|
@ -223,7 +230,7 @@ Gets the shortest "safe" distance from `pos` to the line. If `bounded` is `true`
|
|||
Distance to the line
|
||||
|
||||
---
|
||||
### safeDistanceToSq(pos, bounded)
|
||||
### safeDistanceToSq(pos: object, bounded: bool)
|
||||
Gets the shortest "safe" squared distance from `pos` to the line. If `bounded` is `true` that means that the not the whole line's length will be used, but `lengthInv` less at the start and end.
|
||||
#### Parameters
|
||||
* pos: Point to check against
|
||||
|
@ -232,7 +239,7 @@ Gets the shortest "safe" squared distance from `pos` to the line. If `bounded` i
|
|||
Squared distance to the line
|
||||
|
||||
---
|
||||
### sideOfLine(pos)
|
||||
### sideOfLine(pos: object)
|
||||
Tests which side of the `Linedef` `pos` is on. Returns < 0 for front (right) side, > for back (left) side, and 0 if `pos` is on the line.
|
||||
#### Parameters
|
||||
* pos: Point to check against
|
||||
|
@ -240,7 +247,7 @@ Tests which side of the `Linedef` `pos` is on. Returns < 0 for front (right) sid
|
|||
< 0 for front (right) side, > for back (left) side, and 0 if `pos` is on the line
|
||||
|
||||
---
|
||||
### split(pos)
|
||||
### split(pos: object)
|
||||
Splits the `Linedef` at the given position. This can either be a `Vector2D`, an array of numbers, or an existing `Vertex`. The result will be two lines, from the start `Vertex` of the `Linedef` to `pos`, and from `pos` to the end `Vertex` of the `Linedef`.
|
||||
#### Parameters
|
||||
* pos: `Vertex` to split by
|
||||
|
|
|
@ -24,7 +24,7 @@ The map coordinates of the mouse position as a `Vector2D`. Read-only.
|
|||
## Methods
|
||||
|
||||
---
|
||||
### clearAllMarks(mark=false)
|
||||
### clearAllMarks(mark: bool)
|
||||
Sets the `marked` property of all map elements. Can be passed `true` to mark all map elements.
|
||||
#### Parameters
|
||||
* mark: `false` to set the `marked` property to `false` (default), `true` to set the `marked` property to `true`
|
||||
|
@ -34,31 +34,31 @@ Sets the `marked` property of all map elements. Can be passed `true` to mark all
|
|||
Clears all selected map elements.
|
||||
|
||||
---
|
||||
### clearMarkeLinedefs(mark=false)
|
||||
### clearMarkeLinedefs(mark: bool)
|
||||
Sets the `marked` property of all `Linedef`s. Can be passed `true` to mark all `Linedef`s.
|
||||
#### Parameters
|
||||
* mark: `false` to set the `marked` property to `false` (default), `true` to set the `marked` property to `true`
|
||||
|
||||
---
|
||||
### clearMarkeSectors(mark = false)
|
||||
### clearMarkeSectors(mark: bool)
|
||||
Sets the `marked` property of all `Sector`s. Can be passed `true` to mark all `Sector`s.
|
||||
#### Parameters
|
||||
* mark: `false` to set the `marked` property to `false` (default), `true` to set the `marked` property to `true`
|
||||
|
||||
---
|
||||
### clearMarkeSidedefs(mark = false)
|
||||
### clearMarkeSidedefs(mark: bool)
|
||||
Sets the `marked` property of all `Sidedef`s. Can be passed `true` to mark all `Sidedef`s.
|
||||
#### Parameters
|
||||
* mark: `false` to set the `marked` property to `false` (default), `true` to set the `marked` property to `true`
|
||||
|
||||
---
|
||||
### clearMarkedThings(mark=false)
|
||||
### clearMarkedThings(mark: bool)
|
||||
Sets the `marked` property of all `Thing`s. Can be passed `true` to mark all `Thing`s.
|
||||
#### Parameters
|
||||
* mark: `false` to set the `marked` property to `false` (default), `true` to set the `marked` property to `true`
|
||||
|
||||
---
|
||||
### clearMarkedVertices(mark=false)
|
||||
### clearMarkedVertices(mark: bool)
|
||||
Sets the `marked` property of all vertices. Can be passed `true` to mark all vertices.
|
||||
#### Parameters
|
||||
* mark: `false` to set the `marked` property to `false` (default), `true` to set the `marked` property to `true`
|
||||
|
@ -76,7 +76,7 @@ Clears all selected `Thing`s.
|
|||
Clears all selected vertices.
|
||||
|
||||
---
|
||||
### createThing(pos, type=0)
|
||||
### createThing(pos: object, type: int)
|
||||
Creates a new `Thing` at the given position. The position can be a `Vector2D`, `Vector3D`, or an `Array` of two numbers or three numbers (note that the z position only works for game configurations that support vertical pos. A thing type can be supplied optionally.
|
||||
|
||||
```js
|
||||
|
@ -92,7 +92,7 @@ var t4 = UDB.Map.createThing([ 32, 64 ], 3001); // Create an Imp
|
|||
The new `Thing`
|
||||
|
||||
---
|
||||
### createVertex(pos)
|
||||
### createVertex(pos: object)
|
||||
Creates a new `Vertex` at the given position. The position can be a `Vector2D` or an `Array` of two numbers.
|
||||
|
||||
```js
|
||||
|
@ -105,7 +105,7 @@ var v2 = UDB.Map.createVertex([ 32, 64 ]);
|
|||
The created `Vertex`
|
||||
|
||||
---
|
||||
### drawLines(data)
|
||||
### drawLines(data: object)
|
||||
Draws lines. Data has to be an `Array` of `Array` of numbers, `Vector2D`s, `Vector3D`s, or objects with x and y properties. Note that the first and last element have to be at the same positions to make a complete drawing.
|
||||
|
||||
```js
|
||||
|
@ -161,7 +161,7 @@ Returns an `Array` of all `Linedef`s in the map.
|
|||
`Array` of `Linedef`s
|
||||
|
||||
---
|
||||
### getMarkedLinedefs(mark = true)
|
||||
### getMarkedLinedefs(mark: bool)
|
||||
Gets all marked (default) or unmarked `Linedef`s.
|
||||
#### Parameters
|
||||
* mark: `true` to get all marked `Linedef`s (default), `false` to get all unmarked `Linedef`s
|
||||
|
@ -169,7 +169,7 @@ Gets all marked (default) or unmarked `Linedef`s.
|
|||
*missing*
|
||||
|
||||
---
|
||||
### getMarkedSectors(mark = true)
|
||||
### getMarkedSectors(mark: bool)
|
||||
Gets all marked (default) or unmarked `Sector`s.
|
||||
#### Parameters
|
||||
* mark: `true` to get all marked `Sector`s (default), `false` to get all unmarked `Sector`s
|
||||
|
@ -177,7 +177,7 @@ Gets all marked (default) or unmarked `Sector`s.
|
|||
*missing*
|
||||
|
||||
---
|
||||
### getMarkedSidedefs(mark = true)
|
||||
### getMarkedSidedefs(mark: bool)
|
||||
Gets all marked (default) or unmarked `Sidedef`s.
|
||||
#### Parameters
|
||||
* mark: `true` to get all marked `Sidedef`s (default), `false` to get all unmarked `Sidedef`s
|
||||
|
@ -185,7 +185,7 @@ Gets all marked (default) or unmarked `Sidedef`s.
|
|||
*missing*
|
||||
|
||||
---
|
||||
### getMarkedThings(mark = true)
|
||||
### getMarkedThings(mark: bool)
|
||||
Gets all marked (default) or unmarked `Thing`s.
|
||||
#### Parameters
|
||||
* mark: `true` to get all marked `Thing`s (default), `false` to get all unmarked `Thing`s
|
||||
|
@ -193,7 +193,7 @@ Gets all marked (default) or unmarked `Thing`s.
|
|||
*missing*
|
||||
|
||||
---
|
||||
### getMarkedVertices(mark=true)
|
||||
### getMarkedVertices(mark: bool)
|
||||
Gets all marked (default) or unmarked vertices.
|
||||
#### Parameters
|
||||
* mark: `true` to get all marked vertices (default), `false` to get all unmarked vertices
|
||||
|
@ -201,7 +201,7 @@ Gets all marked (default) or unmarked vertices.
|
|||
*missing*
|
||||
|
||||
---
|
||||
### getMultipleNewTags(count)
|
||||
### getMultipleNewTags(count: int)
|
||||
Gets multiple new tags.
|
||||
#### Parameters
|
||||
* count: Number of tags to get
|
||||
|
@ -209,7 +209,7 @@ Gets multiple new tags.
|
|||
`Array` of the new tags
|
||||
|
||||
---
|
||||
### getNewTag(usedtags = null)
|
||||
### getNewTag(usedtags: int[])
|
||||
Gets a new tag.
|
||||
#### Parameters
|
||||
* usedtags: `Array` of tags to skip
|
||||
|
@ -223,7 +223,7 @@ Returns an `Array` of all `Sector`s in the map.
|
|||
`Array` of `Sector`s
|
||||
|
||||
---
|
||||
### getSelectedLinedefs(selected = true)
|
||||
### getSelectedLinedefs(selected: bool)
|
||||
Gets all selected (default) or unselected `Linedef`s.
|
||||
#### Parameters
|
||||
* selected: `true` to get all selected `Linedef`s, `false` to get all unselected ones
|
||||
|
@ -255,7 +255,7 @@ Gets the currently selected `Vertex`s *or*, if no `Vertex`s are selected, a curr
|
|||
`Array` of `Vertex`
|
||||
|
||||
---
|
||||
### getSelectedSectors(selected = true)
|
||||
### getSelectedSectors(selected: bool)
|
||||
Gets all selected (default) or unselected `Sector`s.
|
||||
#### Parameters
|
||||
* selected: `true` to get all selected `Sector`s, `false` to get all unselected ones
|
||||
|
@ -263,7 +263,7 @@ Gets all selected (default) or unselected `Sector`s.
|
|||
`Array` of `Sector`s
|
||||
|
||||
---
|
||||
### getSelectedThings(selected = true)
|
||||
### getSelectedThings(selected: bool)
|
||||
Gets all selected (default) or unselected `Thing`s.
|
||||
#### Parameters
|
||||
* selected: `true` to get all selected `Thing`s, `false` to get all unselected ones
|
||||
|
@ -271,7 +271,7 @@ Gets all selected (default) or unselected `Thing`s.
|
|||
`Array` of `Thing`s
|
||||
|
||||
---
|
||||
### getSelectedVertices(selected=true)
|
||||
### getSelectedVertices(selected: bool)
|
||||
Gets all selected (default) or unselected vertices.
|
||||
#### Parameters
|
||||
* selected: `true` to get all selected vertices, `false` to get all unselected ones
|
||||
|
@ -285,7 +285,7 @@ Returns an `Array` of all `Sidedef`s in the map.
|
|||
`Array` of `Sidedef`s
|
||||
|
||||
---
|
||||
### getSidedefsFromSelectedLinedefs(selected = true)
|
||||
### getSidedefsFromSelectedLinedefs(selected: bool)
|
||||
Gets all `Sidedef`s from the selected `Linedef`s.
|
||||
In classic modes this will return both sidedefs of 2-sided lines, in visual mode it will only return the actually selected `Sidedef`.
|
||||
#### Parameters
|
||||
|
@ -338,43 +338,43 @@ Inverts the `marked` property of all `Thing`s.
|
|||
Inverts the `marked` property of all vertices.
|
||||
|
||||
---
|
||||
### joinSectors(sectors)
|
||||
### joinSectors(sectors: Sector[])
|
||||
Joins `Sector`s, keeping lines shared by the `Sector`s. All `Sector`s will be joined with the first `Sector` in the array.
|
||||
#### Parameters
|
||||
* sectors: `Array` of `Sector`s
|
||||
|
||||
---
|
||||
### markSelectedLinedefs(mark = true)
|
||||
### markSelectedLinedefs(mark: bool)
|
||||
Marks (default) or unmarks all selected `Linedef`s.
|
||||
#### Parameters
|
||||
* mark: `true` to mark all selected `Linedef`s (default), `false` to unmark
|
||||
|
||||
---
|
||||
### markSelectedSectors(mark = true)
|
||||
### markSelectedSectors(mark: bool)
|
||||
Marks (default) or unmarks all selected `Sector`s.
|
||||
#### Parameters
|
||||
* mark: `true` to mark all selected `Sector`s (default), `false` to unmark
|
||||
|
||||
---
|
||||
### markSelectedThings(mark = true)
|
||||
### markSelectedThings(mark: bool)
|
||||
Marks (default) or unmarks all selected `Thing`s.
|
||||
#### Parameters
|
||||
* mark: `true` to mark all selected `Thing`s (default), `false` to unmark
|
||||
|
||||
---
|
||||
### markSelectedVertices(mark=true)
|
||||
### markSelectedVertices(mark: bool)
|
||||
Marks (default) or unmarks all selected vertices.
|
||||
#### Parameters
|
||||
* mark: `true` to mark all selected vertices (default), `false` to unmark
|
||||
|
||||
---
|
||||
### mergeSectors(sectors)
|
||||
### mergeSectors(sectors: Sector[])
|
||||
Merges `Sector`s, deleting lines shared by the `Sector`s. All `Sector`s will be merged into the first `Sector` in the array.
|
||||
#### Parameters
|
||||
* sectors: `Array` of `Sector`s
|
||||
|
||||
---
|
||||
### nearestLinedef(pos, maxrange = double.NaN)
|
||||
### nearestLinedef(pos: object, maxrange: double)
|
||||
Gets the `Linedef` that's nearest to the specified position.
|
||||
#### Parameters
|
||||
* pos: Position to check against
|
||||
|
@ -383,7 +383,7 @@ Gets the `Linedef` that's nearest to the specified position.
|
|||
Nearest `Linedef`
|
||||
|
||||
---
|
||||
### nearestSidedef(pos)
|
||||
### nearestSidedef(pos: object)
|
||||
Gets the `Sidedef` that's nearest to the specified position.
|
||||
#### Parameters
|
||||
* pos: Position to check against
|
||||
|
@ -392,7 +392,7 @@ Gets the `Sidedef` that's nearest to the specified position.
|
|||
Nearest `Sidedef`
|
||||
|
||||
---
|
||||
### nearestThing(pos, maxrange = double.NaN)
|
||||
### nearestThing(pos: object, maxrange: double)
|
||||
Gets the `Thing` that's nearest to the specified position.
|
||||
#### Parameters
|
||||
* pos: Position to check against
|
||||
|
@ -401,7 +401,7 @@ Gets the `Thing` that's nearest to the specified position.
|
|||
Nearest `Linedef`
|
||||
|
||||
---
|
||||
### nearestVertex(pos, maxrange = double.NaN)
|
||||
### nearestVertex(pos: object, maxrange: double)
|
||||
Gets the `Vertex` that's nearest to the specified position.
|
||||
#### Parameters
|
||||
* pos: Position to check against
|
||||
|
@ -410,13 +410,13 @@ Gets the `Vertex` that's nearest to the specified position.
|
|||
Nearest `Vertex`
|
||||
|
||||
---
|
||||
### snapAllToAccuracy(usepreciseposition = true)
|
||||
### snapAllToAccuracy(usepreciseposition: bool)
|
||||
Snaps all vertices and things to the map format accuracy. Call this to ensure the vertices and things are at valid coordinates.
|
||||
#### Parameters
|
||||
* usepreciseposition: `true` if decimal places defined by the map format should be used, `false` if no decimal places should be used
|
||||
|
||||
---
|
||||
### snappedToGrid(pos)
|
||||
### snappedToGrid(pos: object)
|
||||
Returns the given point snapped to the current grid.
|
||||
#### Parameters
|
||||
* pos: Point that should be snapped to the grid
|
||||
|
@ -424,9 +424,23 @@ Returns the given point snapped to the current grid.
|
|||
Snapped position as `Vector2D`
|
||||
|
||||
---
|
||||
### stitchGeometry(mergemode = MergeGeometryMode.CLASSIC)
|
||||
### stitchGeometry(mergemode: MergeGeometryMode)
|
||||
Stitches marked geometry with non-marked geometry.
|
||||
#### Parameters
|
||||
* mergemode: Mode to merge by
|
||||
* mergemode: Mode to merge by as `MergeGeometryMode`
|
||||
#### Return value
|
||||
`true` if successful, `false` if failed
|
||||
## Enums
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### MergeGeometryMode
|
||||
How geometry should be merged when geometry is stitched.
|
||||
|
||||
```js
|
||||
UDB.Map.stitchGeometry(UDB.Map.MergeometryMode.MERGE);
|
||||
```
|
||||
#### Options
|
||||
* CLASSIC: Merge vertices only
|
||||
* MERGE: Merge vertices and lines
|
||||
* REPLACE: Merge vertices and lines, replacing sector geometry
|
||||
|
|
124
Source/Plugins/UDBScript/docs/htmldoc/docs/Plane.md
Normal file
124
Source/Plugins/UDBScript/docs/htmldoc/docs/Plane.md
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Plane
|
||||
|
||||
## Constructors
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### Plane(normal: object, offset: double)
|
||||
Creates a new `Plane` from a normal and an offset. The normal vector has to be `Vector3D`, `Array`s of 3 numbers, or an object with x, y, and z properties.
|
||||
|
||||
```js
|
||||
let plane1 = new UDB.Plane(new Vector3D(0.0, -0.707, 0.707), 32);
|
||||
let plane2 = new UDB.Plane([ 0.0, -0.707, 0.707 ], 32);
|
||||
```
|
||||
#### Parameters
|
||||
* normal: Normal vector of the plane
|
||||
* offset: Distance of the plane from the origin
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### Plane(p1: object, p2: object, p3: object, up: bool)
|
||||
Creates a new `Plane` from 3 points. The points have to be `Vector3D`, `Array`s of 3 numbers, or an object with x, y, and z properties.
|
||||
|
||||
```js
|
||||
let plane1 = new UDB.Plane(new Vector3D(0, 0, 0), new Vector3D(64, 0, 0), new Vector3D(64, 64, 32), true);
|
||||
let plane2 = new UDB.Plane([ 0, 0, 0 ], [ 64, 0, 0 ], [ 64, 64, 32 ], true);
|
||||
```
|
||||
#### Parameters
|
||||
* p1: First point
|
||||
* p2: Second point
|
||||
* p3: Thrid point
|
||||
* up: `true` if plane is pointing up, `false` if pointing down
|
||||
## Properties
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### a
|
||||
The `a` value of the plane equation. This is the `x` value of the normal vector.
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### b
|
||||
The `b` value of the plane equation. This is the `y` value of the normal vector.
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### c
|
||||
The `c` value of the plane equation. This is the `z` value of the normal vector.
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### d
|
||||
The `d` value of the plane equation. This is the same as the `offset` value.
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### normal
|
||||
The plane's normal vector.
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### offset
|
||||
The distance of the plane along the normal vector.
|
||||
## Methods
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### closestOnPlane(p: object)
|
||||
Returns the point that's closest to the given point on the `Plane`. The given point can be a `Vector3D` or an `Array` of three numbers.
|
||||
|
||||
```js
|
||||
const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true);
|
||||
UDB.log(plane.closestOnPlane([ 16, 16, 32 ])); // Prints '16, 25.6, 12.8'
|
||||
```
|
||||
#### Parameters
|
||||
* p: Point to get the closest position from
|
||||
#### Return value
|
||||
Point as `Vector3D` on the plane closest to the given point
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### distance(p: object)
|
||||
Computes the distance between the `Plane` and a point. The given point can be a `Vector3D` or an `Array` of three numbers. A result greater than 0 means the point is on the front of the plane, less than 0 means the point is behind the plane.
|
||||
|
||||
```js
|
||||
const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true);
|
||||
UDB.log(plane.distance([ 16, 16, 32 ])); // Prints '21.466252583998'
|
||||
```
|
||||
#### Parameters
|
||||
* p: Point to compute the distnace to
|
||||
#### Return value
|
||||
Distance between the `Plane` and the point as `number`
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getIntersection(from: object, to: object)
|
||||
Checks if the line between `from` and `to` intersects the plane.
|
||||
|
||||
It returns an `Array`, where the first element is a `bool` vaue indicating if there is an intersector, and the second element is the position of the intersection on the line between the two points.
|
||||
|
||||
|
||||
```js
|
||||
const plane = new UDB.Plane([ 0, 0, 1 ], 0);
|
||||
const [intersecting, u] = plane.getIntersection([0, 0, 32], [0, 0, -32]);
|
||||
UDB.log(`${intersecting} / ${u}`); // Prints "true / 0.5"
|
||||
```
|
||||
#### Parameters
|
||||
* from: `Vector3D` of the start of the line
|
||||
* to: `Vector3D` of the end of the line
|
||||
#### Return value
|
||||
*missing*
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getZ(p: object)
|
||||
Returns the position on the z axis of the plane for the given point. The given point can be a `Vector2D` or an `Array` of two numbers.
|
||||
|
||||
```js
|
||||
const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true);
|
||||
UDB.log(plane.getZ([ 16, 16 ])); // Prints '8'
|
||||
```
|
||||
#### Parameters
|
||||
* p: Point to get the z position from
|
||||
#### Return value
|
||||
*missing*
|
|
@ -26,7 +26,7 @@ Object containing all the added options as properties.
|
|||
## Methods
|
||||
|
||||
---
|
||||
### addOption(name, description, type, defaultvalue)
|
||||
### addOption(name: string, description: string, type: int, defaultvalue: object)
|
||||
Adds a parameter to query
|
||||
#### Parameters
|
||||
* name: Name of the variable that the queried value is stored in
|
||||
|
@ -35,7 +35,7 @@ Adds a parameter to query
|
|||
* defaultvalue: Default value of the parameter
|
||||
|
||||
---
|
||||
### addOption(name, description, type, defaultvalue, enumvalues)
|
||||
### addOption(name: string, description: string, type: int, defaultvalue: object, enumvalues: object)
|
||||
Adds a parameter to query
|
||||
#### Parameters
|
||||
* name: Name of the variable that the queried value is stored in
|
||||
|
|
|
@ -47,7 +47,14 @@ There are some restrictions, though:
|
|||
|
||||
* it only works for fields that are not in the base UDMF standard, since those are handled directly in the respective class
|
||||
* it does not work for flags. While they are technically also UDMF fields, they are handled in the `flags` field of the respective class (where applicable)
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation, using the `UniValue` class:
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation:
|
||||
Version 5 and later:
|
||||
You can use a `BigInt`. This is done by appending a `n` to the number. Note that this is just a convenient way to define whole numbers, it still only supports 32 bit integers:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = 25n; // Sets the 'user_myintfield' field to an integer value of 25
|
||||
```
|
||||
In version 4 and earlier you have to use the `UniValue` class:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = new UDB.UniValue(0, 25); // Sets the 'user_myintfield' field to an integer value of 25
|
||||
|
@ -112,7 +119,7 @@ The `Sector`'s tag.
|
|||
## Methods
|
||||
|
||||
---
|
||||
### addTag(tag)
|
||||
### addTag(tag: int)
|
||||
Adds a tag to the `Sector`. UDMF only. Supported game configurations only.
|
||||
#### Parameters
|
||||
* tag: Tag to add
|
||||
|
@ -124,7 +131,7 @@ Adds a tag to the `Sector`. UDMF only. Supported game configurations only.
|
|||
Clears all flags.
|
||||
|
||||
---
|
||||
### copyPropertiesTo(s)
|
||||
### copyPropertiesTo(s: Sector)
|
||||
Copies the properties from this `Sector` to another.
|
||||
#### Parameters
|
||||
* s: the `Sector` to copy the properties to
|
||||
|
@ -145,6 +152,24 @@ Gets the floor's slope vector.
|
|||
#### Return value
|
||||
The floor's slope normal as a `Vector3D`
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### getLabelPositions()
|
||||
Returns an `Array` of `Vector2D` of label positions for the `Sector`. This are the positions where for example selection number or tags are shown.
|
||||
|
||||
This example adds an imp to the label position of each sector in the map:
|
||||
|
||||
```js
|
||||
UDB.Map.getSectors().forEach(s => {
|
||||
const positions = s.getLabelPositions();
|
||||
if(positions.length > 0)
|
||||
UDB.Map.createThing(positions[0], 3001);
|
||||
});
|
||||
```
|
||||
#### Return value
|
||||
`Array` of `Vector2D` of all label positions
|
||||
|
||||
---
|
||||
### getSidedefs()
|
||||
Returns an `Array` of all `Sidedef`s of the `Sector`.
|
||||
|
@ -164,7 +189,7 @@ Gets an array of `Vector2D` arrays, representing the vertices of the triangulate
|
|||
Array of `Vector2D` arrays
|
||||
|
||||
---
|
||||
### intersect(p)
|
||||
### intersect(p: object)
|
||||
Checks if the given point is in this `Sector` or not. The given point can be a `Vector2D` or an `Array` of two numbers.
|
||||
|
||||
```js
|
||||
|
@ -180,13 +205,13 @@ if(s.intersect([ 32, 64 ]))
|
|||
`true` if the point is in the `Sector`, `false` if it isn't
|
||||
|
||||
---
|
||||
### join(other)
|
||||
### join(other: Sector)
|
||||
Joins this `Sector` with another `Sector`. Lines shared between the sectors will not be removed.
|
||||
#### Parameters
|
||||
* other: Sector to join with
|
||||
|
||||
---
|
||||
### removeTag(tag)
|
||||
### removeTag(tag: int)
|
||||
Removes a tag from the `Sector`. UDMF only. Supported game configurations only.
|
||||
#### Parameters
|
||||
* tag: Tag to remove
|
||||
|
@ -194,13 +219,13 @@ Removes a tag from the `Sector`. UDMF only. Supported game configurations only.
|
|||
`true` when the tag was removed successfully, `false` when the tag did not exist
|
||||
|
||||
---
|
||||
### setCeilingSlope(normal)
|
||||
### setCeilingSlope(normal: object)
|
||||
Sets the ceiling's slope vector. The vector has to be normalized.
|
||||
#### Parameters
|
||||
* normal: The new slope vector as `Vector3D`
|
||||
|
||||
---
|
||||
### setFloorSlope(normal)
|
||||
### setFloorSlope(normal: object)
|
||||
Sets the floor's slope vector. The vector has to be normalized.
|
||||
#### Parameters
|
||||
* normal: The new slope vector as `Vector3D`
|
||||
|
|
|
@ -29,7 +29,14 @@ There are some restrictions, though:
|
|||
|
||||
* it only works for fields that are not in the base UDMF standard, since those are handled directly in the respective class
|
||||
* it does not work for flags. While they are technically also UDMF fields, they are handled in the `flags` field of the respective class (where applicable)
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation, using the `UniValue` class:
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation:
|
||||
Version 5 and later:
|
||||
You can use a `BigInt`. This is done by appending a `n` to the number. Note that this is just a convenient way to define whole numbers, it still only supports 32 bit integers:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = 25n; // Sets the 'user_myintfield' field to an integer value of 25
|
||||
```
|
||||
In version 4 and earlier you have to use the `UniValue` class:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = new UDB.UniValue(0, 25); // Sets the 'user_myintfield' field to an integer value of 25
|
||||
|
|
|
@ -37,7 +37,14 @@ There are some restrictions, though:
|
|||
|
||||
* it only works for fields that are not in the base UDMF standard, since those are handled directly in the respective class
|
||||
* it does not work for flags. While they are technically also UDMF fields, they are handled in the `flags` field of the respective class (where applicable)
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation, using the `UniValue` class:
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation:
|
||||
Version 5 and later:
|
||||
You can use a `BigInt`. This is done by appending a `n` to the number. Note that this is just a convenient way to define whole numbers, it still only supports 32 bit integers:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = 25n; // Sets the 'user_myintfield' field to an integer value of 25
|
||||
```
|
||||
In version 4 and earlier you have to use the `UniValue` class:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = new UDB.UniValue(0, 25); // Sets the 'user_myintfield' field to an integer value of 25
|
||||
|
@ -115,7 +122,7 @@ Type of the `Thing`.
|
|||
Clears all flags.
|
||||
|
||||
---
|
||||
### copyPropertiesTo(t)
|
||||
### copyPropertiesTo(t: Thing)
|
||||
Copies the properties from this `Thing` to another.
|
||||
#### Parameters
|
||||
* t: The `Thing` to copy the properties to
|
||||
|
@ -125,7 +132,7 @@ Copies the properties from this `Thing` to another.
|
|||
Deletes the `Thing`.
|
||||
|
||||
---
|
||||
### distanceTo(pos)
|
||||
### distanceTo(pos: object)
|
||||
Gets the distance between this `Thing` and the given point. The point can be either a `Vector2D` or an array of numbers.
|
||||
|
||||
```js
|
||||
|
@ -138,7 +145,7 @@ t.distanceToSq([ 32, 64 ]);
|
|||
Distance to `pos`
|
||||
|
||||
---
|
||||
### distanceToSq(pos)
|
||||
### distanceToSq(pos: object)
|
||||
Gets the squared distance between this `Thing` and the given point.
|
||||
The point can be either a `Vector2D` or an array of numbers.
|
||||
|
||||
|
|
|
@ -10,6 +10,11 @@ Class containing methods related to angles. See [Angle2D](Angle2D.md) for more i
|
|||
let rad = UDB.Angle2D.degToRad(46);
|
||||
```
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### BlockMap
|
||||
Instantiable class that contains methods related to blockmaps. See [BlockMap][BlockMap.md) for more information.
|
||||
|
||||
---
|
||||
### Data
|
||||
Class containing methods related to the game data. See [Data](Data.md) for more information.
|
||||
|
@ -38,6 +43,11 @@ Object containing methods related to the map. See [Map](Map.md) for more informa
|
|||
let sectors = UDB.Map.getSelectedOrHighlightedSectors();
|
||||
```
|
||||
|
||||
---
|
||||
<span style="float:right;font-weight:normal;font-size:66%">Version: 5</span>
|
||||
### Plane
|
||||
Instantiable class that contains methods related to a three-dimensional Plane. See [Plane](Plane.md) for more information.
|
||||
|
||||
---
|
||||
### QueryOptions
|
||||
Class containing methods and properties related to querying options from the user at runtime. See [QueryOptions](QueryOptions.md) for more information.
|
||||
|
@ -65,40 +75,44 @@ let v = new UDB.Vector2D(32, 64);
|
|||
---
|
||||
### Vector3D
|
||||
Instantiable class that contains methods related to three-dimensional vectors. See [Vector3D](Vector3D.md) for more information.
|
||||
|
||||
```js
|
||||
let v = new UDB.Vector3D(32, 64, 128);
|
||||
```
|
||||
## Methods
|
||||
|
||||
---
|
||||
### die(s=null)
|
||||
### die(s: string)
|
||||
Exist the script prematurely with undoing its changes.
|
||||
#### Parameters
|
||||
* s: Text to show in the status bar (optional)
|
||||
|
||||
---
|
||||
### exit(s=null)
|
||||
### exit(s: string)
|
||||
Exist the script prematurely without undoing its changes.
|
||||
#### Parameters
|
||||
* s: Text to show in the status bar (optional)
|
||||
|
||||
---
|
||||
### log(text)
|
||||
### log(text: object)
|
||||
Adds a line to the script log. Also shows the script running dialog.
|
||||
#### Parameters
|
||||
* text: Line to add to the script log
|
||||
|
||||
---
|
||||
### setProgress(value)
|
||||
### setProgress(value: int)
|
||||
Set the progress of the script in percent. Value can be between 0 and 100. Also shows the script running dialog.
|
||||
#### Parameters
|
||||
* value: Number between 0 and 100
|
||||
|
||||
---
|
||||
### showMessage(message)
|
||||
### showMessage(message: object)
|
||||
Shows a message box with an "OK" button.
|
||||
#### Parameters
|
||||
* message: Message to show
|
||||
|
||||
---
|
||||
### showMessageYesNo(message)
|
||||
### showMessageYesNo(message: object)
|
||||
Shows a message box with an "Yes" and "No" button.
|
||||
#### Parameters
|
||||
* message: Message to show
|
||||
|
|
|
@ -3,17 +3,7 @@
|
|||
## Constructors
|
||||
|
||||
---
|
||||
### Vector2D(v)
|
||||
Creates a new `Vector2D` from a point.
|
||||
|
||||
```js
|
||||
let v = new UDB.Vector2D([ 32, 64 ]);
|
||||
```
|
||||
#### Parameters
|
||||
* v: The vector to create the `Vector2D` from
|
||||
|
||||
---
|
||||
### Vector2D(x, y)
|
||||
### Vector2D(x: double, y: double)
|
||||
Creates a new `Vector2D` from x and y coordinates
|
||||
|
||||
```js
|
||||
|
@ -22,10 +12,20 @@ let v = new UDB.Vector2D(32, 64);
|
|||
#### Parameters
|
||||
* x: The x coordinate
|
||||
* y: The y coordinate
|
||||
|
||||
---
|
||||
### Vector2D(v: object)
|
||||
Creates a new `Vector2D` from a point.
|
||||
|
||||
```js
|
||||
let v = new UDB.Vector2D([ 32, 64 ]);
|
||||
```
|
||||
#### Parameters
|
||||
* v: The vector to create the `Vector2D` from
|
||||
## Static methods
|
||||
|
||||
---
|
||||
### crossProduct(a, b)
|
||||
### crossProduct(a: object, b: object)
|
||||
Returns the cross product of two `Vector2D`s.
|
||||
#### Parameters
|
||||
* a: First `Vector2D`
|
||||
|
@ -34,7 +34,7 @@ Returns the cross product of two `Vector2D`s.
|
|||
Cross product of the two vectors as `Vector2D`
|
||||
|
||||
---
|
||||
### dotProduct(a, b)
|
||||
### dotProduct(a: Vector2D, b: Vector2D)
|
||||
Returns the dot product of two `Vector2D`s.
|
||||
#### Parameters
|
||||
* a: First `Vector2D`
|
||||
|
@ -43,7 +43,7 @@ Returns the dot product of two `Vector2D`s.
|
|||
The dot product of the two vectors
|
||||
|
||||
---
|
||||
### fromAngle(angle)
|
||||
### fromAngle(angle: double)
|
||||
Creates a `Vector2D` from an angle in degrees,
|
||||
#### Parameters
|
||||
* angle: Angle in degrees
|
||||
|
@ -51,7 +51,7 @@ Creates a `Vector2D` from an angle in degrees,
|
|||
Vector as `Vector2D`
|
||||
|
||||
---
|
||||
### fromAngleRad(angle)
|
||||
### fromAngleRad(angle: double)
|
||||
Creates a `Vector2D` from an angle in radians,
|
||||
#### Parameters
|
||||
* angle: Angle in radians
|
||||
|
@ -59,7 +59,7 @@ Creates a `Vector2D` from an angle in radians,
|
|||
Vector as `Vector2D`
|
||||
|
||||
---
|
||||
### getAngle(a, b)
|
||||
### getAngle(a: object, b: object)
|
||||
Returns the angle between two `Vector2D`s in degrees.
|
||||
#### Parameters
|
||||
* a: First `Vector2D`
|
||||
|
@ -68,7 +68,7 @@ Returns the angle between two `Vector2D`s in degrees.
|
|||
Angle in degrees
|
||||
|
||||
---
|
||||
### getAngleRad(a, b)
|
||||
### getAngleRad(a: object, b: object)
|
||||
Returns the angle between two `Vector2D`s in radians
|
||||
#### Parameters
|
||||
* a: First `Vector2D`
|
||||
|
@ -77,7 +77,7 @@ Returns the angle between two `Vector2D`s in radians
|
|||
Angle in radians
|
||||
|
||||
---
|
||||
### getDistance(a, b)
|
||||
### getDistance(a: object, b: object)
|
||||
Returns the distance between two `Vector2D`s.
|
||||
#### Parameters
|
||||
* a: First `Vector2D`
|
||||
|
@ -86,7 +86,7 @@ Returns the distance between two `Vector2D`s.
|
|||
The distance
|
||||
|
||||
---
|
||||
### getDistanceSq(a, b)
|
||||
### getDistanceSq(a: object, b: object)
|
||||
Returns the square distance between two `Vector2D`s.
|
||||
#### Parameters
|
||||
* a: First `Vector2D`
|
||||
|
@ -95,7 +95,7 @@ Returns the square distance between two `Vector2D`s.
|
|||
The squared distance
|
||||
|
||||
---
|
||||
### reflect(v, m)
|
||||
### reflect(v: object, m: object)
|
||||
Reflects a `Vector2D` over a mirror `Vector2D`.
|
||||
#### Parameters
|
||||
* v: `Vector2D` to reflect
|
||||
|
@ -104,7 +104,7 @@ Reflects a `Vector2D` over a mirror `Vector2D`.
|
|||
The reflected vector as `Vector2D`
|
||||
|
||||
---
|
||||
### reversed(v)
|
||||
### reversed(v: object)
|
||||
Returns a reversed `Vector2D`.
|
||||
#### Parameters
|
||||
* v: `Vector2D` to reverse
|
||||
|
@ -134,7 +134,7 @@ Returns the angle of the `Vector2D` in radians.
|
|||
The angle of the `Vector2D` in radians
|
||||
|
||||
---
|
||||
### getInverseTransformed(invoffsetx, invoffsety, invscalex, invscaley)
|
||||
### getInverseTransformed(invoffsetx: double, invoffsety: double, invscalex: double, invscaley: double)
|
||||
Returns the inverse transformed vector as `Vector2D`.
|
||||
#### Parameters
|
||||
* invoffsetx: X offset
|
||||
|
@ -169,7 +169,7 @@ Returns the perpendicular to the `Vector2D`.
|
|||
The perpendicular as `Vector2D`
|
||||
|
||||
---
|
||||
### getRotated(theta)
|
||||
### getRotated(theta: double)
|
||||
Returns the rotated vector as `Vector2D`.
|
||||
#### Parameters
|
||||
* theta: Angle in degree to rotate by
|
||||
|
@ -177,7 +177,7 @@ Returns the rotated vector as `Vector2D`.
|
|||
The rotated `Vector2D`
|
||||
|
||||
---
|
||||
### getRotatedRad(theta)
|
||||
### getRotatedRad(theta: double)
|
||||
Returns the rotated vector as `Vector2D`.
|
||||
#### Parameters
|
||||
* theta: Angle in radians to rotate by
|
||||
|
@ -191,7 +191,7 @@ Returns a `Vector2D` with the sign of all components.
|
|||
A `Vector2D` with the sign of all components
|
||||
|
||||
---
|
||||
### getTransformed(offsetx, offsety, scalex, scaley)
|
||||
### getTransformed(offsetx: double, offsety: double, scalex: double, scaley: double)
|
||||
Returns the transformed vector as `Vector2D`.
|
||||
#### Parameters
|
||||
* offsetx: X offset
|
||||
|
|
|
@ -3,17 +3,7 @@
|
|||
## Constructors
|
||||
|
||||
---
|
||||
### Vector3D(v)
|
||||
Creates a new `Vector3D` from a point.
|
||||
|
||||
```js
|
||||
let v = new UDB.Vector3D([ 32, 64, 128 ]);
|
||||
```
|
||||
#### Parameters
|
||||
* v: The vector to create the `Vector3D` from
|
||||
|
||||
---
|
||||
### Vector3D(x, y, z)
|
||||
### Vector3D(x: double, y: double, z: double)
|
||||
Creates a new `Vector3D` from x and y coordinates
|
||||
|
||||
```js
|
||||
|
@ -23,10 +13,20 @@ let v = new UDB.Vector3D(32, 64, 128);
|
|||
* x: The x coordinate
|
||||
* y: The y coordinate
|
||||
* z: The z coordinate
|
||||
|
||||
---
|
||||
### Vector3D(v: object)
|
||||
Creates a new `Vector3D` from a point.
|
||||
|
||||
```js
|
||||
let v = new UDB.Vector3D([ 32, 64, 128 ]);
|
||||
```
|
||||
#### Parameters
|
||||
* v: The vector to create the `Vector3D` from
|
||||
## Static methods
|
||||
|
||||
---
|
||||
### crossProduct(a, b)
|
||||
### crossProduct(a: object, b: object)
|
||||
Returns the cross product of two `Vector3D`s.
|
||||
#### Parameters
|
||||
* a: First `Vector3D`
|
||||
|
@ -35,7 +35,7 @@ Returns the cross product of two `Vector3D`s.
|
|||
Cross product of the two vectors as `Vector3D`
|
||||
|
||||
---
|
||||
### dotProduct(a, b)
|
||||
### dotProduct(a: Vector3D, b: Vector3D)
|
||||
Returns the dot product of two `Vector3D`s.
|
||||
#### Parameters
|
||||
* a: First `Vector3D`
|
||||
|
@ -44,7 +44,7 @@ Returns the dot product of two `Vector3D`s.
|
|||
The dot product of the two vectors
|
||||
|
||||
---
|
||||
### fromAngleXY(angle)
|
||||
### fromAngleXY(angle: double)
|
||||
Creates a `Vector3D` from an angle in radians,
|
||||
#### Parameters
|
||||
* angle: Angle on the x/y axes in degrees
|
||||
|
@ -52,7 +52,7 @@ Creates a `Vector3D` from an angle in radians,
|
|||
Vector as `Vector3D`
|
||||
|
||||
---
|
||||
### fromAngleXYRad(angle)
|
||||
### fromAngleXYRad(angle: double)
|
||||
Creates a `Vector3D` from an angle in radians
|
||||
#### Parameters
|
||||
* angle: Angle on the x/y axes in radians
|
||||
|
@ -60,7 +60,7 @@ Creates a `Vector3D` from an angle in radians
|
|||
Vector as `Vector3D`
|
||||
|
||||
---
|
||||
### fromAngleXYZ(anglexy, anglez)
|
||||
### fromAngleXYZ(anglexy: double, anglez: double)
|
||||
Creates a `Vector3D` from two angles in degrees
|
||||
#### Parameters
|
||||
* anglexy: Angle on the x/y axes in radians
|
||||
|
@ -69,7 +69,7 @@ Creates a `Vector3D` from two angles in degrees
|
|||
Vector as `Vector3D`
|
||||
|
||||
---
|
||||
### fromAngleXYZRad(anglexy, anglez)
|
||||
### fromAngleXYZRad(anglexy: double, anglez: double)
|
||||
Creates a `Vector3D` from two angles in radians
|
||||
#### Parameters
|
||||
* anglexy: Angle on the x/y axes in radians
|
||||
|
@ -78,7 +78,7 @@ Creates a `Vector3D` from two angles in radians
|
|||
Vector as `Vector3D`
|
||||
|
||||
---
|
||||
### reflect(v, m)
|
||||
### reflect(v: object, m: object)
|
||||
Reflects a `Vector3D` over a mirror `Vector3D`.
|
||||
#### Parameters
|
||||
* v: `Vector3D` to reflect
|
||||
|
@ -87,7 +87,7 @@ Reflects a `Vector3D` over a mirror `Vector3D`.
|
|||
The reflected vector as `Vector3D`
|
||||
|
||||
---
|
||||
### reversed(v)
|
||||
### reversed(v: object)
|
||||
Returns a reversed `Vector3D`.
|
||||
#### Parameters
|
||||
* v: `Vector3D` to reverse
|
||||
|
@ -151,7 +151,7 @@ Returns the normal of the `Vector3D`.
|
|||
The normal as `Vector3D`
|
||||
|
||||
---
|
||||
### getScaled(scale)
|
||||
### getScaled(scale: double)
|
||||
Return the scaled `Vector3D`.
|
||||
#### Parameters
|
||||
* scale: Scale, where 1.0 is unscaled
|
||||
|
|
|
@ -25,7 +25,14 @@ There are some restrictions, though:
|
|||
|
||||
* it only works for fields that are not in the base UDMF standard, since those are handled directly in the respective class
|
||||
* it does not work for flags. While they are technically also UDMF fields, they are handled in the `flags` field of the respective class (where applicable)
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation, using the `UniValue` class:
|
||||
* JavaScript does not distinguish between integer and floating point numbers, it only has floating point numbers (of double precision). For fields where UDB knows that they are integers this it not a problem, since it'll automatically convert the floating point numbers to integers (dropping the fractional part). However, if you need to specify an integer value for an unknown or custom field you have to work around this limitation:
|
||||
Version 5 and later:
|
||||
You can use a `BigInt`. This is done by appending a `n` to the number. Note that this is just a convenient way to define whole numbers, it still only supports 32 bit integers:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = 25n; // Sets the 'user_myintfield' field to an integer value of 25
|
||||
```
|
||||
In version 4 and earlier you have to use the `UniValue` class:
|
||||
|
||||
```js
|
||||
s.fields.user_myintfield = new UDB.UniValue(0, 25); // Sets the 'user_myintfield' field to an integer value of 25
|
||||
|
@ -70,7 +77,7 @@ If the `Vertex` is selected or not.
|
|||
## Methods
|
||||
|
||||
---
|
||||
### copyPropertiesTo(v)
|
||||
### copyPropertiesTo(v: Vertex)
|
||||
Copies the properties from this `Vertex` to another.
|
||||
#### Parameters
|
||||
* v: the vertex to copy the properties to
|
||||
|
@ -80,7 +87,7 @@ Copies the properties from this `Vertex` to another.
|
|||
Deletes the `Vertex`. Note that this can result in unclosed sectors.
|
||||
|
||||
---
|
||||
### distanceTo(pos)
|
||||
### distanceTo(pos: object)
|
||||
Gets the distance between this `Vertex` and the given point.
|
||||
The point can be either a `Vector2D` or an array of numbers.
|
||||
|
||||
|
@ -94,7 +101,7 @@ v.distanceTo([ 32, 64 ]);
|
|||
Distance to `pos`
|
||||
|
||||
---
|
||||
### distanceToSq(pos)
|
||||
### distanceToSq(pos: object)
|
||||
Gets the squared distance between this `Vertex` and the given point.
|
||||
The point can be either a `Vector2D` or an array of numbers.
|
||||
|
||||
|
@ -114,13 +121,13 @@ Gets all `Linedefs` that are connected to this `Vertex`.
|
|||
Array of linedefs
|
||||
|
||||
---
|
||||
### join(other)
|
||||
### join(other: Vertex)
|
||||
Joins this `Vertex` with another `Vertex`, deleting this `Vertex` and keeping the other.
|
||||
#### Parameters
|
||||
* other: `Vertex` to join with
|
||||
|
||||
---
|
||||
### nearestLinedef(pos)
|
||||
### nearestLinedef(pos: object)
|
||||
Returns the `Linedef` that is connected to this `Vertex` that is closest to the given point.
|
||||
#### Parameters
|
||||
* pos: Point to get the nearest `Linedef` connected to this `Vertex` from
|
||||
|
|
|
@ -1,23 +1,32 @@
|
|||
# Changes
|
||||
This site lists all changes between different API version of UDBScript
|
||||
|
||||
## Verstion 4
|
||||
## Version 5
|
||||
|
||||
- Added `Plane` class
|
||||
- Added `BlockMap`, `BlockEntry`, and `BlackMapQueryResult` classes
|
||||
- `Sector` class
|
||||
- Added `getLabelPositions` method to get the position of sector labels (where tags, effects etc. are displayed)
|
||||
- Added support for JavaScript BigInt for UDMF fields. This means it's not necessary anymore to use `UniValue` to assign integers to new UDMF fields. Instead it can be done like this: `sector.fields.my_int_field = 1n;`
|
||||
- Added type information file (udbscript.d.ts)
|
||||
|
||||
## Version 4
|
||||
|
||||
- Moved all classes, object, and methods into the `UDB` namespace (everything has to be prefixed wiht `UDB.`)
|
||||
- Added methods to report progress for long running scripts and script log output. See [Communicating with the user](gettingstartet.md#communicating-with-the-user) for more information
|
||||
- Added methods to report progress for long running scripts and script log output. See [Communicating with the user](gettingstarted.md#communicating-with-the-user) for more information
|
||||
|
||||
## Version 3
|
||||
|
||||
- Exported the classes `Linedef`, `Sector`, `Sidedef`, `Thing`, and `Vertex`, so that they can be used with `instanceof`
|
||||
- `Map` class
|
||||
- the `getSidedefsFromSelectedLinedefs()` method now correctly only returns the `Sidedef`s of selected `Linedef`s in visual mode (and not also the highlighted one)
|
||||
- added a new `getSidedefsFromSelectedOrHighlightedLinedefs()` method as the equivalent to the other `getSelectedOrHighlighted*()` methods
|
||||
- The `getSidedefsFromSelectedLinedefs()` method now correctly only returns the `Sidedef`s of selected `Linedef`s in visual mode (and not also the highlighted one)
|
||||
- Added a new `getSidedefsFromSelectedOrHighlightedLinedefs()` method as the equivalent to the other `getSelectedOrHighlighted*()` methods
|
||||
- `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
|
||||
- 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
|
||||
- `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
|
||||
- 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
|
||||
|
||||
## Version 2
|
||||
|
||||
- `Pen` built-in library
|
||||
- the methods of the `Pen` class now return the instance of the Pen class to allow method chaining
|
||||
- The methods of the `Pen` class now return the instance of the Pen class to allow method chaining
|
|
@ -58,6 +58,19 @@ You can open a context menu for each script by right-clicking on it. In the cont
|
|||
|
||||
## Writing scripts
|
||||
|
||||
### Type information file (udbscript.d.ts)
|
||||
|
||||
UDBScript comes with a type information called `udbscript.d.ts` located in the `UDBScript` directory in the UDB installation directory. This file contains information about the available classes, methods, and their parameters. This makes writing scripts more comfortable if you are using an text editor that can interpret this file, such as Visual Studio Code.
|
||||
|
||||
To use the file it has to be referenced at the very top of the script file:
|
||||
```js
|
||||
/// <reference path="../udbscript.d.ts" />
|
||||
```
|
||||
Depending on where your script is located you have to change the path to the file.
|
||||
|
||||
!!! attention
|
||||
`.d.ts` files are originally for the TypeScript programming language, which is a superset of JavaScript. UDBScript does *not* support TypeScript, it merely provides a definition file to make writing scripts easier.
|
||||
|
||||
### Script metadata
|
||||
|
||||
Scripts can contain metadata at the top of the file to provide information about the script as well as available script options. The metadata is specified as JavaScript template strings, i.e. strings enclosed by backticks (`` ` ``). The template string has to start with a `#`, followed by a command, followed by the payload, followed by a `;`.
|
||||
|
|
|
@ -8,12 +8,16 @@
|
|||
## API
|
||||
|
||||
- [Angle2D](Angle2D.md)
|
||||
- [BlockEntry](BlockEntry.md)
|
||||
- [BlockMap](BlockMap.md)
|
||||
- [BlockMapQueryResult](BlockMapQueryResult.md)
|
||||
- [Data](Data.md)
|
||||
- [GameConfiguration](GameConfiguration.md)
|
||||
- [ImageInfo](ImageInfo.md)
|
||||
- [Line2D](Line2D.md)
|
||||
- [Linedef](Linedef.md)
|
||||
- [Map](Map.md)
|
||||
- [Plane](Plane.md)
|
||||
- [QueryOptions](QueryOptions.md)
|
||||
- [Sector](Sector.md)
|
||||
- [Sidedef](Sidedef.md)
|
||||
|
|
|
@ -10,12 +10,16 @@ nav:
|
|||
- 'Changes': 'changes.md'
|
||||
- 'API':
|
||||
- Angle2D: 'Angle2D.md'
|
||||
- BlockEntry: 'BlockEntry.md'
|
||||
- BlockMap: 'BlockMap.md'
|
||||
- BlockMapQueryResult: 'BlockMapQueryResult.md'
|
||||
- Data: 'Data.md'
|
||||
- GameConfiguration: 'GameConfiguration.md'
|
||||
- ImageInfo: 'ImageInfo.md'
|
||||
- Line2D: 'Line2D.md'
|
||||
- Linedef: 'Linedef.md'
|
||||
- Map: 'Map.md'
|
||||
- Plane: 'Plane.md'
|
||||
- QueryOptions: 'QueryOptions.md'
|
||||
- Sector: 'Sector.md'
|
||||
- Sidedef: 'Sidedef.md'
|
||||
|
|
|
@ -1,258 +0,0 @@
|
|||
# UDB Scripting
|
||||
## Introduction
|
||||
Scripting is one of the big features UDB is missing. This branch is trying to rectify this.
|
||||
|
||||
It uses the [Jint](https://github.com/sebastienros/jint) interpreter to let the users execute their own JavaScript (ECMAScript 5.1, with some 6.0 features) scripts in the editor.
|
||||
Since it exposes the whole UDB API (including those of the loaded plugins) to the scripting engine, much of what required a dedicated plugin can now be done with scripts.
|
||||
|
||||
## How it works
|
||||
### Directory structure
|
||||
Scripts are automatically found if they are placed in the correct directory structure. The directory structure is in the UDB installation folder and looks like this:
|
||||
|
||||
```
|
||||
.\UDBScript\
|
||||
.\UDBScript\Libraries\
|
||||
.\UDBScript\Scripts\
|
||||
```
|
||||
|
||||
All files ending on .js in the Libraries directory are loaded (parsed and executed) every time a script is run. It is used to provide common functionality to multiple script. Currently there's the Pen.js library file that simplifies drawing geometry (it's inspired by the DBX Lua Pen class).
|
||||
|
||||
All files ending on .js in the Scripts directory (and its subdirectories) are added to the Scripts docker. They are only run on the user's command. Scripts can optionally have a configuration file with the same name, just ending on .cfg.
|
||||
|
||||
### Script configuration files
|
||||
|
||||
The optional script configuration files can be used to let the user set script options before running the script. The configuration files look like this:
|
||||
|
||||
```
|
||||
name = "Draw Voodoo Doll Closet";
|
||||
|
||||
options
|
||||
{
|
||||
length
|
||||
{
|
||||
description = "Length of closet";
|
||||
default = 256;
|
||||
type = 0; // Integer
|
||||
}
|
||||
|
||||
direction
|
||||
{
|
||||
description = "Direction of closet";
|
||||
default = "North";
|
||||
type = 11; // Enum
|
||||
enumvalues {
|
||||
0 = "North";
|
||||
1 = "East";
|
||||
2 = "South";
|
||||
3 = "West";
|
||||
}
|
||||
}
|
||||
|
||||
inactive
|
||||
{
|
||||
description = "Start inactive";
|
||||
default = "True";
|
||||
type = 3; // Boolean
|
||||
}
|
||||
|
||||
looping
|
||||
{
|
||||
description = "Looping";
|
||||
default = "False";
|
||||
type = 3; // Boolean
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### The docker
|
||||
|
||||
![The docker](docker.png)
|
||||
|
||||
|
||||
## Known issues and quirks
|
||||
|
||||
### Exposing Assemblies also exposes the System namespace
|
||||
Scripts have access to the whole CLR, including Syste.IO and System.Net. [This is intentional behavior in Jint](https://github.com/sebastienros/jint/issues/222). This isn't a problem per se, since plugins could do the same. It'd be nice to blacklist certain namespaces, though, which isn't possible.
|
||||
|
||||
It *is* possible to remove the System namespace retroactively on the C# side:
|
||||
|
||||
```cs
|
||||
engine.Global.RemoveOwnProperty("System");
|
||||
```
|
||||
|
||||
This, however, it's really feasible, since parts of the namespace (for example System.Collection.Generic) are required for certain things to work, for example Tool.DrawLines takes an IList as an argument, passing an array from a script to it does not work.
|
||||
|
||||
### Setting array values doesn't work
|
||||
This is a [known issue in Jint that won't be changed](https://github.com/sebastienros/jint/issues/776). This means that it's not possible to set a thing's or linedef's arguments by accessing the Args property:
|
||||
|
||||
```js
|
||||
var t = UDB.General.Map.Map.CreateThing();
|
||||
t.Args[0] = 123; // Won't work, it'll stay at 0
|
||||
```
|
||||
A workaround would be to implement a setter method the the args on the C# side:
|
||||
|
||||
```cs
|
||||
public void SetArg(int num, int val)
|
||||
{
|
||||
if(num >= 0 && num < args.Length)
|
||||
args[num] = val;
|
||||
}
|
||||
```
|
||||
|
||||
The downside is that this setter is likely to stay, even if the issue gets fixed in Jint (which seems unlikely), since simply removing it will break scripts that use it. It could be tried to later deprecate it, with spilling out error messages telling the user to update their scripts.
|
||||
|
||||
Another options is to replace the `args` array with an class that acts like an array, like this:
|
||||
|
||||
```cs
|
||||
public sealed class MapElementArguments : IEnumerable<int>
|
||||
{
|
||||
private int[] data;
|
||||
|
||||
public MapElementArguments(int numargs)
|
||||
{
|
||||
data = new int[numargs];
|
||||
}
|
||||
|
||||
public MapElementArguments(int numargs, IEnumerable<int> newdata) : this(numargs)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
foreach(int d in newdata)
|
||||
{
|
||||
if (i < numargs)
|
||||
data[i] = d;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public int this[int i]
|
||||
{
|
||||
get { return data[i]; }
|
||||
set { data[i] = value; }
|
||||
}
|
||||
|
||||
public int Length { get { return data.Length; } }
|
||||
|
||||
public IEnumerator<int> GetEnumerator()
|
||||
{
|
||||
foreach(int i in data)
|
||||
yield return i;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public MapElementArguments Clone()
|
||||
{
|
||||
return new MapElementArguments(data.Length, data);
|
||||
}
|
||||
}
|
||||
```
|
||||
This works mostly transparent, with few changes to the rest of the code.
|
||||
|
||||
### ECMAScript Array can't be passed to methods that take List<> as a parameter
|
||||
The good news is that you can create instances of List<> objects. It's rather unwieldy, though. To get the equivalent to C#
|
||||
|
||||
```cs
|
||||
List<Linedef> linedefs = new List<Linedef>();
|
||||
```
|
||||
|
||||
in the script you have to write
|
||||
|
||||
```js
|
||||
var linedefs = new (System.Collections.Generic.List(UDB.Map.Linedef))();
|
||||
```
|
||||
|
||||
A helper function could be created, for example
|
||||
|
||||
```js
|
||||
function MakeList(cls)
|
||||
{
|
||||
return new (System.Collections.Generic.List(cls))();
|
||||
}
|
||||
|
||||
var linedefs = MakeList(UDB.Map.Linedef);
|
||||
```
|
||||
|
||||
Another options would be to add a library that extends the Array prototype like this:
|
||||
|
||||
```js
|
||||
Array.prototype.ToList = function(cls)
|
||||
{
|
||||
var list = new (System.Collections.Generic.List(cls))();
|
||||
|
||||
this.forEach(e => {
|
||||
list.Add(e);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
```
|
||||
|
||||
which could then be called liks this:
|
||||
|
||||
```js
|
||||
var myarray = [];
|
||||
|
||||
UDB.General.Map.Map.Things.forEach(t => { myarray.push(t); });
|
||||
|
||||
var mylist = myarray.ToList(UDB.Map.Thing);
|
||||
```
|
||||
|
||||
|
||||
### Iterating over LinkedList
|
||||
It's cumbersome. It's not possible to use neat methods like `forEach` or `filter` on them. You have to iterate over them using their `First` and `Next` properties. I don't think they are used widely, it mostly seems to affects the `Sidedefs` property of the `Sector` class, and the `Linedefs` property of the `Vertex` class.
|
||||
|
||||
Ways to iterate over `LinkedList`:
|
||||
|
||||
```js
|
||||
function LinkedListToArray(linkedlist)
|
||||
{
|
||||
var array = [];
|
||||
|
||||
for(var it=linkedlist.First; it != null; it = it.Next)
|
||||
array.push(it.Value);
|
||||
|
||||
return array;
|
||||
}
|
||||
```
|
||||
or
|
||||
```js
|
||||
function LinkedListToArray(linkedlist)
|
||||
{
|
||||
var array = [];
|
||||
|
||||
var enumerator = linkedlist.GetEnumerator();
|
||||
|
||||
while(enumerator.MoveNext())
|
||||
array.push(enumerator.Current);
|
||||
|
||||
return array;
|
||||
}
|
||||
```
|
||||
|
||||
### ECMAScript doesn't have operator overloading
|
||||
This is only a minor nuisance. An example where this comes into play is when working with Vector2D or Vector3D. Doing basic math operations like addition or multiplication on them doesn't work, instead a new instance has to be created with the desired values:
|
||||
|
||||
```js
|
||||
var Vector2D = UDB.Geometry.Vector2D;
|
||||
|
||||
var v1 = new Vector2D(1, 1);
|
||||
var v2 = new Vector2D(2, 2);
|
||||
|
||||
var v3 = v1 + v2; // Doesn't work, results in v3 being the string "1, 12, 2"
|
||||
|
||||
var v4 = new Vector2D(v1.x + v2.x, v1.y + v2.y); // You have to do this
|
||||
```
|
||||
|
||||
### Lack of documentation
|
||||
There's no API documentation. Since the scripts directly access the UDB API doing an documentation seems futile. It's probably a better idea to go through the source files that are most relevant for scripting, add triple-slash-comments where needed and automatically generate a documentation with something like [DocFX](https://dotnet.github.io/docfx/). Having a FAQ and well-commented example scripts would also help.
|
||||
|
||||
## Possible future improvements
|
||||
- Update the script file tree when files are added to the directory structure at runtime
|
||||
- Add option to open the script file and configuration file in an external editor through the context menu
|
||||
- Add option to set favorite scripts
|
||||
- Add multiple actions to run user-defined scripts
|
|
@ -1,18 +0,0 @@
|
|||
# What's still missing
|
||||
## Wrappers
|
||||
- `Line3D` wrapper
|
||||
|
||||
## Interop
|
||||
- Make (parts of) game configuration (for example ThingTypeInfo) available?
|
||||
|
||||
## Map elements
|
||||
- is the current implementation for thing and linedef action arguments OK?
|
||||
|
||||
## UI
|
||||
- add favorite script functionality (in the UI and with hotkeys)
|
||||
- add "quick script" function to write and run one-shot scripts in UDB without having to create files
|
||||
|
||||
## Other
|
||||
- remove the `Wrapper` part from the wrapper class names?
|
||||
- some way to get information about the current editing mode (name, ...)
|
||||
- radians vs degrees?
|
Loading…
Reference in a new issue