diff --git a/Utility Mods/SCDefenseBlocks/Audio/Alert_Damaged.wav b/Utility Mods/SCDefenseBlocks/Audio/Alert_Damaged.wav
new file mode 100644
index 000000000..1bd27b3c4
Binary files /dev/null and b/Utility Mods/SCDefenseBlocks/Audio/Alert_Damaged.wav differ
diff --git a/Utility Mods/SCDefenseBlocks/Audio/Alert_Offline.wav b/Utility Mods/SCDefenseBlocks/Audio/Alert_Offline.wav
new file mode 100644
index 000000000..296869a29
Binary files /dev/null and b/Utility Mods/SCDefenseBlocks/Audio/Alert_Offline.wav differ
diff --git a/Utility Mods/SCDefenseBlocks/Audio/Brake_Applied.wav b/Utility Mods/SCDefenseBlocks/Audio/Brake_Applied.wav
new file mode 100644
index 000000000..ede85d719
Binary files /dev/null and b/Utility Mods/SCDefenseBlocks/Audio/Brake_Applied.wav differ
diff --git a/Utility Mods/SCDefenseBlocks/Audio/DamageRepaired.wav b/Utility Mods/SCDefenseBlocks/Audio/DamageRepaired.wav
new file mode 100644
index 000000000..8681c1260
Binary files /dev/null and b/Utility Mods/SCDefenseBlocks/Audio/DamageRepaired.wav differ
diff --git a/Utility Mods/SCDefenseBlocks/Audio/PowerRestored.wav b/Utility Mods/SCDefenseBlocks/Audio/PowerRestored.wav
new file mode 100644
index 000000000..35a1cb119
Binary files /dev/null and b/Utility Mods/SCDefenseBlocks/Audio/PowerRestored.wav differ
diff --git a/Utility Mods/SCDefenseBlocks/Audio/Warning_Damaged.wav b/Utility Mods/SCDefenseBlocks/Audio/Warning_Damaged.wav
new file mode 100644
index 000000000..45deb9351
Binary files /dev/null and b/Utility Mods/SCDefenseBlocks/Audio/Warning_Damaged.wav differ
diff --git a/Utility Mods/SCDefenseBlocks/Audio/Warning_Offline.wav b/Utility Mods/SCDefenseBlocks/Audio/Warning_Offline.wav
new file mode 100644
index 000000000..de0e97a33
Binary files /dev/null and b/Utility Mods/SCDefenseBlocks/Audio/Warning_Offline.wav differ
diff --git a/Utility Mods/SCDefenseBlocks/Data/Audio_FieldGen.sbc b/Utility Mods/SCDefenseBlocks/Data/Audio_FieldGen.sbc
new file mode 100644
index 000000000..783a37257
--- /dev/null
+++ b/Utility Mods/SCDefenseBlocks/Data/Audio_FieldGen.sbc
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+ MyObjectBuilder_AudioDefinition
+ FieldGen_Brake
+
+ HUD
+ true
+ false
+ 50
+ false
+ 4
+ 0.75
+
+
+ Audio\Brake_Applied.wav
+
+
+
+
+
+
+ MyObjectBuilder_AudioDefinition
+ FieldGen_Damaged
+
+ HUD
+ true
+ false
+ 50
+ false
+ 4
+ 0.75
+
+
+ Audio\Warning_Damaged.wav
+ Audio\Alert_Damaged.wav
+
+
+
+
+
+
+ MyObjectBuilder_AudioDefinition
+ FieldGen_Offline
+
+ HUD
+ true
+ false
+ 50
+ false
+ 4
+ 0.75
+
+
+ Audio\Warning_Offline.wav
+ Audio\Alert_Offline.wav
+
+
+
+
+
+
+ MyObjectBuilder_AudioDefinition
+ FieldGen_PowerRestored
+
+ HUD
+ true
+ false
+ 50
+ false
+ 4
+ 0.75
+
+
+ Audio\PowerRestored.wav
+
+
+
+
+
+
+ MyObjectBuilder_AudioDefinition
+ FieldGen_DamagedRepaired
+
+ HUD
+ true
+ false
+ 50
+ false
+ 4
+ 0.75
+
+
+ Audio\DamageRepaired.wav
+
+
+
+
+
\ No newline at end of file
diff --git a/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_Core.cs b/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_Core.cs
index 28f4cdf96..fa4f8d219 100644
--- a/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_Core.cs
+++ b/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_Core.cs
@@ -5,9 +5,9 @@
using ProtoBuf;
using Sandbox.Common.ObjectBuilders;
using Sandbox.Game;
+using Sandbox.Game.Entities;
using Sandbox.Game.EntityComponents;
using Sandbox.ModAPI;
-using VRage.Game;
using VRage.Game.Components;
using VRage.Game.Entity;
using VRage.Game.ModAPI;
@@ -16,11 +16,11 @@
using VRage.Network;
using VRage.ObjectBuilders;
using VRage.Sync;
+using VRage.Utils;
using VRageMath;
using static Draygo.API.HudAPIv2;
using static VRageRender.MyBillboard;
-using Sandbox.Game.Gui;
-using Draygo.API;
+
namespace Starcore.FieldGenerator
{
@@ -36,7 +36,15 @@ public class FieldGenerator : MyGameLogicComponent, IMyEventProxy
private int _damageEventCounter = 0;
private float _stabilityChange = 0;
private int _resetCounter = 0;
- private bool _lowStability = false;
+ private bool _lowStability = false;
+
+ internal int _stopTickCounter = -1;
+ internal Vector3? angularAxis1 = null;
+ internal Vector3? angularAxis2 = null;
+
+ internal bool _cachedState;
+ internal MyEntity3DSoundEmitter BlockSoundEmitter;
+ internal MySoundPair BlockSoundPair;
private int initValueDelayTicks = 60; // 1 second delay (60 ticks)
private bool valuesInitialized = false;
@@ -44,7 +52,8 @@ public class FieldGenerator : MyGameLogicComponent, IMyEventProxy
#region Sync Properties
public MySync SiegeMode;
public MySync SiegeCooldownActive;
- public MySync GridStopped = null;
+ public MySync SlowdownActive;
+ public MySync GridStopped;
public MySync SiegeElapsedTime;
public MySync SiegeCooldownTime;
@@ -85,6 +94,7 @@ public override void UpdateOnceBeforeFrame()
if (Block?.CubeGrid?.Physics == null)
return;
+ BlockSoundEmitter = new MyEntity3DSoundEmitter((MyEntity)MyAPIGateway.Entities.GetEntityById(Block.EntityId));
FieldGeneratorControls.DoOnce(ModContext);
Sink = Block.Components.Get();
@@ -130,7 +140,7 @@ public override void UpdateOnceBeforeFrame()
NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME;
NeedsUpdate |= MyEntityUpdateEnum.EACH_10TH_FRAME;
- }
+ }
public override void UpdateAfterSimulation()
{
@@ -146,11 +156,37 @@ public override void UpdateAfterSimulation()
}
else
{
+ _cachedState = Block.IsWorking;
Stability.Value = 100;
InitExistingUpgrades();
valuesInitialized = true;
}
}
+
+ if (SiegeMode.Value && !GridStopped.Value)
+ {
+ if (Block.CubeGrid.Physics.LinearVelocity != Vector3D.Zero)
+ {
+ SiegeEmergencyStop();
+ _stopTickCounter++;
+ }
+ }
+ }
+
+ if (SiegeMode.Value && !GridStopped.Value)
+ {
+ if (!SlowdownActive.Value)
+ {
+ BlockSoundPair = new MySoundPair("FieldGen_Brake");
+ BlockSoundEmitter?.PlaySound(BlockSoundPair, false, false, true, true, false, null, true);
+ SlowdownActive.Value = true;
+ }
+ }
+
+ if (_cachedState != Block.IsWorking)
+ {
+ _cachedState = Block.IsWorking;
+ Block_IsWorkingChanged();
}
if (MyAPIGateway.Session.GameplayFrameCounter % 60 == 0)
@@ -159,7 +195,10 @@ public override void UpdateAfterSimulation()
{
if (IsServer)
{
- UpdateSiegeState();
+ if (GridStopped.Value || SiegeCooldownActive.Value)
+ {
+ UpdateSiegeState();
+ }
if (!Config.SimplifiedMode)
{
@@ -350,7 +389,7 @@ private void HandleResistence()
return;
}
- if (SiegeMode.Value)
+ if (SiegeMode.Value && GridStopped.Value)
{
MyVisualScriptLogicProvider.SetGridGeneralDamageModifier(Block.CubeGrid.Name, (1 - Config.SiegeModeResistence));
return;
@@ -400,6 +439,20 @@ private void OnGridStopValueChange(MySync obj)
if (obj?.Value ?? false)
Block.CubeGrid.Physics.LinearVelocity = Vector3.Zero;
}
+
+ private void Block_IsWorkingChanged()
+ {
+ if (!Block.IsWorking)
+ {
+ BlockSoundPair = Block.IsFunctional ? BlockSoundPair = new MySoundPair("FieldGen_Offline") : BlockSoundPair = new MySoundPair("FieldGen_Damaged");
+ BlockSoundEmitter?.PlaySound(BlockSoundPair, false, false, true, true, false, null, true);
+ }
+ else
+ {
+ BlockSoundPair = Block.SlimBlock.IsFullIntegrity ? BlockSoundPair = new MySoundPair("FieldGen_PowerRestored") : BlockSoundPair = new MySoundPair("FieldGen_DamagedRepaired");
+ BlockSoundEmitter?.PlaySound(BlockSoundPair, false, false, true, true, false, null, true);
+ }
+ }
#endregion
#region Siege Mode
@@ -458,12 +511,82 @@ private void SiegeBlockEnabler(IEnumerable allFunctionalBloc
FieldGeneratorSession.CoreSysAPI.SetFiringAllowed(entBlock, enabled);
block.Enabled = enabled;
}
+ else if (block is IMyThrust || block is IMyGyro)
+ {
+ block.Enabled = enabled;
+ }
}
else
continue;
}
}
+ private void SiegeEmergencyStop()
+ {
+ if (Block.CubeGrid.Physics == null)
+ return;
+
+ float elapsed = _stopTickCounter / 60f;
+ float maxTime = 10f;
+
+ float minForce = 1000000f;
+ float maxForce = 120000000f;
+
+ float timeScale = MathHelper.Clamp(elapsed / maxTime, 0f, 1f);
+ float forceMagnitude = MathHelper.Lerp(minForce, maxForce, timeScale);
+
+ Vector3 direction = Vector3.Normalize(Block.CubeGrid.Physics.LinearVelocity);
+ Vector3 linearDrag = -direction * forceMagnitude;
+
+ Block.CubeGrid.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, linearDrag, null, null);
+
+ if (Block.CubeGrid.Physics.LinearVelocity.LengthSquared() < 25f || elapsed >= maxTime) // 5 m/s squared = 25
+ {
+ Block.CubeGrid.Physics.LinearVelocity = Vector3D.Zero;
+ GridStopped.Value = true;
+ SlowdownActive.Value = false;
+ _stopTickCounter = -1;
+ angularAxis1 = null;
+ angularAxis2 = null;
+ return;
+ }
+
+ // ----- ANGULAR DRAG -----
+ if (angularAxis1 == null)
+ {
+ angularAxis1 = GetRandomUnitVector();
+
+ Vector3 candidate;
+ do
+ {
+ candidate = GetRandomUnitVector();
+ }
+ while (Math.Abs(Vector3D.Dot(candidate, angularAxis1.Value)) > 0.99f);
+
+ angularAxis2 = candidate;
+ }
+
+ float targetAngularAccel = 0.1f;
+ Vector3 torqueDirection = new Vector3(0,0,0);
+
+ torqueDirection += angularAxis1.Value;
+ torqueDirection += angularAxis2.Value;
+
+ Vector3 angularImpulse = torqueDirection * targetAngularAccel / 60f;
+
+ Block.CubeGrid.Physics.AngularVelocity += angularImpulse;
+ }
+
+ Vector3 GetRandomUnitVector()
+ {
+ Vector3 v = new Vector3(
+ MyUtils.GetRandomFloat(-1f, 1f),
+ MyUtils.GetRandomFloat(-1f, 1f),
+ MyUtils.GetRandomFloat(-1f, 1f)
+ );
+ return Vector3.Normalize(v);
+ }
+
private void EndSiegeMode()
{
if (IsServer && GridStopped.Value)
@@ -606,6 +729,20 @@ public float CalculatePowerDraw()
return Config.MinPowerDraw + t * (Config.MaxPowerDraw - Config.MinPowerDraw);
}
+ public float CheckPowerDraw(float fieldValue)
+ {
+ float maxPossibleFieldPowerV = Config.PerModuleAmount * Config.MaxModuleCount;
+ float clampedFieldPowerV = MathHelper.Clamp(fieldValue, 0, maxPossibleFieldPowerV);
+ float tV = clampedFieldPowerV / maxPossibleFieldPowerV;
+
+ return Config.MinPowerDraw + tV * (Config.MaxPowerDraw - Config.MinPowerDraw);
+ }
+
+ public float CheckPowerGeneration()
+ {
+ return Block.CubeGrid.ResourceDistributor.MaxAvailableResourceByType(MyResourceDistributorComponent.ElectricityId);
+ }
+
private bool IsClientInShip()
{
if (Block != null)
@@ -751,7 +888,11 @@ private void UpdateHUD()
GeneratorHUDContent.Append(GenerateBar("Stability:", Stability.Value, 100, true));
}
- if (SiegeMode.Value)
+ if (SiegeMode.Value && !GridStopped.Value)
+ {
+ GeneratorHUDContent.Append($"\nSiege Mode Actived | Emergency Braking Applied");
+ }
+ else if (SiegeMode.Value)
{
GeneratorHUDContent.Append($"\nSiege Mode Active | {SiegeElapsedTime.Value} / {Config.MaxSiegeTime}");
}
diff --git a/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_TerminalControls.cs b/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_TerminalControls.cs
index 0b7f693dc..50a852471 100644
--- a/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_TerminalControls.cs
+++ b/Utility Mods/SCDefenseBlocks/Data/Scripts/OneFuckingFolderDeeper/FieldGenerator/FieldGenerator_TerminalControls.cs
@@ -48,7 +48,7 @@ static bool CooldownEnabler(IMyTerminalBlock b)
var logic = GetLogic(b);
if (logic != null)
{
- return !logic.SiegeCooldownActive;
+ return !logic.SiegeCooldownActive && !logic.SlowdownActive;
}
return false;
}
@@ -149,6 +149,9 @@ static void CreateActions(IMyModContext context)
var logic = GetLogic(b);
if (logic != null)
{
+ if (logic.CheckPowerDraw(logic.FieldPower.Value + 2.5f) > logic.CheckPowerGeneration())
+ return;
+
logic.FieldPower.Value += 2.5f;
}
};