Fix Flares, Give Skia Spacewalk (#4417)
* Fix various light sources counting as Light, Give Skia spacewalk * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Replace the Ignore Gravity with Jetpack * Clean up event code + Avoid touching upstream code where possible * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Double cone, strategic untouches * Additional strategic untouch --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
061b844c99
commit
01fe85f77e
|
|
@ -0,0 +1,22 @@
|
|||
using Content.Client.Light.Components;
|
||||
using Content.Shared._DV.Light;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client._DV.Light.EntitySystems;
|
||||
|
||||
public sealed partial class ExpendableLightEnergySystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ExpendableLightComponent, OnGetLightEnergyEvent>(GetLightEnergy);
|
||||
}
|
||||
private void GetLightEnergy(Entity<ExpendableLightComponent> ent, ref OnGetLightEnergyEvent args)
|
||||
{
|
||||
if (!TryComp<PointLightComponent>(ent, out var pointLight))
|
||||
return;
|
||||
args.LightEnergy = pointLight.Energy;
|
||||
args.LightRadius = pointLight.Radius;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ public sealed partial class LightReactiveSystem : SharedLightReactiveSystem
|
|||
_validLightsInRange.Clear();
|
||||
foreach (var light in _lightsInRange)
|
||||
{
|
||||
if(light.Comp.Enabled && !light.Comp.Deleted && light.Comp.NetSyncEnabled)
|
||||
if (light.Comp.Enabled && !light.Comp.Deleted)
|
||||
_validLightsInRange.Add(new(light.Owner, light.Comp));
|
||||
}
|
||||
return _validLightsInRange;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
using Content.Server.Light.Components;
|
||||
using Content.Shared._DV.Light;
|
||||
using Content.Shared.Light.Components;
|
||||
|
||||
namespace Content.Server._DV.Light.EntitySystems;
|
||||
|
||||
public sealed partial class ExpendableLightEnergySystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ExpendableLightComponent, OnGetLightEnergyEvent>(GetLightEnergy);
|
||||
}
|
||||
|
||||
private void GetLightEnergy(Entity<ExpendableLightComponent> ent, ref OnGetLightEnergyEvent args)
|
||||
{
|
||||
// This isn't a perfect clone of the Clientside code, as it relies on animation behaviours
|
||||
// and thus is by nature different per-client (Especially those with random flickers)
|
||||
// This same code is not used clientside, because the client doesn't actually have access to the start time(??)
|
||||
float lightFactor;
|
||||
switch (ent.Comp.CurrentState)
|
||||
{
|
||||
case ExpendableLightState.Lit:
|
||||
float timeElapsed = ent.Comp.GlowDuration.Seconds - ent.Comp.StateExpiryTime;
|
||||
lightFactor = MathF.Min(1.0f, 1.0f - timeElapsed / ent.Comp.FadeInDuration);
|
||||
break;
|
||||
case ExpendableLightState.Fading:
|
||||
lightFactor = MathF.Min(1.0f, ent.Comp.StateExpiryTime / ent.Comp.FadeOutDuration.Seconds);
|
||||
break;
|
||||
default: // Other states aren't lit.
|
||||
return;
|
||||
}
|
||||
args.LightEnergy = ent.Comp.LitEnergy * lightFactor;
|
||||
args.LightRadius = ent.Comp.LitRadius * lightFactor;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,10 @@ public sealed partial class LightReactiveSystem : SharedLightReactiveSystem
|
|||
_validLightsInRange.Clear();
|
||||
foreach (var light in _lightsInRange)
|
||||
{
|
||||
if(light.Comp.Enabled && !light.Comp.Deleted && light.Comp.NetSyncEnabled)
|
||||
// On the server, we check if it's Enabled OR if netSyncEnabled is false
|
||||
// Because sometimes the server doesn't actually know if it should be enabled or not.
|
||||
// The Client however, can be assumed to always be right.
|
||||
if ((light.Comp.Enabled || !light.Comp.NetSyncEnabled) && !light.Comp.Deleted)
|
||||
_validLightsInRange.Add(new(light.Owner, light.Comp));
|
||||
}
|
||||
return _validLightsInRange;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,17 @@ public abstract partial class SharedExpendableLightComponent : Component
|
|||
|
||||
[DataField]
|
||||
public SoundSpecifier? DieSound;
|
||||
|
||||
// Begin DeltaV additions
|
||||
[DataField(required: true)]
|
||||
public float LitRadius = 0.0f;
|
||||
|
||||
[DataField(required: true)]
|
||||
public float LitEnergy = 0.0f;
|
||||
|
||||
[DataField]
|
||||
public float FadeInDuration = 0.0f;
|
||||
// End DeltaV additions
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
using Content.Shared._DV.Light;
|
||||
using Content.Shared.Light.Components;
|
||||
|
||||
namespace Content.Shared._DV.Light.EntitySystems;
|
||||
|
||||
public sealed partial class ItemTogglePointLightEnergySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedPointLightSystem _light = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ItemTogglePointLightComponent, OnGetLightEnergyEvent>(GetLightEnergy);
|
||||
}
|
||||
private void GetLightEnergy(Entity<ItemTogglePointLightComponent> ent, ref OnGetLightEnergyEvent args)
|
||||
{
|
||||
if (!_light.TryGetLight(ent.Owner, out var light))
|
||||
return;
|
||||
|
||||
if (!light.Enabled)
|
||||
return;
|
||||
|
||||
args.LightEnergy = light.Energy;
|
||||
args.LightRadius = light.Radius;
|
||||
}
|
||||
}
|
||||
|
|
@ -77,6 +77,21 @@ public abstract class SharedLightReactiveSystem : EntitySystem
|
|||
|
||||
foreach (var (lightUid, lightComp) in GetLights(uid))
|
||||
{
|
||||
var energy = lightComp.Energy;
|
||||
var radius = lightComp.Radius;
|
||||
if (!lightComp.NetSyncEnabled)
|
||||
{
|
||||
// Try to use the GetLightEnergyEvent if we can't rely on it being network synced.
|
||||
var lightEnergyEvnt = new OnGetLightEnergyEvent();
|
||||
RaiseLocalEvent(lightUid, ref lightEnergyEvnt);
|
||||
energy = lightEnergyEvnt.LightEnergy;
|
||||
radius = lightEnergyEvnt.LightRadius;
|
||||
if (MathHelper.CloseTo(energy, 0f))
|
||||
continue; // No light, no problem.
|
||||
}
|
||||
|
||||
energy = MathF.Min(energy, 2f); // Clamp energy, to normalize strange values.
|
||||
|
||||
// Ensure we're on the same grid as the light source
|
||||
if (_transform.GetMap(lightUid) != map)
|
||||
continue;
|
||||
|
|
@ -84,26 +99,50 @@ public abstract class SharedLightReactiveSystem : EntitySystem
|
|||
// Ensure we're within the light's radius.
|
||||
var lightPos = _transform.GetWorldPosition(lightUid);
|
||||
var sqrDistance = Vector2.DistanceSquared(pos, lightPos);
|
||||
if (sqrDistance > lightComp.Radius * lightComp.Radius)
|
||||
if (sqrDistance > radius * radius)
|
||||
continue;
|
||||
|
||||
if (sqrDistance < 0.01f)
|
||||
{
|
||||
// If we're right on top of the light, just add its full energy value.
|
||||
val += lightComp.Energy;
|
||||
val += energy;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Collision ray check from the entity to the light source
|
||||
var ray = new CollisionRay(pos, (lightPos - pos).Normalized(), (int)CollisionGroup.Opaque);
|
||||
var hit = _physics.IntersectRay(_transform.GetMapId(uid), ray, MathF.Sqrt(sqrDistance) - 0.5f, returnOnFirstHit: true);
|
||||
var hit = _physics.IntersectRay(_transform.GetMapId(uid), ray, MathF.Sqrt(sqrDistance) - 0.5f, ignoredEnt: lightUid, returnOnFirstHit: true);
|
||||
if (hit.Any() && hit.First().Distance != 0)
|
||||
continue;
|
||||
|
||||
// Manual hack for cones.
|
||||
if (lightComp.MaskPath == "/Textures/Effects/LightMasks/cone.png")
|
||||
{
|
||||
var forward = _transform.GetWorldRotation(lightUid).RotateVec(new Vector2(0.0f, -1.0f));
|
||||
energy *= MathF.Max(0f, Vector2.Dot((pos - lightPos).Normalized(), forward));
|
||||
}
|
||||
else if (lightComp.MaskPath == "/Textures/Effects/LightMasks/double_cone.png")
|
||||
{
|
||||
var forward = _transform.GetWorldRotation(lightUid).RotateVec(new Vector2(0.0f, -1.0f));
|
||||
energy *= MathF.Abs(Vector2.Dot((pos - lightPos).Normalized(), forward));
|
||||
}
|
||||
|
||||
// If we reach here, the light is unobstructed and within range, calculate a light value to add.
|
||||
val += lightComp.Energy * (1.0f - sqrDistance / (lightComp.Radius * lightComp.Radius));
|
||||
val += energy * (1.0f - sqrDistance / (radius * radius));
|
||||
}
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Passed to unsync'd light sources to get the expected light energy.
|
||||
/// ONLY called when NetSync is not enabled. Otherwise, uses the light directly.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct OnGetLightEnergyEvent()
|
||||
{
|
||||
public float LightEnergy = 0f;
|
||||
public float LightRadius = 0f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
iconStateSpent: torch_spent
|
||||
turnOnBehaviourID: turn_on
|
||||
fadeOutBehaviourID: fade_out
|
||||
litRadius: 6.0 # DeltaV
|
||||
litEnergy: 5.0 # DeltaV
|
||||
fadeInDuration: 8.0 # DeltaV
|
||||
# Sounds legit nuff
|
||||
litSound:
|
||||
path: /Audio/Items/Flare/flare_on.ogg
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
iconStateSpent: flare_spent
|
||||
turnOnBehaviourID: turn_on
|
||||
fadeOutBehaviourID: fade_out
|
||||
litRadius: 10.0 # DeltaV
|
||||
litEnergy: 9.0 # DeltaV
|
||||
fadeInDuration: 45.0 # DeltaV
|
||||
litSound:
|
||||
path: /Audio/Items/Flare/flare_on.ogg
|
||||
loopedSound:
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
fadeOutBehaviourID: fade_out
|
||||
iconStateLit: glowstick_lit
|
||||
iconStateSpent: glowstick_unlit
|
||||
litRadius: 5.0 # DeltaV
|
||||
litEnergy: 3.0 # DeltaV
|
||||
litSound:
|
||||
path: /Audio/Items/Handcuffs/rope_breakout.ogg
|
||||
- type: Sprite
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@
|
|||
- type: MovementSpeedModifier
|
||||
baseWalkSpeed: 2.25
|
||||
baseSprintSpeed: 3.75
|
||||
- type: NoSlip
|
||||
- type: MovedByPressure
|
||||
enabled: false
|
||||
- type: JetpackUser
|
||||
- type: CombatMode
|
||||
- type: MeleeWeapon
|
||||
soundHit:
|
||||
|
|
|
|||
Loading…
Reference in New Issue