[Dependency] private readonly ReactiveSystem _reactive = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
- private const float ReactTime = 0.125f;
-
public override void Initialize()
{
base.Initialize();
}
// Check for collision with a impassable object (e.g. wall) and stop
- if ((args.OtherFixture.CollisionLayer & (int) CollisionGroup.Impassable) != 0 && args.OtherFixture.Hard)
+ if ((args.OtherFixture.CollisionLayer & (int)CollisionGroup.Impassable) != 0 && args.OtherFixture.Hard)
{
EntityManager.QueueDeleteEntity(entity);
}
}
- public void Start(Entity<VaporComponent> vapor, TransformComponent vaporXform, Vector2 dir, float speed, MapCoordinates target, float aliveTime, EntityUid? user = null)
+ public void Start(Entity<VaporComponent> vapor,
+ TransformComponent vaporXform,
+ Vector2 dir,
+ float speed,
+ MapCoordinates target,
+ float aliveTime,
+ EntityUid? user = null)
{
vapor.Comp.Active = true;
var despawn = EnsureComp<TimedDespawnComponent>(vapor);
return false;
}
- if (!_solutionContainerSystem.TryGetSolution(vapor.Owner, VaporComponent.SolutionName, out var vaporSolution))
+ if (!_solutionContainerSystem.TryGetSolution(vapor.Owner,
+ VaporComponent.SolutionName,
+ out var vaporSolution))
{
return false;
}
public override void Update(float frameTime)
{
+ base.Update(frameTime);
+
+ // Enumerate over all VaporComponents
var query = EntityQueryEnumerator<VaporComponent, SolutionContainerManagerComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var vaporComp, out var container, out var xform))
{
- foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((uid, container)))
- {
- Update(frameTime, (uid, vaporComp), soln, xform);
- }
- }
- }
-
- private void Update(float frameTime, Entity<VaporComponent> ent, Entity<SolutionComponent> soln, TransformComponent xform)
- {
- var (entity, vapor) = ent;
- if (!vapor.Active)
- return;
-
- vapor.ReactTimer += frameTime;
-
- var contents = soln.Comp.Solution;
- if (vapor.ReactTimer >= ReactTime && TryComp(xform.GridUid, out MapGridComponent? gridComp))
- {
- vapor.ReactTimer = 0;
+ // Return early if we're not active
+ if (!vaporComp.Active)
+ continue;
- var tile = _map.GetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates);
- foreach (var reagentQuantity in contents.Contents.ToArray())
+ // Get the current location of the vapor entity first
+ if (TryComp(xform.GridUid, out MapGridComponent? gridComp))
{
- if (reagentQuantity.Quantity == FixedPoint2.Zero) continue;
- var reagent = _protoManager.Index<ReagentPrototype>(reagentQuantity.Reagent.Prototype);
+ var tile = _map.GetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates);
- var reaction =
- reagent.ReactionTile(tile, (reagentQuantity.Quantity / vapor.TransferAmount) * 0.25f, EntityManager, reagentQuantity.Reagent.Data);
+ // Check if the tile is a tile we've reacted with previously. If so, skip it.
+ // If we have no previous tile reference, we don't return so we can save one.
+ if (vaporComp.PreviousTileRef != null && tile == vaporComp.PreviousTileRef)
+ continue;
- if (reaction > reagentQuantity.Quantity)
+ // Enumerate over all the reagents in the vapor entity solution
+ foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((uid, container)))
{
- Log.Error($"Tried to tile react more than we have for reagent {reagentQuantity}. Found {reaction} and we only have {reagentQuantity.Quantity}");
- reaction = reagentQuantity.Quantity;
+ // Iterate over the reagents in the solution
+ // Reason: Each reagent in our solution may have a unique TileReaction
+ // In this instance, we check individually for each reagent's TileReaction
+ // This is not doing chemical reactions!
+ var contents = soln.Comp.Solution;
+ foreach (var reagentQuantity in contents.Contents.ToArray())
+ {
+ // Check if the reagent is empty
+ if (reagentQuantity.Quantity == FixedPoint2.Zero)
+ continue;
+
+ var reagent = _protoManager.Index<ReagentPrototype>(reagentQuantity.Reagent.Prototype);
+
+ // Limit the reaction amount to a minimum value to ensure no floating point funnies.
+ // Ex: A solution with a low percentage transfer amount will slowly approach 0.01... and never get deleted
+ var clampedAmount = Math.Max(
+ (float)reagentQuantity.Quantity * vaporComp.TransferAmountPercentage,
+ vaporComp.MinimumTransferAmount);
+
+ // Preform the reagent's TileReaction
+ var reaction =
+ reagent.ReactionTile(tile,
+ clampedAmount,
+ EntityManager,
+ reagentQuantity.Reagent.Data);
+
+ if (reaction > reagentQuantity.Quantity)
+ reaction = reagentQuantity.Quantity;
+
+ _solutionContainerSystem.RemoveReagent(soln, reagentQuantity.Reagent, reaction);
+ }
+
+ // Delete the vapor entity if it has no contents
+ if (contents.Volume == 0)
+ EntityManager.QueueDeleteEntity(uid);
+
}
- _solutionContainerSystem.RemoveReagent(soln, reagentQuantity.Reagent, reaction);
+ // Set the previous tile reference to the current tile
+ vaporComp.PreviousTileRef = tile;
}
}
-
- if (contents.Volume == 0)
- {
- // Delete this
- EntityManager.QueueDeleteEntity(entity);
- }
}
}
}