From 8660ec7cd21ba912c83beca1fed819edaaf35f6e Mon Sep 17 00:00:00 2001 From: Rynchodon Date: Sat, 15 Apr 2017 16:27:54 -0400 Subject: [PATCH] turret fix --- Scripts/Utility/Logger.cs | 44 +---------- .../Weapons/Guided/GuidedMissileLauncher.cs | 30 +++++++- Scripts/Weapons/Turret.cs | 41 +++-------- Scripts/Weapons/WeaponTargeting.cs | 73 +++++++++---------- 4 files changed, 77 insertions(+), 111 deletions(-) diff --git a/Scripts/Utility/Logger.cs b/Scripts/Utility/Logger.cs index 292e38a8..0a96a6c6 100644 --- a/Scripts/Utility/Logger.cs +++ b/Scripts/Utility/Logger.cs @@ -525,7 +525,7 @@ private static void appendWithBrackets(string append) [System.Diagnostics.Conditional("DEBUG")] public static void DebugNotify(string message, int disappearTimeMs = 2000, severity level = severity.TRACE) { Notify(message, disappearTimeMs, level); } -#if UNSTABLE + /// /// For a safe way to display a message as a notification, not conditional. /// @@ -567,49 +567,7 @@ private static string fontForSeverity(severity level = severity.TRACE) return MyFontEnum.White; } } -#else - /// - /// For a safe way to display a message as a notification, not conditional. - /// - /// the notification message - /// time on screen, in milliseconds - /// severity level - /// true iff the message was displayed - public static void Notify(string message, int disappearTimeMs = 2000, severity level = severity.TRACE) - { - if (Globals.WorldClosed) - return; - - MyFontEnum font = fontForSeverity(level); - if (MyAPIGateway.Utilities != null) - MyAPIGateway.Utilities.TryInvokeOnGameThread(() => MyAPIGateway.Utilities.ShowNotification(message, disappearTimeMs, font)); - //else - // log(severity.WARNING, "ShowNotificationDebug()", "MyAPIGateway.Utilities == null"); - } - - public enum severity : byte { OFF, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE, ALL } - private static MyFontEnum fontForSeverity(severity level = severity.TRACE) - { - switch (level) - { - case severity.TRACE: - return MyFontEnum.Blue; - case severity.DEBUG: - return MyFontEnum.DarkBlue; - case severity.INFO: - return MyFontEnum.Green; - case severity.WARNING: - return MyFontEnum.Red; - case severity.ERROR: - return MyFontEnum.Red; - case severity.FATAL: - return MyFontEnum.Red; - default: - return MyFontEnum.White; - } - } -#endif /// /// Append the relevant portion of the stack to a StringBuilder. /// diff --git a/Scripts/Weapons/Guided/GuidedMissileLauncher.cs b/Scripts/Weapons/Guided/GuidedMissileLauncher.cs index 8301ca9a..b4639a55 100644 --- a/Scripts/Weapons/Guided/GuidedMissileLauncher.cs +++ b/Scripts/Weapons/Guided/GuidedMissileLauncher.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Reflection; using Rynchodon.AntennaRelay; using Rynchodon.Utility.Network; using Sandbox.Definitions; @@ -27,8 +28,18 @@ private enum InitialTargetStatus : byte { NotReady, Golis, FromWeapon, NoStorage #region Static + private static readonly FieldInfo MyMissile__m_missileAmmoDefinition; + private static ValueSync termControl_shoot; + static GuidedMissileLauncher() + { + Type MyMissileType = typeof(MyAmmoBase).Assembly.GetType("Sandbox.Game.Weapons.MyMissile", true); + MyMissile__m_missileAmmoDefinition = MyMissileType.GetField("m_missileAmmoDefinition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + if (MyMissile__m_missileAmmoDefinition == null) + throw new NullReferenceException("MyMissile__m_missileAmmoDefinition"); + } + [OnWorldLoad] private static void Init() { @@ -51,8 +62,10 @@ private static void Entities_OnEntityAdd(IMyEntity obj) { if (obj.IsMissile()) { + MyDefinitionId definition = ((MyMissileAmmoDefinition)MyMissile__m_missileAmmoDefinition.GetValue(obj)).Id; + Logger.TraceLog("missile definition: " + definition); foreach (GuidedMissileLauncher launcher in Registrar.Scripts()) - if (launcher.MissileBelongsTo(obj)) + if (launcher.MissileBelongsTo(obj, ref definition)) return; Logger.TraceLog("No launcher for: " + obj.nameWithId()); } @@ -94,7 +107,10 @@ private static void HijackShoot() }; shoot.Setter = (block, value) => { if (IsGuidedMissileLauncher(block)) + { + Logger.TraceLog("Set shoot: " + value); termControl_shoot.SetValue(block, value); + } else originalSetter(block, value); }; @@ -187,13 +203,20 @@ public void Update1() LockAndShoot(); } - private bool MissileBelongsTo(IMyEntity missile) + private bool MissileBelongsTo(IMyEntity missile, ref MyDefinitionId definition) { if (!_isShooting) { myLogger.traceLog("Not mine, not shooting"); return false; } + if (definition != loadedAmmo.MissileDefinition.Id) + { + myLogger.traceLog("Not mine, not my loaded ammo definition"); + myLogger.traceLog("defn: " + definition); + myLogger.traceLog("loaded: " + loadedAmmo.MissileDefinition.Id); + return false; + } Vector3D local = Vector3D.Transform(missile.GetPosition(), CubeBlock.WorldMatrixNormalizedInv); if (MissileSpawnBox.Contains(local) != ContainmentType.Contains) { @@ -321,7 +344,10 @@ private void CheckCooldown() private void LockAndShoot() { if (m_onCooldown || m_onGameCooldown) + { + myLogger.traceLog("on cooldown"); return; + } if (!_shootCluster) { diff --git a/Scripts/Weapons/Turret.cs b/Scripts/Weapons/Turret.cs index f210e1cf..1279b38b 100644 --- a/Scripts/Weapons/Turret.cs +++ b/Scripts/Weapons/Turret.cs @@ -4,8 +4,8 @@ using System.Collections.Generic; using Sandbox.Definitions; using Sandbox.Game.Entities; +using Sandbox.Game.Weapons; using Sandbox.ModAPI; -using Sandbox.ModAPI.Interfaces; using VRage.Game.Entity; using VRage.Game.ModAPI; using VRage.ModAPI; @@ -16,9 +16,6 @@ namespace Rynchodon.Weapons public sealed class Turret : WeaponTargeting { - /// vanilla property - private static ITerminalProperty TP_TargetMissiles, TP_TargetMeteors, TP_TargetCharacters, TP_TargetMoving, TP_TargetLargeGrids, TP_TargetSmallGrids, TP_TargetStations, TP_TargetNeutrals; - private readonly MyEntitySubpart m_barrel; /// limits to determine whether or not a turret can face a target private readonly float minElevation, maxElevation, minAzimuth, maxAzimuth; @@ -36,21 +33,6 @@ public Turret(IMyCubeBlock block) : base(block) { myLogger = new Logger(block); - //Registrar.Add(CubeBlock, this); - - if (TP_TargetMissiles == null) - { - myLogger.debugLog("Filling Terminal Properties", Logger.severity.INFO); - IMyTerminalBlock term = CubeBlock as IMyTerminalBlock; - TP_TargetMissiles = term.GetProperty("TargetMissiles").AsBool(); - TP_TargetMeteors = term.GetProperty("TargetMeteors").AsBool(); - TP_TargetCharacters = term.GetProperty("TargetCharacters").AsBool(); - TP_TargetMoving = term.GetProperty("TargetMoving").AsBool(); - TP_TargetLargeGrids = term.GetProperty("TargetLargeShips").AsBool(); - TP_TargetSmallGrids = term.GetProperty("TargetSmallShips").AsBool(); - TP_TargetStations = term.GetProperty("TargetStations").AsBool(); - TP_TargetNeutrals = term.GetProperty("TargetNeutrals").AsBool(); - } // definition limits MyLargeTurretBaseDefinition definition = CubeBlock.GetCubeBlockDefinition() as MyLargeTurretBaseDefinition; @@ -89,14 +71,15 @@ public Turret(IMyCubeBlock block) /// protected override void Update100_Options_TargetingThread(TargetingOptions Options) { - SetFlag(TP_TargetMissiles, TargetType.Missile); - SetFlag(TP_TargetMeteors, TargetType.Meteor); - SetFlag(TP_TargetCharacters, TargetType.Character); - SetFlag(TP_TargetMoving, TargetType.Moving); - SetFlag(TP_TargetLargeGrids, TargetType.LargeGrid); - SetFlag(TP_TargetSmallGrids, TargetType.SmallGrid); - SetFlag(TP_TargetStations, TargetType.Station); - if (TP_TargetNeutrals.GetValue(CubeBlock)) + MyLargeTurretBase turret = (MyLargeTurretBase)CubeBlock; + SetFlag(turret.TargetMissiles, TargetType.Missile); + SetFlag(turret.TargetMeteors, TargetType.Meteor); + SetFlag(turret.TargetCharacters, TargetType.Character); + SetFlag(turret.TargetLargeGrids, TargetType.LargeGrid); + SetFlag(turret.TargetSmallGrids, TargetType.SmallGrid); + SetFlag(turret.TargetStations, TargetType.Station); + + if (turret.TargetNeutrals) Options.Flags &= ~TargetingFlags.IgnoreOwnerless; else Options.Flags |= TargetingFlags.IgnoreOwnerless; @@ -106,9 +89,9 @@ protected override void Update100_Options_TargetingThread(TargetingOptions Optio //myLogger.debugLog("CanTarget = " + Options.CanTarget, "TargetOptionsFromTurret()"); } - private void SetFlag(ITerminalProperty prop, TargetType typeFlag) + private void SetFlag(bool enable, TargetType typeFlag) { - if (prop.GetValue(CubeBlock)) + if (enable) Options.CanTarget |= typeFlag; else Options.CanTarget &= ~typeFlag; diff --git a/Scripts/Weapons/WeaponTargeting.cs b/Scripts/Weapons/WeaponTargeting.cs index 26f9d7e9..f4ba564d 100644 --- a/Scripts/Weapons/WeaponTargeting.cs +++ b/Scripts/Weapons/WeaponTargeting.cs @@ -17,6 +17,7 @@ using Sandbox.Game.Weapons; using Sandbox.Graphics.GUI; using Sandbox.ModAPI; +using Sandbox.ModAPI.Interfaces; using Sandbox.ModAPI.Interfaces.Terminal; using SpaceEngineers.Game.Weapons.Guns; using VRage.Game; @@ -83,20 +84,16 @@ public StaticVariables() TerminalControlHelper.EnsureTerminalControlCreated(); TerminalControlHelper.EnsureTerminalControlCreated(); - //// find the current position of shoot On/Off - //foreach (ITerminalControl control in MyTerminalControlFactory.GetControls(typeof(MyUserControllableGun))) - //{ - // ++ControlsIndex; - // if (control.Id == "Shoot") - // break; - //} - - //Logger.TraceLog("controls index: " + ControlsIndex); - termControl_targetFlag = new FlagsValueSync("TargetFlag", "value_termControl_targetFlag"); termControl_targetType = new FlagsValueSync("TargetType", "value_termControl_targetType"); termControl_weaponFlags = new FlagsValueSync("WeaponFlags", "value_termControl_weaponFlags"); + { + MyTerminalControlOnOffSwitch targetMoving = new MyTerminalControlOnOffSwitch("ArmsTargetMoving", MyStringId.GetOrCompute("Target moving"), MyStringId.GetOrCompute("ARMS will target fast approaching objects")); + termControl_targetType.AddControl(targetMoving, TargetType.Moving); + AddControl(targetMoving, Visibility.Turret); + } + AddControl(new MyTerminalControlSeparator()); { @@ -199,7 +196,6 @@ public StaticVariables() } CloneTurretControl_OnOff("TargetMeteors", TargetType.Meteor); - CloneTurretControl_OnOff("TargetMoving", TargetType.Moving); CloneTurretControl_OnOff("TargetMissiles", TargetType.Missile); CloneTurretControl_OnOff("TargetSmallShips", TargetType.SmallGrid); CloneTurretControl_OnOff("TargetLargeShips", TargetType.LargeGrid); @@ -218,6 +214,12 @@ public StaticVariables() } } + { + MyTerminalControlOnOffSwitch targetMoving = new MyTerminalControlOnOffSwitch("ArmsTargetMoving", MyStringId.GetOrCompute("Target moving"), MyStringId.GetOrCompute("ARMS will target fast approaching objects")); + termControl_targetType.AddControl(targetMoving, TargetType.Moving); + AddControl(targetMoving, Visibility.Fixed); + } + Logger.TraceLog("initialized"); //Controls.TrimExcess(); //MyAPIGateway.TerminalControls.CustomControlGetter += CustomControlGetter; @@ -472,7 +474,7 @@ private static void OnGpsListItemSelected(IMyTerminalBlock block, ListFirst item is target, second is the weapon, followed by custom items. @@ -572,7 +574,6 @@ public Control CurrentControl } } -#if UNSTABLE /* * Bug in Space Engineers breaks Shoot_On, Shoot_Off, SetShooting, SetTarget, and TrackTarget for turrets. */ @@ -601,42 +602,40 @@ private void RestoreDefaultTargeting() } } + private static ITerminalProperty m_shootProperty; + + private bool GetShootProp() + { + if (m_shootProperty == null) + m_shootProperty = CubeBlock.GetProperty("Shoot").AsBool(); + return m_shootProperty.GetValue(CubeBlock); + } + private void ShootOn() { + if (GetShootProp()) + return; + + myLogger.traceLog("Opening fire"); if (myTurret != null) { TurretNeedsUpdate(true); myTurret.SetTarget(ProjectilePosition() + CurrentTarget.FiringDirection.Value * 1000f); } - ((MyUserControllableGun)CubeBlock).SetShooting(true); + m_shootProperty.SetValue(CubeBlock, true); } private void ShootOff() { + if (!GetShootProp()) + return; + + myLogger.traceLog("Holding fire"); if (myTurret != null) TurretNeedsUpdate(false); - ((MyUserControllableGun)CubeBlock).SetShooting(false); - } -#else - private void RestoreDefaultTargeting() - { - if (myTurret != null) - myTurret.ResetTargetingToDefault(); + m_shootProperty.SetValue(CubeBlock, false); } - private void ShootOn() - { - // has to be this way for guided missiles - ((MyUserControllableGun)CubeBlock).SetShooting(true); - } - - private void ShootOff() - { - // has to be this way for guided missiles - ((MyUserControllableGun)CubeBlock).SetShooting(false); - } -#endif - /// Checks that it is possible to control the weapon: working, not in use, etc. public bool CanControl { @@ -721,16 +720,16 @@ public void Update_Targeting() try { GameThreadActions.DequeueAll(action => action.Invoke()); - if (CurrentControl != Control.Off && FireWeapon != IsFiringWeapon && MyAPIGateway.Multiplayer.IsServer) + if (CurrentControl != Control.Off && MyAPIGateway.Multiplayer.IsServer) { if (FireWeapon) { - myLogger.traceLog("Opening fire"); + //myLogger.traceLog("Opening fire"); ShootOn(); } else { - myLogger.traceLog("Holding fire"); + //myLogger.traceLog("Holding fire"); ShootOff(); } }