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; } }