Merge remote-tracking branch 'upstream/master' into rt-265-update

This commit is contained in:
PJB3005
2025-07-23 01:17:46 +02:00
12 changed files with 131 additions and 55 deletions

View File

@@ -334,7 +334,12 @@ namespace Content.Client.Actions
private void OnEntityTargetAttempt(Entity<EntityTargetActionComponent> ent, ref ActionTargetAttemptEvent args)
{
if (args.Handled || args.Input.EntityUid is not { Valid: true } entity)
if (args.Handled)
return;
args.Handled = true;
if (args.Input.EntityUid is not { Valid: true } entity)
return;
// let world target component handle it
@@ -345,8 +350,6 @@ namespace Content.Client.Actions
return;
}
args.Handled = true;
var action = args.Action;
var user = args.User;

View File

@@ -1,4 +1,3 @@
using System.Threading;
using Content.Server.GameTicking;
using Content.Server.RoundEnd;
using Content.Shared.CCVar;
@@ -22,7 +21,7 @@ namespace Content.IntegrationTests.Tests
private void OnRoundEnd(RoundEndSystemChangedEvent ev)
{
Interlocked.Increment(ref RoundCount);
RoundCount += 1;
}
}
@@ -127,13 +126,17 @@ namespace Content.IntegrationTests.Tests
async Task WaitForEvent()
{
var timeout = Task.Delay(TimeSpan.FromSeconds(10));
var currentCount = Thread.VolatileRead(ref sys.RoundCount);
while (currentCount == Thread.VolatileRead(ref sys.RoundCount) && !timeout.IsCompleted)
const int maxTicks = 60;
var currentCount = sys.RoundCount;
for (var i = 0; i < maxTicks; i++)
{
await pair.RunTicksSync(5);
if (currentCount != sys.RoundCount)
return;
await pair.RunTicksSync(1);
}
if (timeout.IsCompleted) throw new TimeoutException("Event took too long to trigger");
throw new TimeoutException("Event took too long to trigger");
}
// Need to clean self up

View File

@@ -1,6 +1,6 @@
using Content.Shared.Actions;
using Content.Shared.Interaction;
using Robust.Shared.GameStates;
using Content.Shared.Interaction;
using Content.Shared.Physics;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared.Actions.Components;
@@ -37,6 +37,16 @@ public sealed partial class TargetActionComponent : Component
[DataField]
public bool CheckCanAccess = true;
/// <summary>
/// The collision group to use to check for accessibility if <see cref="CheckCanAccess" /> is true.
/// </summary>
[DataField]
public CollisionGroup AccessMask = SharedInteractionSystem.InRangeUnobstructedMask;
/// <summary>
/// The allowed range for a target to be. If zero or negative, the range check is skipped,
/// unless <see cref="CheckCanAccess"/> is true.
/// </summary>
[DataField]
public float Range = SharedInteractionSystem.InteractionRange;

View File

@@ -417,13 +417,18 @@ public abstract class SharedActionsSystem : EntitySystem
return comp.CanTargetSelf;
var targetAction = Comp<TargetActionComponent>(uid);
// not using the ValidateBaseTarget logic since its raycast fails if the target is e.g. a wall
if (targetAction.CheckCanAccess)
return _interaction.InRangeAndAccessible(user, target, range: targetAction.Range);
return _interaction.InRangeAndAccessible(user, target, targetAction.Range, targetAction.AccessMask);
// if not just checking pure range, let stored entities be targeted by actions
// if it's out of range it probably isn't stored anyway...
return _interaction.CanAccessViaStorage(user, target);
// Just check normal in range, allowing <= 0 range to mean infinite range.
if (targetAction.Range > 0
&& !_transform.InRange(user, target, targetAction.Range))
return false;
// If checkCanAccess isn't set, we allow targeting things in containers
return _interaction.IsAccessible(user, target);
}
public bool ValidateWorldTarget(EntityUid user, EntityCoordinates target, Entity<WorldTargetActionComponent> ent)

View File

@@ -86,7 +86,11 @@ namespace Content.Shared.Interaction
private EntityQuery<UseDelayComponent> _delayQuery;
private EntityQuery<ActivatableUIComponent> _uiQuery;
private const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
/// <summary>
/// The collision mask used by default for
/// <see cref="InRangeUnobstructed(MapCoordinates,MapCoordinates,float,CollisionGroup,Ignored?,bool)" />
/// </summary>
public const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
public const float InteractionRange = 1.5f;
public const float InteractionRangeSquared = InteractionRange * InteractionRange;

View File

@@ -1,29 +1,49 @@
using Content.Shared.CCVar;
using Content.Shared.StatusIcon;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.SSDIndicator;
/// <summary>
/// Shows status icon when player in SSD
/// Shows status icon when an entity is SSD, based on if a player is attached or not.
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState, AutoGenerateComponentPause]
public sealed partial class SSDIndicatorComponent : Component
{
[DataField, ViewVariables(VVAccess.ReadOnly)]
/// <summary>
/// Whether or not the entity is SSD.
/// </summary>
[AutoNetworkedField]
[DataField, ViewVariables(VVAccess.ReadOnly)]
public bool IsSSD = true;
/// <summary>
/// The icon displayed next to the associated entity when it is SSD.
/// </summary>
[DataField]
public ProtoId<SsdIconPrototype> Icon = "SSDIcon";
/// <summary>
/// When the entity should fall asleep
/// The time at which the entity will fall asleep, if <see cref="CCVars.ICSSDSleep"/> is true.
/// </summary>
[DataField]
[AutoNetworkedField, AutoPausedField]
[Access(typeof(SSDIndicatorSystem))]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan FallAsleepTime = TimeSpan.Zero;
/// <summary>
/// The next time this component will be updated.
/// </summary>
[AutoNetworkedField, AutoPausedField]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextUpdate = TimeSpan.Zero;
/// <summary>
/// The time between updates checking if the entity should be force slept.
/// </summary>
[DataField]
public TimeSpan UpdateInterval = TimeSpan.FromSeconds(1);
}

View File

@@ -61,12 +61,12 @@ public sealed class SSDIndicatorSystem : EntitySystem
// Prevents mapped mobs to go to sleep immediately
private void OnMapInit(EntityUid uid, SSDIndicatorComponent component, MapInitEvent args)
{
if (_icSsdSleep &&
component.IsSSD &&
component.FallAsleepTime == TimeSpan.Zero)
{
component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime);
}
if (!_icSsdSleep || !component.IsSSD)
return;
component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime);
component.NextUpdate = _timing.CurTime + component.UpdateInterval;
Dirty(uid, component);
}
public override void Update(float frameTime)
@@ -76,17 +76,21 @@ public sealed class SSDIndicatorSystem : EntitySystem
if (!_icSsdSleep)
return;
var curTime = _timing.CurTime;
var query = EntityQueryEnumerator<SSDIndicatorComponent>();
while (query.MoveNext(out var uid, out var ssd))
{
// Forces the entity to sleep when the time has come
if (ssd.IsSSD &&
ssd.FallAsleepTime <= _timing.CurTime &&
!TerminatingOrDeleted(uid))
{
_statusEffects.TrySetStatusEffectDuration(uid, StatusEffectSSDSleeping, null);
}
if (!ssd.IsSSD
|| ssd.NextUpdate > curTime
|| ssd.FallAsleepTime > curTime
|| TerminatingOrDeleted(uid))
continue;
_statusEffects.TryUpdateStatusEffectDuration(uid, StatusEffectSSDSleeping);
ssd.NextUpdate += ssd.UpdateInterval;
Dirty(uid, ssd);
}
}
}

View File

@@ -1,19 +1,4 @@
Entries:
- author: HyperB1
changes:
- message: ERT engineering hardsuit now features proper fire protection.
type: Fix
id: 8285
time: '2025-04-20T14:06:14.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/34949
- author: K-Dynamic
changes:
- message: Nonlethal throwables crate can be ordered from cargo (2500 spesos) and
contains 4x bolas, 4x flashbang grenades, 4x tear gas grenades, 4x stinger grenades.
type: Add
id: 8286
time: '2025-04-20T14:08:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/35808
- author: RedBookcase
changes:
- message: Updated Pirate weapons & hardsuits to be more inline with similar items.
@@ -3905,3 +3890,20 @@
id: 8797
time: '2025-07-21T03:21:28.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/38648
- author: ArtisticRoomba
changes:
- message: China-lake fragmentation grenades now spew fragmentation in all directions
upon impact. They now do reduced explosion damage.
type: Tweak
- message: China-lake blast grenades no longer cause spacing.
type: Tweak
id: 8798
time: '2025-07-22T15:05:46.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/39106
- author: perryprog
changes:
- message: Void applause should now function as expected again.
type: Fix
id: 8799
time: '2025-07-22T19:34:39.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/38731

View File

@@ -2176,6 +2176,7 @@
- type: entity
parent: [ SimpleMobBase, FlyingMobBase ]
id: MobParrotBase
name: parrot
abstract: true
description: Infiltrates your domain, spies on you, and somehow still a cool pet.
components:
@@ -2251,7 +2252,6 @@
bloodMaxVolume: 50
- type: entity
name: parrot
parent: MobParrotBase
id: MobParrot
components:

View File

@@ -54,3 +54,20 @@
count: 10
- type: TimedDespawn
lifetime: 0.25
- type: entity
id: PelletClusterLessLethal
name: pellet (ball, less lethal)
categories: [ HideSpawnMenu ]
parent: BaseBullet
components:
- type: Sprite
sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi
state: buckshot
- type: Projectile
deleteOnCollide: false
damage:
types:
Piercing: 5
- type: TimedDespawn
lifetime: 0.25

View File

@@ -863,6 +863,7 @@
totalIntensity: 150 # a ~2 tile radius
intensitySlope: 5
maxIntensity: 10
canCreateVacuum: false
- type: entity
id: BulletGrenadeFlash
@@ -882,7 +883,6 @@
timeRemaining: 0.3
- type: DeleteOnTrigger
# This is supposed to spawn shrapnel and stuff so uhh... TODO?
- type: entity
id: BulletGrenadeFrag
name: frag grenade
@@ -896,9 +896,16 @@
- type: ExplodeOnTrigger
- type: Explosive
explosionType: Default
totalIntensity: 175 # about a ~6 tile radius
totalIntensity: 50
intensitySlope: 1
maxIntensity: 10
maxIntensity: 5
canCreateVacuum: false
- type: ContainerContainer
containers:
cluster-payload: !type:Container
- type: ProjectileGrenade
fillPrototype: PelletClusterLessLethal
capacity: 30
- type: entity
parent: BaseBulletTrigger

View File

@@ -35,7 +35,8 @@
sprite: Objects/Magic/Eldritch/eldritch_actions.rsi
state: voidblink
- type: TargetAction
checkCanAccess: false
accessMask:
- Opaque
repeat: false
range: 16
- type: EntityTargetAction