Per-map parallax support (#9786)
* Per-map parallax support * Comments for future sloth * c * bet * Fix exception * VV support * Fix parallax * mem * weightless sounds * Gravity stuff * placeholder coz im too lazy to stash don't @ me son * decent clouds * sky * Fast parallax * Imagine spelling * Loicense * perish * Fix weightless status Co-authored-by: metalgearsloth <metalgearsloth@gmail.com>
This commit is contained in:
@@ -182,10 +182,10 @@ namespace Content.Client.Entry
|
||||
ContentContexts.SetupContexts(inputMan.Contexts);
|
||||
|
||||
IoCManager.Resolve<IGameHud>().Initialize();
|
||||
IoCManager.Resolve<IParallaxManager>().LoadParallax(); // Have to do this later because prototypes are needed.
|
||||
IoCManager.Resolve<IParallaxManager>().LoadDefaultParallax(); // Have to do this later because prototypes are needed.
|
||||
|
||||
var overlayMgr = IoCManager.Resolve<IOverlayManager>();
|
||||
overlayMgr.AddOverlay(new ParallaxOverlay());
|
||||
|
||||
overlayMgr.AddOverlay(new SingularityOverlay());
|
||||
overlayMgr.AddOverlay(new FlashOverlay());
|
||||
overlayMgr.AddOverlay(new RadiationPulseOverlay());
|
||||
|
||||
@@ -2,7 +2,7 @@ using Content.Shared.Gravity;
|
||||
|
||||
namespace Content.Client.Gravity
|
||||
{
|
||||
internal sealed class GravitySystem : SharedGravitySystem
|
||||
public sealed class GravitySystem : SharedGravitySystem
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
namespace Content.Client.Parallax.Data
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using Content.Client.Resources;
|
||||
using Content.Client.IoC;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Parallax.Data;
|
||||
|
||||
@@ -62,5 +62,12 @@ public sealed class ParallaxLayerConfig
|
||||
/// </summary>
|
||||
[DataField("slowness")]
|
||||
public float Slowness { get; set; } = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Should the parallax scroll at a specific rate per second.
|
||||
/// </summary>
|
||||
[DataField("scrolling")] public Vector2 Scrolling = Vector2.Zero;
|
||||
|
||||
[DataField("shader")] public string? Shader = "unshaded";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,30 @@
|
||||
using System;
|
||||
using Robust.Client.Graphics;
|
||||
using Content.Client.Parallax;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Content.Client.Parallax.Managers;
|
||||
|
||||
public interface IParallaxManager
|
||||
{
|
||||
/// <summary>
|
||||
/// The current parallax.
|
||||
/// Changing this causes a new parallax to be loaded (eventually).
|
||||
/// Do not alter until prototype manager is available.
|
||||
/// Useful "csi" input for testing new parallaxes:
|
||||
/// using Content.Client.Parallax.Managers; IoCManager.Resolve<IParallaxManager>().ParallaxName = "test";
|
||||
/// </summary>
|
||||
string ParallaxName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All WorldHomePosition values are offset by this.
|
||||
/// </summary>
|
||||
Vector2 ParallaxAnchor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The layers of the currently loaded parallax.
|
||||
/// This will change on a whim without notification.
|
||||
/// </summary>
|
||||
ParallaxLayerPrepared[] ParallaxLayers { get; }
|
||||
bool IsLoaded(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Used to initialize the manager.
|
||||
/// The layers of the selected parallax.
|
||||
/// </summary>
|
||||
ParallaxLayerPrepared[] GetParallaxLayers(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Loads in the default parallax to use.
|
||||
/// Do not call until prototype manager is available.
|
||||
/// </summary>
|
||||
void LoadParallax();
|
||||
void LoadDefaultParallax();
|
||||
|
||||
Task LoadParallaxByName(string name);
|
||||
|
||||
void UnloadParallax(string name);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,111 +1,103 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Client.Parallax.Data;
|
||||
using Content.Shared;
|
||||
using Content.Shared.CCVar;
|
||||
using Nett;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Utility;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
namespace Content.Client.Parallax.Managers;
|
||||
|
||||
internal sealed class ParallaxManager : IParallaxManager
|
||||
public sealed class ParallaxManager : IParallaxManager
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
|
||||
private string _parallaxName = "";
|
||||
public string ParallaxName
|
||||
{
|
||||
get => _parallaxName;
|
||||
set
|
||||
{
|
||||
LoadParallaxByName(value);
|
||||
}
|
||||
}
|
||||
private ISawmill _sawmill = Logger.GetSawmill("parallax");
|
||||
|
||||
public Vector2 ParallaxAnchor { get; set; }
|
||||
|
||||
private CancellationTokenSource? _presentParallaxLoadCancel;
|
||||
private readonly ConcurrentDictionary<string, ParallaxLayerPrepared[]> _parallaxesLQ = new();
|
||||
private readonly ConcurrentDictionary<string, ParallaxLayerPrepared[]> _parallaxesHQ = new();
|
||||
|
||||
private ParallaxLayerPrepared[] _parallaxLayersHQ = {};
|
||||
private ParallaxLayerPrepared[] _parallaxLayersLQ = {};
|
||||
private readonly ConcurrentDictionary<string, CancellationTokenSource> _loadingParallaxes = new();
|
||||
|
||||
public ParallaxLayerPrepared[] ParallaxLayers => _configurationManager.GetCVar(CCVars.ParallaxLowQuality) ? _parallaxLayersLQ : _parallaxLayersHQ;
|
||||
public bool IsLoaded(string name) => _parallaxesLQ.ContainsKey(name);
|
||||
|
||||
public async void LoadParallax()
|
||||
public ParallaxLayerPrepared[] GetParallaxLayers(string name)
|
||||
{
|
||||
await LoadParallaxByName("default");
|
||||
if (_configurationManager.GetCVar(CCVars.ParallaxLowQuality))
|
||||
{
|
||||
return !_parallaxesLQ.TryGetValue(name, out var lq) ? Array.Empty<ParallaxLayerPrepared>() : lq;
|
||||
}
|
||||
|
||||
private async Task LoadParallaxByName(string name)
|
||||
return !_parallaxesLQ.TryGetValue(name, out var hq) ? Array.Empty<ParallaxLayerPrepared>() : hq;
|
||||
}
|
||||
|
||||
public void UnloadParallax(string name)
|
||||
{
|
||||
// Update _parallaxName
|
||||
if (_parallaxName == name)
|
||||
if (_loadingParallaxes.TryGetValue(name, out var loading))
|
||||
{
|
||||
loading.Cancel();
|
||||
_loadingParallaxes.Remove(name, out _);
|
||||
return;
|
||||
}
|
||||
_parallaxName = name;
|
||||
|
||||
if (!_parallaxesLQ.ContainsKey(name)) return;
|
||||
_parallaxesLQ.Remove(name, out _);
|
||||
_parallaxesHQ.Remove(name, out _);
|
||||
}
|
||||
|
||||
public async void LoadDefaultParallax()
|
||||
{
|
||||
await LoadParallaxByName("Default");
|
||||
}
|
||||
|
||||
public async Task LoadParallaxByName(string name)
|
||||
{
|
||||
if (_parallaxesLQ.ContainsKey(name) || _loadingParallaxes.ContainsKey(name)) return;
|
||||
|
||||
// Cancel any existing load and setup the new cancellation token
|
||||
_presentParallaxLoadCancel?.Cancel();
|
||||
_presentParallaxLoadCancel = new CancellationTokenSource();
|
||||
var cancel = _presentParallaxLoadCancel.Token;
|
||||
|
||||
// Empty parallax name = no layers (this is so that the initial "" parallax name is consistent)
|
||||
if (_parallaxName == "")
|
||||
{
|
||||
_parallaxLayersHQ = _parallaxLayersLQ = new ParallaxLayerPrepared[] {};
|
||||
return;
|
||||
}
|
||||
var token = new CancellationTokenSource();
|
||||
_loadingParallaxes[name] = token;
|
||||
var cancel = token.Token;
|
||||
|
||||
// Begin (for real)
|
||||
Logger.InfoS("parallax", $"Loading parallax {name}");
|
||||
_sawmill.Info($"Loading parallax {name}");
|
||||
|
||||
try
|
||||
{
|
||||
var parallaxPrototype = _prototypeManager.Index<ParallaxPrototype>(name);
|
||||
|
||||
ParallaxLayerPrepared[] hq;
|
||||
ParallaxLayerPrepared[] lq;
|
||||
ParallaxLayerPrepared[][] layers;
|
||||
|
||||
if (parallaxPrototype.LayersLQUseHQ)
|
||||
{
|
||||
lq = hq = await LoadParallaxLayers(parallaxPrototype.Layers, cancel);
|
||||
layers = new ParallaxLayerPrepared[2][];
|
||||
layers[0] = layers[1] = await LoadParallaxLayers(parallaxPrototype.Layers, cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
var results = await Task.WhenAll(
|
||||
layers = await Task.WhenAll(
|
||||
LoadParallaxLayers(parallaxPrototype.Layers, cancel),
|
||||
LoadParallaxLayers(parallaxPrototype.LayersLQ, cancel)
|
||||
);
|
||||
hq = results[0];
|
||||
lq = results[1];
|
||||
}
|
||||
|
||||
// Still keeping this check just in case.
|
||||
if (_parallaxName == name)
|
||||
{
|
||||
_parallaxLayersHQ = hq;
|
||||
_parallaxLayersLQ = lq;
|
||||
Logger.InfoS("parallax", $"Loaded parallax {name}");
|
||||
}
|
||||
_loadingParallaxes.Remove(name, out _);
|
||||
|
||||
if (token.Token.IsCancellationRequested) return;
|
||||
|
||||
_parallaxesLQ[name] = layers[0];
|
||||
_parallaxesHQ[name] = layers[1];
|
||||
|
||||
_sawmill.Info($"Loaded parallax {name}");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorS("parallax", $"Failed to loaded parallax {name}: {ex}");
|
||||
_sawmill.Error($"Failed to loaded parallax {name}: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
using Content.Client.Parallax.Managers;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Client.Parallax;
|
||||
|
||||
@@ -28,7 +25,7 @@ public sealed class ParallaxControl : Control
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
foreach (var layer in _parallaxManager.ParallaxLayers)
|
||||
foreach (var layer in _parallaxManager.GetParallaxLayers("Default"))
|
||||
{
|
||||
var tex = layer.Texture;
|
||||
var texSize = tex.Size * layer.Config.Scale.Floored();
|
||||
|
||||
@@ -1,47 +1,55 @@
|
||||
using System;
|
||||
using Content.Client.Parallax.Managers;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Parallax;
|
||||
|
||||
public sealed class ParallaxOverlay : Overlay
|
||||
{
|
||||
[Dependency] private readonly IParallaxManager _parallaxManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly IParallaxManager _manager = default!;
|
||||
private readonly ParallaxSystem _parallax;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowWorld;
|
||||
private readonly ShaderInstance _shader;
|
||||
|
||||
public ParallaxOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_shader = _prototypeManager.Index<ShaderPrototype>("unshaded").Instance();
|
||||
_parallax = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ParallaxSystem>();
|
||||
|
||||
}
|
||||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
if (args.Viewport.Eye == null)
|
||||
{
|
||||
if (args.MapId == MapId.Nullspace)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_configurationManager.GetCVar(CCVars.ParallaxEnabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var position = args.Viewport.Eye?.Position.Position ?? Vector2.Zero;
|
||||
var screenHandle = args.WorldHandle;
|
||||
screenHandle.UseShader(_shader);
|
||||
|
||||
foreach (var layer in _parallaxManager.ParallaxLayers)
|
||||
var layers = _parallax.GetParallaxLayers(args.MapId);
|
||||
var realTime = (float) _timing.RealTime.TotalSeconds;
|
||||
|
||||
foreach (var layer in layers)
|
||||
{
|
||||
ShaderInstance? shader;
|
||||
|
||||
if (!string.IsNullOrEmpty(layer.Config.Shader))
|
||||
shader = _prototypeManager.Index<ShaderPrototype>(layer.Config.Shader).Instance();
|
||||
else
|
||||
shader = null;
|
||||
|
||||
screenHandle.UseShader(shader);
|
||||
var tex = layer.Texture;
|
||||
|
||||
// Size of the texture in world units.
|
||||
@@ -52,10 +60,11 @@ public sealed class ParallaxOverlay : Overlay
|
||||
// The effects of this are such that a slowness of 1 anchors the layer to the centre of the screen, while a slowness of 0 anchors the layer to the world.
|
||||
// (For values 0.0 to 1.0 this is in effect a lerp, but it's deliberately unclamped.)
|
||||
// The ParallaxAnchor adapts the parallax for station positioning and possibly map-specific tweaks.
|
||||
var home = layer.Config.WorldHomePosition + _parallaxManager.ParallaxAnchor;
|
||||
var home = layer.Config.WorldHomePosition + _manager.ParallaxAnchor;
|
||||
var scrolled = layer.Config.Scrolling * realTime;
|
||||
|
||||
// Origin - start with the parallax shift itself.
|
||||
var originBL = (args.Viewport.Eye.Position.Position - home) * layer.Config.Slowness;
|
||||
var originBL = (position - home) * layer.Config.Slowness + scrolled;
|
||||
|
||||
// Place at the home.
|
||||
originBL += home;
|
||||
@@ -90,6 +99,8 @@ public sealed class ParallaxOverlay : Overlay
|
||||
screenHandle.DrawTextureRect(tex, Box2.FromDimensions(originBL, size));
|
||||
}
|
||||
}
|
||||
|
||||
screenHandle.UseShader(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
71
Content.Client/Parallax/ParallaxSystem.cs
Normal file
71
Content.Client/Parallax/ParallaxSystem.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Content.Client.Parallax.Managers;
|
||||
using Content.Shared.Parallax;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Parallax;
|
||||
|
||||
public sealed class ParallaxSystem : SharedParallaxSystem
|
||||
{
|
||||
[Dependency] private readonly IMapManager _map = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlay = default!;
|
||||
[Dependency] private readonly IParallaxManager _parallax = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||
|
||||
private const string Fallback = "Default";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_overlay.AddOverlay(new ParallaxOverlay());
|
||||
SubscribeLocalEvent<ParallaxComponent, ComponentHandleState>(OnParallaxHandleState);
|
||||
_protoManager.PrototypesReloaded += OnReload;
|
||||
}
|
||||
|
||||
private void OnReload(PrototypesReloadedEventArgs obj)
|
||||
{
|
||||
_parallax.UnloadParallax(Fallback);
|
||||
_parallax.LoadDefaultParallax();
|
||||
|
||||
foreach (var comp in EntityQuery<ParallaxComponent>(true))
|
||||
{
|
||||
_parallax.UnloadParallax(comp.Parallax);
|
||||
_parallax.LoadParallaxByName(comp.Parallax);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
_overlay.RemoveOverlay<ParallaxOverlay>();
|
||||
_protoManager.PrototypesReloaded -= OnReload;
|
||||
}
|
||||
|
||||
private void OnParallaxHandleState(EntityUid uid, ParallaxComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not ParallaxComponentState state) return;
|
||||
component.Parallax = state.Parallax;
|
||||
|
||||
if (!_parallax.IsLoaded(component.Parallax))
|
||||
{
|
||||
_parallax.LoadParallaxByName(component.Parallax);
|
||||
}
|
||||
}
|
||||
|
||||
public ParallaxLayerPrepared[] GetParallaxLayers(MapId mapId)
|
||||
{
|
||||
return _parallax.GetParallaxLayers(GetParallax(_map.GetMapEntityId(mapId)));
|
||||
}
|
||||
|
||||
public string GetParallax(MapId mapId)
|
||||
{
|
||||
return GetParallax(_map.GetMapEntityId(mapId));
|
||||
}
|
||||
|
||||
public string GetParallax(EntityUid mapUid)
|
||||
{
|
||||
return TryComp<ParallaxComponent>(mapUid, out var parallax) ? parallax.Parallax : Fallback;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Client.Parallax.Managers;
|
||||
using Content.Client.Parallax;
|
||||
using Robust.Shared.Maths;
|
||||
@@ -6,13 +8,30 @@ namespace Content.IntegrationTests
|
||||
{
|
||||
public sealed class DummyParallaxManager : IParallaxManager
|
||||
{
|
||||
public string ParallaxName { get; set; } = "";
|
||||
public Vector2 ParallaxAnchor { get; set; }
|
||||
public ParallaxLayerPrepared[] ParallaxLayers { get; } = {};
|
||||
|
||||
public void LoadParallax()
|
||||
public bool IsLoaded(string name)
|
||||
{
|
||||
ParallaxName = "default";
|
||||
return true;
|
||||
}
|
||||
|
||||
public ParallaxLayerPrepared[] GetParallaxLayers(string name)
|
||||
{
|
||||
return Array.Empty<ParallaxLayerPrepared>();
|
||||
}
|
||||
|
||||
public void LoadDefaultParallax()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public Task LoadParallaxByName(string name)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void UnloadParallax(string name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ using Robust.Shared.Map;
|
||||
namespace Content.IntegrationTests.Tests.Gravity
|
||||
{
|
||||
[TestFixture]
|
||||
[TestOf(typeof(WeightlessSystem))]
|
||||
[TestOf(typeof(GravitySystem))]
|
||||
[TestOf(typeof(GravityGeneratorComponent))]
|
||||
public sealed class WeightlessStatusTests
|
||||
{
|
||||
@@ -21,6 +21,9 @@ namespace Content.IntegrationTests.Tests.Gravity
|
||||
id: HumanDummy
|
||||
components:
|
||||
- type: Alerts
|
||||
- type: Physics
|
||||
bodyType: Dynamic
|
||||
|
||||
- type: entity
|
||||
name: GravityGeneratorDummy
|
||||
id: GravityGeneratorDummy
|
||||
@@ -38,7 +41,6 @@ namespace Content.IntegrationTests.Tests.Gravity
|
||||
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{NoClient = true, ExtraPrototypes = Prototypes});
|
||||
var server = pairTracker.Pair.Server;
|
||||
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var alertsSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<AlertsSystem>();
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ namespace Content.IntegrationTests.Tests
|
||||
var grid1Entity = grid1.GridEntityId;
|
||||
var grid2Entity = grid2.GridEntityId;
|
||||
|
||||
Assert.That(!entityMan.GetComponent<GravityComponent>(grid1Entity).Enabled);
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).Enabled);
|
||||
Assert.That(!entityMan.GetComponent<GravityComponent>(grid1Entity).EnabledVV);
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).EnabledVV);
|
||||
|
||||
// Re-enable needs power so it turns off again.
|
||||
// Charge rate is ridiculously high so it finishes in one tick.
|
||||
@@ -88,7 +88,7 @@ namespace Content.IntegrationTests.Tests
|
||||
|
||||
var grid2Entity = grid2.GridEntityId;
|
||||
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).Enabled, Is.False);
|
||||
Assert.That(entityMan.GetComponent<GravityComponent>(grid2Entity).EnabledVV, Is.False);
|
||||
});
|
||||
|
||||
await pairTracker.CleanReturnAsync();
|
||||
|
||||
@@ -4,16 +4,16 @@ using JetBrains.Annotations;
|
||||
namespace Content.Server.Gravity.EntitySystems
|
||||
{
|
||||
[UsedImplicitly]
|
||||
internal sealed class GravitySystem : SharedGravitySystem
|
||||
public sealed class GravitySystem : SharedGravitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<GravityComponent, ComponentInit>(HandleGravityInitialize);
|
||||
SubscribeLocalEvent<GravityComponent, ComponentShutdown>(HandleGravityShutdown);
|
||||
SubscribeLocalEvent<GravityComponent, ComponentInit>(OnGravityInit);
|
||||
SubscribeLocalEvent<GravityComponent, ComponentShutdown>(OnGravityShutdown);
|
||||
}
|
||||
|
||||
private void HandleGravityInitialize(EntityUid uid, GravityComponent component, ComponentInit args)
|
||||
private void OnGravityInit(EntityUid uid, GravityComponent component, ComponentInit args)
|
||||
{
|
||||
// Incase there's already a generator on the grid we'll just set it now.
|
||||
var gridId = Transform(component.Owner).GridUid;
|
||||
@@ -21,25 +21,25 @@ namespace Content.Server.Gravity.EntitySystems
|
||||
if (gridId == null)
|
||||
return;
|
||||
|
||||
GravityChangedMessage message;
|
||||
GravityChangedEvent message;
|
||||
|
||||
foreach (var generator in EntityManager.EntityQuery<GravityGeneratorComponent>())
|
||||
{
|
||||
if (Transform(generator.Owner).GridUid == gridId && generator.GravityActive)
|
||||
{
|
||||
component.Enabled = true;
|
||||
message = new GravityChangedMessage(gridId.Value, true);
|
||||
message = new GravityChangedEvent(gridId.Value, true);
|
||||
RaiseLocalEvent(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
component.Enabled = false;
|
||||
message = new GravityChangedMessage(gridId.Value, false);
|
||||
message = new GravityChangedEvent(gridId.Value, false);
|
||||
RaiseLocalEvent(message);
|
||||
}
|
||||
|
||||
private void HandleGravityShutdown(EntityUid uid, GravityComponent component, ComponentShutdown args)
|
||||
private void OnGravityShutdown(EntityUid uid, GravityComponent component, ComponentShutdown args)
|
||||
{
|
||||
DisableGravity(component);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ namespace Content.Server.Gravity.EntitySystems
|
||||
return;
|
||||
|
||||
comp.Enabled = true;
|
||||
var message = new GravityChangedMessage(gridId.Value, true);
|
||||
var message = new GravityChangedEvent(gridId.Value, true);
|
||||
RaiseLocalEvent(message);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Content.Server.Gravity.EntitySystems
|
||||
if (gridId == null)
|
||||
return;
|
||||
|
||||
var message = new GravityChangedMessage(gridId.Value, false);
|
||||
var message = new GravityChangedEvent(gridId.Value, false);
|
||||
RaiseLocalEvent(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Gravity;
|
||||
using Content.Shared.Movement.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Gravity.EntitySystems
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public sealed class WeightlessSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
|
||||
|
||||
private readonly Dictionary<EntityUid, List<AlertsComponent>> _alerts = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
|
||||
SubscribeLocalEvent<GravityChangedMessage>(GravityChanged);
|
||||
SubscribeLocalEvent<AlertsComponent, EntParentChangedMessage>(EntParentChanged);
|
||||
SubscribeLocalEvent<AlertsComponent, AlertSyncEvent>(HandleAlertSyncEvent);
|
||||
}
|
||||
|
||||
public void Reset(RoundRestartCleanupEvent ev)
|
||||
{
|
||||
_alerts.Clear();
|
||||
}
|
||||
|
||||
public void AddAlert(AlertsComponent status)
|
||||
{
|
||||
var xform = Transform(status.Owner);
|
||||
if (xform.GridUid != null)
|
||||
{
|
||||
var alerts = _alerts.GetOrNew(xform.GridUid.Value);
|
||||
alerts.Add(status);
|
||||
}
|
||||
|
||||
if (_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
||||
{
|
||||
var alerts = _alerts.GetOrNew(xform.GridUid.Value);
|
||||
alerts.Add(status);
|
||||
|
||||
if (EntityManager.GetComponent<GravityComponent>(grid.GridEntityId).Enabled)
|
||||
{
|
||||
RemoveWeightless(status.Owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddWeightless(status.Owner);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddWeightless(status.Owner);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAlert(AlertsComponent status)
|
||||
{
|
||||
var grid = EntityManager.GetComponent<TransformComponent>(status.Owner).GridUid;
|
||||
if (grid == null || !_alerts.TryGetValue(grid.Value, out var statuses))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
statuses.Remove(status);
|
||||
}
|
||||
|
||||
private void GravityChanged(GravityChangedMessage ev)
|
||||
{
|
||||
if (!_alerts.TryGetValue(ev.ChangedGridIndex, out var statuses))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ev.HasGravity)
|
||||
{
|
||||
foreach (var status in statuses)
|
||||
{
|
||||
RemoveWeightless(status.Owner);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var status in statuses)
|
||||
{
|
||||
AddWeightless(status.Owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddWeightless(EntityUid euid)
|
||||
{
|
||||
_alertsSystem.ShowAlert(euid, AlertType.Weightless);
|
||||
}
|
||||
|
||||
private void RemoveWeightless(EntityUid euid)
|
||||
{
|
||||
_alertsSystem.ClearAlert(euid, AlertType.Weightless);
|
||||
}
|
||||
|
||||
private void EntParentChanged(EntityUid uid, AlertsComponent status, ref EntParentChangedMessage ev)
|
||||
{
|
||||
// First, update the `_alerts` dictionary
|
||||
if (ev.OldParent is {Valid: true} old &&
|
||||
EntityManager.TryGetComponent(old, out IMapGridComponent? mapGrid))
|
||||
{
|
||||
var oldGrid = mapGrid.Owner;
|
||||
|
||||
if (_alerts.TryGetValue(oldGrid, out var oldStatuses))
|
||||
{
|
||||
oldStatuses.Remove(status);
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.Transform.MapID == MapId.Nullspace)
|
||||
return;
|
||||
|
||||
|
||||
var newGrid = ev.Transform.GridUid;
|
||||
if (newGrid != null)
|
||||
{
|
||||
var newStatuses = _alerts.GetOrNew(newGrid.Value);
|
||||
newStatuses.Add(status);
|
||||
}
|
||||
|
||||
// then update the actual alert. The alert is only removed if either the player is on a grid with gravity,
|
||||
// or if they ignore gravity-based movement altogether.
|
||||
// TODO: update this when planets and the like are added.
|
||||
// TODO: update alert when the ignore-gravity component is added or removed.
|
||||
if (_mapManager.TryGetGrid(newGrid, out var grid)
|
||||
&& TryComp(grid.GridEntityId, out GravityComponent? gravity)
|
||||
&& gravity.Enabled)
|
||||
RemoveWeightless(status.Owner);
|
||||
else if (!HasComp<MovementIgnoreGravityComponent>(uid))
|
||||
AddWeightless(status.Owner);
|
||||
}
|
||||
|
||||
private void HandleAlertSyncEvent(EntityUid uid, AlertsComponent component, AlertSyncEvent args)
|
||||
{
|
||||
switch (component.LifeStage)
|
||||
{
|
||||
case ComponentLifeStage.Starting:
|
||||
AddAlert(component);
|
||||
break;
|
||||
case ComponentLifeStage.Removing:
|
||||
RemoveAlert(component);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Content.Server/Parallax/ParallaxSystem.cs
Normal file
23
Content.Server/Parallax/ParallaxSystem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Content.Shared.Parallax;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Server.Parallax;
|
||||
|
||||
public sealed class ParallaxSystem : SharedParallaxSystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ParallaxComponent, ComponentGetState>(OnParallaxGetState);
|
||||
}
|
||||
|
||||
private void OnParallaxGetState(EntityUid uid, ParallaxComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new ParallaxComponentState
|
||||
{
|
||||
Parallax = component.Parallax
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using Content.Server.Doors.Systems;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.Stunnable;
|
||||
using Content.Shared.Parallax;
|
||||
using Content.Shared.Shuttles.Systems;
|
||||
using Content.Shared.Sound;
|
||||
using Content.Shared.StatusEffect;
|
||||
@@ -195,6 +196,8 @@ public sealed partial class ShuttleSystem
|
||||
component = AddComp<FTLComponent>(uid);
|
||||
// TODO: Need BroadcastGrid to not be bad.
|
||||
SoundSystem.Play(_startupSound.GetSound(), Filter.Empty().AddInRange(Transform(uid).MapPosition, GetSoundRange(component.Owner)), _startupSound.Params);
|
||||
// Make sure the map is setup before we leave to avoid pop-in (e.g. parallax).
|
||||
SetupHyperspace();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -217,7 +220,6 @@ public sealed partial class ShuttleSystem
|
||||
DoTheDinosaur(xform);
|
||||
|
||||
comp.State = FTLState.Travelling;
|
||||
SetupHyperspace();
|
||||
|
||||
var width = Comp<IMapGridComponent>(comp.Owner).Grid.LocalAABB.Width;
|
||||
xform.Coordinates = new EntityCoordinates(_mapManager.GetMapEntityId(_hyperSpaceMap!.Value), new Vector2(_index + width / 2f, 0f));
|
||||
@@ -352,6 +354,8 @@ public sealed partial class ShuttleSystem
|
||||
_hyperSpaceMap = _mapManager.CreateMap();
|
||||
_sawmill.Info($"Setup hyperspace map at {_hyperSpaceMap.Value}");
|
||||
DebugTools.Assert(!_mapManager.IsMapPaused(_hyperSpaceMap.Value));
|
||||
var parallax = EnsureComp<ParallaxComponent>(_mapManager.GetMapEntityId(_hyperSpaceMap.Value));
|
||||
parallax.Parallax = "FastSpace";
|
||||
}
|
||||
|
||||
private void CleanupHyperspace()
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace Content.Shared.Friction
|
||||
|
||||
private float _stopSpeed;
|
||||
private float _frictionModifier;
|
||||
private const float DefaultFriction = 0.3f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -168,17 +169,21 @@ namespace Content.Shared.Friction
|
||||
private float GetTileFriction(PhysicsComponent body, TransformComponent xform)
|
||||
{
|
||||
// TODO: Make IsWeightless event-based; we already have grid traversals tracked so just raise events
|
||||
if (_gravity.IsWeightless(body.Owner, body, xform) ||
|
||||
!_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
||||
if (_gravity.IsWeightless(body.Owner, body, xform))
|
||||
return 0.0f;
|
||||
|
||||
if (!xform.Coordinates.IsValid(EntityManager)) return 0.0f;
|
||||
|
||||
if (_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
||||
{
|
||||
var tile = grid.GetTileRef(xform.Coordinates);
|
||||
var tileDef = _tileDefinitionManager[tile.Tile.TypeId];
|
||||
return tileDef.Friction;
|
||||
}
|
||||
|
||||
return TryComp<TileFrictionModifierComponent>(xform.MapUid, out var friction) ? friction.Modifier : DefaultFriction;
|
||||
}
|
||||
|
||||
[NetSerializable, Serializable]
|
||||
private sealed class TileFrictionComponentState : ComponentState
|
||||
{
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Shared.Gravity
|
||||
{
|
||||
public sealed class GravityChangedMessage : EntityEventArgs
|
||||
public sealed class GravityChangedEvent : EntityEventArgs
|
||||
{
|
||||
public GravityChangedMessage(EntityUid changedGridIndex, bool newGravityState)
|
||||
public GravityChangedEvent(EntityUid changedGridIndex, bool newGravityState)
|
||||
{
|
||||
HasGravity = newGravityState;
|
||||
ChangedGridIndex = changedGridIndex;
|
||||
@@ -12,48 +12,19 @@ namespace Content.Shared.Gravity
|
||||
public SoundSpecifier GravityShakeSound { get; set; } = new SoundPathSpecifier("/Audio/Effects/alert.ogg");
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool Enabled
|
||||
public bool EnabledVV
|
||||
{
|
||||
get => _enabled;
|
||||
get => Enabled;
|
||||
set
|
||||
{
|
||||
if (_enabled == value) return;
|
||||
_enabled = value;
|
||||
if (_enabled)
|
||||
{
|
||||
Logger.Info($"Enabled gravity for {Owner}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info($"Disabled gravity for {Owner}");
|
||||
}
|
||||
if (Enabled == value) return;
|
||||
Enabled = value;
|
||||
IoCManager.Resolve<IEntityManager>().EventBus.RaiseLocalEvent(Owner, new GravityChangedEvent(Owner, value));
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _enabled;
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
{
|
||||
return new GravityComponentState(_enabled);
|
||||
}
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
base.HandleComponentState(curState, nextState);
|
||||
if (curState is not GravityComponentState state) return;
|
||||
Enabled = state.Enabled;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
private sealed class GravityComponentState : ComponentState
|
||||
{
|
||||
public bool Enabled { get; }
|
||||
|
||||
public GravityComponentState(bool enabled)
|
||||
{
|
||||
Enabled = enabled;
|
||||
}
|
||||
}
|
||||
[DataField("enabled")]
|
||||
public bool Enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Gravity
|
||||
{
|
||||
public abstract class SharedGravitySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
|
||||
public bool IsWeightless(EntityUid uid, PhysicsComponent? body = null, TransformComponent? xform = null)
|
||||
@@ -21,23 +24,16 @@ namespace Content.Shared.Gravity
|
||||
if (TryComp<MovementIgnoreGravityComponent>(uid, out var ignoreGravityComponent))
|
||||
return ignoreGravityComponent.Weightless;
|
||||
|
||||
if (!Resolve(uid, ref xform)) return true;
|
||||
|
||||
bool gravityEnabled = false;
|
||||
if (!Resolve(uid, ref xform))
|
||||
return true;
|
||||
|
||||
// If grid / map has gravity
|
||||
if ((TryComp<GravityComponent>(xform.GridUid, out var gravity) ||
|
||||
TryComp(xform.MapUid, out gravity)) && gravity.Enabled)
|
||||
{
|
||||
gravityEnabled = gravity.Enabled;
|
||||
|
||||
if (gravityEnabled) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// On the map then always weightless (unless it has gravity comp obv).
|
||||
if (!_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
||||
return true;
|
||||
|
||||
// Something holding us down
|
||||
if (_inventory.TryGetSlotEntity(uid, "shoes", out var ent))
|
||||
{
|
||||
@@ -45,21 +41,76 @@ namespace Content.Shared.Gravity
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gravityEnabled || !xform.Coordinates.IsValid(EntityManager)) return true;
|
||||
|
||||
var tile = grid.GetTileRef(xform.Coordinates).Tile;
|
||||
return tile.IsEmpty;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<GridInitializeEvent>(HandleGridInitialize);
|
||||
SubscribeLocalEvent<AlertsComponent, EntParentChangedMessage>(OnAlertsParentChange);
|
||||
SubscribeLocalEvent<GravityChangedEvent>(OnGravityChange);
|
||||
SubscribeLocalEvent<GravityComponent, ComponentGetState>(OnGetState);
|
||||
SubscribeLocalEvent<GravityComponent, ComponentHandleState>(OnHandleState);
|
||||
}
|
||||
|
||||
private void OnHandleState(EntityUid uid, GravityComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not GravityComponentState state) return;
|
||||
|
||||
if (component.EnabledVV == state.Enabled) return;
|
||||
component.EnabledVV = state.Enabled;
|
||||
RaiseLocalEvent(new GravityChangedEvent(uid, component.EnabledVV));
|
||||
}
|
||||
|
||||
private void OnGetState(EntityUid uid, GravityComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new GravityComponentState(component.EnabledVV);
|
||||
}
|
||||
|
||||
private void OnGravityChange(GravityChangedEvent ev)
|
||||
{
|
||||
foreach (var (comp, xform) in EntityQuery<AlertsComponent, TransformComponent>(true))
|
||||
{
|
||||
if (xform.GridUid != ev.ChangedGridIndex) continue;
|
||||
|
||||
if (!ev.HasGravity)
|
||||
{
|
||||
_alerts.ShowAlert(comp.Owner, AlertType.Weightless);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlert(comp.Owner, AlertType.Weightless);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAlertsParentChange(EntityUid uid, AlertsComponent component, ref EntParentChangedMessage args)
|
||||
{
|
||||
if (IsWeightless(component.Owner))
|
||||
{
|
||||
_alerts.ShowAlert(uid, AlertType.Weightless);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlert(uid, AlertType.Weightless);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleGridInitialize(GridInitializeEvent ev)
|
||||
{
|
||||
EntityManager.EnsureComponent<GravityComponent>(ev.EntityUid);
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
private sealed class GravityComponentState : ComponentState
|
||||
{
|
||||
public bool Enabled { get; }
|
||||
|
||||
public GravityComponentState(bool enabled)
|
||||
{
|
||||
Enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Movement.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Changes footstep sound
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed class FootstepModifierComponent : Component
|
||||
{
|
||||
[DataField("footstepSoundCollection", required: true)]
|
||||
public SoundSpecifier SoundCollection = default!;
|
||||
|
||||
[DataField("variation")]
|
||||
public float Variation = default;
|
||||
public SoundSpecifier Sound = default!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Content.Shared.Movement.Components
|
||||
var gridId = transform.GridUid;
|
||||
|
||||
if ((entityManager.TryGetComponent<GravityComponent>(transform.GridUid, out var gravity) ||
|
||||
entityManager.TryGetComponent(transform.MapUid, out gravity)) && gravity.Enabled)
|
||||
entityManager.TryGetComponent(transform.MapUid, out gravity)) && gravity.EnabledVV)
|
||||
return false;
|
||||
|
||||
if (gridId == null)
|
||||
@@ -67,7 +67,7 @@ namespace Content.Shared.Movement.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entityManager.GetComponent<GravityComponent>(grid.GridEntityId).Enabled)
|
||||
if (!entityManager.GetComponent<GravityComponent>(grid.GridEntityId).EnabledVV)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
SubscribeLocalEvent<JetpackUserComponent, ComponentGetState>(OnJetpackUserGetState);
|
||||
SubscribeLocalEvent<JetpackUserComponent, ComponentHandleState>(OnJetpackUserHandleState);
|
||||
|
||||
SubscribeLocalEvent<GravityChangedMessage>(OnJetpackUserGravityChanged);
|
||||
SubscribeLocalEvent<GravityChangedEvent>(OnJetpackUserGravityChanged);
|
||||
}
|
||||
|
||||
private void OnJetpackCanWeightlessMove(EntityUid uid, JetpackComponent component, ref CanWeightlessMoveEvent args)
|
||||
@@ -44,7 +44,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
args.CanMove = true;
|
||||
}
|
||||
|
||||
private void OnJetpackUserGravityChanged(GravityChangedMessage ev)
|
||||
private void OnJetpackUserGravityChanged(GravityChangedEvent ev)
|
||||
{
|
||||
var gridUid = ev.ChangedGridIndex;
|
||||
var jetpackQuery = GetEntityQuery<JetpackComponent>();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Movement.Systems;
|
||||
|
||||
public abstract partial class SharedMoverController
|
||||
{
|
||||
private void InitializeFootsteps()
|
||||
{
|
||||
SubscribeLocalEvent<FootstepModifierComponent, ComponentGetState>(OnFootGetState);
|
||||
SubscribeLocalEvent<FootstepModifierComponent, ComponentHandleState>(OnFootHandleState);
|
||||
}
|
||||
|
||||
private void OnFootHandleState(EntityUid uid, FootstepModifierComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not FootstepModifierComponentState state) return;
|
||||
component.Sound = state.Sound;
|
||||
}
|
||||
|
||||
private void OnFootGetState(EntityUid uid, FootstepModifierComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new FootstepModifierComponentState()
|
||||
{
|
||||
Sound = component.Sound,
|
||||
};
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
private sealed class FootstepModifierComponentState : ComponentState
|
||||
{
|
||||
public SoundSpecifier Sound = default!;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ using Content.Shared.MobState.EntitySystems;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Pulling.Components;
|
||||
using Content.Shared.Sound;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Configuration;
|
||||
@@ -61,6 +62,7 @@ namespace Content.Shared.Movement.Systems
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeFootsteps();
|
||||
InitializeInput();
|
||||
InitializeMob();
|
||||
InitializePushing();
|
||||
@@ -215,12 +217,13 @@ namespace Content.Shared.Movement.Systems
|
||||
: worldTotal.ToWorldAngle();
|
||||
rotateXform.DeferUpdates = false;
|
||||
|
||||
if (!weightless && TryComp<MobMoverComponent>(mover.Owner, out var mobMover) && TryGetSound(mover, mobMover, xform, out var variation, out var sound))
|
||||
if (!weightless && TryComp<MobMoverComponent>(mover.Owner, out var mobMover) &&
|
||||
TryGetSound(weightless, mover, mobMover, xform, out var sound))
|
||||
{
|
||||
var soundModifier = mover.Sprinting ? 1.0f : FootstepWalkingAddedVolumeMultiplier;
|
||||
SoundSystem.Play(sound,
|
||||
SoundSystem.Play(sound.GetSound(),
|
||||
GetSoundPlayers(mover.Owner),
|
||||
mover.Owner, AudioHelpers.WithVariation(variation).WithVolume(FootstepVolume * soundModifier));
|
||||
mover.Owner, sound.Params.WithVolume(FootstepVolume * soundModifier));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,19 +316,17 @@ namespace Content.Shared.Movement.Systems
|
||||
|
||||
protected abstract bool CanSound();
|
||||
|
||||
private bool TryGetSound(InputMoverComponent mover, MobMoverComponent mobMover, TransformComponent xform, out float variation, [NotNullWhen(true)] out string? sound)
|
||||
private bool TryGetSound(bool weightless, InputMoverComponent mover, MobMoverComponent mobMover, TransformComponent xform, [NotNullWhen(true)] out SoundSpecifier? sound)
|
||||
{
|
||||
sound = null;
|
||||
variation = 0f;
|
||||
|
||||
if (!CanSound() || !_tags.HasTag(mover.Owner, "FootstepSound")) return false;
|
||||
|
||||
var coordinates = xform.Coordinates;
|
||||
var gridId = coordinates.GetGridUid(EntityManager);
|
||||
var distanceNeeded = mover.Sprinting ? StepSoundMoveDistanceRunning : StepSoundMoveDistanceWalking;
|
||||
|
||||
// Handle footsteps.
|
||||
if (_mapManager.GridExists(gridId))
|
||||
if (!weightless)
|
||||
{
|
||||
// Can happen when teleporting between grids.
|
||||
if (!coordinates.TryDistance(EntityManager, mobMover.LastPosition, out var distance) ||
|
||||
@@ -344,7 +345,6 @@ namespace Content.Shared.Movement.Systems
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugTools.Assert(gridId != null);
|
||||
mobMover.LastPosition = coordinates;
|
||||
|
||||
if (mobMover.StepSoundDistance < distanceNeeded) return false;
|
||||
@@ -354,19 +354,31 @@ namespace Content.Shared.Movement.Systems
|
||||
if (_inventory.TryGetSlotEntity(mover.Owner, "shoes", out var shoes) &&
|
||||
EntityManager.TryGetComponent<FootstepModifierComponent>(shoes, out var modifier))
|
||||
{
|
||||
sound = modifier.SoundCollection.GetSound();
|
||||
variation = modifier.Variation;
|
||||
sound = modifier.Sound;
|
||||
return true;
|
||||
}
|
||||
|
||||
return TryGetFootstepSound(gridId!.Value, coordinates, out variation, out sound);
|
||||
return TryGetFootstepSound(coordinates, out sound);
|
||||
}
|
||||
|
||||
private bool TryGetFootstepSound(EntityUid gridId, EntityCoordinates coordinates, out float variation, [NotNullWhen(true)] out string? sound)
|
||||
private bool TryGetFootstepSound(EntityCoordinates coordinates, [NotNullWhen(true)] out SoundSpecifier? sound)
|
||||
{
|
||||
variation = 0f;
|
||||
sound = null;
|
||||
var grid = _mapManager.GetGrid(gridId);
|
||||
var gridUid = coordinates.GetGridUid(EntityManager);
|
||||
|
||||
// Fallback to the map
|
||||
if (gridUid == null)
|
||||
{
|
||||
if (TryComp<FootstepModifierComponent>(coordinates.GetMapUid(EntityManager), out var modifier))
|
||||
{
|
||||
sound = modifier.Sound;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var grid = _mapManager.GetGrid(gridUid.Value);
|
||||
var tile = grid.GetTileRef(coordinates);
|
||||
|
||||
if (tile.IsSpace(_tileDefinitionManager)) return false;
|
||||
@@ -377,18 +389,15 @@ namespace Content.Shared.Movement.Systems
|
||||
{
|
||||
if (EntityManager.TryGetComponent(maybeFootstep, out FootstepModifierComponent? footstep))
|
||||
{
|
||||
sound = footstep.SoundCollection.GetSound();
|
||||
variation = footstep.Variation;
|
||||
sound = footstep.Sound;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Walking on a tile.
|
||||
var def = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
|
||||
sound = def.FootstepSounds?.GetSound();
|
||||
variation = FootstepVariation;
|
||||
|
||||
return !string.IsNullOrEmpty(sound);
|
||||
sound = def.FootstepSounds;
|
||||
return sound != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
Content.Shared/Parallax/ParallaxComponent.cs
Normal file
28
Content.Shared/Parallax/ParallaxComponent.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Parallax;
|
||||
|
||||
/// <summary>
|
||||
/// Handles per-map parallax
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed class ParallaxComponent : Component
|
||||
{
|
||||
// I wish I could use a typeserializer here but parallax is extremely client-dependent.
|
||||
[DataField("parallax")]
|
||||
public string Parallax = "Default";
|
||||
|
||||
[UsedImplicitly, ViewVariables(VVAccess.ReadWrite)]
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public string ParallaxVV
|
||||
{
|
||||
get => Parallax;
|
||||
set
|
||||
{
|
||||
if (value.Equals(Parallax)) return;
|
||||
Parallax = value;
|
||||
IoCManager.Resolve<IEntityManager>().Dirty(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Content.Shared/Parallax/SharedParallaxSystem.cs
Normal file
16
Content.Shared/Parallax/SharedParallaxSystem.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Parallax;
|
||||
|
||||
/// <summary>
|
||||
/// Handles per-map parallax in sim. Out of sim parallax is handled by ParallaxManager.
|
||||
/// </summary>
|
||||
public abstract class SharedParallaxSystem: EntitySystem
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
protected sealed class ParallaxComponentState : ComponentState
|
||||
{
|
||||
public string Parallax = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -89,8 +89,6 @@ grids:
|
||||
tiles: MAAAAC0AAAAtAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAALQAAAC0AAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAALQAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: 1,-2
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAwAAAAMAAAADAAAAAwAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAtAAAAMAAAADAAAAAtAAAAMAAAADAAAAAtAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAALQAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAALQAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAMAAAADAAAAAwAAAALQAAADAAAAAwAAAAMAAAAA==
|
||||
- ind: -2,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: -2,0
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAAC0AAAAtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAtAAAALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAAC0AAAAtAAAALQAAAC0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAA==
|
||||
- ind: -2,1
|
||||
@@ -107,12 +105,6 @@ grids:
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: -3,-2
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtAAAALQAAAC0AAAAtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALQAAAC0AAAAtAAAALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0AAAAtAAAALQAAAC0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtAAAALQAAAC0AAAAtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: -4,0
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: -4,1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: -4,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: 0,2
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
- ind: 1,2
|
||||
@@ -221,8 +213,6 @@ entities:
|
||||
- pos: 3.9415665,-8.34479
|
||||
parent: 104
|
||||
type: Transform
|
||||
- canCollide: False
|
||||
type: Physics
|
||||
- solution: drink
|
||||
type: DrainableSolution
|
||||
- uid: 16
|
||||
@@ -238,8 +228,6 @@ entities:
|
||||
- pos: 3.5882664,-8.344303
|
||||
parent: 104
|
||||
type: Transform
|
||||
- canCollide: False
|
||||
type: Physics
|
||||
- uid: 18
|
||||
type: computerBodyScanner
|
||||
components:
|
||||
@@ -293,8 +281,6 @@ entities:
|
||||
- pos: -0.5303154,-6.2851996
|
||||
parent: 104
|
||||
type: Transform
|
||||
- canCollide: False
|
||||
type: Physics
|
||||
- solution: drink
|
||||
type: DrainableSolution
|
||||
- uid: 26
|
||||
@@ -303,8 +289,6 @@ entities:
|
||||
- pos: 4.4214306,-6.3946886
|
||||
parent: 104
|
||||
type: Transform
|
||||
- canCollide: False
|
||||
type: Physics
|
||||
- uid: 27
|
||||
type: Windoor
|
||||
components:
|
||||
@@ -792,7 +776,7 @@ entities:
|
||||
- name: Syndicate Outpost
|
||||
type: MetaData
|
||||
- pos: -23.318382,8.069332
|
||||
parent: null
|
||||
parent: 1291
|
||||
type: Transform
|
||||
- whitelist:
|
||||
tags:
|
||||
@@ -800,8 +784,8 @@ entities:
|
||||
type: FTLDestination
|
||||
- index: 0
|
||||
type: MapGrid
|
||||
- angularDamping: 100
|
||||
linearDamping: 50
|
||||
- angularDamping: 0.05
|
||||
linearDamping: 0.05
|
||||
fixedRotation: False
|
||||
bodyType: Dynamic
|
||||
type: Physics
|
||||
@@ -1119,47 +1103,47 @@ entities:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-13
|
||||
171:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-15
|
||||
170:
|
||||
166:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-14
|
||||
173:
|
||||
167:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-17
|
||||
172:
|
||||
coordinates: -9,-15
|
||||
168:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-16
|
||||
174:
|
||||
169:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-17
|
||||
170:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-18
|
||||
175:
|
||||
171:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-19
|
||||
176:
|
||||
172:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-20
|
||||
177:
|
||||
173:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-21
|
||||
178:
|
||||
174:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-22
|
||||
179:
|
||||
175:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-23
|
||||
180:
|
||||
176:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnLineS
|
||||
coordinates: -9,-24
|
||||
@@ -1533,19 +1517,19 @@ entities:
|
||||
color: '#FFFFFFFF'
|
||||
id: Caution
|
||||
coordinates: -18,1
|
||||
164:
|
||||
162:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarningLine
|
||||
coordinates: -18,1
|
||||
167:
|
||||
163:
|
||||
color: '#FFFFFFFF'
|
||||
id: Box
|
||||
coordinates: -14,1
|
||||
168:
|
||||
164:
|
||||
color: '#FFFFFFFF'
|
||||
id: StandClear
|
||||
coordinates: -14,1
|
||||
169:
|
||||
165:
|
||||
color: '#FFFFFFFF'
|
||||
id: WarnEnd
|
||||
coordinates: -6,21
|
||||
@@ -5703,6 +5687,46 @@ entities:
|
||||
18,32: 0
|
||||
19,32: 0
|
||||
20,32: 0
|
||||
-32,1: 1
|
||||
-32,2: 1
|
||||
-32,3: 1
|
||||
-32,4: 1
|
||||
-31,1: 1
|
||||
-31,2: 1
|
||||
-31,3: 1
|
||||
-31,4: 1
|
||||
-30,1: 1
|
||||
-30,2: 1
|
||||
-30,3: 1
|
||||
-30,4: 1
|
||||
-29,1: 1
|
||||
-29,2: 1
|
||||
-29,3: 1
|
||||
-29,4: 1
|
||||
-28,1: 1
|
||||
-28,2: 1
|
||||
-28,3: 1
|
||||
-28,4: 1
|
||||
-27,1: 1
|
||||
-27,2: 1
|
||||
-27,3: 1
|
||||
-27,4: 1
|
||||
-26,1: 1
|
||||
-26,2: 1
|
||||
-26,3: 1
|
||||
-26,4: 1
|
||||
-35,1: 1
|
||||
-35,2: 1
|
||||
-35,3: 1
|
||||
-35,4: 1
|
||||
-34,1: 1
|
||||
-34,2: 1
|
||||
-34,3: 1
|
||||
-34,4: 1
|
||||
-33,1: 1
|
||||
-33,2: 1
|
||||
-33,3: 1
|
||||
-33,4: 1
|
||||
uniqueMixes:
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
@@ -5715,6 +5739,17 @@ entities:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
type: GridAtmosphere
|
||||
- uid: 105
|
||||
type: WallRiveted
|
||||
@@ -13554,6 +13589,32 @@ entities:
|
||||
- pos: -10.5,-1.5
|
||||
parent: 104
|
||||
type: Transform
|
||||
- uid: 1291
|
||||
components:
|
||||
- index: 2
|
||||
type: Map
|
||||
- footstepSoundCollection:
|
||||
collection: footstep_snow
|
||||
type: FootstepModifier
|
||||
- gravityShakeSound: !type:SoundPathSpecifier
|
||||
path: /Audio/Effects/alert.ogg
|
||||
type: Gravity
|
||||
- parallax: Sky
|
||||
type: Parallax
|
||||
- space: False
|
||||
mixture:
|
||||
volume: 2500
|
||||
temperature: 248.15
|
||||
moles:
|
||||
- 21.824879
|
||||
- 82.10312
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
type: MapAtmosphere
|
||||
- uid: 1298
|
||||
type: AsteroidRock
|
||||
components:
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
- type: Clothing
|
||||
sprite: Clothing/Shoes/Misc/duck-slippers.rsi
|
||||
- type: FootstepModifier
|
||||
variation: 0.07
|
||||
footstepSoundCollection:
|
||||
collection: footstep_duck
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
- type: EmitSoundOnUse
|
||||
sound:
|
||||
collection: BikeHorn
|
||||
variation: 0.125
|
||||
- type: UseDelay
|
||||
delay: 0.5
|
||||
- type: EmitSoundOnTrigger
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- type: parallax
|
||||
id: default
|
||||
id: Default
|
||||
layers:
|
||||
- texture:
|
||||
!type:ImageParallaxTextureSource
|
||||
@@ -33,3 +33,41 @@
|
||||
configPath: "/Prototypes/Parallaxes/parallax_config.toml"
|
||||
slowness: 0.875
|
||||
layersLQUseHQ: false
|
||||
|
||||
# Because hyperspace and the menu need their own.
|
||||
- type: parallax
|
||||
id: FastSpace
|
||||
layers:
|
||||
- texture:
|
||||
!type:ImageParallaxTextureSource
|
||||
path: "/Textures/Parallaxes/layer1.png"
|
||||
slowness: 0.5
|
||||
scale: "1, 1"
|
||||
- texture:
|
||||
!type:GeneratedParallaxTextureSource
|
||||
id: "hq_wizard_stars"
|
||||
configPath: "/Prototypes/Parallaxes/parallax_config_stars.toml"
|
||||
slowness: 0.25
|
||||
- texture:
|
||||
!type:GeneratedParallaxTextureSource
|
||||
id: "hq_wizards_star_slower"
|
||||
configPath: "/Prototypes/Parallaxes/parallax_config_stars-2.toml"
|
||||
slowness: 0.15
|
||||
- texture:
|
||||
!type:GeneratedParallaxTextureSource
|
||||
id: "hq_wizard_stars_dim"
|
||||
configPath: "/Prototypes/Parallaxes/parallax_config_stars_dim.toml"
|
||||
slowness: 0.375
|
||||
- texture:
|
||||
!type:GeneratedParallaxTextureSource
|
||||
id: "hq_wizard_stars_dim_faster"
|
||||
configPath: "/Prototypes/Parallaxes/parallax_config_stars_dim-2.toml"
|
||||
slowness: 0.125
|
||||
layersLQ:
|
||||
- texture:
|
||||
!type:GeneratedParallaxTextureSource
|
||||
id: ""
|
||||
configPath: "/Prototypes/Parallaxes/parallax_config.toml"
|
||||
slowness: 0.5
|
||||
layersLQUseHQ: false
|
||||
|
||||
|
||||
24
Resources/Prototypes/Parallaxes/planet.yml
Normal file
24
Resources/Prototypes/Parallaxes/planet.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
- type: parallax
|
||||
id: Sky
|
||||
layers:
|
||||
- texture:
|
||||
!type:ImageParallaxTextureSource
|
||||
path: "/Textures/Parallaxes/land.png"
|
||||
slowness: 0.98
|
||||
scale: 1,1
|
||||
- texture:
|
||||
!type:ImageParallaxTextureSource
|
||||
path: "/Textures/Parallaxes/noise.png"
|
||||
slowness: 0.95
|
||||
scale: "2, 2"
|
||||
scrolling: "0.1, -0.05"
|
||||
|
||||
- type: parallax
|
||||
id: Snow
|
||||
layers:
|
||||
- texture:
|
||||
!type:ImageParallaxTextureSource
|
||||
path: "/Textures/Tiles/snow.png"
|
||||
slowness: 0
|
||||
scale: "1, 1"
|
||||
shader: ""
|
||||
BIN
Resources/Textures/Parallaxes/land.png
Normal file
BIN
Resources/Textures/Parallaxes/land.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 834 KiB |
4
Resources/Textures/Parallaxes/licences.txt
Normal file
4
Resources/Textures/Parallaxes/licences.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
land.png generated from https://cpetry.github.io/TextureGenerator-Online/
|
||||
Licensed under MIT at https://github.com/cpetry/TextureGenerator-Online/blob/gh-pages/LICENSE
|
||||
|
||||
noise.png generated from https://giggster.com/guide/cloud-texture-generator/
|
||||
BIN
Resources/Textures/Parallaxes/noise.png
Normal file
BIN
Resources/Textures/Parallaxes/noise.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 643 KiB |
Reference in New Issue
Block a user