Skip to content

Commit

Permalink
Create HeartApi (#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
ari-steas authored Jan 18, 2025
2 parents 41af90b + b5a35ae commit 6c8c312
Show file tree
Hide file tree
Showing 9 changed files with 383 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,7 @@ public static HitscanProjectile GetProjectile(uint id)
}

public static int ActiveProjectiles => _?._projectiles.Count ?? -1;

public static bool TryGetProjectile(uint id, out HitscanProjectile projectile) => _._projectiles.TryGetValue(id, out projectile);
}
}
9 changes: 9 additions & 0 deletions Data/Scripts/HeartModule/MasterSession.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using Orrery.HeartModule.Shared.Definitions;
using Orrery.HeartModule.Shared.HeartApi;
using Orrery.HeartModule.Shared.Logging;
using Sandbox.ModAPI;
using VRage.Game.Components;
using VRage.Utils;
using VRageMath;

namespace Orrery.HeartModule
{
Expand All @@ -13,6 +15,7 @@ internal class MasterSession : MySessionComponentBase
public static MasterSession I;
private HeartLog _heartLog;
private CriticalHandle _criticalHandle;
private ApiSender _apiSender = new ApiSender();
private int _ticks;

public override void LoadData()
Expand All @@ -27,6 +30,9 @@ public override void LoadData()

DefinitionManager.LoadData();

_apiSender.LoadData();
HeartLog.Info("HeartAPI ready.");

HeartLog.Info("[MasterSession] finished LoadData.");
MyLog.Default.WriteLineAndConsole("\n========================================\nOrrery Combat Framework initialized - check [\\Storage\\3130655435.sbm_HeartModule\\debug.log] for logs.\n========================================");
}
Expand Down Expand Up @@ -57,6 +63,9 @@ protected override void UnloadData()
{
HeartLog.Info("[MasterSession] Begin UnloadData.");

_apiSender.UnloadData();
HeartLog.Info("HeartAPI unloaded.");

DefinitionManager.UnloadData();

_criticalHandle.UnloadData();
Expand Down
13 changes: 10 additions & 3 deletions Data/Scripts/HeartModule/Server/Projectiles/HitscanProjectile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,7 @@ internal virtual void CheckImpact()

{
double closestDistance = double.MaxValue;
LineD testLine = Raycast;
testLine.To -= Direction * 0.5f;
testLine.From += Direction * 0.5f;
LineD testLine = new LineD(Raycast.From - Direction * 0.5f, Raycast.To + Direction * 0.5f);

foreach (var grid in grids)
{
Expand Down Expand Up @@ -171,6 +169,15 @@ internal virtual void CheckImpact()

if (Definition.UngroupedDef.Impulse != 0)
closestBlock.CubeGrid.Physics?.ApplyImpulse(Direction * Definition.UngroupedDef.Impulse * (HitCount - prevHitCount), closestIntersect);

try
{
Definition.LiveMethods.ServerOnImpact?.Invoke(Id, Position, Direction, closestBlock.CubeGrid);
}
catch (Exception ex)
{
HeartLog.Exception(ex, typeof(HitscanProjectile));
}
}
}

Expand Down
36 changes: 29 additions & 7 deletions Data/Scripts/HeartModule/Server/Projectiles/ProjectileManager.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orrery.HeartModule.Server.Networking;
using Orrery.HeartModule.Shared.Definitions;
using Orrery.HeartModule.Shared.Logging;
using Orrery.HeartModule.Shared.Networking;
using Orrery.HeartModule.Shared.Utility;
using Sandbox.ModAPI;
using VRage.Collections;
using VRage.ModAPI;
using VRageMath;

Expand All @@ -17,7 +19,8 @@ internal class ProjectileManager

private readonly HashSet<HitscanProjectile> _projectiles = new HashSet<HitscanProjectile>();
private readonly HashSet<HitscanProjectile> _projectilesWithHealth = new HashSet<HitscanProjectile>();
private readonly HashSet<HitscanProjectile> _deadProjectiles = new HashSet<HitscanProjectile>();
private readonly MyConcurrentList<HitscanProjectile> _deadProjectiles = new MyConcurrentList<HitscanProjectile>();
private readonly MyConcurrentList<HitscanProjectile> _queuedProjectiles = new MyConcurrentList<HitscanProjectile>();
private uint _maxProjectileId = 0;

public ProjectileManager()
Expand All @@ -32,6 +35,14 @@ public void Close()

public void UpdateBeforeSimulation()
{
foreach (var projectile in _queuedProjectiles)
{
_projectiles.Add(projectile);
if (projectile.Definition.PhysicalProjectileDef.Health > 0)
_projectilesWithHealth.Add(projectile);
}
_queuedProjectiles.Clear();

MyAPIGateway.Parallel.ForEach(_projectiles, projectile =>
{
projectile.UpdateTick(1/60d);
Expand All @@ -52,14 +63,14 @@ public void UpdateAfterSimulation()

foreach (var deadProjectile in _deadProjectiles)
{
if (!deadProjectile.Definition.PhysicalProjectileDef.IsHitscan) // Hitscans only last one tick.
if (deadProjectile != null && !deadProjectile.Definition.PhysicalProjectileDef.IsHitscan) // Hitscans only last one tick.
ServerNetwork.SendToEveryoneInSync((SerializedCloseProjectile) deadProjectile, deadProjectile.Position);
_projectiles.Remove(deadProjectile);
_projectilesWithHealth.Remove(deadProjectile);

try
{
deadProjectile.Definition.LiveMethods.ServerOnEndOfLife?.Invoke(deadProjectile.Id);
deadProjectile?.Definition.LiveMethods.ServerOnEndOfLife?.Invoke(deadProjectile.Id);
}
catch (Exception ex)
{
Expand All @@ -74,10 +85,7 @@ public static void SpawnProjectile(HitscanProjectile projectile)
{
if (projectile == null) throw new Exception("Tried spawning null projectile!");
projectile.Id = _._maxProjectileId++;
_._projectiles.Add(projectile);

if (projectile.Definition.PhysicalProjectileDef.Health > 0)
_._projectilesWithHealth.Add(projectile);
_._queuedProjectiles.Add(projectile);

ServerNetwork.SendToEveryoneInSync((SerializedSpawnProjectile) projectile, projectile.Position);
try
Expand Down Expand Up @@ -145,5 +153,19 @@ public static void GetProjectilesInLine(LineD line, ref HashSet<PhysicalProjecti
projectiles.Add(projectile);
}
}

public static bool TryGetProjectile(uint id, out HitscanProjectile projectile)
{
foreach (var p in _._projectiles)
{
if (p.Id != id)
continue;
projectile = p;
return true;
}

projectile = null;
return false;
}
}
}
13 changes: 6 additions & 7 deletions Data/Scripts/HeartModule/Shared/HeartApi/ApiSender.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
using System;
using System.Collections.Generic;
using Orrery.HeartModule.Shared.Logging;
using Orrery.HeartModule.Shared.Logging;
using Sandbox.ModAPI;

namespace Orrery.HeartModule.Shared.HeartApi
{
internal class ApiSender
{
const long HeartApiChannel = 8644; // https://xkcd.com/221/
private const long HeartApiChannel = 8644; // https://xkcd.com/221/

Dictionary<string, Delegate> methods = new HeartApiMethods().ModApiMethods;
private readonly HeartApiMethods _methods = new HeartApiMethods();

public void LoadData()
{
MyAPIGateway.Utilities.SendModMessage(HeartApiChannel, methods); // Update mods that loaded before this one
MyAPIGateway.Utilities.SendModMessage(HeartApiChannel, _methods.CommunicationTuple); // Update mods that loaded before this one
MyAPIGateway.Utilities.RegisterMessageHandler(HeartApiChannel, RecieveApiMethods);
HeartLog.Debug("Orrery Combat Framework: HeartAPISender ready.");
}

public void UnloadData()
{
MyAPIGateway.Utilities.UnregisterMessageHandler(HeartApiChannel, RecieveApiMethods);
MyAPIGateway.Utilities.SendModMessage(HeartApiChannel, false); // Tell all HeartApi instances to close
}

/// <summary>
Expand All @@ -34,7 +33,7 @@ public void RecieveApiMethods(object data)

if (data is bool && (bool)data)
{
MyAPIGateway.Utilities.SendModMessage(HeartApiChannel, methods);
MyAPIGateway.Utilities.SendModMessage(HeartApiChannel, _methods.CommunicationTuple);
HeartLog.Debug("Orrery Combat Framework: HeartAPISender send methods.");
}
}
Expand Down
Loading

0 comments on commit 6c8c312

Please sign in to comment.