Skip to content

Commit

Permalink
Merge branch 'master' into experimental-teleporter
Browse files Browse the repository at this point in the history
  • Loading branch information
Spatison authored Sep 26, 2024
2 parents 8491556 + f3dd435 commit 058b4fb
Show file tree
Hide file tree
Showing 108 changed files with 869 additions and 73 deletions.
6 changes: 6 additions & 0 deletions Content.Client/Ghost/GhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,11 @@ public void ToggleGhostVisibility()
{
GhostVisibility = !GhostVisibility;
}

public void ReturnToRound() // WD EDIT
{
var msg = new GhostReturnToRoundRequest();
RaiseNetworkEvent(msg);
}
}
}
2 changes: 1 addition & 1 deletion Content.Client/Lobby/UI/LobbyGui.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Stretch="KeepAspectCovered" />
<BoxContainer Name="MainContainer" VerticalExpand="True" HorizontalExpand="True" Orientation="Horizontal"
Margin="10 10 10 10" SeparationOverride="2">
<SplitContainer State="Auto" HorizontalExpand="True">
<SplitContainer State="Auto" ResizeMode="NotResizable" HorizontalExpand="True">
<!-- LHS Controls -->
<BoxContainer Name="LeftSide" Orientation="Vertical" SeparationOverride="4" HorizontalExpand="True">
<Control Name="DefaultState" VerticalExpand="True">
Expand Down
3 changes: 2 additions & 1 deletion Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using Content.Client.Chat.Managers;
using Content.Client.Message;
using Content.Shared.Chat;
Expand Down Expand Up @@ -75,7 +76,7 @@ public LawDisplay(EntityUid uid, SiliconLaw law, HashSet<string>? radioChannels)
case SharedChatSystem.CommonChannel:
_chatManager.SendMessage($"{SharedChatSystem.RadioCommonPrefix} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break;
default:
_chatManager.SendMessage($"{SharedChatSystem.RadioChannelPrefix}{radioChannelProto.KeyCode} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break;
_chatManager.SendMessage($"{SharedChatSystem.RadioChannelPrefix}{radioChannelProto.KeyCodes.First()} {lawIdentifier}: {lawDescription}", ChatSelectChannel.Radio); break;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ public void LoadGui()
Gui.ReturnToBodyPressed += ReturnToBody;
Gui.GhostRolesPressed += GhostRolesPressed;
Gui.TargetWindow.WarpClicked += OnWarpClicked;
Gui.ReturnToRoundPressed += ReturnToRound; // WD EDIT

UpdateGui();
}
Expand All @@ -133,6 +134,7 @@ public void UnloadGui()
Gui.ReturnToBodyPressed -= ReturnToBody;
Gui.GhostRolesPressed -= GhostRolesPressed;
Gui.TargetWindow.WarpClicked -= OnWarpClicked;
Gui.ReturnToRoundPressed -= ReturnToRound; // WD EDIT

Gui.Hide();
}
Expand All @@ -142,6 +144,11 @@ private void ReturnToBody()
_system?.ReturnToBody();
}

private void ReturnToRound() // WD EDIT
{
_system?.ReturnToRound();
}

private void RequestWarps()
{
_system?.RequestWarps();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<Button Name="ReturnToBodyButton" Text="{Loc ghost-gui-return-to-body-button}" />
<Button Name="GhostWarpButton" Text="{Loc ghost-gui-ghost-warp-button}" />
<Button Name="GhostRolesButton" />
<Button Name="ReturnToRound" Text="{Loc ghost-gui-return-to-round-button}" /> <!-- WD EDIT -->
</BoxContainer>
</widgets:GhostGui>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public sealed partial class GhostGui : UIWidget
public event Action? RequestWarpsPressed;
public event Action? ReturnToBodyPressed;
public event Action? GhostRolesPressed;
public event Action? ReturnToRoundPressed; // WD EDIT

public GhostGui()
{
Expand All @@ -26,6 +27,7 @@ public GhostGui()
GhostWarpButton.OnPressed += _ => RequestWarpsPressed?.Invoke();
ReturnToBodyButton.OnPressed += _ => ReturnToBodyPressed?.Invoke();
GhostRolesButton.OnPressed += _ => GhostRolesPressed?.Invoke();
ReturnToRound.OnPressed += _ => ReturnToRoundPressed?.Invoke(); // WD EDIT
}

public void Hide()
Expand Down
3 changes: 3 additions & 0 deletions Content.Server/GameTicking/GameTicker.GamePreset.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Content.Server._White.Ghost;
using Content.Server.GameTicking.Presets;
using Content.Server.Maps;
using Content.Shared.CCVar;
Expand All @@ -21,6 +22,7 @@ namespace Content.Server.GameTicking
public sealed partial class GameTicker
{
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
[Dependency] private readonly GhostReturnToRoundSystem _ghostReturnToRound = default!; // WD EDIT

public const float PresetFailedCooldownIncrease = 30f;

Expand Down Expand Up @@ -303,6 +305,7 @@ public bool OnGhostAttempt(EntityUid mindId, bool canReturnGlobal, bool viaComma
_mind.Visit(mindId, ghost, mind);
else
_mind.TransferTo(mindId, ghost, mind: mind);

return true;
}

Expand Down
78 changes: 78 additions & 0 deletions Content.Server/GameTicking/GameTicker.Spawning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
using Content.Server.Speech.Components;
using Content.Server.Station.Components;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.Mind;
using Content.Shared.Players;
using Content.Shared.Preferences;
using Content.Shared.Roles;
Expand Down Expand Up @@ -154,6 +156,22 @@ private void SpawnPlayer(ICommonSession player, HumanoidCharacterProfile charact
return;
}

//WD EDIT START
//Ghost system return to round, check for whether the character isn't the same.
if (lateJoin && !_adminManager.IsAdmin(player) && !CheckGhostReturnToRound(player, character, out var checkAvoid))
{
var message = checkAvoid
? Loc.GetString("ghost-respawn-same-character-slightly-changed-name")
: Loc.GetString("ghost-respawn-same-character");
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));

_chatManager.ChatMessageToOne(ChatChannel.Server, message, wrappedMessage,
default, false, player.Channel, Color.Red);

return;
}
//WD EDIT END

// We raise this event to allow other systems to handle spawning this player themselves. (e.g. late-join wizard, etc)
var bev = new PlayerBeforeSpawnEvent(player, character, jobId, lateJoin, station);
RaiseLocalEvent(bev);
Expand Down Expand Up @@ -346,6 +364,66 @@ public void SpawnObserver(ICommonSession player)
_adminLogger.Add(LogType.LateJoin, LogImpact.Low, $"{player.Name} late joined the round as an Observer with {ToPrettyString(ghost):entity}.");
}

//WD EDIT START
private bool CheckGhostReturnToRound(ICommonSession player, HumanoidCharacterProfile character, out bool checkAvoid)
{
checkAvoid = false;

var allPlayerMinds = EntityQuery<MindComponent>()
.Where(mind => mind.OriginalOwnerUserId == player.UserId);

foreach (var mind in allPlayerMinds)
{
if (mind.CharacterName == character.Name)
return false;

if (mind.CharacterName == null)
continue;

var similarity = CalculateStringSimilarity(mind.CharacterName, character.Name);
switch (similarity)
{
case >= 85f:
{
_chatManager.SendAdminAlert(Loc.GetString("ghost-respawn-log-character-almost-same",
("player", player.Name), ("try", false), ("oldName", mind.CharacterName),
("newName", character.Name)));
checkAvoid = true;

return false;
}
case >= 50f:
{
_chatManager.SendAdminAlert(Loc.GetString("ghost-respawn-log-character-almost-same",
("player", player.Name), ("try", true), ("oldName", mind.CharacterName),
("newName", character.Name)));

break;
}
}
}

return true;
}

private float CalculateStringSimilarity(string str1, string str2)
{
var minLength = Math.Min(str1.Length, str2.Length);
var matchingCharacters = 0;

for (var i = 0; i < minLength; i++)
{
if (str1[i] == str2[i])
matchingCharacters++;
}

float maxLength = Math.Max(str1.Length, str2.Length);
var similarityPercentage = (matchingCharacters / maxLength) * 100;

return similarityPercentage;
}
//WD EDIT END

#region Mob Spawning Helpers
private EntityUid SpawnObserverMob()
{
Expand Down
3 changes: 2 additions & 1 deletion Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid?
}

// Something like ballistic might want to leave it in the container still
if (!cartridge.DeleteOnSpawn && !Containers.IsEntityInContainer(ent!.Value))
if (!cartridge.DeleteOnSpawn && !Containers.IsEntityInContainer(ent!.Value) &&
(!TryComp(gunUid, out BallisticAmmoProviderComponent? ballistic) || ballistic.AutoCycle)) // WD EDIT
EjectCartridge(ent.Value, angle);

Dirty(ent!.Value, cartridge);
Expand Down
81 changes: 81 additions & 0 deletions Content.Server/_White/Ghost/GhostReturnToRoundSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Content.Server.Administration.Logs;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Shared._White;
using Content.Shared.Database;
using Content.Shared.GameTicking;
using Content.Shared.Ghost;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Timing;

namespace Content.Server._White.Ghost;

public sealed class GhostReturnToRoundSystem : EntitySystem
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;

public override void Initialize()
{
SubscribeNetworkEvent<GhostReturnToRoundRequest>(OnGhostReturnToRoundRequest);
}

private void OnGhostReturnToRoundRequest(GhostReturnToRoundRequest msg, EntitySessionEventArgs args)
{
var uid = args.SenderSession.AttachedEntity;

if (uid == null)
return;

var connectedClient = args.SenderSession.ConnectedClient;
var userId = args.SenderSession.UserId;

TryGhostReturnToRound(uid.Value, connectedClient, userId, out var message, out var wrappedMessage);

_chatManager.ChatMessageToOne(Shared.Chat.ChatChannel.Server,
message,
wrappedMessage,
default,
false,
connectedClient,
Color.Red);
}

private void TryGhostReturnToRound(EntityUid uid, INetChannel connectedClient, NetUserId userId, out string message, out string wrappedMessage)
{
var maxPlayers = _cfg.GetCVar(WhiteCVars.GhostRespawnMaxPlayers);
if (_playerManager.PlayerCount >= maxPlayers)
{
message = Loc.GetString("ghost-respawn-max-players", ("players", maxPlayers));
wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
return;
}

var deathTime = EnsureComp<GhostComponent>(uid).TimeOfDeath;
var timeUntilRespawn = _cfg.GetCVar(WhiteCVars.GhostRespawnTime);
var timePast = (_gameTiming.CurTime - deathTime).TotalMinutes;
if (timePast >= timeUntilRespawn)
{
var ticker = Get<GameTicker>();
_playerManager.TryGetSessionById(userId, out var targetPlayer);

if (targetPlayer != null)
ticker.Respawn(targetPlayer);

_adminLogger.Add(LogType.Mind, LogImpact.Medium, $"{Loc.GetString("ghost-respawn-log-return-to-lobby", ("userName", connectedClient.UserName))}");

message = Loc.GetString("ghost-respawn-window-rules-footer");
wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));

return;
}

message = Loc.GetString("ghost-respawn-time-left", ("time", (int) (timeUntilRespawn - timePast)));
wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Content.Shared._White.BackStab;
namespace Content.Server._White.Melee.BackStab;

[RegisterComponent]
public sealed partial class BackStabComponent : Component
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
using Content.Server.Popups;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.Mobs.Components;
using Content.Shared.Popups;
using Content.Shared.Weapons.Melee.Events;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;

namespace Content.Shared._White.BackStab;
namespace Content.Server._White.Melee.BackStab;

public sealed class BackStabSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly PopupSystem _popup = default!;

public override void Initialize()
{
Expand Down Expand Up @@ -49,10 +48,7 @@ private void HandleHit(Entity<BackStabComponent> ent, ref MeleeHitEvent args)
args.BonusDamage = new DamageSpecifier(_prototypeManager.Index<DamageTypePrototype>("Slash"),
damage - args.BaseDamage.GetTotal());

if (!_net.IsServer)
return;

var message = Loc.GetString("backstab-damage-betrayal-dagger", ("damage", damage));
var message = Loc.GetString("melee-backstab-damage", ("damage", damage));
_popup.PopupEntity(message, args.User, args.User, PopupType.MediumCaution);
}
}
13 changes: 13 additions & 0 deletions Content.Server/_White/Melee/Crit/CritComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Content.Server._White.Melee.Crit;

[RegisterComponent]
public sealed partial class CritComponent : Component
{
[DataField]
public float CritChance = 0.2f;

[DataField]
public float CritMultiplier = 2f;

public float? RealChance;
}
Loading

0 comments on commit 058b4fb

Please sign in to comment.