Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mass Bug Fixes #452

Merged
merged 10 commits into from
Jan 4, 2025
13 changes: 8 additions & 5 deletions Content.Client/Effects/ColorFlashEffectSystem.cs
Original file line number Diff line number Diff line change
@@ -45,7 +45,9 @@ private void OnEffectAnimationCompleted(EntityUid uid, ColorFlashEffectComponent
sprite.Color = component.Color;
}

RemCompDeferred<ColorFlashEffectComponent>(uid);
// Floof - commented this out due to a race condition. It's quite complicated to explain;
// in short terms, don't do deferred component removal when dealing with concurrent tasks concerning the same component.
// RemCompDeferred<ColorFlashEffectComponent>(uid);
}

private Animation? GetDamageAnimation(EntityUid uid, Color color, SpriteComponent? sprite = null)
@@ -107,10 +109,11 @@ private void OnColorFlashEffect(ColorFlashEffectEvent ev)
continue;
}

if (TryComp<ColorFlashEffectComponent>(ent, out var effect))
{
sprite.Color = effect.Color;
}
// Floof - commented out. This is handled by the animation complete event.
// if (TryComp<ColorFlashEffectComponent>(ent, out var effect))
// {
// sprite.Color = effect.Color;
// }

var animation = GetDamageAnimation(ent, color, sprite);

2 changes: 1 addition & 1 deletion Content.Server/Carrying/CarryingSystem.cs
Original file line number Diff line number Diff line change
@@ -273,6 +273,7 @@ private void Carry(EntityUid carrier, EntityUid carried)
if (TryComp<PullableComponent>(carried, out var pullable))
_pullingSystem.TryStopPull(carried, pullable);

EnsureComp<KnockedDownComponent>(carried); // Floof - moved this statement up because some systems can break carrying in response to knockdown
_transform.AttachToGridOrMap(carrier);
_transform.AttachToGridOrMap(carried);
_transform.SetCoordinates(carried, Transform(carrier).Coordinates);
@@ -282,7 +283,6 @@ private void Carry(EntityUid carrier, EntityUid carried)
var carryingComp = EnsureComp<CarryingComponent>(carrier);
ApplyCarrySlowdown(carrier, carried);
var carriedComp = EnsureComp<BeingCarriedComponent>(carried);
EnsureComp<KnockedDownComponent>(carried);

carryingComp.Carried = carried;
carriedComp.Carrier = carrier;
94 changes: 42 additions & 52 deletions Content.Server/FootPrint/FootPrintsSystem.cs
Original file line number Diff line number Diff line change
@@ -11,34 +11,33 @@
using Content.Shared.Forensics;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;

namespace Content.Server.FootPrint;

// Floof: this system has been effectively rewritten. DO NOT MERGE UPSTREAM CHANGES.
public sealed class FootPrintsSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;

[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!; // Floof
[Dependency] private readonly EntityLookupSystem _lookup = default!;

private EntityQuery<TransformComponent> _transformQuery;
private EntityQuery<MobThresholdsComponent> _mobThresholdQuery;
private EntityQuery<AppearanceComponent> _appearanceQuery;
private EntityQuery<LayingDownComponent> _layingQuery;
private EntityQuery<StandingStateComponent> _standingStateQuery;

public override void Initialize()
{
base.Initialize();

_transformQuery = GetEntityQuery<TransformComponent>();
_mobThresholdQuery = GetEntityQuery<MobThresholdsComponent>();
_appearanceQuery = GetEntityQuery<AppearanceComponent>();
_layingQuery = GetEntityQuery<LayingDownComponent>();
_standingStateQuery = GetEntityQuery<StandingStateComponent>();

SubscribeLocalEvent<FootPrintsComponent, ComponentStartup>(OnStartupComponent);
SubscribeLocalEvent<FootPrintsComponent, MoveEvent>(OnMove);
@@ -51,81 +50,72 @@ private void OnStartupComponent(EntityUid uid, FootPrintsComponent component, Co

private void OnMove(EntityUid uid, FootPrintsComponent component, ref MoveEvent args)
{
// Floof: clear stored DNAs if footprints are now invisible
if (component.PrintsColor.A <= .3f)
component.DNAs.Clear();

if (component.PrintsColor.A <= .3f // avoid creating footsteps that are invisible
if (component.ContainedSolution.Volume <= 0
|| TryComp<PhysicsComponent>(uid, out var physics) && physics.BodyStatus != BodyStatus.OnGround // Floof: do not create footprints if the entity is flying
|| !_transformQuery.TryComp(uid, out var transform)
|| !_mobThresholdQuery.TryComp(uid, out var mobThreshHolds)
|| !_map.TryFindGridAt(_transform.GetMapCoordinates((uid, transform)), out var gridUid, out _))
|| args.Entity.Comp1.GridUid is not {} gridUid)
return;

// Floof - this is dumb
// var dragging = mobThreshHolds.CurrentThresholdState is MobState.Critical or MobState.Dead
// || _layingQuery.TryComp(uid, out var laying) && laying.IsCrawlingUnder;
var dragging = TryComp<StandingStateComponent>(uid, out var standing) && standing.CurrentState == StandingState.Lying; // Floof - replaced the above
var distance = (transform.LocalPosition - component.StepPos).Length();
var newPos = _transform.ToMapCoordinates(args.NewPosition).Position;
var dragging = _standingStateQuery.TryComp(uid, out var standing) && standing.CurrentState == StandingState.Lying;
var distance = (newPos - component.LastStepPos).Length();
var stepSize = dragging ? component.DragSize : component.StepSize;

if (!(distance > stepSize))
if (distance < stepSize)
return;

// Floof section
// are we on a puddle? we exit, ideally we would exchange liquid and DNA with the puddle but meh, too lazy to do that now.
var entities = _lookup.GetEntitiesIntersecting(uid, LookupFlags.All);
foreach (var entityUid in entities.Where(entityUid => HasComp<PuddleFootPrintsComponent>(entityUid)))
return; // are we on a puddle? we exit, ideally we would exchange liquid and DNA with the puddle but meh, too lazy to do that now.
// Floof section end

component.RightStep = !component.RightStep;
if (entities.Any(HasComp<PuddleFootPrintsComponent>))
return;

var entity = Spawn(component.StepProtoId, CalcCoords(gridUid, component, transform, dragging));
var footPrintComponent = EnsureComp<FootPrintComponent>(entity);
// Spawn the footprint
var footprintUid = Spawn(component.StepProtoId, CalcCoords(gridUid, component, args.Component, dragging));
var stepTransform = Transform(footprintUid);
var footPrintComponent = EnsureComp<FootPrintComponent>(footprintUid);

// Floof section
var forensics = EntityManager.EnsureComponent<ForensicsComponent>(entity);
if (TryComp<ForensicsComponent>(uid, out var ownerForensics)) // transfer owner DNA into the footsteps
// transfer owner DNA into the footsteps
var forensics = EntityManager.EnsureComponent<ForensicsComponent>(footprintUid);
if (TryComp<ForensicsComponent>(uid, out var ownerForensics))
forensics.DNAs.UnionWith(ownerForensics.DNAs);
// Floof section end

footPrintComponent.PrintOwner = uid;
Dirty(entity, footPrintComponent);
Dirty(footprintUid, footPrintComponent);

if (_appearanceQuery.TryComp(entity, out var appearance))
if (_appearanceQuery.TryComp(footprintUid, out var appearance))
{
_appearance.SetData(entity, FootPrintVisualState.State, PickState(uid, dragging), appearance);
_appearance.SetData(entity, FootPrintVisualState.Color, component.PrintsColor, appearance);
}
var color = component.ContainedSolution.GetColor(_protoMan);
color.A = Math.Max(0.3f, component.ContainedSolution.FillFraction);

if (!_transformQuery.TryComp(entity, out var stepTransform))
return;
_appearance.SetData(footprintUid, FootPrintVisualState.State, PickState(uid, dragging), appearance);
_appearance.SetData(footprintUid, FootPrintVisualState.Color, color, appearance);
}

stepTransform.LocalRotation = dragging
? (transform.LocalPosition - component.StepPos).ToAngle() + Angle.FromDegrees(-90f)
: transform.LocalRotation + Angle.FromDegrees(180f);
? (newPos - component.LastStepPos).ToAngle() + Angle.FromDegrees(-90f)
: args.Component.LocalRotation + Angle.FromDegrees(180f);

component.PrintsColor = component.PrintsColor.WithAlpha(Math.Max(0f, component.PrintsColor.A - component.ColorReduceAlpha));
component.StepPos = transform.LocalPosition;

if (!TryComp<SolutionContainerManagerComponent>(entity, out var solutionContainer)
|| !_solution.ResolveSolution((entity, solutionContainer), footPrintComponent.SolutionName, ref footPrintComponent.Solution, out var solution)
|| string.IsNullOrWhiteSpace(component.ReagentToTransfer) || solution.Volume >= 1)
if (!TryComp<SolutionContainerManagerComponent>(footprintUid, out var solutionContainer)
|| !_solution.ResolveSolution((footprintUid, solutionContainer), footPrintComponent.SolutionName, ref footPrintComponent.Solution, out var solution))
return;

_solution.TryAddReagent(footPrintComponent.Solution.Value, component.ReagentToTransfer, 1, out _);
// Transfer from the component to the footprint
var removedReagents = component.ContainedSolution.SplitSolution(component.FootprintVolume);
_solution.ForceAddSolution(footPrintComponent.Solution.Value, removedReagents);

component.RightStep = !component.RightStep;
component.LastStepPos = newPos;
}

private EntityCoordinates CalcCoords(EntityUid uid, FootPrintsComponent component, TransformComponent transform, bool state)
{
if (state)
return new EntityCoordinates(uid, transform.LocalPosition);
return new(uid, transform.LocalPosition);

var offset = component.RightStep
? new Angle(Angle.FromDegrees(180f) + transform.LocalRotation).RotateVec(component.OffsetPrint)
: new Angle(transform.LocalRotation).RotateVec(component.OffsetPrint);

return new EntityCoordinates(uid, transform.LocalPosition + offset);
return new(uid, transform.LocalPosition + offset);
}

private FootPrintVisuals PickState(EntityUid uid, bool dragging)
40 changes: 16 additions & 24 deletions Content.Server/FootPrint/PuddleFootPrintsSystem.cs
Original file line number Diff line number Diff line change
@@ -2,16 +2,20 @@
using Content.Shared.FootPrint;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.FixedPoint;
using Content.Shared.Fluids;
using Content.Shared.Fluids.Components;
using Content.Shared.Forensics;
using Robust.Shared.Physics.Events;
using Robust.Shared.Prototypes;


namespace Content.Server.FootPrint;

// Floof: this system has been effectively rewritten. DO NOT MERGE UPSTREAM CHANGES.
public sealed class PuddleFootPrintsSystem : EntitySystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;

public override void Initialize()
@@ -22,39 +26,27 @@ public override void Initialize()

private void OnStepTrigger(EntityUid uid, PuddleFootPrintsComponent component, ref EndCollideEvent args)
{
if (!TryComp<AppearanceComponent>(uid, out var appearance)
|| !TryComp<PuddleComponent>(uid, out var puddle)
|| !TryComp<FootPrintsComponent>(args.OtherEntity, out var tripper)
|| !TryComp<SolutionContainerManagerComponent>(uid, out var solutionManager)
|| !_solutionContainer.ResolveSolution((uid, solutionManager), puddle.SolutionName, ref puddle.Solution, out var solutions))
return;

var totalSolutionQuantity = solutions.Contents.Sum(sol => (float) sol.Quantity);
var waterQuantity = (from sol in solutions.Contents where sol.Reagent.Prototype == "Water" select (float) sol.Quantity).FirstOrDefault();

if (waterQuantity / (totalSolutionQuantity / 100f) > component.OffPercent || solutions.Contents.Count <= 0)
if (!TryComp<PuddleComponent>(uid, out var puddle) || !TryComp<FootPrintsComponent>(args.OtherEntity, out var tripper))
return;

tripper.ReagentToTransfer =
solutions.Contents.Aggregate((l, r) => l.Quantity > r.Quantity ? l : r).Reagent.Prototype;

// Transfer DNAs from the puddle to the tripper
if (TryComp<ForensicsComponent>(uid, out var puddleForensics))
{
tripper.DNAs.UnionWith(puddleForensics.DNAs);
if(TryComp<ForensicsComponent>(args.OtherEntity, out var tripperForensics))
tripperForensics.DNAs.UnionWith(puddleForensics.DNAs);
}

if (_appearance.TryGetData(uid, PuddleVisuals.SolutionColor, out var color, appearance)
&& _appearance.TryGetData(uid, PuddleVisuals.CurrentVolume, out var volume, appearance))
AddColor((Color) color, (float) volume * component.SizeRatio, tripper);
// Transfer reagents from the puddle to the tripper.
// Ideally it should be a two-way process, but that is too hard to simulate and will have very little effect outside of potassium-water spills.
var quantity = puddle.Solution?.Comp?.Solution?.Volume ?? 0;
var footprintsCapacity = tripper.ContainedSolution.AvailableVolume;

_solutionContainer.RemoveEachReagent(puddle.Solution.Value, 1);
}
if (quantity <= 0 || footprintsCapacity <= 0)
return;

private void AddColor(Color col, float quantity, FootPrintsComponent component)
{
component.PrintsColor = component.ColorQuantity == 0f ? col : Color.InterpolateBetween(component.PrintsColor, col, component.ColorInterpolationFactor);
component.ColorQuantity += quantity;
var transferAmount = FixedPoint2.Min(footprintsCapacity, quantity * component.SizeRatio);
var transferred = _solutionContainer.SplitSolution(puddle.Solution!.Value, transferAmount);
tripper.ContainedSolution.AddSolution(transferred, _protoMan);
}
}
3 changes: 2 additions & 1 deletion Content.Server/Instruments/InstrumentSystem.cs
Original file line number Diff line number Diff line change
@@ -252,7 +252,8 @@ private void OnBoundUIRequestBands(EntityUid uid, InstrumentComponent component,
// Maybe a bit expensive but oh well GetBands is queued and has a timer anyway.
// Make sure the instrument is visible, uses the Opaque collision group so this works across windows etc.
if (!_interactions.InRangeUnobstructed(uid, entity, MaxInstrumentBandRange,
CollisionGroup.Opaque, e => e == playerUid || e == originPlayer))
CollisionGroup.Opaque,
e => e == playerUid || e == originPlayer || !HasComp<OccluderComponent>(e))) // Floof - added the occluder check.
continue;

if (!metadataQuery.TryGetComponent(playerUid, out var playerMetadata)
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ private void OnInteractUsing(EntityUid uid, DeepFryerComponent component, Intera

private void OnInsertItem(EntityUid uid, DeepFryerComponent component, DeepFryerInsertItemMessage args)
{
var user = EntityManager.GetEntity(args.Entity);
var user = args.Actor; // Floof - fix

if (!TryComp<HandsComponent>(user, out var handsComponent) ||
handsComponent.ActiveHandEntity == null)
Original file line number Diff line number Diff line change
@@ -524,7 +524,7 @@ private void OnRemoveItem(EntityUid uid, DeepFryerComponent component, DeepFryer
if (!_containerSystem.Remove(removedItem, component.Storage))
return;

var user = EntityManager.GetEntity(args.Entity);
var user = args.Actor; // Floof - fix;

_handsSystem.TryPickupAnyHand(user, removedItem);

@@ -577,7 +577,7 @@ private bool TryGetActiveHandSolutionContainer(

private void OnScoopVat(EntityUid uid, DeepFryerComponent component, DeepFryerScoopVatMessage args)
{
var user = EntityManager.GetEntity(args.Entity);
var user = args.Actor; // Floof - fix

if (!TryGetActiveHandSolutionContainer(uid, user, out var heldItem, out var heldSolution,
out var transferAmount))
@@ -598,7 +598,7 @@ private void OnScoopVat(EntityUid uid, DeepFryerComponent component, DeepFryerSc

private void OnClearSlagStart(EntityUid uid, DeepFryerComponent component, DeepFryerClearSlagMessage args)
{
var user = EntityManager.GetEntity(args.Entity);
var user = args.Actor; // Floof - fix

if (!TryGetActiveHandSolutionContainer(uid, user, out var heldItem, out var heldSolution,
out var transferAmount))
@@ -639,7 +639,7 @@ private void OnRemoveAllItems(EntityUid uid, DeepFryerComponent component, DeepF

_containerSystem.EmptyContainer(component.Storage);

var user = EntityManager.GetEntity(args.Entity);
var user = args.Actor; // Floof - fix

_adminLogManager.Add(LogType.Action, LogImpact.Low,
$"{ToPrettyString(user)} removed all items from {ToPrettyString(uid)}.");
Loading