Eye damage (#10262)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using Content.Client.Verbs;
|
using Content.Client.Verbs;
|
||||||
|
using Content.Shared.Eye.Blinding;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
@@ -116,7 +117,7 @@ namespace Content.Client.Examine
|
|||||||
// Tooltips coming in from the server generally prioritize
|
// Tooltips coming in from the server generally prioritize
|
||||||
// opening at the old tooltip rather than the cursor/another entity,
|
// opening at the old tooltip rather than the cursor/another entity,
|
||||||
// since there's probably one open already if it's coming in from the server.
|
// since there's probably one open already if it's coming in from the server.
|
||||||
OpenTooltip(player.Value, ev.EntityUid, ev.CenterAtCursor, ev.OpenAtOldTooltip);
|
OpenTooltip(player.Value, ev.EntityUid, ev.CenterAtCursor, ev.OpenAtOldTooltip, ev.KnowTarget);
|
||||||
UpdateTooltipInfo(player.Value, ev.EntityUid, ev.Message, ev.Verbs);
|
UpdateTooltipInfo(player.Value, ev.EntityUid, ev.Message, ev.Verbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ namespace Content.Client.Examine
|
|||||||
/// not fill it with information. This is done when the server sends examine info/verbs,
|
/// not fill it with information. This is done when the server sends examine info/verbs,
|
||||||
/// or immediately if it's entirely clientside.
|
/// or immediately if it's entirely clientside.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OpenTooltip(EntityUid player, EntityUid target, bool centeredOnCursor=true, bool openAtOldTooltip=true)
|
public void OpenTooltip(EntityUid player, EntityUid target, bool centeredOnCursor=true, bool openAtOldTooltip=true, bool knowTarget = true)
|
||||||
{
|
{
|
||||||
// Close any examine tooltip that might already be opened
|
// Close any examine tooltip that might already be opened
|
||||||
// Before we do that, save its position. We'll prioritize opening any new popups there if
|
// Before we do that, save its position. We'll prioritize opening any new popups there if
|
||||||
@@ -191,11 +192,22 @@ namespace Content.Client.Examine
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hBox.AddChild(new Label
|
if (knowTarget)
|
||||||
{
|
{
|
||||||
Text = Identity.Name(target, EntityManager, player),
|
hBox.AddChild(new Label
|
||||||
HorizontalExpand = true,
|
{
|
||||||
});
|
Text = Identity.Name(target, EntityManager, player),
|
||||||
|
HorizontalExpand = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hBox.AddChild(new Label
|
||||||
|
{
|
||||||
|
Text = "???",
|
||||||
|
HorizontalExpand = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
panel.Measure(Vector2.Infinity);
|
panel.Measure(Vector2.Infinity);
|
||||||
var size = Vector2.ComponentMax((minWidth, 0), panel.DesiredSize);
|
var size = Vector2.ComponentMax((minWidth, 0), panel.DesiredSize);
|
||||||
@@ -294,7 +306,13 @@ namespace Content.Client.Examine
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
FormattedMessage message;
|
FormattedMessage message;
|
||||||
OpenTooltip(playerEnt.Value, entity, centeredOnCursor, false);
|
|
||||||
|
// Basically this just predicts that we can't make out the entity if we have poor vision.
|
||||||
|
var canSeeClearly = true;
|
||||||
|
if (HasComp<BlurryVisionComponent>(playerEnt))
|
||||||
|
canSeeClearly = false;
|
||||||
|
|
||||||
|
OpenTooltip(playerEnt.Value, entity, centeredOnCursor, false, knowTarget: canSeeClearly);
|
||||||
if (entity.IsClientSide())
|
if (entity.IsClientSide())
|
||||||
{
|
{
|
||||||
message = GetExamineText(entity, playerEnt);
|
message = GetExamineText(entity, playerEnt);
|
||||||
|
|||||||
68
Content.Client/Eye/Blinding/BlurryVisionOverlay.cs
Normal file
68
Content.Client/Eye/Blinding/BlurryVisionOverlay.cs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.Enums;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Content.Shared.Eye.Blinding;
|
||||||
|
|
||||||
|
namespace Content.Client.Eye.Blinding
|
||||||
|
{
|
||||||
|
public sealed class BlurryVisionOverlay : Overlay
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
|
|
||||||
|
public override bool RequestScreenTexture => true;
|
||||||
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||||
|
private readonly ShaderInstance _blurryVisionXShader;
|
||||||
|
private readonly ShaderInstance _blurryVisionYShader;
|
||||||
|
private BlurryVisionComponent _blurryVisionComponent = default!;
|
||||||
|
|
||||||
|
public BlurryVisionOverlay()
|
||||||
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
_blurryVisionXShader = _prototypeManager.Index<ShaderPrototype>("BlurryVisionX").InstanceUnique();
|
||||||
|
_blurryVisionYShader = _prototypeManager.Index<ShaderPrototype>("BlurryVisionY").InstanceUnique();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||||
|
{
|
||||||
|
var playerEntity = _playerManager.LocalPlayer?.ControlledEntity;
|
||||||
|
|
||||||
|
if (playerEntity == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!_entityManager.TryGetComponent<BlurryVisionComponent>(playerEntity, out var blurComp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!blurComp.Active)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_entityManager.TryGetComponent<BlindableComponent>(playerEntity, out var blindComp)
|
||||||
|
&& blindComp.Sources > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_blurryVisionComponent = blurComp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(in OverlayDrawArgs args)
|
||||||
|
{
|
||||||
|
if (ScreenTexture == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_blurryVisionXShader?.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||||
|
_blurryVisionXShader?.SetParameter("BLUR_AMOUNT", (_blurryVisionComponent.Magnitude / 10));
|
||||||
|
_blurryVisionYShader?.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||||
|
_blurryVisionYShader?.SetParameter("BLUR_AMOUNT", (_blurryVisionComponent.Magnitude / 10));
|
||||||
|
|
||||||
|
var worldHandle = args.WorldHandle;
|
||||||
|
var viewport = args.WorldBounds;
|
||||||
|
worldHandle.SetTransform(Matrix3.Identity);
|
||||||
|
worldHandle.UseShader(_blurryVisionXShader);
|
||||||
|
worldHandle.DrawRect(viewport, Color.White);
|
||||||
|
worldHandle.UseShader(_blurryVisionYShader);
|
||||||
|
worldHandle.DrawRect(viewport, Color.White);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
61
Content.Client/Eye/Blinding/BlurryVisionSystem.cs
Normal file
61
Content.Client/Eye/Blinding/BlurryVisionSystem.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using Content.Shared.Eye.Blinding;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Client.Eye.Blinding;
|
||||||
|
|
||||||
|
public sealed class BlurryVisionSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPlayerManager _player = default!;
|
||||||
|
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||||
|
private BlurryVisionOverlay _overlay = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<BlurryVisionComponent, ComponentInit>(OnBlurryInit);
|
||||||
|
SubscribeLocalEvent<BlurryVisionComponent, ComponentShutdown>(OnBlurryShutdown);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<BlurryVisionComponent, PlayerAttachedEvent>(OnPlayerAttached);
|
||||||
|
SubscribeLocalEvent<BlurryVisionComponent, PlayerDetachedEvent>(OnPlayerDetached);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<BlurryVisionComponent, ComponentHandleState>(OnHandleState);
|
||||||
|
|
||||||
|
_overlay = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, PlayerAttachedEvent args)
|
||||||
|
{
|
||||||
|
_overlayMan.AddOverlay(_overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, PlayerDetachedEvent args)
|
||||||
|
{
|
||||||
|
_overlayMan.RemoveOverlay(_overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBlurryInit(EntityUid uid, BlurryVisionComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
if (_player.LocalPlayer?.ControlledEntity == uid)
|
||||||
|
_overlayMan.AddOverlay(_overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBlurryShutdown(EntityUid uid, BlurryVisionComponent component, ComponentShutdown args)
|
||||||
|
{
|
||||||
|
if (_player.LocalPlayer?.ControlledEntity == uid)
|
||||||
|
{
|
||||||
|
_overlayMan.RemoveOverlay(_overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnHandleState(EntityUid uid, BlurryVisionComponent component, ref ComponentHandleState args)
|
||||||
|
{
|
||||||
|
if (args.Current is not BlurryVisionComponentState state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
component.Magnitude = state.Magnitude;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Content.Server/Chemistry/ReagentEffects/ChemHealEyeDamage.cs
Normal file
23
Content.Server/Chemistry/ReagentEffects/ChemHealEyeDamage.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Content.Shared.Chemistry.Reagent;
|
||||||
|
using Content.Shared.Eye.Blinding;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Content.Server.Chemistry.ReagentEffects
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Heal eye damage (or deal)
|
||||||
|
/// </summary>
|
||||||
|
[UsedImplicitly]
|
||||||
|
public sealed class ChemHealEyeDamage : ReagentEffect
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Add or remove eye damage?
|
||||||
|
[DataField("add")]
|
||||||
|
public bool Add = false;
|
||||||
|
|
||||||
|
public override void Effect(ReagentEffectArgs args)
|
||||||
|
{
|
||||||
|
EntitySystem.Get<SharedBlindingSystem>().AdjustEyeDamage(args.SolutionEntity, Add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,10 +16,14 @@ namespace Content.Server.Examine
|
|||||||
|
|
||||||
private static readonly FormattedMessage _entityNotFoundMessage;
|
private static readonly FormattedMessage _entityNotFoundMessage;
|
||||||
|
|
||||||
|
private static readonly FormattedMessage _entityOutOfRangeMessage;
|
||||||
|
|
||||||
static ExamineSystem()
|
static ExamineSystem()
|
||||||
{
|
{
|
||||||
_entityNotFoundMessage = new FormattedMessage();
|
_entityNotFoundMessage = new FormattedMessage();
|
||||||
_entityNotFoundMessage.AddText(Loc.GetString("examine-system-entity-does-not-exist"));
|
_entityNotFoundMessage.AddText(Loc.GetString("examine-system-entity-does-not-exist"));
|
||||||
|
_entityOutOfRangeMessage = new FormattedMessage();
|
||||||
|
_entityOutOfRangeMessage.AddText(Loc.GetString("examine-system-cant-see-entity"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -54,14 +58,20 @@ namespace Content.Server.Examine
|
|||||||
var channel = player.ConnectedClient;
|
var channel = player.ConnectedClient;
|
||||||
|
|
||||||
if (session.AttachedEntity is not {Valid: true} playerEnt
|
if (session.AttachedEntity is not {Valid: true} playerEnt
|
||||||
|| !EntityManager.EntityExists(request.EntityUid)
|
|| !EntityManager.EntityExists(request.EntityUid))
|
||||||
|| !CanExamine(playerEnt, request.EntityUid))
|
|
||||||
{
|
{
|
||||||
RaiseNetworkEvent(new ExamineSystemMessages.ExamineInfoResponseMessage(
|
RaiseNetworkEvent(new ExamineSystemMessages.ExamineInfoResponseMessage(
|
||||||
request.EntityUid, _entityNotFoundMessage), channel);
|
request.EntityUid, _entityNotFoundMessage), channel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CanExamine(playerEnt, request.EntityUid))
|
||||||
|
{
|
||||||
|
RaiseNetworkEvent(new ExamineSystemMessages.ExamineInfoResponseMessage(
|
||||||
|
request.EntityUid, _entityOutOfRangeMessage, knowTarget: false), channel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SortedSet<Verb>? verbs = null;
|
SortedSet<Verb>? verbs = null;
|
||||||
if (request.GetVerbs)
|
if (request.GetVerbs)
|
||||||
verbs = _verbSystem.GetLocalVerbs(request.EntityUid, playerEnt, typeof(ExamineVerb));
|
verbs = _verbSystem.GetLocalVerbs(request.EntityUid, playerEnt, typeof(ExamineVerb));
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using Content.Shared.Eye.Blinding.EyeProtection; // why aren't tools predicted 🙂
|
||||||
|
using Content.Shared.Eye.Blinding;
|
||||||
|
using Content.Shared.StatusEffect;
|
||||||
|
using Content.Shared.Clothing.Components;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Inventory.Events;
|
||||||
|
using Content.Server.Tools;
|
||||||
|
|
||||||
|
namespace Content.Server.Eye.Blinding.EyeProtection
|
||||||
|
{
|
||||||
|
public sealed class EyeProtectionSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
|
||||||
|
[Dependency] private readonly SharedBlindingSystem _blindingSystem = default!;
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<RequiresEyeProtectionComponent, ToolUseAttemptEvent>(OnUseAttempt);
|
||||||
|
SubscribeLocalEvent<RequiresEyeProtectionComponent, WelderToggledEvent>(OnWelderToggled);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<EyeProtectionComponent, GotEquippedEvent>(OnEquipped);
|
||||||
|
SubscribeLocalEvent<EyeProtectionComponent, GotUnequippedEvent>(OnUnequipped);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUseAttempt(EntityUid uid, RequiresEyeProtectionComponent component, ToolUseAttemptEvent args)
|
||||||
|
{
|
||||||
|
if (!component.Toggled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<StatusEffectsComponent>(args.User, out var status) || !TryComp<BlindableComponent>(args.User, out var blindable))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (blindable.Sources > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float statusTime = (float) component.StatusEffectTime.TotalSeconds - blindable.BlindResistance;
|
||||||
|
|
||||||
|
if (statusTime <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var statusTimeSpan = TimeSpan.FromSeconds(statusTime * (blindable.EyeDamage + 1));
|
||||||
|
// Add permanent eye damage if they had zero protection, also scale their temporary blindness by how much they already accumulated.
|
||||||
|
if (_statusEffectsSystem.TryAddStatusEffect(args.User, SharedBlindingSystem.BlindingStatusEffect, statusTimeSpan, false, "TemporaryBlindness") && blindable.BlindResistance <= 0)
|
||||||
|
_blindingSystem.AdjustEyeDamage(args.User, true, blindable);
|
||||||
|
}
|
||||||
|
private void OnWelderToggled(EntityUid uid, RequiresEyeProtectionComponent component, WelderToggledEvent args)
|
||||||
|
{
|
||||||
|
component.Toggled = args.WelderOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEquipped(EntityUid uid, EyeProtectionComponent component, GotEquippedEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<SharedClothingComponent>(uid, out var clothing) || clothing.Slots == SlotFlags.PREVENTEQUIP)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!clothing.Slots.HasFlag(args.SlotFlags))
|
||||||
|
return;
|
||||||
|
|
||||||
|
component.IsActive = true;
|
||||||
|
if (!TryComp<BlindableComponent>(args.Equipee, out var blindComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
blindComp.BlindResistance += (float) component.ProtectionTime.TotalSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUnequipped(EntityUid uid, EyeProtectionComponent component, GotUnequippedEvent args)
|
||||||
|
{
|
||||||
|
if (!component.IsActive)
|
||||||
|
return;
|
||||||
|
component.IsActive = false;
|
||||||
|
if (!TryComp<BlindableComponent>(args.Equipee, out var blindComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
blindComp.BlindResistance -= (float) component.ProtectionTime.TotalSeconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -104,6 +104,9 @@ namespace Content.Server.Tools
|
|||||||
|
|
||||||
welder.Lit = true;
|
welder.Lit = true;
|
||||||
|
|
||||||
|
var ev = new WelderToggledEvent(true);
|
||||||
|
RaiseLocalEvent(welder.Owner, ev, false);
|
||||||
|
|
||||||
if(item != null)
|
if(item != null)
|
||||||
_itemSystem.SetHeldPrefix(uid, "on", item);
|
_itemSystem.SetHeldPrefix(uid, "on", item);
|
||||||
|
|
||||||
@@ -140,6 +143,9 @@ namespace Content.Server.Tools
|
|||||||
|
|
||||||
welder.Lit = false;
|
welder.Lit = false;
|
||||||
|
|
||||||
|
var ev = new WelderToggledEvent(false);
|
||||||
|
RaiseLocalEvent(welder.Owner, ev, false);
|
||||||
|
|
||||||
// TODO: Make all this use visualizers.
|
// TODO: Make all this use visualizers.
|
||||||
if (item != null)
|
if (item != null)
|
||||||
_itemSystem.SetHeldPrefix(uid, "off", item);
|
_itemSystem.SetHeldPrefix(uid, "off", item);
|
||||||
@@ -332,4 +338,14 @@ namespace Content.Server.Tools
|
|||||||
_welderTimer -= WelderUpdateTimer;
|
_welderTimer -= WelderUpdateTimer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class WelderToggledEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public bool WelderOn;
|
||||||
|
|
||||||
|
public WelderToggledEvent(bool welderOn)
|
||||||
|
{
|
||||||
|
WelderOn = welderOn;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,17 @@ namespace Content.Shared.Examine
|
|||||||
public readonly bool CenterAtCursor;
|
public readonly bool CenterAtCursor;
|
||||||
public readonly bool OpenAtOldTooltip;
|
public readonly bool OpenAtOldTooltip;
|
||||||
|
|
||||||
|
public readonly bool KnowTarget;
|
||||||
|
|
||||||
public ExamineInfoResponseMessage(EntityUid entityUid, FormattedMessage message, List<Verb>? verbs=null,
|
public ExamineInfoResponseMessage(EntityUid entityUid, FormattedMessage message, List<Verb>? verbs=null,
|
||||||
bool centerAtCursor=true, bool openAtOldTooltip=true)
|
bool centerAtCursor=true, bool openAtOldTooltip=true, bool knowTarget = true)
|
||||||
{
|
{
|
||||||
EntityUid = entityUid;
|
EntityUid = entityUid;
|
||||||
Message = message;
|
Message = message;
|
||||||
Verbs = verbs;
|
Verbs = verbs;
|
||||||
CenterAtCursor = centerAtCursor;
|
CenterAtCursor = centerAtCursor;
|
||||||
OpenAtOldTooltip = openAtOldTooltip;
|
OpenAtOldTooltip = openAtOldTooltip;
|
||||||
|
KnowTarget = knowTarget;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ namespace Content.Shared.Examine
|
|||||||
return DeadExamineRange;
|
return DeadExamineRange;
|
||||||
else if (MobStateSystem.IsCritical(examiner, mobState) || (TryComp<BlindableComponent>(examiner, out var blind) && blind.Sources > 0))
|
else if (MobStateSystem.IsCritical(examiner, mobState) || (TryComp<BlindableComponent>(examiner, out var blind) && blind.Sources > 0))
|
||||||
return CritExamineRange;
|
return CritExamineRange;
|
||||||
|
|
||||||
|
else if (TryComp<BlurryVisionComponent>(examiner, out var blurry) && blurry.Magnitude != 0)
|
||||||
|
{
|
||||||
|
float range = ExamineRange - (2 * (8 - blurry.Magnitude));
|
||||||
|
return Math.Clamp(range, 2, 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ExamineRange;
|
return ExamineRange;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,24 @@ namespace Content.Shared.Eye.Blinding
|
|||||||
[DataField("sources")]
|
[DataField("sources")]
|
||||||
public int Sources = 0;
|
public int Sources = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many seconds will be subtracted from each attempt to add blindness to us?
|
||||||
|
/// </summary>
|
||||||
|
[DataField("blindResistance")]
|
||||||
|
public float BlindResistance = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replace with actual eye damage after bobby I guess
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public int EyeDamage = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether eye damage has accumulated enough to blind them.
|
||||||
|
/// <summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public bool EyeTooDamaged = false;
|
||||||
|
|
||||||
/// <description>
|
/// <description>
|
||||||
/// Used to ensure that this doesn't break with sandbox or admin tools.
|
/// Used to ensure that this doesn't break with sandbox or admin tools.
|
||||||
/// This is not "enabled/disabled".
|
/// This is not "enabled/disabled".
|
||||||
|
|||||||
14
Content.Shared/Eye/Blinding/BlurryVisionComponent.cs
Normal file
14
Content.Shared/Eye/Blinding/BlurryVisionComponent.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Eye.Blinding
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
[NetworkedComponent]
|
||||||
|
public sealed class BlurryVisionComponent : Component
|
||||||
|
{
|
||||||
|
[DataField("mangitude")]
|
||||||
|
public float Magnitude = 1f;
|
||||||
|
|
||||||
|
public bool Active => Magnitude < 10f;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Content.Shared.Eye.Blinding.EyeProtection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// For welding masks, sunglasses, etc.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class EyeProtectionComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How many seconds to subtract from the status effect. If it's greater than the source
|
||||||
|
/// of blindness, do not blind.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("protectionTime")]
|
||||||
|
public TimeSpan ProtectionTime = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
|
public bool IsActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
namespace Content.Shared.Eye.Blinding.EyeProtection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// For tools like welders that will damage your eyes when you use them.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class RequiresEyeProtectionComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How long to apply temporary blindness to the user.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("statusEffectTime")]
|
||||||
|
public TimeSpan StatusEffectTime = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// You probably want to turn this on in yaml if it's something always on and not a welder.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("toggled")]
|
||||||
|
public bool Toggled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,28 @@
|
|||||||
using Content.Shared.Clothing.Components;
|
using Content.Shared.Clothing.Components;
|
||||||
using Content.Shared.Inventory.Events;
|
using Content.Shared.Inventory.Events;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.Item;
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace Content.Shared.Eye.Blinding
|
namespace Content.Shared.Eye.Blinding
|
||||||
{
|
{
|
||||||
public sealed class SharedBlindingSystem : EntitySystem
|
public sealed class SharedBlindingSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
public const string BlindingStatusEffect = "TemporaryBlindness";
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<BlindfoldComponent, GotEquippedEvent>(OnEquipped);
|
SubscribeLocalEvent<BlindfoldComponent, GotEquippedEvent>(OnEquipped);
|
||||||
SubscribeLocalEvent<BlindfoldComponent, GotUnequippedEvent>(OnUnequipped);
|
SubscribeLocalEvent<BlindfoldComponent, GotUnequippedEvent>(OnUnequipped);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<VisionCorrectionComponent, GotEquippedEvent>(OnGlassesEquipped);
|
||||||
|
SubscribeLocalEvent<VisionCorrectionComponent, GotUnequippedEvent>(OnGlassesUnequipped);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<BlurryVisionComponent, ComponentGetState>(OnGetState);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<TemporaryBlindnessComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<TemporaryBlindnessComponent, ComponentShutdown>(OnShutdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEquipped(EntityUid uid, BlindfoldComponent component, GotEquippedEvent args)
|
private void OnEquipped(EntityUid uid, BlindfoldComponent component, GotEquippedEvent args)
|
||||||
@@ -39,6 +49,46 @@ namespace Content.Shared.Eye.Blinding
|
|||||||
AdjustBlindSources(args.Equipee, false, blindComp);
|
AdjustBlindSources(args.Equipee, false, blindComp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGlassesEquipped(EntityUid uid, VisionCorrectionComponent component, GotEquippedEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<SharedClothingComponent>(uid, out var clothing) || clothing.Slots == SlotFlags.PREVENTEQUIP) // we live in a society
|
||||||
|
return;
|
||||||
|
// Is the clothing in its actual slot?
|
||||||
|
if (!clothing.Slots.HasFlag(args.SlotFlags))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<BlurryVisionComponent>(args.Equipee, out var blur))
|
||||||
|
return;
|
||||||
|
|
||||||
|
component.IsActive = true;
|
||||||
|
blur.Magnitude += component.VisionBonus;
|
||||||
|
blur.Dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGlassesUnequipped(EntityUid uid, VisionCorrectionComponent component, GotUnequippedEvent args)
|
||||||
|
{
|
||||||
|
if (!component.IsActive || !TryComp<BlurryVisionComponent>(args.Equipee, out var blur))
|
||||||
|
return;
|
||||||
|
component.IsActive = false;
|
||||||
|
blur.Magnitude -= component.VisionBonus;
|
||||||
|
blur.Dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetState(EntityUid uid, BlurryVisionComponent component, ref ComponentGetState args)
|
||||||
|
{
|
||||||
|
args.State = new BlurryVisionComponentState(component.Magnitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInit(EntityUid uid, TemporaryBlindnessComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
AdjustBlindSources(uid, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnShutdown(EntityUid uid, TemporaryBlindnessComponent component, ComponentShutdown args)
|
||||||
|
{
|
||||||
|
AdjustBlindSources(uid, false);
|
||||||
|
}
|
||||||
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public void AdjustBlindSources(EntityUid uid, bool Add, BlindableComponent? blindable = null)
|
public void AdjustBlindSources(EntityUid uid, bool Add, BlindableComponent? blindable = null)
|
||||||
{
|
{
|
||||||
@@ -52,6 +102,56 @@ namespace Content.Shared.Eye.Blinding
|
|||||||
{
|
{
|
||||||
blindable.Sources--;
|
blindable.Sources--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blindable.Sources = Math.Max(blindable.Sources, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AdjustEyeDamage(EntityUid uid, bool add, BlindableComponent? blindable = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref blindable, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (add)
|
||||||
|
{
|
||||||
|
blindable.EyeDamage++;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
blindable.EyeDamage--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blindable.EyeDamage > 0)
|
||||||
|
{
|
||||||
|
var blurry = EnsureComp<BlurryVisionComponent>(uid);
|
||||||
|
blurry.Magnitude = (9 - blindable.EyeDamage);
|
||||||
|
blurry.Dirty();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
RemComp<BlurryVisionComponent>(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blindable.EyeTooDamaged && blindable.EyeDamage >= 8)
|
||||||
|
{
|
||||||
|
blindable.EyeTooDamaged = true;
|
||||||
|
AdjustBlindSources(uid, true, blindable);
|
||||||
|
}
|
||||||
|
if (blindable.EyeTooDamaged && blindable.EyeDamage < 8)
|
||||||
|
{
|
||||||
|
blindable.EyeTooDamaged = false;
|
||||||
|
AdjustBlindSources(uid, false, blindable);
|
||||||
|
}
|
||||||
|
|
||||||
|
blindable.EyeDamage = Math.Clamp(blindable.EyeDamage, 0, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// I have no idea why blurry vision needs this but blindness doesn't
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class BlurryVisionComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public float Magnitude;
|
||||||
|
public BlurryVisionComponentState(float magnitude)
|
||||||
|
{
|
||||||
|
Magnitude = magnitude;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
Content.Shared/Eye/Blinding/TemporaryBlindnessComponent.cs
Normal file
11
Content.Shared/Eye/Blinding/TemporaryBlindnessComponent.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Eye.Blinding
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Blind status effect.
|
||||||
|
/// </summary>
|
||||||
|
[NetworkedComponent, RegisterComponent]
|
||||||
|
public sealed class TemporaryBlindnessComponent : Component
|
||||||
|
{}
|
||||||
|
}
|
||||||
15
Content.Shared/Eye/Blinding/VisionCorrectionComponent.cs
Normal file
15
Content.Shared/Eye/Blinding/VisionCorrectionComponent.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Eye.Blinding
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
[NetworkedComponent]
|
||||||
|
public sealed class VisionCorrectionComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables]
|
||||||
|
public bool IsActive = false;
|
||||||
|
|
||||||
|
[DataField("visionBonus")]
|
||||||
|
public float VisionBonus = 3f;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
examine-system-entity-does-not-exist = That entity doesn't exist
|
examine-system-entity-does-not-exist = That entity doesn't exist
|
||||||
|
|
||||||
|
examine-system-cant-see-entity = You can't make out whatever that is.
|
||||||
|
|
||||||
examine-verb-name = Basic
|
examine-verb-name = Basic
|
||||||
|
|
||||||
examinable-anchored = It is anchored to the floor
|
examinable-anchored = It is anchored to the floor
|
||||||
|
|||||||
@@ -85,5 +85,8 @@ reagent-desc-omnizine = A soothing milky liquid with an iridescent gleam. A well
|
|||||||
reagent-name-ultravasculine = ultravasculine
|
reagent-name-ultravasculine = ultravasculine
|
||||||
reagent-desc-ultravasculine = Rapidly flushes toxins from the body, but places some stress on the veins. Do not overdose.
|
reagent-desc-ultravasculine = Rapidly flushes toxins from the body, but places some stress on the veins. Do not overdose.
|
||||||
|
|
||||||
|
reagent-name-oculine = oculine
|
||||||
|
reagent-desc-oculine = Heals eye damage.
|
||||||
|
|
||||||
reagent-name-ethylredoxrazine = ethylredoxrazine
|
reagent-name-ethylredoxrazine = ethylredoxrazine
|
||||||
reagent-desc-ethylredoxrazine = Neutralises the effects of alcohol in the blood stream. Though it is commonly needed, it is rarely requested.
|
reagent-desc-ethylredoxrazine = Neutralises the effects of alcohol in the blood stream. Though it is commonly needed, it is rarely requested.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
spriteName: engivend
|
spriteName: engivend
|
||||||
startingInventory:
|
startingInventory:
|
||||||
ClothingEyesGlassesMeson: 4
|
ClothingEyesGlassesMeson: 4
|
||||||
|
ClothingHeadHatWelding: 4
|
||||||
Multitool: 4
|
Multitool: 4
|
||||||
PowerCellMedium: 5
|
PowerCellMedium: 5
|
||||||
ClothingHandsGlovesColorYellow: 6
|
ClothingHandsGlovesColorYellow: 6
|
||||||
|
|||||||
@@ -65,17 +65,14 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesBase
|
parent: ClothingEyesBase
|
||||||
id: ClothingEyesGlassesMeson
|
id: ClothingEyesGlassesMeson
|
||||||
name: optical meson scanners
|
name: engineering goggles #less confusion
|
||||||
description: The pinnacle of modern science, wallhacks in real life
|
description: Green-tinted goggles using a proprietary polymer that provides protection from eye damage of all types.
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Clothing/Eyes/Glasses/meson.rsi
|
sprite: Clothing/Eyes/Glasses/meson.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Eyes/Glasses/meson.rsi
|
sprite: Clothing/Eyes/Glasses/meson.rsi
|
||||||
- type: Armor
|
- type: EyeProtection
|
||||||
modifiers:
|
|
||||||
coefficients:
|
|
||||||
Radiation: 0.5
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesBase
|
parent: ClothingEyesBase
|
||||||
@@ -87,6 +84,7 @@
|
|||||||
sprite: Clothing/Eyes/Glasses/glasses.rsi
|
sprite: Clothing/Eyes/Glasses/glasses.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Eyes/Glasses/glasses.rsi
|
sprite: Clothing/Eyes/Glasses/glasses.rsi
|
||||||
|
- type: VisionCorrection
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesBase
|
parent: ClothingEyesBase
|
||||||
@@ -99,6 +97,8 @@
|
|||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Eyes/Glasses/sunglasses.rsi
|
sprite: Clothing/Eyes/Glasses/sunglasses.rsi
|
||||||
- type: FlashImmunity
|
- type: FlashImmunity
|
||||||
|
- type: EyeProtection
|
||||||
|
protectionTime: 5
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesBase
|
parent: ClothingEyesBase
|
||||||
@@ -111,6 +111,8 @@
|
|||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Eyes/Glasses/secglasses.rsi
|
sprite: Clothing/Eyes/Glasses/secglasses.rsi
|
||||||
- type: FlashImmunity
|
- type: FlashImmunity
|
||||||
|
- type: EyeProtection
|
||||||
|
protectionTime: 5
|
||||||
|
|
||||||
#Make a scanner category when these actually function and we get the trayson
|
#Make a scanner category when these actually function and we get the trayson
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
sprite: Clothing/Eyes/Misc/eyepatch.rsi
|
sprite: Clothing/Eyes/Misc/eyepatch.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Eyes/Misc/eyepatch.rsi
|
sprite: Clothing/Eyes/Misc/eyepatch.rsi
|
||||||
|
- type: EyeProtection
|
||||||
|
protectionTime: 5
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesBase
|
parent: ClothingEyesBase
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
- type: IngestionBlocker
|
- type: IngestionBlocker
|
||||||
- type: FlashImmunity
|
- type: FlashImmunity
|
||||||
- type: IdentityBlocker
|
- type: IdentityBlocker
|
||||||
|
- type: EyeProtection
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: WeldingMaskBase
|
parent: WeldingMaskBase
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Mask/gassyndicate.rsi
|
sprite: Clothing/Mask/gassyndicate.rsi
|
||||||
- type: FlashImmunity
|
- type: FlashImmunity
|
||||||
|
- type: EyeProtection
|
||||||
|
protectionTime: 5
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingMaskGas
|
parent: ClothingMaskGas
|
||||||
|
|||||||
@@ -112,6 +112,7 @@
|
|||||||
- Stutter
|
- Stutter
|
||||||
- Electrocution
|
- Electrocution
|
||||||
- ForcedSleep
|
- ForcedSleep
|
||||||
|
- TemporaryBlindness
|
||||||
- type: Body
|
- type: Body
|
||||||
template: AnimalTemplate
|
template: AnimalTemplate
|
||||||
preset: AnimalPreset
|
preset: AnimalPreset
|
||||||
@@ -179,6 +180,7 @@
|
|||||||
- Stutter
|
- Stutter
|
||||||
- Electrocution
|
- Electrocution
|
||||||
- ForcedSleep
|
- ForcedSleep
|
||||||
|
- TemporaryBlindness
|
||||||
- type: ThermalRegulator
|
- type: ThermalRegulator
|
||||||
metabolismHeat: 800
|
metabolismHeat: 800
|
||||||
radiatedHeat: 100
|
radiatedHeat: 100
|
||||||
|
|||||||
@@ -80,6 +80,7 @@
|
|||||||
- PressureImmunity
|
- PressureImmunity
|
||||||
- Muted
|
- Muted
|
||||||
- ForcedSleep
|
- ForcedSleep
|
||||||
|
- TemporaryBlindness
|
||||||
- type: DiseaseCarrier
|
- type: DiseaseCarrier
|
||||||
- type: Blindable
|
- type: Blindable
|
||||||
# Other
|
# Other
|
||||||
|
|||||||
@@ -108,6 +108,17 @@
|
|||||||
- state: carrot
|
- state: carrot
|
||||||
- type: SliceableFood
|
- type: SliceableFood
|
||||||
slice: FoodCakeCarrotSlice
|
slice: FoodCakeCarrotSlice
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
food:
|
||||||
|
maxVol: 30
|
||||||
|
reagents:
|
||||||
|
- ReagentId: JuiceCarrot
|
||||||
|
Quantity: 15
|
||||||
|
- ReagentId: Sugar
|
||||||
|
Quantity: 5
|
||||||
|
- ReagentId: Vitamin
|
||||||
|
Quantity: 5
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: slice of carrot cake
|
name: slice of carrot cake
|
||||||
@@ -120,6 +131,18 @@
|
|||||||
- state: plate-small
|
- state: plate-small
|
||||||
- state: plate-slice-shading
|
- state: plate-slice-shading
|
||||||
- state: carrot-slice
|
- state: carrot-slice
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
food:
|
||||||
|
maxVol: 6
|
||||||
|
reagents:
|
||||||
|
- ReagentId: JuiceCarrot
|
||||||
|
Quantity: 3
|
||||||
|
- ReagentId: Sugar
|
||||||
|
Quantity: 1
|
||||||
|
- ReagentId: Vitamin
|
||||||
|
Quantity: 1
|
||||||
|
|
||||||
# Tastes like sweetness, cake, carrot.
|
# Tastes like sweetness, cake, carrot.
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -265,5 +265,7 @@
|
|||||||
reagents:
|
reagents:
|
||||||
- ReagentId: Nutriment
|
- ReagentId: Nutriment
|
||||||
Quantity: 2
|
Quantity: 2
|
||||||
|
- ReagentId: JuiceCarrot
|
||||||
|
Quantity: 1
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
state: dink
|
state: dink
|
||||||
|
|||||||
@@ -74,7 +74,8 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
layers:
|
layers:
|
||||||
- state: margherita-slice
|
- state: margherita-slice
|
||||||
# Tastes like crust, tomato, cheese.
|
- type: SliceableFood
|
||||||
|
slice: FoodPizzaMeatSlice
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: meat pizza
|
name: meat pizza
|
||||||
@@ -133,6 +134,17 @@
|
|||||||
- state: vegetable
|
- state: vegetable
|
||||||
- type: SliceableFood
|
- type: SliceableFood
|
||||||
slice: FoodPizzaVegetableSlice
|
slice: FoodPizzaVegetableSlice
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
food:
|
||||||
|
maxVol: 40
|
||||||
|
reagents:
|
||||||
|
- ReagentId: Nutriment
|
||||||
|
Quantity: 25
|
||||||
|
- ReagentId: JuiceCarrot
|
||||||
|
Quantity: 5
|
||||||
|
- ReagentId: Vitamin
|
||||||
|
Quantity: 5
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: slice of vegetable pizza
|
name: slice of vegetable pizza
|
||||||
@@ -143,6 +155,18 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
layers:
|
layers:
|
||||||
- state: vegetable-slice
|
- state: vegetable-slice
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
food:
|
||||||
|
maxVol: 40
|
||||||
|
reagents:
|
||||||
|
- ReagentId: Nutriment
|
||||||
|
Quantity: 4
|
||||||
|
- ReagentId: JuiceCarrot
|
||||||
|
Quantity: 1
|
||||||
|
- ReagentId: Vitamin
|
||||||
|
Quantity: 1
|
||||||
|
|
||||||
# Tastes like crust, tomato, cheese, carrot.
|
# Tastes like crust, tomato, cheese, carrot.
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -61,6 +61,14 @@
|
|||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
state: fries-carrot
|
state: fries-carrot
|
||||||
|
netsync: false
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
food:
|
||||||
|
maxVol: 26
|
||||||
|
reagents:
|
||||||
|
- ReagentId: JuiceCarrot
|
||||||
|
Quantity: 20
|
||||||
# Tastes like carrots, salt.
|
# Tastes like carrots, salt.
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -228,7 +228,7 @@
|
|||||||
food:
|
food:
|
||||||
maxVol: 9
|
maxVol: 9
|
||||||
reagents:
|
reagents:
|
||||||
- ReagentId: Nutriment
|
- ReagentId: JuiceCarrot
|
||||||
Quantity: 5
|
Quantity: 5
|
||||||
- ReagentId: Vitamin
|
- ReagentId: Vitamin
|
||||||
Quantity: 4
|
Quantity: 4
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
radius: 1.5
|
radius: 1.5
|
||||||
color: orange
|
color: orange
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
|
- type: RequiresEyeProtection
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: industrial welding tool
|
name: industrial welding tool
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
growthStages: 3
|
growthStages: 3
|
||||||
waterConsumption: 6
|
waterConsumption: 6
|
||||||
chemicals:
|
chemicals:
|
||||||
Nutriment:
|
JuiceCarrot:
|
||||||
Min: 1
|
Min: 1
|
||||||
Max: 5
|
Max: 5
|
||||||
PotencyDivisor: 20
|
PotencyDivisor: 20
|
||||||
|
|||||||
@@ -57,6 +57,17 @@
|
|||||||
desc: reagent-desc-juice-carrot
|
desc: reagent-desc-juice-carrot
|
||||||
physicalDesc: reagent-physical-desc-crisp
|
physicalDesc: reagent-physical-desc-crisp
|
||||||
color: "#FF8820"
|
color: "#FF8820"
|
||||||
|
metabolisms:
|
||||||
|
Drink:
|
||||||
|
effects:
|
||||||
|
- !type:SatiateThirst
|
||||||
|
factor: 2
|
||||||
|
- !type:AdjustReagent
|
||||||
|
reagent: Oculine
|
||||||
|
amount: 0.15
|
||||||
|
- !type:AdjustReagent
|
||||||
|
reagent: Nutriment
|
||||||
|
amount: 0.5
|
||||||
|
|
||||||
- type: reagent
|
- type: reagent
|
||||||
id: JuiceGrape
|
id: JuiceGrape
|
||||||
|
|||||||
@@ -658,3 +658,14 @@
|
|||||||
reagent: Ultravasculine
|
reagent: Ultravasculine
|
||||||
amount: 0.5
|
amount: 0.5
|
||||||
|
|
||||||
|
- type: reagent
|
||||||
|
id: Oculine
|
||||||
|
name: reagent-name-oculine
|
||||||
|
desc: reagent-desc-oculine
|
||||||
|
group: Medicine
|
||||||
|
physicalDesc: reagent-physical-desc-translucent
|
||||||
|
color: "#404040"
|
||||||
|
metabolisms:
|
||||||
|
Medicine:
|
||||||
|
effects:
|
||||||
|
- !type:ChemHealEyeDamage
|
||||||
|
|||||||
@@ -323,6 +323,20 @@
|
|||||||
products:
|
products:
|
||||||
Ultravasculine: 2
|
Ultravasculine: 2
|
||||||
|
|
||||||
|
- type: reaction
|
||||||
|
id: Oculine
|
||||||
|
reactants:
|
||||||
|
TableSalt:
|
||||||
|
amount: 1
|
||||||
|
Blood:
|
||||||
|
amount: 1
|
||||||
|
Carbon:
|
||||||
|
amount: 1
|
||||||
|
Hydrogen:
|
||||||
|
amount: 1
|
||||||
|
products:
|
||||||
|
Oculine: 4
|
||||||
|
|
||||||
- type: reaction
|
- type: reaction
|
||||||
id: Siderlac
|
id: Siderlac
|
||||||
reactants:
|
reactants:
|
||||||
|
|||||||
@@ -55,3 +55,13 @@
|
|||||||
pixelSize: 32, 32
|
pixelSize: 32, 32
|
||||||
alphaCutoff: 0
|
alphaCutoff: 0
|
||||||
removeTransparency: false
|
removeTransparency: false
|
||||||
|
|
||||||
|
- type: shader
|
||||||
|
id: BlurryVisionX
|
||||||
|
kind: source
|
||||||
|
path: "/Textures/Shaders/blurryx.swsl"
|
||||||
|
|
||||||
|
- type: shader
|
||||||
|
id: BlurryVisionY
|
||||||
|
kind: source
|
||||||
|
path: "/Textures/Shaders/blurryy.swsl"
|
||||||
|
|||||||
@@ -48,3 +48,5 @@
|
|||||||
- type: statusEffect
|
- type: statusEffect
|
||||||
id: ForcedSleep #I.e., they will not wake on damage or similar
|
id: ForcedSleep #I.e., they will not wake on damage or similar
|
||||||
|
|
||||||
|
- type: statusEffect
|
||||||
|
id: TemporaryBlindness
|
||||||
|
|||||||
16
Resources/Textures/Shaders/blurryx.swsl
Normal file
16
Resources/Textures/Shaders/blurryx.swsl
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
uniform sampler2D SCREEN_TEXTURE;
|
||||||
|
uniform highp float BLUR_AMOUNT;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
highp vec3 col = texture(SCREEN_TEXTURE, UV).xyz * BLUR_AMOUNT;
|
||||||
|
highp vec4 color = zTexture(UV);
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.15;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(-SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.15;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(2.0 * SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.12;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(2.0 * -SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.12;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(3.0 * SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.09;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(3.0 * -SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.09;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(4.0 * SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.05;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(4.0 * -SCREEN_PIXEL_SIZE.x, 0.0)).xyz * 0.05;
|
||||||
|
COLOR = vec4(vec3(col), color.a);
|
||||||
|
}
|
||||||
16
Resources/Textures/Shaders/blurryy.swsl
Normal file
16
Resources/Textures/Shaders/blurryy.swsl
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
uniform sampler2D SCREEN_TEXTURE;
|
||||||
|
uniform highp float BLUR_AMOUNT;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
highp vec3 col = texture(SCREEN_TEXTURE, UV).xyz * BLUR_AMOUNT;
|
||||||
|
highp vec4 color = zTexture(UV);
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, SCREEN_PIXEL_SIZE.y)).xyz * 0.15;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, -SCREEN_PIXEL_SIZE.y)).xyz * 0.15;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, 2.0 * SCREEN_PIXEL_SIZE.y)).xyz * 0.12;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, 2.0 * -SCREEN_PIXEL_SIZE.y)).xyz * 0.12;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, 3.0 * SCREEN_PIXEL_SIZE.y)).xyz * 0.09;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, 3.0 * -SCREEN_PIXEL_SIZE.y)).xyz * 0.09;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, 4.0 * SCREEN_PIXEL_SIZE.y)).xyz * 0.05;
|
||||||
|
col += texture(SCREEN_TEXTURE, UV + vec2(0.0, 4.0 * -SCREEN_PIXEL_SIZE.y)).xyz * 0.05;
|
||||||
|
COLOR = vec4(vec3(col), color.a);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user