forked from space-wizards/space-station-14
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
740288e
commit 261747c
Showing
15 changed files
with
349 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using Content.Shared.Rootable; | ||
|
||
namespace Content.Client.Rootable; | ||
|
||
public sealed class RootableSystem : SharedRootableSystem | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
using Content.Server.Body.Components; | ||
using Content.Server.Body.Systems; | ||
using Content.Shared.Administration.Logs; | ||
using Content.Shared.Chemistry; | ||
using Content.Shared.Chemistry.Components; | ||
using Content.Shared.Chemistry.EntitySystems; | ||
using Content.Shared.Chemistry.Reagent; | ||
using Content.Shared.Database; | ||
using Content.Shared.FixedPoint; | ||
using Content.Shared.Fluids.Components; | ||
using Content.Shared.Rootable; | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Timing; | ||
|
||
namespace Content.Server.Rootable; | ||
|
||
/// <summary> | ||
/// Adds an action to toggle rooting to the ground, primarily for the Diona species. | ||
/// </summary> | ||
public sealed class RootableSystem : SharedRootableSystem | ||
{ | ||
|
||
[Dependency] private readonly ISharedAdminLogManager _logger = default!; | ||
[Dependency] private readonly IGameTiming _timing = default!; | ||
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; | ||
[Dependency] private readonly IPrototypeManager _prototype = default!; | ||
[Dependency] private readonly ReactiveSystem _reactive = default!; | ||
[Dependency] private readonly BloodstreamSystem _blood = default!; | ||
|
||
public override void Update(float frameTime) | ||
{ | ||
base.Update(frameTime); | ||
|
||
var query = EntityQueryEnumerator<RootableComponent>(); | ||
var curTime = _timing.CurTime; | ||
while (query.MoveNext(out var uid, out var rooted)) | ||
{ | ||
if (!rooted.Rooted || rooted.PuddleEntity == null || curTime < rooted.NextSecond) | ||
continue; | ||
|
||
rooted.NextSecond += TimeSpan.FromSeconds(1); | ||
|
||
PuddleReact(uid, rooted.PuddleEntity.Value); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Determines if the puddle is set up properly and if so, moves on to reacting. | ||
/// </summary> | ||
private void PuddleReact(EntityUid entity, EntityUid puddleUid, RootableComponent? rootableComponent = null, PuddleComponent? puddleComponent = null) | ||
{ | ||
if (!Resolve(entity, ref rootableComponent) || !Resolve(puddleUid, ref puddleComponent)) | ||
return; | ||
|
||
if (!_solutionContainerSystem.ResolveSolution(puddleUid, puddleComponent.SolutionName, ref puddleComponent.Solution, out var solution) || | ||
solution.Contents.Count == 0) | ||
{ | ||
return; | ||
} | ||
|
||
ReactWithEntity(entity, puddleUid, solution, rootableComponent, puddleComponent); | ||
} | ||
|
||
/// <summary> | ||
/// Attempt to transfer an amount of the solution to the entity's bloodstream. | ||
/// </summary> | ||
private void ReactWithEntity(EntityUid entity, EntityUid puddleUid, Solution solution, RootableComponent? rootableComponent = null, PuddleComponent? puddleComponent = null) | ||
{ | ||
if (!Resolve(entity, ref rootableComponent) || !Resolve(puddleUid, ref puddleComponent) || puddleComponent.Solution == null) | ||
return; | ||
|
||
if (!TryComp<BloodstreamComponent>(entity, out var bloodstream)) | ||
return; | ||
|
||
if (!_solutionContainerSystem.ResolveSolution(entity, bloodstream.ChemicalSolutionName, ref bloodstream.ChemicalSolution, out var chemSolution) || chemSolution.AvailableVolume <= 0) | ||
return; | ||
|
||
var availableTransfer = FixedPoint2.Min(solution.Volume, rootableComponent.TransferRate); | ||
var transferAmount = FixedPoint2.Min(availableTransfer, chemSolution.AvailableVolume); | ||
var transferSolution = _solutionContainerSystem.SplitSolution(puddleComponent.Solution.Value, transferAmount); | ||
|
||
foreach (var reagentQuantity in transferSolution.Contents.ToArray()) | ||
{ | ||
if (reagentQuantity.Quantity == FixedPoint2.Zero) | ||
continue; | ||
var reagentProto = _prototype.Index<ReagentPrototype>(reagentQuantity.Reagent.Prototype); | ||
|
||
_reactive.ReactionEntity(entity, ReactionMethod.Ingestion, reagentProto, reagentQuantity, transferSolution); | ||
} | ||
|
||
if (_blood.TryAddToChemicals(entity, transferSolution, bloodstream)) | ||
{ | ||
// Log solution addition by puddle | ||
_logger.Add(LogType.ForceFeed, LogImpact.Medium, $"{ToPrettyString(entity):target} absorbed puddle {SharedSolutionContainerSystem.ToPrettyString(transferSolution)}"); | ||
} | ||
} | ||
} |
4 changes: 1 addition & 3 deletions
4
...omponents/DamageUserOnTriggerComponent.cs → ...omponents/DamageUserOnTriggerComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using Content.Shared.Alert; | ||
using Content.Shared.FixedPoint; | ||
using Robust.Shared.GameStates; | ||
using Robust.Shared.Prototypes; | ||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; | ||
|
||
namespace Content.Shared.Rootable; | ||
|
||
/// <summary> | ||
/// A rooting action, for Diona. | ||
/// </summary> | ||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] | ||
public sealed partial class RootableComponent : Component | ||
{ | ||
[DataField] | ||
public EntProtoId Action = "ActionToggleRootable"; | ||
|
||
[DataField] | ||
public ProtoId<AlertPrototype> RootedAlert = "Rooted"; | ||
|
||
[DataField] | ||
public EntityUid? ActionEntity; | ||
|
||
/// <summary> | ||
/// Is the entity currently rooted? | ||
/// </summary> | ||
[DataField, AutoNetworkedField] | ||
public bool Rooted = false; | ||
|
||
/// <summary> | ||
/// The puddle that is currently affecting this entity. | ||
/// </summary> | ||
[DataField] | ||
public EntityUid? PuddleEntity; | ||
|
||
/// <summary> | ||
/// The time at which the next absorption metabolism will occur. | ||
/// </summary> | ||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] | ||
[AutoPausedField] | ||
public TimeSpan NextSecond; | ||
|
||
/// <summary> | ||
/// The max rate at which chemicals are transferred from the puddle to the rooted entity. | ||
/// </summary> | ||
[DataField] | ||
public FixedPoint2 TransferRate = 0.75; | ||
|
||
/// <summary> | ||
/// The movement speed modifier for when rooting is active. | ||
/// </summary> | ||
[DataField] | ||
public float SpeedModifier = 0.8f; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
using Content.Shared.Damage.Components; | ||
using Content.Shared.Actions; | ||
using Content.Shared.Alert; | ||
using Content.Shared.Fluids.Components; | ||
using Content.Shared.Gravity; | ||
using Content.Shared.Mobs; | ||
using Content.Shared.Movement.Systems; | ||
using Content.Shared.Slippery; | ||
using Content.Shared.Toggleable; | ||
using Robust.Shared.Physics.Components; | ||
using Robust.Shared.Physics.Events; | ||
using Robust.Shared.Physics.Systems; | ||
using Robust.Shared.Timing; | ||
|
||
namespace Content.Shared.Rootable; | ||
|
||
/// <summary> | ||
/// Adds an action to toggle rooting to the ground, primarily for the Diona species. | ||
/// </summary> | ||
public abstract class SharedRootableSystem : EntitySystem | ||
{ | ||
[Dependency] private readonly IGameTiming _timing = default!; | ||
[Dependency] private readonly SharedActionsSystem _actions = default!; | ||
[Dependency] private readonly SharedGravitySystem _gravity = default!; | ||
[Dependency] private readonly SharedPhysicsSystem _physics = default!; | ||
[Dependency] private readonly IEntityManager _entityManager = default!; | ||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; | ||
[Dependency] private readonly AlertsSystem _alerts = default!; | ||
|
||
private EntityQuery<PuddleComponent> _puddleQuery; | ||
|
||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
|
||
_puddleQuery = GetEntityQuery<PuddleComponent>(); | ||
|
||
SubscribeLocalEvent<RootableComponent, MapInitEvent>(OnRootableMapInit); | ||
SubscribeLocalEvent<RootableComponent, ComponentShutdown>(OnRootableShutdown); | ||
SubscribeLocalEvent<RootableComponent, StartCollideEvent>(OnStartCollide); | ||
SubscribeLocalEvent<RootableComponent, EndCollideEvent>(OnEndCollide); | ||
SubscribeLocalEvent<RootableComponent, ToggleActionEvent>(OnRootableToggle); | ||
SubscribeLocalEvent<RootableComponent, MobStateChangedEvent>(OnMobStateChanged); | ||
SubscribeLocalEvent<RootableComponent, IsWeightlessEvent>(OnIsWeightless); | ||
SubscribeLocalEvent<RootableComponent, SlipAttemptEvent>(OnSlipAttempt); | ||
SubscribeLocalEvent<RootableComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeed); | ||
} | ||
|
||
private void OnRootableMapInit(EntityUid uid, RootableComponent component, MapInitEvent args) | ||
{ | ||
_actions.AddAction(uid, ref component.ActionEntity, component.Action, uid); | ||
} | ||
|
||
private void OnRootableShutdown(EntityUid uid, RootableComponent component, ComponentShutdown args) | ||
{ | ||
_actions.RemoveAction(uid, component.ActionEntity); | ||
} | ||
|
||
private void OnRootableToggle(EntityUid uid, RootableComponent component, ref ToggleActionEvent args) | ||
{ | ||
args.Handled = TryToggleRooting(uid, rooted: component); | ||
} | ||
|
||
private void OnMobStateChanged(EntityUid uid, RootableComponent component, MobStateChangedEvent args) | ||
{ | ||
if (component.Rooted) | ||
TryToggleRooting(uid, rooted: component); | ||
} | ||
|
||
public bool TryToggleRooting(EntityUid uid, RootableComponent? rooted = null) | ||
{ | ||
if (!Resolve(uid, ref rooted)) | ||
return false; | ||
|
||
rooted.Rooted = !rooted.Rooted; | ||
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid); | ||
Dirty(uid, rooted); | ||
|
||
if (rooted.Rooted) | ||
_alerts.ShowAlert(uid, rooted.RootedAlert); | ||
else | ||
_alerts.ClearAlert(uid, rooted.RootedAlert); | ||
|
||
return true; | ||
} | ||
|
||
private void OnIsWeightless(Entity<RootableComponent> ent, ref IsWeightlessEvent args) | ||
{ | ||
if (args.Handled || !ent.Comp.Rooted) | ||
return; | ||
|
||
// do not cancel weightlessness if the person is in off-grid. | ||
if (!_gravity.EntityOnGravitySupportingGridOrMap(ent.Owner)) | ||
return; | ||
|
||
args.IsWeightless = false; | ||
args.Handled = true; | ||
} | ||
|
||
private void OnSlipAttempt(Entity<RootableComponent> ent, ref SlipAttemptEvent args) | ||
{ | ||
if (!ent.Comp.Rooted) | ||
return; | ||
|
||
if (args.SlipCausingEntity != null && HasComp<DamageUserOnTriggerComponent>(args.SlipCausingEntity)) | ||
return; | ||
|
||
args.NoSlip = true; | ||
} | ||
|
||
private void OnStartCollide(Entity<RootableComponent> entity, ref StartCollideEvent args) | ||
{ | ||
if (!_entityManager.HasComponent<PuddleComponent>(args.OtherEntity)) | ||
{ | ||
return; | ||
} | ||
|
||
entity.Comp.PuddleEntity = args.OtherEntity; | ||
|
||
if (entity.Comp.NextSecond < _timing.CurTime) // To prevent constantly moving to new puddles resetting the timer | ||
entity.Comp.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1); | ||
} | ||
|
||
private void OnEndCollide(Entity<RootableComponent> entity, ref EndCollideEvent args) | ||
{ | ||
if (entity.Comp.PuddleEntity != args.OtherEntity) | ||
return; | ||
|
||
var exists = Exists(args.OtherEntity); | ||
|
||
if (!TryComp<PhysicsComponent>(entity, out var body)) | ||
return; | ||
|
||
foreach (var ent in _physics.GetContactingEntities(entity, body)) | ||
{ | ||
if (exists && ent == args.OtherEntity) | ||
continue; | ||
|
||
if (!_puddleQuery.HasComponent(ent)) | ||
continue; | ||
|
||
entity.Comp.PuddleEntity = ent; | ||
return; // New puddle found, no need to continue | ||
} | ||
|
||
entity.Comp.PuddleEntity = null; | ||
} | ||
|
||
private void OnRefreshMovementSpeed(Entity<RootableComponent> entity, ref RefreshMovementSpeedModifiersEvent args) | ||
{ | ||
if (entity.Comp.Rooted) | ||
args.ModifySpeed(entity.Comp.SpeedModifier); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
action-name-toggle-rootable = Rootable | ||
action-description-toggle-rootable = Begin or stop being rooted to the floor. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.