diff --git a/OpenRA.Game/WAngle.cs b/OpenRA.Game/WAngle.cs
index 8bdec691cc..3c9274dad2 100644
--- a/OpenRA.Game/WAngle.cs
+++ b/OpenRA.Game/WAngle.cs
@@ -10,13 +10,16 @@
#endregion
using System;
+using Eluant;
+using Eluant.ObjectBinding;
+using OpenRA.Scripting;
namespace OpenRA
{
///
/// 1D angle - 1024 units = 360 degrees.
///
- public struct WAngle : IEquatable
+ public struct WAngle : IScriptBindable, ILuaAdditionBinding, ILuaSubtractionBinding, ILuaEqualityBinding, IEquatable
{
public readonly int Angle;
public int AngleSquared { get { return (int)Angle * Angle; } }
@@ -169,5 +172,58 @@ namespace OpenRA
9233, 9781, 10396, 11094, 11891, 12810, 13882, 15148, 16667, 18524, 20843,
23826, 27801, 33366, 41713, 55622, 83438, 166883, int.MaxValue
};
+
+ #region Scripting interface
+
+ public LuaValue Add(LuaRuntime runtime, LuaValue left, LuaValue right)
+ {
+ WAngle a, b;
+ int c;
+
+ if (!left.TryGetClrValue(out a))
+ throw new LuaException("Attempted to call WAngle.Add(WAngle, WAngle) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, right.WrappedClrType().Name));
+
+ if (right.TryGetClrValue(out c))
+ {
+ Game.Debug("Support for facing calculations mixing Angle with integers is deprecated. Make sure all facing calculations use Angle");
+ return new LuaCustomClrObject(a + FromFacing(c));
+ }
+
+ if (right.TryGetClrValue(out b))
+ return new LuaCustomClrObject(a + b);
+
+ throw new LuaException("Attempted to call WAngle.Add(WAngle, WAngle) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, right.WrappedClrType().Name));
+ }
+
+ public LuaValue Subtract(LuaRuntime runtime, LuaValue left, LuaValue right)
+ {
+ WAngle a, b;
+ int c;
+
+ if (!left.TryGetClrValue(out a))
+ throw new LuaException("Attempted to call WAngle.Subtract(WAngle, WAngle) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, right.WrappedClrType().Name));
+
+ if (right.TryGetClrValue(out c))
+ {
+ Game.Debug("Support for facing calculations mixing Angle with integers is deprecated. Make sure all facing calculations use Angle");
+ return new LuaCustomClrObject(a - FromFacing(c));
+ }
+
+ if (right.TryGetClrValue(out b))
+ return new LuaCustomClrObject(a - b);
+
+ throw new LuaException("Attempted to call WAngle.Subtract(WAngle, WAngle) with invalid arguments ({0}, {1})".F(left.WrappedClrType().Name, right.WrappedClrType().Name));
+ }
+
+ public LuaValue Equals(LuaRuntime runtime, LuaValue left, LuaValue right)
+ {
+ WAngle a, b;
+ if (!left.TryGetClrValue(out a) || !right.TryGetClrValue(out b))
+ return false;
+
+ return a == b;
+ }
+
+ #endregion
}
}
diff --git a/OpenRA.Game/WVec.cs b/OpenRA.Game/WVec.cs
index 865e749edb..cb4cbce63e 100644
--- a/OpenRA.Game/WVec.cs
+++ b/OpenRA.Game/WVec.cs
@@ -150,7 +150,7 @@ namespace OpenRA
case "X": return X;
case "Y": return Y;
case "Z": return Z;
- case "Facing": return Yaw.Facing;
+ case "Facing": return new LuaCustomClrObject(Yaw);
default: throw new LuaException("WVec does not define a member '{0}'".F(key));
}
}
diff --git a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs
index 6b0b039bd5..5e20a2a71c 100644
--- a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs
+++ b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs
@@ -75,6 +75,20 @@ namespace OpenRA.Mods.Common.Scripting
return init;
}
+ // HACK: Forward compatibility for future WAngle facings
+ var facingInit = init as FacingInit;
+ if (facingInit != null)
+ {
+ WAngle angle;
+ if (value.TryGetClrValue(out angle))
+ {
+ facingInit.Initialize(angle.Facing);
+ return facingInit;
+ }
+
+ Game.Debug("Initializing Facing with integers is deprecated. Use Angle instead.");
+ }
+
var initializers = initType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(m => m.Name == "Initialize" && m.GetParameters().Length == 1);
diff --git a/OpenRA.Mods.Common/Scripting/Global/AngleGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/AngleGlobal.cs
new file mode 100644
index 0000000000..7815611098
--- /dev/null
+++ b/OpenRA.Mods.Common/Scripting/Global/AngleGlobal.cs
@@ -0,0 +1,34 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you 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. For more
+ * information, see COPYING.
+ */
+#endregion
+
+using OpenRA.Scripting;
+
+namespace OpenRA.Mods.Common.Scripting.Global
+{
+ [ScriptGlobal("Angle")]
+ public class AngleGlobal : ScriptGlobal
+ {
+ public AngleGlobal(ScriptContext context)
+ : base(context) { }
+
+ public WAngle North { get { return WAngle.Zero; } }
+ public WAngle NorthWest { get { return new WAngle(128); } }
+ public WAngle West { get { return new WAngle(256); } }
+ public WAngle SouthWest { get { return new WAngle(384); } }
+ public WAngle South { get { return new WAngle(512); } }
+ public WAngle SouthEast { get { return new WAngle(640); } }
+ public WAngle East { get { return new WAngle(768); } }
+ public WAngle NorthEast { get { return new WAngle(896); } }
+
+ [Desc("Create an arbitrary angle.")]
+ public WAngle New(int a) { return new WAngle(a); }
+ }
+}
diff --git a/OpenRA.Mods.Common/Scripting/Global/FacingGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/FacingGlobal.cs
index 1f4d55fe2c..25aabfe23d 100644
--- a/OpenRA.Mods.Common/Scripting/Global/FacingGlobal.cs
+++ b/OpenRA.Mods.Common/Scripting/Global/FacingGlobal.cs
@@ -19,13 +19,18 @@ namespace OpenRA.Mods.Common.Scripting.Global
public FacingGlobal(ScriptContext context)
: base(context) { }
- public int North { get { return 0; } }
- public int NorthWest { get { return 32; } }
- public int West { get { return 64; } }
- public int SouthWest { get { return 96; } }
- public int South { get { return 128; } }
- public int SouthEast { get { return 160; } }
- public int East { get { return 192; } }
- public int NorthEast { get { return 224; } }
+ void Deprecated()
+ {
+ Game.Debug("The Facing table is deprecated. Use Angle instead.");
+ }
+
+ public int North { get { Deprecated(); return 0; } }
+ public int NorthWest { get { Deprecated(); return 32; } }
+ public int West { get { Deprecated(); return 64; } }
+ public int SouthWest { get { Deprecated(); return 96; } }
+ public int South { get { Deprecated(); return 128; } }
+ public int SouthEast { get { Deprecated(); return 160; } }
+ public int East { get { Deprecated(); return 192; } }
+ public int NorthEast { get { Deprecated(); return 224; } }
}
}
diff --git a/OpenRA.Mods.Common/Scripting/Properties/GeneralProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/GeneralProperties.cs
index 8c3a397882..f53af83b5c 100644
--- a/OpenRA.Mods.Common/Scripting/Properties/GeneralProperties.cs
+++ b/OpenRA.Mods.Common/Scripting/Properties/GeneralProperties.cs
@@ -122,14 +122,14 @@ namespace OpenRA.Mods.Common.Scripting
public WPos CenterPosition { get { return Self.CenterPosition; } }
[Desc("The direction that the actor is facing.")]
- public int Facing
+ public WAngle Facing
{
get
{
if (facing == null)
throw new LuaException("Actor '{0}' doesn't define a facing".F(Self));
- return facing.Facing.Facing;
+ return facing.Facing;
}
}