}
// Define target coordinates relative to gun entity, so that network latency on moving grids doesn't fuck up the target location.
- var coordinates = EntityCoordinates.FromMap(entity, mousePos, Transform, EntityManager);
+ var coordinates = EntityCoordinates.FromMap(entity, mousePos, TransformSystem, EntityManager);
Sawmill.Debug($"Sending shoot request tick {Timing.CurTick} / {Timing.CurTime}");
// Rather than splitting client / server for every ammo provider it's easier
// to just delete the spawned entities. This is for programmer sanity despite the wasted perf.
// This also means any ammo specific stuff can be grabbed as necessary.
- var direction = fromCoordinates.ToMapPos(EntityManager, Transform) - toCoordinates.ToMapPos(EntityManager, Transform);
+ var direction = fromCoordinates.ToMapPos(EntityManager, TransformSystem) - toCoordinates.ToMapPos(EntityManager, TransformSystem);
foreach (var (ent, shootable) in ammo)
{
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.Coordinates;
+using Content.Shared.Sound.Components;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Serialization.Markdown.Validation;
using Robust.Shared.Serialization.Markdown.Value;
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
+using Robust.Shared.Timing;
namespace Content.IntegrationTests.Tests;
foreach (var prototype in prototypes)
{
uid = entityMan.SpawnEntity(prototype.ID, testLocation);
- server.RunTicks(1);
// get default prototype data
Dictionary<string, MappingDataNode> protoData = new();
try
{
+ context.WritingReadingPrototypes = true;
+
foreach (var (compType, comp) in prototype.Components)
{
- protoData.Add(compType, seriMan.WriteValueAs<MappingDataNode>(comp.Component.GetType(), comp.Component, alwaysWrite:true, context: context));
+ protoData.Add(compType, seriMan.WriteValueAs<MappingDataNode>(comp.Component.GetType(), comp.Component, alwaysWrite: true, context: context));
}
+
+ context.WritingReadingPrototypes = false;
}
catch (Exception e)
{
ITypeSerializer<EntityUid, ValueDataNode>
{
public SerializationManager.SerializerProvider SerializerProvider { get; }
+ public bool WritingReadingPrototypes { get; set; }
public TestEntityUidContext()
{
public readonly Dictionary<int, uint> Data = new();
}
- public void CopyTo(ISerializationManager serializationManager, Dictionary<Vector2i, TileAtmosphere> source, ref Dictionary<Vector2i, TileAtmosphere> target, SerializationHookContext hookCtx,
+ public void CopyTo(ISerializationManager serializationManager, Dictionary<Vector2i, TileAtmosphere> source, ref Dictionary<Vector2i, TileAtmosphere> target,
+ IDependencyCollection dependencies,
+ SerializationHookContext hookCtx,
ISerializationContext? context = null)
{
target.Clear();
/// The time when the next charge will be added
/// </summary>
[DataField("nextChargeTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
- public TimeSpan NextChargeTime = TimeSpan.MaxValue;
+ public TimeSpan NextChargeTime;
}
base.Initialize();
SubscribeLocalEvent<SolutionPurgeComponent, EntityUnpausedEvent>(OnUnpaused);
- SubscribeLocalEvent<SolutionPurgeComponent, MapInitEvent>(OnMapInit);
}
public override void Update(float frameTime)
{
comp.NextPurgeTime += args.PausedTime;
}
-
- private void OnMapInit(EntityUid uid, SolutionPurgeComponent comp, MapInitEvent args)
- {
- if (comp.NextPurgeTime < _timing.CurTime)
- comp.NextPurgeTime = _timing.CurTime;
- }
}
{
base.Initialize();
SubscribeLocalEvent<SmokeComponent, EntityUnpausedEvent>(OnSmokeUnpaused);
- SubscribeLocalEvent<SmokeComponent, MapInitEvent>(OnSmokeMapInit);
SubscribeLocalEvent<SmokeComponent, ReactionAttemptEvent>(OnReactionAttempt);
SubscribeLocalEvent<SmokeComponent, SpreadNeighborsEvent>(OnSmokeSpread);
SubscribeLocalEvent<SmokeDissipateSpawnComponent, TimedDespawnEvent>(OnSmokeDissipate);
}
}
- private void OnSmokeMapInit(EntityUid uid, SmokeComponent component, MapInitEvent args)
- {
- component.NextReact = _timing.CurTime;
- }
-
private void OnSmokeUnpaused(EntityUid uid, SmokeComponent component, ref EntityUnpausedEvent args)
{
component.NextReact += args.PausedTime;
ISerializationManager serializationManager,
NPCBlackboard source,
ref NPCBlackboard target,
+ IDependencyCollection dependencies,
SerializationHookContext hookCtx,
ISerializationContext? context = null)
{
public override void Initialize()
{
SubscribeLocalEvent<ProximityBeeperComponent, UseInHandEvent>(OnUseInHand);
- SubscribeLocalEvent<ProximityBeeperComponent, MapInitEvent>(OnInit);
SubscribeLocalEvent<ProximityBeeperComponent, EntityUnpausedEvent>(OnUnpaused);
SubscribeLocalEvent<ProximityBeeperComponent, PowerCellSlotEmptyEvent>(OnPowerCellSlotEmpty);
}
args.Handled = TryToggle(uid, component, args.User);
}
- private void OnInit(EntityUid uid, ProximityBeeperComponent component, MapInitEvent args)
- {
- if (component.NextBeepTime < _timing.CurTime)
- component.NextBeepTime = _timing.CurTime;
- }
-
private void OnUnpaused(EntityUid uid, ProximityBeeperComponent component, ref EntityUnpausedEvent args)
{
component.NextBeepTime += args.PausedTime;
SubscribeLocalEvent<PowerCellComponent, ExaminedEvent>(OnCellExamined);
- SubscribeLocalEvent<PowerCellDrawComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<PowerCellDrawComponent, EntityUnpausedEvent>(OnUnpaused);
// funny
RaiseLocalEvent(uid, ref ev);
}
- private void OnMapInit(EntityUid uid, PowerCellDrawComponent component, MapInitEvent args)
- {
- if (component.NextUpdateTime < _timing.CurTime)
- component.NextUpdateTime = _timing.CurTime;
- }
-
private void OnUnpaused(EntityUid uid, PowerCellDrawComponent component, ref EntityUnpausedEvent args)
{
component.NextUpdateTime += args.PausedTime;
SubscribeLocalEvent<ThrusterComponent, ActivateInWorldEvent>(OnActivateThruster);
SubscribeLocalEvent<ThrusterComponent, ComponentInit>(OnThrusterInit);
SubscribeLocalEvent<ThrusterComponent, ComponentShutdown>(OnThrusterShutdown);
- SubscribeLocalEvent<ThrusterComponent, MapInitEvent>(OnThrusterMapInit);
SubscribeLocalEvent<ThrusterComponent, PowerChangedEvent>(OnPowerChange);
SubscribeLocalEvent<ThrusterComponent, AnchorStateChangedEvent>(OnAnchorChange);
SubscribeLocalEvent<ThrusterComponent, ReAnchorEvent>(OnThrusterReAnchor);
EnableThruster(uid, component);
}
- private void OnThrusterMapInit(EntityUid uid, ThrusterComponent component, MapInitEvent args)
- {
- if (component.NextFire < _timing.CurTime)
- component.NextFire = _timing.CurTime;
- }
-
private void OnThrusterInit(EntityUid uid, ThrusterComponent component, ComponentInit args)
{
_ambient.SetAmbience(uid, false);
{
SubscribeLocalEvent<AirtightChanged>(OnAirtightChanged);
SubscribeLocalEvent<GridInitializeEvent>(OnGridInit);
- SubscribeLocalEvent<SpreaderGridComponent, MapInitEvent>(OnSpreaderGridMapInit);
SubscribeLocalEvent<SpreaderGridComponent, EntityUnpausedEvent>(OnGridUnpaused);
_prototype.PrototypesReloaded += OnPrototypeReload;
}
- private void OnSpreaderGridMapInit(EntityUid uid, SpreaderGridComponent component, MapInitEvent args)
- {
- component.NextUpdate = _timing.CurTime;
- }
-
public override void Shutdown()
{
base.Shutdown();
}
}
- var fromMap = fromCoordinates.ToMap(EntityManager, Transform);
- var toMap = toCoordinates.ToMapPos(EntityManager, Transform);
+ var fromMap = fromCoordinates.ToMap(EntityManager, TransformSystem);
+ var toMap = toCoordinates.ToMapPos(EntityManager, TransformSystem);
var mapDirection = toMap - fromMap.Position;
var mapAngle = mapDirection.ToAngle();
var angle = GetRecoilAngle(Timing.CurTime, gun, mapDirection.ToAngle());
Projectiles.SetShooter(projectile, user.Value);
}
- Transform.SetWorldRotation(uid, direction.ToWorldAngle());
+ TransformSystem.SetWorldRotation(uid, direction.ToWorldAngle());
}
/// <summary>
if (xformQuery.TryGetComponent(gridUid, out var gridXform))
{
- var (_, gridRot, gridInvMatrix) = Transform.GetWorldPositionRotationInvMatrix(gridUid.Value, xformQuery);
+ var (_, gridRot, gridInvMatrix) = TransformSystem.GetWorldPositionRotationInvMatrix(gridUid.Value, xformQuery);
fromCoordinates = new EntityCoordinates(gridUid.Value,
- gridInvMatrix.Transform(fromCoordinates.ToMapPos(EntityManager, Transform)));
+ gridInvMatrix.Transform(fromCoordinates.ToMapPos(EntityManager, TransformSystem)));
// Use the fallback angle I guess?
angle -= gridRot;
/// The time at which the next artifact pulse will occur.
/// </summary>
[DataField("nextPulseTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
- public TimeSpan NextPulseTime = TimeSpan.MaxValue;
+ public TimeSpan NextPulseTime = TimeSpan.Zero;
/// <summary>
/// The minimum interval between pulses.
public override void Initialize()
{
base.Initialize();
+ SubscribeLocalEvent<StaminaComponent, EntityUnpausedEvent>(OnStamUnpaused);
SubscribeLocalEvent<StaminaComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<StaminaComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<StaminaComponent, ComponentGetState>(OnStamGetState);
SubscribeLocalEvent<StaminaDamageOnHitComponent, MeleeHitEvent>(OnHit);
}
+ private void OnStamUnpaused(EntityUid uid, StaminaComponent component, ref EntityUnpausedEvent args)
+ {
+ component.NextUpdate += args.PausedTime;
+ }
+
private void OnStamGetState(EntityUid uid, StaminaComponent component, ref ComponentGetState args)
{
args.State = new StaminaComponentState()
{
if (!args.OurFixture.ID.Equals(CollideFixture)) return;
- TakeStaminaDamage(args.OtherFixture.Body.Owner, component.Damage, source:args.OurFixture.Body.Owner);
+ TakeStaminaDamage(args.OtherEntity, component.Damage, source:args.OurEntity);
}
private void SetStaminaAlert(EntityUid uid, StaminaComponent? component = null)
/// <summary>
/// To avoid sound spam add a cooldown to it.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("nextSound", customTypeSerializer:typeof(TimeOffsetSerializer))]
- public TimeSpan NextSound;
+ [ViewVariables(VVAccess.ReadWrite), DataField("nextSound", customTypeSerializer: typeof(TimeOffsetSerializer))]
+ public TimeSpan NextSound = TimeSpan.FromSeconds(0.2);
}
SubscribeLocalEvent<EmitSoundOnActivateComponent, ActivateInWorldEvent>(OnEmitSoundOnActivateInWorld);
SubscribeLocalEvent<EmitSoundOnPickupComponent, GotEquippedHandEvent>(OnEmitSoundOnPickup);
SubscribeLocalEvent<EmitSoundOnDropComponent, DroppedEvent>(OnEmitSoundOnDrop);
+
+ SubscribeLocalEvent<EmitSoundOnCollideComponent, EntityUnpausedEvent>(OnEmitSoundUnpaused);
SubscribeLocalEvent<EmitSoundOnCollideComponent, StartCollideEvent>(OnEmitSoundOnCollide);
}
}
}
+ private void OnEmitSoundUnpaused(EntityUid uid, EmitSoundOnCollideComponent component, ref EntityUnpausedEvent args)
+ {
+ component.NextSound += args.PausedTime;
+ }
+
private void OnEmitSoundOnCollide(EntityUid uid, EmitSoundOnCollideComponent component, ref StartCollideEvent args)
{
if (!args.OurFixture.Hard ||
base.Initialize();
Sawmill = Logger.GetSawmill("melee");
+ SubscribeLocalEvent<MeleeWeaponComponent, EntityUnpausedEvent>(OnMeleeUnpaused);
SubscribeLocalEvent<MeleeWeaponComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<MeleeWeaponComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<MeleeWeaponComponent, HandDeselectedEvent>(OnMeleeDropped);
private void OnMapInit(EntityUid uid, MeleeWeaponComponent component, MapInitEvent args)
{
- if (component.NextAttack > TimeSpan.Zero)
+ if (component.NextAttack > Timing.CurTime)
Logger.Warning($"Initializing a map that contains an entity that is on cooldown. Entity: {ToPrettyString(uid)}");
#endif
}
+ private void OnMeleeUnpaused(EntityUid uid, MeleeWeaponComponent component, ref EntityUnpausedEvent args)
+ {
+ component.NextAttack += args.PausedTime;
+ }
+
private void OnMeleeSelected(EntityUid uid, MeleeWeaponComponent component, HandSelectedEvent args)
{
if (component.AttackRate.Equals(0f))
[Dependency] protected readonly SharedAudioSystem Audio = default!;
[Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] protected readonly SharedProjectileSystem Projectiles = default!;
- [Dependency] protected readonly SharedTransformSystem Transform = default!;
+ [Dependency] protected readonly SharedTransformSystem TransformSystem = default!;
protected ISawmill Sawmill = default!;
SubscribeLocalEvent<GunComponent, GetVerbsEvent<AlternativeVerb>>(OnAltVerb);
SubscribeLocalEvent<GunComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<GunComponent, CycleModeEvent>(OnCycleMode);
- SubscribeLocalEvent<GunComponent, ComponentInit>(OnGunInit);
+ SubscribeLocalEvent<GunComponent, EntityUnpausedEvent>(OnGunUnpaused);
#if DEBUG
SubscribeLocalEvent<GunComponent, MapInitEvent>(OnMapInit);
private void OnMapInit(EntityUid uid, GunComponent component, MapInitEvent args)
{
- if (component.NextFire > TimeSpan.Zero)
+ if (component.NextFire > Timing.CurTime)
Logger.Warning($"Initializing a map that contains an entity that is on cooldown. Entity: {ToPrettyString(uid)}");
+
+ DebugTools.Assert((component.AvailableModes & component.SelectedMode) != 0x0);
#endif
}
- private void OnGunInit(EntityUid uid, GunComponent component, ComponentInit args)
+ private void OnGunUnpaused(EntityUid uid, GunComponent component, ref EntityUnpausedEvent args)
{
- DebugTools.Assert((component.AvailableModes & component.SelectedMode) != 0x0);
+ component.NextFire += args.PausedTime;
}
private void OnGunMeleeAttempt(EntityUid uid, GunComponent component, ref MeleeAttackAttemptEvent args)
public void CauseImpulse(EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, EntityUid user, PhysicsComponent userPhysics)
{
- var fromMap = fromCoordinates.ToMapPos(EntityManager, Transform);
- var toMap = toCoordinates.ToMapPos(EntityManager, Transform);
+ var fromMap = fromCoordinates.ToMapPos(EntityManager, TransformSystem);
+ var toMap = toCoordinates.ToMapPos(EntityManager, TransformSystem);
var shotDirection = (toMap - fromMap).Normalized;
const float impulseStrength = 25.0f;