Skip to content

Commit

Permalink
Сумеречники (#179)
Browse files Browse the repository at this point in the history
<!-- ЭТО ШАБЛОН ВАШЕГО PULL REQUEST. Текст между стрелками - это
комментарии - они не будут видны в PR. -->

## Описание PR
<!-- Ниже опишите ваш Pull Request. Что он изменяет? На что еще это
может повлиять? Постарайтесь описать все внесённые вами изменения! -->
Перенос сумеречников на новую сборку
И НАКОНЕЦ-ТО они названы Shadekin вместо Shadowkin

**Медиа**
<!-- Если приемлемо, добавьте скриншоты для демонстрации вашего PR. Если
ваш PR представляет собой визуальное изменение, добавьте
скриншоты, иначе он может быть закрыт. -->

![ezgif-2-2197192745](https://github.com/user-attachments/assets/1d34ecf4-417f-4126-a171-31ff009cc7db)

**Проверки**
<!-- Выполнение всех следующих действий, если это приемлемо для вида
изменений сильно ускорит разбор вашего PR -->
- [x] PR полностью завершён и мне не нужна помощь чтобы его закончить.
- [x] Я внимательно просмотрел все свои изменения и багов в них не
нашёл.
- [x] Я запускал локальный сервер со своими изменениями и всё
протестировал.
- [x] Я добавил скриншот/видео демонстрации PR в игре, **или** этот PR
этого не требует.

**Изменения**
<!--
Здесь вы можете написать список изменений, который будет автоматически
добавлен в игру, когда ваш PR будет принят.

В журнал изменений следует помещать только то, что действительно важно
игрокам.

В списке изменений тип значка не является часть предложения, поэтому
явно указывайте - Добавлен, Удалён, Изменён.
плохо: - add: Новый инструмент для инженеров
хорошо: - add: Добавлен новый инструмент для инженеров

Вы можете указать своё имя после символа 🆑 именно оно будет
отображаться в журнале изменений (иначе будет использоваться ваше имя на
GitHub)
Например: 🆑 Ian

-->

🆑
- add: Добавлено иное отображение одежды на сумеречниках

---------

Co-authored-by: Schrodinger71 <[email protected]>
Co-authored-by: Schrödinger <[email protected]>
  • Loading branch information
3 people authored Aug 6, 2024
1 parent 58bf7d2 commit d65b910
Show file tree
Hide file tree
Showing 58 changed files with 1,307 additions and 29 deletions.
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

0 comments on commit d65b910

Please sign in to comment.