Files
crystall-punk-14/Content.Server/AME/AMENodeGroup.cs

185 lines
6.7 KiB
C#
Raw Normal View History

using System.Linq;
2021-06-09 22:19:39 +02:00
using Content.Server.AME.Components;
using Content.Server.Explosion.EntitySystems;
2021-06-09 22:19:39 +02:00
using Content.Server.NodeContainer.NodeGroups;
using Content.Server.NodeContainer.Nodes;
using Robust.Shared.Map;
2021-06-09 22:19:39 +02:00
using Robust.Shared.Random;
2021-06-09 22:19:39 +02:00
namespace Content.Server.AME
{
/// <summary>
/// Node group class for handling the Antimatter Engine's console and parts.
/// </summary>
[NodeGroup(NodeGroupID.AMEngine)]
public sealed class AMENodeGroup : BaseNodeGroup
{
/// <summary>
/// The AME controller which is currently in control of this node group.
/// This could be tracked a few different ways, but this is most convenient,
/// since any part connected to the node group can easily find the master.
/// </summary>
[ViewVariables]
2021-02-02 05:20:24 -06:00
private AMEControllerComponent? _masterController;
2021-12-08 17:04:21 +01:00
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
2021-02-02 05:20:24 -06:00
public AMEControllerComponent? MasterController => _masterController;
private readonly List<AMEShieldComponent> _cores = new();
public int CoreCount => _cores.Count;
public override void LoadNodes(List<Node> groupNodes)
{
base.LoadNodes(groupNodes);
var mapManager = IoCManager.Resolve<IMapManager>();
2022-06-24 00:21:44 +12:00
IMapGrid? grid = null;
foreach (var node in groupNodes)
{
var nodeOwner = node.Owner;
2021-12-08 17:04:21 +01:00
if (_entMan.TryGetComponent(nodeOwner, out AMEShieldComponent? shield))
2021-02-02 05:20:24 -06:00
{
2022-06-24 00:21:44 +12:00
var xform = _entMan.GetComponent<TransformComponent>(nodeOwner);
if (xform.GridUid != grid?.GridEntityId && !mapManager.TryGetGrid(xform.GridUid, out grid))
continue;
if (grid == null)
continue;
var nodeNeighbors = grid.GetCellsInSquareArea(xform.Coordinates, 1)
2021-12-08 17:04:21 +01:00
.Where(entity => entity != nodeOwner && _entMan.HasComponent<AMEShieldComponent>(entity));
if (nodeNeighbors.Count() >= 8)
{
_cores.Add(shield);
shield.SetCore();
// Core visuals will be updated later.
}
else
{
shield.UnsetCore();
}
2021-02-02 05:20:24 -06:00
}
}
// Separate to ensure core count is correctly updated.
foreach (var node in groupNodes)
{
var nodeOwner = node.Owner;
2021-12-08 17:04:21 +01:00
if (_entMan.TryGetComponent(nodeOwner, out AMEControllerComponent? controller))
{
if (_masterController == null)
{
// Has to be the first one, as otherwise IsMasterController will return true on them all for this first update.
_masterController = controller;
}
controller.OnAMENodeGroupUpdate();
}
}
UpdateCoreVisuals();
}
public void UpdateCoreVisuals()
{
var injectionAmount = 0;
var injecting = false;
if (_masterController != null)
{
injectionAmount = _masterController.InjectionAmount;
injecting = _masterController.Injecting;
}
var injectionStrength = CoreCount > 0 ? injectionAmount / CoreCount : 0;
foreach (AMEShieldComponent core in _cores)
{
core.UpdateCoreVisuals(injectionStrength, injecting);
}
}
public float InjectFuel(int fuel, out bool overloading)
{
overloading = false;
if(fuel > 0 && CoreCount > 0)
{
var safeFuelLimit = CoreCount * 2;
if (fuel > safeFuelLimit)
{
// The AME is being overloaded.
// Note about these maths: I would assume the general idea here is to make larger engines less safe to overload.
// In other words, yes, those are supposed to be CoreCount, not safeFuelLimit.
var instability = 0;
var overloadVsSizeResult = fuel - CoreCount;
// fuel > safeFuelLimit: Slow damage. Can safely run at this level for burst periods if the engine is small and someone is keeping an eye on it.
if (_random.Prob(0.5f))
instability = 1;
// overloadVsSizeResult > 5:
if (overloadVsSizeResult > 5)
instability = 5;
// overloadVsSizeResult > 10: This will explode in at most 5 injections.
if (overloadVsSizeResult > 10)
instability = 20;
// Apply calculated instability
if (instability != 0)
{
overloading = true;
foreach(AMEShieldComponent core in _cores)
{
core.CoreIntegrity -= instability;
}
}
}
// Note the float conversions. The maths will completely fail if not done using floats.
// Oh, and don't ever stuff the result of this in an int. Seriously.
return (((float) fuel) / CoreCount) * fuel * 20000;
}
return 0;
}
public int GetTotalStability()
{
if(CoreCount < 1) { return 100; }
var stability = 0;
foreach(AMEShieldComponent core in _cores)
{
stability += core.CoreIntegrity;
}
stability = stability / CoreCount;
return stability;
}
public void ExplodeCores()
{
if(_cores.Count < 1 || MasterController == null) { return; }
Explosion refactor (#5230) * Explosions * fix yaml typo and prevent silly UI inputs * oop * Use modified contains() checks And remove IEnumerable * Buff nuke, nerf meteors * optimize the entity lookup stuff a bit * fix tile (0,0) error forgot to do an initial Enumerator.MoveNext(), so the first tile was always the "null" tile. * remove celebration * byte -> int * remove diag edge tile dict * fix one bug but there is another * fix the other bug turns out dividing a ushort leads to rounding errors. Why TF is the grid tile size even a ushort in the first place. * improve edge map * fix minor bug If the initial-explosion tile had an airtight entity on it, the tile was processed twice. * some reviews (transform queries, eye.mapid, and tilesizes in overlays) * Apply suggestions from code review Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * is map paused * GetAllTiles ignores space by default * WriteLine -> WriteError * First -> FirstOrDefault() * default prototype const string * entity query * misc review changes * grid edge max distance * fix fire texture defn bad use of type serializer and ioc-resolves * Remove ExplosionLaunched And allow nukes to throw items towards the outer part of an explosion * no hot-reload disclaimer * replace prototype id string with int index * optimise damage a tiiiiny bit. * entity queries * comments * misc mirror comments * cvars * admin logs * move intensity-per-state to prototype * update tile event to ECS event * git mv * Tweak rpg & minibomb also fix merge bug * you don't exist anymore go away * Fix build Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2022-04-01 15:39:26 +13:00
float radius = 0;
/*
* todo: add an exact to the shielding and make this find the core closest to the controller
* so they chain explode, after helpers have been added to make it not cancer
*/
foreach (AMEShieldComponent core in _cores)
{
Explosion refactor (#5230) * Explosions * fix yaml typo and prevent silly UI inputs * oop * Use modified contains() checks And remove IEnumerable * Buff nuke, nerf meteors * optimize the entity lookup stuff a bit * fix tile (0,0) error forgot to do an initial Enumerator.MoveNext(), so the first tile was always the "null" tile. * remove celebration * byte -> int * remove diag edge tile dict * fix one bug but there is another * fix the other bug turns out dividing a ushort leads to rounding errors. Why TF is the grid tile size even a ushort in the first place. * improve edge map * fix minor bug If the initial-explosion tile had an airtight entity on it, the tile was processed twice. * some reviews (transform queries, eye.mapid, and tilesizes in overlays) * Apply suggestions from code review Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * is map paused * GetAllTiles ignores space by default * WriteLine -> WriteError * First -> FirstOrDefault() * default prototype const string * entity query * misc review changes * grid edge max distance * fix fire texture defn bad use of type serializer and ioc-resolves * Remove ExplosionLaunched And allow nukes to throw items towards the outer part of an explosion * no hot-reload disclaimer * replace prototype id string with int index * optimise damage a tiiiiny bit. * entity queries * comments * misc mirror comments * cvars * admin logs * move intensity-per-state to prototype * update tile event to ECS event * git mv * Tweak rpg & minibomb also fix merge bug * you don't exist anymore go away * Fix build Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2022-04-01 15:39:26 +13:00
radius += MasterController.InjectionAmount;
}
Explosion refactor (#5230) * Explosions * fix yaml typo and prevent silly UI inputs * oop * Use modified contains() checks And remove IEnumerable * Buff nuke, nerf meteors * optimize the entity lookup stuff a bit * fix tile (0,0) error forgot to do an initial Enumerator.MoveNext(), so the first tile was always the "null" tile. * remove celebration * byte -> int * remove diag edge tile dict * fix one bug but there is another * fix the other bug turns out dividing a ushort leads to rounding errors. Why TF is the grid tile size even a ushort in the first place. * improve edge map * fix minor bug If the initial-explosion tile had an airtight entity on it, the tile was processed twice. * some reviews (transform queries, eye.mapid, and tilesizes in overlays) * Apply suggestions from code review Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * is map paused * GetAllTiles ignores space by default * WriteLine -> WriteError * First -> FirstOrDefault() * default prototype const string * entity query * misc review changes * grid edge max distance * fix fire texture defn bad use of type serializer and ioc-resolves * Remove ExplosionLaunched And allow nukes to throw items towards the outer part of an explosion * no hot-reload disclaimer * replace prototype id string with int index * optimise damage a tiiiiny bit. * entity queries * comments * misc mirror comments * cvars * admin logs * move intensity-per-state to prototype * update tile event to ECS event * git mv * Tweak rpg & minibomb also fix merge bug * you don't exist anymore go away * Fix build Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2022-04-01 15:39:26 +13:00
radius *= 2;
radius = Math.Min(radius, 8);
EntitySystem.Get<ExplosionSystem>().TriggerExplosive(MasterController.Owner, radius: radius, delete: false);
}
}
}