UltimateZoneBuilder/Source/Plugins/UDBScript/API/UDBWrapper.cs
biwa 5b2b149b40
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)
2022-11-13 01:15:17 +01:00

368 lines
9.5 KiB
C#

#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.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Jint;
using Jint.Runtime.Interop;
#endregion
namespace CodeImp.DoomBuilder.UDBScript.Wrapper
{
internal class UDBWrapper
{
#region ================== Variables
private GameConfigurationWrapper gameconfiguration;
private TypeReference queryoptions;
private ExpandoObject scriptoptions;
private Angle2DWrapper angle2d;
private DataWrapper data;
private TypeReference line2d;
private MapWrapper map;
private TypeReference univalue;
private TypeReference vector2d;
private TypeReference vector3d;
private TypeReference linedef;
private TypeReference sector;
private TypeReference sidedef;
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;
#endregion
#region ================== Properties
/// <summary>
/// Class containing methods related to the game configuration. See [GameConfiguration](GameConfiguration.md) for more information.
/// </summary>
public GameConfigurationWrapper GameConfiguration
{
get
{
return gameconfiguration;
}
}
/// <summary>
/// Class containing methods and properties related to querying options from the user at runtime. See [QueryOptions](QueryOptions.md) for more information.
/// </summary>
public TypeReference QueryOptions
{
get
{
return queryoptions;
}
}
/// <summary>
/// Object containing the script options. See [Setting script options](gettingstarted.md#setting-script-options).
/// </summary>
public ExpandoObject ScriptOptions
{
get
{
return scriptoptions;
}
}
/// <summary>
/// Class containing methods related to angles. See [Angle2D](Angle2D.md) for more information.
/// ```js
/// let rad = UDB.Angle2D.degToRad(46);
/// ```
/// </summary>
public Angle2DWrapper Angle2D
{
get
{
return angle2d;
}
}
/// <summary>
/// Class containing methods related to the game data. See [Data](Data.md) for more information.
/// ```js
/// let hasfireblu = UDB.Data.textureExists('FIREBLU1');
/// ```
/// </summary>
public DataWrapper Data
{
get
{
return data;
}
}
/// <summary>
/// Instantiable class that contains methods related to two-dimensional lines. See [Line2D](Line2D.md) for more information.
/// ```js
/// let line = new UDB.Line2D([ 32, 64 ], [ 96, 128 ]);
/// ```
/// </summary>
public TypeReference Line2D
{
get
{
return line2d;
}
}
/// <summary>
/// Object containing methods related to the map. See [Map](Map.md) for more information.
/// ```js
/// let sectors = UDB.Map.getSelectedOrHighlightedSectors();
/// ```
/// </summary>
public MapWrapper Map
{
get
{
return map;
}
}
/// <summary>
/// The `UniValue` class. Is only needed when trying to assign integer values to UDMF fields.
/// ```js
/// s.fields.user_myintfield = new UDB.UniValue(0, 25);
/// ```
/// </summary>
public TypeReference UniValue
{
get
{
return univalue;
}
}
/// <summary>
/// Instantiable class that contains methods related to two-dimensional vectors. See [Vector2D](Vector2D.md) for more information.
/// ```js
/// let v = new UDB.Vector2D(32, 64);
/// ```
/// </summary>
public TypeReference Vector2D
{
get
{
return vector2d;
}
}
/// <summary>
/// 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);
/// ```
/// </summary>
public TypeReference Vector3D
{
get
{
return vector3d;
}
}
public TypeReference Linedef { get { return linedef; } }
public TypeReference Sector { get { return sector; } }
public TypeReference Sidedef { get { return sidedef; } }
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
internal UDBWrapper(Engine engine, ScriptInfo scriptinfo, IProgress<int> progress, IProgress<string> status, IProgress<string> logger)
{
gameconfiguration = new GameConfigurationWrapper();
queryoptions = TypeReference.CreateTypeReference(engine, typeof(QueryOptions));
scriptoptions = scriptinfo.GetScriptOptionsObject();
angle2d = new Angle2DWrapper();
data = new DataWrapper();
line2d = TypeReference.CreateTypeReference(engine, typeof(Line2DWrapper));
map = new MapWrapper();
univalue = TypeReference.CreateTypeReference(engine, typeof(CodeImp.DoomBuilder.Map.UniValue));
vector2d = TypeReference.CreateTypeReference(engine, typeof(Vector2DWrapper));
vector3d = TypeReference.CreateTypeReference(engine, typeof(Vector3DWrapper));
// These can not be directly instanciated and don't have static method, but it's required to
// for example use "instanceof" in scripts
linedef = TypeReference.CreateTypeReference(engine, typeof(LinedefWrapper));
sector = TypeReference.CreateTypeReference(engine, typeof(SectorWrapper));
sidedef = TypeReference.CreateTypeReference(engine, typeof(SidedefWrapper));
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;
}
#endregion
#region ================== Methods
/// <summary>
/// Set the progress of the script in percent. Value can be between 0 and 100. Also shows the script running dialog.
/// </summary>
/// <param name="value">Number between 0 and 100</param>
public void setProgress(int value)
{
progress.Report(value);
}
/*
public void setStatus(string text)
{
status.Report(text);
}
*/
/// <summary>
/// Adds a line to the script log. Also shows the script running dialog.
/// </summary>
/// <param name="text">Line to add to the script log</param>
public void log(object text)
{
if (text == null)
return;
logger.Report(text.ToString());
}
/// <summary>
/// Shows a message box with an "OK" button.
/// </summary>
/// <param name="message">Message to show</param>
public void showMessage(object message)
{
BuilderPlug.Me.ScriptRunnerForm.InvokePaused(new Action(() => {
if (message == null)
message = string.Empty;
MessageForm mf = new MessageForm("OK", null, message.ToString());
DialogResult result = mf.ShowDialog();
if (result == DialogResult.Abort)
throw new UserScriptAbortException();
}));
}
/// <summary>
/// Shows a message box with an "Yes" and "No" button.
/// </summary>
/// <param name="message">Message to show</param>
/// <returns>true if "Yes" was clicked, false if "No" was clicked</returns>
public bool showMessageYesNo(object message)
{
return (bool)BuilderPlug.Me.ScriptRunnerForm.InvokePaused(new Func<bool>(() =>
{
if (message == null)
message = string.Empty;
MessageForm mf = new MessageForm("Yes", "No", message.ToString());
DialogResult result = mf.ShowDialog();
if (result == DialogResult.Abort)
throw new UserScriptAbortException();
return result == DialogResult.OK;
}));
}
/// <summary>
/// Exist the script prematurely without undoing its changes.
/// </summary>
/// <param name="s">Text to show in the status bar (optional)</param>
public void exit(string s=null)
{
if (string.IsNullOrEmpty(s))
throw new ExitScriptException();
throw new ExitScriptException(s);
}
/// <summary>
/// Exist the script prematurely with undoing its changes.
/// </summary>
/// <param name="s">Text to show in the status bar (optional)</param>
public void die(string s=null)
{
if (string.IsNullOrEmpty(s))
throw new DieScriptException();
throw new DieScriptException(s);
}
#endregion
}
}