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

Красивые циферки урона #993

Merged
merged 16 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Content.Client/Options/UI/Tabs/ExtraTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
<!-- Combat -->
<Label Text="{Loc 'ui-options-sunrise-general-combat'}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="DamageOverlayCheckBox" Text="{Loc 'ui-options-damage-overlay'}" />
<CheckBox Name="DamageOverlayEnableCheckBox" Text="{Loc 'ui-options-damage-overlay-enable'}" />
<CheckBox Name="DamageOverlaySelfCheckBox" Text="{Loc 'ui-options-damage-overlay-self'}" />
<CheckBox Name="DamageOverlayStructuresCheckBox" Text="{Loc 'ui-options-damage-overlay-structures'}" />

<!-- Audio -->
<Label Text="{Loc 'ui-options-sunrise-general-audio'}" StyleClasses="LabelKeyText"/>
Expand Down
5 changes: 4 additions & 1 deletion Content.Client/Options/UI/Tabs/ExtraTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,15 @@ public ExtraTab()
var layoutLoc = Loc.GetString($"lobby-animation-{lobbyAnimation.ID}");
lobbyAnimations.Add(new OptionDropDownCVar<string>.ValueOption(lobbyAnimation.ID, layoutLoc));
}

ThereDrD0 marked this conversation as resolved.
Show resolved Hide resolved
Control.AddOptionDropDown(SunriseCCVars.LobbyBackgroundType, DropDownLobbyBackgroundType, lobbyBackgroundTypes);
Control.AddOptionDropDown(SunriseCCVars.LobbyArt, DropDownLobbyArt, lobbyArts);
Control.AddOptionDropDown(SunriseCCVars.LobbyAnimation, DropDownLobbyAnimation, lobbyAnimations);
Control.AddOptionDropDown(SunriseCCVars.LobbyParallax, DropDownLobbyParallax, lobbyParallaxes);
Control.AddOptionPercentSlider(SunriseCCVars.LobbyOpacity, LobbyOpacitySlider);
Control.AddOptionCheckBox(SunriseCCVars.DamageOverlay, DamageOverlayCheckBox);
Control.AddOptionCheckBox(SunriseCCVars.DamageOverlayEnable, DamageOverlayEnableCheckBox);
Control.AddOptionCheckBox(SunriseCCVars.DamageOverlaySelf, DamageOverlaySelfCheckBox);
Control.AddOptionCheckBox(SunriseCCVars.DamageOverlayStructures, DamageOverlayStructuresCheckBox);

Control.Initialize();
}
Expand Down
12 changes: 11 additions & 1 deletion Content.Client/Popups/PopupOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,18 @@ private void DrawWorld(DrawingHandleScreen worldHandle, OverlayDrawArgs args, fl
e => e == popup.InitialPos.EntityId || e == ourEntity, entMan: _entManager))
continue;

// Sunrise edit start
var horizontalDirection = 0f;
if (ourEntity.HasValue)
{
var moverCoords = _transform.GetMoverCoordinates(ourEntity.Value);
// float horizontalDirection = 0f -1 for left, 1 for right.
horizontalDirection = moverCoords.X <= popup.InitialPos.X ? 1f : -1f;
}
// Sunrise edit end

var pos = Vector2.Transform(mapPos.Position, matrix);
_controller.DrawPopup(popup, worldHandle, pos, scale);
_controller.DrawPopup(popup, worldHandle, pos, scale, horizontalDirection); // Sunrise edit
}
}
}
26 changes: 24 additions & 2 deletions Content.Client/Popups/PopupUIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,24 @@ public void OnStateExited(GameplayState state)
_popupControl = null;
}

public void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle, Vector2 position, float scale)
public void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle, Vector2 position, float scale, float horizontalDirection = 0f)
{
var lifetime = PopupSystem.GetPopupLifetime(popup);

// Keep alpha at 1 until TotalTime passes half its lifetime, then gradually decrease to 0.
var alpha = MathF.Min(1f, 1f - MathF.Max(0f, popup.TotalTime - lifetime / 2) * 2 / lifetime);

var updatedPosition = position - new Vector2(0f, MathF.Min(8f, 12f * (popup.TotalTime * popup.TotalTime + popup.TotalTime)));
var font = _smallFont;
var color = Color.White.WithAlpha(alpha);
var useHorizontalDirection = false;

switch (popup.Type)
{
// Sunrise start
case PopupType.SmallFloating:
useHorizontalDirection = true;
break;
// Sunrise end
case PopupType.SmallCaution:
color = Color.Red;
break;
Expand All @@ -71,6 +76,13 @@ public void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle,
font = _mediumFont;
color = Color.Red;
break;
// Sunrise start
case PopupType.MediumCautionFloating:
font = _mediumFont;
color = Color.Red;
useHorizontalDirection = true;
break;
// Sunrise end
case PopupType.Large:
font = _largeFont;
color = Color.LightGray;
Expand All @@ -87,6 +99,16 @@ public void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle,
// Sunrise-End
}

// Sunrise edit start
if (!useHorizontalDirection)
horizontalDirection = 0f;

// Calculate horizontal offset based on direction.
var horizontalOffset = horizontalDirection * MathF.Min(8f, 12f * popup.TotalTime);
// Adjust position to move both vertically and horizontally.
var updatedPosition = position + new Vector2(horizontalOffset, -MathF.Min(8f, 12f * (popup.TotalTime * popup.TotalTime + popup.TotalTime)));
// Sunrise edit end

var dimensions = handle.GetDimensions(font, popup.Text, scale);
handle.DrawString(font, updatedPosition - dimensions / 2f, popup.Text, scale, color.WithAlpha(alpha));
}
Expand Down
13 changes: 10 additions & 3 deletions Content.Client/_Sunrise/DamageOverlay/DamageOverlaySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,25 @@ public override void Initialize()
{
base.Initialize();

_cfg.OnValueChanged(SunriseCCVars.DamageOverlay, OnDamageOverlayOptionChanged, true);
_cfg.OnValueChanged(SunriseCCVars.DamageOverlayEnable, OnDamageOverlayOptionChanged, true);
_cfg.OnValueChanged(SunriseCCVars.DamageOverlaySelf, OnDamageOverlayOptionChanged, true);
_cfg.OnValueChanged(SunriseCCVars.DamageOverlayStructures, OnDamageOverlayOptionChanged, true);
}

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

_cfg.UnsubValueChanged(SunriseCCVars.DamageOverlay, OnDamageOverlayOptionChanged);
_cfg.UnsubValueChanged(SunriseCCVars.DamageOverlayEnable, OnDamageOverlayOptionChanged);
_cfg.UnsubValueChanged(SunriseCCVars.DamageOverlaySelf, OnDamageOverlayOptionChanged);
_cfg.UnsubValueChanged(SunriseCCVars.DamageOverlayStructures, OnDamageOverlayOptionChanged);
}

private void OnDamageOverlayOptionChanged(bool option)
{
RaiseNetworkEvent(new DamageOverlayOptionEvent(option));
var enable = _cfg.GetCVar(SunriseCCVars.DamageOverlayEnable);
var enableSelf = _cfg.GetCVar(SunriseCCVars.DamageOverlaySelf);
var enableStructures = _cfg.GetCVar(SunriseCCVars.DamageOverlayStructures);
RaiseNetworkEvent(new DamageOverlayOptionEvent(enable, enableSelf, enableStructures));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
namespace Content.Server._Sunrise.DamageOverlay;
using Content.Shared.Popups;

namespace Content.Server._Sunrise.DamageOverlay;

[RegisterComponent, Access(typeof(DamageOverlaySystem))]
public sealed partial class DamageOverlayComponent : Component
{
[DataField]
public PopupType DamagePopupType = PopupType.MediumCautionFloating;

[DataField]
public PopupType HealPopupType = PopupType.LargeGreen;

[DataField]
public float Radius = 0.5f;

/// SUNRISE-TODO: Более адекватная реализация
[DataField]
public bool IsStructure;
}
89 changes: 70 additions & 19 deletions Content.Server/_Sunrise/DamageOverlay/DamageOverlaySystem.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
using System.Numerics;
using Content.Server.Mind;
using Content.Server.Popups;
using Content.Shared._Sunrise.DamageOverlay;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Popups;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Random;

namespace Content.Server._Sunrise.DamageOverlay;

public sealed class DamageOverlaySystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;

private readonly List<ICommonSession> _disabledSessions = new();
private readonly List<ICommonSession> _disabledSessions = [];
private readonly Dictionary<ICommonSession, DamageOverlaySettings> _playerSettings = new ();

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

SubscribeLocalEvent<DamageOverlayComponent, DamageChangedEvent>(OnDamageChange);

SubscribeNetworkEvent<DamageOverlayOptionEvent>(OnDamageOverlayOption);
}

Expand All @@ -28,45 +34,90 @@ private async void OnDamageOverlayOption(DamageOverlayOptionEvent ev, EntitySess
_disabledSessions.Remove(args.SenderSession);
else
_disabledSessions.Add(args.SenderSession);

_playerSettings[args.SenderSession] = new DamageOverlaySettings(ev.SelfEnabled, ev.StructuresEnabled);
}

private void OnDamageChange(EntityUid uid, DamageOverlayComponent component, DamageChangedEvent args)
private void OnDamageChange(Entity<DamageOverlayComponent> ent, ref DamageChangedEvent args)
{
if (args.DamageDelta == null)
return;

var damageDelta = args.DamageDelta.GetTotal();
var coords = GenerateRandomCoordinates(Transform(ent).Coordinates, ent.Comp.Radius);

if (_mindSystem.TryGetMind(uid, out _, out var mindTarget) && mindTarget.Session != null)
if (_mindSystem.TryGetMind(ent, out _, out var mindTarget) && mindTarget.Session != null)
{
if (_disabledSessions.Contains(mindTarget.Session))
if (IsDisabledByClient(mindTarget.Session, ent))
return;

if (damageDelta > 0)
{
_popupSystem.PopupEntity($"-{damageDelta}", uid, mindTarget.Session, PopupType.LargeCaution);
_popupSystem.PopupCoordinates($"-{damageDelta}", coords, mindTarget.Session, ent.Comp.DamagePopupType);
}
}

if (args.Origin == null)
return;

if (_mindSystem.TryGetMind(args.Origin.Value, out _, out var mindOrigin) && mindOrigin.Session != null)
if (!_mindSystem.TryGetMind(args.Origin.Value, out _, out var mindOrigin) || mindOrigin.Session == null)
return;

if (IsDisabledByClient(mindOrigin.Session, ent))
return;

if (damageDelta > 0)
{
if (_disabledSessions.Contains(mindOrigin.Session))
return;
_popupSystem.PopupCoordinates($"-{damageDelta}", coords, mindOrigin.Session, ent.Comp.DamagePopupType);
}
else
{
_popupSystem.PopupCoordinates($"+{FixedPoint2.Abs(damageDelta)}", coords, mindOrigin.Session, ent.Comp.HealPopupType);
}
}

if (damageDelta > 0)
{
if (args.Origin == uid)
return;
private EntityCoordinates GenerateRandomCoordinates(EntityCoordinates center, float radius)
{
var angle = _random.NextDouble() * 2 * Math.PI;

_popupSystem.PopupEntity($"-{damageDelta}", uid, mindOrigin.Session, PopupType.LargeCaution);
}
else
{
_popupSystem.PopupEntity($"+{FixedPoint2.Abs(damageDelta)}", uid, mindOrigin.Session, PopupType.LargeGreen);
}
var distance = _random.NextDouble() * radius;

var offsetX = (float)(Math.Cos(angle) * distance);
var offsetY = (float)(Math.Sin(angle) * distance);

var newPosition = new Vector2(center.Position.X + offsetX, center.Position.Y + offsetY);

return new EntityCoordinates(center.EntityId, newPosition);
}

private bool IsDisabledByClient(ICommonSession session, Entity<DamageOverlayComponent> target)
{
if (_disabledSessions.Contains(session))
return true;

if (_playerSettings.TryGetValue(session, out var playerSettings))
{
if (target.Comp.IsStructure && !playerSettings.StructureDamage)
return true;

if (target == session.AttachedEntity && !playerSettings.SelfDamage)
return true;
}

return false;
}

private sealed class DamageOverlaySettings
{
public readonly bool StructureDamage;

public readonly bool SelfDamage;

public DamageOverlaySettings(bool evSelfEnabled, bool evStructuresEnabled)
{
SelfDamage = evSelfEnabled;

StructureDamage = evStructuresEnabled;
}
}
}
2 changes: 2 additions & 0 deletions Content.Shared/Popups/SharedPopupSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,13 @@ public enum PopupType : byte
/// </summary>
Small,
SmallCaution,
SmallFloating, // Sunrise
/// <summary>
/// Medium popups should be used for actions which are not spammable but may not be particularly important.
/// </summary>
Medium,
MediumCaution,
MediumCautionFloating, // Sunrise
/// <summary>
/// Large popups should be used for actions which may be important or very important to one or more users,
/// but is not life-threatening.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
namespace Content.Shared._Sunrise.DamageOverlay;

[Serializable, NetSerializable]
public sealed class DamageOverlayOptionEvent : EntityEventArgs
public sealed class DamageOverlayOptionEvent(bool enabled, bool selfEnabled, bool structuresEnabled) : EntityEventArgs
{
public bool Enabled { get; }
public DamageOverlayOptionEvent(bool enabled)
{
Enabled = enabled;
}
public bool Enabled { get; } = enabled;
public bool SelfEnabled { get; } = selfEnabled;
public bool StructuresEnabled { get; } = structuresEnabled;
}
16 changes: 13 additions & 3 deletions Content.Shared/_Sunrise/SunriseCCVars/SunriseCCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,6 @@ public static readonly CVarDef<bool>
* Damage
*/

public static readonly CVarDef<bool> DamageOverlay =
CVarDef.Create("damage.overlay", true, CVar.CLIENTONLY | CVar.ARCHIVE);

public static readonly CVarDef<float> DamageVariance =
CVarDef.Create("damage.variance", 0.15f, CVar.SERVER | CVar.REPLICATED);

Expand Down Expand Up @@ -392,4 +389,17 @@ public static readonly CVarDef<bool>

public static readonly CVarDef<int> FlavorTextBaseLength =
CVarDef.Create("flavor_text.length", 512, CVar.SERVER | CVar.REPLICATED);

/*
* Damage Overlay
*/

public static readonly CVarDef<bool> DamageOverlayEnable =
CVarDef.Create("damage_overlay.enable", true, CVar.CLIENTONLY | CVar.ARCHIVE);

public static readonly CVarDef<bool> DamageOverlaySelf =
CVarDef.Create("damage_overlay.self", true, CVar.CLIENTONLY | CVar.ARCHIVE);

public static readonly CVarDef<bool> DamageOverlayStructures =
CVarDef.Create("damage_overlay.structures", true, CVar.CLIENTONLY | CVar.ARCHIVE);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ ui-options-lobby-background-type = Тип фона лобби
ui-options-lobby-art = Арт лобби
ui-options-lobby-animation = Анимация лобби
ui-options-lobby-parallax = Паралакс лобби
ui-options-damage-overlay = Оверлей урона
ui-options-damage-overlay-enable = Оверлей урона
ui-options-damage-overlay-structures = Показывать урон по структурам
ui-options-damage-overlay-self = Показывать урон по себе
ui-options-sunrise-general-audio = Аудио
ui-options-sunrise-general-graphics = Графика
ui-options-sunrise-general-lobby = Лобби
Expand Down
3 changes: 3 additions & 0 deletions Resources/Prototypes/Entities/Structures/base_structure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
voice: FactCore # Sunrise-TTS
- type: StaticPrice
price: 0 # Sunrise-TTS
- type: DamageOverlay
damagePopupType: SmallFloating
isStructure: true

- type: entity
# This means that it's not anchored on spawn.
Expand Down
Loading