FTL иплакт. Задержка на отсегивание других

This commit is contained in:
Vigers Ray 2025-08-03 06:41:02 +03:00
parent b70945f5c4
commit 6fb7cca203
9 changed files with 213 additions and 13 deletions

View file

@ -4,6 +4,7 @@ using System.Numerics;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Server.Station.Events;
using Content.Shared.Atmos.Components;
using Content.Shared.Body.Components;
using Content.Shared.CCVar;
using Content.Shared.Database;
@ -51,6 +52,7 @@ public sealed partial class ShuttleSystem
private float FTLCooldown;
public float FTLMassLimit;
private TimeSpan _hyperspaceKnockdownTime = TimeSpan.FromSeconds(5);
private const float _ftlThrowForce = 20.0f;
/// <summary>
/// Left-side of the station we're allowed to use
@ -74,6 +76,7 @@ public sealed partial class ShuttleSystem
private EntityQuery<BodyComponent> _bodyQuery;
private EntityQuery<FTLSmashImmuneComponent> _immuneQuery;
private EntityQuery<StatusEffectsComponent> _statusQuery;
private EntityQuery<MovedByPressureComponent> _movedByPressureQuery;
private void InitializeFTL()
{
@ -83,6 +86,7 @@ public sealed partial class ShuttleSystem
_bodyQuery = GetEntityQuery<BodyComponent>();
_immuneQuery = GetEntityQuery<FTLSmashImmuneComponent>();
_statusQuery = GetEntityQuery<StatusEffectsComponent>();
_movedByPressureQuery = GetEntityQuery<MovedByPressureComponent>();
_cfg.OnValueChanged(CCVars.FTLStartupTime, time => DefaultStartupTime = time, true);
_cfg.OnValueChanged(CCVars.FTLTravelTime, time => DefaultTravelTime = time, true);
@ -375,7 +379,8 @@ public sealed partial class ShuttleSystem
var uid = entity.Owner;
var comp = entity.Comp1;
var xform = _xformQuery.GetComponent(entity);
DoTheDinosaur(xform);
// Sunrise-Edit
//DoTheDinosaur(xform);
comp.State = FTLState.Travelling;
var fromMapUid = xform.MapUid;
@ -429,6 +434,10 @@ public sealed partial class ShuttleSystem
var wowdio = _audio.PlayPvs(comp.TravelSound, uid);
comp.TravelStream = wowdio?.Entity;
_audio.SetGridAudio(wowdio);
// Sunrise-Start
DoTheDinosaur(xform, Direction.South.ToVec());
// Sunrise-End
}
/// <summary>
@ -441,6 +450,16 @@ public sealed partial class ShuttleSystem
comp.StateTime = StartEndTime.FromCurTime(_gameTiming, DefaultArrivalTime);
comp.State = FTLState.Arriving;
// Sunrise-Start
// Почему оно здесь а не в UpdateFTLArriving?
// Ну потому что когда шаттл выходит из фтл он телепортируется
// к докам и меняет угол поворота. А вот брошеная сущность все еще летит
// в том направлении когда шаттл был в фтл зоне,
// как итог полет будет не назад или вперед а в бок.
var xform = _xformQuery.GetComponent(entity.Owner);
DoTheDinosaur(xform, Direction.North.ToVec());
// Sunrise-End
if (entity.Comp1.VisualizerProto != null)
{
comp.VisualizerEntity = SpawnAttachedTo(entity.Comp1.VisualizerProto, entity.Comp1.TargetCoordinates);
@ -467,7 +486,8 @@ public sealed partial class ShuttleSystem
var xform = _xformQuery.GetComponent(uid);
var body = _physicsQuery.GetComponent(uid);
var comp = entity.Comp1;
DoTheDinosaur(xform);
// Sunrise-Edit
//DoTheDinosaur(xform);
_dockSystem.SetDockBolts(entity, false);
_physics.SetLinearVelocity(uid, Vector2.Zero, body: body);
@ -610,7 +630,7 @@ public sealed partial class ShuttleSystem
/// <summary>
/// Puts everyone unbuckled on the floor, paralyzed.
/// </summary>
private void DoTheDinosaur(TransformComponent xform)
private void DoTheDinosaur(TransformComponent xform, Vector2 throwDirection) // Sunrise-Edit
{
// Get enumeration exceptions from people dropping things if we just paralyze as we go
var toKnock = new ValueList<EntityUid>();
@ -626,6 +646,22 @@ public sealed partial class ShuttleSystem
_stuns.TryParalyze(child, _hyperspaceKnockdownTime, true, status);
// Sunrise-Start
if (_physicsQuery.TryGetComponent(child, out var physics))
{
if ((physics.BodyType & BodyType.Static) != 0)
continue;
_throwing.TryThrow(child,
throwDirection * _ftlThrowForce,
physics,
Transform(child),
_projQuery,
_ftlThrowForce,
playSound: false);
}
// Sunrise-End
// If the guy we knocked down is on a spaced tile, throw them too
if (grid != null)
TossIfSpaced((xform.GridUid.Value, grid, shuttleBody), child);
@ -667,6 +703,11 @@ public sealed partial class ShuttleSystem
if (!_buckleQuery.TryGetComponent(child, out var buckle) || buckle.Buckled)
continue;
// Sunrise-Start
if (_movedByPressureQuery.TryComp(child, out var moved) && !moved.Enabled)
continue;
// Sunrise-End
toKnock.Add(child);
}
}

View file

@ -9,3 +9,11 @@ public sealed partial class BuckleDoAfterEvent : SimpleDoAfterEvent
{
}
// Sunrise-Start
[Serializable, NetSerializable]
public sealed partial class UnbuckleDoAfterEvent : SimpleDoAfterEvent
{
}
// Sunrise-End

View file

@ -70,6 +70,11 @@ public sealed partial class BuckleComponent : Component
/// Used for client rendering
/// </summary>
[ViewVariables] public int? OriginalDrawDepth;
// Sunrise-Start
[DataField]
public float UnbuckleDoafterTime = 2f;
// Sunrise-End
}
public sealed partial class UnbuckleAlertEvent : BaseAlertEvent;

View file

@ -60,6 +60,14 @@ public abstract partial class SharedBuckleSystem
{
BuckleDoafterEarly((uid, comp), ev.Event, ev);
});
// Sunrise-Start
SubscribeLocalEvent<BuckleComponent, UnbuckleDoAfterEvent>(OnUnbuckleDoafter);
SubscribeLocalEvent<BuckleComponent, DoAfterAttemptEvent<UnbuckleDoAfterEvent>>((uid, comp, ev) =>
{
UnbuckleDoafterEarly((uid, comp), ev.Event, ev);
});
// Sunrise-End
}
private void OnBuckleComponentShutdown(Entity<BuckleComponent> ent, ref ComponentShutdown args)
@ -74,6 +82,11 @@ public abstract partial class SharedBuckleSystem
// Prevent people pulling the chair they're on, etc.
if (ent.Comp.BuckledTo == args.Pulled && !ent.Comp.PullStrap)
args.Cancel();
// Sunrise-Start
if (ent.Comp.Buckled)
args.Cancel();
// Sunrise-End
}
private void OnBeingPulledAttempt(Entity<BuckleComponent> ent, ref BeingPulledAttemptEvent args)
@ -282,7 +295,7 @@ public abstract partial class SharedBuckleSystem
return false;
}
if (buckleComp.Buckled && !TryUnbuckle(buckleUid, user, buckleComp))
if (buckleComp.Buckled) // && !TryUnbuckle(buckleUid, user, buckleComp) Sunrise-Edit
{
if (popup)
{
@ -604,4 +617,27 @@ public abstract partial class SharedBuckleSystem
TryBuckle(args.Target.Value, args.User, args.Used.Value, popup: false);
}
}
// Sunrise-Start
private void OnUnbuckleDoafter(Entity<BuckleComponent> entity, ref UnbuckleDoAfterEvent args)
{
if (args.Cancelled || args.Handled || args.Target == null)
return;
args.Handled = TryUnbuckle(args.Target.Value, args.User, popup: false);
}
private void UnbuckleDoafterEarly(Entity<BuckleComponent> entity, UnbuckleDoAfterEvent args, CancellableEntityEventArgs ev)
{
if (args.Target == null)
return;
if (TryComp<CuffableComponent>(args.Target, out var targetCuffableComp) && targetCuffableComp.CuffedHandCount > 0
|| _mobState.IsIncapacitated(args.Target.Value))
{
ev.Cancel();
TryUnbuckle(args.Target.Value, args.User, popup: false);
}
}
// Sunrise-End
}

View file

@ -107,11 +107,26 @@ public abstract partial class SharedBuckleSystem
}
// Unbuckle others
if (component.BuckledEntities.TryFirstOrNull(out var buckled) && TryUnbuckle(buckled.Value, args.User))
// Sunrise-Start
if (component.BuckledEntities.TryFirstOrNull(out var buckled))
{
args.Handled = true;
return;
if (CanUnbuckle(buckled.Value, args.User, false))
{
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, buckle.UnbuckleDoafterTime, new UnbuckleDoAfterEvent(), buckled.Value, buckled.Value)
{
BreakOnMove = true,
BreakOnDamage = true,
AttemptFrequency = AttemptFrequency.EveryTick
};
if (_doAfter.TryStartDoAfter(doAfterArgs))
{
args.Handled = true;
return;
}
}
}
// Sunrise-End
// TODO BUCKLE add out bool for whether a pop-up was generated or not.
}
@ -122,7 +137,31 @@ public abstract partial class SharedBuckleSystem
return;
if (ent.Comp.BuckledTo != null)
args.Handled = TryUnbuckle(ent!, args.User, popup: true);
{
// Sunrise-Start
if (CanUnbuckle((ent.Owner, ent.Comp), args.User, false))
{
if (ent.Owner == args.User)
{
args.Handled = TryUnbuckle(ent!, args.User, popup: true);
}
else
{
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, ent.Comp.UnbuckleDoafterTime, new UnbuckleDoAfterEvent(), ent.Owner, ent.Owner)
{
BreakOnMove = true,
BreakOnDamage = true,
AttemptFrequency = AttemptFrequency.EveryTick
};
if (_doAfter.TryStartDoAfter(doAfterArgs))
{
args.Handled = true;
}
}
}
// Sunrise-End
}
// TODO BUCKLE add out bool for whether a pop-up was generated or not.
}
@ -143,9 +182,31 @@ public abstract partial class SharedBuckleSystem
if (!_interaction.InRangeUnobstructed(args.User, args.Target, range: buckledComp.Range))
continue;
// Sunrise-Start
if (!CanUnbuckle(entity, args.User, false))
continue;
// Sunrise-End
var verb = new InteractionVerb()
{
Act = () => TryUnbuckle(entity, args.User, buckleComp: buckledComp),
// Sunrise-Start
Act = () => {
if (entity == args.User)
{
TryUnbuckle(entity, args.User, buckleComp: buckledComp);
}
else
{
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, buckledComp.UnbuckleDoafterTime, new UnbuckleDoAfterEvent(), entity, entity)
{
BreakOnMove = true,
BreakOnDamage = true,
AttemptFrequency = AttemptFrequency.EveryTick
};
_doAfter.TryStartDoAfter(doAfterArgs);
}
},
// Sunrise-End
Category = VerbCategory.Unbuckle,
Text = entity == args.User
? Loc.GetString("verb-self-target-pronoun")
@ -212,7 +273,24 @@ public abstract partial class SharedBuckleSystem
InteractionVerb verb = new()
{
Act = () => TryUnbuckle(uid, args.User, buckleComp: component),
// Sunrise-Start
Act = () => {
if (uid == args.User)
{
TryUnbuckle(uid, args.User, buckleComp: component);
}
else
{
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, component.UnbuckleDoafterTime, new UnbuckleDoAfterEvent(), uid, uid)
{
BreakOnMove = true,
BreakOnDamage = true,
AttemptFrequency = AttemptFrequency.EveryTick
};
_doAfter.TryStartDoAfter(doAfterArgs);
}
},
// Sunrise-End
Text = Loc.GetString("verb-categories-unbuckle"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/unbuckle.svg.192dpi.png"))
};

View file

@ -86,13 +86,13 @@ public sealed partial class CCVars
/// How long a shuttle spends in FTL.
/// </summary>
public static readonly CVarDef<float> FTLTravelTime =
CVarDef.Create("shuttle.travel_time", 60f, CVar.SERVERONLY);
CVarDef.Create("shuttle.travel_time", 30f, CVar.SERVERONLY); // Sunrise-Edit
/// <summary>
/// How long the final stage of FTL before arrival should be.
/// </summary>
public static readonly CVarDef<float> FTLArrivalTime =
CVarDef.Create("shuttle.arrival_time", 20f, CVar.SERVERONLY);
CVarDef.Create("shuttle.arrival_time", 2f, CVar.SERVERONLY); // Sunrise-Edit
/// <summary>
/// How much time needs to pass before a shuttle can FTL again.

View file

@ -12,7 +12,7 @@ namespace Content.Shared.Damage.Components;
public sealed partial class DamageOnHighSpeedImpactComponent : Component
{
[DataField("minimumSpeed"), ViewVariables(VVAccess.ReadWrite)]
public float MinimumSpeed = 20f;
public float MinimumSpeed = 10f; // Sunrise-Edit
[DataField("speedDamageFactor"), ViewVariables(VVAccess.ReadWrite)]
public float SpeedDamageFactor = 0.5f;

View file

@ -454,6 +454,13 @@ public sealed class PullingSystem : EntitySystem
return false;
}
// Sunrise-Start
if (TryComp<BuckleComponent>(pullableUid, out var buckleComponent) && buckleComponent.Buckled)
{
return false;
}
// Sunrise-End
var getPulled = new BeingPulledAttemptEvent(puller, pullableUid);
RaiseLocalEvent(pullableUid, getPulled, true);
var startPull = new StartPullAttemptEvent(puller, pullableUid);

View file

@ -20016,3 +20016,28 @@
type: Tweak
id: 1329
time: '2025-08-02T20:54:50.494668+00:00'
- author: VigersRay
changes:
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u043F\u0440\u0438 \u0437\u0430\
\u043F\u0443\u0441\u043A\u0435 \u0438 \u043E\u043A\u043E\u043D\u0447\u0430\u043D\
\u0438\u0438 FTL \u043F\u043E\u043C\u0438\u043C\u043E \u043E\u0433\u043B\u0443\
\u0448\u0435\u043D\u0438\u044F \u0432\u0441\u0435 \u0441\u0443\u0449\u0435\u0441\
\u0442\u0432\u0430 \u0431\u0443\u0434\u0443\u0442 \u043E\u0442\u043F\u0440\u0430\
\u0432\u043B\u0435\u043D\u044B \u0432 \u043F\u043E\u043B\u0435\u0442. \u041D\
\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0437\u0430\u0432\
\u0438\u0441\u0438\u0442 \u043E\u0442 \u0442\u043E\u0440\u043C\u043E\u0436\u0435\
\u043D\u0438\u044F \u0438\u043B\u0438 \u043D\u0430\u0447\u0430\u043B\u0430 \u0434\
\u0432\u0438\u0436\u0435\u043D\u0438\u044F."
type: Tweak
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u043E\u0442\u0441\u0442\u0435\u0433\
\u0438\u0432\u0430\u043D\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\
\u0443\u0449\u0435\u0441\u0442\u0432 \u043F\u0440\u043E\u0438\u0441\u0445\u043E\
\u0434\u0438\u0442 \u0441 \u0434\u0432\u0443\u0445 \u0441\u0435\u043A\u0443\u043D\
\u0434\u043D\u043E\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u043E\u0439\
. \u041D\u0438\u043A\u0430\u043A\u0438\u0445 \u0431\u043E\u043B\u044C\u0448\u0435\
\ \u043E\u0442\u0441\u0442\u0435\u0433\u0438\u0432\u0430\u043D\u0438\u0439 \u0440\
\u0430\u0434\u0438 \u0437\u0430\u0431\u0430\u0432\u044B \u043F\u0440\u0438 \u0437\
\u0430\u043F\u0443\u0441\u043A\u0435 \u0448\u0430\u0442\u0442\u043B\u0430."
type: Tweak
id: 1330
time: '2025-08-03T03:37:52.488647+00:00'