Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Сумеречники #179

Merged
merged 13 commits into from
Aug 6, 2024
112 changes: 112 additions & 0 deletions Content.Client/ADT/Shadekin/Systems/ShadekinSystem.Tint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using Robust.Client.Graphics;
using Robust.Client.Player;
using Content.Client.ADT.Overlays;
using Content.Client.ADT.Overlays.Shaders;
using Content.Shared.ADT.Shadekin.Components;
using Robust.Client.GameObjects;
using Content.Shared.GameTicking;
using Content.Shared.Humanoid;
using Robust.Shared.Player;

namespace Content.Client.ADT.Shadekin.Systems;

public sealed class ShadekinTintSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IOverlayManager _overlay = default!;
[Dependency] private readonly IEntityManager _entity = default!;

private ColorTintOverlay _tintOverlay = default!;

public override void Initialize()
{
base.Initialize();

_tintOverlay = new ColorTintOverlay
{
TintColor = new Vector3(0.5f, 0f, 0.5f),
TintAmount = 0.25f,
Comp = new ShadekinComponent()
};

SubscribeLocalEvent<ShadekinComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<ShadekinComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<ShadekinComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<ShadekinComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
}

private void OnStartup(EntityUid uid, ShadekinComponent component, ComponentStartup args)
{
if (_player.LocalPlayer?.ControlledEntity != uid)
return;

_overlay.AddOverlay(_tintOverlay);
}

private void OnShutdown(EntityUid uid, ShadekinComponent component, ComponentShutdown args)
{
if (_player.LocalPlayer?.ControlledEntity != uid)
return;

_overlay.RemoveOverlay(_tintOverlay);
}

private void OnPlayerAttached(EntityUid uid, ShadekinComponent component, PlayerAttachedEvent args)
{
_overlay.AddOverlay(_tintOverlay);
}

private void OnPlayerDetached(EntityUid uid, ShadekinComponent component, PlayerDetachedEvent args)
{
_overlay.RemoveOverlay(_tintOverlay);
}

private void OnRoundRestart(RoundRestartCleanupEvent args)
{
_overlay.RemoveOverlay(_tintOverlay);
}


public override void Update(float frameTime)
{
base.Update(frameTime);

var uid = _player.LocalPlayer?.ControlledEntity;
if (uid == null ||
!_entity.TryGetComponent(uid, out ShadekinComponent? comp) ||
!_entity.TryGetComponent(uid, out SpriteComponent? sprite) ||
!sprite.LayerMapTryGet(HumanoidVisualLayers.Eyes, out var index) ||
!sprite.TryGetLayer(index, out var layer))
return;

// Eye color
comp.TintColor = new Vector3(layer.Color.R, layer.Color.G, layer.Color.B);

// 1/3 = 0.333...
// intensity = min + (power / max)
// intensity = intensity / 0.333
// intensity = clamp intensity min, max
const float min = 0.45f;
const float max = 0.75f;
comp.TintIntensity = Math.Clamp(min + (comp.PowerLevel / comp.PowerLevelMax) * 0.333f, min, max);

UpdateShader(comp.TintColor, comp.TintIntensity);
}


private void UpdateShader(Vector3? color, float? intensity)
{
while (_overlay.HasOverlay<ColorTintOverlay>())
{
_overlay.RemoveOverlay(_tintOverlay);
}

if (color != null)
_tintOverlay.TintColor = color;
if (intensity != null)
_tintOverlay.TintAmount = intensity;

_overlay.AddOverlay(_tintOverlay);
}
}
64 changes: 64 additions & 0 deletions Content.Client/ADT/Shaders/ColorTintOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Numerics;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Matrix3x2 = System.Numerics.Matrix3x2;
using Vector3 = Robust.Shared.Maths.Vector3;

namespace Content.Client.ADT.Overlays.Shaders;

/// <summary>
/// A simple overlay that applies a colored tint to the screen.
/// </summary>
public sealed class ColorTintOverlay : Overlay
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IEntityManager _entity = default!;

public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _shader;

/// <summary>
/// The color to tint the screen to as RGB on a scale of 0-1.
/// </summary>
public Vector3? TintColor = null;
/// <summary>
/// The percent to tint the screen by on a scale of 0-1.
/// </summary>
public float? TintAmount = null;
/// <summary>
/// Component required to be on the entity to tint the screen.
/// </summary>
public Component? Comp = null;

public ColorTintOverlay()
{
IoCManager.InjectDependencies(this);

_shader = _prototype.Index<ShaderPrototype>("ColorTint").InstanceUnique();
}

protected override void Draw(in OverlayDrawArgs args)
{
if (ScreenTexture == null ||
_player.LocalPlayer?.ControlledEntity is not { Valid: true } player ||
Comp != null && !_entity.HasComponent(player, Comp.GetType()))
return;

_shader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
if (TintColor != null)
_shader.SetParameter("tint_color", TintColor.Value);
if (TintAmount != null)
_shader.SetParameter("tint_amount", TintAmount.Value);

var worldHandle = args.WorldHandle;
var viewport = args.WorldBounds;
worldHandle.SetTransform(Matrix3x2.Identity);
worldHandle.UseShader(_shader);
worldHandle.DrawRect(viewport, Color.White);
worldHandle.UseShader(null);
}
}
121 changes: 121 additions & 0 deletions Content.Shared/ADT/Shadekin/Components/ShadekinComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;

namespace Content.Shared.ADT.Shadekin.Components;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ShadekinComponent : Component
{
#region Random occurrences
[ViewVariables(VVAccess.ReadWrite)]
public float MaxedPowerAccumulator = 0f;

[ViewVariables(VVAccess.ReadWrite)]
public float MaxedPowerRoof = 0f;

[ViewVariables(VVAccess.ReadWrite)]
public float MaxedPowerRateMin = 45f;

[ViewVariables(VVAccess.ReadWrite)]
public float MaxedPowerRateMax = 150f;


[ViewVariables(VVAccess.ReadWrite)]
public float MinPowerAccumulator = 0f;

[ViewVariables(VVAccess.ReadWrite)]
public float MinPowerRoof = 0f;

[ViewVariables(VVAccess.ReadWrite)]
public float MinPowerMin = 15f;

[ViewVariables(VVAccess.ReadWrite)]
public float MinPowerMax = 60f;
#endregion


#region Shader
/// <summary>
/// Automatically set to eye color.
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
public Vector3 TintColor = new(0.5f, 0f, 0.5f);

/// <summary>
/// Based on PowerLevel.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float TintIntensity = 0.65f;
#endregion


#region Power level
/// <summary>
/// Current amount of energy.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float PowerLevel
{
get => _powerLevel;
set => _powerLevel = Math.Clamp(value, PowerLevelMin, PowerLevelMax);
}
public float _powerLevel = 150f;

/// <summary>
/// Don't let PowerLevel go above this value.
/// </summary>
[ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
public float PowerLevelMax = PowerThresholds[ShadekinPowerThreshold.Max];

/// <summary>
/// Blackeyes if PowerLevel is this value.
/// </summary>
[ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
public float PowerLevelMin = PowerThresholds[ShadekinPowerThreshold.Min];

/// <summary>
/// How much energy is gained per second.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float PowerLevelGain = 0.75f;

/// <summary>
/// Power gain multiplier
/// </summary>
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float PowerLevelGainMultiplier = 1f;

/// <summary>
/// Whether to gain power or not.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public bool PowerLevelGainEnabled = true;

/// <summary>
/// Whether they are a blackeye.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public bool Blackeye = false;


public static readonly Dictionary<ShadekinPowerThreshold, float> PowerThresholds = new()
{
{ ShadekinPowerThreshold.Max, 250.0f },
{ ShadekinPowerThreshold.Great, 200.0f },
{ ShadekinPowerThreshold.Good, 150.0f },
{ ShadekinPowerThreshold.Okay, 100.0f },
{ ShadekinPowerThreshold.Tired, 50.0f },
{ ShadekinPowerThreshold.Min, 0.0f },
};
#endregion
}

public enum ShadekinPowerThreshold : byte
{
Max = 1 << 4,
Great = 1 << 3,
Good = 1 << 2,
Okay = 1 << 1,
Tired = 1 << 0,
Min = 0,
}
40 changes: 38 additions & 2 deletions Resources/Locale/ru-RU/ADT/Languages/languages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ language-Urs-description = Басистый и рычащий язык, на к
language-Arkane-name = Каукиттен
language-Arkane-description = Протяжный, чем-то напоминающий Солнечный язык, на котором говорят арканы.

language-Shadowkin-name = Миар
language-Shadowkin-description = Загадочный язык, на котором говорят сумеречники.
language-Shadekin-name = Миар
language-Shadekin-description = Загадочный язык, на котором говорят сумеречники.

language-Dwarf-name = Шахт
language-Dwarf-description = Rock and stone!
Expand All @@ -103,3 +103,39 @@ language-Dev-description = Больше звучит как ругань пок

language-CintaTaj-name = Синта’Тайр
language-CintaTaj-description = Язык, разработанный таярами и унатхами для общения между двумя расами, представляет собой смесь шипений и слов.

language-GalacticCommon = Общ.
language-Bubblish = Пузырчатый
language-RootSpeak = Песнь корней
language-CodeSpeak = Кодовый
language-Nekomimetic = Неко
language-Draconic = Синта'унати
language-Canilunzt = Канилунц
language-SikTaj = Сик'тайр
language-Nian = Ткачий
language-Fire = Огненный
language-SolCommon = Солнечный
language-Cat = Кошачий
language-Dog = Собачий
language-Mothroach = Молиный
language-Xeno = Ксено
language-RobotTalk = Троичный
language-Monkey = Обезьяний
language-Bee = Пчелиный
language-Mouse = Мышиный
language-Drask = Орлуум
# These ones are half-assed because these creatures are almost never played as.
language-Chicken = Animal chicken
language-Duck = Animal duck
language-Cow = Animal cow
language-Sheep = Animal sheep
language-Kangaroo = Animal kangaroo
language-Pig = Animal pig
language-Moffic = Паучий
language-BorgTalk = Двоичный
language-Urs = Рыкрур
language-Arkane = Каукиттен
language-Shadekin = Миар
language-Dev = Разраб
language-Dwarf = Шахт
language-CintaTaj = Синта’тайр
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ent-CintaTajTranslator = переводчик Синта’Тайр
ent-ArkaneTranslator = переводчик языка Каукиттен
.desc = Используется для взаимного перевода Общегалактического языка и Каукиттен.

ent-ShadowkinTranslator = переводчик языка Миар
ent-ShadekinTranslator = переводчик языка Миар
.desc = Используется для взаимного перевода Общегалактического языка и Миар.

ent-NianTranslator = переводчик Ткачьего языка
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ent-UrsTranslatorImplanter = полноценный языковой импла
ent-ArkaneTranslatorImplanter = полноценный языковой имплант Каукиттен
.desc = Имплант, позволяющий понимать и общаться на языке Каукиттен.

ent-ShadowkinTranslatorImplanter = полноценный языковой имплант Миар
ent-ShadekinTranslatorImplanter = полноценный языковой имплант Миар
.desc = Имплант, позволяющий понимать и общаться на языке Миар.

ent-BorgTranslatorImplanter = полноценный языковой имплант двоичного кода
Expand Down
1 change: 1 addition & 0 deletions Resources/Locale/ru-RU/ADT/prototypes/Species/shadekin.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
species-name-shadekin = Сумеречник
2 changes: 2 additions & 0 deletions Resources/Locale/ru-RU/ADT/reagents/biological.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
reagent-name-shadekin-blood = фиолетовая кровь
reagent-desc-shadekin-blood = Я надеюсь, что ботаники просто раздавили блюспейс помидор.
Loading
Loading