Merge branch 'master' into 2020-04-28-tool-component
# Conflicts: # Content.Server/GameObjects/Components/AnchorableComponent.cs # Content.Server/GameObjects/Components/Gravity/GravityGeneratorComponent.cs # Content.Server/GameObjects/Components/Interactable/Tools/CrowbarComponent.cs # Content.Server/GameObjects/Components/Power/PowerTransferComponent.cs # Content.Server/GameObjects/Components/WiresComponent.cs # Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs # Resources/Prototypes/Entities/Items/tools.yml
This commit is contained in:
@@ -4,6 +4,7 @@ using Content.Shared.GameObjects.Components.Markers;
|
|||||||
using Robust.Client.Interfaces.Console;
|
using Robust.Client.Interfaces.Console;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
|
||||||
@@ -48,8 +49,7 @@ namespace Content.Client.Commands
|
|||||||
|
|
||||||
public bool Execute(IDebugConsole console, params string[] args)
|
public bool Execute(IDebugConsole console, params string[] args)
|
||||||
{
|
{
|
||||||
IoCManager.Resolve<IEntitySystemManager>()
|
EntitySystem.Get<SubFloorHideSystem>()
|
||||||
.GetEntitySystem<SubFloorHideSystem>()
|
|
||||||
.EnableAll ^= true;
|
.EnableAll ^= true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -148,6 +148,14 @@ namespace Content.Client
|
|||||||
"RandomPottedPlant",
|
"RandomPottedPlant",
|
||||||
"CommunicationsConsole",
|
"CommunicationsConsole",
|
||||||
"BarSign",
|
"BarSign",
|
||||||
|
"DroppedBodyPart",
|
||||||
|
"DroppedMechanism",
|
||||||
|
"BodyManager",
|
||||||
|
"Stunnable",
|
||||||
|
"SolarPanel",
|
||||||
|
"BodyScanner",
|
||||||
|
"Stunbaton",
|
||||||
|
"EmergencyClosetFill"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var ignoreName in registerIgnore)
|
foreach (var ignoreName in registerIgnore)
|
||||||
@@ -239,7 +247,6 @@ namespace Content.Client
|
|||||||
IoCManager.Resolve<IChatManager>().Initialize();
|
IoCManager.Resolve<IChatManager>().Initialize();
|
||||||
IoCManager.Resolve<ISandboxManager>().Initialize();
|
IoCManager.Resolve<ISandboxManager>().Initialize();
|
||||||
IoCManager.Resolve<IClientPreferencesManager>().Initialize();
|
IoCManager.Resolve<IClientPreferencesManager>().Initialize();
|
||||||
IoCManager.Resolve<IItemSlotManager>().Initialize();
|
|
||||||
|
|
||||||
_baseClient.RunLevelChanged += (sender, args) =>
|
_baseClient.RunLevelChanged += (sender, args) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Client.Animations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.GameObjects.Components.Animations;
|
||||||
|
using Robust.Shared.Animations;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class EmergencyLightComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "EmergencyLight";
|
||||||
|
|
||||||
|
protected override void Startup()
|
||||||
|
{
|
||||||
|
base.Startup();
|
||||||
|
|
||||||
|
var animation = new Animation
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromSeconds(4),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackComponentProperty
|
||||||
|
{
|
||||||
|
ComponentType = typeof(PointLightComponent),
|
||||||
|
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||||
|
Property = nameof(PointLightComponent.Rotation),
|
||||||
|
KeyFrames =
|
||||||
|
{
|
||||||
|
new AnimationTrackProperty.KeyFrame(Angle.Zero, 0),
|
||||||
|
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(1080), 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var playerComponent = Owner.EnsureComponent<AnimationPlayerComponent>();
|
||||||
|
playerComponent.Play(animation, "emergency");
|
||||||
|
|
||||||
|
playerComponent.AnimationCompleted += s => playerComponent.Play(animation, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Content.Shared.GameObjects.Components.Instruments;
|
using Content.Shared.GameObjects.Components.Instruments;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using NFluidsynth;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Client.Audio.Midi;
|
using Robust.Client.Audio.Midi;
|
||||||
using Robust.Shared.Audio.Midi;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
using Robust.Shared.Interfaces.Network;
|
||||||
using Robust.Shared.Interfaces.Timing;
|
using Robust.Shared.Interfaces.Timing;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Logger = Robust.Shared.Log.Logger;
|
||||||
|
using MidiEvent = Robust.Shared.Audio.Midi.MidiEvent;
|
||||||
using Timer = Robust.Shared.Timers.Timer;
|
using Timer = Robust.Shared.Timers.Timer;
|
||||||
|
|
||||||
|
|
||||||
@@ -20,6 +22,8 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class InstrumentComponent : SharedInstrumentComponent
|
public class InstrumentComponent : SharedInstrumentComponent
|
||||||
{
|
{
|
||||||
|
public const float TimeBetweenNetMessages = 1.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a midi song stops playing.
|
/// Called when a midi song stops playing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -27,17 +31,22 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
|
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private IMidiManager _midiManager;
|
[Dependency] private IMidiManager _midiManager;
|
||||||
[Dependency] private readonly IGameTiming _timing;
|
[Dependency] private readonly IGameTiming _gameTiming;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private IMidiRenderer _renderer;
|
private IMidiRenderer _renderer;
|
||||||
private int _instrumentProgram = 1;
|
private byte _instrumentProgram = 1;
|
||||||
|
private uint _syncSequencerTick;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A queue of MidiEvents to be sent to the server.
|
/// A queue of MidiEvents to be sent to the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Queue<MidiEvent> _eventQueue = new Queue<MidiEvent>();
|
[ViewVariables]
|
||||||
|
private readonly Queue<MidiEvent> _midiQueue = new Queue<MidiEvent>();
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private float _timer = 0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether a midi song will loop or not.
|
/// Whether a midi song will loop or not.
|
||||||
@@ -59,7 +68,7 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
/// Changes the instrument the midi renderer will play.
|
/// Changes the instrument the midi renderer will play.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public int InstrumentProgram
|
public byte InstrumentProgram
|
||||||
{
|
{
|
||||||
get => _instrumentProgram;
|
get => _instrumentProgram;
|
||||||
set
|
set
|
||||||
@@ -84,61 +93,102 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool IsInputOpen => _renderer?.Status == MidiRendererStatus.Input;
|
public bool IsInputOpen => _renderer?.Status == MidiRendererStatus.Input;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the midi renderer is alive or not.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public bool IsRendererAlive => _renderer != null;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SetupRenderer()
|
||||||
|
{
|
||||||
|
if (IsRendererAlive)
|
||||||
|
return;
|
||||||
|
|
||||||
_renderer = _midiManager.GetNewRenderer();
|
_renderer = _midiManager.GetNewRenderer();
|
||||||
|
|
||||||
if (_renderer != null)
|
if (_renderer != null)
|
||||||
{
|
{
|
||||||
_renderer.MidiProgram = _instrumentProgram;
|
_renderer.MidiProgram = _instrumentProgram;
|
||||||
_renderer.TrackingEntity = Owner;
|
_renderer.TrackingEntity = Owner;
|
||||||
_renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); };
|
_renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); EndRenderer(); SendNetworkMessage(new InstrumentStopMidiMessage()); };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void EndRenderer()
|
||||||
|
{
|
||||||
|
if (IsInputOpen)
|
||||||
|
CloseInput();
|
||||||
|
|
||||||
|
if (IsMidiOpen)
|
||||||
|
CloseMidi();
|
||||||
|
|
||||||
|
_renderer?.StopAllNotes();
|
||||||
|
|
||||||
|
var renderer = _renderer;
|
||||||
|
|
||||||
|
// We dispose of the synth two seconds from now to allow the last notes to stop from playing.
|
||||||
|
Timer.Spawn(2000, () => { renderer?.Dispose(); });
|
||||||
|
_renderer = null;
|
||||||
|
_midiQueue.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Shutdown()
|
protected override void Shutdown()
|
||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
_renderer?.Dispose();
|
EndRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
{
|
{
|
||||||
base.ExposeData(serializer);
|
base.ExposeData(serializer);
|
||||||
serializer.DataField(ref _instrumentProgram, "program", 1);
|
serializer.DataField(ref _instrumentProgram, "program", (byte)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
||||||
{
|
{
|
||||||
base.HandleNetworkMessage(message, channel, session);
|
base.HandleNetworkMessage(message, channel, session);
|
||||||
|
|
||||||
if (_renderer == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case InstrumentMidiEventMessage midiEventMessage:
|
case InstrumentMidiEventMessage midiEventMessage:
|
||||||
// If we're the ones sending the MidiEvents, we ignore this message.
|
// If we're the ones sending the MidiEvents, we ignore this message.
|
||||||
if (IsInputOpen || IsMidiOpen) break;
|
if (!IsRendererAlive || IsInputOpen || IsMidiOpen) break;
|
||||||
Timer.Spawn((int) (500 + _timing.CurTime.TotalMilliseconds - midiEventMessage.Timestamp),
|
for (var i = 0; i < midiEventMessage.MidiEvent.Length; i++)
|
||||||
() => _renderer.SendMidiEvent(midiEventMessage.MidiEvent));
|
{
|
||||||
break;
|
var ev = midiEventMessage.MidiEvent[i];
|
||||||
|
var delta = ((uint)TimeBetweenNetMessages*1250) + ev.Timestamp - _syncSequencerTick;
|
||||||
case InstrumentStopMidiMessage _:
|
_renderer?.ScheduleMidiEvent(ev, delta, true);
|
||||||
_renderer.StopAllNotes();
|
}
|
||||||
if (IsInputOpen) CloseInput();
|
|
||||||
if (IsMidiOpen) CloseMidi();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
|
||||||
|
{
|
||||||
|
base.HandleComponentState(curState, nextState);
|
||||||
|
if (!(curState is InstrumentState state)) return;
|
||||||
|
|
||||||
|
if (state.Playing)
|
||||||
|
{
|
||||||
|
SetupRenderer();
|
||||||
|
_syncSequencerTick = state.SequencerTick;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
EndRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="MidiRenderer.OpenInput"/>
|
/// <inheritdoc cref="MidiRenderer.OpenInput"/>
|
||||||
public bool OpenInput()
|
public bool OpenInput()
|
||||||
{
|
{
|
||||||
|
SetupRenderer();
|
||||||
|
SendNetworkMessage(new InstrumentStartMidiMessage());
|
||||||
|
|
||||||
if (_renderer != null && _renderer.OpenInput())
|
if (_renderer != null && _renderer.OpenInput())
|
||||||
{
|
{
|
||||||
_renderer.OnMidiEvent += RendererOnMidiEvent;
|
_renderer.OnMidiEvent += RendererOnMidiEvent;
|
||||||
@@ -156,13 +206,17 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.OnMidiEvent -= RendererOnMidiEvent;
|
EndRenderer();
|
||||||
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="MidiRenderer.OpenMidi(string)"/>
|
/// <inheritdoc cref="MidiRenderer.OpenMidi(string)"/>
|
||||||
public bool OpenMidi(string filename)
|
public bool OpenMidi(string filename)
|
||||||
{
|
{
|
||||||
|
SetupRenderer();
|
||||||
|
SendNetworkMessage(new InstrumentStartMidiMessage());
|
||||||
|
|
||||||
if (_renderer == null || !_renderer.OpenMidi(filename))
|
if (_renderer == null || !_renderer.OpenMidi(filename))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -180,7 +234,8 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.OnMidiEvent -= RendererOnMidiEvent;
|
EndRenderer();
|
||||||
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +245,29 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
/// <param name="midiEvent">The received midi event</param>
|
/// <param name="midiEvent">The received midi event</param>
|
||||||
private void RendererOnMidiEvent(MidiEvent midiEvent)
|
private void RendererOnMidiEvent(MidiEvent midiEvent)
|
||||||
{
|
{
|
||||||
SendNetworkMessage(new InstrumentMidiEventMessage(midiEvent, _timing.CurTime.TotalMilliseconds));
|
_midiQueue.Enqueue(midiEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float delta)
|
||||||
|
{
|
||||||
|
if (!IsMidiOpen && !IsInputOpen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_timer -= delta;
|
||||||
|
|
||||||
|
if (_timer > 0f) return;
|
||||||
|
|
||||||
|
SendAllMidiMessages();
|
||||||
|
_timer = TimeBetweenNetMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendAllMidiMessages()
|
||||||
|
{
|
||||||
|
if (_midiQueue.Count == 0) return;
|
||||||
|
var events = _midiQueue.ToArray();
|
||||||
|
_midiQueue.Clear();
|
||||||
|
|
||||||
|
SendNetworkMessage(new InstrumentMidiEventMessage(events));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,10 +137,11 @@ namespace Content.Client.GameObjects.Components.Kitchen
|
|||||||
{
|
{
|
||||||
Text = (index <= 0 ? 1 : index).ToString(),
|
Text = (index <= 0 ? 1 : index).ToString(),
|
||||||
TextAlign = Label.AlignMode.Center,
|
TextAlign = Label.AlignMode.Center,
|
||||||
|
ToggleMode = true,
|
||||||
Group = CookTimeButtonGroup,
|
Group = CookTimeButtonGroup,
|
||||||
};
|
};
|
||||||
CookTimeButtonVbox.AddChild(newButton);
|
CookTimeButtonVbox.AddChild(newButton);
|
||||||
newButton.OnPressed += args =>
|
newButton.OnToggled += args =>
|
||||||
{
|
{
|
||||||
OnCookTimeSelected?.Invoke(args);
|
OnCookTimeSelected?.Invoke(args);
|
||||||
_cookTimeInfoLabel.Text = $"{Loc.GetString("COOK TIME")}: {VisualCookTime}";
|
_cookTimeInfoLabel.Text = $"{Loc.GetString("COOK TIME")}: {VisualCookTime}";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Shared.GameObjects.Components.Mobs;
|
using Content.Shared.GameObjects.Components.Mobs;
|
||||||
using Microsoft.CodeAnalysis.Completion;
|
|
||||||
using Robust.Client.Animations;
|
using Robust.Client.Animations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.GameObjects.Components.Animations;
|
using Robust.Client.GameObjects.Components.Animations;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
|||||||
using Content.Shared.GameObjects.Components.Sound;
|
using Content.Shared.GameObjects.Components.Sound;
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
using Robust.Client.GameObjects.EntitySystems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using Robust.Shared.Interfaces.Network;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
@@ -9,6 +10,7 @@ using Robust.Shared.IoC;
|
|||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Timers;
|
using Robust.Shared.Timers;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Sound
|
namespace Content.Client.GameObjects.Components.Sound
|
||||||
{
|
{
|
||||||
@@ -54,7 +56,7 @@ namespace Content.Client.GameObjects.Components.Sound
|
|||||||
Timer.Spawn((int) schedule.Delay + (_random.Next((int) schedule.RandomDelay)),() =>
|
Timer.Spawn((int) schedule.Delay + (_random.Next((int) schedule.RandomDelay)),() =>
|
||||||
{
|
{
|
||||||
if (!schedule.Play) return; // We make sure this hasn't changed.
|
if (!schedule.Play) return; // We make sure this hasn't changed.
|
||||||
if (_audioSystem == null) _audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
if (_audioSystem == null) _audioSystem = EntitySystem.Get<AudioSystem>();
|
||||||
_audioStreams.Add(schedule,_audioSystem.Play(schedule.Filename, Owner, schedule.AudioParams));
|
_audioStreams.Add(schedule,_audioSystem.Play(schedule.Filename, Owner, schedule.AudioParams));
|
||||||
|
|
||||||
if (schedule.Times == 0) return;
|
if (schedule.Times == 0) return;
|
||||||
@@ -87,7 +89,7 @@ namespace Content.Client.GameObjects.Components.Sound
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
IoCManager.Resolve<IEntitySystemManager>().TryGetEntitySystem(out _audioSystem);
|
EntitySystem.TryGet(out _audioSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using YamlDotNet.RepresentationModel;
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
@@ -8,6 +9,7 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
{
|
{
|
||||||
public sealed class StorageVisualizer2D : AppearanceVisualizer
|
public sealed class StorageVisualizer2D : AppearanceVisualizer
|
||||||
{
|
{
|
||||||
|
private string _stateBase;
|
||||||
private string _stateOpen;
|
private string _stateOpen;
|
||||||
private string _stateClosed;
|
private string _stateClosed;
|
||||||
|
|
||||||
@@ -15,7 +17,12 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
{
|
{
|
||||||
base.LoadData(node);
|
base.LoadData(node);
|
||||||
|
|
||||||
if (node.TryGetNode("state_open", out var child))
|
if (node.TryGetNode("state", out var child))
|
||||||
|
{
|
||||||
|
_stateBase = child.AsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.TryGetNode("state_open", out child))
|
||||||
{
|
{
|
||||||
_stateOpen = child.AsString();
|
_stateOpen = child.AsString();
|
||||||
}
|
}
|
||||||
@@ -26,6 +33,19 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void InitializeEntity(IEntity entity)
|
||||||
|
{
|
||||||
|
if (!entity.TryGetComponent(out ISpriteComponent sprite))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_stateBase != null)
|
||||||
|
{
|
||||||
|
sprite.LayerSetState(0, _stateBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
public override void OnChangeData(AppearanceComponent component)
|
||||||
{
|
{
|
||||||
base.OnChangeData(component);
|
base.OnChangeData(component);
|
||||||
@@ -36,7 +56,9 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
}
|
}
|
||||||
|
|
||||||
component.TryGetData(StorageVisuals.Open, out bool open);
|
component.TryGetData(StorageVisuals.Open, out bool open);
|
||||||
sprite.LayerSetState(StorageVisualLayers.Door, open ? _stateOpen : _stateClosed);
|
sprite.LayerSetState(StorageVisualLayers.Door, open
|
||||||
|
? _stateOpen ?? $"{_stateBase}_open"
|
||||||
|
: _stateClosed ?? $"{_stateBase}_door");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
25
Content.Client/GameObjects/EntitySystems/InstrumentSystem.cs
Normal file
25
Content.Client/GameObjects/EntitySystems/InstrumentSystem.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using Content.Client.GameObjects.Components.Instruments;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.EntitySystems
|
||||||
|
{
|
||||||
|
public class InstrumentSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
EntityQuery = new TypeEntityQuery(typeof(InstrumentComponent));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
foreach (var entity in RelevantEntities)
|
||||||
|
{
|
||||||
|
entity.GetComponent<InstrumentComponent>().Update(frameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,37 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
using Content.Client.State;
|
using Content.Client.State;
|
||||||
|
using Content.Client.UserInterface;
|
||||||
|
using Content.Client.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.EntitySystemMessages;
|
using Content.Shared.GameObjects.EntitySystemMessages;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
using Robust.Client.GameObjects.EntitySystems;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Graphics.Drawing;
|
||||||
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
using Robust.Client.Interfaces.Input;
|
using Robust.Client.Interfaces.Input;
|
||||||
|
using Robust.Client.Interfaces.ResourceManagement;
|
||||||
using Robust.Client.Interfaces.State;
|
using Robust.Client.Interfaces.State;
|
||||||
|
using Robust.Client.Interfaces.UserInterface;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
using Robust.Client.Utility;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Input;
|
using Robust.Shared.Input;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Timing;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
using Timer = Robust.Shared.Timers.Timer;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
namespace Content.Client.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -31,11 +43,21 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
[Dependency] private readonly IEntityManager _entityManager;
|
[Dependency] private readonly IEntityManager _entityManager;
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
[Dependency] private readonly IPlayerManager _playerManager;
|
||||||
[Dependency] private readonly IInputManager _inputManager;
|
[Dependency] private readonly IInputManager _inputManager;
|
||||||
|
[Dependency] private readonly IItemSlotManager _itemSlotManager;
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming;
|
||||||
|
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager;
|
||||||
|
[Dependency] private readonly IResourceCache _resourceCache;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
private VerbPopup _currentPopup;
|
private EntityList _currentEntityList;
|
||||||
|
private VerbPopup _currentVerbListRoot;
|
||||||
|
private VerbPopup _currentGroupList;
|
||||||
|
|
||||||
private EntityUid _currentEntity;
|
private EntityUid _currentEntity;
|
||||||
|
|
||||||
|
private bool IsAnyContextMenuOpen => _currentEntityList != null || _currentVerbListRoot != null;
|
||||||
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -51,29 +73,28 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
|
|
||||||
public void OpenContextMenu(IEntity entity, ScreenCoordinates screenCoordinates)
|
public void OpenContextMenu(IEntity entity, ScreenCoordinates screenCoordinates)
|
||||||
{
|
{
|
||||||
if (_currentPopup != null)
|
if (_currentVerbListRoot != null)
|
||||||
{
|
{
|
||||||
CloseContextMenu();
|
CloseVerbMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentEntity = entity.Uid;
|
_currentEntity = entity.Uid;
|
||||||
_currentPopup = new VerbPopup();
|
_currentVerbListRoot = new VerbPopup();
|
||||||
_currentPopup.UserInterfaceManager.ModalRoot.AddChild(_currentPopup);
|
_userInterfaceManager.ModalRoot.AddChild(_currentVerbListRoot);
|
||||||
_currentPopup.OnPopupHide += CloseContextMenu;
|
_currentVerbListRoot.OnPopupHide += CloseVerbMenu;
|
||||||
|
|
||||||
_currentPopup.List.AddChild(new Label {Text = "Waiting on Server..."});
|
_currentVerbListRoot.List.AddChild(new Label {Text = "Waiting on Server..."});
|
||||||
RaiseNetworkEvent(new VerbSystemMessages.RequestVerbsMessage(_currentEntity));
|
RaiseNetworkEvent(new VerbSystemMessages.RequestVerbsMessage(_currentEntity));
|
||||||
|
|
||||||
var size = _currentPopup.List.CombinedMinimumSize;
|
var box = UIBox2.FromDimensions(screenCoordinates.Position, (1, 1));
|
||||||
var box = UIBox2.FromDimensions(screenCoordinates.Position, size);
|
_currentVerbListRoot.Open(box);
|
||||||
_currentPopup.Open(box);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool OnOpenContextMenu(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
private bool OnOpenContextMenu(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
||||||
{
|
{
|
||||||
if (_currentPopup != null)
|
if (IsAnyContextMenuOpen)
|
||||||
{
|
{
|
||||||
CloseContextMenu();
|
CloseAllMenus();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,20 +110,29 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentPopup = new VerbPopup();
|
_currentEntityList = new EntityList();
|
||||||
_currentPopup.OnPopupHide += CloseContextMenu;
|
_currentEntityList.OnPopupHide += CloseAllMenus;
|
||||||
foreach (var entity in entities)
|
for (var i = 0; i < entities.Count; i++)
|
||||||
{
|
{
|
||||||
var button = new Button {Text = entity.Name};
|
if (i != 0)
|
||||||
_currentPopup.List.AddChild(button);
|
{
|
||||||
button.OnPressed += _ => OnContextButtonPressed(entity);
|
_currentEntityList.List.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (0, 2),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#333")}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var entity = entities[i];
|
||||||
|
|
||||||
|
_currentEntityList.List.AddChild(new EntityButton(this, entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentPopup.UserInterfaceManager.ModalRoot.AddChild(_currentPopup);
|
_userInterfaceManager.ModalRoot.AddChild(_currentEntityList);
|
||||||
|
|
||||||
var size = _currentPopup.List.CombinedMinimumSize;
|
var size = _currentEntityList.List.CombinedMinimumSize;
|
||||||
var box = UIBox2.FromDimensions(args.ScreenCoordinates.Position, size);
|
var box = UIBox2.FromDimensions(args.ScreenCoordinates.Position, size);
|
||||||
_currentPopup.Open(box);
|
_currentEntityList.Open(box);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -119,28 +149,31 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugTools.AssertNotNull(_currentPopup);
|
DebugTools.AssertNotNull(_currentVerbListRoot);
|
||||||
|
|
||||||
var buttons = new Dictionary<string, List<Button>>();
|
var buttons = new Dictionary<string, List<ListedVerbData>>();
|
||||||
|
var groupIcons = new Dictionary<string, SpriteSpecifier>();
|
||||||
|
|
||||||
var vBox = _currentPopup.List;
|
var vBox = _currentVerbListRoot.List;
|
||||||
vBox.DisposeAllChildren();
|
vBox.DisposeAllChildren();
|
||||||
|
|
||||||
|
// Local variable so that scope capture ensures this is the correct value.
|
||||||
|
var curEntity = _currentEntity;
|
||||||
|
|
||||||
foreach (var data in msg.Verbs)
|
foreach (var data in msg.Verbs)
|
||||||
{
|
{
|
||||||
var button = new Button {Text = data.Text, Disabled = !data.Available};
|
var list = buttons.GetOrNew(data.Category);
|
||||||
if (data.Available)
|
|
||||||
|
if (data.CategoryIcon != null && !groupIcons.ContainsKey(data.Category))
|
||||||
{
|
{
|
||||||
button.OnPressed += _ =>
|
groupIcons.Add(data.Category, data.CategoryIcon);
|
||||||
{
|
|
||||||
RaiseNetworkEvent(new VerbSystemMessages.UseVerbMessage(_currentEntity, data.Key));
|
|
||||||
CloseContextMenu();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!buttons.ContainsKey(data.Category))
|
list.Add(new ListedVerbData(data.Text, !data.Available, data.Key, entity.ToString(), () =>
|
||||||
buttons[data.Category] = new List<Button>();
|
{
|
||||||
|
RaiseNetworkEvent(new VerbSystemMessages.UseVerbMessage(curEntity, data.Key));
|
||||||
buttons[data.Category].Add(button);
|
CloseAllMenus();
|
||||||
|
}, data.Icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = GetUserEntity();
|
var user = GetUserEntity();
|
||||||
@@ -150,55 +183,87 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(user, entity))
|
if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(user, entity))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (VerbUtility.IsVerbInvisible(verb, user, component, out var vis))
|
var verbData = verb.GetData(user, component);
|
||||||
|
|
||||||
|
if (verbData.IsInvisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var disabled = vis != VerbVisibility.Visible;
|
var list = buttons.GetOrNew(verbData.Category);
|
||||||
var category = verb.GetCategory(user, component);
|
|
||||||
|
|
||||||
|
if (verbData.CategoryIcon != null && !groupIcons.ContainsKey(verbData.Category))
|
||||||
|
{
|
||||||
|
groupIcons.Add(verbData.Category, verbData.CategoryIcon);
|
||||||
|
}
|
||||||
|
|
||||||
if(!buttons.ContainsKey(category))
|
list.Add(new ListedVerbData(verbData.Text, verbData.IsDisabled, verb.ToString(), entity.ToString(),
|
||||||
buttons[category] = new List<Button>();
|
() => verb.Activate(user, component), verbData.Icon));
|
||||||
|
|
||||||
buttons[category].Add(CreateVerbButton(verb.GetText(user, component), disabled, verb.ToString(),
|
|
||||||
entity.ToString(), () => verb.Activate(user, component)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get global verbs. Visible for all entities regardless of their components.
|
//Get global verbs. Visible for all entities regardless of their components.
|
||||||
foreach (var globalVerb in VerbUtility.GetGlobalVerbs(Assembly.GetExecutingAssembly()))
|
foreach (var globalVerb in VerbUtility.GetGlobalVerbs(Assembly.GetExecutingAssembly()))
|
||||||
{
|
{
|
||||||
if (globalVerb.RequireInteractionRange && !VerbUtility.InVerbUseRange(user, entity))
|
if (globalVerb.RequireInteractionRange && !VerbUtility.InVerbUseRange(user, entity))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (VerbUtility.IsVerbInvisible(globalVerb, user, entity, out var vis))
|
var verbData = globalVerb.GetData(user, entity);
|
||||||
|
|
||||||
|
if (verbData.IsInvisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var disabled = vis != VerbVisibility.Visible;
|
var list = buttons.GetOrNew(verbData.Category);
|
||||||
var category = globalVerb.GetCategory(user, entity);
|
|
||||||
|
|
||||||
if(!buttons.ContainsKey(category))
|
if (verbData.CategoryIcon != null && !groupIcons.ContainsKey(verbData.Category))
|
||||||
buttons[category] = new List<Button>();
|
{
|
||||||
|
groupIcons.Add(verbData.Category, verbData.CategoryIcon);
|
||||||
|
}
|
||||||
|
|
||||||
buttons[category].Add(CreateVerbButton(globalVerb.GetText(user, entity), disabled, globalVerb.ToString(),
|
list.Add(new ListedVerbData(verbData.Text, verbData.IsDisabled, globalVerb.ToString(),
|
||||||
entity.ToString(), () => globalVerb.Activate(user, entity)));
|
entity.ToString(),
|
||||||
|
() => globalVerb.Activate(user, entity), verbData.Icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buttons.Count > 0)
|
if (buttons.Count > 0)
|
||||||
{
|
{
|
||||||
|
var first = true;
|
||||||
foreach (var (category, verbs) in buttons)
|
foreach (var (category, verbs) in buttons)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(category))
|
if (string.IsNullOrEmpty(category))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vBox.AddChild(CreateCategoryButton(category, verbs));
|
if (!first)
|
||||||
|
{
|
||||||
|
vBox.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (0, 2),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#333")}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
groupIcons.TryGetValue(category, out var icon);
|
||||||
|
|
||||||
|
vBox.AddChild(CreateCategoryButton(category, verbs, icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buttons.ContainsKey(""))
|
if (buttons.ContainsKey(""))
|
||||||
{
|
{
|
||||||
buttons[""].Sort((a, b) => string.Compare(a.Text, b.Text, StringComparison.Ordinal));
|
buttons[""].Sort((a, b) => string.Compare(a.Text, b.Text, StringComparison.CurrentCulture));
|
||||||
|
|
||||||
foreach (var verb in buttons[""])
|
foreach (var verb in buttons[""])
|
||||||
{
|
{
|
||||||
vBox.AddChild(verb);
|
if (!first)
|
||||||
|
{
|
||||||
|
vBox.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (0, 2),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#333")}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
vBox.AddChild(CreateVerbButton(verb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,69 +275,364 @@ namespace Content.Client.GameObjects.EntitySystems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button CreateVerbButton(string text, bool disabled, string verbName, string ownerName, Action action)
|
private VerbButton CreateVerbButton(ListedVerbData data)
|
||||||
{
|
{
|
||||||
var button = new Button
|
var button = new VerbButton
|
||||||
{
|
{
|
||||||
Text = text,
|
Text = data.Text,
|
||||||
Disabled = disabled
|
Disabled = data.Disabled
|
||||||
};
|
};
|
||||||
if (!disabled)
|
|
||||||
|
if (data.Icon != null)
|
||||||
|
{
|
||||||
|
button.Icon = data.Icon.Frame0();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.Disabled)
|
||||||
{
|
{
|
||||||
button.OnPressed += _ =>
|
button.OnPressed += _ =>
|
||||||
{
|
{
|
||||||
CloseContextMenu();
|
CloseAllMenus();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
action.Invoke();
|
data.Action.Invoke();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.ErrorS("verb", "Exception in verb {0} on {1}:\n{2}", verbName, ownerName, e);
|
Logger.ErrorS("verb", "Exception in verb {0} on {1}:\n{2}", data.VerbName, data.OwnerName, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button CreateCategoryButton(string text, List<Button> verbButtons)
|
private Control CreateCategoryButton(string text, List<ListedVerbData> verbButtons, SpriteSpecifier icon)
|
||||||
{
|
{
|
||||||
verbButtons.Sort((a, b) => string.Compare(a.Text, b.Text, StringComparison.Ordinal));
|
verbButtons.Sort((a, b) => string.Compare(a.Text, b.Text, StringComparison.CurrentCulture));
|
||||||
|
|
||||||
var button = new Button
|
return new VerbGroupButton(this, verbButtons, icon)
|
||||||
{
|
{
|
||||||
Text = $"{text}...",
|
Text = text,
|
||||||
};
|
};
|
||||||
button.OnPressed += _ =>
|
|
||||||
{
|
|
||||||
_currentPopup.List.DisposeAllChildren();
|
|
||||||
foreach (var verb in verbButtons)
|
|
||||||
{
|
|
||||||
_currentPopup.List.AddChild(verb);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return button;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseContextMenu()
|
private void CloseVerbMenu()
|
||||||
{
|
{
|
||||||
_currentPopup?.Dispose();
|
_currentVerbListRoot?.Dispose();
|
||||||
_currentPopup = null;
|
_currentVerbListRoot = null;
|
||||||
_currentEntity = EntityUid.Invalid;
|
_currentEntity = EntityUid.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CloseEntityList()
|
||||||
|
{
|
||||||
|
_currentEntityList?.Dispose();
|
||||||
|
_currentEntityList = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseAllMenus()
|
||||||
|
{
|
||||||
|
CloseVerbMenu();
|
||||||
|
CloseEntityList();
|
||||||
|
CloseGroupMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseGroupMenu()
|
||||||
|
{
|
||||||
|
_currentGroupList?.Dispose();
|
||||||
|
_currentGroupList = null;
|
||||||
|
}
|
||||||
|
|
||||||
private IEntity GetUserEntity()
|
private IEntity GetUserEntity()
|
||||||
{
|
{
|
||||||
return _playerManager.LocalPlayer.ControlledEntity;
|
return _playerManager.LocalPlayer.ControlledEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class EntityList : Popup
|
||||||
|
{
|
||||||
|
public VBoxContainer List { get; }
|
||||||
|
|
||||||
|
public EntityList()
|
||||||
|
{
|
||||||
|
AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
Children = {(List = new VBoxContainer())},
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#111E")}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class VerbPopup : Popup
|
private sealed class VerbPopup : Popup
|
||||||
{
|
{
|
||||||
public VBoxContainer List { get; }
|
public VBoxContainer List { get; }
|
||||||
|
|
||||||
public VerbPopup()
|
public VerbPopup()
|
||||||
{
|
{
|
||||||
AddChild(List = new VBoxContainer());
|
AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
Children = {(List = new VBoxContainer())},
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#111E")}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class EntityButton : Control
|
||||||
|
{
|
||||||
|
private readonly VerbSystem _master;
|
||||||
|
private readonly IEntity _entity;
|
||||||
|
|
||||||
|
public EntityButton(VerbSystem master, IEntity entity)
|
||||||
|
{
|
||||||
|
_master = master;
|
||||||
|
_entity = entity;
|
||||||
|
|
||||||
|
MouseFilter = MouseFilterMode.Stop;
|
||||||
|
|
||||||
|
var control = new HBoxContainer {SeparationOverride = 6};
|
||||||
|
if (entity.TryGetComponent(out ISpriteComponent sprite))
|
||||||
|
{
|
||||||
|
control.AddChild(new SpriteView {Sprite = sprite});
|
||||||
|
}
|
||||||
|
|
||||||
|
control.AddChild(new MarginContainer
|
||||||
|
{
|
||||||
|
MarginLeftOverride = 4,
|
||||||
|
MarginRightOverride = 4,
|
||||||
|
Children = {new Label {Text = entity.Name}}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddChild(control);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
base.KeyBindDown(args);
|
||||||
|
|
||||||
|
if (args.Function == ContentKeyFunctions.OpenContextMenu)
|
||||||
|
{
|
||||||
|
_master.OnContextButtonPressed(_entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Function == EngineKeyFunctions.Use)
|
||||||
|
{
|
||||||
|
var inputSys = _master.EntitySystemManager.GetEntitySystem<InputSystem>();
|
||||||
|
|
||||||
|
var func = args.Function;
|
||||||
|
var funcId = _master._inputManager.NetworkBindMap.KeyFunctionID(args.Function);
|
||||||
|
|
||||||
|
var message = new FullInputCmdMessage(_master._gameTiming.CurTick, funcId, BoundKeyState.Down,
|
||||||
|
_entity.Transform.GridPosition,
|
||||||
|
args.PointerLocation, _entity.Uid);
|
||||||
|
|
||||||
|
// client side command handlers will always be sent the local player session.
|
||||||
|
var session = _master._playerManager.LocalPlayer.Session;
|
||||||
|
inputSys.HandleInputCommand(session, func, message);
|
||||||
|
|
||||||
|
_master.CloseAllMenus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_master._itemSlotManager.OnButtonPressed(args, _entity))
|
||||||
|
{
|
||||||
|
_master.CloseAllMenus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
base.Draw(handle);
|
||||||
|
|
||||||
|
if (UserInterfaceManager.CurrentlyHovered == this)
|
||||||
|
{
|
||||||
|
handle.DrawRect(PixelSizeBox, Color.DarkSlateGray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class VerbButton : BaseButton
|
||||||
|
{
|
||||||
|
private readonly Label _label;
|
||||||
|
private readonly TextureRect _icon;
|
||||||
|
|
||||||
|
public Texture Icon
|
||||||
|
{
|
||||||
|
get => _icon.Texture;
|
||||||
|
set => _icon.Texture = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => _label.Text;
|
||||||
|
set => _label.Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VerbButton()
|
||||||
|
{
|
||||||
|
AddChild(new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_icon = new TextureRect
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (32, 32),
|
||||||
|
Stretch = TextureRect.StretchMode.KeepCentered
|
||||||
|
}),
|
||||||
|
(_label = new Label()),
|
||||||
|
// Padding
|
||||||
|
new Control {CustomMinimumSize = (8, 0)}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
base.Draw(handle);
|
||||||
|
|
||||||
|
if (DrawMode == DrawModeEnum.Hover)
|
||||||
|
{
|
||||||
|
handle.DrawRect(PixelSizeBox, Color.DarkSlateGray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class VerbGroupButton : Control
|
||||||
|
{
|
||||||
|
private static readonly TimeSpan HoverDelay = TimeSpan.FromSeconds(0.2);
|
||||||
|
|
||||||
|
private readonly VerbSystem _system;
|
||||||
|
public List<ListedVerbData> VerbButtons { get; }
|
||||||
|
private readonly Label _label;
|
||||||
|
private readonly TextureRect _icon;
|
||||||
|
|
||||||
|
private CancellationTokenSource _openCancel;
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => _label.Text;
|
||||||
|
set => _label.Text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture Icon
|
||||||
|
{
|
||||||
|
get => _icon.Texture;
|
||||||
|
set => _icon.Texture = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VerbGroupButton(VerbSystem system, List<ListedVerbData> verbButtons, SpriteSpecifier icon)
|
||||||
|
{
|
||||||
|
_system = system;
|
||||||
|
VerbButtons = verbButtons;
|
||||||
|
|
||||||
|
MouseFilter = MouseFilterMode.Stop;
|
||||||
|
|
||||||
|
AddChild(new HBoxContainer
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
(_icon = new TextureRect
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (32, 32),
|
||||||
|
Stretch = TextureRect.StretchMode.KeepCentered
|
||||||
|
}),
|
||||||
|
|
||||||
|
(_label = new Label
|
||||||
|
{
|
||||||
|
SizeFlagsHorizontal = SizeFlags.FillExpand
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Padding
|
||||||
|
new Control {CustomMinimumSize = (8, 0)},
|
||||||
|
|
||||||
|
new TextureRect
|
||||||
|
{
|
||||||
|
Texture = IoCManager.Resolve<IResourceCache>()
|
||||||
|
.GetTexture("/Textures/UserInterface/VerbIcons/group.svg.96dpi.png"),
|
||||||
|
Stretch = TextureRect.StretchMode.KeepCentered,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (icon != null)
|
||||||
|
{
|
||||||
|
_icon.Texture = icon.Frame0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
base.Draw(handle);
|
||||||
|
|
||||||
|
if (this == UserInterfaceManager.CurrentlyHovered)
|
||||||
|
{
|
||||||
|
handle.DrawRect(PixelSizeBox, Color.DarkSlateGray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void MouseEntered()
|
||||||
|
{
|
||||||
|
base.MouseEntered();
|
||||||
|
|
||||||
|
_openCancel = new CancellationTokenSource();
|
||||||
|
|
||||||
|
Timer.Spawn(HoverDelay, () =>
|
||||||
|
{
|
||||||
|
if (_system._currentGroupList != null)
|
||||||
|
{
|
||||||
|
_system.CloseGroupMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
var popup = _system._currentGroupList = new VerbPopup();
|
||||||
|
|
||||||
|
var first = true;
|
||||||
|
foreach (var verb in VerbButtons)
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
{
|
||||||
|
popup.List.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
CustomMinimumSize = (0, 2),
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#333")}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
popup.List.AddChild(_system.CreateVerbButton(verb));
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInterfaceManager.ModalRoot.AddChild(popup);
|
||||||
|
popup.Open(UIBox2.FromDimensions(GlobalPosition + (Width, 0), (1, 1)), GlobalPosition);
|
||||||
|
}, _openCancel.Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void MouseExited()
|
||||||
|
{
|
||||||
|
base.MouseExited();
|
||||||
|
|
||||||
|
_openCancel?.Cancel();
|
||||||
|
_openCancel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class ListedVerbData
|
||||||
|
{
|
||||||
|
public string Text { get; }
|
||||||
|
public bool Disabled { get; }
|
||||||
|
public string VerbName { get; }
|
||||||
|
public string OwnerName { get; }
|
||||||
|
public SpriteSpecifier Icon { get; }
|
||||||
|
public Action Action { get; }
|
||||||
|
|
||||||
|
public ListedVerbData(string text, bool disabled, string verbName, string ownerName,
|
||||||
|
Action action, SpriteSpecifier icon)
|
||||||
|
{
|
||||||
|
Text = text;
|
||||||
|
Disabled = disabled;
|
||||||
|
VerbName = verbName;
|
||||||
|
OwnerName = ownerName;
|
||||||
|
Action = action;
|
||||||
|
Icon = icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,17 +12,19 @@ namespace Content.Client.GlobalVerbs
|
|||||||
[GlobalVerb]
|
[GlobalVerb]
|
||||||
class ViewVariablesVerb : GlobalVerb
|
class ViewVariablesVerb : GlobalVerb
|
||||||
{
|
{
|
||||||
public override string GetText(IEntity user, IEntity target) => "View variables";
|
|
||||||
public override string GetCategory(IEntity user, IEntity target) => "Debug";
|
|
||||||
|
|
||||||
public override bool RequireInteractionRange => false;
|
public override bool RequireInteractionRange => false;
|
||||||
|
|
||||||
public override VerbVisibility GetVisibility(IEntity user, IEntity target)
|
public override void GetData(IEntity user, IEntity target, VerbData data)
|
||||||
{
|
{
|
||||||
var groupController = IoCManager.Resolve<IClientConGroupController>();
|
var groupController = IoCManager.Resolve<IClientConGroupController>();
|
||||||
if (groupController.CanViewVar())
|
if (!groupController.CanViewVar())
|
||||||
return VerbVisibility.Visible;
|
{
|
||||||
return VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.Text = "View Variables";
|
||||||
|
data.CategoryData = VerbCategories.Debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Activate(IEntity user, IEntity target)
|
public override void Activate(IEntity user, IEntity target)
|
||||||
|
|||||||
33
Content.Client/UserInterface/CooldownGraphic.cs
Normal file
33
Content.Client/UserInterface/CooldownGraphic.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Robust.Client.Graphics.Drawing;
|
||||||
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Client.Interfaces.Graphics;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Robust.Client.UserInterface.Controls
|
||||||
|
{
|
||||||
|
public class CooldownGraphic : Control
|
||||||
|
{
|
||||||
|
public float Fraction { get; set; }
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
const int maxSegments = 64;
|
||||||
|
const float segment = MathHelper.TwoPi / maxSegments;
|
||||||
|
|
||||||
|
var segments = (int)Math.Max(2, Math.Ceiling(maxSegments * Fraction)); // ensure that we always have 3 vertices
|
||||||
|
var max = MathHelper.TwoPi * Fraction;
|
||||||
|
var radius = (Math.Min(SizeBox.Height, SizeBox.Width) / 2) * 0.875f; // 28/32 = 0.875 - 2 pixels inwards from the edge
|
||||||
|
|
||||||
|
Span<Vector2> vertices = stackalloc Vector2[segments + 1];
|
||||||
|
vertices[0] = PixelPosition + SizeBox.Center;
|
||||||
|
for (int i = 0; i < segments; i++)
|
||||||
|
{
|
||||||
|
var angle = MathHelper.Pi + Math.Min(max, segment * i);
|
||||||
|
vertices[i + 1] = vertices[0] + new Vector2((float) Math.Sin(angle) * radius, (float) Math.Cos(angle) * radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, vertices, new Color(0.3f, 0.3f, 0.4f, 0.5f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ namespace Content.Client.UserInterface
|
|||||||
{
|
{
|
||||||
public interface IItemSlotManager
|
public interface IItemSlotManager
|
||||||
{
|
{
|
||||||
void Initialize();
|
|
||||||
bool OnButtonPressed(GUIBoundKeyEventArgs args, IEntity item);
|
bool OnButtonPressed(GUIBoundKeyEventArgs args, IEntity item);
|
||||||
void UpdateCooldown(ItemSlotButton cooldownTexture, IEntity entity);
|
void UpdateCooldown(ItemSlotButton cooldownTexture, IEntity entity);
|
||||||
bool SetItemSlot(ItemSlotButton button, IEntity entity);
|
bool SetItemSlot(ItemSlotButton button, IEntity entity);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Client.UserInterface;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
@@ -13,7 +14,7 @@ namespace Content.Client.GameObjects
|
|||||||
public TextureRect Button { get; }
|
public TextureRect Button { get; }
|
||||||
public SpriteView SpriteView { get; }
|
public SpriteView SpriteView { get; }
|
||||||
public BaseButton StorageButton { get; }
|
public BaseButton StorageButton { get; }
|
||||||
public TextureRect CooldownCircle { get; }
|
public CooldownGraphic CooldownDisplay { get; }
|
||||||
|
|
||||||
public Action<GUIBoundKeyEventArgs> OnPressed { get; set; }
|
public Action<GUIBoundKeyEventArgs> OnPressed { get; set; }
|
||||||
public Action<GUIBoundKeyEventArgs> OnStoragePressed { get; set; }
|
public Action<GUIBoundKeyEventArgs> OnStoragePressed { get; set; }
|
||||||
@@ -56,12 +57,10 @@ namespace Content.Client.GameObjects
|
|||||||
|
|
||||||
StorageButton.OnPressed += OnStorageButtonPressed;
|
StorageButton.OnPressed += OnStorageButtonPressed;
|
||||||
|
|
||||||
AddChild(CooldownCircle = new TextureRect
|
AddChild(CooldownDisplay = new CooldownGraphic
|
||||||
{
|
{
|
||||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
SizeFlagsHorizontal = SizeFlags.Fill,
|
||||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
SizeFlagsVertical = SizeFlags.Fill,
|
||||||
Stretch = TextureRect.StretchMode.KeepCentered,
|
|
||||||
TextureScale = (2, 2),
|
|
||||||
Visible = false,
|
Visible = false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,22 +30,8 @@ namespace Content.Client.UserInterface
|
|||||||
[Dependency] private readonly IInputManager _inputManager;
|
[Dependency] private readonly IInputManager _inputManager;
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
||||||
[Dependency] private readonly IEyeManager _eyeManager;
|
[Dependency] private readonly IEyeManager _eyeManager;
|
||||||
[Dependency] private readonly IResourceCache _resourceCache;
|
|
||||||
#pragma warning restore 0649
|
#pragma warning restore 0649
|
||||||
|
|
||||||
private const int CooldownLevels = 8;
|
|
||||||
|
|
||||||
private readonly Texture[] _texturesCooldownOverlay = new Texture[CooldownLevels];
|
|
||||||
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
for (var i = 0; i < CooldownLevels; i++)
|
|
||||||
{
|
|
||||||
_texturesCooldownOverlay[i] =
|
|
||||||
_resourceCache.GetTexture($"/Textures/UserInterface/Inventory/cooldown-{i}.png");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SetItemSlot(ItemSlotButton button, IEntity entity)
|
public bool SetItemSlot(ItemSlotButton button, IEntity entity)
|
||||||
{
|
{
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
@@ -103,7 +89,7 @@ namespace Content.Client.UserInterface
|
|||||||
|
|
||||||
public void UpdateCooldown(ItemSlotButton button, IEntity entity)
|
public void UpdateCooldown(ItemSlotButton button, IEntity entity)
|
||||||
{
|
{
|
||||||
var cooldownTexture = button.CooldownCircle;
|
var cooldownDisplay = button.CooldownDisplay;
|
||||||
|
|
||||||
if (entity != null
|
if (entity != null
|
||||||
&& entity.TryGetComponent(out ItemCooldownComponent cooldown)
|
&& entity.TryGetComponent(out ItemCooldownComponent cooldown)
|
||||||
@@ -115,30 +101,23 @@ namespace Content.Client.UserInterface
|
|||||||
|
|
||||||
var length = (end - start).TotalSeconds;
|
var length = (end - start).TotalSeconds;
|
||||||
var progress = (_gameTiming.CurTime - start).TotalSeconds;
|
var progress = (_gameTiming.CurTime - start).TotalSeconds;
|
||||||
var ratio = (float)(progress / length);
|
var ratio = 1 - (float)(progress / length).Clamp(0, 1);
|
||||||
|
|
||||||
var textureIndex = CalculateCooldownLevel(ratio);
|
cooldownDisplay.Fraction = ratio;
|
||||||
if (textureIndex == CooldownLevels)
|
|
||||||
|
if (ratio > 0)
|
||||||
{
|
{
|
||||||
cooldownTexture.Visible = false;
|
cooldownDisplay.Visible = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cooldownTexture.Visible = true;
|
cooldownDisplay.Visible = false;
|
||||||
cooldownTexture.Texture = _texturesCooldownOverlay[textureIndex];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cooldownTexture.Visible = false;
|
cooldownDisplay.Visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int CalculateCooldownLevel(float cooldownValue)
|
|
||||||
{
|
|
||||||
var val = cooldownValue.Clamp(0, 1);
|
|
||||||
val *= CooldownLevels;
|
|
||||||
return (int)Math.Floor(val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
uniform = entityMan.SpawnEntity("JanitorUniform", MapCoordinates.Nullspace);
|
uniform = entityMan.SpawnEntity("JanitorUniform", MapCoordinates.Nullspace);
|
||||||
idCard = entityMan.SpawnEntity("AssistantIDCard", MapCoordinates.Nullspace);
|
idCard = entityMan.SpawnEntity("AssistantIDCard", MapCoordinates.Nullspace);
|
||||||
pocketItem = entityMan.SpawnEntity("FlashlightLantern", MapCoordinates.Nullspace);
|
pocketItem = entityMan.SpawnEntity("FlashlightLantern", MapCoordinates.Nullspace);
|
||||||
var tooBigItem = entityMan.SpawnEntity("RedToolboxItem", MapCoordinates.Nullspace);
|
var tooBigItem = entityMan.SpawnEntity("ToolboxEmergency", MapCoordinates.Nullspace);
|
||||||
|
|
||||||
inventory = human.GetComponent<InventoryComponent>();
|
inventory = human.GetComponent<InventoryComponent>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Movement;
|
using Content.Server.Interfaces.GameObjects.Components.Movement;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
using Robust.Server.AI;
|
using Robust.Server.AI;
|
||||||
@@ -114,7 +115,7 @@ namespace Content.Server.AI
|
|||||||
var ray = new CollisionRay(myTransform.WorldPosition, dir.Normalized, (int)(CollisionGroup.MobImpassable | CollisionGroup.Impassable));
|
var ray = new CollisionRay(myTransform.WorldPosition, dir.Normalized, (int)(CollisionGroup.MobImpassable | CollisionGroup.Impassable));
|
||||||
|
|
||||||
// cast the ray
|
// cast the ray
|
||||||
var result = _physMan.IntersectRay(myTransform.MapID, ray, maxRayLen, SelfEntity);
|
var result = _physMan.IntersectRay(myTransform.MapID, ray, maxRayLen, SelfEntity).First();
|
||||||
|
|
||||||
// add to visible list
|
// add to visible list
|
||||||
if (result.HitEntity == entity)
|
if (result.HitEntity == entity)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Movement;
|
using Content.Server.GameObjects.Components.Movement;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces.Chat;
|
using Content.Server.Interfaces.Chat;
|
||||||
@@ -127,17 +128,20 @@ namespace Content.Server.AI
|
|||||||
{
|
{
|
||||||
var dir = new Vector2(Random01(ref rngState) * 2 - 1, Random01(ref rngState) *2 -1).Normalized;
|
var dir = new Vector2(Random01(ref rngState) * 2 - 1, Random01(ref rngState) *2 -1).Normalized;
|
||||||
var ray = new CollisionRay(entWorldPos, dir, (int) CollisionGroup.Impassable);
|
var ray = new CollisionRay(entWorldPos, dir, (int) CollisionGroup.Impassable);
|
||||||
var rayResult = _physMan.IntersectRay(SelfEntity.Transform.MapID, ray, MaxWalkDistance, SelfEntity);
|
var rayResults = _physMan.IntersectRay(SelfEntity.Transform.MapID, ray, MaxWalkDistance, SelfEntity).ToList();
|
||||||
|
|
||||||
if (rayResult.DidHitObject && rayResult.Distance > 1) // hit an impassable object
|
if (rayResults.Count == 1)
|
||||||
{
|
{
|
||||||
// set the new position back from the wall a bit
|
var rayResult = rayResults[0];
|
||||||
_walkTargetPos = entWorldPos + dir * (rayResult.Distance - 0.5f);
|
if (rayResult.Distance > 1) // hit an impassable object
|
||||||
WalkingPositiveEdge();
|
{
|
||||||
return;
|
// set the new position back from the wall a bit
|
||||||
|
_walkTargetPos = entWorldPos + dir * (rayResult.Distance - 0.5f);
|
||||||
|
WalkingPositiveEdge();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else // hit nothing (path clear)
|
||||||
if (!rayResult.DidHitObject) // hit nothing (path clear)
|
|
||||||
{
|
{
|
||||||
_walkTargetPos = dir * MaxWalkDistance;
|
_walkTargetPos = dir * MaxWalkDistance;
|
||||||
WalkingPositiveEdge();
|
WalkingPositiveEdge();
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace Content.Server
|
|||||||
"IconSmooth",
|
"IconSmooth",
|
||||||
"SubFloorHide",
|
"SubFloorHide",
|
||||||
"LowWall",
|
"LowWall",
|
||||||
|
"ReinforcedWall",
|
||||||
"Window",
|
"Window",
|
||||||
"CharacterInfo",
|
"CharacterInfo",
|
||||||
"InteractionOutline",
|
"InteractionOutline",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Access;
|
using Content.Shared.Access;
|
||||||
using Content.Shared.GameObjects.Components.Access;
|
using Content.Shared.GameObjects.Components.Access;
|
||||||
using Robust.Server.GameObjects.Components.Container;
|
using Robust.Server.GameObjects.Components.Container;
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ using Content.Shared.GameObjects.Components.Interactable;
|
|||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components
|
namespace Content.Server.GameObjects.Components
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Cargo
|
namespace Content.Server.GameObjects.Components.Cargo
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Content.Server.GameObjects.Components.Metabolism;
|
using Content.Server.GameObjects.Components.Metabolism;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.GameObjects.Components.Chemistry;
|
using Content.Shared.GameObjects.Components.Chemistry;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -110,6 +111,8 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
/// <param name="eventArgs"></param>
|
/// <param name="eventArgs"></param>
|
||||||
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
//Make sure we have the attacking entity
|
//Make sure we have the attacking entity
|
||||||
if (eventArgs.Attacked == null || !_internalContents.Injector)
|
if (eventArgs.Attacked == null || !_internalContents.Injector)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,12 +4,15 @@ using System.Text;
|
|||||||
using Content.Server.GameObjects.Components.Nutrition;
|
using Content.Server.GameObjects.Components.Nutrition;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Chemistry
|
namespace Content.Server.GameObjects.Components.Chemistry
|
||||||
{
|
{
|
||||||
@@ -25,6 +28,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
||||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||||
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
public override string Name => "Pourable";
|
public override string Name => "Pourable";
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Server.GameObjects.EntitySystems;
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.GameObjects.Components.Chemistry;
|
using Content.Shared.GameObjects.Components.Chemistry;
|
||||||
using Robust.Server.GameObjects.Components.Container;
|
using Robust.Server.GameObjects.Components.Container;
|
||||||
|
|||||||
@@ -216,21 +216,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class FillTargetVerb : Verb<SolutionComponent>
|
private sealed class FillTargetVerb : Verb<SolutionComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, SolutionComponent component)
|
protected override void GetData(IEntity user, SolutionComponent component, VerbData data)
|
||||||
{
|
|
||||||
if(!user.TryGetComponent<HandsComponent>(out var hands))
|
|
||||||
return "<I SHOULD BE INVISIBLE>";
|
|
||||||
|
|
||||||
if(hands.GetActiveHand == null)
|
|
||||||
return "<I SHOULD BE INVISIBLE>";
|
|
||||||
|
|
||||||
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
|
|
||||||
var myName = component.Owner.Prototype?.Name ?? "<Item>";
|
|
||||||
|
|
||||||
return $"Transfer liquid from [{heldEntityName}] to [{myName}].";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, SolutionComponent component)
|
|
||||||
{
|
{
|
||||||
if (user.TryGetComponent<HandsComponent>(out var hands))
|
if (user.TryGetComponent<HandsComponent>(out var hands))
|
||||||
{
|
{
|
||||||
@@ -238,13 +224,20 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
{
|
{
|
||||||
if (hands.GetActiveHand.Owner.TryGetComponent<SolutionComponent>(out var solution))
|
if (hands.GetActiveHand.Owner.TryGetComponent<SolutionComponent>(out var solution))
|
||||||
{
|
{
|
||||||
if ((solution.Capabilities & SolutionCaps.PourOut) != 0 && (component.Capabilities & SolutionCaps.PourIn) != 0)
|
if ((solution.Capabilities & SolutionCaps.PourOut) != 0 &&
|
||||||
return VerbVisibility.Visible;
|
(component.Capabilities & SolutionCaps.PourIn) != 0)
|
||||||
|
{
|
||||||
|
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
|
||||||
|
var myName = component.Owner.Prototype?.Name ?? "<Item>";
|
||||||
|
|
||||||
|
data.Text= $"Transfer liquid from [{heldEntityName}] to [{myName}].";
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, SolutionComponent component)
|
protected override void Activate(IEntity user, SolutionComponent component)
|
||||||
@@ -269,7 +262,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
|
|
||||||
var transferSolution = handSolutionComp.SplitSolution(transferQuantity);
|
var transferSolution = handSolutionComp.SplitSolution(transferQuantity);
|
||||||
component.TryAddSolution(transferSolution);
|
component.TryAddSolution(transferSolution);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,21 +296,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class EmptyTargetVerb : Verb<SolutionComponent>
|
private sealed class EmptyTargetVerb : Verb<SolutionComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, SolutionComponent component)
|
protected override void GetData(IEntity user, SolutionComponent component, VerbData data)
|
||||||
{
|
|
||||||
if (!user.TryGetComponent<HandsComponent>(out var hands))
|
|
||||||
return "<I SHOULD BE INVISIBLE>";
|
|
||||||
|
|
||||||
if (hands.GetActiveHand == null)
|
|
||||||
return "<I SHOULD BE INVISIBLE>";
|
|
||||||
|
|
||||||
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
|
|
||||||
var myName = component.Owner.Prototype?.Name ?? "<Item>";
|
|
||||||
|
|
||||||
return $"Transfer liquid from [{myName}] to [{heldEntityName}].";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, SolutionComponent component)
|
|
||||||
{
|
{
|
||||||
if (user.TryGetComponent<HandsComponent>(out var hands))
|
if (user.TryGetComponent<HandsComponent>(out var hands))
|
||||||
{
|
{
|
||||||
@@ -326,13 +304,20 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
|||||||
{
|
{
|
||||||
if (hands.GetActiveHand.Owner.TryGetComponent<SolutionComponent>(out var solution))
|
if (hands.GetActiveHand.Owner.TryGetComponent<SolutionComponent>(out var solution))
|
||||||
{
|
{
|
||||||
if ((solution.Capabilities & SolutionCaps.PourIn) != 0 && (component.Capabilities & SolutionCaps.PourOut) != 0)
|
if ((solution.Capabilities & SolutionCaps.PourIn) != 0 &&
|
||||||
return VerbVisibility.Visible;
|
(component.Capabilities & SolutionCaps.PourOut) != 0)
|
||||||
|
{
|
||||||
|
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
|
||||||
|
var myName = component.Owner.Prototype?.Name ?? "<Item>";
|
||||||
|
|
||||||
|
data.Text = $"Transfer liquid from [{myName}] to [{heldEntityName}].";
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, SolutionComponent component)
|
protected override void Activate(IEntity user, SolutionComponent component)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces.GameTicking;
|
using Content.Server.Interfaces.GameTicking;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Command;
|
using Content.Shared.GameObjects.Components.Command;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Content.Server.GameObjects.Components.Interactable;
|
|||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Construction;
|
using Content.Shared.Construction;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
@@ -11,6 +12,7 @@ using Robust.Server.GameObjects;
|
|||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
@@ -19,6 +21,8 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using static Content.Shared.Construction.ConstructionStepMaterial;
|
using static Content.Shared.Construction.ConstructionStepMaterial;
|
||||||
using static Content.Shared.Construction.ConstructionStepTool;
|
using static Content.Shared.Construction.ConstructionStepTool;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Construction
|
namespace Content.Server.GameObjects.Components.Construction
|
||||||
{
|
{
|
||||||
@@ -47,18 +51,16 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
|
|
||||||
Sprite = Owner.GetComponent<SpriteComponent>();
|
Sprite = Owner.GetComponent<SpriteComponent>();
|
||||||
Transform = Owner.GetComponent<ITransformComponent>();
|
Transform = Owner.GetComponent<ITransformComponent>();
|
||||||
var systemman = IoCManager.Resolve<IEntitySystemManager>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AttackBy(AttackByEventArgs eventArgs)
|
public bool AttackBy(AttackByEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
var playerEntity = eventArgs.User;
|
// default interaction check for AttackBy allows inside blockers, so we will check if its blocked if
|
||||||
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
// we're not allowed to build on impassable stuff
|
||||||
if (!interactionSystem.InRangeUnobstructed(playerEntity.Transform.MapPosition, Owner.Transform.WorldPosition, ignoredEnt: Owner, insideBlockerValid: Prototype.CanBuildInImpassable))
|
if (Prototype.CanBuildInImpassable == false)
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, playerEntity,
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs, false))
|
||||||
_localizationManager.GetString("You can't reach there!"));
|
return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var stage = Prototype.Stages[Stage];
|
var stage = Prototype.Stages[Stage];
|
||||||
@@ -125,7 +127,7 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var sound = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
var sound = EntitySystem.Get<AudioSystem>();
|
||||||
|
|
||||||
switch (step)
|
switch (step)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Construction;
|
using Content.Shared.Construction;
|
||||||
using Content.Shared.GameObjects.Components.Construction;
|
using Content.Shared.GameObjects.Components.Construction;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using Robust.Shared.Interfaces.Network;
|
||||||
@@ -16,6 +18,7 @@ using Robust.Shared.Map;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Construction
|
namespace Content.Server.GameObjects.Components.Construction
|
||||||
{
|
{
|
||||||
@@ -47,16 +50,13 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
{
|
{
|
||||||
var prototype = _prototypeManager.Index<ConstructionPrototype>(prototypeName);
|
var prototype = _prototypeManager.Index<ConstructionPrototype>(prototypeName);
|
||||||
|
|
||||||
var transform = Owner.Transform;
|
if (!InteractionChecks.InRangeUnobstructed(Owner, loc.ToMapPos(_mapManager),
|
||||||
|
ignoredEnt: Owner, insideBlockerValid: prototype.CanBuildInImpassable))
|
||||||
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
|
||||||
if (!interactionSystem.InRangeUnobstructed(loc.ToMap(_mapManager), Owner.Transform.WorldPosition, ignoredEnt: Owner, insideBlockerValid: prototype.CanBuildInImpassable))
|
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(transform.GridPosition, Owner,
|
|
||||||
_localizationManager.GetString("You can't reach there!"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (prototype.Stages.Count < 2)
|
if (prototype.Stages.Count < 2)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Prototype '{prototypeName}' does not have enough stages.");
|
throw new InvalidOperationException($"Prototype '{prototypeName}' does not have enough stages.");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Server.GameObjects.Components.Power;
|
|||||||
using Content.Server.GameObjects.Components.VendingMachines;
|
using Content.Server.GameObjects.Components.VendingMachines;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Doors;
|
using Content.Shared.GameObjects.Components.Doors;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components.Access;
|
using Content.Server.GameObjects.Components.Access;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Doors;
|
using Content.Shared.GameObjects.Components.Doors;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -17,7 +19,7 @@ namespace Content.Server.GameObjects
|
|||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
public class ServerDoorComponent : Component, IActivate
|
public class ServerDoorComponent : Component, IActivate, ICollideBehavior
|
||||||
{
|
{
|
||||||
public override string Name => "Door";
|
public override string Name => "Door";
|
||||||
|
|
||||||
@@ -85,26 +87,16 @@ namespace Content.Server.GameObjects
|
|||||||
ActivateImpl(eventArgs);
|
ActivateImpl(eventArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, IComponent component)
|
|
||||||
|
void ICollideBehavior.CollideWith(IEntity entity)
|
||||||
{
|
{
|
||||||
base.HandleMessage(message, component);
|
if (State != DoorState.Closed)
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
{
|
||||||
case BumpedEntMsg msg:
|
return;
|
||||||
if (State != DoorState.Closed)
|
}
|
||||||
{
|
if (entity.HasComponent(typeof(SpeciesComponent)))
|
||||||
return;
|
{
|
||||||
}
|
TryOpen(entity);
|
||||||
|
|
||||||
// Only open when bumped by mobs.
|
|
||||||
if (!msg.Entity.HasComponent(typeof(SpeciesComponent)))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TryOpen(msg.Entity);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +147,7 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
Timer.Spawn(OpenTimeOne, async () =>
|
Timer.Spawn(OpenTimeOne, async () =>
|
||||||
{
|
{
|
||||||
collidableComponent.IsHardCollidable = false;
|
collidableComponent.CanCollide = false;
|
||||||
|
|
||||||
await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token);
|
await Timer.Delay(OpenTimeTwo, _cancellationTokenSource.Token);
|
||||||
|
|
||||||
@@ -191,14 +183,14 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
public bool Close()
|
public bool Close()
|
||||||
{
|
{
|
||||||
if (collidableComponent.TryCollision(Vector2.Zero))
|
if (collidableComponent.IsColliding(Vector2.Zero))
|
||||||
{
|
{
|
||||||
// Do nothing, somebody's in the door.
|
// Do nothing, somebody's in the door.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
State = DoorState.Closing;
|
State = DoorState.Closing;
|
||||||
collidableComponent.IsHardCollidable = true;
|
collidableComponent.CanCollide = true;
|
||||||
OpenTimeCounter = 0;
|
OpenTimeCounter = 0;
|
||||||
SetAppearance(DoorVisualState.Closing);
|
SetAppearance(DoorVisualState.Closing);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|||||||
@@ -19,19 +19,18 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class FillTargetVerb : Verb<CanSpillComponent>
|
private sealed class FillTargetVerb : Verb<CanSpillComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, CanSpillComponent component)
|
protected override void GetData(IEntity user, CanSpillComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
return "Spill liquid";
|
if (!component.Owner.TryGetComponent(out SolutionComponent solutionComponent))
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, CanSpillComponent component)
|
|
||||||
{
|
|
||||||
if (component.Owner.TryGetComponent(out SolutionComponent solutionComponent))
|
|
||||||
{
|
{
|
||||||
return solutionComponent.CurrentVolume > ReagentUnit.Zero ? VerbVisibility.Visible : VerbVisibility.Disabled;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerbVisibility.Invisible;
|
data.Text = "Spill liquid";
|
||||||
|
data.Visibility = solutionComponent.CurrentVolume > ReagentUnit.Zero
|
||||||
|
? VerbVisibility.Visible
|
||||||
|
: VerbVisibility.Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, CanSpillComponent component)
|
protected override void Activate(IEntity user, CanSpillComponent component)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -59,6 +60,8 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
|
|
||||||
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
Solution solution;
|
Solution solution;
|
||||||
if (eventArgs.Attacked == null)
|
if (eventArgs.Attacked == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Robust.Server.GameObjects.EntitySystems;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components;
|
using Robust.Shared.GameObjects.Components;
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
using Robust.Shared.GameObjects.Components.Transform;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
@@ -17,6 +18,7 @@ using Robust.Shared.Serialization;
|
|||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using Timer = Robust.Shared.Timers.Timer;
|
using Timer = Robust.Shared.Timers.Timer;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Fluids
|
namespace Content.Server.GameObjects.Components.Fluids
|
||||||
{
|
{
|
||||||
@@ -34,7 +36,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
// Small puddles will evaporate after a set delay
|
// Small puddles will evaporate after a set delay
|
||||||
|
|
||||||
// TODO: 'leaves fluidtracks', probably in a separate component for stuff like gibb chunks?;
|
// TODO: 'leaves fluidtracks', probably in a separate component for stuff like gibb chunks?;
|
||||||
// TODO: Add stuff like slipping -> probably in a separate component (for stuff like bananas) and using BumpEntMsg
|
// TODO: Add stuff like slipping -> probably in a separate component (for stuff like bananas)
|
||||||
|
|
||||||
// based on behaviour (e.g. someone being punched vs slashed with a sword would have different blood sprite)
|
// based on behaviour (e.g. someone being punched vs slashed with a sword would have different blood sprite)
|
||||||
// to check for low volumes for evaporation or whatever
|
// to check for low volumes for evaporation or whatever
|
||||||
@@ -137,8 +139,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var entitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
EntitySystem.Get<AudioSystem>().Play(_spillSound);
|
||||||
entitySystemManager.GetEntitySystem<AudioSystem>().Play(_spillSound);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Server.GameObjects.Components.Interactable;
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Gravity;
|
using Content.Shared.GameObjects.Components.Gravity;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
@@ -12,10 +13,12 @@ using Robust.Server.GameObjects.EntitySystems;
|
|||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Gravity
|
namespace Content.Server.GameObjects.Components.Gravity
|
||||||
{
|
{
|
||||||
@@ -114,10 +117,8 @@ namespace Content.Server.GameObjects.Components.Gravity
|
|||||||
breakable.broken = false;
|
breakable.broken = false;
|
||||||
_intact = true;
|
_intact = true;
|
||||||
|
|
||||||
var entitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
|
||||||
var notifyManager = IoCManager.Resolve<IServerNotifyManager>();
|
var notifyManager = IoCManager.Resolve<IServerNotifyManager>();
|
||||||
|
|
||||||
entitySystemManager.GetEntitySystem<AudioSystem>().Play("/Audio/items/welder2.ogg", Owner);
|
|
||||||
notifyManager.PopupMessage(Owner, eventArgs.User, Loc.GetString("You repair the gravity generator with the welder"));
|
notifyManager.PopupMessage(Owner, eventArgs.User, Loc.GetString("You repair the gravity generator with the welder"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
@@ -24,6 +25,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
|||||||
|
|
||||||
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
if (eventArgs.Attacked == null)
|
if (eventArgs.Attacked == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,15 +1,26 @@
|
|||||||
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Mobs;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Instruments;
|
using Content.Shared.GameObjects.Components.Instruments;
|
||||||
|
using NFluidsynth;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
|
using Robust.Server.Player;
|
||||||
|
using Robust.Shared.Enums;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using Robust.Shared.Interfaces.Network;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Logger = Robust.Shared.Log.Logger;
|
||||||
|
using MidiEvent = Robust.Shared.Audio.Midi.MidiEvent;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Instruments
|
namespace Content.Server.GameObjects.Components.Instruments
|
||||||
{
|
{
|
||||||
@@ -18,12 +29,35 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
public class InstrumentComponent : SharedInstrumentComponent,
|
public class InstrumentComponent : SharedInstrumentComponent,
|
||||||
IDropped, IHandSelected, IHandDeselected, IActivate, IUse, IThrown
|
IDropped, IHandSelected, IHandDeselected, IActivate, IUse, IThrown
|
||||||
{
|
{
|
||||||
|
[Dependency] private IServerNotifyManager _notifyManager;
|
||||||
|
|
||||||
|
// These 2 values are quite high for now, and this could be easily abused. Change this if people are abusing it.
|
||||||
|
public const int MaxMidiEventsPerSecond = 20;
|
||||||
|
public const int MaxMidiEventsPerBatch = 50;
|
||||||
|
public const int MaxMidiBatchDropped = 20;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The client channel currently playing the instrument, or null if there's none.
|
/// The client channel currently playing the instrument, or null if there's none.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private ICommonSession _instrumentPlayer;
|
[ViewVariables]
|
||||||
|
private IPlayerSession _instrumentPlayer;
|
||||||
private bool _handheld;
|
private bool _handheld;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private bool _playing = false;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private float _timer = 0f;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private int _batchesDropped = 0;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private uint _lastSequencerTick = 0;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
private int _midiEventCount = 0;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private BoundUserInterface _userInterface;
|
private BoundUserInterface _userInterface;
|
||||||
|
|
||||||
@@ -33,6 +67,43 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool Handheld => _handheld;
|
public bool Handheld => _handheld;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the instrument is currently playing or not.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public bool Playing
|
||||||
|
{
|
||||||
|
get => _playing;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_playing = value;
|
||||||
|
Dirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPlayerSession InstrumentPlayer
|
||||||
|
{
|
||||||
|
get => _instrumentPlayer;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
Playing = false;
|
||||||
|
|
||||||
|
if(_instrumentPlayer != null)
|
||||||
|
_instrumentPlayer.PlayerStatusChanged -= OnPlayerStatusChanged;
|
||||||
|
|
||||||
|
_instrumentPlayer = value;
|
||||||
|
|
||||||
|
if(value != null)
|
||||||
|
_instrumentPlayer.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.NewStatus == SessionStatus.Disconnected)
|
||||||
|
InstrumentPlayer = null;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -46,31 +117,52 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
serializer.DataField(ref _handheld, "handheld", false);
|
serializer.DataField(ref _handheld, "handheld", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ComponentState GetComponentState()
|
||||||
|
{
|
||||||
|
return new InstrumentState(Playing, _lastSequencerTick);
|
||||||
|
}
|
||||||
|
|
||||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
||||||
{
|
{
|
||||||
base.HandleNetworkMessage(message, channel, session);
|
base.HandleNetworkMessage(message, channel, session);
|
||||||
|
|
||||||
// If the client that sent the message isn't the client playing this instrument, we ignore it.
|
|
||||||
if (session != _instrumentPlayer) return;
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case InstrumentMidiEventMessage midiEventMsg:
|
case InstrumentMidiEventMessage midiEventMsg:
|
||||||
SendNetworkMessage(midiEventMsg);
|
if (!Playing || session != _instrumentPlayer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (++_midiEventCount <= MaxMidiEventsPerSecond &&
|
||||||
|
midiEventMsg.MidiEvent.Length < MaxMidiEventsPerBatch)
|
||||||
|
SendNetworkMessage(midiEventMsg);
|
||||||
|
else
|
||||||
|
_batchesDropped++; // Batch dropped!
|
||||||
|
|
||||||
|
_lastSequencerTick = midiEventMsg.MidiEvent[^1].Timestamp;
|
||||||
|
break;
|
||||||
|
case InstrumentStartMidiMessage startMidi:
|
||||||
|
Playing = true;
|
||||||
|
break;
|
||||||
|
case InstrumentStopMidiMessage stopMidi:
|
||||||
|
Playing = false;
|
||||||
|
_lastSequencerTick = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dropped(DroppedEventArgs eventArgs)
|
public void Dropped(DroppedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
Playing = false;
|
||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
_instrumentPlayer = null;
|
InstrumentPlayer = null;
|
||||||
_userInterface.CloseAll();
|
_userInterface.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Thrown(ThrownEventArgs eventArgs)
|
public void Thrown(ThrownEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
Playing = false;
|
||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
_instrumentPlayer = null;
|
InstrumentPlayer = null;
|
||||||
_userInterface.CloseAll();
|
_userInterface.CloseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +172,12 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
|
|
||||||
if (session == null) return;
|
if (session == null) return;
|
||||||
|
|
||||||
_instrumentPlayer = session;
|
InstrumentPlayer = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandDeselected(HandDeselectedEventArgs eventArgs)
|
public void HandDeselected(HandDeselectedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
Playing = false;
|
||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
_userInterface.CloseAll();
|
_userInterface.CloseAll();
|
||||||
}
|
}
|
||||||
@@ -94,10 +187,10 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
if (Handheld || !eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (Handheld || !eventArgs.User.TryGetComponent(out IActorComponent actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_instrumentPlayer != null)
|
if (InstrumentPlayer != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_instrumentPlayer = actor.playerSession;
|
InstrumentPlayer = actor.playerSession;
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,17 +199,18 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
if (!eventArgs.User.TryGetComponent(out IActorComponent actor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(_instrumentPlayer == actor.playerSession)
|
if(InstrumentPlayer == actor.playerSession)
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UserInterfaceOnClosed(IPlayerSession player)
|
private void UserInterfaceOnClosed(IPlayerSession player)
|
||||||
{
|
{
|
||||||
if (!Handheld && player == _instrumentPlayer)
|
if (!Handheld && player == InstrumentPlayer)
|
||||||
{
|
{
|
||||||
_instrumentPlayer = null;
|
InstrumentPlayer = null;
|
||||||
SendNetworkMessage(new InstrumentStopMidiMessage());
|
SendNetworkMessage(new InstrumentStopMidiMessage());
|
||||||
|
Playing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,5 +218,35 @@ namespace Content.Server.GameObjects.Components.Instruments
|
|||||||
{
|
{
|
||||||
_userInterface.Open(session);
|
_userInterface.Open(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Update(float delta)
|
||||||
|
{
|
||||||
|
base.Update(delta);
|
||||||
|
|
||||||
|
if (_instrumentPlayer != null && !ActionBlockerSystem.CanInteract(_instrumentPlayer.AttachedEntity))
|
||||||
|
InstrumentPlayer = null;
|
||||||
|
|
||||||
|
if (_batchesDropped > MaxMidiBatchDropped && InstrumentPlayer != null)
|
||||||
|
{
|
||||||
|
_batchesDropped = 0;
|
||||||
|
var mob = InstrumentPlayer.AttachedEntity;
|
||||||
|
|
||||||
|
_userInterface.CloseAll();
|
||||||
|
|
||||||
|
if (mob.TryGetComponent(out StunnableComponent stun))
|
||||||
|
stun.Stun(1);
|
||||||
|
else
|
||||||
|
StandingStateHelper.DropAllItemsInHands(mob);
|
||||||
|
|
||||||
|
InstrumentPlayer = null;
|
||||||
|
|
||||||
|
_notifyManager.PopupMessage(Owner, mob, "Your fingers cramp up from playing!");
|
||||||
|
}
|
||||||
|
|
||||||
|
_timer += delta;
|
||||||
|
if (_timer < 1) return;
|
||||||
|
_timer = 0f;
|
||||||
|
_midiEventCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
@@ -250,14 +251,17 @@ namespace Content.Server.GameObjects.Components.Interactable
|
|||||||
[Verb]
|
[Verb]
|
||||||
public sealed class EjectCellVerb : Verb<HandheldLightComponent>
|
public sealed class EjectCellVerb : Verb<HandheldLightComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, HandheldLightComponent component)
|
protected override void GetData(IEntity user, HandheldLightComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
return component.Cell == null ? "Eject cell (cell missing)" : "Eject cell";
|
if (component.Cell == null)
|
||||||
}
|
{
|
||||||
|
data.Text = "Eject cell (cell missing)";
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, HandheldLightComponent component)
|
data.Visibility = VerbVisibility.Disabled;
|
||||||
{
|
}
|
||||||
return component.Cell == null ? VerbVisibility.Disabled : VerbVisibility.Visible;
|
else
|
||||||
|
{
|
||||||
|
data.Text = "Eject cell";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, HandheldLightComponent component)
|
protected override void Activate(IEntity user, HandheldLightComponent component)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -40,18 +41,11 @@ namespace Content.Server.GameObjects.Components.Items
|
|||||||
}
|
}
|
||||||
public void AfterAttack(AfterAttackEventArgs eventArgs)
|
public void AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
var attacked = eventArgs.Attacked;
|
var attacked = eventArgs.Attacked;
|
||||||
var mapGrid = _mapManager.GetGrid(eventArgs.ClickLocation.GridID);
|
var mapGrid = _mapManager.GetGrid(eventArgs.ClickLocation.GridID);
|
||||||
var tile = mapGrid.GetTileRef(eventArgs.ClickLocation);
|
var tile = mapGrid.GetTileRef(eventArgs.ClickLocation);
|
||||||
|
|
||||||
var coordinates = mapGrid.GridTileToLocal(tile.GridIndices);
|
|
||||||
float distance = coordinates.Distance(_mapManager, Owner.Transform.GridPosition);
|
|
||||||
|
|
||||||
if (distance > InteractionSystem.InteractionRange)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];
|
var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId];
|
||||||
if (tileDef.IsSubFloor && attacked == null && Stack.Use(1))
|
if (tileDef.IsSubFloor && attacked == null && Stack.Use(1))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Linq;
|
|||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -190,7 +191,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
{
|
{
|
||||||
if (Owner.TryGetComponent<ICollidableComponent>(out var collidableComponent))
|
if (Owner.TryGetComponent<ICollidableComponent>(out var collidableComponent))
|
||||||
{
|
{
|
||||||
collidableComponent.CollisionEnabled = IsCollidableWhenOpen || !Open;
|
collidableComponent.CanCollide = IsCollidableWhenOpen || !Open;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Owner.TryGetComponent<PlaceableSurfaceComponent>(out var placeableSurfaceComponent))
|
if (Owner.TryGetComponent<PlaceableSurfaceComponent>(out var placeableSurfaceComponent))
|
||||||
@@ -250,7 +251,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
entity.Transform.WorldPosition = worldPos;
|
entity.Transform.WorldPosition = worldPos;
|
||||||
if (entityCollidableComponent != null)
|
if (entityCollidableComponent != null)
|
||||||
{
|
{
|
||||||
entityCollidableComponent.CollisionEnabled = false;
|
entityCollidableComponent.CanCollide = false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -265,7 +266,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
{
|
{
|
||||||
if (contained.TryGetComponent<ICollidableComponent>(out var entityCollidableComponent))
|
if (contained.TryGetComponent<ICollidableComponent>(out var entityCollidableComponent))
|
||||||
{
|
{
|
||||||
entityCollidableComponent.CollisionEnabled = true;
|
entityCollidableComponent.CanCollide = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,16 +329,9 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class LockToggleVerb : Verb<EntityStorageComponent>
|
private sealed class LockToggleVerb : Verb<EntityStorageComponent>
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
protected override void GetData(IEntity user, EntityStorageComponent component, VerbData data)
|
||||||
protected override string GetText(IEntity user, EntityStorageComponent component)
|
|
||||||
{
|
{
|
||||||
return component._locked ? "Unlock" : "Lock";
|
data.Text = component._locked ? "Unlock" : "Lock";
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, EntityStorageComponent component)
|
|
||||||
{
|
|
||||||
return VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -350,16 +344,15 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class OpenToggleVerb : Verb<EntityStorageComponent>
|
private sealed class OpenToggleVerb : Verb<EntityStorageComponent>
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
protected override void GetData(IEntity user, EntityStorageComponent component, VerbData data)
|
||||||
protected override string GetText(IEntity user, EntityStorageComponent component)
|
|
||||||
{
|
{
|
||||||
return component.Open ? "Close" : "Open";
|
if (component.NoDoor)
|
||||||
}
|
{
|
||||||
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
data.Text = component.Open ? "Close" : "Open";
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, EntityStorageComponent component)
|
|
||||||
{
|
|
||||||
return component.NoDoor ? VerbVisibility.Invisible : VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Items.Storage.Fill
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
internal sealed class EmergencyClosetFillComponent : Component, IMapInit
|
||||||
|
{
|
||||||
|
public override string Name => "EmergencyClosetFill";
|
||||||
|
|
||||||
|
void IMapInit.MapInit()
|
||||||
|
{
|
||||||
|
var storage = Owner.GetComponent<IStorageComponent>();
|
||||||
|
var random = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
|
||||||
|
void Spawn(string prototype)
|
||||||
|
{
|
||||||
|
storage.Insert(Owner.EntityManager.SpawnEntity(prototype, Owner.Transform.GridPosition));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (random.Prob(40))
|
||||||
|
{
|
||||||
|
Spawn("ToolboxEmergencyFilled");
|
||||||
|
}
|
||||||
|
|
||||||
|
var pick = random.Next(0, 100);
|
||||||
|
if (pick < 40) // 40%
|
||||||
|
{
|
||||||
|
// TODO: uncomment when we actually have these items.
|
||||||
|
// Spawn("TankOxygenSmallFilled");
|
||||||
|
// Spawn("TankOxygenSmallFilled");
|
||||||
|
Spawn("BreathMaskClothing");
|
||||||
|
Spawn("BreathMaskClothing");
|
||||||
|
}
|
||||||
|
else if (pick < 65) // 25%
|
||||||
|
{
|
||||||
|
// Spawn("TankOxygenSmallFilled");
|
||||||
|
// Spawn("MedkitOxygenFilled");
|
||||||
|
Spawn("BreathMaskClothing");
|
||||||
|
}
|
||||||
|
else if (pick < 85) // 20%
|
||||||
|
{
|
||||||
|
// Spawn("TankOxygenFilled");
|
||||||
|
Spawn("BreathMaskClothing");
|
||||||
|
}
|
||||||
|
else if (pick < 95) // 10%
|
||||||
|
{
|
||||||
|
// Spawn("TankOxygenSmallFilled");
|
||||||
|
Spawn("BreathMaskClothing");
|
||||||
|
}
|
||||||
|
else if (pick < 99) // 4%
|
||||||
|
{
|
||||||
|
// nothing, doot
|
||||||
|
}
|
||||||
|
else // 1%
|
||||||
|
{
|
||||||
|
// teehee
|
||||||
|
Owner.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,10 +12,6 @@ namespace Content.Server.GameObjects.Components.Items.Storage.Fill
|
|||||||
{
|
{
|
||||||
public override string Name => "ToolLockerFill";
|
public override string Name => "ToolLockerFill";
|
||||||
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
void IMapInit.MapInit()
|
void IMapInit.MapInit()
|
||||||
{
|
{
|
||||||
var storage = Owner.GetComponent<IStorageComponent>();
|
var storage = Owner.GetComponent<IStorageComponent>();
|
||||||
@@ -23,7 +19,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage.Fill
|
|||||||
|
|
||||||
void Spawn(string prototype)
|
void Spawn(string prototype)
|
||||||
{
|
{
|
||||||
storage.Insert(_entityManager.SpawnEntity(prototype, Owner.Transform.GridPosition));
|
storage.Insert(Owner.EntityManager.SpawnEntity(prototype, Owner.Transform.GridPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (random.Prob(0.4f))
|
if (random.Prob(0.4f))
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Content.Server.GameObjects.Components.Destructible;
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using Content.Server.Throw;
|
using Content.Server.Throw;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
@@ -12,6 +13,7 @@ using Robust.Server.Interfaces.GameObjects;
|
|||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components;
|
using Robust.Shared.GameObjects.Components;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
@@ -23,6 +25,7 @@ using Robust.Shared.Maths;
|
|||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects
|
namespace Content.Server.GameObjects
|
||||||
{
|
{
|
||||||
@@ -35,7 +38,6 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IRobustRandom _robustRandom;
|
[Dependency] private readonly IRobustRandom _robustRandom;
|
||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
|
||||||
[Dependency] private readonly IMapManager _mapManager;
|
[Dependency] private readonly IMapManager _mapManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
@@ -97,8 +99,7 @@ namespace Content.Server.GameObjects
|
|||||||
var userPos = user.Transform.MapPosition;
|
var userPos = user.Transform.MapPosition;
|
||||||
var itemPos = Owner.Transform.WorldPosition;
|
var itemPos = Owner.Transform.WorldPosition;
|
||||||
|
|
||||||
return _entitySystemManager.GetEntitySystem<InteractionSystem>()
|
return InteractionChecks.InRangeUnobstructed(user, itemPos, ignoredEnt: Owner, insideBlockerValid:true);
|
||||||
.InRangeUnobstructed(userPos, itemPos, ignoredEnt: Owner, insideBlockerValid:true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AttackHand(AttackHandEventArgs eventArgs)
|
public bool AttackHand(AttackHandEventArgs eventArgs)
|
||||||
@@ -113,23 +114,15 @@ namespace Content.Server.GameObjects
|
|||||||
[Verb]
|
[Verb]
|
||||||
public sealed class PickUpVerb : Verb<ItemComponent>
|
public sealed class PickUpVerb : Verb<ItemComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, ItemComponent component)
|
protected override void GetData(IEntity user, ItemComponent component, VerbData data)
|
||||||
{
|
|
||||||
if (user.TryGetComponent(out HandsComponent hands) && hands.IsHolding(component.Owner))
|
|
||||||
{
|
|
||||||
return "Pick Up (Already Holding)";
|
|
||||||
}
|
|
||||||
return "Pick Up";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, ItemComponent component)
|
|
||||||
{
|
{
|
||||||
if (ContainerHelpers.IsInContainer(component.Owner) || !component.CanPickup(user))
|
if (ContainerHelpers.IsInContainer(component.Owner) || !component.CanPickup(user))
|
||||||
{
|
{
|
||||||
return VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerbVisibility.Visible;
|
data.Text = "Pick Up";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, ItemComponent component)
|
protected override void Activate(IEntity user, ItemComponent component)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Server.GameObjects.Components;
|
|||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -149,6 +150,8 @@ namespace Content.Server.GameObjects
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return PlayerInsertEntity(eventArgs.User);
|
return PlayerInsertEntity(eventArgs.User);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ using Robust.Server.GameObjects.Components.UserInterface;
|
|||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Kitchen
|
namespace Content.Server.GameObjects.Components.Kitchen
|
||||||
@@ -177,6 +178,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
_userInterface.Open(actor.playerSession);
|
_userInterface.Open(actor.playerSession);
|
||||||
|
|
||||||
@@ -224,6 +226,8 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
|||||||
|
|
||||||
if (!itemEntity.TryGetComponent(typeof(FoodComponent), out var food))
|
if (!itemEntity.TryGetComponent(typeof(FoodComponent), out var food))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
_notifyManager.PopupMessage(Owner, eventArgs.User, "That won't work!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Content.Shared.Preferences.Appearance;
|
using Content.Shared.Preferences.Appearance;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Content.Server.GameObjects.EntitySystems;
|
|||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Medical;
|
using Content.Shared.GameObjects.Components.Medical;
|
||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.Container;
|
using Robust.Server.GameObjects.Components.Container;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
@@ -120,22 +121,20 @@ namespace Content.Server.GameObjects.Components.Medical
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Powered)
|
if (!Powered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_userInterface.Open(actor.playerSession);
|
_userInterface.Open(actor.playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Verb]
|
[Verb]
|
||||||
public sealed class EnterVerb : Verb<MedicalScannerComponent>
|
public sealed class EnterVerb : Verb<MedicalScannerComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, MedicalScannerComponent component)
|
protected override void GetData(IEntity user, MedicalScannerComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
return "Enter";
|
data.Text = "Enter";
|
||||||
}
|
data.Visibility = component.IsOccupied ? VerbVisibility.Invisible : VerbVisibility.Visible;
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, MedicalScannerComponent component)
|
|
||||||
{
|
|
||||||
return component.IsOccupied ? VerbVisibility.Invisible : VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, MedicalScannerComponent component)
|
protected override void Activate(IEntity user, MedicalScannerComponent component)
|
||||||
@@ -147,14 +146,10 @@ namespace Content.Server.GameObjects.Components.Medical
|
|||||||
[Verb]
|
[Verb]
|
||||||
public sealed class EjectVerb : Verb<MedicalScannerComponent>
|
public sealed class EjectVerb : Verb<MedicalScannerComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, MedicalScannerComponent component)
|
protected override void GetData(IEntity user, MedicalScannerComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
return "Eject";
|
data.Text = "Eject";
|
||||||
}
|
data.Visibility = component.IsOccupied ? VerbVisibility.Visible : VerbVisibility.Invisible;
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, MedicalScannerComponent component)
|
|
||||||
{
|
|
||||||
return component.IsOccupied ? VerbVisibility.Visible : VerbVisibility.Invisible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, MedicalScannerComponent component)
|
protected override void Activate(IEntity user, MedicalScannerComponent component)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Melee;
|
using Content.Server.GameObjects.Components.Weapon.Melee;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
if (entity.TryGetComponent(out CollidableComponent collidable))
|
if (entity.TryGetComponent(out CollidableComponent collidable))
|
||||||
{
|
{
|
||||||
collidable.CollisionEnabled = false;
|
collidable.CanCollide = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ namespace Content.Server.GameObjects
|
|||||||
|
|
||||||
if (entity.TryGetComponent(out CollidableComponent collidable))
|
if (entity.TryGetComponent(out CollidableComponent collidable))
|
||||||
{
|
{
|
||||||
collidable.CollisionEnabled = true;
|
collidable.CanCollide = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ using Robust.Server.GameObjects.EntitySystems;
|
|||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components;
|
using Robust.Shared.GameObjects.Components;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Timers;
|
using Robust.Shared.Timers;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Movement
|
namespace Content.Server.GameObjects.Components.Movement
|
||||||
{
|
{
|
||||||
@@ -63,7 +65,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
base.OnAdd();
|
base.OnAdd();
|
||||||
if (Owner.TryGetComponent<CollidableComponent>(out var collide))
|
if (Owner.TryGetComponent<CollidableComponent>(out var collide))
|
||||||
{
|
{
|
||||||
collide.IsHardCollidable = false;
|
//collide.IsHardCollidable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_state = PortalState.Pending;
|
_state = PortalState.Pending;
|
||||||
@@ -195,7 +197,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
if (!immuneEntities.Contains(entity))
|
if (!immuneEntities.Contains(entity))
|
||||||
{
|
{
|
||||||
var position = _connectingTeleporter.Transform.GridPosition;
|
var position = _connectingTeleporter.Transform.GridPosition;
|
||||||
var soundPlayer = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
var soundPlayer = EntitySystem.Get<AudioSystem>();
|
||||||
|
|
||||||
// Departure
|
// Departure
|
||||||
// Do we need to rate-limit sounds to stop ear BLAST?
|
// Do we need to rate-limit sounds to stop ear BLAST?
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Robust.Server.GameObjects.EntitySystems;
|
|||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components;
|
using Robust.Shared.GameObjects.Components;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
@@ -16,6 +17,7 @@ using Robust.Shared.Maths;
|
|||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Timers;
|
using Robust.Shared.Timers;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Movement
|
namespace Content.Server.GameObjects.Components.Movement
|
||||||
{
|
{
|
||||||
@@ -141,7 +143,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
Timer.Spawn(TimeSpan.FromSeconds(_chargeTime + _cooldown), () => SetState(ItemTeleporterState.Off));
|
Timer.Spawn(TimeSpan.FromSeconds(_chargeTime + _cooldown), () => SetState(ItemTeleporterState.Off));
|
||||||
if (_cooldownSound != null)
|
if (_cooldownSound != null)
|
||||||
{
|
{
|
||||||
var soundPlayer = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
var soundPlayer = EntitySystem.Get<AudioSystem>();
|
||||||
soundPlayer.Play(_cooldownSound, Owner);
|
soundPlayer.Play(_cooldownSound, Owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,7 +229,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
{
|
{
|
||||||
// Messy maybe?
|
// Messy maybe?
|
||||||
GridCoordinates targetGrid = new GridCoordinates(vector, user.Transform.GridID);
|
GridCoordinates targetGrid = new GridCoordinates(vector, user.Transform.GridID);
|
||||||
var soundPlayer = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
var soundPlayer = EntitySystem.Get<AudioSystem>();
|
||||||
|
|
||||||
// If portals use those, otherwise just move em over
|
// If portals use those, otherwise just move em over
|
||||||
if (_portalAliveTime > 0.0f)
|
if (_portalAliveTime > 0.0f)
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ namespace Content.Server.GameObjects.Components.Movement
|
|||||||
if (!gridEntity.HasComponent<ICollidableComponent>())
|
if (!gridEntity.HasComponent<ICollidableComponent>())
|
||||||
{
|
{
|
||||||
var collideComp = gridEntity.AddComponent<CollidableComponent>();
|
var collideComp = gridEntity.AddComponent<CollidableComponent>();
|
||||||
collideComp.CollisionEnabled = true;
|
collideComp.CanCollide = true;
|
||||||
collideComp.IsHardCollidable = true;
|
//collideComp.IsHardCollidable = true;
|
||||||
collideComp.PhysicsShapes.Add(new PhysShapeGrid(grid));
|
collideComp.PhysicsShapes.Add(new PhysShapeGrid(grid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,22 @@ using System.Linq;
|
|||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.GameObjects.Components.Nutrition;
|
using Content.Shared.GameObjects.Components.Nutrition;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Content.Shared.Maths;
|
using Content.Shared.Maths;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Nutrition
|
namespace Content.Server.GameObjects.Components.Nutrition
|
||||||
{
|
{
|
||||||
@@ -98,23 +102,25 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
|
|
||||||
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
UseDrink(eventArgs.Attacked);
|
UseDrink(eventArgs.Attacked);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UseDrink(IEntity user)
|
private void UseDrink(IEntity targetEntity)
|
||||||
{
|
{
|
||||||
if (user == null)
|
if (targetEntity == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UsesLeft() == 0 && !_despawnOnFinish)
|
if (UsesLeft() == 0 && !_despawnOnFinish)
|
||||||
{
|
{
|
||||||
user.PopupMessage(user, _localizationManager.GetString("Empty"));
|
targetEntity.PopupMessage(targetEntity, _localizationManager.GetString("Empty"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.TryGetComponent(out StomachComponent stomachComponent))
|
if (targetEntity.TryGetComponent(out StomachComponent stomachComponent))
|
||||||
{
|
{
|
||||||
_drinking = true;
|
_drinking = true;
|
||||||
var transferAmount = ReagentUnit.Min(_transferAmount, _contents.CurrentVolume);
|
var transferAmount = ReagentUnit.Min(_transferAmount, _contents.CurrentVolume);
|
||||||
@@ -124,17 +130,16 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
// When we split Finish gets called which may delete the can so need to use the entity system for sound
|
// When we split Finish gets called which may delete the can so need to use the entity system for sound
|
||||||
if (_useSound != null)
|
if (_useSound != null)
|
||||||
{
|
{
|
||||||
var entitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
var audioSystem = EntitySystem.Get<AudioSystem>();
|
||||||
var audioSystem = entitySystemManager.GetEntitySystem<AudioSystem>();
|
audioSystem.Play(_useSound, Owner, AudioParams.Default.WithVolume(-2f));
|
||||||
audioSystem.Play(_useSound);
|
targetEntity.PopupMessage(targetEntity, _localizationManager.GetString("Slurp"));
|
||||||
user.PopupMessage(user, _localizationManager.GetString("Slurp"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Add it back in
|
// Add it back in
|
||||||
_contents.TryAddSolution(split);
|
_contents.TryAddSolution(split);
|
||||||
user.PopupMessage(user, _localizationManager.GetString("Can't drink"));
|
targetEntity.PopupMessage(targetEntity, _localizationManager.GetString("Can't drink"));
|
||||||
}
|
}
|
||||||
_drinking = false;
|
_drinking = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Content.Server.GameObjects.Components.Chemistry;
|
using Content.Server.GameObjects.Components.Chemistry;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
using Content.Shared.GameObjects.Components.Nutrition;
|
using Content.Shared.GameObjects.Components.Nutrition;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
@@ -111,6 +112,8 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
|||||||
|
|
||||||
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
UseFood(eventArgs.Attacked);
|
UseFood(eventArgs.Attacked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
@@ -58,28 +59,22 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class InsertVerb : Verb<PowerCellChargerComponent>
|
private sealed class InsertVerb : Verb<PowerCellChargerComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, PowerCellChargerComponent component)
|
protected override void GetData(IEntity user, PowerCellChargerComponent component, VerbData data)
|
||||||
{
|
|
||||||
if (!user.TryGetComponent(out HandsComponent handsComponent) || handsComponent.GetActiveHand == null)
|
|
||||||
{
|
|
||||||
return "Insert";
|
|
||||||
}
|
|
||||||
return $"Insert {handsComponent.GetActiveHand.Owner.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, PowerCellChargerComponent component)
|
|
||||||
{
|
{
|
||||||
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
||||||
{
|
{
|
||||||
return VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null)
|
if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null)
|
||||||
{
|
{
|
||||||
return VerbVisibility.Disabled;
|
data.Visibility = VerbVisibility.Disabled;
|
||||||
|
data.Text = "Insert";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerbVisibility.Visible;
|
data.Text = $"Insert {handsComponent.GetActiveHand.Owner.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, PowerCellChargerComponent component)
|
protected override void Activate(IEntity user, PowerCellChargerComponent component)
|
||||||
@@ -102,22 +97,16 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class EjectVerb : Verb<PowerCellChargerComponent>
|
private sealed class EjectVerb : Verb<PowerCellChargerComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, PowerCellChargerComponent component)
|
protected override void GetData(IEntity user, PowerCellChargerComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
if (component._container.ContainedEntity == null)
|
if (component._container.ContainedEntity == null)
|
||||||
{
|
{
|
||||||
return "Eject";
|
data.Text = "Eject";
|
||||||
|
data.Visibility = VerbVisibility.Disabled;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return $"Eject {component._container.ContainedEntity.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, PowerCellChargerComponent component)
|
data.Text = $"Eject {component._container.ContainedEntity.Name}";
|
||||||
{
|
|
||||||
if (component._container.ContainedEntity == null)
|
|
||||||
{
|
|
||||||
return VerbVisibility.Disabled;
|
|
||||||
}
|
|
||||||
return VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, PowerCellChargerComponent component)
|
protected override void Activate(IEntity user, PowerCellChargerComponent component)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan;
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
@@ -48,28 +49,27 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class InsertVerb : Verb<WeaponCapacitorChargerComponent>
|
private sealed class InsertVerb : Verb<WeaponCapacitorChargerComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component)
|
protected override void GetData(IEntity user, WeaponCapacitorChargerComponent component, VerbData data)
|
||||||
{
|
|
||||||
if (!user.TryGetComponent(out HandsComponent handsComponent) || handsComponent.GetActiveHand == null)
|
|
||||||
{
|
|
||||||
return "Insert";
|
|
||||||
}
|
|
||||||
return $"Insert {handsComponent.GetActiveHand.Owner.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component)
|
|
||||||
{
|
{
|
||||||
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
||||||
{
|
{
|
||||||
return VerbVisibility.Invisible;
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null)
|
if (handsComponent.GetActiveHand == null)
|
||||||
{
|
{
|
||||||
return VerbVisibility.Disabled;
|
data.Visibility = VerbVisibility.Disabled;
|
||||||
|
data.Text = "Insert";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerbVisibility.Visible;
|
if (component._container.ContainedEntity != null)
|
||||||
|
{
|
||||||
|
data.Visibility = VerbVisibility.Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.Text = $"Insert {handsComponent.GetActiveHand.Owner.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
|
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
|
||||||
@@ -92,22 +92,16 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
|
|||||||
[Verb]
|
[Verb]
|
||||||
private sealed class EjectVerb : Verb<WeaponCapacitorChargerComponent>
|
private sealed class EjectVerb : Verb<WeaponCapacitorChargerComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component)
|
protected override void GetData(IEntity user, WeaponCapacitorChargerComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
if (component._container.ContainedEntity == null)
|
if (component._container.ContainedEntity == null)
|
||||||
{
|
{
|
||||||
return "Eject";
|
data.Visibility = VerbVisibility.Disabled;
|
||||||
|
data.Text = "Eject";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return $"Eject {component._container.ContainedEntity.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component)
|
data.Text = $"Eject {component._container.ContainedEntity.Name}";
|
||||||
{
|
|
||||||
if (component._container.ContainedEntity == null)
|
|
||||||
{
|
|
||||||
return VerbVisibility.Disabled;
|
|
||||||
}
|
|
||||||
return VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
|
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Content.Shared.Audio;
|
|||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
@@ -12,6 +13,7 @@ using Robust.Shared.Prototypes;
|
|||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Power
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
{
|
{
|
||||||
@@ -126,7 +128,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
var soundCollection = _prototypeManager.Index<SoundCollectionPrototype>("glassbreak");
|
var soundCollection = _prototypeManager.Index<SoundCollectionPrototype>("glassbreak");
|
||||||
var file = _random.Pick(soundCollection.PickFiles);
|
var file = _random.Pick(soundCollection.PickFiles);
|
||||||
|
|
||||||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>().Play(file, Owner);
|
EntitySystem.Get<AudioSystem>().Play(file, Owner);
|
||||||
|
|
||||||
State = LightBulbState.Broken;
|
State = LightBulbState.Broken;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Server.GameObjects.Components.Interactable;
|
|||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Components.Transform;
|
using Robust.Shared.GameObjects.Components.Transform;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.Components.Container;
|
using Robust.Server.GameObjects.Components.Container;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Power
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
{
|
{
|
||||||
@@ -15,8 +17,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
{
|
{
|
||||||
public Powernet()
|
public Powernet()
|
||||||
{
|
{
|
||||||
var EntitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
var powerSystem = EntitySystem.Get<PowerSystem>();
|
||||||
var powerSystem = EntitySystemManager.GetEntitySystem<PowerSystem>();
|
|
||||||
powerSystem.Powernets.Add(this);
|
powerSystem.Powernets.Add(this);
|
||||||
Uid = powerSystem.NewUid();
|
Uid = powerSystem.NewUid();
|
||||||
}
|
}
|
||||||
@@ -374,8 +375,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void RemoveFromSystem()
|
private void RemoveFromSystem()
|
||||||
{
|
{
|
||||||
var EntitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
EntitySystem.Get<PowerSystem>().Powernets.Remove(this);
|
||||||
EntitySystemManager.GetEntitySystem<PowerSystem>().Powernets.Remove(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Registration
|
#region Registration
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -25,6 +26,8 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void AfterAttack(AfterAttackEventArgs eventArgs)
|
public void AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
if(!_mapManager.TryGetGrid(eventArgs.ClickLocation.GridID, out var grid))
|
if(!_mapManager.TryGetGrid(eventArgs.ClickLocation.GridID, out var grid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -62,36 +62,32 @@ namespace Content.Server.GameObjects.Components.Projectiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applys the damage when our projectile collides with its victim
|
/// Applies the damage when our projectile collides with its victim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="collidedwith"></param>
|
/// <param name="entity"></param>
|
||||||
void ICollideBehavior.CollideWith(List<IEntity> collidedwith)
|
void ICollideBehavior.CollideWith(IEntity entity)
|
||||||
{
|
{
|
||||||
foreach (var entity in collidedwith)
|
if (entity.TryGetComponent(out DamageableComponent damage))
|
||||||
{
|
{
|
||||||
if (entity.TryGetComponent(out DamageableComponent damage))
|
Owner.EntityManager.TryGetEntity(Shooter, out var shooter);
|
||||||
|
|
||||||
|
foreach (var (damageType, amount) in _damages)
|
||||||
{
|
{
|
||||||
Owner.EntityManager.TryGetEntity(Shooter, out var shooter);
|
damage.TakeDamage(damageType, amount, Owner, shooter);
|
||||||
|
|
||||||
foreach (var (damageType, amount) in _damages)
|
|
||||||
{
|
|
||||||
|
|
||||||
damage.TakeDamage(damageType, amount, Owner, shooter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entity.Deleted && entity.TryGetComponent(out CameraRecoilComponent recoilComponent)
|
|
||||||
&& Owner.TryGetComponent(out PhysicsComponent physicsComponent))
|
|
||||||
{
|
|
||||||
var direction = physicsComponent.LinearVelocity.Normalized;
|
|
||||||
recoilComponent.Kick(direction);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collidedwith.Count > 0)
|
if (!entity.Deleted && entity.TryGetComponent(out CameraRecoilComponent recoilComponent)
|
||||||
|
&& Owner.TryGetComponent(out PhysicsComponent physicsComponent))
|
||||||
{
|
{
|
||||||
Owner.Delete();
|
var direction = physicsComponent.LinearVelocity.Normalized;
|
||||||
|
recoilComponent.Kick(direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ICollideBehavior.PostCollide(int collideCount)
|
||||||
|
{
|
||||||
|
if (collideCount > 0) Owner.Delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
[Dependency] private readonly IEntitySystemManager _entitySystemManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
private bool _shouldCollide = true;
|
||||||
|
|
||||||
public override string Name => "ThrownItem";
|
public override string Name => "ThrownItem";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -25,32 +27,37 @@ namespace Content.Server.GameObjects.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IEntity User;
|
public IEntity User;
|
||||||
|
|
||||||
void ICollideBehavior.CollideWith(List<IEntity> collidedwith)
|
void ICollideBehavior.CollideWith(IEntity entity)
|
||||||
{
|
{
|
||||||
foreach (var entity in collidedwith)
|
if (!_shouldCollide) return;
|
||||||
|
if (entity.TryGetComponent(out DamageableComponent damage))
|
||||||
{
|
{
|
||||||
if (entity.TryGetComponent(out DamageableComponent damage))
|
damage.TakeDamage(DamageType.Brute, 10, Owner, User);
|
||||||
{
|
|
||||||
damage.TakeDamage(DamageType.Brute, 10, Owner, User);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop colliding with mobs, this mimics not having enough velocity to do damage
|
// Stop colliding with mobs, this mimics not having enough velocity to do damage
|
||||||
// after impacting the first object.
|
// after impacting the first object.
|
||||||
// For realism this should actually be changed when the velocity of the object is less than a threshold.
|
// For realism this should actually be changed when the velocity of the object is less than a threshold.
|
||||||
// This would allow ricochets off walls, and weird gravity effects from slowing the object.
|
// This would allow ricochets off walls, and weird gravity effects from slowing the object.
|
||||||
if (collidedwith.Count > 0 && Owner.TryGetComponent(out CollidableComponent body) && body.PhysicsShapes.Count >= 1)
|
if (Owner.TryGetComponent(out CollidableComponent body) && body.PhysicsShapes.Count >= 1)
|
||||||
|
{
|
||||||
|
_shouldCollide = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostCollide(int collideCount)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (collideCount > 0 && Owner.TryGetComponent(out CollidableComponent body) && body.PhysicsShapes.Count >= 1)
|
||||||
{
|
{
|
||||||
body.PhysicsShapes[0].CollisionMask &= (int)~CollisionGroup.MobImpassable;
|
body.PhysicsShapes[0].CollisionMask &= (int)~CollisionGroup.MobImpassable;
|
||||||
body.IsScrapingFloor = true;
|
|
||||||
|
|
||||||
// KYS, your job is finished. Trigger ILand as well.
|
// KYS, your job is finished. Trigger ILand as well.
|
||||||
|
var physics = Owner.GetComponent<PhysicsComponent>();
|
||||||
|
(physics.Controller as ThrowController).StopThrow();
|
||||||
|
physics.RemoveController();
|
||||||
Owner.RemoveComponent<ThrownItemComponent>();
|
Owner.RemoveComponent<ThrownItemComponent>();
|
||||||
_entitySystemManager.GetEntitySystem<InteractionSystem>().LandInteraction(User, Owner, Owner.Transform.GridPosition);
|
_entitySystemManager.GetEntitySystem<InteractionSystem>().LandInteraction(User, Owner, Owner.Transform.GridPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Random;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public class RandomToolColorComponent : Component, IMapInit
|
||||||
|
{
|
||||||
|
public override string Name => "RandomToolColor";
|
||||||
|
|
||||||
|
private string _selectedColor;
|
||||||
|
private string _baseState;
|
||||||
|
private Dictionary<string, Color> _colors;
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
base.ExposeData(serializer);
|
||||||
|
|
||||||
|
serializer.DataField(ref _selectedColor, "selected", null);
|
||||||
|
serializer.DataField(ref _baseState, "state", "error");
|
||||||
|
serializer.DataFieldCached(ref _colors, "colors", new Dictionary<string, Color>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IMapInit.MapInit()
|
||||||
|
{
|
||||||
|
if (_colors == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var random = IoCManager.Resolve<IRobustRandom>();
|
||||||
|
_selectedColor = random.Pick(_colors.Keys);
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Startup()
|
||||||
|
{
|
||||||
|
base.Startup();
|
||||||
|
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateColor()
|
||||||
|
{
|
||||||
|
if (Owner.TryGetComponent(out SpriteComponent spriteComponent) && _colors != null && _selectedColor != null)
|
||||||
|
{
|
||||||
|
spriteComponent.LayerSetState(0, _baseState);
|
||||||
|
spriteComponent.LayerSetColor(0, _colors[_selectedColor]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ using System.Linq;
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Materials;
|
using Content.Shared.GameObjects.Components.Materials;
|
||||||
using Content.Shared.GameObjects.Components.Power;
|
using Content.Shared.GameObjects.Components.Power;
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
using Content.Shared.GameObjects.Components.Research;
|
||||||
@@ -150,12 +151,13 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
}
|
}
|
||||||
bool IAttackBy.AttackBy(AttackByEventArgs eventArgs)
|
bool IAttackBy.AttackBy(AttackByEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!Owner.TryGetComponent(out MaterialStorageComponent storage)
|
if (!Owner.TryGetComponent(out MaterialStorageComponent storage)
|
||||||
|| !eventArgs.AttackWith.TryGetComponent(out MaterialComponent material)) return false;
|
|| !eventArgs.AttackWith.TryGetComponent(out MaterialComponent material)) return false;
|
||||||
|
|
||||||
var multiplier = 1;
|
var multiplier = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
using Content.Shared.GameObjects.Components.Research;
|
||||||
using Robust.Server.GameObjects.Components.UserInterface;
|
using Robust.Server.GameObjects.Components.UserInterface;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
@@ -60,7 +61,6 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateUserInterface()
|
public void UpdateUserInterface()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.GameObjects.Components.Research;
|
using Content.Shared.GameObjects.Components.Research;
|
||||||
using Content.Shared.Research;
|
using Content.Shared.Research;
|
||||||
@@ -110,6 +111,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenUserInterface(actor.playerSession);
|
OpenUserInterface(actor.playerSession);
|
||||||
PlayKeyboardSound();
|
PlayKeyboardSound();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ using Content.Server.GameObjects.Components.Power;
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Research;
|
using Content.Shared.Research;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Research
|
namespace Content.Server.GameObjects.Components.Research
|
||||||
{
|
{
|
||||||
@@ -73,7 +75,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
Id = ServerCount++;
|
Id = ServerCount++;
|
||||||
IoCManager.Resolve<IEntitySystemManager>()?.GetEntitySystem<ResearchSystem>()?.RegisterServer(this);
|
EntitySystem.Get<ResearchSystem>()?.RegisterServer(this);
|
||||||
Database = Owner.GetComponent<TechnologyDatabaseComponent>();
|
Database = Owner.GetComponent<TechnologyDatabaseComponent>();
|
||||||
Owner.TryGetComponent(out _powerDevice);
|
Owner.TryGetComponent(out _powerDevice);
|
||||||
}
|
}
|
||||||
@@ -82,7 +84,7 @@ namespace Content.Server.GameObjects.Components.Research
|
|||||||
protected override void Shutdown()
|
protected override void Shutdown()
|
||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
IoCManager.Resolve<IEntitySystemManager>()?.GetEntitySystem<ResearchSystem>()?.UnregisterServer(this);
|
EntitySystem.Get<ResearchSystem>()?.UnregisterServer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExposeData(ObjectSerializer serializer)
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
|||||||
@@ -35,16 +35,11 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[Verb]
|
[Verb]
|
||||||
public sealed class RotateVerb : Verb<RotatableComponent>
|
public sealed class RotateVerb : Verb<RotatableComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, RotatableComponent component)
|
protected override void GetData(IEntity user, RotatableComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
return "Rotate clockwise";
|
data.CategoryData = VerbCategories.Rotate;
|
||||||
}
|
data.Text = "Rotate clockwise";
|
||||||
|
data.IconTexture = "/Textures/UserInterface/VerbIcons/rotate_cw.svg.96dpi.png";
|
||||||
protected override string GetCategory(IEntity user, RotatableComponent component) => "Rotate";
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, RotatableComponent component)
|
|
||||||
{
|
|
||||||
return VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, RotatableComponent component)
|
protected override void Activate(IEntity user, RotatableComponent component)
|
||||||
@@ -56,16 +51,11 @@ namespace Content.Server.GameObjects.Components
|
|||||||
[Verb]
|
[Verb]
|
||||||
public sealed class RotateCounterVerb : Verb<RotatableComponent>
|
public sealed class RotateCounterVerb : Verb<RotatableComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, RotatableComponent component)
|
protected override void GetData(IEntity user, RotatableComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
return "Rotate counter-clockwise";
|
data.CategoryData = VerbCategories.Rotate;
|
||||||
}
|
data.Text = "Rotate counter-clockwise";
|
||||||
|
data.IconTexture = "/Textures/UserInterface/VerbIcons/rotate_cw.svg.96dpi.png";
|
||||||
protected override string GetCategory(IEntity user, RotatableComponent component) => "Rotate";
|
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, RotatableComponent component)
|
|
||||||
{
|
|
||||||
return VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, RotatableComponent component)
|
protected override void Activate(IEntity user, RotatableComponent component)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.VendingMachines;
|
using Content.Shared.GameObjects.Components.VendingMachines;
|
||||||
using Content.Shared.VendingMachines;
|
using Content.Shared.VendingMachines;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
@@ -140,7 +141,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
|||||||
for (var i = 0; i < increments; i++)
|
for (var i = 0; i < increments; i++)
|
||||||
{
|
{
|
||||||
var castAngle = new Angle(baseAngle + increment * i);
|
var castAngle = new Angle(baseAngle + increment * i);
|
||||||
var res = _physicsManager.IntersectRay(mapId, new CollisionRay(position, castAngle.ToVec(), 23), _range, ignore, ignoreNonHardCollidables: true);
|
var res = _physicsManager.IntersectRay(mapId, new CollisionRay(position, castAngle.ToVec(), 23), _range, ignore).First();
|
||||||
if (res.HitEntity != null)
|
if (res.HitEntity != null)
|
||||||
{
|
{
|
||||||
resSet.Add(res.HitEntity);
|
resSet.Add(res.HitEntity);
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
@@ -9,6 +11,7 @@ using Robust.Server.GameObjects.EntitySystems;
|
|||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.EntitySystemMessages;
|
using Robust.Shared.GameObjects.EntitySystemMessages;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Physics;
|
using Robust.Shared.Interfaces.Physics;
|
||||||
using Robust.Shared.Interfaces.Timing;
|
using Robust.Shared.Interfaces.Timing;
|
||||||
@@ -17,6 +20,7 @@ using Robust.Shared.Map;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
||||||
{
|
{
|
||||||
@@ -90,10 +94,13 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
|||||||
var angle = new Angle(clickLocation.Position - userPosition);
|
var angle = new Angle(clickLocation.Position - userPosition);
|
||||||
|
|
||||||
var ray = new CollisionRay(userPosition, angle.ToVec(), (int)(CollisionGroup.Impassable | CollisionGroup.MobImpassable));
|
var ray = new CollisionRay(userPosition, angle.ToVec(), (int)(CollisionGroup.Impassable | CollisionGroup.MobImpassable));
|
||||||
var rayCastResults = IoCManager.Resolve<IPhysicsManager>().IntersectRay(user.Transform.MapID, ray, MaxLength, user, ignoreNonHardCollidables: true);
|
var rayCastResults = IoCManager.Resolve<IPhysicsManager>().IntersectRay(user.Transform.MapID, ray, MaxLength, user).ToList();
|
||||||
|
|
||||||
Hit(rayCastResults, energyModifier, user);
|
if (rayCastResults.Count == 1)
|
||||||
AfterEffects(user, rayCastResults, angle, energyModifier);
|
{
|
||||||
|
Hit(rayCastResults[0], energyModifier, user);
|
||||||
|
AfterEffects(user, rayCastResults[0], angle, energyModifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Hit(RayCastResults ray, float damageModifier, IEntity user = null)
|
protected virtual void Hit(RayCastResults ray, float damageModifier, IEntity user = null)
|
||||||
@@ -109,7 +116,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
|||||||
protected virtual void AfterEffects(IEntity user, RayCastResults ray, Angle angle, float energyModifier)
|
protected virtual void AfterEffects(IEntity user, RayCastResults ray, Angle angle, float energyModifier)
|
||||||
{
|
{
|
||||||
var time = IoCManager.Resolve<IGameTiming>().CurTime;
|
var time = IoCManager.Resolve<IGameTiming>().CurTime;
|
||||||
var dist = ray.DidHitObject ? ray.Distance : MaxLength;
|
var dist = ray.Distance;
|
||||||
var offset = angle.ToVec() * dist / 2;
|
var offset = angle.ToVec() * dist / 2;
|
||||||
var message = new EffectSystemMessage
|
var message = new EffectSystemMessage
|
||||||
{
|
{
|
||||||
@@ -125,8 +132,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
|||||||
|
|
||||||
Shaded = false
|
Shaded = false
|
||||||
};
|
};
|
||||||
var mgr = IoCManager.Resolve<IEntitySystemManager>();
|
EntitySystem.Get<EffectSystem>().CreateParticle(message);
|
||||||
mgr.GetEntitySystem<EffectSystem>().CreateParticle(message);
|
|
||||||
Owner.GetComponent<SoundComponent>().Play(_fireSound, AudioParams.Default.WithVolume(-5));
|
Owner.GetComponent<SoundComponent>().Play(_fireSound, AudioParams.Default.WithVolume(-5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.GameObjects.Components.Sound;
|
using Content.Server.GameObjects.Components.Sound;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
using Content.Shared.GameObjects.Components.Weapons.Ranged;
|
||||||
using Content.Shared.Interfaces;
|
using Content.Shared.Interfaces;
|
||||||
@@ -266,14 +267,16 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
|
|||||||
[Verb]
|
[Verb]
|
||||||
public sealed class EjectMagazineVerb : Verb<BallisticMagazineWeaponComponent>
|
public sealed class EjectMagazineVerb : Verb<BallisticMagazineWeaponComponent>
|
||||||
{
|
{
|
||||||
protected override string GetText(IEntity user, BallisticMagazineWeaponComponent component)
|
protected override void GetData(IEntity user, BallisticMagazineWeaponComponent component, VerbData data)
|
||||||
{
|
{
|
||||||
return component.Magazine == null ? "Eject magazine (magazine missing)" : "Eject magazine";
|
if (component.Magazine == null)
|
||||||
}
|
{
|
||||||
|
data.Text = "Eject magazine (magazine missing)";
|
||||||
|
data.Visibility = VerbVisibility.Disabled;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
protected override VerbVisibility GetVisibility(IEntity user, BallisticMagazineWeaponComponent component)
|
data.Text = "Eject magazine";
|
||||||
{
|
|
||||||
return component.Magazine == null ? VerbVisibility.Disabled : VerbVisibility.Visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Activate(IEntity user, BallisticMagazineWeaponComponent component)
|
protected override void Activate(IEntity user, BallisticMagazineWeaponComponent component)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Content.Server.GameObjects.Components.VendingMachines;
|
|||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components;
|
using Content.Shared.GameObjects.Components;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -14,6 +15,7 @@ using Robust.Server.GameObjects.Components.UserInterface;
|
|||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Server.Interfaces.Player;
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Random;
|
using Robust.Shared.Interfaces.Random;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
@@ -21,6 +23,7 @@ using Robust.Shared.Localization;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components
|
namespace Content.Server.GameObjects.Components
|
||||||
{
|
{
|
||||||
@@ -109,7 +112,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
_audioSystem = EntitySystem.Get<AudioSystem>();
|
||||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
_appearance = Owner.GetComponent<AppearanceComponent>();
|
||||||
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen);
|
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen);
|
||||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
||||||
@@ -236,8 +239,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var interactionSystem = IoCManager.Resolve<EntitySystemManager>().GetEntitySystem<InteractionSystem>();
|
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(player.Transform.MapPosition, Owner.Transform.WorldPosition, ignoredEnt: Owner))
|
||||||
if (!interactionSystem.InRangeUnobstructed(player.Transform.MapPosition, Owner.Transform.WorldPosition, ignoredEnt: Owner))
|
|
||||||
{
|
{
|
||||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You can't reach there!"));
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You can't reach there!"));
|
||||||
return;
|
return;
|
||||||
@@ -304,8 +306,7 @@ namespace Content.Server.GameObjects.Components
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
IsPanelOpen = !IsPanelOpen;
|
IsPanelOpen = !IsPanelOpen;
|
||||||
IoCManager.Resolve<IEntitySystemManager>()
|
EntitySystem.Get<AudioSystem>()
|
||||||
.GetEntitySystem<AudioSystem>()
|
|
||||||
.Play(IsPanelOpen ? "/Audio/machines/screwdriveropen.ogg" : "/Audio/machines/screwdriverclose.ogg", Owner);
|
.Play(IsPanelOpen ? "/Audio/machines/screwdriveropen.ogg" : "/Audio/machines/screwdriverclose.ogg", Owner);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Robust.Shared.GameObjects.Systems;
|
|||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Reflection;
|
using Robust.Shared.Interfaces.Reflection;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -101,7 +102,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
var processorId = args[0];
|
var processorId = args[0];
|
||||||
var entId = new EntityUid(int.Parse(args[1]));
|
var entId = new EntityUid(int.Parse(args[1]));
|
||||||
var ent = IoCManager.Resolve<IEntityManager>().GetEntity(entId);
|
var ent = IoCManager.Resolve<IEntityManager>().GetEntity(entId);
|
||||||
var aiSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AiSystem>();
|
var aiSystem = EntitySystem.Get<AiSystem>();
|
||||||
|
|
||||||
if (!aiSystem.ProcessorTypeExists(processorId))
|
if (!aiSystem.ProcessorTypeExists(processorId))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.Interactable;
|
using Content.Server.GameObjects.Components.Interactable;
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Timing;
|
using Content.Server.GameObjects.Components.Timing;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
@@ -21,6 +21,7 @@ using Robust.Shared.Interfaces.GameObjects.Components;
|
|||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
using Robust.Shared.Interfaces.Physics;
|
using Robust.Shared.Interfaces.Physics;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
@@ -30,36 +31,53 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This interface gives components behavior when being clicked on or "attacked" by a user with an object in their hand
|
/// This interface gives components behavior when being clicked on or "attacked" by a user with an object in their hand
|
||||||
|
/// who is in range and has unobstructed reach of the target entity (allows inside blockers).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAttackBy
|
public interface IAttackBy
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when using one object on another
|
/// Called when using one object on another when user is in range of the target entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool AttackBy(AttackByEventArgs eventArgs);
|
bool AttackBy(AttackByEventArgs eventArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AttackByEventArgs : EventArgs
|
public class AttackByEventArgs : EventArgs, ITargetedAttackEventArgs
|
||||||
{
|
{
|
||||||
public IEntity User { get; set; }
|
public IEntity User { get; set; }
|
||||||
public GridCoordinates ClickLocation { get; set; }
|
public GridCoordinates ClickLocation { get; set; }
|
||||||
public IEntity AttackWith { get; set; }
|
public IEntity AttackWith { get; set; }
|
||||||
|
public IEntity Attacked { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITargetedAttackEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Performer of the attack
|
||||||
|
/// </summary>
|
||||||
|
IEntity User { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// Target of the attack
|
||||||
|
/// </summary>
|
||||||
|
IEntity Attacked { get; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This interface gives components behavior when being clicked on or "attacked" by a user with an empty hand
|
/// This interface gives components behavior when being clicked on or "attacked" by a user with an empty hand
|
||||||
|
/// who is in range and has unobstructed reach of the target entity (allows inside blockers).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAttackHand
|
public interface IAttackHand
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when a player directly interacts with an empty hand
|
/// Called when a player directly interacts with an empty hand when user is in range of the target entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool AttackHand(AttackHandEventArgs eventArgs);
|
bool AttackHand(AttackHandEventArgs eventArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AttackHandEventArgs : EventArgs
|
public class AttackHandEventArgs : EventArgs, ITargetedAttackEventArgs
|
||||||
{
|
{
|
||||||
public IEntity User { get; set; }
|
public IEntity User { get; set; }
|
||||||
|
public IEntity Attacked { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -83,8 +101,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This interface gives components a behavior when clicking on another object and no interaction occurs
|
/// This interface gives components a behavior when clicking on another object and no interaction occurs,
|
||||||
/// Doesn't pass what you clicked on as an argument, but if it becomes necessary we can add it later
|
/// at any range.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAfterAttack
|
public interface IAfterAttack
|
||||||
{
|
{
|
||||||
@@ -119,19 +137,21 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This interface gives components behavior when being activated in the world.
|
/// This interface gives components behavior when being activated in the world when the user
|
||||||
|
/// is in range and has unobstructed access to the target entity (allows inside blockers).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IActivate
|
public interface IActivate
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when this component is activated by another entity.
|
/// Called when this component is activated by another entity who is in range.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Activate(ActivateEventArgs eventArgs);
|
void Activate(ActivateEventArgs eventArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ActivateEventArgs : EventArgs
|
public class ActivateEventArgs : EventArgs, ITargetedAttackEventArgs
|
||||||
{
|
{
|
||||||
public IEntity User { get; set; }
|
public IEntity User { get; set; }
|
||||||
|
public IEntity Attacked { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -295,6 +315,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IMapManager _mapManager;
|
[Dependency] private readonly IMapManager _mapManager;
|
||||||
[Dependency] private readonly IPhysicsManager _physicsManager;
|
[Dependency] private readonly IPhysicsManager _physicsManager;
|
||||||
|
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
public const float InteractionRange = 2;
|
public const float InteractionRange = 2;
|
||||||
@@ -362,7 +383,12 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
activateComp.Activate(new ActivateEventArgs {User = user});
|
// all activates should only fire when in range / unbostructed
|
||||||
|
var activateEventArgs = new ActivateEventArgs {User = user, Attacked = used};
|
||||||
|
if (InteractionChecks.InRangeUnobstructed(activateEventArgs))
|
||||||
|
{
|
||||||
|
activateComp.Activate(activateEventArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandleWideAttack(ICommonSession session, GridCoordinates coords, EntityUid uid)
|
private bool HandleWideAttack(ICommonSession session, GridCoordinates coords, EntityUid uid)
|
||||||
@@ -559,14 +585,20 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
var attackBys = attacked.GetAllComponents<IAttackBy>().ToList();
|
var attackBys = attacked.GetAllComponents<IAttackBy>().ToList();
|
||||||
var attackByEventArgs = new AttackByEventArgs
|
var attackByEventArgs = new AttackByEventArgs
|
||||||
{
|
{
|
||||||
User = user, ClickLocation = clickLocation, AttackWith = weapon
|
User = user, ClickLocation = clickLocation, AttackWith = weapon, Attacked = attacked
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var attackBy in attackBys)
|
// all AttackBys should only happen when in range / unobstructed, so no range check is needed
|
||||||
|
if (InteractionChecks.InRangeUnobstructed(attackByEventArgs))
|
||||||
{
|
{
|
||||||
if (attackBy.AttackBy(attackByEventArgs))
|
foreach (var attackBy in attackBys)
|
||||||
// If an AttackBy returns a status completion we finish our attack
|
{
|
||||||
return;
|
if (attackBy.AttackBy(attackByEventArgs))
|
||||||
|
{
|
||||||
|
// If an AttackBy returns a status completion we finish our attack
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var afterAtkMsg = new AfterAttackMessage(user, weapon, attacked, clickLocation);
|
var afterAtkMsg = new AfterAttackMessage(user, weapon, attacked, clickLocation);
|
||||||
@@ -603,14 +635,18 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
}
|
}
|
||||||
|
|
||||||
var attackHands = attacked.GetAllComponents<IAttackHand>().ToList();
|
var attackHands = attacked.GetAllComponents<IAttackHand>().ToList();
|
||||||
var attackHandEventArgs = new AttackHandEventArgs {User = user};
|
var attackHandEventArgs = new AttackHandEventArgs {User = user, Attacked = attacked};
|
||||||
|
|
||||||
foreach (var attackHand in attackHands)
|
// all attackHands should only fire when in range / unbostructed
|
||||||
|
if (InteractionChecks.InRangeUnobstructed(attackHandEventArgs))
|
||||||
{
|
{
|
||||||
if (attackHand.AttackHand(attackHandEventArgs))
|
foreach (var attackHand in attackHands)
|
||||||
{
|
{
|
||||||
// If an AttackHand returns a status completion we finish our attack
|
if (attackHand.AttackHand(attackHandEventArgs))
|
||||||
return;
|
{
|
||||||
|
// If an AttackHand returns a status completion we finish our attack
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ using Robust.Shared.Map;
|
|||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -105,7 +106,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
if (!TryGetAttachedComponent(session as IPlayerSession, out HandsComponent handsComp))
|
if (!TryGetAttachedComponent(session as IPlayerSession, out HandsComponent handsComp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var interactionSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<InteractionSystem>();
|
var interactionSystem = EntitySystem.Get<InteractionSystem>();
|
||||||
|
|
||||||
var oldItem = handsComp.GetActiveHand;
|
var oldItem = handsComp.GetActiveHand;
|
||||||
|
|
||||||
@@ -133,9 +134,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
if (handsComp.GetActiveHand == null)
|
if (handsComp.GetActiveHand == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var interactionSystem = _entitySystemManager.GetEntitySystem<InteractionSystem>();
|
|
||||||
|
|
||||||
if(interactionSystem.InRangeUnobstructed(coords.ToMap(_mapManager), ent.Transform.WorldPosition, ignoredEnt: ent))
|
if(EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(coords.ToMap(_mapManager), ent.Transform.WorldPosition, ignoredEnt: ent))
|
||||||
if (coords.InRange(_mapManager, ent.Transform.GridPosition, InteractionSystem.InteractionRange))
|
if (coords.InRange(_mapManager, ent.Transform.GridPosition, InteractionSystem.InteractionRange))
|
||||||
{
|
{
|
||||||
handsComp.Drop(handsComp.ActiveIndex, coords);
|
handsComp.Drop(handsComp.ActiveIndex, coords);
|
||||||
|
|||||||
25
Content.Server/GameObjects/EntitySystems/InstrumentSystem.cs
Normal file
25
Content.Server/GameObjects/EntitySystems/InstrumentSystem.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using Content.Server.GameObjects.Components.Instruments;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
|
{
|
||||||
|
public class InstrumentSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
EntityQuery = new TypeEntityQuery(typeof(InstrumentComponent));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
foreach (var entity in RelevantEntities)
|
||||||
|
{
|
||||||
|
entity.GetComponent<InstrumentComponent>().Update(frameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ using Content.Server.Observer;
|
|||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.GameObjects.Components.Inventory;
|
using Content.Shared.GameObjects.Components.Inventory;
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
|
using Content.Shared.Physics;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
@@ -148,7 +149,13 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
|
|
||||||
private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null)
|
private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null)
|
||||||
{
|
{
|
||||||
bool weightless = false;
|
if (physics.Controller == null)
|
||||||
|
{
|
||||||
|
// Set up controller
|
||||||
|
physics.SetController<MoverController>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var weightless = false;
|
||||||
|
|
||||||
var tile = _mapManager.GetGrid(transform.GridID).GetTileRef(transform.GridPosition).Tile;
|
var tile = _mapManager.GetGrid(transform.GridID).GetTileRef(transform.GridPosition).Tile;
|
||||||
|
|
||||||
@@ -167,27 +174,27 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
&& !entity.HasComponent<ItemComponent>(); // This can't be an item
|
&& !entity.HasComponent<ItemComponent>(); // This can't be an item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!touching)
|
if (!touching)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner))
|
|
||||||
{
|
|
||||||
if (physics.LinearVelocity != Vector2.Zero)
|
|
||||||
physics.LinearVelocity = Vector2.Zero;
|
|
||||||
|
|
||||||
|
if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless)
|
||||||
|
{
|
||||||
|
(physics.Controller as MoverController)?.StopMoving();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (weightless)
|
if (weightless)
|
||||||
{
|
{
|
||||||
physics.LinearVelocity = mover.VelocityDir * mover.CurrentPushSpeed;
|
(physics.Controller as MoverController)?.Push(mover.VelocityDir, mover.CurrentPushSpeed);
|
||||||
transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();
|
transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
(physics.Controller as MoverController)?.Move(mover.VelocityDir,
|
||||||
physics.LinearVelocity = mover.VelocityDir * (mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed);
|
mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed);
|
||||||
transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();
|
transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle();
|
||||||
|
|
||||||
// Handle footsteps.
|
// Handle footsteps.
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
{
|
{
|
||||||
public class VerbSystem : EntitySystem
|
public class VerbSystem : EntitySystem
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IEntityManager _entityManager;
|
[Dependency] private readonly IEntityManager _entityManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -90,19 +90,19 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
|
|
||||||
var userEntity = player.AttachedEntity;
|
var userEntity = player.AttachedEntity;
|
||||||
|
|
||||||
var data = new List<VerbsResponseMessage.VerbData>();
|
var data = new List<VerbsResponseMessage.NetVerbData>();
|
||||||
//Get verbs, component dependent.
|
//Get verbs, component dependent.
|
||||||
foreach (var (component, verb) in VerbUtility.GetVerbs(entity))
|
foreach (var (component, verb) in VerbUtility.GetVerbs(entity))
|
||||||
{
|
{
|
||||||
if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
|
if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
|
||||||
continue;
|
continue;
|
||||||
if (VerbUtility.IsVerbInvisible(verb, userEntity, component, out var vis))
|
|
||||||
|
var verbData = verb.GetData(userEntity, component);
|
||||||
|
if (verbData.IsInvisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// TODO: These keys being giant strings is inefficient as hell.
|
// TODO: These keys being giant strings is inefficient as hell.
|
||||||
data.Add(new VerbsResponseMessage.VerbData(verb.GetText(userEntity, component),
|
data.Add(new VerbsResponseMessage.NetVerbData(verbData, $"{component.GetType()}:{verb.GetType()}"));
|
||||||
$"{component.GetType()}:{verb.GetType()}", verb.GetCategory(userEntity, component),
|
|
||||||
vis == VerbVisibility.Visible));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get global verbs. Visible for all entities regardless of their components.
|
//Get global verbs. Visible for all entities regardless of their components.
|
||||||
@@ -110,14 +110,15 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
{
|
{
|
||||||
if (globalVerb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
|
if (globalVerb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
|
||||||
continue;
|
continue;
|
||||||
if (VerbUtility.IsVerbInvisible(globalVerb, userEntity, entity, out var vis))
|
|
||||||
|
var verbData = globalVerb.GetData(userEntity, entity);
|
||||||
|
if (verbData.IsInvisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
data.Add(new VerbsResponseMessage.VerbData(globalVerb.GetText(userEntity, entity),
|
data.Add(new VerbsResponseMessage.NetVerbData(verbData, globalVerb.GetType().ToString()));
|
||||||
globalVerb.GetType().ToString(), globalVerb.GetCategory(userEntity, entity), vis == VerbVisibility.Visible));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = new VerbsResponseMessage(data, req.EntityUid);
|
var response = new VerbsResponseMessage(data.ToArray(), req.EntityUid);
|
||||||
RaiseNetworkEvent(response, player.ConnectedClient);
|
RaiseNetworkEvent(response, player.ConnectedClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,64 @@
|
|||||||
using Content.Server.GameObjects;
|
|
||||||
using Content.Server.GameObjects.Components.Mobs;
|
using Content.Server.GameObjects.Components.Mobs;
|
||||||
using Content.Server.GameObjects.Components.Nutrition;
|
|
||||||
using Content.Server.GameObjects.Components.Observer;
|
using Content.Server.GameObjects.Components.Observer;
|
||||||
using Content.Server.Players;
|
using Content.Server.Players;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Robust.Server.Console;
|
using Robust.Server.Console;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Log;
|
|
||||||
|
|
||||||
namespace Content.Server.GlobalVerbs
|
namespace Content.Server.GlobalVerbs
|
||||||
{
|
{
|
||||||
[GlobalVerb]
|
[GlobalVerb]
|
||||||
public class ControlMobVerb : GlobalVerb
|
public class ControlMobVerb : GlobalVerb
|
||||||
{
|
{
|
||||||
public override string GetText(IEntity user, IEntity target) => "Control Mob";
|
|
||||||
public override string GetCategory(IEntity user, IEntity target) => "Debug";
|
|
||||||
|
|
||||||
public override bool RequireInteractionRange => false;
|
public override bool RequireInteractionRange => false;
|
||||||
|
|
||||||
public override VerbVisibility GetVisibility(IEntity user, IEntity target)
|
public override void GetData(IEntity user, IEntity target, VerbData data)
|
||||||
{
|
{
|
||||||
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
|
||||||
var groupController = IoCManager.Resolve<IConGroupController>();
|
var groupController = IoCManager.Resolve<IConGroupController>();
|
||||||
if (user == target) return VerbVisibility.Invisible;
|
if (user == target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (user.TryGetComponent<IActorComponent>(out var player))
|
if (user.TryGetComponent<IActorComponent>(out var player))
|
||||||
{
|
{
|
||||||
if (!user.HasComponent<MindComponent>() || !target.HasComponent<MindComponent>())
|
if (!user.HasComponent<MindComponent>() || !target.HasComponent<MindComponent>())
|
||||||
return VerbVisibility.Invisible;
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (groupController.CanCommand(player.playerSession, "controlmob"))
|
if (groupController.CanCommand(player.playerSession, "controlmob"))
|
||||||
return VerbVisibility.Visible;
|
{
|
||||||
|
data.Visibility = VerbVisibility.Visible;
|
||||||
|
data.Text = "Control Mob";
|
||||||
|
data.CategoryData = VerbCategories.Debug;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerbVisibility.Invisible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Activate(IEntity user, IEntity target)
|
public override void Activate(IEntity user, IEntity target)
|
||||||
{
|
{
|
||||||
var userMind = user.GetComponent<IActorComponent>().playerSession.ContentData().Mind;
|
var groupController = IoCManager.Resolve<IConGroupController>();
|
||||||
|
|
||||||
|
var player = user.GetComponent<IActorComponent>().playerSession;
|
||||||
|
if (!groupController.CanCommand(player, "controlmob"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var userMind = player.ContentData().Mind;
|
||||||
|
|
||||||
var targetMind = target.GetComponent<MindComponent>();
|
var targetMind = target.GetComponent<MindComponent>();
|
||||||
var oldEntity = userMind.CurrentEntity;
|
var oldEntity = userMind.CurrentEntity;
|
||||||
|
|
||||||
targetMind.Mind?.TransferTo(null);
|
targetMind.Mind?.TransferTo(null);
|
||||||
userMind.TransferTo(target);
|
userMind.TransferTo(target);
|
||||||
|
|
||||||
if(oldEntity.HasComponent<GhostComponent>())
|
if (oldEntity.HasComponent<GhostComponent>())
|
||||||
oldEntity.Delete();
|
oldEntity.Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,24 +14,29 @@ namespace Content.Server.GlobalVerbs
|
|||||||
[GlobalVerb]
|
[GlobalVerb]
|
||||||
class RejuvenateVerb : GlobalVerb
|
class RejuvenateVerb : GlobalVerb
|
||||||
{
|
{
|
||||||
public override string GetText(IEntity user, IEntity target) => "Rejuvenate";
|
|
||||||
public override string GetCategory(IEntity user, IEntity target) => "Debug";
|
|
||||||
|
|
||||||
public override bool RequireInteractionRange => false;
|
public override bool RequireInteractionRange => false;
|
||||||
|
|
||||||
public override VerbVisibility GetVisibility(IEntity user, IEntity target)
|
public override void GetData(IEntity user, IEntity target, VerbData data)
|
||||||
{
|
{
|
||||||
|
data.Text = "Rejuvenate";
|
||||||
|
data.CategoryData = VerbCategories.Debug;
|
||||||
|
data.Visibility = VerbVisibility.Invisible;
|
||||||
|
|
||||||
var groupController = IoCManager.Resolve<IConGroupController>();
|
var groupController = IoCManager.Resolve<IConGroupController>();
|
||||||
|
|
||||||
if (user.TryGetComponent<IActorComponent>(out var player))
|
if (user.TryGetComponent<IActorComponent>(out var player))
|
||||||
{
|
{
|
||||||
if (!target.HasComponent<DamageableComponent>() && !target.HasComponent<HungerComponent>() && !target.HasComponent<ThirstComponent>())
|
if (!target.HasComponent<DamageableComponent>() && !target.HasComponent<HungerComponent>() &&
|
||||||
return VerbVisibility.Invisible;
|
!target.HasComponent<ThirstComponent>())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (groupController.CanCommand(player.playerSession, "rejuvenate"))
|
if (groupController.CanCommand(player.playerSession, "rejuvenate"))
|
||||||
return VerbVisibility.Visible;
|
{
|
||||||
|
data.Visibility = VerbVisibility.Visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return VerbVisibility.Invisible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Activate(IEntity user, IEntity target)
|
public override void Activate(IEntity user, IEntity target)
|
||||||
@@ -42,7 +47,6 @@ namespace Content.Server.GlobalVerbs
|
|||||||
if (groupController.CanCommand(player.playerSession, "rejuvenate"))
|
if (groupController.CanCommand(player.playerSession, "rejuvenate"))
|
||||||
PerformRejuvenate(target);
|
PerformRejuvenate(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public static void PerformRejuvenate(IEntity target)
|
public static void PerformRejuvenate(IEntity target)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.BodySystem;
|
using Content.Shared.BodySystem;
|
||||||
|
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ namespace Content.Server.BodySystem
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor.playerSession.AttachedEntity.TryGetComponent(out BodyManagerComponent attempt))
|
if (actor.playerSession.AttachedEntity.TryGetComponent(out BodyManagerComponent attempt))
|
||||||
{
|
{
|
||||||
_userInterface.SetState(PrepareBodyScannerInterfaceState(attempt.Template, attempt.PartDictionary));
|
_userInterface.SetState(PrepareBodyScannerInterfaceState(attempt.Template, attempt.PartDictionary));
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.BodySystem;
|
using Content.Server.BodySystem;
|
||||||
using Content.Server.GameObjects.EntitySystems;
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Server.Utility;
|
||||||
using Content.Shared.BodySystem;
|
using Content.Shared.BodySystem;
|
||||||
using Content.Shared.GameObjects;
|
using Content.Shared.GameObjects;
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
@@ -42,6 +43,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
|||||||
|
|
||||||
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
void IAfterAttack.AfterAttack(AfterAttackEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs)) return;
|
||||||
|
|
||||||
if (eventArgs.Attacked == null)
|
if (eventArgs.Attacked == null)
|
||||||
return;
|
return;
|
||||||
if (eventArgs.Attacked.TryGetComponent<BodySystem.BodyManagerComponent>(out BodySystem.BodyManagerComponent bodyManager))
|
if (eventArgs.Attacked.TryGetComponent<BodySystem.BodyManagerComponent>(out BodySystem.BodyManagerComponent bodyManager))
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace Content.Server.Throw
|
|||||||
|
|
||||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||||
|
|
||||||
colComp.CollisionEnabled = true;
|
colComp.CanCollide = true;
|
||||||
// I can now collide with player, so that i can do damage.
|
// I can now collide with player, so that i can do damage.
|
||||||
|
|
||||||
if (!thrownEnt.TryGetComponent(out ThrownItemComponent projComp))
|
if (!thrownEnt.TryGetComponent(out ThrownItemComponent projComp))
|
||||||
@@ -37,7 +37,7 @@ namespace Content.Server.Throw
|
|||||||
colComp.PhysicsShapes.Add(new PhysShapeAabb());
|
colComp.PhysicsShapes.Add(new PhysShapeAabb());
|
||||||
|
|
||||||
colComp.PhysicsShapes[0].CollisionMask |= (int) (CollisionGroup.MobImpassable | CollisionGroup.Impassable);
|
colComp.PhysicsShapes[0].CollisionMask |= (int) (CollisionGroup.MobImpassable | CollisionGroup.Impassable);
|
||||||
colComp.IsScrapingFloor = false;
|
colComp.Status = BodyStatus.InAir;
|
||||||
}
|
}
|
||||||
var angle = new Angle(targetLoc.ToMapPos(mapManager) - sourceLoc.ToMapPos(mapManager));
|
var angle = new Angle(targetLoc.ToMapPos(mapManager) - sourceLoc.ToMapPos(mapManager));
|
||||||
|
|
||||||
@@ -58,20 +58,16 @@ namespace Content.Server.Throw
|
|||||||
if (!thrownEnt.TryGetComponent(out PhysicsComponent physComp))
|
if (!thrownEnt.TryGetComponent(out PhysicsComponent physComp))
|
||||||
physComp = thrownEnt.AddComponent<PhysicsComponent>();
|
physComp = thrownEnt.AddComponent<PhysicsComponent>();
|
||||||
|
|
||||||
// TODO: Move this into PhysicsSystem, we need an ApplyForce function.
|
|
||||||
var a = throwForce / (float) Math.Max(0.001, physComp.Mass); // a = f / m
|
|
||||||
|
|
||||||
var timing = IoCManager.Resolve<IGameTiming>();
|
var timing = IoCManager.Resolve<IGameTiming>();
|
||||||
var spd = a / (1f / timing.TickRate); // acceleration is applied in 1 tick instead of 1 second, scale appropriately
|
var spd = throwForce / (1f / timing.TickRate); // acceleration is applied in 1 tick instead of 1 second, scale appropriately
|
||||||
|
|
||||||
physComp.LinearVelocity = angle.ToVec() * spd;
|
physComp.SetController<ThrowController>();
|
||||||
|
(physComp.Controller as ThrowController)?.StartThrow(angle.ToVec() * spd);
|
||||||
|
|
||||||
if (throwSourceEnt != null)
|
if (throwSourceEnt != null && throwSourceEnt.TryGetComponent<PhysicsComponent>(out var physics))
|
||||||
{
|
{
|
||||||
var p = throwSourceEnt.GetComponent<PhysicsComponent>();
|
const float ThrowFactor = 5.0f; // Break Newton's Third Law for better gameplay
|
||||||
var playerAccel = 5 * throwForce / (float) Math.Max(0.001, p.Mass);
|
(physics.Controller as MoverController)?.Push(-angle.ToVec(), spd * ThrowFactor / physics.Mass);
|
||||||
p.LinearVelocity = Angle.FromDegrees(angle.Degrees + 180).ToVec()
|
|
||||||
* playerAccel / (1f / timing.TickRate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
100
Content.Server/Utility/InteractionChecks.cs
Normal file
100
Content.Server/Utility/InteractionChecks.cs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.Interfaces;
|
||||||
|
using Content.Shared.Physics;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.Map;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Server.Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Convenient methods for checking for various conditions commonly needed
|
||||||
|
/// for interactions.
|
||||||
|
/// </summary>
|
||||||
|
public static class InteractionChecks
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default interaction check for targeted attack interaction types.
|
||||||
|
/// Same as <see cref="SharedInteractionSystem.InRangeUnobstructed"/>, but defaults to allow inside blockers.
|
||||||
|
/// Validates that attacker is in range of the attacked entity. Additionally shows a popup if
|
||||||
|
/// validation fails.
|
||||||
|
/// </summary>
|
||||||
|
public static bool InRangeUnobstructed(ITargetedAttackEventArgs eventArgs, bool insideBlockerValid = true)
|
||||||
|
{
|
||||||
|
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(eventArgs.User.Transform.MapPosition,
|
||||||
|
eventArgs.Attacked.Transform.WorldPosition, ignoredEnt: eventArgs.Attacked, insideBlockerValid: insideBlockerValid))
|
||||||
|
{
|
||||||
|
var localizationManager = IoCManager.Resolve<ILocalizationManager>();
|
||||||
|
eventArgs.Attacked.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default interaction check for after attack interaction types.
|
||||||
|
/// Same as <see cref="SharedInteractionSystem.InRangeUnobstructed"/>, but defaults to allow inside blockers.
|
||||||
|
/// Validates that attacker is in range of the attacked entity, if there is such an entity.
|
||||||
|
/// If there is no attacked entity, validates that they are in range of the clicked position.
|
||||||
|
/// Additionally shows a popup if validation fails.
|
||||||
|
/// </summary>
|
||||||
|
public static bool InRangeUnobstructed(AfterAttackEventArgs eventArgs, bool insideBlockerValid = true)
|
||||||
|
{
|
||||||
|
if (eventArgs.Attacked != null)
|
||||||
|
{
|
||||||
|
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(eventArgs.User.Transform.MapPosition,
|
||||||
|
eventArgs.Attacked.Transform.WorldPosition, ignoredEnt: eventArgs.Attacked, insideBlockerValid: insideBlockerValid))
|
||||||
|
{
|
||||||
|
var localizationManager = IoCManager.Resolve<ILocalizationManager>();
|
||||||
|
eventArgs.Attacked.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||||
|
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(eventArgs.User.Transform.MapPosition,
|
||||||
|
eventArgs.ClickLocation.ToMapPos(mapManager), ignoredEnt: eventArgs.User, insideBlockerValid: insideBlockerValid))
|
||||||
|
{
|
||||||
|
var localizationManager = IoCManager.Resolve<ILocalizationManager>();
|
||||||
|
eventArgs.User.PopupMessage(eventArgs.User, localizationManager.GetString("You can't reach there!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convenient static alternative to <see cref="SharedInteractionSystem.InRangeUnobstructed"/>, which also
|
||||||
|
/// shows a popup message if not in range.
|
||||||
|
/// </summary>
|
||||||
|
public static bool InRangeUnobstructed(IEntity user, Vector2 targetWorldCoords,
|
||||||
|
float range = SharedInteractionSystem.InteractionRange,
|
||||||
|
int collisionMask = (int) CollisionGroup.Impassable, IEntity ignoredEnt = null,
|
||||||
|
bool insideBlockerValid = false)
|
||||||
|
{
|
||||||
|
var interactionSystem = EntitySystem.Get<SharedInteractionSystem>();
|
||||||
|
if (!interactionSystem.InRangeUnobstructed(user.Transform.MapPosition, targetWorldCoords, range, collisionMask,
|
||||||
|
ignoredEnt, insideBlockerValid))
|
||||||
|
{
|
||||||
|
var localizationManager = IoCManager.Resolve<ILocalizationManager>();
|
||||||
|
user.PopupMessage(user, localizationManager.GetString("You can't reach there!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Shared.BodySystem;
|
||||||
using Robust.Shared.Audio.Midi;
|
using Robust.Shared.Audio.Midi;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
@@ -9,6 +10,10 @@ namespace Content.Shared.GameObjects.Components.Instruments
|
|||||||
{
|
{
|
||||||
public override string Name => "Instrument";
|
public override string Name => "Instrument";
|
||||||
public override uint? NetID => ContentNetIDs.INSTRUMENTS;
|
public override uint? NetID => ContentNetIDs.INSTRUMENTS;
|
||||||
|
|
||||||
|
public virtual void Update(float delta)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -20,19 +25,39 @@ namespace Content.Shared.GameObjects.Components.Instruments
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This message is sent to the client to start the synth.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public class InstrumentStartMidiMessage : ComponentMessage
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This message carries a MidiEvent to be played on clients.
|
/// This message carries a MidiEvent to be played on clients.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class InstrumentMidiEventMessage : ComponentMessage
|
public class InstrumentMidiEventMessage : ComponentMessage
|
||||||
{
|
{
|
||||||
public MidiEvent MidiEvent;
|
public MidiEvent[] MidiEvent;
|
||||||
public double Timestamp;
|
|
||||||
|
|
||||||
public InstrumentMidiEventMessage(MidiEvent midiEvent, double timestamp)
|
public InstrumentMidiEventMessage(MidiEvent[] midiEvent)
|
||||||
{
|
{
|
||||||
MidiEvent = midiEvent;
|
MidiEvent = midiEvent;
|
||||||
Timestamp = timestamp;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public class InstrumentState : ComponentState
|
||||||
|
{
|
||||||
|
public bool Playing { get; }
|
||||||
|
public uint SequencerTick { get; }
|
||||||
|
|
||||||
|
public InstrumentState(bool playing, uint sequencerTick = 0) : base(ContentNetIDs.INSTRUMENTS)
|
||||||
|
{
|
||||||
|
Playing = playing;
|
||||||
|
SequencerTick = sequencerTick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.EntitySystemMessages
|
namespace Content.Shared.GameObjects.EntitySystemMessages
|
||||||
{
|
{
|
||||||
@@ -21,29 +22,33 @@ namespace Content.Shared.GameObjects.EntitySystemMessages
|
|||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class VerbsResponseMessage : EntitySystemMessage
|
public class VerbsResponseMessage : EntitySystemMessage
|
||||||
{
|
{
|
||||||
public readonly List<VerbData> Verbs;
|
public readonly NetVerbData[] Verbs;
|
||||||
public readonly EntityUid Entity;
|
public readonly EntityUid Entity;
|
||||||
|
|
||||||
public VerbsResponseMessage(List<VerbData> verbs, EntityUid entity)
|
public VerbsResponseMessage(NetVerbData[] verbs, EntityUid entity)
|
||||||
{
|
{
|
||||||
Verbs = verbs;
|
Verbs = verbs;
|
||||||
Entity = entity;
|
Entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public readonly struct VerbData
|
public readonly struct NetVerbData
|
||||||
{
|
{
|
||||||
public readonly string Text;
|
public readonly string Text;
|
||||||
public readonly string Key;
|
public readonly string Key;
|
||||||
public readonly string Category;
|
public readonly string Category;
|
||||||
|
public readonly SpriteSpecifier Icon;
|
||||||
|
public readonly SpriteSpecifier CategoryIcon;
|
||||||
public readonly bool Available;
|
public readonly bool Available;
|
||||||
|
|
||||||
public VerbData(string text, string key, string category, bool available)
|
public NetVerbData(VerbData data, string key)
|
||||||
{
|
{
|
||||||
Text = text;
|
Text = data.Text;
|
||||||
Key = key;
|
Key = key;
|
||||||
Category = category;
|
Category = data.Category;
|
||||||
Available = available;
|
CategoryIcon = data.CategoryIcon;
|
||||||
|
Icon = data.Icon;
|
||||||
|
Available = data.Visibility == VerbVisibility.Visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using Content.Shared.GameObjects.Components.Mobs;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.EntitySystems
|
namespace Content.Shared.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -30,8 +30,7 @@ namespace Content.Shared.GameObjects.EntitySystems
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IoCManager.Resolve<IEntitySystemManager>()
|
return EntitySystem.Get<SharedInteractionSystem>()
|
||||||
.GetEntitySystem<SharedInteractionSystem>()
|
|
||||||
.InRangeUnobstructed(examiner.Transform.MapPosition, examined.Transform.MapPosition.Position,
|
.InRangeUnobstructed(examiner.Transform.MapPosition, examined.Transform.MapPosition.Position,
|
||||||
ExamineRange, predicate: entity => entity == examiner || entity == examined, insideBlockerValid:true);
|
ExamineRange, predicate: entity => entity == examiner || entity == examined, insideBlockerValid:true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
using Robust.Shared.GameObjects.Systems;
|
||||||
@@ -36,7 +37,6 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
/// <param name="range">maximum distance between the two sets of coordinates.</param>
|
/// <param name="range">maximum distance between the two sets of coordinates.</param>
|
||||||
/// <param name="collisionMask">the mask to check for collisions</param>
|
/// <param name="collisionMask">the mask to check for collisions</param>
|
||||||
/// <param name="predicate">.</param>
|
/// <param name="predicate">.</param>
|
||||||
/// <param name="mapManager">Map manager containing the two GridIds.</param>
|
|
||||||
/// <param name="insideBlockerValid">if coordinates inside obstructions count as obstructed or not</param>
|
/// <param name="insideBlockerValid">if coordinates inside obstructions count as obstructed or not</param>
|
||||||
/// <returns>True if the two points are within a given range without being obstructed.</returns>
|
/// <returns>True if the two points are within a given range without being obstructed.</returns>
|
||||||
public bool InRangeUnobstructed(MapCoordinates coords, Vector2 otherCoords, float range = InteractionRange,
|
public bool InRangeUnobstructed(MapCoordinates coords, Vector2 otherCoords, float range = InteractionRange,
|
||||||
@@ -48,8 +48,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
if (range > 0f && !(dir.LengthSquared <= range * range)) return false;
|
if (range > 0f && !(dir.LengthSquared <= range * range)) return false;
|
||||||
|
|
||||||
var ray = new CollisionRay(coords.Position, dir.Normalized, collisionMask);
|
var ray = new CollisionRay(coords.Position, dir.Normalized, collisionMask);
|
||||||
var rayResults = _physicsManager.IntersectRayWithPredicate(coords.MapId, ray, dir.Length, predicate, true);
|
var rayResults = _physicsManager.IntersectRayWithPredicate(coords.MapId, ray, dir.Length, predicate).ToList();
|
||||||
if(!rayResults.DidHitObject || (insideBlockerValid && rayResults.DidHitObject && (rayResults.HitPos - otherCoords).Length < 1f))
|
if(rayResults.Count == 0 || (insideBlockerValid && rayResults.Count > 0 && (rayResults[0].HitPos - otherCoords).Length < 1f))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (_mapManager.TryFindGridAt(coords, out var mapGrid) && mapGrid != null)
|
if (_mapManager.TryFindGridAt(coords, out var mapGrid) && mapGrid != null)
|
||||||
@@ -77,7 +77,6 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
/// <param name="range">maximum distance between the two sets of coordinates.</param>
|
/// <param name="range">maximum distance between the two sets of coordinates.</param>
|
||||||
/// <param name="collisionMask">the mask to check for collisions</param>
|
/// <param name="collisionMask">the mask to check for collisions</param>
|
||||||
/// <param name="ignoredEnt">the entity to be ignored when checking for collisions.</param>
|
/// <param name="ignoredEnt">the entity to be ignored when checking for collisions.</param>
|
||||||
/// <param name="mapManager">Map manager containing the two GridIds.</param>
|
|
||||||
/// <param name="insideBlockerValid">if coordinates inside obstructions count as obstructed or not</param>
|
/// <param name="insideBlockerValid">if coordinates inside obstructions count as obstructed or not</param>
|
||||||
/// <returns>True if the two points are within a given range without being obstructed.</returns>
|
/// <returns>True if the two points are within a given range without being obstructed.</returns>
|
||||||
public bool InRangeUnobstructed(MapCoordinates coords, Vector2 otherCoords, float range = InteractionRange,
|
public bool InRangeUnobstructed(MapCoordinates coords, Vector2 otherCoords, float range = InteractionRange,
|
||||||
|
|||||||
@@ -21,25 +21,16 @@ namespace Content.Shared.GameObjects
|
|||||||
public virtual bool RequireInteractionRange => true;
|
public virtual bool RequireInteractionRange => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the text string that will be shown to <paramref name="user"/> in the right click menu.
|
/// Gets the visible verb data for the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Implementations should write into <paramref name="data"/> to return their data.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
/// <param name="user">The entity of the user opening this menu.</param>
|
||||||
|
/// <param name="target">The entity this verb is being evaluated for.</param>
|
||||||
|
/// <param name="data">The data that must be filled in.</param>
|
||||||
/// <returns>The text string that is shown in the right click menu for this verb.</returns>
|
/// <returns>The text string that is shown in the right click menu for this verb.</returns>
|
||||||
public abstract string GetText(IEntity user, IEntity target);
|
public abstract void GetData(IEntity user, IEntity target, VerbData data);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the category of this verb.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
|
||||||
/// <returns>The category of this verb.</returns>
|
|
||||||
public virtual string GetCategory(IEntity user, IEntity target) => "";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the visibility level of this verb in the right click menu.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
|
||||||
/// <returns>The visibility level of the verb in the client's right click menu.</returns>
|
|
||||||
public abstract VerbVisibility GetVisibility(IEntity user, IEntity target);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when this verb is activated from the right click menu.
|
/// Invoked when this verb is activated from the right click menu.
|
||||||
@@ -47,6 +38,13 @@ namespace Content.Shared.GameObjects
|
|||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
/// <param name="user">The entity of the user opening this menu.</param>
|
||||||
/// <param name="target">The entity that is being acted upon.</param>
|
/// <param name="target">The entity that is being acted upon.</param>
|
||||||
public abstract void Activate(IEntity user, IEntity target);
|
public abstract void Activate(IEntity user, IEntity target);
|
||||||
|
|
||||||
|
public VerbData GetData(IEntity user, IEntity target)
|
||||||
|
{
|
||||||
|
var data = new VerbData();
|
||||||
|
GetData(user, target, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -19,33 +19,20 @@ namespace Content.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true, this verb requires the user to be inside within
|
/// If true, this verb requires the user to be inside within
|
||||||
/// <see cref="InteractionRange"/> meters from the entity on which this verb resides.
|
/// <see cref="VerbUtility.InteractionRange"/> meters from the entity on which this verb resides.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool RequireInteractionRange => true;
|
public virtual bool RequireInteractionRange => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the text string that will be shown to <paramref name="user"/> in the right click menu.
|
/// Gets the visible verb data for the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Implementations should write into <paramref name="data"/> to return their data.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
/// <param name="user">The entity of the user opening this menu.</param>
|
||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
||||||
/// <returns>The text string that is shown in the right click menu for this verb.</returns>
|
/// <param name="data">The data that must be filled into.</param>
|
||||||
public abstract string GetText(IEntity user, IComponent component);
|
protected abstract void GetData(IEntity user, IComponent component, VerbData data);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the category of this verb.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
|
||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
|
||||||
/// <returns>The category of this verb.</returns>
|
|
||||||
public virtual string GetCategory(IEntity user, IComponent component) => "";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the visibility level of this verb in the right click menu.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
|
||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
|
||||||
/// <returns>The visibility level of the verb in the client's right click menu.</returns>
|
|
||||||
public abstract VerbVisibility GetVisibility(IEntity user, IComponent component);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when this verb is activated from the right click menu.
|
/// Invoked when this verb is activated from the right click menu.
|
||||||
@@ -53,6 +40,13 @@ namespace Content.Shared.GameObjects
|
|||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
/// <param name="user">The entity of the user opening this menu.</param>
|
||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
||||||
public abstract void Activate(IEntity user, IComponent component);
|
public abstract void Activate(IEntity user, IComponent component);
|
||||||
|
|
||||||
|
public VerbData GetData(IEntity user, IComponent component)
|
||||||
|
{
|
||||||
|
var data = new VerbData();
|
||||||
|
GetData(user, component, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -64,28 +58,15 @@ namespace Content.Shared.GameObjects
|
|||||||
public abstract class Verb<T> : Verb where T : IComponent
|
public abstract class Verb<T> : Verb where T : IComponent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the text string that will be shown to <paramref name="user"/> in the right click menu.
|
/// Gets the visible verb data for the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Implementations should write into <paramref name="data"/> to return their data.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
/// <param name="user">The entity of the user opening this menu.</param>
|
||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
||||||
/// <returns>The text string that is shown in the right click menu for this verb.</returns>
|
/// <param name="data">The data that must be filled into.</param>
|
||||||
protected abstract string GetText(IEntity user, T component);
|
protected abstract void GetData(IEntity user, T component, VerbData data);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the category of this verb.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
|
||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
|
||||||
/// <returns>The category of this verb.</returns>
|
|
||||||
protected virtual string GetCategory(IEntity user, T component) => "";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the visibility level of this verb in the right click menu.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The entity of the user opening this menu.</param>
|
|
||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
|
||||||
/// <returns>The visibility level of the verb in the client's right click menu.</returns>
|
|
||||||
protected abstract VerbVisibility GetVisibility(IEntity user, T component);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when this verb is activated from the right click menu.
|
/// Invoked when this verb is activated from the right click menu.
|
||||||
@@ -94,22 +75,9 @@ namespace Content.Shared.GameObjects
|
|||||||
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
/// <param name="component">The component instance for which this verb is being loaded.</param>
|
||||||
protected abstract void Activate(IEntity user, T component);
|
protected abstract void Activate(IEntity user, T component);
|
||||||
|
|
||||||
/// <inheritdoc />
|
protected sealed override void GetData(IEntity user, IComponent component, VerbData data)
|
||||||
public sealed override string GetText(IEntity user, IComponent component)
|
|
||||||
{
|
{
|
||||||
return GetText(user, (T) component);
|
GetData(user, (T) component, data);
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public sealed override string GetCategory(IEntity user, IComponent component)
|
|
||||||
{
|
|
||||||
return GetCategory(user, (T) component);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public sealed override VerbVisibility GetVisibility(IEntity user, IComponent component)
|
|
||||||
{
|
|
||||||
return GetVisibility(user, (T) component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -128,25 +96,4 @@ namespace Content.Shared.GameObjects
|
|||||||
public sealed class VerbAttribute : Attribute
|
public sealed class VerbAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Possible states of visibility for the verb in the right click menu.
|
|
||||||
/// </summary>
|
|
||||||
public enum VerbVisibility
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The verb will be listed in the right click menu.
|
|
||||||
/// </summary>
|
|
||||||
Visible,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The verb will be listed, but it will be grayed out and unable to be clicked on.
|
|
||||||
/// </summary>
|
|
||||||
Disabled,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The verb will not be listed in the right click menu.
|
|
||||||
/// </summary>
|
|
||||||
Invisible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user