Merge remote-tracking branch 'upstream/master'
@@ -56,23 +56,39 @@ public sealed class ChargeActionSystem : SharedChargingSystem
|
|||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|
||||||
if (_playerManager.LocalEntity is not { } user)
|
if (!_timing.IsFirstTimePredicted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_playerManager.LocalEntity is not { } user)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_mobState.IsAlive(user) || _statusEffects.HasStatusEffect(user, "Incorporeal"))
|
if (!_mobState.IsAlive(user) || _statusEffects.HasStatusEffect(user, "Incorporeal"))
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_timing.IsFirstTimePredicted || _controller == null || _controller.SelectingTargetFor is not { } actionId)
|
if (_controller == null || _controller.SelectingTargetFor is not { } actionId)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_actionsSystem.TryGetActionData(actionId, out var baseAction) ||
|
if (!_actionsSystem.TryGetActionData(actionId, out var baseAction) ||
|
||||||
baseAction is not BaseTargetActionComponent action || !action.IsChargeEnabled)
|
baseAction is not BaseTargetActionComponent action || !action.IsChargeEnabled)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!action.Enabled
|
if (!action.Enabled
|
||||||
|| action is { Charges: 0, RenewCharges: false }
|
|| action is { Charges: 0, RenewCharges: false }
|
||||||
|| action.Cooldown.HasValue && action.Cooldown.Value.End > _timing.CurTime)
|
|| action.Cooldown.HasValue && action.Cooldown.Value.End > _timing.CurTime)
|
||||||
{
|
{
|
||||||
|
Reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +155,17 @@ public sealed class ChargeActionSystem : SharedChargingSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Reset()
|
||||||
|
{
|
||||||
|
_charging = false;
|
||||||
|
_prevCharging = false;
|
||||||
|
_chargeTime = 0f;
|
||||||
|
_chargeLevel = 0;
|
||||||
|
_prevChargeLevel = 0;
|
||||||
|
_isChargingPlaying = false;
|
||||||
|
_isChargedPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleAction(EntityUid actionId, BaseTargetActionComponent action, EntityUid user, int chargeLevel)
|
private void HandleAction(EntityUid actionId, BaseTargetActionComponent action, EntityUid user, int chargeLevel)
|
||||||
{
|
{
|
||||||
var mousePos = _eyeManager.PixelToMap(_inputManager.MouseScreenPosition);
|
var mousePos = _eyeManager.PixelToMap(_inputManager.MouseScreenPosition);
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public sealed partial class HumanoidProfileEditor
|
|||||||
if (_previewDummy is null || Profile is null)
|
if (_previewDummy is null || Profile is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_ttsSys.StopAllStreams();
|
_ttsSys.StopCurrentTTS(_previewDummy.Value);
|
||||||
_ttsMgr.RequestTTS(_previewDummy.Value, IoCManager.Resolve<IRobustRandom>().Pick(_sampleText), Profile.Voice);
|
_ttsMgr.RequestTTS(_previewDummy.Value, IoCManager.Resolve<IRobustRandom>().Pick(_sampleText), Profile.Voice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,38 +1,29 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Shared.Physics;
|
|
||||||
using Content.Shared._White;
|
using Content.Shared._White;
|
||||||
using Content.Shared._White.TTS;
|
using Content.Shared._White.TTS;
|
||||||
using Robust.Client.Audio;
|
using Robust.Client.Audio;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Shared.Audio.Components;
|
||||||
using Robust.Shared.Audio.Sources;
|
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Map;
|
// ReSharper disable InconsistentNaming
|
||||||
using Robust.Shared.Physics;
|
|
||||||
using Robust.Shared.Physics.Systems;
|
|
||||||
|
|
||||||
namespace Content.Client._White.TTS;
|
namespace Content.Client._White.TTS;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Plays TTS audio in world
|
/// Plays TTS audio in world
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
public sealed class TTSSystem : EntitySystem
|
public sealed class TTSSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IAudioManager _audioSystem = default!;
|
[Dependency] private readonly IAudioManager _audioManager = default!;
|
||||||
[Dependency] private readonly IEntityManager _entity = default!;
|
|
||||||
[Dependency] private readonly IEyeManager _eye = default!;
|
|
||||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||||
[Dependency] private readonly SharedPhysicsSystem _broadPhase = default!;
|
[Dependency] private readonly AudioSystem _audioSystem = default!;
|
||||||
[Dependency] private readonly TransformSystem _transform = default!;
|
|
||||||
|
|
||||||
private float _volume;
|
private float _volume;
|
||||||
private const int TTSCollisionMask = (int)CollisionGroup.Impassable;
|
private readonly Dictionary<EntityUid, AudioComponent> _currentlyPlaying = new();
|
||||||
|
private readonly Dictionary<EntityUid, Queue<AudioStreamWithParams>> _enquedStreams = new();
|
||||||
private readonly HashSet<AudioStream> _currentStreams = new();
|
|
||||||
private readonly Dictionary<EntityUid, Queue<AudioStream>> _entityQueues = new();
|
// Same as Server.ChatSystem.VoiceRange
|
||||||
|
private const float VoiceRange = 10;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -44,54 +35,35 @@ public sealed class TTSSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
_cfg.UnsubValueChanged(WhiteCVars.TtsVolume, OnTtsVolumeChanged);
|
_cfg.UnsubValueChanged(WhiteCVars.TtsVolume, OnTtsVolumeChanged);
|
||||||
EndStreams();
|
ClearQueues();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Little bit of duplication logic from AudioSystem
|
|
||||||
public override void FrameUpdate(float frameTime)
|
public override void FrameUpdate(float frameTime)
|
||||||
{
|
{
|
||||||
var streamToRemove = new HashSet<AudioStream>();
|
foreach (var (uid, audioComponent) in _currentlyPlaying)
|
||||||
|
|
||||||
var ourPos = _eye.CurrentEye.Position.Position;
|
|
||||||
foreach (var stream in _currentStreams)
|
|
||||||
{
|
{
|
||||||
if (!stream.Source.Playing ||
|
if (audioComponent is { Running: true, Playing: true })
|
||||||
!_entity.TryGetComponent<MetaDataComponent>(stream.Uid, out var meta) ||
|
|
||||||
Deleted(stream.Uid, meta) ||
|
|
||||||
!_entity.TryGetComponent<TransformComponent>(stream.Uid, out var xform))
|
|
||||||
{
|
|
||||||
stream.Source.Dispose();
|
|
||||||
streamToRemove.Add(stream);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var mapPos = _transform.GetMapCoordinates(xform);
|
|
||||||
if (mapPos.MapId != MapId.Nullspace)
|
|
||||||
{
|
|
||||||
stream.Source.Position = mapPos.Position;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapPos.MapId != _eye.CurrentMap)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sourceRelative = ourPos - mapPos.Position;
|
if (!_enquedStreams.TryGetValue(uid, out var queue))
|
||||||
var occlusion = 0f;
|
|
||||||
if (sourceRelative.Length() > 0)
|
|
||||||
{
|
{
|
||||||
occlusion = _broadPhase.IntersectRayPenetration(mapPos.MapId,
|
continue;
|
||||||
new CollisionRay(mapPos.Position, sourceRelative.Normalized(), TTSCollisionMask),
|
|
||||||
sourceRelative.Length(), stream.Uid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.Source.Occlusion = occlusion;
|
if (!queue.TryDequeue(out var toPlay))
|
||||||
}
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var audioStream in streamToRemove)
|
var audio = _audioSystem.PlayEntity(toPlay.Stream, uid, toPlay.Params);
|
||||||
{
|
if (!audio.HasValue)
|
||||||
_currentStreams.Remove(audioStream);
|
{
|
||||||
ProcessEntityQueue(audioStream.Uid);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentlyPlaying[uid] = audio.Value.Component;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,114 +74,76 @@ public sealed class TTSSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnPlayTTS(PlayTTSEvent ev)
|
private void OnPlayTTS(PlayTTSEvent ev)
|
||||||
{
|
{
|
||||||
if (_volume <= -20f)
|
PlayTTS(GetEntity(ev.Uid), ev.Data, ev.BoostVolume ? _volume + 5 : _volume);
|
||||||
return;
|
|
||||||
|
|
||||||
var volume = _volume;
|
|
||||||
if (ev.BoostVolume)
|
|
||||||
volume += 5f;
|
|
||||||
if (!TryCreateAudioSource(ev.Data, out var source, volume))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var stream = new AudioStream(GetEntity(ev.Uid), source);
|
|
||||||
AddEntityStreamToQueue(stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PlayCustomText(string text)
|
public void PlayTTS(EntityUid uid, byte[] data, float volume)
|
||||||
{
|
{
|
||||||
RaiseNetworkEvent(new RequestTTSEvent(text));
|
if (_volume <= -20f)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stream = CreateAudioStream(data);
|
||||||
|
|
||||||
|
var audioParams = new AudioParams
|
||||||
|
{
|
||||||
|
Volume = volume,
|
||||||
|
MaxDistance = VoiceRange
|
||||||
|
};
|
||||||
|
|
||||||
|
var audioStream = new AudioStreamWithParams(stream, audioParams);
|
||||||
|
EnqueueAudio(uid, audioStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryCreateAudioSource(byte[] data, [NotNullWhen(true)] out IAudioSource? source, float volume = 0f)
|
public void StopCurrentTTS(EntityUid uid)
|
||||||
|
{
|
||||||
|
if (!_currentlyPlaying.TryGetValue(uid, out var audio))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_audioSystem.Stop(audio.Owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnqueueAudio(EntityUid uid, AudioStreamWithParams audioStream)
|
||||||
|
{
|
||||||
|
if (!_currentlyPlaying.ContainsKey(uid))
|
||||||
|
{
|
||||||
|
var audio = _audioSystem.PlayEntity(audioStream.Stream, uid, audioStream.Params);
|
||||||
|
if (!audio.HasValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentlyPlaying[uid] = audio.Value.Component;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_enquedStreams.TryGetValue(uid, out var queue))
|
||||||
|
{
|
||||||
|
queue.Enqueue(audioStream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue = new Queue<AudioStreamWithParams>();
|
||||||
|
queue.Enqueue(audioStream);
|
||||||
|
_enquedStreams[uid] = queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearQueues()
|
||||||
|
{
|
||||||
|
foreach (var (_, queue) in _enquedStreams)
|
||||||
|
{
|
||||||
|
queue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AudioStream CreateAudioStream(byte[] data)
|
||||||
{
|
{
|
||||||
var dataStream = new MemoryStream(data) { Position = 0 };
|
var dataStream = new MemoryStream(data) { Position = 0 };
|
||||||
var audioStream = _audioSystem.LoadAudioOggVorbis(dataStream);
|
return _audioManager.LoadAudioOggVorbis(dataStream);
|
||||||
source = _audioSystem.CreateAudioSource(audioStream);
|
|
||||||
if (source == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
source.Volume = volume == 0f ? _volume : volume;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddEntityStreamToQueue(AudioStream stream)
|
private record AudioStreamWithParams(AudioStream Stream, AudioParams Params);
|
||||||
{
|
|
||||||
if (_entityQueues.TryGetValue(stream.Uid, out var queue))
|
|
||||||
{
|
|
||||||
queue.Enqueue(stream);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_entityQueues.Add(stream.Uid, new Queue<AudioStream>(new[] { stream }));
|
|
||||||
|
|
||||||
if (!IsEntityCurrentlyPlayStream(stream.Uid))
|
|
||||||
ProcessEntityQueue(stream.Uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsEntityCurrentlyPlayStream(EntityUid uid)
|
|
||||||
{
|
|
||||||
return _currentStreams.Any(s => s.Uid == uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessEntityQueue(EntityUid uid)
|
|
||||||
{
|
|
||||||
if (TryTakeEntityStreamFromQueue(uid, out var stream))
|
|
||||||
PlayEntity(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryTakeEntityStreamFromQueue(EntityUid uid, [NotNullWhen(true)] out AudioStream? stream)
|
|
||||||
{
|
|
||||||
if (_entityQueues.TryGetValue(uid, out var queue))
|
|
||||||
{
|
|
||||||
stream = queue.Dequeue();
|
|
||||||
if (queue.Count == 0)
|
|
||||||
_entityQueues.Remove(uid);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PlayEntity(AudioStream stream)
|
|
||||||
{
|
|
||||||
if (!_entity.TryGetComponent<TransformComponent>(stream.Uid, out var xform))
|
|
||||||
return;
|
|
||||||
|
|
||||||
stream.Source.Position = _transform.GetWorldPosition(xform);
|
|
||||||
stream.Source.StartPlaying();
|
|
||||||
_currentStreams.Add(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopAllStreams()
|
|
||||||
{
|
|
||||||
foreach (var stream in _currentStreams)
|
|
||||||
{
|
|
||||||
stream.Source.StopPlaying();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EndStreams()
|
|
||||||
{
|
|
||||||
foreach (var stream in _currentStreams)
|
|
||||||
{
|
|
||||||
stream.Source.StopPlaying();
|
|
||||||
stream.Source.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentStreams.Clear();
|
|
||||||
_entityQueues.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
private sealed class AudioStream(EntityUid uid, IAudioSource source)
|
|
||||||
{
|
|
||||||
public EntityUid Uid { get; } = uid;
|
|
||||||
|
|
||||||
public IAudioSource Source { get; } = source;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ public sealed partial class AdminVerbSystem
|
|||||||
Act = () =>
|
Act = () =>
|
||||||
{
|
{
|
||||||
// Fuck you. Burn Forever.
|
// Fuck you. Burn Forever.
|
||||||
flammable.FireStacks = flammable.MaximumFireStacks;
|
flammable.FireStacks = FlammableSystem.MaximumFireStacks;
|
||||||
_flammableSystem.Ignite(args.Target, args.User);
|
_flammableSystem.Ignite(args.Target, args.User);
|
||||||
var xform = Transform(args.Target);
|
var xform = Transform(args.Target);
|
||||||
_popupSystem.PopupEntity(Loc.GetString("admin-smite-set-alight-self"), args.Target,
|
_popupSystem.PopupEntity(Loc.GetString("admin-smite-set-alight-self"), args.Target,
|
||||||
|
|||||||
@@ -11,65 +11,49 @@ namespace Content.Server.Atmos.Components
|
|||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField]
|
[DataField]
|
||||||
public bool OnFire;
|
public bool OnFire { get; set; }
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField]
|
[DataField]
|
||||||
public float FireStacks;
|
public float FireStacks { get; set; }
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField]
|
[DataField("fireSpread")]
|
||||||
public float MaximumFireStacks = 10f;
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
[DataField]
|
|
||||||
public float MinimumFireStacks = -10f;
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
[DataField]
|
|
||||||
public string FlammableFixtureID = "flammable";
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
[DataField]
|
|
||||||
public float MinIgnitionTemperature = 373.15f;
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
[DataField]
|
|
||||||
public bool FireSpread { get; private set; } = false;
|
public bool FireSpread { get; private set; } = false;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField]
|
[DataField("canResistFire")]
|
||||||
public bool CanResistFire { get; private set; } = false;
|
public bool CanResistFire { get; private set; } = false;
|
||||||
|
|
||||||
[DataField(required: true)]
|
[DataField("damage", required: true)]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public DamageSpecifier Damage = new(); // Empty by default, we don't want any funny NREs.
|
public DamageSpecifier Damage = new(); // Empty by default, we don't want any funny NREs.
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used for the fixture created to handle passing firestacks when two flammable objects collide.
|
/// Used for the fixture created to handle passing firestacks when two flammable objects collide.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField("flammableCollisionShape")]
|
||||||
public IPhysShape FlammableCollisionShape = new PhysShapeCircle(0.35f);
|
public IPhysShape FlammableCollisionShape = new PhysShapeCircle(0.35f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Should the component be set on fire by interactions with isHot entities
|
/// Should the component be set on fire by interactions with isHot entities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField]
|
[DataField("alwaysCombustible")]
|
||||||
public bool AlwaysCombustible = false;
|
public bool AlwaysCombustible = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Can the component anyhow lose its FireStacks?
|
/// Can the component anyhow lose its FireStacks?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField]
|
[DataField("canExtinguish")]
|
||||||
public bool CanExtinguish = true;
|
public bool CanExtinguish = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How many firestacks should be applied to component when being set on fire?
|
/// How many firestacks should be applied to component when being set on fire?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField]
|
[DataField("firestacksOnIgnite")]
|
||||||
public float FirestacksOnIgnite = 2.0f;
|
public float FirestacksOnIgnite = 2.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -52,11 +52,13 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly SpellBladeSystem _spellBlade = default!; // WD
|
[Dependency] private readonly SpellBladeSystem _spellBlade = default!; // WD
|
||||||
|
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
public const float MinimumFireStacks = -10f;
|
||||||
|
public const float MaximumFireStacks = 20f;
|
||||||
// This should probably be moved to the component, requires a rewrite, all fires tick at the same time
|
|
||||||
private const float UpdateTime = 1f;
|
private const float UpdateTime = 1f;
|
||||||
|
|
||||||
|
public const float MinIgnitionTemperature = 373.15f;
|
||||||
|
public const string FlammableFixtureID = "flammable";
|
||||||
|
|
||||||
private float _timer;
|
private float _timer;
|
||||||
|
|
||||||
private readonly Dictionary<Entity<FlammableComponent>, float> _fireEvents = new();
|
private readonly Dictionary<Entity<FlammableComponent>, float> _fireEvents = new();
|
||||||
@@ -65,8 +67,6 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
UpdatesAfter.Add(typeof(AtmosphereSystem));
|
UpdatesAfter.Add(typeof(AtmosphereSystem));
|
||||||
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<FlammableComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<FlammableComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<FlammableComponent, InteractUsingEvent>(OnInteractUsing);
|
SubscribeLocalEvent<FlammableComponent, InteractUsingEvent>(OnInteractUsing);
|
||||||
SubscribeLocalEvent<FlammableComponent, StartCollideEvent>(OnCollide);
|
SubscribeLocalEvent<FlammableComponent, StartCollideEvent>(OnCollide);
|
||||||
@@ -141,7 +141,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (!TryComp<PhysicsComponent>(uid, out var body))
|
if (!TryComp<PhysicsComponent>(uid, out var body))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_fixture.TryCreateFixture(uid, component.FlammableCollisionShape, component.FlammableFixtureID, hard: false,
|
_fixture.TryCreateFixture(uid, component.FlammableCollisionShape, FlammableFixtureID, hard: false,
|
||||||
collisionMask: (int) CollisionGroup.FullTileLayer, body: body);
|
collisionMask: (int) CollisionGroup.FullTileLayer, body: body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
// Normal hard collisions, though this isn't generally possible since most flammable things are mobs
|
// Normal hard collisions, though this isn't generally possible since most flammable things are mobs
|
||||||
// which don't collide with one another, shouldn't work here.
|
// which don't collide with one another, shouldn't work here.
|
||||||
if (args.OtherFixtureId != flammable.FlammableFixtureID && args.OurFixtureId != flammable.FlammableFixtureID)
|
if (args.OtherFixtureId != FlammableFixtureID && args.OurFixtureId != FlammableFixtureID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!flammable.FireSpread)
|
if (!flammable.FireSpread)
|
||||||
@@ -211,30 +211,49 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (!flammable.OnFire && !otherFlammable.OnFire)
|
if (!flammable.OnFire && !otherFlammable.OnFire)
|
||||||
return; // Neither are on fire
|
return; // Neither are on fire
|
||||||
|
|
||||||
// Both are on fire -> equalize fire stacks.
|
// WD START
|
||||||
// Weight each thing's firestacks by its mass
|
var weHold = _spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(uid);
|
||||||
var mass1 = 1f;
|
var theyHold = _spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(otherUid);
|
||||||
var mass2 = 1f;
|
// WD END
|
||||||
if (_physicsQuery.TryComp(uid, out var physics) && _physicsQuery.TryComp(otherUid, out var otherPhys))
|
|
||||||
|
if (flammable.OnFire && otherFlammable.OnFire)
|
||||||
{
|
{
|
||||||
mass1 = physics.Mass;
|
if (weHold && !theyHold || theyHold && !weHold) // WD
|
||||||
mass2 = otherPhys.Mass;
|
return;
|
||||||
|
// Both are on fire -> equalize fire stacks.
|
||||||
|
var avg = (flammable.FireStacks + otherFlammable.FireStacks) / 2;
|
||||||
|
flammable.FireStacks = flammable.CanExtinguish ? avg : Math.Max(flammable.FireStacks, avg);
|
||||||
|
otherFlammable.FireStacks = otherFlammable.CanExtinguish ? avg : Math.Max(otherFlammable.FireStacks, avg);
|
||||||
|
UpdateAppearance(uid, flammable);
|
||||||
|
UpdateAppearance(otherUid, otherFlammable);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// when the thing on fire is more massive than the other, the following happens:
|
// Only one is on fire -> attempt to spread the fire.
|
||||||
// - the thing on fire loses a small number of firestacks
|
if (flammable.OnFire)
|
||||||
// - the other thing gains a large number of firestacks
|
{
|
||||||
// so a person on fire engulfs a mouse, but an engulfed mouse barely does anything to a person
|
if (theyHold) // WD
|
||||||
var total = mass1 + mass2;
|
return;
|
||||||
var avg = (flammable.FireStacks + otherFlammable.FireStacks) / total;
|
otherFlammable.FireStacks += flammable.FireStacks / 2;
|
||||||
|
Ignite(otherUid, uid, otherFlammable);
|
||||||
// swap the entity losing stacks depending on whichever has the most firestack kilos
|
if (flammable.CanExtinguish)
|
||||||
var (src, dest) = flammable.FireStacks * mass1 > otherFlammable.FireStacks * mass2
|
{
|
||||||
? (-1f, 1f)
|
flammable.FireStacks /= 2;
|
||||||
: (1f, -1f);
|
UpdateAppearance(uid, flammable);
|
||||||
// bring each entity to the same firestack mass, firestacks being scaled by the other's mass
|
}
|
||||||
AdjustFireStacks(uid, src * avg * mass2, flammable, ignite: true);
|
}
|
||||||
AdjustFireStacks(otherUid, dest * avg * mass1, otherFlammable, ignite: true);
|
else
|
||||||
|
{
|
||||||
|
if (weHold) // WD
|
||||||
|
return;
|
||||||
|
flammable.FireStacks += otherFlammable.FireStacks / 2;
|
||||||
|
Ignite(uid, otherUid, flammable);
|
||||||
|
if (otherFlammable.CanExtinguish)
|
||||||
|
{
|
||||||
|
otherFlammable.FireStacks /= 2;
|
||||||
|
UpdateAppearance(otherUid, otherFlammable);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnIsHot(EntityUid uid, FlammableComponent flammable, IsHotEvent args)
|
private void OnIsHot(EntityUid uid, FlammableComponent flammable, IsHotEvent args)
|
||||||
@@ -244,7 +263,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
private void OnTileFire(Entity<FlammableComponent> ent, ref TileFireEvent args)
|
private void OnTileFire(Entity<FlammableComponent> ent, ref TileFireEvent args)
|
||||||
{
|
{
|
||||||
var tempDelta = args.Temperature - ent.Comp.MinIgnitionTemperature;
|
var tempDelta = args.Temperature - MinIgnitionTemperature;
|
||||||
|
|
||||||
_fireEvents.TryGetValue(ent, out var maxTemp);
|
_fireEvents.TryGetValue(ent, out var maxTemp);
|
||||||
|
|
||||||
@@ -272,30 +291,17 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
_appearance.SetData(uid, ToggleableLightVisuals.Enabled, flammable.OnFire, appearance);
|
_appearance.SetData(uid, ToggleableLightVisuals.Enabled, flammable.OnFire, appearance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AdjustFireStacks(EntityUid uid, float relativeFireStacks, FlammableComponent? flammable = null, bool ignite = false)
|
public void AdjustFireStacks(EntityUid uid, float relativeFireStacks, FlammableComponent? flammable = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref flammable))
|
if (!Resolve(uid, ref flammable))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetFireStacks(uid, flammable.FireStacks + relativeFireStacks, flammable, ignite);
|
flammable.FireStacks = MathF.Min(MathF.Max(MinimumFireStacks, flammable.FireStacks + relativeFireStacks), MaximumFireStacks);
|
||||||
}
|
|
||||||
|
|
||||||
public void SetFireStacks(EntityUid uid, float stacks, FlammableComponent? flammable = null, bool ignite = false)
|
if (flammable.OnFire && flammable.FireStacks <= 0)
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref flammable))
|
|
||||||
return;
|
|
||||||
|
|
||||||
flammable.FireStacks = MathF.Min(MathF.Max(flammable.MinimumFireStacks, stacks), flammable.MaximumFireStacks);
|
|
||||||
|
|
||||||
if (flammable.FireStacks <= 0)
|
|
||||||
{
|
|
||||||
Extinguish(uid, flammable);
|
Extinguish(uid, flammable);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
flammable.OnFire = ignite;
|
|
||||||
UpdateAppearance(uid, flammable);
|
UpdateAppearance(uid, flammable);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Extinguish(EntityUid uid, FlammableComponent? flammable = null)
|
public void Extinguish(EntityUid uid, FlammableComponent? flammable = null)
|
||||||
@@ -444,11 +450,13 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
EnsureComp<IgnitionSourceComponent>(uid);
|
EnsureComp<IgnitionSourceComponent>(uid);
|
||||||
_ignitionSourceSystem.SetIgnited(uid);
|
_ignitionSourceSystem.SetIgnited(uid);
|
||||||
|
|
||||||
|
var damageScale = MathF.Min( flammable.FireStacks, 5);
|
||||||
|
|
||||||
if (TryComp(uid, out TemperatureComponent? temp))
|
if (TryComp(uid, out TemperatureComponent? temp))
|
||||||
_temperatureSystem.ChangeHeat(uid, 12500 * flammable.FireStacks, false, temp);
|
_temperatureSystem.ChangeHeat(uid, 12500 * damageScale, false, temp);
|
||||||
|
|
||||||
if (!_spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(uid)) // WD EDIT
|
if (!_spellBlade.IsHoldingItemWithComponent<FireAspectComponent>(uid)) // WD EDIT
|
||||||
_damageableSystem.TryChangeDamage(uid, flammable.Damage * flammable.FireStacks, interruptsDoAfters: false);
|
_damageableSystem.TryChangeDamage(uid, flammable.Damage * damageScale, interruptsDoAfters: false);
|
||||||
|
|
||||||
AdjustFireStacks(uid, flammable.FirestackFade * (flammable.Resisting ? 10f : 1f), flammable);
|
AdjustFireStacks(uid, flammable.FirestackFade * (flammable.Resisting ? 10f : 1f), flammable);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,13 +108,18 @@ public partial class SeedData
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true, the properties of this seed cannot be modified.
|
/// If true, the properties of this seed cannot be modified.
|
||||||
|
/// to spare others like me: this DOES NOT prevent mutations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("immutable")] public bool Immutable;
|
[DataField("immutable")] public bool Immutable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, you cannot clip this plant for more seeds, used for special plants such as the gnome plant
|
||||||
|
/// </summary>
|
||||||
|
[DataField("unclippable")] public bool Unclippable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true, there is only a single reference to this seed and it's properties can be directly modified without
|
/// If true, there is only a single reference to this seed and it's properties can be directly modified without
|
||||||
/// needing to clone the seed.
|
/// needing to clone the seed.
|
||||||
/// </summary>
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool Unique = false; // seed-prototypes or yaml-defined seeds for entity prototypes will not generally be unique.
|
public bool Unique = false; // seed-prototypes or yaml-defined seeds for entity prototypes will not generally be unique.
|
||||||
#endregion
|
#endregion
|
||||||
@@ -255,6 +260,7 @@ public partial class SeedData
|
|||||||
{
|
{
|
||||||
DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed.");
|
DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed.");
|
||||||
|
|
||||||
|
|
||||||
var newSeed = new SeedData
|
var newSeed = new SeedData
|
||||||
{
|
{
|
||||||
Name = Name,
|
Name = Name,
|
||||||
@@ -290,6 +296,7 @@ public partial class SeedData
|
|||||||
HarvestRepeat = HarvestRepeat,
|
HarvestRepeat = HarvestRepeat,
|
||||||
Potency = Potency,
|
Potency = Potency,
|
||||||
|
|
||||||
|
Unclippable = Unclippable,
|
||||||
Seedless = Seedless,
|
Seedless = Seedless,
|
||||||
Viable = Viable,
|
Viable = Viable,
|
||||||
Slip = Slip,
|
Slip = Slip,
|
||||||
|
|||||||
@@ -245,6 +245,13 @@ public sealed class PlantHolderSystem : EntitySystem
|
|||||||
_popup.PopupCursor(Loc.GetString("plant-holder-component-nothing-to-sample-message"), args.User);
|
_popup.PopupCursor(Loc.GetString("plant-holder-component-nothing-to-sample-message"), args.User);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//rejects clipping of unclippable plants
|
||||||
|
if (component.Seed.Unclippable)
|
||||||
|
{
|
||||||
|
_popup.PopupCursor(Loc.GetString("plant-holder-component-nothing-to-sample-message"), args.User);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (component.Sampled)
|
if (component.Sampled)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -164,8 +164,7 @@ public sealed class MagicSystem : EntitySystem
|
|||||||
if (!_wizardSpells.CanCast(args)) // WD EDIT
|
if (!_wizardSpells.CanCast(args)) // WD EDIT
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
_wizardSpells.Cast(args); // WD EDIT
|
||||||
Speak(args);
|
|
||||||
|
|
||||||
var transform = Transform(args.Performer);
|
var transform = Transform(args.Performer);
|
||||||
var coords = transform.Coordinates;
|
var coords = transform.Coordinates;
|
||||||
@@ -190,9 +189,7 @@ public sealed class MagicSystem : EntitySystem
|
|||||||
if (!_wizardSpells.CanCast(ev)) // WD EDIT
|
if (!_wizardSpells.CanCast(ev)) // WD EDIT
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ev.Handled = true;
|
_wizardSpells.Cast(ev); // WD EDIT
|
||||||
|
|
||||||
Speak(ev);
|
|
||||||
|
|
||||||
var direction = _transformSystem.GetMapCoordinates(ev.Target).Position - _transformSystem.GetMapCoordinates(ev.Performer).Position;
|
var direction = _transformSystem.GetMapCoordinates(ev.Target).Position - _transformSystem.GetMapCoordinates(ev.Performer).Position;
|
||||||
var impulseVector = direction * 10000;
|
var impulseVector = direction * 10000;
|
||||||
|
|||||||
@@ -6,15 +6,37 @@ using Content.Shared.Popups;
|
|||||||
using Content.Shared.Repairable;
|
using Content.Shared.Repairable;
|
||||||
using Content.Shared.Tools;
|
using Content.Shared.Tools;
|
||||||
using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem;
|
using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem;
|
||||||
|
using Content.Server.DoAfter;
|
||||||
|
using Content.Server.EUI;
|
||||||
|
using Content.Server.Ghost;
|
||||||
|
using Content.Server.Popups;
|
||||||
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.DoAfter;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Interaction.Components;
|
||||||
|
using Content.Shared.Interaction.Events;
|
||||||
|
using Content.Shared.Mind;
|
||||||
|
using Content.Shared.Mobs;
|
||||||
|
using Content.Shared.Mobs.Components;
|
||||||
|
using Content.Shared.Mobs.Systems;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
using Content.Shared.Tools.Components;
|
||||||
|
using Content.Server.Construction.Conditions;
|
||||||
|
//many of these arent reqired but some seem neessesary so ill leave them for now
|
||||||
|
|
||||||
namespace Content.Server.Repairable
|
namespace Content.Server.Repairable
|
||||||
{
|
{
|
||||||
public sealed class RepairableSystem : SharedRepairableSystem
|
public sealed class RepairableSystem : SharedRepairableSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly EuiManager _euiManager = default!;
|
||||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
[Dependency] private readonly IAdminLogManager _adminLogger= default!;
|
[Dependency] private readonly IAdminLogManager _adminLogger= default!;
|
||||||
|
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||||
|
[Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
|
||||||
|
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -24,6 +46,8 @@ namespace Content.Server.Repairable
|
|||||||
|
|
||||||
private void OnRepairFinished(EntityUid uid, RepairableComponent component, RepairFinishedEvent args)
|
private void OnRepairFinished(EntityUid uid, RepairableComponent component, RepairFinishedEvent args)
|
||||||
{
|
{
|
||||||
|
ICommonSession? session = null;
|
||||||
|
|
||||||
if (args.Cancelled)
|
if (args.Cancelled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -34,15 +58,36 @@ namespace Content.Server.Repairable
|
|||||||
{
|
{
|
||||||
var damageChanged = _damageableSystem.TryChangeDamage(uid, component.Damage, true, false, origin: args.User);
|
var damageChanged = _damageableSystem.TryChangeDamage(uid, component.Damage, true, false, origin: args.User);
|
||||||
_adminLogger.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target} by {damageChanged?.GetTotal()}");
|
_adminLogger.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target} by {damageChanged?.GetTotal()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Repair all damage
|
// Repair all damage
|
||||||
_damageableSystem.SetAllDamage(uid, damageable, 0);
|
_damageableSystem.SetAllDamage(uid, damageable, 0);
|
||||||
_adminLogger.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target} back to full health");
|
_adminLogger.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target} back to full health");
|
||||||
}
|
|
||||||
|
|
||||||
|
// this is to revive gnomes and call their ghost back
|
||||||
|
//check for target for threshholds, i hardly understand WHY this works but it does so i wont touch it
|
||||||
|
if (TryComp(uid, out MobThresholdsComponent? mobthresholds))
|
||||||
|
{
|
||||||
|
if (_mobThreshold.TryGetThresholdForState(uid, MobState.Dead, out var threshold) &&
|
||||||
|
TryComp<DamageableComponent>(uid, out var damageableComponent) &&
|
||||||
|
damageableComponent.TotalDamage < threshold)
|
||||||
|
{
|
||||||
|
_mobState.ChangeMobState(uid, MobState.Alive, null, uid);
|
||||||
|
}
|
||||||
|
if (_mind.TryGetMind(uid, out _, out var mind) &&
|
||||||
|
mind.Session is { } playerSession)
|
||||||
|
{
|
||||||
|
session = playerSession;
|
||||||
|
// notify them they're being revived.
|
||||||
|
if (mind.CurrentEntity != uid)
|
||||||
|
{
|
||||||
|
_euiManager.OpenEui(new ReturnToBodyEui(mind, _mind), session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
var str = Loc.GetString("comp-repairable-repair",
|
var str = Loc.GetString("comp-repairable-repair",
|
||||||
("target", uid),
|
("target", uid),
|
||||||
("tool", args.Used!));
|
("tool", args.Used!));
|
||||||
|
|||||||
8
Content.Server/Speech/Components/GnomeAccentComponent.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Content.Server.Speech.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// garden time
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class GnomeAccentComponent : Component
|
||||||
|
{}
|
||||||
52
Content.Server/Speech/EntitySystems/GnomeAccentSystem.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using Content.Server.Speech.Components;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Content.Server.Speech.EntitySystems;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// System that Gnomes the Gnomes talking
|
||||||
|
/// </summary>
|
||||||
|
public sealed class GnomeAccentSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ReplacementAccentSystem _replacement = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<GnomeAccentComponent, AccentGetEvent>(OnAccentGet);
|
||||||
|
}
|
||||||
|
public string Accentuate(string message, GnomeAccentComponent component)
|
||||||
|
{
|
||||||
|
var msg = message;
|
||||||
|
|
||||||
|
msg = _replacement.ApplyReplacements(msg, "gnome");
|
||||||
|
|
||||||
|
// Пиздец, а не код
|
||||||
|
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bне", "ГНЕМ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bнет", "ГНЕМТ", RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bнахуй", "ГНАМХУЙ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bпидоры", "ГНОМЕРЫ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bхуесос", "ГНОХУСОМ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bебал", "ГНОМИЛ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bзаебал", "ЗАГНОМИЛ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bубил", "УГНОМИЛ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bубит", "УГНОМЛЕН", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bебнул", "УГНОМЛЕН", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bстрелял", "СТРЕГНОМИЛ", RegexOptions.IgnoreCase);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bзаколол", "СГНОМИЛ", RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bмой", "муй", RegexOptions.None);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bдруг", "бро", RegexOptions.None);
|
||||||
|
msg = Regex.Replace(msg, @"(?<!\w)\bдрузья", "друганы", RegexOptions.None);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void OnAccentGet(EntityUid uid, GnomeAccentComponent component, AccentGetEvent args)
|
||||||
|
{
|
||||||
|
args.Message = Accentuate(args.Message, component);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,11 +48,11 @@ public sealed partial class MeteorSwarmComponent : Component
|
|||||||
public Dictionary<EntProtoId, float> Meteors = new();
|
public Dictionary<EntProtoId, float> Meteors = new();
|
||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public MinMax Waves = new(3, 3);
|
public MinMax Waves = new(2, 4);
|
||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public MinMax MeteorsPerWave = new(3, 4);
|
public MinMax MeteorsPerWave = new(3, 4);
|
||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public MinMax WaveCooldown = new (10, 60);
|
public MinMax WaveCooldown = new (30, 60);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Content.Server.Chat.Systems;
|
||||||
|
using Content.Server.GameTicking;
|
||||||
|
using Content.Server.Radio.EntitySystems;
|
||||||
|
using Content.Shared._White.Announcement;
|
||||||
|
using Content.Shared.Radio;
|
||||||
|
using Content.Shared.Roles;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Server._White.Announcement;
|
||||||
|
|
||||||
|
public sealed class ArrivalNotificationSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly RadioSystem _radioSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeAllEvent<PlayerSpawnCompleteEvent>(OnPlayerSpawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerSpawn(PlayerSpawnCompleteEvent args)
|
||||||
|
{
|
||||||
|
if (args.JobId == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_prototypeManager.TryIndex<JobPrototype>(args.JobId, out var jobPrototype))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (jobPrototype.AnnouncementPrototype == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_prototypeManager.TryIndex<ArrivalNotificationPrototype>(jobPrototype.AnnouncementPrototype, out var notification))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var message = GetMessage(args.Mob,
|
||||||
|
jobPrototype,
|
||||||
|
notification.UseGlobalAnnouncement ? notification.GlobalMessage : notification.Message);
|
||||||
|
|
||||||
|
var senderName = Loc.GetString("head-arrived-sender");
|
||||||
|
var source = args.Station;
|
||||||
|
|
||||||
|
if (notification.UseGlobalAnnouncement)
|
||||||
|
_chatSystem.DispatchGlobalAnnouncement(message, senderName, colorOverride: Color.Gold);
|
||||||
|
|
||||||
|
message = GetMessage(args.Mob, jobPrototype, notification.Message); // Changing message type for radio notification
|
||||||
|
|
||||||
|
foreach (var channel in notification.RadioChannelsPrototypes)
|
||||||
|
{
|
||||||
|
if (!_prototypeManager.TryIndex<RadioChannelPrototype>(channel, out _))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_radioSystem.SendRadioMessage(source, message, channel, args.Mob);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetMessage(EntityUid mob, JobPrototype jobPrototype, string type)
|
||||||
|
{
|
||||||
|
var message = Loc.GetString(type,
|
||||||
|
("character", MetaData(mob).EntityName),
|
||||||
|
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Loc.GetString(jobPrototype.Name))));
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,16 @@
|
|||||||
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
namespace Content.Server._White.Other.DeathGasps;
|
namespace Content.Server._White.Other.DeathGasps;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed partial class DeathGaspsComponent : Component
|
public sealed partial class DeathGaspsComponent : Component
|
||||||
{
|
{
|
||||||
|
[DataField]
|
||||||
|
public SoundSpecifier DeathSounds = new SoundCollectionSpecifier("deathSounds");
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public SoundSpecifier HeartSounds = new SoundCollectionSpecifier("heartSounds");
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public bool CanOtherHearDeathSound;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ public sealed class OnDeath : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<EntityUid, EntityUid> _playingStreams = new();
|
private readonly Dictionary<EntityUid, EntityUid> _playingStreams = new();
|
||||||
private static readonly SoundSpecifier DeathSounds = new SoundCollectionSpecifier("deathSounds");
|
|
||||||
private static readonly SoundSpecifier HeartSounds = new SoundCollectionSpecifier("heartSounds");
|
|
||||||
|
|
||||||
private void HandleDeathEvent(EntityUid uid, DeathGaspsComponent component, MobStateChangedEvent args)
|
private void HandleDeathEvent(EntityUid uid, DeathGaspsComponent component, MobStateChangedEvent args)
|
||||||
{
|
{
|
||||||
@@ -31,23 +30,23 @@ public sealed class OnDeath : EntitySystem
|
|||||||
StopPlayingStream(uid);
|
StopPlayingStream(uid);
|
||||||
break;
|
break;
|
||||||
case MobState.Critical:
|
case MobState.Critical:
|
||||||
PlayPlayingStream(uid);
|
PlayPlayingStream(uid, component);
|
||||||
break;
|
break;
|
||||||
case MobState.Dead:
|
case MobState.Dead:
|
||||||
StopPlayingStream(uid);
|
StopPlayingStream(uid);
|
||||||
PlayDeathSound(uid);
|
PlayDeathSound(uid, component);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayPlayingStream(EntityUid uid)
|
private void PlayPlayingStream(EntityUid uid, DeathGaspsComponent component)
|
||||||
{
|
{
|
||||||
if (_playingStreams.TryGetValue(uid, out var currentStream))
|
if (_playingStreams.TryGetValue(uid, out var currentStream))
|
||||||
{
|
{
|
||||||
_audio.Stop(currentStream);
|
_audio.Stop(currentStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
var newStream = _audio.PlayEntity(HeartSounds, uid, uid, AudioParams.Default.WithLoop(true));
|
var newStream = _audio.PlayEntity(component.HeartSounds, uid, uid, AudioParams.Default.WithLoop(true));
|
||||||
|
|
||||||
if (newStream.HasValue)
|
if (newStream.HasValue)
|
||||||
{
|
{
|
||||||
@@ -64,9 +63,12 @@ public sealed class OnDeath : EntitySystem
|
|||||||
_playingStreams.Remove(uid);
|
_playingStreams.Remove(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayDeathSound(EntityUid uid)
|
private void PlayDeathSound(EntityUid uid, DeathGaspsComponent component)
|
||||||
{
|
{
|
||||||
_audio.PlayEntity(DeathSounds, uid, uid, AudioParams.Default);
|
if (component.CanOtherHearDeathSound)
|
||||||
|
_audio.PlayPvs(component.DeathSounds, uid, AudioParams.Default);
|
||||||
|
else
|
||||||
|
_audio.PlayEntity(component.DeathSounds, uid, uid, AudioParams.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDetach(EntityUid uid, DeathGaspsComponent component, PlayerDetachedEvent args)
|
private void OnDetach(EntityUid uid, DeathGaspsComponent component, PlayerDetachedEvent args)
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ public sealed partial class TTSSystem : EntitySystem
|
|||||||
|
|
||||||
Filter filter;
|
Filter filter;
|
||||||
if (ev.Global)
|
if (ev.Global)
|
||||||
|
{
|
||||||
filter = Filter.Broadcast();
|
filter = Filter.Broadcast();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var station = _stationSystem.GetOwningStation(ev.Source);
|
var station = _stationSystem.GetOwningStation(ev.Source);
|
||||||
@@ -132,11 +134,7 @@ public sealed partial class TTSSystem : EntitySystem
|
|||||||
|
|
||||||
private async void OnEntitySpoke(EntityUid uid, SharedTTSComponent component, EntitySpokeEvent args)
|
private async void OnEntitySpoke(EntityUid uid, SharedTTSComponent component, EntitySpokeEvent args)
|
||||||
{
|
{
|
||||||
if (!_isEnabled ||
|
if (!_isEnabled || string.IsNullOrEmpty(_apiUrl) || args.Message.Length > MaxMessageChars)
|
||||||
args.Message.Length > MaxMessageChars)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_apiUrl))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -154,6 +152,7 @@ public sealed partial class TTSSystem : EntitySystem
|
|||||||
var soundData = await GenerateTTS(uid, message, protoVoice.Speaker);
|
var soundData = await GenerateTTS(uid, message, protoVoice.Speaker);
|
||||||
if (soundData is null)
|
if (soundData is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var ttsEvent = new PlayTTSEvent(GetNetEntity(uid), soundData, false);
|
var ttsEvent = new PlayTTSEvent(GetNetEntity(uid), soundData, false);
|
||||||
|
|
||||||
// Say
|
// Say
|
||||||
@@ -182,7 +181,6 @@ public sealed partial class TTSSystem : EntitySystem
|
|||||||
var sourcePos = _xforms.GetWorldPosition(xformQuery.GetComponent(uid), xformQuery);
|
var sourcePos = _xforms.GetWorldPosition(xformQuery.GetComponent(uid), xformQuery);
|
||||||
var receptions = Filter.Pvs(uid).Recipients;
|
var receptions = Filter.Pvs(uid).Recipients;
|
||||||
|
|
||||||
|
|
||||||
foreach (var session in receptions)
|
foreach (var session in receptions)
|
||||||
{
|
{
|
||||||
if (!session.AttachedEntity.HasValue)
|
if (!session.AttachedEntity.HasValue)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Content.Shared._White.Wizard;
|
using Content.Shared._White.Wizard;
|
||||||
using Content.Shared._White.Wizard.Charging;
|
using Content.Shared._White.Wizard.Charging;
|
||||||
using Content.Shared.Follower;
|
using Content.Shared.Follower;
|
||||||
|
using Content.Shared.Mobs;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
@@ -25,10 +26,13 @@ public sealed class ChargingSystem : SharedChargingSystem
|
|||||||
SubscribeNetworkEvent<RequestSpellChargingAudio>(OnCharging);
|
SubscribeNetworkEvent<RequestSpellChargingAudio>(OnCharging);
|
||||||
SubscribeNetworkEvent<RequestSpellChargedAudio>(OnCharged);
|
SubscribeNetworkEvent<RequestSpellChargedAudio>(OnCharged);
|
||||||
SubscribeNetworkEvent<RequestAudioSpellStop>(OnStop);
|
SubscribeNetworkEvent<RequestAudioSpellStop>(OnStop);
|
||||||
|
|
||||||
SubscribeLocalEvent<PlayerDetachedEvent>(OnDetach);
|
SubscribeLocalEvent<PlayerDetachedEvent>(OnDetach);
|
||||||
|
SubscribeLocalEvent<MobStateChangedEvent>(OnStateChanged);
|
||||||
|
|
||||||
SubscribeNetworkEvent<AddWizardChargeEvent>(Add);
|
SubscribeNetworkEvent<AddWizardChargeEvent>(Add);
|
||||||
SubscribeNetworkEvent<RemoveWizardChargeEvent>(Remove);
|
SubscribeNetworkEvent<RemoveWizardChargeEvent>(Remove);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Audio
|
#region Audio
|
||||||
@@ -103,40 +107,29 @@ public sealed class ChargingSystem : SharedChargingSystem
|
|||||||
if (user == null)
|
if (user == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_chargingLoops.TryGetValue(user.Value, out var currentStream))
|
StopAllSounds(user.Value);
|
||||||
{
|
|
||||||
_audio.Stop(currentStream);
|
|
||||||
_chargingLoops.Remove(user.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_chargedLoop.TryGetValue(user.Value, out var chargedLoop))
|
|
||||||
{
|
|
||||||
_audio.Stop(chargedLoop);
|
|
||||||
_chargedLoop.Remove(user.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDetach(PlayerDetachedEvent msg, EntitySessionEventArgs args)
|
|
||||||
{
|
|
||||||
var user = msg.Entity;
|
|
||||||
|
|
||||||
if (_chargingLoops.TryGetValue(user, out var currentStream))
|
|
||||||
{
|
|
||||||
_audio.Stop(currentStream);
|
|
||||||
_chargingLoops.Remove(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_chargedLoop.TryGetValue(user, out var chargedLoop))
|
|
||||||
{
|
|
||||||
_audio.Stop(chargedLoop);
|
|
||||||
_chargedLoop.Remove(user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Charges
|
#region Charges
|
||||||
|
|
||||||
|
private void OnDetach(PlayerDetachedEvent msg)
|
||||||
|
{
|
||||||
|
var user = msg.Entity;
|
||||||
|
|
||||||
|
RemoveAllCharges(user);
|
||||||
|
StopAllSounds(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStateChanged(MobStateChangedEvent ev)
|
||||||
|
{
|
||||||
|
var user = ev.Target;
|
||||||
|
|
||||||
|
RemoveAllCharges(user);
|
||||||
|
StopAllSounds(user);
|
||||||
|
}
|
||||||
|
|
||||||
private void Add(AddWizardChargeEvent msg, EntitySessionEventArgs args)
|
private void Add(AddWizardChargeEvent msg, EntitySessionEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.SenderSession.AttachedEntity != null)
|
if (args.SenderSession.AttachedEntity != null)
|
||||||
@@ -153,6 +146,21 @@ public sealed class ChargingSystem : SharedChargingSystem
|
|||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
|
public void StopAllSounds(EntityUid uid)
|
||||||
|
{
|
||||||
|
if (_chargingLoops.TryGetValue(uid, out var currentStream))
|
||||||
|
{
|
||||||
|
_audio.Stop(currentStream);
|
||||||
|
_chargingLoops.Remove(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_chargedLoop.TryGetValue(uid, out var chargedLoop))
|
||||||
|
{
|
||||||
|
_audio.Stop(chargedLoop);
|
||||||
|
_chargedLoop.Remove(uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void AddCharge(EntityUid uid, string msgChargeProto)
|
public void AddCharge(EntityUid uid, string msgChargeProto)
|
||||||
{
|
{
|
||||||
var itemEnt = Spawn(msgChargeProto, Transform(uid).Coordinates);
|
var itemEnt = Spawn(msgChargeProto, Transform(uid).Coordinates);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System.Linq;
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Server._White.Cult;
|
using Content.Server._White.Cult;
|
||||||
using Content.Server._White.IncorporealSystem;
|
using Content.Server._White.IncorporealSystem;
|
||||||
|
using Content.Server._White.Wizard.Charging;
|
||||||
using Content.Server._White.Wizard.Magic.Amaterasu;
|
using Content.Server._White.Wizard.Magic.Amaterasu;
|
||||||
using Content.Server._White.Wizard.Magic.Other;
|
using Content.Server._White.Wizard.Magic.Other;
|
||||||
using Content.Server._White.Wizard.Magic.TeslaProjectile;
|
using Content.Server._White.Wizard.Magic.TeslaProjectile;
|
||||||
@@ -80,6 +81,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
[Dependency] private readonly EuiManager _euiManager = default!;
|
[Dependency] private readonly EuiManager _euiManager = default!;
|
||||||
[Dependency] private readonly MindSystem _mindSystem = default!;
|
[Dependency] private readonly MindSystem _mindSystem = default!;
|
||||||
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
||||||
|
[Dependency] private readonly ChargingSystem _charging = default!;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -125,7 +127,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -143,8 +145,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
var comp = EnsureComp<PreventCollideComponent>(ent);
|
var comp = EnsureComp<PreventCollideComponent>(ent);
|
||||||
comp.Uid = msg.Performer;
|
comp.Uid = msg.Performer;
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -187,8 +188,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
_standing.TryLieDown(uid);
|
_standing.TryLieDown(uid);
|
||||||
_standing.TryLieDown(target);
|
_standing.TryLieDown(target);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
|
|
||||||
SwapComponent<WizardComponent>(uid, target);
|
SwapComponent<WizardComponent>(uid, target);
|
||||||
SwapComponent<RevolutionaryComponent>(uid, target);
|
SwapComponent<RevolutionaryComponent>(uid, target);
|
||||||
@@ -213,8 +213,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
_euiManager.OpenEui(eui, actor.PlayerSession);
|
_euiManager.OpenEui(eui, actor.PlayerSession);
|
||||||
eui.StateDirty();
|
eui.StateDirty();
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg, false);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -264,8 +263,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
_handsSystem.TryForcePickupAnyHand(msg.Performer, recallComponent.Item.Value);
|
_handsSystem.TryForcePickupAnyHand(msg.Performer, recallComponent.Item.Value);
|
||||||
_audio.PlayPvs(recallComponent.RecallSound, msg.Performer);
|
_audio.PlayPvs(recallComponent.RecallSound, msg.Performer);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,8 +291,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -317,8 +314,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -340,8 +336,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
Spawn("AdminInstantEffectSmoke3", Transform(msg.Target).Coordinates);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -357,8 +352,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
|
|
||||||
_empSystem.EmpPulse(coords, 15, 1000000, 60f);
|
_empSystem.EmpPulse(coords, 15, 1000000, 60f);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -381,8 +375,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
_statusEffectsSystem.TryAddStatusEffect<IncorporealComponent>(msg.Performer, "Incorporeal",
|
_statusEffectsSystem.TryAddStatusEffect<IncorporealComponent>(msg.Performer, "Incorporeal",
|
||||||
TimeSpan.FromSeconds(10), false);
|
TimeSpan.FromSeconds(10), false);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -434,8 +427,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
Spawn("AdminInstantEffectSmoke3", oldCoords);
|
Spawn("AdminInstantEffectSmoke3", oldCoords);
|
||||||
Spawn("AdminInstantEffectSmoke3", coords);
|
Spawn("AdminInstantEffectSmoke3", coords);
|
||||||
|
|
||||||
msg.Handled = true;
|
Cast(msg);
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -460,9 +452,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCooldown(msg.Action, msg.ActionUseType);
|
Cast(msg);
|
||||||
msg.Handled = true;
|
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ForcewallSpellDefault(ForceWallSpellEvent msg)
|
private void ForcewallSpellDefault(ForceWallSpellEvent msg)
|
||||||
@@ -533,9 +523,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetCooldown(msg.Action, msg.ActionUseType);
|
Cast(msg);
|
||||||
msg.Handled = true;
|
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CardsSpellDefault(CardsSpellEvent msg)
|
private void CardsSpellDefault(CardsSpellEvent msg)
|
||||||
@@ -638,9 +626,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetCooldown(msg.Action, msg.ActionUseType);
|
Cast(msg);
|
||||||
msg.Handled = true;
|
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FireballSpellDefault(FireballSpellEvent msg)
|
private void FireballSpellDefault(FireballSpellEvent msg)
|
||||||
@@ -725,9 +711,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetCooldown(msg.Action, msg.ActionUseType);
|
Cast(msg);
|
||||||
msg.Handled = true;
|
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ForceSpellAlt(ForceSpellEvent msg)
|
private bool ForceSpellAlt(ForceSpellEvent msg)
|
||||||
@@ -782,9 +766,7 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetCooldown(msg.Action, msg.ActionUseType);
|
Cast(msg);
|
||||||
msg.Handled = true;
|
|
||||||
Speak(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ArcSpellDefault(ArcSpellEvent msg)
|
private bool ArcSpellDefault(ArcSpellEvent msg)
|
||||||
@@ -844,6 +826,17 @@ public sealed class WizardSpellsSystem : EntitySystem
|
|||||||
RaiseLocalEvent(uid, new EnergyDomeClothesTurnOffEvent());
|
RaiseLocalEvent(uid, new EnergyDomeClothesTurnOffEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Cast(BaseActionEvent msg, bool removeAllCharges = true)
|
||||||
|
{
|
||||||
|
SetCooldown(msg.Action, msg.ActionUseType);
|
||||||
|
msg.Handled = true;
|
||||||
|
Speak(msg);
|
||||||
|
if (!removeAllCharges)
|
||||||
|
return;
|
||||||
|
_charging.RemoveAllCharges(msg.Performer);
|
||||||
|
_charging.StopAllSounds(msg.Performer);
|
||||||
|
}
|
||||||
|
|
||||||
public bool CanCast(BaseActionEvent msg)
|
public bool CanCast(BaseActionEvent msg)
|
||||||
{
|
{
|
||||||
return !msg.Handled && CheckRequirements(msg.Action, msg.Performer) &&
|
return !msg.Handled && CheckRequirements(msg.Action, msg.Performer) &&
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.EUI;
|
using Content.Server._White.Wizard.Charging;
|
||||||
|
using Content.Server.EUI;
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Shared._White.Wizard.Teleport;
|
using Content.Shared._White.Wizard.Teleport;
|
||||||
using Content.Shared.Eui;
|
using Content.Shared.Eui;
|
||||||
@@ -15,6 +16,7 @@ public sealed class WizardTeleportSpellEui : BaseEui
|
|||||||
private readonly TeleportLocationSystem _teleportLocation;
|
private readonly TeleportLocationSystem _teleportLocation;
|
||||||
private readonly PullingSystem _pulling;
|
private readonly PullingSystem _pulling;
|
||||||
private readonly PopupSystem _popupSystem;
|
private readonly PopupSystem _popupSystem;
|
||||||
|
private readonly ChargingSystem _charging;
|
||||||
|
|
||||||
private readonly EntityUid _performer;
|
private readonly EntityUid _performer;
|
||||||
|
|
||||||
@@ -28,6 +30,7 @@ public sealed class WizardTeleportSpellEui : BaseEui
|
|||||||
_pulling = _entityManager.System<PullingSystem>();
|
_pulling = _entityManager.System<PullingSystem>();
|
||||||
_teleportLocation = _entityManager.System<TeleportLocationSystem>();
|
_teleportLocation = _entityManager.System<TeleportLocationSystem>();
|
||||||
_popupSystem = _entityManager.System<PopupSystem>();
|
_popupSystem = _entityManager.System<PopupSystem>();
|
||||||
|
_charging = _entityManager.System<ChargingSystem>();
|
||||||
|
|
||||||
_performer = performer;
|
_performer = performer;
|
||||||
|
|
||||||
@@ -107,6 +110,9 @@ public sealed class WizardTeleportSpellEui : BaseEui
|
|||||||
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", oldCoords);
|
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", oldCoords);
|
||||||
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", coords);
|
_entityManager.SpawnEntity("AdminInstantEffectSmoke10", coords);
|
||||||
|
|
||||||
|
_charging.RemoveAllCharges(_performer);
|
||||||
|
_charging.StopAllSounds(_performer);
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,13 +125,13 @@ namespace Content.Shared.CCVar
|
|||||||
/// Minimum time between meteor swarms in minutes.
|
/// Minimum time between meteor swarms in minutes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<float>
|
public static readonly CVarDef<float>
|
||||||
MeteorSwarmMinTime = CVarDef.Create("events.meteor_swarm_min_time", 12.5f, CVar.ARCHIVE | CVar.SERVERONLY);
|
MeteorSwarmMinTime = CVarDef.Create("events.meteor_swarm_min_time", 20f, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum time between meteor swarms in minutes.
|
/// Maximum time between meteor swarms in minutes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<float>
|
public static readonly CVarDef<float>
|
||||||
MeteorSwarmMaxTime = CVarDef.Create("events.meteor_swarm_max_time", 17.5f, CVar.ARCHIVE | CVar.SERVERONLY);
|
MeteorSwarmMaxTime = CVarDef.Create("events.meteor_swarm_max_time", 30f, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Game
|
* Game
|
||||||
|
|||||||
@@ -19,16 +19,16 @@ namespace Content.Shared.Roles
|
|||||||
[IdDataField]
|
[IdDataField]
|
||||||
public string ID { get; private set; } = default!;
|
public string ID { get; private set; } = default!;
|
||||||
|
|
||||||
[DataField("playTimeTracker", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<PlayTimeTrackerPrototype>))]
|
[DataField(required: true, customTypeSerializer: typeof(PrototypeIdSerializer<PlayTimeTrackerPrototype>))]
|
||||||
public string PlayTimeTracker { get; private set; } = string.Empty;
|
public string PlayTimeTracker { get; private set; } = string.Empty;
|
||||||
|
|
||||||
[DataField("supervisors")]
|
[DataField]
|
||||||
public string Supervisors { get; private set; } = "nobody";
|
public string Supervisors { get; private set; } = "nobody";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of this job as displayed to players.
|
/// The name of this job as displayed to players.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("name")]
|
[DataField]
|
||||||
public string Name { get; private set; } = string.Empty;
|
public string Name { get; private set; } = string.Empty;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
@@ -37,22 +37,25 @@ namespace Content.Shared.Roles
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of this job as displayed to players.
|
/// The name of this job as displayed to players.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("description")]
|
[DataField]
|
||||||
public string? Description { get; private set; }
|
public string? Description { get; private set; }
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
public string? LocalizedDescription => Description is null ? null : Loc.GetString(Description);
|
public string? LocalizedDescription => Description is null ? null : Loc.GetString(Description);
|
||||||
|
|
||||||
[DataField("requirements")]
|
[DataField]
|
||||||
public HashSet<JobRequirement>? Requirements;
|
public HashSet<JobRequirement>? Requirements;
|
||||||
|
|
||||||
[DataField("joinNotifyCrew")]
|
[DataField]
|
||||||
public bool JoinNotifyCrew { get; private set; } = false;
|
public bool JoinNotifyCrew { get; private set; } = false;
|
||||||
|
|
||||||
[DataField("requireAdminNotify")]
|
[DataField]
|
||||||
|
public string? AnnouncementPrototype;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
public bool RequireAdminNotify { get; private set; } = false;
|
public bool RequireAdminNotify { get; private set; } = false;
|
||||||
|
|
||||||
[DataField("setPreference")]
|
[DataField]
|
||||||
public bool SetPreference { get; private set; } = true;
|
public bool SetPreference { get; private set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -62,14 +65,14 @@ namespace Content.Shared.Roles
|
|||||||
[DataField]
|
[DataField]
|
||||||
public bool? OverrideConsoleVisibility { get; private set; } = null;
|
public bool? OverrideConsoleVisibility { get; private set; } = null;
|
||||||
|
|
||||||
[DataField("canBeAntag")]
|
[DataField]
|
||||||
public bool CanBeAntag { get; private set; } = true;
|
public bool CanBeAntag { get; private set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this job is a head.
|
/// Whether this job is a head.
|
||||||
/// The job system will try to pick heads before other jobs on the same priority level.
|
/// The job system will try to pick heads before other jobs on the same priority level.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("weight")]
|
[DataField]
|
||||||
public int Weight { get; private set; }
|
public int Weight { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -86,10 +89,10 @@ namespace Content.Shared.Roles
|
|||||||
/// A numerical score for how much easier this job is for antagonists.
|
/// A numerical score for how much easier this job is for antagonists.
|
||||||
/// For traitors, reduces starting TC by this amount. Other gamemodes can use it for whatever they find fitting.
|
/// For traitors, reduces starting TC by this amount. Other gamemodes can use it for whatever they find fitting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("antagAdvantage")]
|
[DataField]
|
||||||
public int AntagAdvantage = 0;
|
public int AntagAdvantage = 0;
|
||||||
|
|
||||||
[DataField("startingGear", customTypeSerializer: typeof(PrototypeIdSerializer<StartingGearPrototype>))]
|
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<StartingGearPrototype>))]
|
||||||
public string? StartingGear { get; private set; }
|
public string? StartingGear { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -97,28 +100,28 @@ namespace Content.Shared.Roles
|
|||||||
/// Starting gear will be ignored.
|
/// Starting gear will be ignored.
|
||||||
/// If you want to just add special attributes to a humanoid, use AddComponentSpecial instead.
|
/// If you want to just add special attributes to a humanoid, use AddComponentSpecial instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("jobEntity", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||||
public string? JobEntity = null;
|
public string? JobEntity = null;
|
||||||
|
|
||||||
[DataField("icon", customTypeSerializer: typeof(PrototypeIdSerializer<StatusIconPrototype>))]
|
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<StatusIconPrototype>))]
|
||||||
public string Icon { get; private set; } = "JobIconUnknown";
|
public string Icon { get; private set; } = "JobIconUnknown";
|
||||||
|
|
||||||
[DataField("special", serverOnly: true)]
|
[DataField(serverOnly: true)]
|
||||||
public JobSpecial[] Special { get; private set; } = Array.Empty<JobSpecial>();
|
public JobSpecial[] Special { get; private set; } = Array.Empty<JobSpecial>();
|
||||||
|
|
||||||
[DataField("access")]
|
[DataField]
|
||||||
public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> Access { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
|
public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> Access { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
|
||||||
|
|
||||||
[DataField("accessGroups")]
|
[DataField]
|
||||||
public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> AccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
|
public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> AccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
|
||||||
|
|
||||||
[DataField("extendedAccess")]
|
[DataField]
|
||||||
public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> ExtendedAccess { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
|
public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> ExtendedAccess { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
|
||||||
|
|
||||||
[DataField("extendedAccessGroups")]
|
[DataField]
|
||||||
public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> ExtendedAccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
|
public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> ExtendedAccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
|
||||||
|
|
||||||
[DataField("whitelistedSpecies")]
|
[DataField]
|
||||||
public IReadOnlyCollection<ProtoId<SpeciesPrototype>> WhitelistedSpecies { get; private set; } = Array.Empty<ProtoId<SpeciesPrototype>>();
|
public IReadOnlyCollection<ProtoId<SpeciesPrototype>> WhitelistedSpecies { get; private set; } = Array.Empty<ProtoId<SpeciesPrototype>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared._White.Announcement;
|
||||||
|
|
||||||
|
[Prototype("arrivalNotification")]
|
||||||
|
public sealed partial class ArrivalNotificationPrototype : IPrototype
|
||||||
|
{
|
||||||
|
[IdDataField] public string ID { get; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The message that the department will receive upon the player arrival
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public string Message = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The message that the station will receive upon the player arrival
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public string GlobalMessage = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ID of the channel where the player arrival will be announced.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public HashSet<string> RadioChannelsPrototypes = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the notification will be made to the entire station. If false, the notification will be on the department radio channel
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public bool UseGlobalAnnouncement;
|
||||||
|
}
|
||||||
BIN
Resources/Audio/Voice/Gnome/Gnome_Clumsy_Sound_Effect.ogg
Normal file
BIN
Resources/Audio/Voice/Gnome/Gnome_Woo_Sound_Effect.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Death1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Death2.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Death3.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Death4.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome1V1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome2V1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome3V1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome4V1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome5V1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome6V1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome7V1.ogg
Normal file
BIN
Resources/Audio/White/Voice/Gnomes/Gnome8V1.ogg
Normal file
@@ -5264,3 +5264,140 @@
|
|||||||
id: 339
|
id: 339
|
||||||
time: '2024-06-30T07:04:16.0000000+00:00'
|
time: '2024-06-30T07:04:16.0000000+00:00'
|
||||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/400
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/400
|
||||||
|
- author: Warete
|
||||||
|
changes:
|
||||||
|
- message: "\u0423\u043F\u0440\u043E\u0449\u0435\u043D \u043A\u0440\u0430\u0444\u0442\
|
||||||
|
\ \u043F\u0430\u0440\u044B \u0440\u0435\u0446\u0435\u043F\u0442\u043E\u0432"
|
||||||
|
type: Fix
|
||||||
|
id: 340
|
||||||
|
time: '2024-07-01T04:33:47.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/401
|
||||||
|
- author: ThereDrD
|
||||||
|
changes:
|
||||||
|
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E \u043E\u043F\u043E\
|
||||||
|
\u0432\u0435\u0449\u0435\u043D\u0438\u0435 \u043E \u043F\u0440\u0438\u0431\u044B\
|
||||||
|
\u0442\u0438\u0438 \u0433\u043B\u0430\u0432 \u043E\u0442\u0434\u0435\u043B\u043E\
|
||||||
|
\u0432 \u0432 \u043A\u0430\u043D\u0430\u043B\u044B \u043E\u0442\u0434\u0435\u043B\
|
||||||
|
\u0430 \u0438 \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u043E\u0435 \u043E\
|
||||||
|
\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u0435"
|
||||||
|
type: Add
|
||||||
|
id: 341
|
||||||
|
time: '2024-07-01T10:10:32.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/402
|
||||||
|
- author: Aviu
|
||||||
|
changes:
|
||||||
|
- message: "\u0423 \u0441\u0432\u0435\u0442\u043E\u0432\u043E\u0433\u043E \u043A\
|
||||||
|
\u043E\u043F\u044C\u044F \u0446\u0435\u043D\u0430 \u0441\u043D\u043E\u0432\u0430\
|
||||||
|
\ 10, \u0443\u0440\u043E\u043D \u043E\u0442 \u0431\u0440\u043E\u0441\u043A\u0430\
|
||||||
|
\ \u0441\u043D\u043E\u0432\u0430 60, \u043D\u043E \u043A\u0434 \u0442\u0435\u043F\
|
||||||
|
\u0435\u0440\u044C 2.5 \u0441\u0435\u043A\u0443\u043D\u0434."
|
||||||
|
type: Add
|
||||||
|
id: 342
|
||||||
|
time: '2024-07-01T11:36:15.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/405
|
||||||
|
- author: ThereDrD
|
||||||
|
changes:
|
||||||
|
- message: "\u0423\u0431\u0440\u0430\u043D\u043E \u043B\u0438\u0448\u043D\u0435\u0435\
|
||||||
|
\ \u043E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u0435 \u0441\u0442\u0430\
|
||||||
|
\u043D\u0446\u0438\u0438 \u043E \u043F\u0440\u0438\u0431\u044B\u0442\u0438\u0438\
|
||||||
|
\ \u0433\u043B\u0430\u0432\u044B"
|
||||||
|
type: Fix
|
||||||
|
id: 343
|
||||||
|
time: '2024-07-01T13:02:51.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/407
|
||||||
|
- author: Aviu
|
||||||
|
changes:
|
||||||
|
- message: "\u041E\u0442\u043A\u0430\u0442 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\
|
||||||
|
\u0438\u0439, \u0441\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0445 \u0441\
|
||||||
|
\ \u043E\u0433\u043D\u0435\u043C, \u043D\u043E \u043E\u0433\u043E\u043D\u044C\
|
||||||
|
\ \u0432\u0441\u0435 \u0435\u0449\u0435 \u043C\u0435\u043D\u0435\u0435 \u043E\
|
||||||
|
\u043F\u0430\u0441\u0435\u043D."
|
||||||
|
type: Fix
|
||||||
|
id: 344
|
||||||
|
time: '2024-07-01T13:27:22.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/408
|
||||||
|
- author: ThereDrD
|
||||||
|
changes:
|
||||||
|
- message: "\u041E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u0435 \u043E\
|
||||||
|
\ \u0433\u043B\u0430\u0432\u0435 \u043E\u0442\u0434\u0435\u043B\u0430 \u0442\
|
||||||
|
\u0435\u043F\u0435\u0440\u044C \u043E\u043F\u043E\u0432\u0435\u0449\u0430\u0435\
|
||||||
|
\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u0432 \u043E\u0434\u0438\
|
||||||
|
\u043D \u043A\u0430\u043D\u0430\u043B"
|
||||||
|
type: Tweak
|
||||||
|
id: 345
|
||||||
|
time: '2024-07-01T13:46:56.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/409
|
||||||
|
- author: ThereDrD
|
||||||
|
changes:
|
||||||
|
- message: "\u041C\u0435\u0442\u0435\u043E\u0440\u043E\u0432 \u0434\u043E\u043B\u0436\
|
||||||
|
\u043D\u043E \u0441\u0442\u0430\u0442\u044C \u043D\u0435\u043C\u043D\u043E\u0433\
|
||||||
|
\u043E \u043C\u0435\u043D\u044C\u0448\u0435"
|
||||||
|
type: Add
|
||||||
|
id: 346
|
||||||
|
time: '2024-07-02T09:55:38.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/410
|
||||||
|
- author: ThereDrD
|
||||||
|
changes:
|
||||||
|
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u0413\u041D\u041E\
|
||||||
|
\u041C\u042B. \u041E\u043D\u0438 \u043C\u043E\u0433\u0443\u0442 \u043F\u043E\
|
||||||
|
\u043C\u043E\u0433\u0430\u0442\u044C \u0432 \u0441\u0430\u0434\u0443, \u0441\
|
||||||
|
\u043C\u0435\u0448\u043D\u043E \u0433\u043E\u0432\u043E\u0440\u0438\u0442\u044C\
|
||||||
|
, \u0441\u043C\u0435\u0448\u043D\u043E \u043A\u0440\u0438\u0447\u0430\u0442\u044C\
|
||||||
|
, \u0441\u0438\u0434\u0435\u0442\u044C \u043D\u0430 \u0433\u043E\u043B\u043E\
|
||||||
|
\u0432\u0435, \u0432\u043E\u0440\u043E\u0432\u0430\u0442\u044C, \u0438\u0441\
|
||||||
|
\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C\u0441\u044F \u043A\
|
||||||
|
\u0430\u043A \u043E\u0442\u0432\u0435\u0440\u0442\u043A\u0430 \u0438 \u0440\u0430\
|
||||||
|
\u0437\u0431\u0438\u0432\u0430\u0442\u044C\u0441\u044F \u043E\u0431 \u0441\u0442\
|
||||||
|
\u0435\u043D\u043A\u0443. \u0418\u0445 \u043C\u043E\u0436\u043D\u043E \u0432\
|
||||||
|
\u044B\u0440\u0430\u0441\u0442\u0438\u0442\u044C, \u0438\u0441\u043F\u043E\u043B\
|
||||||
|
\u044C\u0437\u0443\u044F \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u044C\u043D\
|
||||||
|
\u044B\u0435 \u0441\u0435\u043C\u0435\u043D\u0430. \u041D\u0435\u0441\u043A\u043E\
|
||||||
|
\u043B\u044C\u043A\u043E \u0441\u0435\u043C\u044F\u043D \u043C\u043E\u0436\u043D\
|
||||||
|
\u043E \u043D\u0430\u0439\u0442\u0438 \u0432 \u0432\u0435\u043D\u0434\u043E\u043C\
|
||||||
|
\u0430\u0442\u0435 \u0431\u043E\u0442\u0430\u043D\u0438\u043A\u0430"
|
||||||
|
type: Add
|
||||||
|
id: 347
|
||||||
|
time: '2024-07-02T09:55:25.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/411
|
||||||
|
- author: ThereDrD
|
||||||
|
changes:
|
||||||
|
- message: "\u0423\u043C\u0435\u043D\u044C\u0448\u0435\u043D\u043E \u043A\u043E\u043B\
|
||||||
|
\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0441\u0435\u043C\u044F\u043D \u0433\
|
||||||
|
\u043D\u043E\u043C\u043E\u0432 \u0432 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\
|
||||||
|
\u0435 \u0431\u043E\u0442\u0430\u043D\u0438\u043A\u0430 \u0434\u043E 1"
|
||||||
|
type: Tweak
|
||||||
|
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u0434\u043B\u044F \u043F\u043E\
|
||||||
|
\u043B\u0443\u0447\u0435\u043D\u0438\u044F \u0441\u0435\u043C\u044F\u043D \u0433\
|
||||||
|
\u043D\u043E\u043C\u043E\u0432 \u0430\u0432\u0442\u043E\u043C\u0430\u0442 \u0431\
|
||||||
|
\u043E\u0442\u0430\u043D\u0438\u043A\u043E\u0432 \u0442\u0440\u0435\u0431\u0443\
|
||||||
|
\u0435\u0442\u0441\u044F \u0432\u0437\u043B\u043E\u043C\u0430\u0442\u044C"
|
||||||
|
type: Tweak
|
||||||
|
- message: "\u0423\u0440\u043E\u043D \u0433\u043D\u043E\u043C\u043E\u0432 \u043E\
|
||||||
|
\u0442 \u0434\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0443\u043C\u0435\u043D\
|
||||||
|
\u044C\u0448\u0435\u043D"
|
||||||
|
type: Tweak
|
||||||
|
- message: "\u0420\u0430\u043D\u0434\u043E\u043C \u0438\u0433\u0440\u043E\u043A\u043E\
|
||||||
|
\u0432 \u0434\u043B\u044F \u0433\u043E\u0441\u0442\u0440\u043E\u043B\u0438 \u0433\
|
||||||
|
\u043D\u043E\u043C\u0430"
|
||||||
|
type: Tweak
|
||||||
|
- message: "\u0421\u0435\u043C\u0435\u043D\u0430 \u0433\u043D\u043E\u043C\u043E\u0432\
|
||||||
|
\ \u0432 \u044F\u0449\u0438\u043A \u0441 \u044D\u043A\u0437\u043E\u0442\u0438\
|
||||||
|
\u0447\u0435\u0441\u043A\u0438\u043C\u0438 \u0440\u0430\u0441\u0442\u0435\u043D\
|
||||||
|
\u0438\u044F\u043C\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0437\u0430\
|
||||||
|
\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u0432 \u043A\u0430\
|
||||||
|
\u0440\u0433\u043E"
|
||||||
|
type: Tweak
|
||||||
|
id: 348
|
||||||
|
time: '2024-07-02T15:12:29.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/412
|
||||||
|
- author: Remuchi
|
||||||
|
changes:
|
||||||
|
- message: "\u0422\u0422\u0421 \u0441\u043E \u0432\u0441\u0435\u0439 \u0441\u0442\
|
||||||
|
\u0430\u043D\u0446\u0438\u0438 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\
|
||||||
|
\ \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0441\u043B\
|
||||||
|
\u044B\u0448\u0435\u043D \u0432 \u0441\u043B\u0443\u0447\u0430\u0439\u043D\u044B\
|
||||||
|
\u0445 \u043C\u0435\u0441\u0442\u0430\u0445 \u043A\u0430\u0440\u0442\u044B."
|
||||||
|
type: Fix
|
||||||
|
id: 349
|
||||||
|
time: '2024-07-02T15:56:53.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/413
|
||||||
|
|||||||
@@ -232,3 +232,7 @@ ghost-role-information-artifact-name = Sentient Artifact
|
|||||||
ghost-role-information-artifact-description =
|
ghost-role-information-artifact-description =
|
||||||
Enact your eldritch whims.
|
Enact your eldritch whims.
|
||||||
Forcibly activate your nodes for good or for evil.
|
Forcibly activate your nodes for good or for evil.
|
||||||
|
|
||||||
|
|
||||||
|
ghost-role-information-gnome-name = Garden Gnome
|
||||||
|
ghost-role-information-gnome-description = You are the trusted keeper of the station garden, keep your domain safe.
|
||||||
|
|||||||
@@ -111,3 +111,5 @@ seeds-pumpkin-name = pumpkin
|
|||||||
seeds-pumpkin-display-name = pumpkins
|
seeds-pumpkin-display-name = pumpkins
|
||||||
seeds-cotton-name = cotton
|
seeds-cotton-name = cotton
|
||||||
seeds-cotton-display-name = cotton plant
|
seeds-cotton-display-name = cotton plant
|
||||||
|
seeds-gome-name = gnome
|
||||||
|
seeds-gnome-display-name = gnome plant
|
||||||
|
|||||||
3
Resources/Locale/ru-RU/_white/announce/announce.ftl
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
head-arrived-message = { $character }, { $job }, Глава отдела
|
||||||
|
head-arrived-message-global = { $job } { $character } на станции
|
||||||
|
head-arrived-sender = Автоматическая Система Оповещений
|
||||||
6
Resources/Locale/ru-RU/_white/mobs/gnomes.ftl
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
ent-MobGnome = гном
|
||||||
|
.desc = Добросовестный помощник по саду
|
||||||
|
ent-GnomeSeeds = пакет семян гнома
|
||||||
|
.desc = { ent-SeedBase.desc }
|
||||||
|
ent-ClothingHeadHatGnome = шляпа гнома
|
||||||
|
.desc = Шляпа настоящего садового помощника
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
- type: body
|
- type: body
|
||||||
id: Bot
|
id: Bot
|
||||||
name: "bot"
|
name: "bot"
|
||||||
root: hand 1
|
root: hand 1
|
||||||
|
|||||||
19
Resources/Prototypes/Body/Prototypes/gnome.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
- type: body
|
||||||
|
id: gnome
|
||||||
|
name: "gnome"
|
||||||
|
root: torso
|
||||||
|
slots:
|
||||||
|
torso:
|
||||||
|
part: TorsoAnimal
|
||||||
|
connections:
|
||||||
|
- hands
|
||||||
|
- legs
|
||||||
|
organs:
|
||||||
|
hands:
|
||||||
|
part: HandsAnimal
|
||||||
|
legs:
|
||||||
|
part: LegsAnimal
|
||||||
|
connections:
|
||||||
|
- feet
|
||||||
|
feet:
|
||||||
|
part: FeetAnimal
|
||||||
@@ -20,6 +20,8 @@
|
|||||||
amount: 2
|
amount: 2
|
||||||
- id: BungoSeeds
|
- id: BungoSeeds
|
||||||
amount: 2
|
amount: 2
|
||||||
|
- id: GnomeSeeds
|
||||||
|
amount: 1
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: CrateHydroponicsSeedsMedicinal
|
id: CrateHydroponicsSeedsMedicinal
|
||||||
|
|||||||
@@ -125,7 +125,19 @@
|
|||||||
- id: Soap
|
- id: Soap
|
||||||
prob: 0.10
|
prob: 0.10
|
||||||
- id: PlushieCarp
|
- id: PlushieCarp
|
||||||
prob: 0.1
|
prob: 0.2
|
||||||
|
orGroup: carp
|
||||||
|
- id: ClothingHeadHatGnome
|
||||||
|
prob: 0.2
|
||||||
|
- id: PlushieHolocarp
|
||||||
|
prob: 0.05
|
||||||
|
orGroup: carp
|
||||||
|
- id: PlushieMagicarp
|
||||||
|
prob: 0.05
|
||||||
|
orGroup: carp
|
||||||
|
- id: PlushieRainbowCarp
|
||||||
|
prob: 0.03
|
||||||
|
orGroup: carp
|
||||||
- id: PlushieSlime
|
- id: PlushieSlime
|
||||||
prob: 0.1
|
prob: 0.1
|
||||||
- id: PlushieSnake
|
- id: PlushieSnake
|
||||||
|
|||||||
@@ -37,5 +37,7 @@
|
|||||||
BerrySeeds: 5
|
BerrySeeds: 5
|
||||||
PeaSeeds: 5
|
PeaSeeds: 5
|
||||||
CottonSeeds: 5
|
CottonSeeds: 5
|
||||||
|
contrabandInventory:
|
||||||
|
GnomeSeeds: 1
|
||||||
emaggedInventory:
|
emaggedInventory:
|
||||||
FlyAmanitaSeeds: 1
|
FlyAmanitaSeeds: 1
|
||||||
|
|||||||
@@ -1108,3 +1108,19 @@
|
|||||||
sprite: Clothing/Head/Hats/beret_medic.rsi
|
sprite: Clothing/Head/Hats/beret_medic.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Head/Hats/beret_medic.rsi
|
sprite: Clothing/Head/Hats/beret_medic.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ClothingHeadBase
|
||||||
|
id: ClothingHeadHatGnome
|
||||||
|
name: gnome hat
|
||||||
|
description: The cap of a true garden helper
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Clothing/Head/Hats/hat_gnome.rsi
|
||||||
|
- type: Clothing
|
||||||
|
sprite: Clothing/Head/Hats/hat_gnome.rsi
|
||||||
|
- type: Seed
|
||||||
|
seedId: gnome
|
||||||
|
- type: AddAccentClothing
|
||||||
|
accent: GnomeAccent
|
||||||
|
|
||||||
|
|||||||
@@ -819,3 +819,182 @@
|
|||||||
# - type: AlwaysRevolutionaryConvertible
|
# - type: AlwaysRevolutionaryConvertible
|
||||||
- type: StealTarget
|
- type: StealTarget
|
||||||
stealGroup: AnimalTropico
|
stealGroup: AnimalTropico
|
||||||
|
|
||||||
|
|
||||||
|
- type: entity #WHY MUST YOU THROW ERRORS HOW DARE YOU
|
||||||
|
name: Gnome #this thing is covered in comments, its for my sanity, ignore them please.
|
||||||
|
parent: [BaseSimpleMob, MobCombat, MobAtmosExposed]
|
||||||
|
id: MobGnome
|
||||||
|
description: "A garden's trusty helper"
|
||||||
|
components:
|
||||||
|
- type: Inventory
|
||||||
|
templateId: gnome
|
||||||
|
speciesId: gnome
|
||||||
|
- type: InventorySlots
|
||||||
|
- type: RotationVisuals
|
||||||
|
defaultRotation: 90
|
||||||
|
horizontalRotation: 90
|
||||||
|
- type: Fixtures
|
||||||
|
fixtures:
|
||||||
|
fix1:
|
||||||
|
shape:
|
||||||
|
!type:PhysShapeCircle #displays error, works anyways so i wont touch it, whatever it does
|
||||||
|
radius: 0.2
|
||||||
|
density: 80
|
||||||
|
mask:
|
||||||
|
- SmallMobMask #lets em go under doors for escapes from sec/greytide/hunting mice
|
||||||
|
layer:
|
||||||
|
- SmallMobLayer
|
||||||
|
- type: Stripping
|
||||||
|
- type: Strippable
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.StrippingUiKey.Key
|
||||||
|
type: StrippableBoundUserInterface
|
||||||
|
- type: GhostRole
|
||||||
|
prob: 1
|
||||||
|
makeSentient: true
|
||||||
|
allowSpeech: true
|
||||||
|
allowMovement: true
|
||||||
|
name: ghost-role-information-gnome-name
|
||||||
|
description: ghost-role-information-gnome-description
|
||||||
|
raffle:
|
||||||
|
settings: short
|
||||||
|
- type: GhostTakeoverAvailable
|
||||||
|
- type: Flashable
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- CannotSuicide
|
||||||
|
- VimPilot
|
||||||
|
- type: MobThresholds
|
||||||
|
thresholds: #VERY easy to kill, if it was harder to kill them the sneaky fuckers would rule the world
|
||||||
|
0: Alive
|
||||||
|
10: Dead
|
||||||
|
- type: DamageStateVisuals
|
||||||
|
states:
|
||||||
|
Alive:
|
||||||
|
Base: Gnome-0
|
||||||
|
Dead:
|
||||||
|
Base: dead-1
|
||||||
|
- type: GnomeAccent
|
||||||
|
- type: NameIdentifier
|
||||||
|
group: Gnome
|
||||||
|
- type: Sprite
|
||||||
|
drawdepth: SmallMobs
|
||||||
|
sprite: Mobs/Animals/gnome.rsi
|
||||||
|
layers:
|
||||||
|
- map: ["enum.DamageStateVisualLayers.Base"]
|
||||||
|
state: Gnome-0
|
||||||
|
- type: Item
|
||||||
|
size: Small
|
||||||
|
- type: Clothing #TO VALLHALLA
|
||||||
|
quickEquip: false
|
||||||
|
sprite: Mobs/Animals/gnome.rsi
|
||||||
|
equippedPrefix: 1
|
||||||
|
slots:
|
||||||
|
- HEAD
|
||||||
|
- type: IdExaminable
|
||||||
|
- type: InteractionPopup
|
||||||
|
interactSuccessString: hugging-success-generic
|
||||||
|
interactSuccessSound: /Audio/Effects/thudswoosh.ogg
|
||||||
|
messagePerceivedByOthers: hugging-success-generic-others
|
||||||
|
- type: MeleeWeapon
|
||||||
|
soundHit:
|
||||||
|
collection: ToySqueak
|
||||||
|
angle: 30
|
||||||
|
animation: WeaponArcPunch
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Piercing: 3
|
||||||
|
- type: Puller #dont need hands because they are at a disadvantage anyway, this way they can hold a light and drag a box for a backpack
|
||||||
|
needsHands: false
|
||||||
|
- type: CanHostGuardian #touch this stuff to make the fuckers hold still when not possesed (NOT THE GAURDIAN)
|
||||||
|
- type: FactionException
|
||||||
|
- type: NpcFactionMember
|
||||||
|
factions:
|
||||||
|
- Passive
|
||||||
|
- type: Hands #gives em hands, the item sprites for holding things look all strange but its FINE, I DONT WANNA FIX IT ITS FINE ILL DO IT LATER
|
||||||
|
- type: Body #gives em a body, is needed for organs and hands
|
||||||
|
prototype: gnome
|
||||||
|
requiredLegs: 0
|
||||||
|
- type: Clumsy #no guns for youuuu if they shoot a gun they die >:3
|
||||||
|
clumsyDamage:
|
||||||
|
types:
|
||||||
|
Blunt: 2
|
||||||
|
Piercing: 7
|
||||||
|
groups:
|
||||||
|
Burn: 2
|
||||||
|
clumsySound:
|
||||||
|
path: /Audio/Voice/Gnome/Gnome_Clumsy_Sound_Effect.ogg
|
||||||
|
- type: Barotrauma #gnomes instantly explode in space, gnomes shouldnt go in space
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 20 #per second, scales with pressure and other constants.
|
||||||
|
- type: Repairable
|
||||||
|
fuelCost: 5
|
||||||
|
qualityNeeded: Gluing
|
||||||
|
doAfterDelay: 8
|
||||||
|
- type: ZombieImmune
|
||||||
|
- type: Damageable
|
||||||
|
damageContainer: StructuralInorganic
|
||||||
|
- type: CanEscapeInventory
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTypeTrigger #gnomes gib once they are in enough bits that they cant be glued back together
|
||||||
|
damageType: Blunt
|
||||||
|
damage: 60
|
||||||
|
behaviors:
|
||||||
|
- !type:PlaySoundBehavior
|
||||||
|
sound:
|
||||||
|
collection: GlassBreak
|
||||||
|
- !type:SpawnEntitiesBehavior
|
||||||
|
spawn:
|
||||||
|
ClothingHeadHatGnome:
|
||||||
|
min: 1
|
||||||
|
max: 1
|
||||||
|
ShardGlass:
|
||||||
|
min: 1
|
||||||
|
max: 3
|
||||||
|
- !type:DoActsBehavior
|
||||||
|
acts: [ "Destruction" ]
|
||||||
|
- type: DamageOnHighSpeedImpact #gnomes break when thrown, another anti gnometide device
|
||||||
|
minimumSpeed: 10
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 20
|
||||||
|
soundHit:
|
||||||
|
collection: GlassBreak
|
||||||
|
- type: Vocal
|
||||||
|
sounds:
|
||||||
|
Male: Gnome
|
||||||
|
Female: Gnome
|
||||||
|
Unsexed: Gnome
|
||||||
|
wilhelmProbability: 0.0001
|
||||||
|
- type: Unrevivable
|
||||||
|
- type: Tool
|
||||||
|
qualities:
|
||||||
|
- Screwing
|
||||||
|
useSound:
|
||||||
|
collection: Screwdriver
|
||||||
|
- type: FelinidFood
|
||||||
|
- type: Speech
|
||||||
|
speechSounds: GnomesSpeech
|
||||||
|
speechVerb: SmallMob
|
||||||
|
- type: Extractable
|
||||||
|
grindableSolutionName: food
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
food:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: UnstableMutagen
|
||||||
|
Quantity: 5
|
||||||
|
- type: BadFood
|
||||||
|
- type: DeathGasps
|
||||||
|
deathSounds:
|
||||||
|
collection: GnomesDeathCollection
|
||||||
|
canOtherHearDeathSound: True
|
||||||
|
- type: Thieving
|
||||||
|
stripTimeReduction: 4
|
||||||
|
- type: Pacified
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
map: [ "enum.SolutionContainerLayers.Overlay" ]
|
map: [ "enum.SolutionContainerLayers.Overlay" ]
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
- type: Glue
|
- type: Glue
|
||||||
|
- type: RefillableSolution
|
||||||
|
solution: drink
|
||||||
- type: SolutionContainerManager
|
- type: SolutionContainerManager
|
||||||
solutions:
|
solutions:
|
||||||
drink:
|
drink:
|
||||||
@@ -26,6 +28,11 @@
|
|||||||
reagents:
|
reagents:
|
||||||
- ReagentId: SpaceGlue
|
- ReagentId: SpaceGlue
|
||||||
Quantity: 30
|
Quantity: 30
|
||||||
|
Welder:
|
||||||
|
reagents:
|
||||||
|
- ReagentId: SpaceGlue
|
||||||
|
Quantity: 30
|
||||||
|
maxVol: 30
|
||||||
- type: SolutionContainerVisuals
|
- type: SolutionContainerVisuals
|
||||||
maxFillLevels: 6
|
maxFillLevels: 6
|
||||||
fillBaseName: fill
|
fillBaseName: fill
|
||||||
@@ -38,8 +45,15 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- DrinkSpaceGlue
|
- DrinkSpaceGlue
|
||||||
|
- GlueTool
|
||||||
- type: TrashOnSolutionEmpty
|
- type: TrashOnSolutionEmpty
|
||||||
solution: drink
|
solution: drink
|
||||||
|
- type: Tool
|
||||||
|
qualities: Gluing
|
||||||
|
- type: Welder #this here uses welding code to take fuel out of the bottle (fuel being glue)
|
||||||
|
fuelSolutionName: drink
|
||||||
|
fuelReagent: SpaceGlue
|
||||||
|
hiddenInfo: true
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: DrinkBase
|
parent: DrinkBase
|
||||||
|
|||||||
@@ -1514,6 +1514,8 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- DrinkSpaceGlue
|
- DrinkSpaceGlue
|
||||||
|
- type: Tool
|
||||||
|
qualities: Gluing
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
|
|||||||
@@ -571,3 +571,13 @@
|
|||||||
seedId: cotton
|
seedId: cotton
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Specific/Hydroponics/cotton.rsi
|
sprite: Objects/Specific/Hydroponics/cotton.rsi
|
||||||
|
|
||||||
|
- type: entity #you should never see this, this is for testing, if someone has these then I FUCKED UP and you should ping BITTERLYNX
|
||||||
|
parent: SeedBase
|
||||||
|
name: packet of Gnome seeds
|
||||||
|
id: GnomeSeeds
|
||||||
|
components:
|
||||||
|
- type: Seed
|
||||||
|
seedId: gnome
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/cotton.rsi
|
||||||
|
|||||||
@@ -1501,3 +1501,22 @@
|
|||||||
Max: 10
|
Max: 10
|
||||||
PotencyDivisor: 20
|
PotencyDivisor: 20
|
||||||
|
|
||||||
|
- type: seed #once again, replacing learning with comments because ive been in this file for 10 hours
|
||||||
|
id: gnome
|
||||||
|
name: seeds-gome-name #the name of the seeds
|
||||||
|
noun: seeds-noun-seeds
|
||||||
|
displayName: seeds-gnome-display-name #name of the plant when looking at the tray
|
||||||
|
plantRsi: Objects/Specific/Hydroponics/gnome.rsi
|
||||||
|
packetPrototype: GnomeSeeds #seeds you get when clipping? BUT YOU CANT CLIP THIS PLANT TAKE THAT BOTANISTS!
|
||||||
|
productPrototypes:
|
||||||
|
- MobGnome #THE THING THAT SPAWNS!
|
||||||
|
lifespan: 25
|
||||||
|
maturation: 10
|
||||||
|
production: 1
|
||||||
|
yield: 1
|
||||||
|
potency: 1
|
||||||
|
idealLight: 8
|
||||||
|
growthStages: 2
|
||||||
|
waterConsumption: 0
|
||||||
|
seedless: true #fuckin does nothing but im keeping it just in case someone wants botany to riot
|
||||||
|
unclippable: true
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
- type: inventoryTemplate
|
||||||
|
id: gnome
|
||||||
|
#slots: i was on the fence to give them an id slot so ill comment this out for now
|
||||||
|
# - name: id
|
||||||
|
# slotTexture: id
|
||||||
|
# slotFlags: IDCARD
|
||||||
|
# slotGroup: SecondHotbar
|
||||||
|
# stripTime: 6
|
||||||
|
# uiWindowPos: 2,1
|
||||||
|
# strippingWindowPos: 2,4
|
||||||
|
# dependsOn: jumpsuit
|
||||||
|
# displayName: ID
|
||||||
|
|
||||||
@@ -32,12 +32,5 @@
|
|||||||
icon:
|
icon:
|
||||||
sprite: Objects/Misc/stock_parts.rsi
|
sprite: Objects/Misc/stock_parts.rsi
|
||||||
state: capacitor
|
state: capacitor
|
||||||
doAfter: 5
|
|
||||||
- tag: CapacitorStockPart
|
|
||||||
name: capacitor
|
|
||||||
icon:
|
|
||||||
sprite: Objects/Misc/stock_parts.rsi
|
|
||||||
state: capacitor
|
|
||||||
doAfter: 5
|
|
||||||
- node: medsecHud
|
- node: medsecHud
|
||||||
entity: ClothingEyesHudMedSec
|
entity: ClothingEyesHudMedSec
|
||||||
|
|||||||
@@ -65,10 +65,5 @@
|
|||||||
icon:
|
icon:
|
||||||
sprite: Objects/Misc/stock_parts.rsi
|
sprite: Objects/Misc/stock_parts.rsi
|
||||||
state: capacitor
|
state: capacitor
|
||||||
- tag: CapacitorStockPart
|
|
||||||
name: capacitor
|
|
||||||
icon:
|
|
||||||
sprite: Objects/Misc/stock_parts.rsi
|
|
||||||
state: capacitor
|
|
||||||
- node: potatoaichip
|
- node: potatoaichip
|
||||||
entity: PotatoAIChip
|
entity: PotatoAIChip
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
weight: 10
|
weight: 10
|
||||||
startingGear: QuartermasterGear
|
startingGear: QuartermasterGear
|
||||||
icon: "JobIconQuarterMaster"
|
icon: "JobIconQuarterMaster"
|
||||||
|
announcementPrototype: QuartermasterArrivalNotification
|
||||||
supervisors: job-supervisors-captain
|
supervisors: job-supervisors-captain
|
||||||
whitelistedSpecies:
|
whitelistedSpecies:
|
||||||
- Human
|
- Human
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
icon: "JobIconCaptain"
|
icon: "JobIconCaptain"
|
||||||
requireAdminNotify: true
|
requireAdminNotify: true
|
||||||
joinNotifyCrew: true
|
joinNotifyCrew: true
|
||||||
|
announcementPrototype: CaptainArrivalNotification
|
||||||
supervisors: job-supervisors-centcom
|
supervisors: job-supervisors-centcom
|
||||||
whitelistedSpecies:
|
whitelistedSpecies:
|
||||||
- Human
|
- Human
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
startingGear: HoPGear
|
startingGear: HoPGear
|
||||||
icon: "JobIconHeadOfPersonnel"
|
icon: "JobIconHeadOfPersonnel"
|
||||||
requireAdminNotify: true
|
requireAdminNotify: true
|
||||||
|
announcementPrototype: HeadOfPersonnelArrivalNotification
|
||||||
supervisors: job-supervisors-captain
|
supervisors: job-supervisors-captain
|
||||||
whitelistedSpecies:
|
whitelistedSpecies:
|
||||||
- Human
|
- Human
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
startingGear: ChiefEngineerGear
|
startingGear: ChiefEngineerGear
|
||||||
icon: "JobIconChiefEngineer"
|
icon: "JobIconChiefEngineer"
|
||||||
requireAdminNotify: true
|
requireAdminNotify: true
|
||||||
|
announcementPrototype: ChiefEngineerArrivalNotification
|
||||||
supervisors: job-supervisors-captain
|
supervisors: job-supervisors-captain
|
||||||
whitelistedSpecies:
|
whitelistedSpecies:
|
||||||
- Human
|
- Human
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
time: 36000 #10 hrs
|
time: 36000 #10 hrs
|
||||||
startingGear: InspectorGear
|
startingGear: InspectorGear
|
||||||
icon: "JobIconInspector"
|
icon: "JobIconInspector"
|
||||||
|
announcementPrototype: InspectorArrivalNotification
|
||||||
supervisors: job-supervisors-captain
|
supervisors: job-supervisors-captain
|
||||||
access:
|
access:
|
||||||
- Service
|
- Service
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
weight: 10
|
weight: 10
|
||||||
startingGear: CMOGear
|
startingGear: CMOGear
|
||||||
icon: "JobIconChiefMedicalOfficer"
|
icon: "JobIconChiefMedicalOfficer"
|
||||||
|
announcementPrototype: ChiefMedicalOfficerArrivalNotification
|
||||||
requireAdminNotify: true
|
requireAdminNotify: true
|
||||||
supervisors: job-supervisors-captain
|
supervisors: job-supervisors-captain
|
||||||
whitelistedSpecies:
|
whitelistedSpecies:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
startingGear: ResearchDirectorGear
|
startingGear: ResearchDirectorGear
|
||||||
icon: "JobIconResearchDirector"
|
icon: "JobIconResearchDirector"
|
||||||
requireAdminNotify: true
|
requireAdminNotify: true
|
||||||
|
announcementPrototype: ResearchDirectorArrivalNotification
|
||||||
supervisors: job-supervisors-captain
|
supervisors: job-supervisors-captain
|
||||||
whitelistedSpecies:
|
whitelistedSpecies:
|
||||||
- Human
|
- Human
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
startingGear: HoSGear
|
startingGear: HoSGear
|
||||||
icon: "JobIconHeadOfSecurity"
|
icon: "JobIconHeadOfSecurity"
|
||||||
requireAdminNotify: true
|
requireAdminNotify: true
|
||||||
|
announcementPrototype: HeadOfSecurityArrivalNotification
|
||||||
supervisors: job-supervisors-captain
|
supervisors: job-supervisors-captain
|
||||||
whitelistedSpecies:
|
whitelistedSpecies:
|
||||||
- Human
|
- Human
|
||||||
|
|||||||
@@ -620,3 +620,13 @@
|
|||||||
path: /Audio/Animals/parrot_raught.ogg
|
path: /Audio/Animals/parrot_raught.ogg
|
||||||
params:
|
params:
|
||||||
variation: 0.125
|
variation: 0.125
|
||||||
|
|
||||||
|
- type: emoteSounds
|
||||||
|
id: Gnome
|
||||||
|
params:
|
||||||
|
variation: 0.125
|
||||||
|
sounds:
|
||||||
|
Scream:
|
||||||
|
path: /Audio/Voice/Gnome/Gnome_Woo_Sound_Effect.ogg
|
||||||
|
Weh:
|
||||||
|
collection: Weh
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: InstantAction
|
- type: InstantAction
|
||||||
useDelay: 1.5
|
useDelay: 2.5
|
||||||
itemIconStyle: BigAction
|
itemIconStyle: BigAction
|
||||||
priority: -20
|
priority: -20
|
||||||
icon:
|
icon:
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
- type: arrivalNotification
|
||||||
|
id: CaptainArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
globalMessage: head-arrived-message-global
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Command
|
||||||
|
useGlobalAnnouncement: True
|
||||||
|
|
||||||
|
- type: arrivalNotification
|
||||||
|
id: HeadOfPersonnelArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Service
|
||||||
|
|
||||||
|
- type: arrivalNotification
|
||||||
|
id: HeadOfSecurityArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Security
|
||||||
|
|
||||||
|
- type: arrivalNotification
|
||||||
|
id: ChiefMedicalOfficerArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Medical
|
||||||
|
|
||||||
|
- type: arrivalNotification
|
||||||
|
id: ChiefEngineerArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Engineering
|
||||||
|
|
||||||
|
- type: arrivalNotification
|
||||||
|
id: ResearchDirectorArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Science
|
||||||
|
|
||||||
|
- type: arrivalNotification
|
||||||
|
id: QuartermasterArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Cargo
|
||||||
|
|
||||||
|
- type: arrivalNotification
|
||||||
|
id: InspectorArrivalNotification
|
||||||
|
message: head-arrived-message
|
||||||
|
radioChannelsPrototypes:
|
||||||
|
- Security
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
icon: { sprite: /Textures/White/Objects/Weapons/hardlight_spear.rsi, state: spear }
|
icon: { sprite: /Textures/White/Objects/Weapons/hardlight_spear.rsi, state: spear }
|
||||||
productEntity: HardlightSpearImplanter
|
productEntity: HardlightSpearImplanter
|
||||||
cost:
|
cost:
|
||||||
Telecrystal: 12
|
Telecrystal: 10
|
||||||
categories:
|
categories:
|
||||||
- UplinkImplants
|
- UplinkImplants
|
||||||
conditions:
|
conditions:
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
- type: DamageOtherOnHit
|
- type: DamageOtherOnHit
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Piercing: 20
|
Piercing: 30
|
||||||
Heat: 20
|
Heat: 30
|
||||||
- type: Wieldable
|
- type: Wieldable
|
||||||
- type: IncreaseDamageOnWield
|
- type: IncreaseDamageOnWield
|
||||||
damage:
|
damage:
|
||||||
|
|||||||
@@ -61,8 +61,8 @@
|
|||||||
ckey: reider207
|
ckey: reider207
|
||||||
sprite: White/Ghosts/reider207-ghost.rsi
|
sprite: White/Ghosts/reider207-ghost.rsi
|
||||||
alpha: 0.8
|
alpha: 0.8
|
||||||
ghostName: Соня
|
ghostName: Tighnari
|
||||||
ghostDescription: Видишь спит соня? Так не буди
|
ghostDescription: But what are they going to do, lock me up?
|
||||||
size: 0.8, 0.8
|
size: 0.8, 0.8
|
||||||
|
|
||||||
#mikvisan
|
#mikvisan
|
||||||
|
|||||||
8
Resources/Prototypes/_White/Sound/Speech/gnomes.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
- type: speechSounds
|
||||||
|
id: GnomesSpeech
|
||||||
|
saySound:
|
||||||
|
collection: GnomesSpeechCollection
|
||||||
|
askSound:
|
||||||
|
collection: GnomesSpeechCollection
|
||||||
|
exclaimSound:
|
||||||
|
collection: GnomesSpeechCollection
|
||||||
19
Resources/Prototypes/_White/SoundCollections/gnomes.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
- type: soundCollection
|
||||||
|
id: GnomesSpeechCollection
|
||||||
|
files:
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome1V1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome2V1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome3V1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome4V1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome5V1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome6V1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome7V1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Gnome8V1.ogg
|
||||||
|
|
||||||
|
- type: soundCollection
|
||||||
|
id: GnomesDeathCollection
|
||||||
|
files:
|
||||||
|
- /Audio/White/Voice/Gnomes/Death1.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Death2.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Death3.ogg
|
||||||
|
- /Audio/White/Voice/Gnomes/Death4.ogg
|
||||||
12
Resources/Prototypes/_White/Spawners/spawners.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
- type: entity
|
||||||
|
name: Gnome spawner
|
||||||
|
id: SpawnMobGnome
|
||||||
|
parent: MarkerBase
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: green
|
||||||
|
- state: ai
|
||||||
|
- type: ConditionalSpawner
|
||||||
|
prototypes:
|
||||||
|
- MobGnome
|
||||||
@@ -15,12 +15,15 @@
|
|||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
|
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
|
||||||
slots:
|
slots:
|
||||||
- back
|
- none
|
||||||
- suitStorage
|
|
||||||
- type: Reflect
|
- type: Reflect
|
||||||
reflectProb: 0.4
|
reflectProb: 0.4
|
||||||
- type: Item
|
- type: Item
|
||||||
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
|
sprite: White/Objects/Weapons/Chaplain/hfrequency.rsi
|
||||||
|
size: Large
|
||||||
|
storedRotation: 44
|
||||||
|
shape:
|
||||||
|
- 0, 0, 3, 0
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: клинок заклинаний
|
name: клинок заклинаний
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
rules:
|
rules:
|
||||||
- RampingStationEventScheduler
|
- RampingStationEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
- GameRuleMeteorScheduler
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: AllAtOnce
|
id: AllAtOnce
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
- Cult
|
- Cult
|
||||||
- Wizard
|
- Wizard
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
- GameRuleMeteorScheduler
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: Extended
|
id: Extended
|
||||||
@@ -175,6 +177,7 @@
|
|||||||
- Pirates
|
- Pirates
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
- GameRuleMeteorScheduler
|
||||||
|
|
||||||
#WD EDIT START
|
#WD EDIT START
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
@@ -190,6 +193,7 @@
|
|||||||
- SubGamemodesRule
|
- SubGamemodesRule
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
- GameRuleMeteorScheduler
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: Changeling
|
id: Changeling
|
||||||
@@ -204,6 +208,7 @@
|
|||||||
- SubGamemodesRule
|
- SubGamemodesRule
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
- GameRuleMeteorScheduler
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: Wizard
|
id: Wizard
|
||||||
@@ -219,4 +224,5 @@
|
|||||||
- SubGamemodesRule
|
- SubGamemodesRule
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
- GameRuleMeteorScheduler
|
||||||
#WD EDIT END
|
#WD EDIT END
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
# Non-fungible apes, anyone?
|
# Non-fungible apes, anyone?
|
||||||
- type: nameIdentifierGroup
|
- type: nameIdentifierGroup
|
||||||
id: Monkey
|
id: Monkey
|
||||||
prefix: MK
|
prefix: MK
|
||||||
|
|
||||||
|
- type: nameIdentifierGroup
|
||||||
|
id: Gnome
|
||||||
|
prefix: GN
|
||||||
|
|
||||||
- type: nameIdentifierGroup
|
- type: nameIdentifierGroup
|
||||||
id: Kobold
|
id: Kobold
|
||||||
prefix: KB
|
prefix: KB
|
||||||
|
|||||||
@@ -644,6 +644,9 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
id: Grenade
|
id: Grenade
|
||||||
|
|
||||||
|
- type: Tag # tag to make a glue tool use glue on repair
|
||||||
|
id: GlueTool
|
||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: HudMedical
|
id: HudMedical
|
||||||
|
|
||||||
@@ -1325,5 +1328,3 @@
|
|||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: WriteIgnoreStamps
|
id: WriteIgnoreStamps
|
||||||
|
|
||||||
# ALPHABETICAL
|
|
||||||
|
|||||||
@@ -74,3 +74,10 @@
|
|||||||
toolName: tool-quality-rolling-tool-name
|
toolName: tool-quality-rolling-tool-name
|
||||||
spawn: RollingPin
|
spawn: RollingPin
|
||||||
icon: { sprite: Objects/Tools/rolling_pin.rsi, state: icon }
|
icon: { sprite: Objects/Tools/rolling_pin.rsi, state: icon }
|
||||||
|
|
||||||
|
- type: tool
|
||||||
|
id: Gluing
|
||||||
|
name: tool-quality-gluing-name
|
||||||
|
toolName: tool-quality-rolling-tool-name
|
||||||
|
spawn: DrinkSpaceGlue
|
||||||
|
icon: { sprite: Objects/Tools/rolling_pin.rsi, state: icon }
|
||||||
|
|||||||
|
After Width: | Height: | Size: 368 B |
BIN
Resources/Textures/Clothing/Head/Hats/hat_gnome.rsi/icon.png
Normal file
|
After Width: | Height: | Size: 631 B |
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Sprited by DanoftheE (Discord)",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "equipped-HELMET",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Resources/Textures/Mobs/Animals/gnome.rsi/0-equipped-HELMET.png
Normal file
|
After Width: | Height: | Size: 827 B |
BIN
Resources/Textures/Mobs/Animals/gnome.rsi/1-equipped-HELMET.png
Normal file
|
After Width: | Height: | Size: 827 B |
BIN
Resources/Textures/Mobs/Animals/gnome.rsi/Gnome-0.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/Textures/Mobs/Animals/gnome.rsi/Gnome-1.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/Textures/Mobs/Animals/gnome.rsi/dead-1.png
Normal file
|
After Width: | Height: | Size: 430 B |
63
Resources/Textures/Mobs/Animals/gnome.rsi/meta.json
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Sprited by DanoftheE (Discord)",
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "dead-1",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gnome-0",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gnome-1",
|
||||||
|
"directions": 4,
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "0-equipped-HELMET",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "1-equipped-HELMET",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 444 B |
|
After Width: | Height: | Size: 443 B |
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Sprited by DanoftheE (Discord)",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "dead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "harvest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stage-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stage-2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 173 B |
|
After Width: | Height: | Size: 246 B |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 18 KiB |
@@ -3,8 +3,8 @@
|
|||||||
"license": "CC-BY-SA-3.0",
|
"license": "CC-BY-SA-3.0",
|
||||||
"copyright": "reider207",
|
"copyright": "reider207",
|
||||||
"size": {
|
"size": {
|
||||||
"x": 64,
|
"x": 128,
|
||||||
"y": 64
|
"y": 128
|
||||||
},
|
},
|
||||||
"states": [
|
"states": [
|
||||||
{
|
{
|
||||||
|
|||||||