Goida revert (#600)
* Revert "- fix: YAML linter fixes. (#598)" This reverts commit012bf3c357. * Revert "Automatic changelog update" This reverts commitcf1c3a9af5. * Revert "[Fix] Base Layer Prototype (#597)" This reverts commitb000423999. * Revert "Modules update (#596)" This reverts commit00fbdead77. * Revert "Automatic changelog update" This reverts commit0d7a12b2a2. * Revert "Fixes (#593)" This reverts commit943c77031c. * Revert "minor loadout fixes (#594)" This reverts commit143c010a89. * Revert "Update DryDock.yml (#595)" This reverts commit4cd0100ac7. * Revert "Automatic changelog update" This reverts commit08eadc690f. * Revert "fix: Maximum message size (#591)" This reverts commit343f3612eb. * Revert "Черри пики 7 (#592)" This reverts commit3f97bdce2f. * Revert "Automatic changelog update" This reverts commit0678eca250. * Revert "Рандомфиксы (#590)" This reverts commit2b9e5e2437. * Revert "Нижнее бельё в лодауты (#580)" This reverts commite01a47b089. * Revert "add lathe sounds (#588)" This reverts commitc80a2985f2. * Revert "Добавил параметр группы для некоторых реагентов (#585)" This reverts commit713b16bb98. * Revert "add hrp ++++ aspect (#587)" This reverts commita6a69cc60f. * Revert "Новые амбиенты и пару песен (#586)" This reverts commit48c86bd846. * Revert "Сообщения в ПДА 2 (#583)" This reverts commitcced3cc98b. * Revert "Automatic changelog update" This reverts commitabf435b11d. * Revert "Chem stuff and more (#584)" This reverts commit3608960f5c. * Revert "JobRequiremet refactor (#579)" This reverts commit9a9c9598e0. * Revert "Revert "Reapply "Нижнее бельё в лодауты""" This reverts commit44447d573f. * Revert "Reapply "Нижнее бельё в лодауты"" This reverts commit0c4d082ad3. * Revert "Revert "Нижнее бельё в лодауты"" This reverts commit56473c5492. * Revert "Нижнее бельё в лодауты" This reverts commitd1cb0cb364. * Revert "DryDock and WhiteMoose update (#578)" This reverts commit14755808af. * Revert "Automatic changelog update" This reverts commit0133f82722. * Revert "Fixes (#576)" This reverts commitb7cc49896c. * Revert "порт системы регенерации солюшена цинки (#574)" This reverts commita22cf3d50b. * Revert "Воровские перчатки (#573)" This reverts commitbb7140f3d4. * Revert "mood resprite (#572)" This reverts commit4db96dc569. * Revert "fix missing letter (#571)" This reverts commit94ea756794. * Revert "Сообщения в ПДА (#564)" This reverts commitd023d29e54. * Revert "- fix: No visible aghost." This reverts commit27e7f25f7e. * Revert "- tweak: Nerf cult shield." This reverts commit6a384246b8.
This commit is contained in:
@@ -42,7 +42,7 @@ public sealed partial class RoleBanWindow : DefaultWindow
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
foreach (var proto in prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
||||
{
|
||||
CreateRoleGroup(proto.ID, proto.Roles.Select(x => x.Id), proto.Color);
|
||||
CreateRoleGroup(proto.ID, proto.Roles, proto.Color);
|
||||
}
|
||||
|
||||
CreateRoleGroup("Antagonist", prototypeManager.EnumeratePrototypes<AntagPrototype>().Select(p => p.ID),
|
||||
|
||||
@@ -54,7 +54,7 @@ public sealed class AudioUIController : UIController
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
var resource = GetSoundOrFallback(value, CCVars.UIClickSound.DefaultValue);
|
||||
var resource = _cache.GetResource<AudioResource>(value);
|
||||
var source =
|
||||
_audioManager.CreateAudioSource(resource);
|
||||
|
||||
@@ -77,7 +77,7 @@ public sealed class AudioUIController : UIController
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
var hoverResource = GetSoundOrFallback(value, CCVars.UIHoverSound.DefaultValue);
|
||||
var hoverResource = _cache.GetResource<AudioResource>(value);
|
||||
var hoverSource =
|
||||
_audioManager.CreateAudioSource(hoverResource);
|
||||
|
||||
@@ -95,12 +95,4 @@ public sealed class AudioUIController : UIController
|
||||
UIManager.SetHoverSound(null);
|
||||
}
|
||||
}
|
||||
|
||||
private AudioResource GetSoundOrFallback(string path, string fallback)
|
||||
{
|
||||
if (!_cache.TryGetResource(path, out AudioResource? resource))
|
||||
return _cache.GetResource<AudioResource>(fallback);
|
||||
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ public sealed partial class ContentAudioSystem
|
||||
[Dependency] private readonly RulesSystem _rules = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
|
||||
private readonly TimeSpan _minAmbienceTime = TimeSpan.FromSeconds(5);
|
||||
private readonly TimeSpan _maxAmbienceTime = TimeSpan.FromSeconds(10);
|
||||
private readonly TimeSpan _minAmbienceTime = TimeSpan.FromSeconds(30);
|
||||
private readonly TimeSpan _maxAmbienceTime = TimeSpan.FromSeconds(60);
|
||||
|
||||
private const float AmbientMusicFadeTime = 10f;
|
||||
private static float _volumeSlider;
|
||||
|
||||
@@ -82,7 +82,6 @@ namespace Content.Client.Input
|
||||
human.AddFunction(ContentKeyFunctions.Arcade3);
|
||||
human.AddFunction(ContentKeyFunctions.LieDown); // WD EDIT
|
||||
human.AddFunction(ContentKeyFunctions.OfferItem); // WD EDIT
|
||||
human.AddFunction(ContentKeyFunctions.LookUp); // WD EDIT
|
||||
|
||||
// actions should be common (for ghosts, mobs, etc)
|
||||
common.AddFunction(ContentKeyFunctions.OpenActionsMenu);
|
||||
|
||||
@@ -4,9 +4,7 @@ using Content.Client.CrewManifest;
|
||||
using Content.Client.GameTicking.Managers;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.Players.PlayTimeTracking;
|
||||
using Content.Client.Preferences;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.StatusIcon;
|
||||
using Robust.Client.Console;
|
||||
@@ -28,7 +26,6 @@ namespace Content.Client.LateJoin
|
||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
||||
[Dependency] private readonly JobRequirementsManager _jobRequirements = default!;
|
||||
[Dependency] private readonly IClientPreferencesManager _preferencesManager = default!;
|
||||
|
||||
public event Action<(NetEntity, string)> SelectedId;
|
||||
|
||||
@@ -257,7 +254,7 @@ namespace Content.Client.LateJoin
|
||||
|
||||
jobButton.OnPressed += _ => SelectedId.Invoke((id, jobButton.JobId));
|
||||
|
||||
if (!_jobRequirements.IsAllowed(prototype, (HumanoidCharacterProfile?)_preferencesManager.Preferences?.SelectedCharacter, out var reason))
|
||||
if (!_jobRequirements.IsAllowed(prototype, out var reason))
|
||||
{
|
||||
jobButton.Disabled = true;
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ namespace Content.Client.Options.UI.Tabs
|
||||
AddButton(ContentKeyFunctions.SaveItemLocation);
|
||||
AddButton(ContentKeyFunctions.OfferItem); // WD EDIT
|
||||
AddButton(ContentKeyFunctions.LieDown); // WD EDIT
|
||||
AddButton(ContentKeyFunctions.LookUp); // WD EDIT
|
||||
AddCheckBox("ui-options-function-auto-get-up", _cfg.GetCVar(WhiteCVars.AutoGetUp), HandleToggleAutoGetUp); // WD EDIT
|
||||
|
||||
AddHeader("ui-options-header-interaction-adv");
|
||||
|
||||
@@ -26,13 +26,13 @@ namespace Content.Client.PDA
|
||||
public const int ProgramContentView = 3;
|
||||
|
||||
|
||||
private string _pdaOwnerName = Loc.GetString("comp-pda-ui-unknown");
|
||||
private string _pdaOwner = Loc.GetString("comp-pda-ui-unknown");
|
||||
private string _owner = Loc.GetString("comp-pda-ui-unknown");
|
||||
private string _jobTitle = Loc.GetString("comp-pda-ui-unassigned");
|
||||
private string _stationName = Loc.GetString("comp-pda-ui-unknown");
|
||||
private string _alertLevel = Loc.GetString("comp-pda-ui-unknown");
|
||||
private string _instructions = Loc.GetString("comp-pda-ui-unknown");
|
||||
|
||||
|
||||
|
||||
private int _currentView;
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace Content.Client.PDA
|
||||
|
||||
PdaOwnerButton.OnPressed += _ =>
|
||||
{
|
||||
_clipboard.SetText(_pdaOwnerName);
|
||||
_clipboard.SetText(_pdaOwner);
|
||||
};
|
||||
|
||||
IdInfoButton.OnPressed += _ =>
|
||||
@@ -125,7 +125,7 @@ namespace Content.Client.PDA
|
||||
_clipboard.SetText(_instructions);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
HideAllViews();
|
||||
@@ -138,9 +138,9 @@ namespace Content.Client.PDA
|
||||
|
||||
if (state.PdaOwnerInfo.ActualOwnerName != null)
|
||||
{
|
||||
_pdaOwnerName = state.PdaOwnerInfo.ActualOwnerName;
|
||||
_pdaOwner = state.PdaOwnerInfo.ActualOwnerName;
|
||||
PdaOwnerLabel.SetMarkup(Loc.GetString("comp-pda-ui-owner",
|
||||
("actualOwnerName", _pdaOwnerName)));
|
||||
("actualOwnerName", _pdaOwner)));
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace Content.Client.PDA
|
||||
_stationName = state.StationName ?? Loc.GetString("comp-pda-ui-unknown");
|
||||
StationNameLabel.SetMarkup(Loc.GetString("comp-pda-ui-station",
|
||||
("station", _stationName)));
|
||||
|
||||
|
||||
|
||||
var stationTime = _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan);
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Client.Administration.Managers;
|
||||
using Content.Client.Lobby;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Players;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client;
|
||||
using Robust.Client.Player;
|
||||
@@ -24,7 +22,7 @@ public sealed class JobRequirementsManager : ISharedPlaytimeManager
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypes = default!;
|
||||
[Dependency] private readonly IClientAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly IClientAdminManager _adminManager = default!; // WD
|
||||
|
||||
private readonly Dictionary<string, TimeSpan> _roles = new();
|
||||
private readonly List<string> _roleBans = new();
|
||||
@@ -42,6 +40,7 @@ public sealed class JobRequirementsManager : ISharedPlaytimeManager
|
||||
_net.RegisterNetMessage<MsgPlayTime>(RxPlayTime);
|
||||
|
||||
_client.RunLevelChanged += ClientOnRunLevelChanged;
|
||||
_adminManager.AdminStatusUpdated += () => Updated?.Invoke(); // WD
|
||||
}
|
||||
|
||||
private void ClientOnRunLevelChanged(object? sender, RunLevelChangedEventArgs e)
|
||||
@@ -83,8 +82,7 @@ public sealed class JobRequirementsManager : ISharedPlaytimeManager
|
||||
Updated?.Invoke();
|
||||
}
|
||||
|
||||
|
||||
public bool IsAllowed(JobPrototype job, HumanoidCharacterProfile? profile, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = null;
|
||||
|
||||
@@ -98,16 +96,11 @@ public sealed class JobRequirementsManager : ISharedPlaytimeManager
|
||||
if (player == null)
|
||||
return true;
|
||||
|
||||
return CheckRoleRequirements(job, profile, out reason);
|
||||
return _adminManager.IsActive() || // WD
|
||||
CheckRoleTime(job.Requirements, out reason);
|
||||
}
|
||||
|
||||
public bool CheckRoleRequirements(JobPrototype job, HumanoidCharacterProfile? profile, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
var reqs = _entManager.System<SharedRoleSystem>().GetJobRequirement(job);
|
||||
return CheckRoleRequirements(reqs, profile, out reason);
|
||||
}
|
||||
|
||||
public bool CheckRoleRequirements(HashSet<JobRequirement>? requirements, HumanoidCharacterProfile? profile, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
public bool CheckRoleTime(HashSet<JobRequirement>? requirements, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = null;
|
||||
|
||||
@@ -115,13 +108,9 @@ public sealed class JobRequirementsManager : ISharedPlaytimeManager
|
||||
return true;
|
||||
|
||||
var reasons = new List<string>();
|
||||
var isAdmin = _adminManager.IsAdmin(true); // WD
|
||||
foreach (var requirement in requirements)
|
||||
{
|
||||
if (requirement.IgnoreIfAdmin && isAdmin) // WD
|
||||
continue;
|
||||
|
||||
if (requirement.Check(_entManager, _prototypes, profile, _roles, out var jobReason))
|
||||
if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes))
|
||||
continue;
|
||||
|
||||
reasons.Add(jobReason.ToMarkup());
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Client.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
@@ -16,7 +15,7 @@ public sealed class AntagPreferenceSelector : RequirementsSelector<AntagPrototyp
|
||||
|
||||
public event Action<bool>? PreferenceChanged;
|
||||
|
||||
public AntagPreferenceSelector(AntagPrototype proto, ButtonGroup btnGroup, HumanoidCharacterProfile profile)
|
||||
public AntagPreferenceSelector(AntagPrototype proto, ButtonGroup btnGroup)
|
||||
: base(proto, btnGroup)
|
||||
{
|
||||
Options.OnItemSelected += args => PreferenceChanged?.Invoke(Preference);
|
||||
@@ -29,12 +28,12 @@ public sealed class AntagPreferenceSelector : RequirementsSelector<AntagPrototyp
|
||||
var title = Loc.GetString(proto.Name);
|
||||
var description = Loc.GetString(proto.Objective);
|
||||
// Not supported yet get fucked.
|
||||
Setup(null, profile, items, title, 250, description);
|
||||
Setup(null, items, title, 250, description);
|
||||
|
||||
// immediately lock requirements if they arent met.
|
||||
// another function checks Disabled after creating the selector so this has to be done now
|
||||
var requirements = IoCManager.Resolve<JobRequirementsManager>();
|
||||
if (!requirements.CheckRoleRequirements(proto.Requirements, profile, out var reason))
|
||||
if (proto.Requirements != null && !requirements.CheckRoleTime(proto.Requirements, out var reason))
|
||||
{
|
||||
LockRequirements(reason);
|
||||
}
|
||||
|
||||
@@ -557,16 +557,12 @@ namespace Content.Client.Preferences.UI
|
||||
_antagPreferences.Clear();
|
||||
var btnGroup = new ButtonGroup();
|
||||
|
||||
var character = (HumanoidCharacterProfile?) _preferencesManager.Preferences?.SelectedCharacter;
|
||||
if (character == null)
|
||||
return;
|
||||
|
||||
foreach (var antag in _prototypeManager.EnumeratePrototypes<AntagPrototype>().OrderBy(a => Loc.GetString(a.Name)))
|
||||
{
|
||||
if (!antag.SetPreference)
|
||||
continue;
|
||||
|
||||
var selector = new AntagPreferenceSelector(antag, btnGroup, character)
|
||||
var selector = new AntagPreferenceSelector(antag, btnGroup)
|
||||
{
|
||||
Margin = new Thickness(3f, 3f, 3f, 0f),
|
||||
};
|
||||
@@ -594,10 +590,6 @@ namespace Content.Client.Preferences.UI
|
||||
_jobCategories.Clear();
|
||||
var firstCategory = true;
|
||||
|
||||
var character = (HumanoidCharacterProfile?) _preferencesManager.Preferences?.SelectedCharacter;
|
||||
if (character == null)
|
||||
return;
|
||||
|
||||
var departments = _prototypeManager.EnumeratePrototypes<DepartmentPrototype>().ToArray();
|
||||
Array.Sort(departments, DepartmentUIComparer.Instance);
|
||||
|
||||
@@ -658,12 +650,12 @@ namespace Content.Client.Preferences.UI
|
||||
// Clone so we don't modify the underlying loadout.
|
||||
Profile?.Loadouts.TryGetValue(LoadoutSystem.GetJobPrototype(job.ID), out loadout);
|
||||
loadout = loadout?.Clone();
|
||||
var selector = new JobPrioritySelector(loadout, job, jobLoadoutGroup, _prototypeManager, character)
|
||||
var selector = new JobPrioritySelector(loadout, job, jobLoadoutGroup, _prototypeManager)
|
||||
{
|
||||
Margin = new Thickness(3f, 3f, 3f, 0f),
|
||||
};
|
||||
|
||||
if (!_requirements.IsAllowed(job, (HumanoidCharacterProfile?)_preferencesManager.Preferences?.SelectedCharacter, out var reason))
|
||||
if (!_requirements.IsAllowed(job, out var reason))
|
||||
{
|
||||
selector.LockRequirements(reason);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class JobPrioritySelector : RequirementsSelector<JobPrototype>
|
||||
|
||||
public event Action<JobPriority>? PriorityChanged;
|
||||
|
||||
public JobPrioritySelector(RoleLoadout? loadout, JobPrototype proto, ButtonGroup btnGroup, IPrototypeManager protoMan, HumanoidCharacterProfile profile)
|
||||
public JobPrioritySelector(RoleLoadout? loadout, JobPrototype proto, ButtonGroup btnGroup, IPrototypeManager protoMan)
|
||||
: base(proto, btnGroup)
|
||||
{
|
||||
Options.OnItemSelected += args => PriorityChanged?.Invoke(Priority);
|
||||
@@ -41,6 +41,6 @@ public sealed class JobPrioritySelector : RequirementsSelector<JobPrototype>
|
||||
var jobIcon = protoMan.Index<StatusIconPrototype>(proto.Icon);
|
||||
icon.Texture = jobIcon.Icon.Frame0();
|
||||
|
||||
Setup(loadout, profile, items, proto.LocalizedName, 200, proto.LocalizedDescription, icon);
|
||||
Setup(loadout, items, proto.LocalizedName, 200, proto.LocalizedDescription, icon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Preferences.Loadouts;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
@@ -18,18 +17,18 @@ public sealed partial class LoadoutGroupContainer : BoxContainer
|
||||
public event Action<ProtoId<ItemLoadoutPrototype>>? OnLoadoutPressed;
|
||||
public event Action<ProtoId<ItemLoadoutPrototype>>? OnLoadoutUnpressed;
|
||||
|
||||
public LoadoutGroupContainer(HumanoidCharacterProfile profile, RoleLoadout loadout, LoadoutGroupPrototype groupProto, ICommonSession session, IDependencyCollection collection)
|
||||
public LoadoutGroupContainer(RoleLoadout loadout, LoadoutGroupPrototype groupProto, ICommonSession session, IDependencyCollection collection)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_groupProto = groupProto;
|
||||
|
||||
RefreshLoadouts(profile, loadout, session, collection);
|
||||
RefreshLoadouts(loadout, session, collection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates button availabilities and buttons.
|
||||
/// </summary>
|
||||
public void RefreshLoadouts(HumanoidCharacterProfile profile, RoleLoadout loadout, ICommonSession session, IDependencyCollection collection)
|
||||
public void RefreshLoadouts(RoleLoadout loadout, ICommonSession session, IDependencyCollection collection)
|
||||
{
|
||||
var protoMan = collection.Resolve<IPrototypeManager>();
|
||||
var loadoutSystem = collection.Resolve<IEntityManager>().System<LoadoutSystem>();
|
||||
@@ -75,7 +74,7 @@ public sealed partial class LoadoutGroupContainer : BoxContainer
|
||||
var matchingLoadout = selected.FirstOrDefault(e => e.Prototype == loadoutProto);
|
||||
var pressed = matchingLoadout != null;
|
||||
|
||||
var enabled = loadout.IsValid(profile, session, loadoutProto, collection, out var reason);
|
||||
var enabled = loadout.IsValid(session, loadoutProto, collection, out var reason);
|
||||
var loadoutContainer = new LoadoutContainer(loadoutProto, !enabled, reason);
|
||||
loadoutContainer.Select.Pressed = pressed;
|
||||
loadoutContainer.Text = loadoutSystem.GetName(loadProto);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Client.Lobby;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Preferences.Loadouts;
|
||||
using Content.Shared.Preferences.Loadouts.Effects;
|
||||
using Robust.Client.AutoGenerated;
|
||||
@@ -18,12 +17,9 @@ public sealed partial class LoadoutWindow : FancyWindow
|
||||
|
||||
private List<LoadoutGroupContainer> _groups = new();
|
||||
|
||||
public HumanoidCharacterProfile Profile;
|
||||
|
||||
public LoadoutWindow(HumanoidCharacterProfile profile, RoleLoadout loadout, RoleLoadoutPrototype proto, ICommonSession session, IDependencyCollection collection)
|
||||
public LoadoutWindow(RoleLoadout loadout, RoleLoadoutPrototype proto, ICommonSession session, IDependencyCollection collection)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
Profile = profile;
|
||||
var protoManager = collection.Resolve<IPrototypeManager>();
|
||||
|
||||
foreach (var group in proto.Groups)
|
||||
@@ -31,7 +27,7 @@ public sealed partial class LoadoutWindow : FancyWindow
|
||||
if (!protoManager.TryIndex(group, out var groupProto))
|
||||
continue;
|
||||
|
||||
var container = new LoadoutGroupContainer(profile, loadout, protoManager.Index(group), session, collection);
|
||||
var container = new LoadoutGroupContainer(loadout, protoManager.Index(group), session, collection);
|
||||
LoadoutGroupsContainer.AddTab(container, Loc.GetString(groupProto.Name));
|
||||
_groups.Add(container);
|
||||
|
||||
@@ -58,7 +54,7 @@ public sealed partial class LoadoutWindow : FancyWindow
|
||||
{
|
||||
foreach (var group in _groups)
|
||||
{
|
||||
group.RefreshLoadouts(Profile, loadout, session, collection);
|
||||
group.RefreshLoadouts(loadout, session, collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using Content.Client.Lobby;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Preferences.Loadouts;
|
||||
using Content.Shared.Preferences.Loadouts.Effects;
|
||||
using Content.Shared.Roles;
|
||||
@@ -76,7 +75,7 @@ public abstract class RequirementsSelector<T> : BoxContainer where T : IPrototyp
|
||||
/// <summary>
|
||||
/// Actually adds the controls, must be called in the inheriting class' constructor.
|
||||
/// </summary>
|
||||
protected void Setup(RoleLoadout? loadout, HumanoidCharacterProfile profile, (string, int)[] items, string title, int titleSize, string? description, TextureRect? icon = null)
|
||||
protected void Setup(RoleLoadout? loadout, (string, int)[] items, string title, int titleSize, string? description, TextureRect? icon = null)
|
||||
{
|
||||
_loadout = loadout;
|
||||
|
||||
@@ -132,7 +131,7 @@ public abstract class RequirementsSelector<T> : BoxContainer where T : IPrototyp
|
||||
_loadout ??= new RoleLoadout(LoadoutSystem.GetJobPrototype(Proto.ID));
|
||||
_loadout.SetDefault(protoManager);
|
||||
|
||||
_loadoutWindow = new LoadoutWindow(profile, _loadout, protoManager.Index(_loadout.Role), session, collection)
|
||||
_loadoutWindow = new LoadoutWindow(_loadout, protoManager.Index(_loadout.Role), session, collection)
|
||||
{
|
||||
Title = Loc.GetString(Proto.ID + "-loadout"),
|
||||
};
|
||||
@@ -151,7 +150,7 @@ public abstract class RequirementsSelector<T> : BoxContainer where T : IPrototyp
|
||||
if (!_loadout.RemoveLoadout(selectedGroup, selectedLoadout, protoManager))
|
||||
return;
|
||||
|
||||
_loadout.EnsureValid(profile, session, collection);
|
||||
_loadout.EnsureValid(session, collection);
|
||||
_loadoutWindow.RefreshLoadouts(_loadout, session, collection);
|
||||
var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
|
||||
controller.ReloadProfile();
|
||||
@@ -163,7 +162,7 @@ public abstract class RequirementsSelector<T> : BoxContainer where T : IPrototyp
|
||||
if (!_loadout.AddLoadout(selectedGroup, selectedLoadout, protoManager))
|
||||
return;
|
||||
|
||||
_loadout.EnsureValid(profile, session, collection);
|
||||
_loadout.EnsureValid(session, collection);
|
||||
_loadoutWindow.RefreshLoadouts(_loadout, session, collection);
|
||||
var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
|
||||
controller.ReloadProfile();
|
||||
|
||||
@@ -23,7 +23,6 @@ using Content.Shared._White;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Utils;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared._White.Radio;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
@@ -576,12 +575,6 @@ public sealed class ChatUIController : UIController
|
||||
FilterableChannels |= ChatChannel.Changeling;
|
||||
CanSendChannels |= ChatSelectChannel.Changeling;
|
||||
}
|
||||
|
||||
if (_entities.HasComponent<NetworkChatComponent>(localEnt))
|
||||
{
|
||||
FilterableChannels |= ChatChannel.Network;
|
||||
CanSendChannels |= ChatSelectChannel.Network;
|
||||
}
|
||||
// WD EDIT END
|
||||
|
||||
SelectableChannels = CanSendChannels;
|
||||
|
||||
@@ -24,11 +24,8 @@ public sealed partial class ChannelFilterPopup : Popup
|
||||
ChatChannel.AdminAlert,
|
||||
ChatChannel.AdminChat,
|
||||
ChatChannel.Server,
|
||||
// WD EDIT START
|
||||
ChatChannel.Changeling,
|
||||
ChatChannel.Cult,
|
||||
ChatChannel.Network
|
||||
// WD EDIT END
|
||||
ChatChannel.Cult // WD EDIT
|
||||
};
|
||||
|
||||
private readonly Dictionary<ChatChannel, ChannelFilterCheckbox> _filterStates = new();
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Content.Client.UserInterface.Systems.Ghost.Controls.Roles
|
||||
bool hasAccess = true;
|
||||
FormattedMessage? reason;
|
||||
|
||||
if (!requirementsManager.CheckRoleRequirements(group.Key.Requirements, null, out reason))
|
||||
if (!requirementsManager.CheckRoleTime(group.Key.Requirements, out reason))
|
||||
{
|
||||
hasAccess = false;
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
using Content.Client.UserInterface.Fragments;
|
||||
using Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._White.CartridgeLoader.Cartridges;
|
||||
|
||||
public sealed partial class MessagesUi : UIFragment
|
||||
{
|
||||
private MessagesUiFragment _fragment;
|
||||
|
||||
public override Control GetUIFragmentRoot()
|
||||
{
|
||||
return _fragment;
|
||||
}
|
||||
|
||||
public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner)
|
||||
{
|
||||
_fragment = new MessagesUiFragment();
|
||||
_fragment.OnMessageSent += note => SendMessagesMessage(MessagesUiAction.Send, note, null, userInterface);
|
||||
_fragment.OnButtonPressed += userUid => SendMessagesMessage(MessagesUiAction.ChangeChat, null, userUid, userInterface);
|
||||
}
|
||||
|
||||
public override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
if (state is not MessagesUiState messagesState)
|
||||
return;
|
||||
|
||||
_fragment.UpdateState(messagesState.Mode, messagesState.Users, messagesState.Messages, messagesState.Name);
|
||||
}
|
||||
|
||||
private void SendMessagesMessage(MessagesUiAction action, string? stringInput, int? uidInput, BoundUserInterface userInterface)
|
||||
{
|
||||
var messagesMessage = new MessagesUiMessageEvent(action, stringInput, uidInput);
|
||||
var message = new CartridgeUiMessage(messagesMessage);
|
||||
userInterface.SendMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._White.CartridgeLoader.Cartridges;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class MessagesUiFragment : BoxContainer
|
||||
{
|
||||
public event Action<string>? OnMessageSent;
|
||||
public event Action<int?>? OnButtonPressed;
|
||||
|
||||
private string _searchText = string.Empty;
|
||||
|
||||
public MessagesUiFragment()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
Input.OnTextEntered += _ =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Input.Text))
|
||||
OnMessageSent?.Invoke(Input.Text);
|
||||
Input.Clear();
|
||||
};
|
||||
|
||||
BackButton.OnPressed += _ => OnButtonPressed?.Invoke(null);
|
||||
SearchBar.OnTextChanged += OnSearchTextChanged;
|
||||
|
||||
UpdateState(MessagesUiStateMode.UserList, [], [], null);
|
||||
}
|
||||
|
||||
public void UpdateState(MessagesUiStateMode mode, List<(MessagesUserData, int?)>? users, List<(string, int?)>? messages, string? name)
|
||||
{
|
||||
MessageContainer.DisposeAllChildren();
|
||||
Input.Orphan();
|
||||
BackButton.Orphan();
|
||||
|
||||
SearchBar.Visible = false;
|
||||
|
||||
if (mode == MessagesUiStateMode.Chat && messages != null)
|
||||
{
|
||||
HeaderLabel.Text = name;
|
||||
|
||||
foreach (var (senderName, message) in messages)
|
||||
{
|
||||
AddNote($"{senderName} {message}");
|
||||
}
|
||||
|
||||
OverContainer.AddChild(Input);
|
||||
HeaderBox.AddChild(BackButton);
|
||||
BackButton.SetPositionInParent(0);
|
||||
}
|
||||
else if (mode == MessagesUiStateMode.Error)
|
||||
{
|
||||
HeaderLabel.Text = Loc.GetString("messages-pda-error-header");
|
||||
AddNote(Loc.GetString("messages-pda-error-message"));
|
||||
}
|
||||
else if (mode == MessagesUiStateMode.UserList && users != null)
|
||||
{
|
||||
SearchBar.Visible = true;
|
||||
HeaderLabel.Text = Loc.GetString("messages-pda-chat-choice");
|
||||
foreach (var (messagesUser, userUid) in users)
|
||||
{
|
||||
AddButton(userUid, messagesUser.Name + ", " + messagesUser.Job, messagesUser.Department);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Adding a button for selecting a chat
|
||||
///</summary>
|
||||
private void AddButton(int? userUid, string userName, string departmentId)
|
||||
{
|
||||
var styleClass = IoCManager.Resolve<IPrototypeManager>().Index<DepartmentPrototype>(departmentId).ButtonStyle;
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
Text = userName,
|
||||
HorizontalExpand = true,
|
||||
ClipText = true,
|
||||
StyleClasses = { styleClass },
|
||||
MinWidth = 60
|
||||
};
|
||||
button.OnPressed += _ => OnButtonPressed?.Invoke(userUid);
|
||||
MessageContainer.AddChild(button);
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Adding a text label to the message container
|
||||
///</summary>
|
||||
private void AddNote(string note)
|
||||
{
|
||||
MessageContainer.AddChild(new Label
|
||||
{
|
||||
Text = note,
|
||||
HorizontalExpand = true,
|
||||
ClipText = false
|
||||
});
|
||||
}
|
||||
|
||||
private bool ButtonIsVisible(Button button)
|
||||
{
|
||||
return string.IsNullOrEmpty(_searchText) || button.Text == null || button.Text.Contains(_searchText, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private void UpdateVisibleButtons()
|
||||
{
|
||||
foreach (var child in MessageContainer.Children)
|
||||
{
|
||||
if (child is Button button)
|
||||
button.Visible = ButtonIsVisible(button);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSearchTextChanged(LineEdit.LineEditEventArgs args)
|
||||
{
|
||||
_searchText = args.Text;
|
||||
|
||||
UpdateVisibleButtons();
|
||||
MessagesScroll.SetScrollValue(Vector2.Zero);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<cartridges1:MessagesUiFragment
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:cartridges1="clr-namespace:Content.Client._White.CartridgeLoader.Cartridges"
|
||||
Margin="1 0 2 0" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<PanelContainer StyleClasses="BackgroundDark"/>
|
||||
<BoxContainer Name="OverContainer" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Name="HeaderBox">
|
||||
<Button Name="BackButton" Text="{Loc 'messages-pda-ui-back'}" HorizontalExpand="False"/>
|
||||
<Label Name="HeaderLabel"/>
|
||||
</BoxContainer>
|
||||
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True" Margin="0 4" />
|
||||
<ScrollContainer Name="MessagesScroll" HorizontalExpand="True" VerticalExpand="True" HScrollEnabled="True">
|
||||
<BoxContainer Orientation="Vertical" Name="MessageContainer" HorizontalExpand="True" VerticalExpand="True"/>
|
||||
</ScrollContainer>
|
||||
<LineEdit Name="Input" HorizontalExpand="True" SetHeight="32"/>
|
||||
</BoxContainer>
|
||||
</cartridges1:MessagesUiFragment>
|
||||
@@ -2,7 +2,6 @@ using System.Numerics;
|
||||
using Content.Client.Viewport;
|
||||
using Content.Shared._White.Telescope;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Input;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
@@ -24,7 +23,6 @@ public sealed class TelescopeSystem : SharedTelescopeSystem
|
||||
|
||||
private ScalingViewport? _viewport;
|
||||
|
||||
|
||||
public override void FrameUpdate(float frameTime)
|
||||
{
|
||||
base.FrameUpdate(frameTime);
|
||||
@@ -34,25 +32,19 @@ public sealed class TelescopeSystem : SharedTelescopeSystem
|
||||
|
||||
var player = _player.LocalEntity;
|
||||
|
||||
var entity = GetRightEntity(player);
|
||||
|
||||
if (entity == EntityUid.Invalid)
|
||||
return;
|
||||
|
||||
var telescope = Comp<TelescopeComponent>(entity);
|
||||
|
||||
if (!TryComp<EyeComponent>(player, out var eye))
|
||||
if (!TryComp<HandsComponent>(player, out var hands) ||
|
||||
!TryComp<TelescopeComponent>(hands.ActiveHandEntity, out var telescope) ||
|
||||
!TryComp<EyeComponent>(player.Value, out var eye))
|
||||
return;
|
||||
|
||||
var offset = Vector2.Zero;
|
||||
|
||||
if (_inputSystem.CmdStates.GetState(ContentKeyFunctions.LookUp) != BoundKeyState.Down)
|
||||
if (_inputSystem.CmdStates.GetState(EngineKeyFunctions.UseSecondary) != BoundKeyState.Down)
|
||||
{
|
||||
RaisePredictiveEvent(new EyeOffsetChangedEvent
|
||||
{
|
||||
Offset = offset
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,8 +392,7 @@ namespace Content.Server.Administration.Managers
|
||||
// я ебался в зад, поймите
|
||||
if (!data.HasFlag(AdminFlags.Permissions) && !data.HasFlag(AdminFlags.Host) &&
|
||||
dbData.AdminServer != null && dbData.AdminServer != "unknown" && currentServerName != "unknown"
|
||||
&& currentServerName != dbData.AdminServer
|
||||
&& _cfg.GetCVar(CCVars.AdminUseCustomNamesAdminRank))
|
||||
&& currentServerName != dbData.AdminServer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -405,21 +405,14 @@ namespace Content.Server.Administration.Systems
|
||||
var escapedText = FormattedMessage.EscapeText(message.Text);
|
||||
|
||||
string bwoinkText;
|
||||
string adminPrefix = "";
|
||||
|
||||
//Getting an administrator position
|
||||
if (_config.GetCVar(CCVars.AhelpAdminPrefix) && senderAdmin is not null && senderAdmin.Title is not null)
|
||||
{
|
||||
adminPrefix = $"[bold]\\[{senderAdmin.Title}\\][/bold] ";
|
||||
}
|
||||
|
||||
if (senderAdmin is not null && senderAdmin.Flags == AdminFlags.Adminhelp) // Mentor. Not full admin. That's why it's colored differently.
|
||||
{
|
||||
bwoinkText = $"[color=purple]{adminPrefix}{senderSession.Name}[/color]";
|
||||
bwoinkText = $"[color=purple]{senderSession.Name}[/color]";
|
||||
}
|
||||
else if (senderAdmin is not null && senderAdmin.HasFlag(AdminFlags.Adminhelp))
|
||||
{
|
||||
bwoinkText = $"[color=red]{adminPrefix}{senderSession.Name}[/color]";
|
||||
bwoinkText = $"[color=red]{senderSession.Name}[/color]";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -442,13 +435,6 @@ namespace Content.Server.Administration.Systems
|
||||
RaiseNetworkEvent(msg, channel);
|
||||
}
|
||||
|
||||
string adminPrefixWebhook = "";
|
||||
|
||||
if (_config.GetCVar(CCVars.AhelpAdminPrefixWebhook) && senderAdmin is not null && senderAdmin.Title is not null)
|
||||
{
|
||||
adminPrefixWebhook = $"[bold]\\[{senderAdmin.Title}\\][/bold] ";
|
||||
}
|
||||
|
||||
// Notify player
|
||||
if (_playerManager.TryGetSessionById(message.UserId, out var session))
|
||||
{
|
||||
@@ -461,11 +447,11 @@ namespace Content.Server.Administration.Systems
|
||||
// Doing the same thing as above, but with the override name. Theres probably a better way to do this.
|
||||
if (senderAdmin is not null && senderAdmin.Flags == AdminFlags.Adminhelp) // Mentor. Not full admin. That's why it's colored differently.
|
||||
{
|
||||
overrideMsgText = $"[color=purple]{adminPrefixWebhook}{_overrideClientName}[/color]";
|
||||
overrideMsgText = $"[color=purple]{_overrideClientName}[/color]";
|
||||
}
|
||||
else if (senderAdmin is not null && senderAdmin.HasFlag(AdminFlags.Adminhelp))
|
||||
{
|
||||
overrideMsgText = $"[color=red]{adminPrefixWebhook}{_overrideClientName}[/color]";
|
||||
overrideMsgText = $"[color=red]{_overrideClientName}[/color]";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -386,4 +386,4 @@ public sealed class AntagSelectionSystem : GameRuleSystem<GameRuleComponent>
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace Content.Server.Body.Components
|
||||
/// The sound to be played when a weapon instantly deals blood loss damage.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier InstantBloodSound = new SoundCollectionSpecifier("BloodLossRun");
|
||||
public SoundSpecifier InstantBloodSound = new SoundCollectionSpecifier("blood");
|
||||
|
||||
/// <summary>
|
||||
/// The sound to be played when some damage actually heals bleeding rather than starting it.
|
||||
@@ -181,12 +181,6 @@ namespace Content.Server.Body.Components
|
||||
/// </summary>
|
||||
public bool IsBleeding => BleedAmount > 0;
|
||||
|
||||
public readonly AudioParams DefaultParams = AudioParams.Default.WithVolume(-1f);
|
||||
|
||||
public SoundSpecifier? BloodLossSound = new SoundCollectionSpecifier("BloodLoss");
|
||||
|
||||
//public SoundSpecifier? BloodLossRunSound = new SoundCollectionSpecifier("");
|
||||
|
||||
//WD-EDIT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Shared.Chat.Prototypes;
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
using Robust.Shared.Audio; // WD
|
||||
|
||||
@@ -53,16 +51,10 @@ namespace Content.Server.Body.Components
|
||||
public DamageSpecifier DamageRecovery = default!;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan GaspEmoteCooldown = TimeSpan.FromSeconds(8);
|
||||
public TimeSpan GaspPopupCooldown = TimeSpan.FromSeconds(8);
|
||||
|
||||
[ViewVariables]
|
||||
public TimeSpan LastGaspEmoteTime;
|
||||
|
||||
/// <summary>
|
||||
/// The emote when gasps
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<EmotePrototype> GaspEmote = "Gasp";
|
||||
public TimeSpan LastGaspPopupTime;
|
||||
|
||||
/// <summary>
|
||||
/// How many cycles in a row has the mob been under-saturated?
|
||||
|
||||
@@ -13,12 +13,9 @@ using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.Drunk;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Popups;
|
||||
@@ -47,7 +44,7 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
|
||||
[Dependency] private readonly ForensicsSystem _forensicsSystem = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _speed = default!; // WD
|
||||
[Dependency] private readonly BloodLossAccent _bloodLossAccent = default!; // WD
|
||||
[Dependency] private readonly BloodLossAccent _bloodLossAccent = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -386,13 +383,6 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
}
|
||||
|
||||
tempSolution.RemoveAllSolution();
|
||||
|
||||
// WD edit start
|
||||
if (TryComp<MobStateComponent>(uid, out var mobState) && TryComp<StaminaComponent>(uid, out var stamina))
|
||||
if (mobState.CurrentState != MobState.Critical && !stamina.Critical)
|
||||
_audio.PlayPvs(component.BloodLossSound, uid, component.DefaultParams);
|
||||
|
||||
// WD edit end
|
||||
}
|
||||
|
||||
_solutionContainerSystem.UpdateChemicals(component.TemporarySolution.Value);
|
||||
|
||||
@@ -2,7 +2,6 @@ using Content.Server.Administration.Logs;
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Nutrition.Components; // WD
|
||||
@@ -43,16 +42,14 @@ public sealed class RespiratorSystem : EntitySystem
|
||||
[Dependency] private readonly BodySystem _bodySystem = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageableSys = default!;
|
||||
[Dependency] private readonly LungSystem _lungSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!; // WD
|
||||
[Dependency] private readonly ActionBlockerSystem _blocker = default!; // WD
|
||||
[Dependency] private readonly AudioSystem _audio = default!; // WD
|
||||
[Dependency] private readonly DoAfterSystem _doAfter = default!; // WD
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!; // WD
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!; // WD
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -119,10 +116,10 @@ public sealed class RespiratorSystem : EntitySystem
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_gameTiming.CurTime >= respirator.LastGaspEmoteTime + respirator.GaspEmoteCooldown)
|
||||
if (_gameTiming.CurTime >= respirator.LastGaspPopupTime + respirator.GaspPopupCooldown)
|
||||
{
|
||||
respirator.LastGaspEmoteTime = _gameTiming.CurTime;
|
||||
_chat.TryEmoteWithChat(uid, respirator.GaspEmote, ignoreActionBlocker: true);
|
||||
respirator.LastGaspPopupTime = _gameTiming.CurTime;
|
||||
_popupSystem.PopupEntity($"{Name(Identity.Entity(uid, EntityManager))} задыхается!", uid);
|
||||
}
|
||||
|
||||
TakeSuffocationDamage((uid, respirator));
|
||||
|
||||
@@ -24,7 +24,6 @@ using Content.Server.Popups;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Server.Temperature.Components;
|
||||
using Content.Server.Temperature.Systems;
|
||||
using Content.Shared._White.Item.PseudoItem;
|
||||
using Content.Shared._White.Overlays;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Borer;
|
||||
@@ -1012,7 +1011,7 @@ public sealed partial class ChangelingSystem
|
||||
|
||||
if (!TryComp(polymorphEntity.Value, out FelinidComponent? felinid))
|
||||
return polymorphEntity;
|
||||
|
||||
|
||||
_action.SetCharges(felinid.HairballAction, 0);
|
||||
_action.SetEnabled(felinid.HairballAction, false);
|
||||
|
||||
@@ -1021,9 +1020,6 @@ public sealed partial class ChangelingSystem
|
||||
|
||||
private void BeforeTransform(EntityUid target)
|
||||
{
|
||||
if (TryComp(target, out PseudoItemComponent? pseudoItem) && pseudoItem.Active)
|
||||
_transform.AttachToGridOrMap(target);
|
||||
|
||||
if (TryComp(target, out BorerHostComponent? host) && host.BorerContainer.Count > 0)
|
||||
_borer.GetOut(host.BorerContainer.ContainedEntities[0]);
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ using Content.Shared._White;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared.Speech;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared._White.Radio;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
@@ -774,7 +773,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
.Select(p => p.Channel);
|
||||
}
|
||||
|
||||
// WD EDIT START
|
||||
// WD EDIT
|
||||
private void SendCultChat(EntityUid source, ICommonSession player, string message, bool hideChat)
|
||||
{
|
||||
var clients = GetCultChatClients();
|
||||
@@ -803,28 +802,6 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
.Select(p => p.Channel);
|
||||
}
|
||||
|
||||
public void SendNetworkChat(EntityUid source, string message, bool hideChat)
|
||||
{
|
||||
var clients = GetNetworkChatClients();
|
||||
var wrappedMessage = Loc.GetString("chat-manager-send-message-chat-wrap-message",
|
||||
("channelName", Loc.GetString("chat-manager-message-channel-name")),
|
||||
("message", FormattedMessage.EscapeText(message)));
|
||||
|
||||
_chatManager.ChatMessageToMany(ChatChannel.Network, message, wrappedMessage, source, hideChat, false,
|
||||
clients.ToList());
|
||||
}
|
||||
|
||||
private IEnumerable<INetChannel> GetNetworkChatClients()
|
||||
{
|
||||
return Filter.Empty()
|
||||
.AddWhereAttachedEntity(HasComp<GhostComponent>)
|
||||
.AddWhereAttachedEntity(HasComp<NetworkChatComponent>)
|
||||
.Recipients
|
||||
.Union(_adminManager.ActiveAdmins)
|
||||
.Select(p => p.Channel);
|
||||
}
|
||||
// WD EDIT END
|
||||
|
||||
private void SendDeadChat(EntityUid source, ICommonSession player, string message, bool hideChat)
|
||||
{
|
||||
var clients = GetDeadChatClients();
|
||||
|
||||
@@ -205,7 +205,7 @@ public sealed class InjectorSystem : SharedInjectorSystem
|
||||
|
||||
DoAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, actualDelay, new InjectorDoAfterEvent(), injector.Owner, target: target, used: injector.Owner)
|
||||
{
|
||||
BreakOnMove = isTarget, // WD EDIT
|
||||
BreakOnMove = true,
|
||||
BreakOnWeightlessMove = false,
|
||||
BreakOnDamage = true,
|
||||
NeedHand = true,
|
||||
|
||||
@@ -56,7 +56,7 @@ public sealed class SingletonDeviceNetServerSystem : EntitySystem
|
||||
|
||||
if (!server.Available)
|
||||
{
|
||||
DisconnectServer(uid, server, device);
|
||||
DisconnectServer(uid,server, device);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,10 +149,8 @@ public sealed partial class EnergyDomeSystem : EntitySystem
|
||||
|
||||
private void OnGetActions(Entity<EnergyDomeGeneratorComponent> generator, ref GetItemActionsEvent args)
|
||||
{
|
||||
if (args.SlotFlags != SlotFlags.OUTERCLOTHING)
|
||||
return;
|
||||
|
||||
args.AddAction(ref generator.Comp.ToggleActionEntity, generator.Comp.ToggleAction);
|
||||
if (generator.Comp.CanInteractUse)
|
||||
args.AddAction(ref generator.Comp.ToggleActionEntity, generator.Comp.ToggleAction);
|
||||
}
|
||||
|
||||
private void OnToggleAction(Entity<EnergyDomeGeneratorComponent> generator, ref ToggleActionEvent args)
|
||||
|
||||
@@ -14,10 +14,6 @@ namespace Content.Server.Ghost.Roles.Components
|
||||
|
||||
[DataField("rules")] private string _roleRules = "ghost-role-component-default-rules";
|
||||
|
||||
// TODO ROLE TIMERS
|
||||
// Actually make use of / enforce this requirement?
|
||||
// Why is this even here.
|
||||
// Move to ghost role prototype & respect CCvars.GameRoleTimerOverride
|
||||
[DataField("requirements")]
|
||||
public HashSet<JobRequirement>? Requirements;
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ using Content.Server.Station.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.StationRecords;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Content.Server.Chat.Managers;
|
||||
|
||||
namespace Content.Server.MassMedia.Systems;
|
||||
|
||||
@@ -36,7 +35,6 @@ public sealed class NewsSystem : SharedNewsSystem
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
|
||||
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -169,12 +167,6 @@ public sealed class NewsSystem : SharedNewsSystem
|
||||
$"{ToPrettyString(author):actor} created news article {article.Title} by {article.Author}: {article.Content}"
|
||||
);
|
||||
|
||||
_chatManager.SendAdminAnnouncement(Loc.GetString("news-publish-admin-announcement",
|
||||
("actor", msg.Session.AttachedEntity),
|
||||
("title", article.Title),
|
||||
("author", article.Author ?? Loc.GetString("news-read-ui-no-author"))
|
||||
));
|
||||
|
||||
articles.Add(article);
|
||||
|
||||
var args = new NewsArticlePublishedEvent(article);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Medical.SuitSensors;
|
||||
|
||||
@@ -7,9 +7,12 @@ using Content.Server.Ghost;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.PowerCell;
|
||||
using Content.Server.Traits.Assorted;
|
||||
using Content.Shared._White.Item.DelayedKnockdown;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Damage.Events;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Interaction.Events;
|
||||
@@ -21,6 +24,8 @@ using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.PowerCell;
|
||||
using Content.Shared.Timing;
|
||||
using Content.Shared.Toggleable;
|
||||
using Content.Shared.Weapons.Melee;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
@@ -67,8 +72,6 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
{
|
||||
if (!_powerCell.HasActivatableCharge(uid))
|
||||
TryDisable(uid, comp);
|
||||
comp.NextZapTime = _timing.CurTime + TimeSpan.FromSeconds(3);
|
||||
_appearance.SetData(uid, DefibrillatorVisuals.Ready, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -198,7 +201,6 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
uid, target, uid)
|
||||
{
|
||||
BreakOnMove = user == target, // WD EDIT
|
||||
DuplicateCondition = DuplicateConditions.None, // WD EDIT
|
||||
BlockDuplicate = true,
|
||||
BreakOnHandChange = true,
|
||||
NeedHand = true
|
||||
|
||||
@@ -88,7 +88,7 @@ public sealed class RenameCommand : IConsoleCommand
|
||||
{
|
||||
if (pda.OwnerName == oldName)
|
||||
{
|
||||
pdaSystem.SetOwnerName(uid, pda, name);
|
||||
pdaSystem.SetOwner(uid, pda, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Light.Components;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
@@ -91,24 +90,12 @@ namespace Content.Server.PDA
|
||||
UpdatePdaUi(uid, pda);
|
||||
}
|
||||
|
||||
public void SetOwnerName(EntityUid uid, PdaComponent pda, string ownerName)
|
||||
public void SetOwner(EntityUid uid, PdaComponent pda, string ownerName)
|
||||
{
|
||||
pda.OwnerName = ownerName;
|
||||
UpdatePdaUi(uid, pda);
|
||||
}
|
||||
|
||||
public void SetOwnerJob(EntityUid uid, PdaComponent pda, string ownerJob)
|
||||
{
|
||||
pda.OwnerJob = ownerJob;
|
||||
UpdatePdaUi(uid, pda);
|
||||
}
|
||||
|
||||
public void SetOwnerDepartment(EntityUid uid, PdaComponent pda, string ownerDepartment)
|
||||
{
|
||||
pda.OwnerDepartment = ownerDepartment;
|
||||
UpdatePdaUi(uid, pda);
|
||||
}
|
||||
|
||||
private void OnStationRenamed(StationRenamedEvent ev)
|
||||
{
|
||||
UpdateAllPdaUisOnStation();
|
||||
@@ -185,7 +172,6 @@ namespace Content.Server.PDA
|
||||
new PdaIdInfoText
|
||||
{
|
||||
ActualOwnerName = pda.OwnerName,
|
||||
ActualOwnerJob = pda.OwnerJob, // WD EDIT
|
||||
IdOwner = id?.FullName,
|
||||
JobTitle = id?.JobTitle,
|
||||
StationAlertLevel = pda.StationAlertLevel,
|
||||
|
||||
@@ -4,15 +4,12 @@ using Content.Server.Afk;
|
||||
using Content.Server.Afk.Events;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Preferences.Managers;
|
||||
using Content.Server.Station.Events;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Players;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
@@ -36,8 +33,6 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
[Dependency] private readonly MindSystem _minds = default!;
|
||||
[Dependency] private readonly IPlayTimeTrackingManager _tracking = default!;
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _role = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -164,9 +159,18 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
_tracking.QueueSendTimers(ev.PlayerSession);
|
||||
}
|
||||
|
||||
private bool IsBypassingChecks(ICommonSession player)
|
||||
{
|
||||
return _adminManager.IsAdmin(player, true);
|
||||
}
|
||||
|
||||
public bool IsAllowed(ICommonSession player, string role)
|
||||
{
|
||||
if (IsBypassingChecks(player))
|
||||
return true;
|
||||
|
||||
if (!_prototypes.TryIndex<JobPrototype>(role, out var job) ||
|
||||
job.Requirements == null ||
|
||||
!_cfg.GetCVar(CCVars.GameRoleTimers))
|
||||
return true;
|
||||
|
||||
@@ -176,15 +180,16 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
playTimes = new Dictionary<string, TimeSpan>();
|
||||
}
|
||||
|
||||
var isAdmin = _adminManager.IsAdmin(player, true); // WD
|
||||
|
||||
return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(player.UserId).SelectedCharacter, isAdmin); // WD EDIT
|
||||
return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes);
|
||||
}
|
||||
|
||||
public HashSet<string> GetDisallowedJobs(ICommonSession player)
|
||||
{
|
||||
var roles = new HashSet<string>();
|
||||
|
||||
if (IsBypassingChecks(player))
|
||||
return roles;
|
||||
|
||||
if (!_cfg.GetCVar(CCVars.GameRoleTimers))
|
||||
return roles;
|
||||
|
||||
@@ -194,24 +199,36 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
playTimes = new Dictionary<string, TimeSpan>();
|
||||
}
|
||||
|
||||
var isAdmin = _adminManager.IsAdmin(player, true); // WD
|
||||
|
||||
foreach (var job in _prototypes.EnumeratePrototypes<JobPrototype>())
|
||||
{
|
||||
if (JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(player.UserId).SelectedCharacter, isAdmin)) // WD EDIT
|
||||
roles.Add(job.ID);
|
||||
if (job.Requirements != null)
|
||||
{
|
||||
foreach (var requirement in job.Requirements)
|
||||
{
|
||||
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
|
||||
continue;
|
||||
|
||||
goto NoRole;
|
||||
}
|
||||
}
|
||||
|
||||
roles.Add(job.ID);
|
||||
NoRole:;
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void RemoveDisallowedJobs(NetUserId userId, List<ProtoId<JobPrototype>> jobs)
|
||||
public void RemoveDisallowedJobs(NetUserId userId, ref List<string> jobs)
|
||||
{
|
||||
if (!_cfg.GetCVar(CCVars.GameRoleTimers))
|
||||
return;
|
||||
|
||||
var player = _playerManager.GetSessionById(userId);
|
||||
|
||||
if (IsBypassingChecks(player))
|
||||
return;
|
||||
|
||||
if (!_tracking.TryGetTrackerTimes(player, out var playTimes))
|
||||
{
|
||||
// Sorry mate but your playtimes haven't loaded.
|
||||
@@ -219,18 +236,24 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
playTimes ??= new Dictionary<string, TimeSpan>();
|
||||
}
|
||||
|
||||
var isAdmin = _adminManager.IsAdmin(player, true); // WD
|
||||
|
||||
for (var i = 0; i < jobs.Count; i++)
|
||||
{
|
||||
if (_prototypes.TryIndex(jobs[i], out var job)
|
||||
&& JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, (HumanoidCharacterProfile?) _preferencesManager.GetPreferences(userId).SelectedCharacter, isAdmin)) // WD EDIT
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var job = jobs[i];
|
||||
|
||||
jobs.RemoveSwap(i);
|
||||
i--;
|
||||
if (!_prototypes.TryIndex<JobPrototype>(job, out var jobber) ||
|
||||
jobber.Requirements == null ||
|
||||
jobber.Requirements.Count == 0)
|
||||
continue;
|
||||
|
||||
foreach (var requirement in jobber.Requirements)
|
||||
{
|
||||
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
|
||||
continue;
|
||||
|
||||
jobs.RemoveSwap(i);
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Server.Lightning;
|
||||
using Content.Server.Beam;
|
||||
using Content.Shared.Revenant.Components;
|
||||
using Content.Shared.Revenant.EntitySystems;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Content.Server.Revenant.EntitySystems;
|
||||
/// </summary>
|
||||
public sealed class RevenantOverloadedLightsSystem : SharedRevenantOverloadedLightsSystem
|
||||
{
|
||||
[Dependency] private readonly LightningSystem _lightning = default!; // WD EDIT
|
||||
[Dependency] private readonly BeamSystem _beam = default!;
|
||||
|
||||
protected override void OnZap(Entity<RevenantOverloadedLightsComponent> lights)
|
||||
{
|
||||
@@ -25,6 +25,6 @@ public sealed class RevenantOverloadedLightsSystem : SharedRevenantOverloadedLig
|
||||
if (distance > component.ZapRange)
|
||||
return;
|
||||
|
||||
_lightning.ShootLightning(lights, component.Target.Value, component.ZapBeamEntityId, false); // WD EDIT
|
||||
_beam.TryCreateBeam(lights, component.Target.Value, component.ZapBeamEntityId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,20 @@ namespace Content.Server.Speech.EntitySystems
|
||||
{
|
||||
public sealed class OwOAccentSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
private static readonly IReadOnlyList<string> Faces = new List<string>{
|
||||
//WD-EDIT
|
||||
" (`ω´)", " ;;w;;", " owo", " UwU", " >w<", " ^w^"
|
||||
//WD-EDIT
|
||||
}.AsReadOnly();
|
||||
|
||||
private static readonly IReadOnlyDictionary<string, string> SpecialWords = new Dictionary<string, string>()
|
||||
{
|
||||
{ "you", "wu" },
|
||||
{ "ты", "ти" } // WD
|
||||
//WD-EDIT
|
||||
{ "ты", "ти" }
|
||||
//WD-EDIT
|
||||
};
|
||||
|
||||
public override void Initialize()
|
||||
@@ -23,7 +33,8 @@ namespace Content.Server.Speech.EntitySystems
|
||||
message = message.Replace(word, repl);
|
||||
}
|
||||
|
||||
return message.Replace("r", "w").Replace("R", "W")
|
||||
return message.Replace("!", _random.Pick(Faces))
|
||||
.Replace("r", "w").Replace("R", "W")
|
||||
.Replace("l", "w").Replace("L", "W")
|
||||
|
||||
//WD-EDIT
|
||||
|
||||
@@ -345,8 +345,8 @@ public sealed partial class StationJobsSystem
|
||||
foreach (var (player, profile) in profiles)
|
||||
{
|
||||
var roleBans = _banManager.GetJobBans(player);
|
||||
var profileJobs = profile.JobPriorities.Keys.Select(k => new ProtoId<JobPrototype>(k)).ToList();
|
||||
_playTime.RemoveDisallowedJobs(player, profileJobs);
|
||||
var profileJobs = profile.JobPriorities.Keys.ToList();
|
||||
_playTime.RemoveDisallowedJobs(player, ref profileJobs);
|
||||
|
||||
List<string>? availableJobs = null;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ using Content.Shared.Access.Systems;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Server.Roles.Jobs;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Shared.Preferences;
|
||||
@@ -50,7 +49,6 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
|
||||
[Dependency] private readonly SharedAccessSystem _accessSystem = default!;
|
||||
[Dependency] private readonly IdentitySystem _identity = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
|
||||
[Dependency] private readonly JobSystem _jobs = default!; // WD EDIT
|
||||
|
||||
[Dependency] private readonly ArrivalsSystem _arrivalsSystem = default!;
|
||||
[Dependency] private readonly ContainerSpawnPointSystem _containerSpawnPointSystem = default!;
|
||||
@@ -339,14 +337,7 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
|
||||
_accessSystem.SetAccessToJob(cardId, jobPrototype, extendedAccess);
|
||||
|
||||
if (pdaComponent != null)
|
||||
{
|
||||
_pdaSystem.SetOwnerName(idUid.Value, pdaComponent, characterName);
|
||||
//WD EDIT START
|
||||
_pdaSystem.SetOwnerJob(idUid.Value, pdaComponent, jobPrototype.LocalizedName);
|
||||
_jobs.TryGetDepartment(jobPrototype.ID, out var department);
|
||||
_pdaSystem.SetOwnerDepartment(idUid.Value, pdaComponent, department?.ID ?? "Specific");
|
||||
//WD EDIT END
|
||||
}
|
||||
_pdaSystem.SetOwner(idUid.Value, pdaComponent, characterName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public sealed partial class BuyerDepartmentCondition : ListingCondition
|
||||
{
|
||||
foreach (var department in prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
||||
{
|
||||
if (department.Roles.Contains(job.Prototype.Value) && Blacklist.Contains(department.ID))
|
||||
if (department.Roles.Contains(job.Prototype) && Blacklist.Contains(department.ID))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public sealed partial class BuyerDepartmentCondition : ListingCondition
|
||||
{
|
||||
foreach (var department in prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
||||
{
|
||||
if (department.Roles.Contains(job.Prototype.Value) && Whitelist.Contains(department.ID))
|
||||
if (department.Roles.Contains(job.Prototype) && Whitelist.Contains(department.ID))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace Content.Server.VendingMachines
|
||||
|
||||
private void OnWithdrawMessage(EntityUid uid, VendingMachineComponent component, VendingMachineWithdrawMessage args)
|
||||
{
|
||||
_stackSystem.Spawn(component.Credits, PrototypeManager.Index(component.CreditStackPrototype),
|
||||
_stackSystem.Spawn(component.Credits, PrototypeManager.Index(component.CreditStackPrototype),
|
||||
Transform(uid).Coordinates);
|
||||
component.Credits = 0;
|
||||
Audio.PlayPvs(component.SoundWithdrawCurrency, uid);
|
||||
@@ -583,7 +583,7 @@ namespace Content.Server.VendingMachines
|
||||
if (!Resolve(uid, ref vendComponent))
|
||||
return;
|
||||
|
||||
RestockInventoryFromPrototype(uid, vendComponent, false);
|
||||
RestockInventoryFromPrototype(uid, vendComponent);
|
||||
|
||||
UpdateVendingMachineInterfaceState(uid, vendComponent);
|
||||
TryUpdateVisualState(uid, vendComponent);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Content.Server._White.AspectsSystem.Aspects.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ImmersiveAspectComponent : Component
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server._White.AspectsSystem.Aspects.Components;
|
||||
using Content.Server._White.AspectsSystem.Base;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Shared._White.Telescope;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Movement.Systems;
|
||||
|
||||
namespace Content.Server._White.AspectsSystem.Aspects;
|
||||
|
||||
public sealed class ImmersiveAspect : AspectSystem<ImmersiveAspectComponent>
|
||||
{
|
||||
|
||||
[Dependency] private readonly SharedContentEyeSystem _eye = default!;
|
||||
[Dependency] private readonly SharedTelescopeSystem _telescope = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(HandleLateJoin);
|
||||
}
|
||||
|
||||
protected override void Started(EntityUid uid, ImmersiveAspectComponent component, GameRuleComponent gameRule,
|
||||
GameRuleStartedEvent args)
|
||||
{
|
||||
base.Started(uid, component, gameRule, args);
|
||||
|
||||
WayToHRPPlusPlus();
|
||||
}
|
||||
|
||||
private void WayToHRPPlusPlus()
|
||||
{
|
||||
var humans = EntityQuery<HumanoidAppearanceComponent>();
|
||||
|
||||
foreach (var human in humans)
|
||||
{
|
||||
var entity = human.Owner;
|
||||
|
||||
if (!HasComp<ContentEyeComponent>(entity))
|
||||
continue;
|
||||
|
||||
FuckUpEye(entity, 0.6f);
|
||||
AddTelescope(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private void FuckUpEye(EntityUid human, float modifier)
|
||||
{
|
||||
_eye.SetMaxZoom(human, new Vector2(modifier));
|
||||
_eye.SetZoom(human, new Vector2(modifier));
|
||||
}
|
||||
|
||||
private void AddTelescope(EntityUid human)
|
||||
{
|
||||
var telescope = EnsureComp<TelescopeComponent>(human);
|
||||
|
||||
_telescope.SetParameters((human, telescope), 0.15f, 0.07f);
|
||||
}
|
||||
|
||||
private void HandleLateJoin(PlayerSpawnCompleteEvent ev)
|
||||
{
|
||||
if (!ev.LateJoin)
|
||||
return;
|
||||
|
||||
if (!HasComp<ContentEyeComponent>(ev.Mob))
|
||||
return;
|
||||
|
||||
var query = EntityQueryEnumerator<ImmersiveAspectComponent, GameRuleComponent>();
|
||||
while (query.MoveNext(out var ruleEntity, out _, out var gameRule))
|
||||
{
|
||||
if (!GameTicker.IsGameRuleAdded(ruleEntity, gameRule))
|
||||
continue;
|
||||
|
||||
FuckUpEye(ev.Mob, 0.6f);
|
||||
AddTelescope(ev.Mob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void Ended(EntityUid uid, ImmersiveAspectComponent component, GameRuleComponent gameRule, GameRuleEndedEvent args)
|
||||
{
|
||||
base.Ended(uid, component, gameRule, args);
|
||||
|
||||
var humans = EntityQuery<HumanoidAppearanceComponent>();
|
||||
|
||||
foreach (var human in humans)
|
||||
{
|
||||
var entity = human.Owner;
|
||||
|
||||
if (!HasComp<ContentEyeComponent>(entity))
|
||||
continue;
|
||||
|
||||
FuckUpEye(entity, 1f);
|
||||
|
||||
RemComp<TelescopeComponent>(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Server._White.AutoRegenReagent
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class AutoRegenReagentComponent : Component
|
||||
{
|
||||
[DataField("solution", required: true)]
|
||||
public string? SolutionName = null; // we'll fail during tests otherwise
|
||||
|
||||
[DataField("reagents", required: true)]
|
||||
public List<string> Reagents = default!;
|
||||
|
||||
[DataField]
|
||||
public string CurrentReagent = "";
|
||||
|
||||
[DataField]
|
||||
public int CurrentIndex = 0;
|
||||
|
||||
public Entity<SolutionComponent>? Solution = default!;
|
||||
|
||||
[DataField("interval")]
|
||||
public TimeSpan Interval = TimeSpan.FromSeconds(10);
|
||||
|
||||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||
public TimeSpan NextUpdate;
|
||||
|
||||
[DataField("unitsPerInterval")]
|
||||
public float UnitsPerInterval = 1f;
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._White.AutoRegenReagent
|
||||
{
|
||||
/// <summary>
|
||||
/// So we have a solution name in AutoRegenReagent comp. We will try to get it and start generating reagents. When we switch reagents we clear the solution and start generating different reagent.
|
||||
/// </summary>
|
||||
public sealed class AutoRegenReagentSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popups = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<AutoRegenReagentComponent, ComponentInit>(OnCompInit);
|
||||
SubscribeLocalEvent<AutoRegenReagentComponent, GetVerbsEvent<AlternativeVerb>>(AddSwitchVerb);
|
||||
SubscribeLocalEvent<AutoRegenReagentComponent, ExaminedEvent>(OnExamined);
|
||||
SubscribeLocalEvent<AutoRegenReagentComponent, UseInHandEvent>(OnUseInHand,
|
||||
before: new[] { typeof(ChemistrySystem) });
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
var query = EntityQueryEnumerator<AutoRegenReagentComponent>();
|
||||
while (query.MoveNext(out var uid, out var autoComp))
|
||||
{
|
||||
if (_timing.CurTime < autoComp.NextUpdate)
|
||||
return;
|
||||
|
||||
autoComp.NextUpdate += autoComp.Interval;
|
||||
|
||||
if (autoComp.Solution == null)
|
||||
TryGetSolution(uid, autoComp);
|
||||
|
||||
if (autoComp.Solution == null)
|
||||
return;
|
||||
|
||||
_solutionSystem.TryAddReagent(autoComp.Solution.Value, autoComp.CurrentReagent, autoComp.UnitsPerInterval);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCompInit(EntityUid uid, AutoRegenReagentComponent component, ComponentInit args)
|
||||
{
|
||||
component.NextUpdate = _timing.CurTime + component.Interval;
|
||||
SwitchReagent(component);
|
||||
}
|
||||
|
||||
private void OnUseInHand(EntityUid uid, AutoRegenReagentComponent component, UseInHandEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (component.Reagents.Count <= 1)
|
||||
return;
|
||||
|
||||
SwitchReagent(component, args.User);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnExamined(EntityUid uid, AutoRegenReagentComponent component, ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("reagent-name", ("reagent", component.CurrentReagent)));
|
||||
}
|
||||
|
||||
private void AddSwitchVerb(EntityUid uid, AutoRegenReagentComponent component,
|
||||
GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!args.CanInteract || !args.CanAccess)
|
||||
return;
|
||||
|
||||
if (component.Reagents.Count <= 1)
|
||||
return;
|
||||
|
||||
AlternativeVerb verb = new()
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
SwitchReagent(component, args.User);
|
||||
},
|
||||
Text = Loc.GetString("autoreagent-switch"),
|
||||
Priority = 2
|
||||
};
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private void TryGetSolution(EntityUid uid, AutoRegenReagentComponent component)
|
||||
{
|
||||
if (component.SolutionName == null)
|
||||
return;
|
||||
|
||||
if (!_solutionSystem.TryGetSolution(uid, component.SolutionName, out var solution))
|
||||
return;
|
||||
|
||||
component.Solution = solution;
|
||||
|
||||
component.CurrentReagent = component.Reagents[component.CurrentIndex];
|
||||
}
|
||||
|
||||
private string SwitchReagent(AutoRegenReagentComponent component, EntityUid? user = null)
|
||||
{
|
||||
if (component.CurrentIndex + 1 == component.Reagents.Count)
|
||||
component.CurrentIndex = 0;
|
||||
else
|
||||
component.CurrentIndex++;
|
||||
|
||||
if (component.Solution != null)
|
||||
_solutionSystem.RemoveAllSolution(component.Solution.Value);
|
||||
|
||||
component.CurrentReagent = component.Reagents[component.CurrentIndex];
|
||||
|
||||
if (user != null)
|
||||
_popups.PopupEntity(Loc.GetString("autoregen-switched", ("reagent", component.CurrentReagent)), user.Value, user.Value);
|
||||
|
||||
return component.CurrentReagent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace Content.Server._White.CartridgeLoader.Cartridges;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class MessagesCartridgeComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The component of the last contacted server
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid? LastServer;
|
||||
|
||||
/// <summary>
|
||||
/// The message system user id of the crew the user is chatting with
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int? ChatUid;
|
||||
|
||||
[DataField]
|
||||
public int? UserUid;
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
using System.Linq;
|
||||
using Content.Server._White.Radio.Components;
|
||||
using Content.Server._White.Radio.EntitySystems;
|
||||
using Content.Server.CartridgeLoader;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Server.GameTicking;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
|
||||
namespace Content.Server._White.CartridgeLoader.Cartridges;
|
||||
|
||||
public sealed class MessagesCartridgeSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly CartridgeLoaderSystem _cartridgeLoaderSystem = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
[Dependency] private readonly MessagesServerSystem _messagesServerSystem = default!;
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!;
|
||||
[Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = default!;
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, CartridgeMessageEvent>(OnUiMessage);
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, CartridgeUiReadyEvent>(OnUiReady);
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, CartridgeActivatedEvent>(OnCartActivation);
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, CartridgeDeactivatedEvent>(OnCartDeactivation);
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, CartridgeAddedEvent>(OnCartInsertion);
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<MessagesCartridgeComponent, ComponentRemove>(OnRemove);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, MessagesCartridgeComponent component, ComponentInit args)
|
||||
{
|
||||
var stationId = _stationSystem.GetOwningStation(uid);
|
||||
if (!stationId.HasValue ||
|
||||
!_singletonServerSystem.TryGetActiveServerAddress<MessagesServerComponent>(stationId.Value,
|
||||
out var address) || !TryComp(uid, out CartridgeComponent? cartComponent))
|
||||
return;
|
||||
|
||||
SendName(uid, component, cartComponent, address);
|
||||
component.UserUid = cartComponent.LoaderUid?.Id;
|
||||
}
|
||||
|
||||
private void OnRemove(EntityUid uid, MessagesCartridgeComponent component, ComponentRemove args)
|
||||
{
|
||||
if (component.LastServer == null || !TryComp<MessagesServerComponent>(component.LastServer, out var messagesServerComponent) || component.UserUid == null)
|
||||
return;
|
||||
|
||||
messagesServerComponent.Dictionary.Remove(component.UserUid.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This gets called when the ui fragment needs to be updated for the first time after activating
|
||||
/// </summary>
|
||||
private void OnUiReady(EntityUid uid, MessagesCartridgeComponent component, CartridgeUiReadyEvent args)
|
||||
{
|
||||
var stationId = _stationSystem.GetOwningStation(uid);
|
||||
if (stationId.HasValue && _singletonServerSystem.TryGetActiveServerAddress<MessagesServerComponent>(stationId.Value, out var address) && TryComp(uid, out CartridgeComponent? cartComponent))
|
||||
SendName(uid, component, cartComponent, address);
|
||||
|
||||
UpdateUiState(uid, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The ui messages received here get wrapped by a CartridgeMessageEvent and are relayed from the <see cref="CartridgeLoaderSystem"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The cartridge specific ui message event needs to inherit from the CartridgeMessageEvent
|
||||
/// </remarks>
|
||||
private void OnUiMessage(EntityUid uid, MessagesCartridgeComponent component, CartridgeMessageEvent args)
|
||||
{
|
||||
if (args is not MessagesUiMessageEvent messageEvent)
|
||||
return;
|
||||
|
||||
if (messageEvent.Action == MessagesUiAction.Send && HasComp<CartridgeComponent>(uid) && component.UserUid is { } userId && component.ChatUid != null && messageEvent.StringInput != null)
|
||||
{
|
||||
var stationId = _stationSystem.GetOwningStation(uid);
|
||||
if (!stationId.HasValue)
|
||||
return;
|
||||
|
||||
var content = messageEvent.StringInput;
|
||||
if (content.Length > 1000)
|
||||
content = content.Substring(0, 997) + "...";
|
||||
|
||||
MessagesMessageData messageData = new()
|
||||
{
|
||||
SenderId = userId,
|
||||
ReceiverId = component.ChatUid.Value,
|
||||
Content = content,
|
||||
Time = _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan)
|
||||
};
|
||||
var packet = new NetworkPayload()
|
||||
{
|
||||
[MessagesNetworkKeys.Message] = messageData
|
||||
};
|
||||
_singletonServerSystem.TryGetActiveServerAddress<MessagesServerComponent>(stationId.Value, out var address);
|
||||
_deviceNetworkSystem.QueuePacket(uid, address, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (messageEvent.Action == MessagesUiAction.ChangeChat)
|
||||
component.ChatUid = messageEvent.TargetChatUid;
|
||||
}
|
||||
|
||||
UpdateUiState(uid, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On cart insertion, register as background process.
|
||||
/// </summary>
|
||||
private void OnCartInsertion(EntityUid uid, MessagesCartridgeComponent component, CartridgeAddedEvent args)
|
||||
{
|
||||
_cartridgeLoaderSystem.RegisterBackgroundProgram(args.Loader, uid);
|
||||
component.UserUid = args.Loader.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On cartridge activation, connect to messages network.
|
||||
/// </summary>
|
||||
private void OnCartActivation(EntityUid uid, MessagesCartridgeComponent component, CartridgeActivatedEvent args)
|
||||
{
|
||||
_deviceNetworkSystem.ConnectDevice(uid);
|
||||
var stationId = _stationSystem.GetOwningStation(uid);
|
||||
if (stationId.HasValue && _singletonServerSystem.TryGetActiveServerAddress<MessagesServerComponent>(stationId.Value, out var address) && TryComp(uid, out CartridgeComponent? cartComponent))
|
||||
SendName(uid, component, cartComponent, address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On cartridge deactivation, disconnect from messages network.
|
||||
/// </summary>
|
||||
private void OnCartDeactivation(EntityUid uid, MessagesCartridgeComponent component, CartridgeDeactivatedEvent args)
|
||||
{
|
||||
_deviceNetworkSystem.DisconnectDevice(uid, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// React and respond to packets from the server
|
||||
/// </summary>
|
||||
private void OnPacketReceived(EntityUid uid, MessagesCartridgeComponent component, DeviceNetworkPacketEvent args)
|
||||
{
|
||||
if (!TryComp(uid, out CartridgeComponent? cartComponent))
|
||||
return;
|
||||
component.LastServer = args.Sender;
|
||||
if (args.Data.TryGetValue<MessagesMessageData>(MessagesNetworkKeys.Message, out var message) && cartComponent.LoaderUid != null)
|
||||
{
|
||||
if (message.ReceiverId == cartComponent.LoaderUid.Value.Id)
|
||||
{
|
||||
TryGetName(message.SenderId, component, out var name);
|
||||
|
||||
var subtitleString = Loc.GetString("messages-pda-notification-header", ("name", name));
|
||||
|
||||
_cartridgeLoaderSystem.SendNotification(
|
||||
cartComponent.LoaderUid.Value,
|
||||
subtitleString,
|
||||
message.Content);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateUiState(uid, component);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the user's name in the storage component.
|
||||
/// </summary>
|
||||
private void SendName(EntityUid uid, MessagesCartridgeComponent component, CartridgeComponent cartComponent, string? address)
|
||||
{
|
||||
TryGetMessagesUser(component, cartComponent, out var messagesUser);
|
||||
|
||||
var packet = new NetworkPayload()
|
||||
{
|
||||
[MessagesNetworkKeys.UserId] = component.UserUid,
|
||||
[MessagesNetworkKeys.NewUser] = messagesUser
|
||||
};
|
||||
_deviceNetworkSystem.QueuePacket(uid, address, packet);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the name of the given user from the last contacted server
|
||||
/// </summary>
|
||||
private void TryGetName(int key, MessagesCartridgeComponent component, out string name)
|
||||
{
|
||||
if (component.LastServer != null && _messagesServerSystem.TryGetUserFromDict(component.LastServer, key, out var messagesUser))
|
||||
{
|
||||
name = messagesUser.Name;
|
||||
return;
|
||||
}
|
||||
|
||||
name = Loc.GetString("messages-pda-connection-error");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the user's name, job title and job department
|
||||
/// </summary>
|
||||
public bool TryGetMessagesUser(MessagesCartridgeComponent component, CartridgeComponent cartridgeComponent, out MessagesUserData messagesUserData)
|
||||
{
|
||||
messagesUserData = new MessagesUserData();
|
||||
|
||||
if (component.LastServer != null &&
|
||||
TryComp<MessagesServerComponent>(component.LastServer, out var messagesServerComponent) &&
|
||||
component.UserUid != null)
|
||||
messagesUserData = messagesServerComponent.Dictionary[component.UserUid.Value];
|
||||
|
||||
var pda = cartridgeComponent.LoaderUid;
|
||||
if (pda == null)
|
||||
return false;
|
||||
|
||||
var pdaComponent = CompOrNull<PdaComponent>(pda);
|
||||
if (pdaComponent?.OwnerName == null)
|
||||
return false;
|
||||
|
||||
messagesUserData.SetMessagesUser(pdaComponent.OwnerName, pdaComponent.OwnerJob, pdaComponent.OwnerDepartment);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateUiState(EntityUid uid, MessagesCartridgeComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
if (!TryComp(uid, out CartridgeComponent? cartComponent))
|
||||
return;
|
||||
|
||||
if (cartComponent.LoaderUid == null)
|
||||
return;
|
||||
|
||||
var loaderUid = cartComponent.LoaderUid.Value;
|
||||
MessagesUiState state;
|
||||
var currentUserId = component.UserUid;
|
||||
if (currentUserId == null || component.LastServer == null)
|
||||
{
|
||||
state = new MessagesUiState(MessagesUiStateMode.Error);
|
||||
_cartridgeLoaderSystem.UpdateCartridgeUiState(loaderUid, state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (component.ChatUid == null) //if no chat is loaded, list users
|
||||
{
|
||||
List<(MessagesUserData, int?)> userList = [];
|
||||
|
||||
var dictionary = _messagesServerSystem.GetNameDict(component.LastServer);
|
||||
|
||||
foreach (var nameEntry in dictionary.Keys)
|
||||
{
|
||||
if (nameEntry == currentUserId)
|
||||
continue;
|
||||
userList.Add((dictionary[nameEntry], nameEntry));
|
||||
}
|
||||
|
||||
userList.Sort((a, b) => TimeSpan.Compare(b.Item1.Messages.LastOrDefault().Time, a.Item1.Messages.LastOrDefault().Time));
|
||||
|
||||
state = new MessagesUiState(MessagesUiStateMode.UserList, userList);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<MessagesMessageData> messageList = []; //Else, list messages from the current chat
|
||||
|
||||
foreach (var message in _messagesServerSystem.GetMessages(component.LastServer, component.ChatUid.Value, currentUserId.Value))
|
||||
{
|
||||
if (message.SenderId == component.ChatUid && message.ReceiverId == currentUserId || message.ReceiverId == component.ChatUid && message.SenderId == currentUserId)
|
||||
messageList.Add(message);
|
||||
}
|
||||
|
||||
messageList.Sort((a, b) => TimeSpan.Compare(a.Time, b.Time));
|
||||
|
||||
List<(string, int?)> formattedMessageList = [];
|
||||
|
||||
foreach (var message in messageList)
|
||||
{
|
||||
TryGetName(message.SenderId, component, out var name);
|
||||
var stationTime = message.Time.Subtract(_gameTicker.RoundStartTimeSpan);
|
||||
var content = $"{stationTime:\\[hh\\:mm\\:ss\\]} {name}: {message.Content}";
|
||||
formattedMessageList.Add((content, null));
|
||||
}
|
||||
|
||||
TryGetName(component.ChatUid.Value, component, out var user);
|
||||
state = new MessagesUiState(MessagesUiStateMode.Chat, null, formattedMessageList, user);
|
||||
}
|
||||
_cartridgeLoaderSystem.UpdateCartridgeUiState(loaderUid, state);
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public sealed class RandomHumanSystem : EntitySystem
|
||||
var cardId = pdaComponent.ContainedId.Value;
|
||||
|
||||
_card.TryChangeFullName(cardId, newProfile.Name, card);
|
||||
_pda.SetOwnerName(idUid.Value, pdaComponent, newProfile.Name);
|
||||
_pda.SetOwner(idUid.Value, pdaComponent, newProfile.Name);
|
||||
|
||||
if (EntityManager.TryGetComponent(cardId, out StationRecordKeyStorageComponent? keyStorage)
|
||||
&& keyStorage.Key is { } key)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
|
||||
|
||||
namespace Content.Server._White.Radio.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Entities with <see cref="MessagesServerComponent"/> are needed to transmit messages using PDAs.
|
||||
/// They also need to be powered by <see cref="ApcPowerReceiverComponent"/>
|
||||
/// in order for them to work on the same map as server.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class MessagesServerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictionary translating IDs to MessagesUser
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Dictionary<int, MessagesUserData> Dictionary = new();
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
using System.Linq;
|
||||
using Content.Server._White.CartridgeLoader.Cartridges;
|
||||
using Content.Server._White.Radio.Components;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
|
||||
|
||||
namespace Content.Server._White.Radio.EntitySystems;
|
||||
|
||||
public sealed class MessagesServerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!;
|
||||
[Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = default!;
|
||||
[Dependency] private readonly MessagesCartridgeSystem _messagesSystem = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<MessagesServerComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
||||
SubscribeLocalEvent<MessagesServerComponent, ComponentInit>(OnInit);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, MessagesServerComponent component, ComponentInit args)
|
||||
{
|
||||
var query = EntityQueryEnumerator<MessagesCartridgeComponent>();
|
||||
|
||||
while (query.MoveNext(out var entityUid, out var cartridge))
|
||||
{
|
||||
if (!TryComp(entityUid, out CartridgeComponent? cartComponent))
|
||||
continue;
|
||||
|
||||
_messagesSystem.TryGetMessagesUser(cartridge, cartComponent, out var messagesUser);
|
||||
|
||||
if (cartridge.UserUid == null || messagesUser.Name == Loc.GetString("messages-pda-unknown-name"))
|
||||
continue;
|
||||
|
||||
component.Dictionary[cartridge.UserUid.Value] = messagesUser;
|
||||
cartridge.LastServer = uid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reacts to packets received from clients
|
||||
/// </summary>
|
||||
private void OnPacketReceived(EntityUid uid, MessagesServerComponent component, DeviceNetworkPacketEvent args)
|
||||
{
|
||||
if (!_singletonServerSystem.IsActiveServer(uid))
|
||||
return;
|
||||
|
||||
if (args.Data.TryGetValue<MessagesUserData>(MessagesNetworkKeys.NewUser, out var messagesUser) && args.Data.TryGetValue<int>(MessagesNetworkKeys.UserId, out var userId))
|
||||
{
|
||||
component.Dictionary[userId] = messagesUser;
|
||||
|
||||
var packet = new NetworkPayload();
|
||||
_deviceNetworkSystem.QueuePacket(uid, args.SenderAddress, packet);
|
||||
}
|
||||
|
||||
if (args.Data.TryGetValue<MessagesMessageData>(MessagesNetworkKeys.Message, out var message))
|
||||
SendMessage(uid, component, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts a message into the network
|
||||
/// </summary>
|
||||
private void SendMessage(EntityUid uid, MessagesServerComponent component, MessagesMessageData message)
|
||||
{
|
||||
component.Dictionary[message.ReceiverId].Messages.Add(message);
|
||||
component.Dictionary[message.SenderId].Messages.Add(message);
|
||||
|
||||
_adminLogger.Add(LogType.DeviceNetwork, $"{Loc.GetString("chat-manager-send-message", ("sender", component.Dictionary[message.SenderId].Name + $" ({message.SenderId})"), ("receiver", component.Dictionary[message.ReceiverId].Name + $" ({message.ReceiverId})"), ("message", message.Content))}");
|
||||
_chat.SendNetworkChat(uid, Loc.GetString("chat-manager-send-message", ("sender", component.Dictionary[message.SenderId].Name), ("receiver", component.Dictionary[message.ReceiverId].Name), ("message", message.Content)), false);
|
||||
|
||||
var packet = new NetworkPayload()
|
||||
{
|
||||
[MessagesNetworkKeys.Message] = message
|
||||
};
|
||||
|
||||
_deviceNetworkSystem.QueuePacket(uid, null, packet);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns user
|
||||
/// </summary>
|
||||
public bool TryGetUserFromDict(EntityUid? uid, int key, out MessagesUserData messagesUserData)
|
||||
{
|
||||
messagesUserData = new MessagesUserData();
|
||||
|
||||
if (!TryComp(uid, out MessagesServerComponent? component) || !component.Dictionary.TryGetValue(key, out var keyValue))
|
||||
return false;
|
||||
|
||||
messagesUserData = keyValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the user dictionary cache
|
||||
/// </summary>
|
||||
public Dictionary<int, MessagesUserData> GetNameDict(EntityUid? uid)
|
||||
{
|
||||
return !TryComp(uid, out MessagesServerComponent? component) ? new Dictionary<int, MessagesUserData>() : component.Dictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns list of messages between the two users
|
||||
/// </summary>
|
||||
public List<MessagesMessageData> GetMessages(EntityUid? uid, int id1, int id2)
|
||||
{
|
||||
if (!TryComp(uid, out MessagesServerComponent? component))
|
||||
return [];
|
||||
|
||||
return
|
||||
[
|
||||
..component.Dictionary[id1]
|
||||
.Messages.Where(message =>
|
||||
message.SenderId == id1 && message.ReceiverId == id2 ||
|
||||
message.SenderId == id2 && message.ReceiverId == id1)
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class MessagesNetworkKeys
|
||||
{
|
||||
public const string NewUser = "new_user";
|
||||
public const string UserId = "user_id";
|
||||
public const string Message = "message";
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared._White.Telescope;
|
||||
using Content.Shared._White.WeaponModules;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
@@ -128,7 +128,7 @@ public sealed class WeaponModulesSystem : EntitySystem
|
||||
return;
|
||||
|
||||
weaponModulesComponent.WeaponFireEffect = true;
|
||||
Dirty(weapon, weaponModulesComponent);
|
||||
Dirty(module, weaponModulesComponent);
|
||||
}
|
||||
|
||||
private void SilencerModuleOnInsert(EntityUid module, SilencerModuleComponent component, EntGotInsertedIntoContainerMessage args)
|
||||
@@ -145,7 +145,7 @@ public sealed class WeaponModulesSystem : EntitySystem
|
||||
weaponModulesComponent.WeaponFireEffect = true;
|
||||
_gunSystem.SetSound(weapon, component.NewSoundGunshot);
|
||||
|
||||
Dirty(weapon, weaponModulesComponent);
|
||||
Dirty(module, weaponModulesComponent);
|
||||
}
|
||||
|
||||
private void AcceleratorModuleOnInsert(EntityUid module, AcceleratorModuleComponent component, EntGotInsertedIntoContainerMessage args)
|
||||
@@ -224,7 +224,7 @@ public sealed class WeaponModulesSystem : EntitySystem
|
||||
return;
|
||||
|
||||
weaponModulesComponent.WeaponFireEffect = false;
|
||||
Dirty(weapon, weaponModulesComponent);
|
||||
Dirty(module, weaponModulesComponent);
|
||||
}
|
||||
|
||||
private void SilencerModuleOnEject(EntityUid module, SilencerModuleComponent component, EntGotRemovedFromContainerMessage args)
|
||||
@@ -236,7 +236,7 @@ public sealed class WeaponModulesSystem : EntitySystem
|
||||
|
||||
weaponModulesComponent.WeaponFireEffect = false;
|
||||
_gunSystem.SetSound(weapon, component.OldSoundGunshot!);
|
||||
Dirty(weapon, weaponModulesComponent);
|
||||
Dirty(module, weaponModulesComponent);
|
||||
}
|
||||
|
||||
private void AcceleratorModuleOnEject(EntityUid module, AcceleratorModuleComponent component, EntGotRemovedFromContainerMessage args)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
@@ -237,12 +235,6 @@ namespace Content.Shared.CCVar
|
||||
public static readonly CVarDef<bool>
|
||||
GameRoleTimers = CVarDef.Create("game.role_timers", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Override default role requirements using a <see cref="JobRequirementOverridePrototype"/>
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string>
|
||||
GameRoleTimerOverride = CVarDef.Create("game.role_timer_override", "", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not disconnecting inside of a cryopod should remove the character or just store them until they reconnect.
|
||||
/// </summary>
|
||||
@@ -874,52 +866,6 @@ namespace Content.Shared.CCVar
|
||||
public static readonly CVarDef<bool> AdminBypassMaxPlayers =
|
||||
CVarDef.Create("admin.bypass_max_players", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if custom rank names are used.
|
||||
/// If it is false, it'd use the actual rank name regardless of the individual's title.
|
||||
/// </summary>
|
||||
/// <seealso cref="AhelpAdminPrefix"/>
|
||||
/// <seealso cref="AhelpAdminPrefixWebhook"/>
|
||||
public static readonly CVarDef<bool> AdminUseCustomNamesAdminRank =
|
||||
CVarDef.Create("admin.use_custom_names_admin_rank", true, CVar.SERVERONLY);
|
||||
|
||||
/*
|
||||
* AHELP
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Ahelp rate limit values are accounted in periods of this size (seconds).
|
||||
/// After the period has passed, the count resets.
|
||||
/// </summary>
|
||||
/// <seealso cref="AhelpRateLimitCount"/>
|
||||
public static readonly CVarDef<int> AhelpRateLimitPeriod =
|
||||
CVarDef.Create("ahelp.rate_limit_period", 2, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// How many ahelp messages are allowed in a single rate limit period.
|
||||
/// </summary>
|
||||
/// <seealso cref="AhelpRateLimitPeriod"/>
|
||||
public static readonly CVarDef<int> AhelpRateLimitCount =
|
||||
CVarDef.Create("ahelp.rate_limit_count", 10, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the administrator's position be displayed in ahelp.
|
||||
/// If it is is false, only the admin's ckey will be displayed in the ahelp.
|
||||
/// </summary>
|
||||
/// <seealso cref="AdminUseCustomNamesAdminRank"/>
|
||||
/// <seealso cref="AhelpAdminPrefixWebhook"/>
|
||||
public static readonly CVarDef<bool> AhelpAdminPrefix =
|
||||
CVarDef.Create("ahelp.admin_prefix", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the administrator's position be displayed in the webhook.
|
||||
/// If it is is false, only the admin's ckey will be displayed in webhook.
|
||||
/// </summary>
|
||||
/// <seealso cref="AdminUseCustomNamesAdminRank"/>
|
||||
/// <seealso cref="AhelpAdminPrefix"/>
|
||||
public static readonly CVarDef<bool> AhelpAdminPrefixWebhook =
|
||||
CVarDef.Create("ahelp.admin_prefix_webhook", true, CVar.SERVERONLY);
|
||||
|
||||
/*
|
||||
* Explosions
|
||||
*/
|
||||
|
||||
@@ -33,7 +33,7 @@ public sealed partial class CartridgeLoaderComponent : Component
|
||||
/// The maximum amount of programs that can be installed on the cartridge loader entity
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int DiskSpace = 7; // WD EDIT
|
||||
public int DiskSpace = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether the cartridge loader will play notifications if it supports it at all
|
||||
|
||||
@@ -80,26 +80,23 @@ public enum ChatChannel : uint
|
||||
/// </summary>
|
||||
AdminChat = 1 << 13,
|
||||
|
||||
//WD EDIT START
|
||||
/// <summary>
|
||||
/// Changeling
|
||||
/// </summary>
|
||||
Changeling = 1 << 14,
|
||||
|
||||
//WD EDIT
|
||||
Cult = 1 << 15,
|
||||
|
||||
Network = 1 << 16,
|
||||
//WD EDIT END
|
||||
|
||||
/// <summary>
|
||||
/// Unspecified.
|
||||
/// </summary>
|
||||
Unspecified = 1 << 17,
|
||||
Unspecified = 1 << 16,
|
||||
|
||||
/// <summary>
|
||||
/// Channels considered to be IC.
|
||||
/// </summary>
|
||||
IC = Local | Whisper | Radio | Dead | Emotes | Damage | Visual | Notifications | Cult | Changeling | Network,
|
||||
IC = Local | Whisper | Radio | Dead | Emotes | Damage | Visual | Notifications | Cult | Changeling,
|
||||
|
||||
AdminRelated = Admin | AdminAlert | AdminChat,
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,8 @@ public static class ChatChannelExtensions
|
||||
ChatChannel.AdminAlert => Color.Red,
|
||||
ChatChannel.AdminChat => Color.HotPink,
|
||||
ChatChannel.Whisper => Color.DarkGray,
|
||||
// WD EDIT START
|
||||
ChatChannel.Cult => Color.DarkRed,
|
||||
ChatChannel.Changeling => Color.Purple,
|
||||
ChatChannel.Network => Color.White,
|
||||
// WD EDIT END
|
||||
ChatChannel.Cult => Color.DarkRed, // WD EDIT
|
||||
_ => Color.LightGray
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,19 +46,15 @@
|
||||
/// </summary>
|
||||
Dead = ChatChannel.Dead,
|
||||
|
||||
// WD EDIT START
|
||||
Cult = ChatChannel.Cult,
|
||||
|
||||
Changeling = ChatChannel.Changeling,
|
||||
|
||||
Network = ChatChannel.Network,
|
||||
// WD EDIT END
|
||||
|
||||
/// <summary>
|
||||
/// Admin chat
|
||||
/// </summary>
|
||||
Admin = ChatChannel.AdminChat,
|
||||
|
||||
Changeling = ChatChannel.Changeling,
|
||||
|
||||
Console = ChatChannel.Unspecified
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Damage.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
[NetworkedComponent, AutoGenerateComponentState] // WD
|
||||
public sealed partial class StaminaDamageOnHitComponent : Component
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("damage")]
|
||||
[AutoNetworkedField] // WD
|
||||
public float Damage = 30f;
|
||||
|
||||
[DataField("sound")]
|
||||
[AutoNetworkedField] // WD
|
||||
public SoundSpecifier? Sound;
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Ghost.Roles;
|
||||
|
||||
/// <summary>
|
||||
/// For selectable ghostrole prototypes in ghostrole spawners.
|
||||
/// </summary>
|
||||
[Prototype]
|
||||
public sealed partial class GhostRolePrototype : IPrototype
|
||||
{
|
||||
[ViewVariables]
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the ghostrole.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The description of the ghostrole.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Description { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The entity prototype of the ghostrole
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public EntProtoId EntityPrototype;
|
||||
|
||||
/// <summary>
|
||||
/// Rules of the ghostrole
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Rules = default!;
|
||||
}
|
||||
@@ -11,11 +11,6 @@ namespace Content.Shared.Ghost.Roles
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Rules { get; set; }
|
||||
|
||||
// TODO ROLE TIMERS
|
||||
// Actually make use of / enforce this requirement?
|
||||
// Why is this even here.
|
||||
// Move to ghost role prototype & respect CCvars.GameRoleTimerOverride
|
||||
public HashSet<JobRequirement>? Requirements { get; set; }
|
||||
|
||||
/// <inheritdoc cref="GhostRoleKind"/>
|
||||
|
||||
@@ -59,7 +59,6 @@ namespace Content.Shared.Input
|
||||
public static readonly BoundKeyFunction ResetZoom = "ResetZoom";
|
||||
public static readonly BoundKeyFunction LieDown = "LieDown"; // WD EDIT
|
||||
public static readonly BoundKeyFunction OfferItem = "OfferItem"; // WD EDIT
|
||||
public static readonly BoundKeyFunction LookUp = "LookUp"; // WD EDIT
|
||||
|
||||
public static readonly BoundKeyFunction ArcadeUp = "ArcadeUp";
|
||||
public static readonly BoundKeyFunction ArcadeDown = "ArcadeDown";
|
||||
|
||||
@@ -13,12 +13,12 @@ public sealed partial class ContentEyeComponent : Component
|
||||
/// <summary>
|
||||
/// Zoom we're lerping to.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
[DataField("targetZoom"), AutoNetworkedField]
|
||||
public Vector2 TargetZoom = Vector2.One;
|
||||
|
||||
/// <summary>
|
||||
/// How far we're allowed to zoom out.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("maxZoom"), AutoNetworkedField]
|
||||
public Vector2 MaxZoom = Vector2.One;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.GameStates;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Shared.PDA
|
||||
@@ -38,8 +37,6 @@ namespace Content.Shared.PDA
|
||||
[ViewVariables] public bool FlashlightOn;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)] public string? OwnerName;
|
||||
[ViewVariables(VVAccess.ReadWrite)] public string? OwnerJob; // WD EDIT
|
||||
[ViewVariables(VVAccess.ReadWrite)] public string? OwnerDepartment; // WD EDIT
|
||||
[ViewVariables] public string? StationName;
|
||||
[ViewVariables] public string? StationAlertLevel;
|
||||
[ViewVariables] public Color StationAlertColor = Color.White;
|
||||
|
||||
@@ -45,7 +45,6 @@ namespace Content.Shared.PDA
|
||||
public struct PdaIdInfoText
|
||||
{
|
||||
public string? ActualOwnerName;
|
||||
public string? ActualOwnerJob; // WD EDIT
|
||||
public string? IdOwner;
|
||||
public string? JobTitle;
|
||||
public string? StationAlertLevel;
|
||||
|
||||
@@ -707,7 +707,7 @@ namespace Content.Shared.Preferences
|
||||
continue;
|
||||
}
|
||||
|
||||
loadouts.EnsureValid(this, session, collection);
|
||||
loadouts.EnsureValid(session, collection);
|
||||
}
|
||||
|
||||
foreach (var value in toRemove)
|
||||
|
||||
@@ -13,13 +13,13 @@ public sealed partial class GroupLoadoutEffect : LoadoutEffect
|
||||
[DataField(required: true)]
|
||||
public ProtoId<LoadoutEffectGroupPrototype> Proto;
|
||||
|
||||
public override bool Validate(HumanoidCharacterProfile profile, RoleLoadout loadout, ICommonSession session, IDependencyCollection collection, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
public override bool Validate(RoleLoadout loadout, ICommonSession session, IDependencyCollection collection, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
var effectsProto = collection.Resolve<IPrototypeManager>().Index(Proto);
|
||||
|
||||
foreach (var effect in effectsProto.Effects)
|
||||
{
|
||||
if (!effect.Validate(profile, loadout, session, collection, out reason))
|
||||
if (!effect.Validate(loadout, session, collection, out reason))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,12 @@ public sealed partial class JobRequirementLoadoutEffect : LoadoutEffect
|
||||
[DataField(required: true)]
|
||||
public JobRequirement Requirement = default!;
|
||||
|
||||
public override bool Validate(HumanoidCharacterProfile profile, RoleLoadout loadout, ICommonSession session, IDependencyCollection collection, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
public override bool Validate(RoleLoadout loadout, ICommonSession session, IDependencyCollection collection, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
var manager = collection.Resolve<ISharedPlaytimeManager>();
|
||||
var playtimes = manager.GetPlayTimes(session);
|
||||
return Requirement.Check(collection.Resolve<IEntityManager>(),
|
||||
collection.Resolve<IPrototypeManager>(),
|
||||
profile,
|
||||
playtimes,
|
||||
out reason);
|
||||
return JobRequirements.TryRequirementMet(Requirement, playtimes, out reason,
|
||||
collection.Resolve<IEntityManager>(),
|
||||
collection.Resolve<IPrototypeManager>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ public abstract partial class LoadoutEffect
|
||||
/// Tries to validate the effect.
|
||||
/// </summary>
|
||||
public abstract bool Validate(
|
||||
HumanoidCharacterProfile profile,
|
||||
RoleLoadout loadout,
|
||||
ICommonSession session,
|
||||
IDependencyCollection collection,
|
||||
|
||||
@@ -11,7 +11,6 @@ public sealed partial class PointsCostLoadoutEffect : LoadoutEffect
|
||||
public int Cost = 1;
|
||||
|
||||
public override bool Validate(
|
||||
HumanoidCharacterProfile profile,
|
||||
RoleLoadout loadout,
|
||||
ICommonSession session,
|
||||
IDependencyCollection collection,
|
||||
|
||||
@@ -44,7 +44,7 @@ public sealed class RoleLoadout
|
||||
/// <summary>
|
||||
/// Ensures all prototypes exist and effects can be applied.
|
||||
/// </summary>
|
||||
public void EnsureValid(HumanoidCharacterProfile profile, ICommonSession session, IDependencyCollection collection)
|
||||
public void EnsureValid(ICommonSession session, IDependencyCollection collection)
|
||||
{
|
||||
var groupRemove = new ValueList<string>();
|
||||
var protoManager = collection.Resolve<IPrototypeManager>();
|
||||
@@ -81,7 +81,7 @@ public sealed class RoleLoadout
|
||||
}
|
||||
|
||||
// Validate the loadout can be applied (e.g. points).
|
||||
if (!IsValid(profile, session, loadout.Prototype, collection, out _))
|
||||
if (!IsValid(session, loadout.Prototype, collection, out _))
|
||||
{
|
||||
loadouts.RemoveAt(i);
|
||||
continue;
|
||||
@@ -167,7 +167,7 @@ public sealed class RoleLoadout
|
||||
/// <summary>
|
||||
/// Returns whether a loadout is valid or not.
|
||||
/// </summary>
|
||||
public bool IsValid(HumanoidCharacterProfile profile, ICommonSession session, ProtoId<ItemLoadoutPrototype> loadout, IDependencyCollection collection, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
public bool IsValid(ICommonSession session, ProtoId<ItemLoadoutPrototype> loadout, IDependencyCollection collection, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = null;
|
||||
|
||||
@@ -190,7 +190,7 @@ public sealed class RoleLoadout
|
||||
|
||||
foreach (var effect in loadoutProto.Effects)
|
||||
{
|
||||
valid = valid && effect.Validate(profile, this, session, collection, out reason);
|
||||
valid = valid && effect.Validate(this, session, collection, out reason);
|
||||
}
|
||||
|
||||
return valid;
|
||||
|
||||
@@ -41,8 +41,6 @@ public sealed partial class AntagPrototype : IPrototype
|
||||
/// <summary>
|
||||
/// Requirements that must be met to opt in to this antag role.
|
||||
/// </summary>
|
||||
// TODO ROLE TIMERS
|
||||
// Actually check if the requirements are met. Because apparently this is actually unused.
|
||||
[DataField]
|
||||
[DataField("requirements")]
|
||||
public HashSet<JobRequirement>? Requirements;
|
||||
}
|
||||
|
||||
@@ -9,16 +9,16 @@ public sealed partial class DepartmentPrototype : IPrototype
|
||||
[IdDataField] public string ID { get; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The name LocId of the department that will be displayed in the various menus.
|
||||
/// A name string.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public LocId Name = string.Empty;
|
||||
public string Name = default!;
|
||||
|
||||
/// <summary>
|
||||
/// A description LocId to display in the character menu as an explanation of the department's function.
|
||||
/// A description string to display in the character menu as an explanation of the department's function.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public LocId Description = string.Empty;
|
||||
[DataField (required: true)]
|
||||
public string Description = default!;
|
||||
|
||||
/// <summary>
|
||||
/// A color representing this department to use for text.
|
||||
@@ -26,8 +26,8 @@ public sealed partial class DepartmentPrototype : IPrototype
|
||||
[DataField(required: true)]
|
||||
public Color Color = default!;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public List<ProtoId<JobPrototype>> Roles = new();
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<JobPrototype>))]
|
||||
public List<string> Roles = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whether this is a primary department or not.
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Roles;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the character to be older or younger than a certain age (inclusive)
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class AgeRequirement : JobRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public int RequiredAge;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
|
||||
if (profile is null) //the profile could be null if the player is a ghost. In this case we don't need to block the role selection for ghostrole
|
||||
return true;
|
||||
|
||||
if (!Inverted)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString("role-timer-age-to-young",
|
||||
("age", RequiredAge)));
|
||||
|
||||
if (profile.Age <= RequiredAge)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString("role-timer-age-to-old",
|
||||
("age", RequiredAge)));
|
||||
|
||||
if (profile.Age >= RequiredAge)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Roles;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class DepartmentTimeRequirement : JobRequirement
|
||||
{
|
||||
public override bool IgnoreIfAdmin => true; // WD
|
||||
|
||||
/// <summary>
|
||||
/// Which department needs the required amount of time.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ProtoId<DepartmentPrototype> Department = default!;
|
||||
|
||||
/// <summary>
|
||||
/// How long (in seconds) this requirement is.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public TimeSpan Time;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
var playtime = TimeSpan.Zero;
|
||||
|
||||
// Check all jobs' departments
|
||||
var department = protoManager.Index(Department);
|
||||
var jobs = department.Roles;
|
||||
string proto;
|
||||
|
||||
// Check all jobs' playtime
|
||||
foreach (var other in jobs)
|
||||
{
|
||||
// The schema is stored on the Job role but we want to explode if the timer isn't found anyway.
|
||||
proto = protoManager.Index(other).PlayTimeTracker;
|
||||
|
||||
playTimes.TryGetValue(proto, out var otherTime);
|
||||
playtime += otherTime;
|
||||
}
|
||||
|
||||
var deptDiff = Time.TotalMinutes - playtime.TotalMinutes;
|
||||
var nameDepartment = "role-timer-department-unknown";
|
||||
|
||||
if (protoManager.TryIndex(Department, out var departmentIndexed))
|
||||
{
|
||||
nameDepartment = departmentIndexed.Name;
|
||||
}
|
||||
|
||||
if (!Inverted)
|
||||
{
|
||||
if (deptDiff <= 0)
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString(
|
||||
"role-timer-department-insufficient",
|
||||
("time", Math.Ceiling(deptDiff)),
|
||||
("department", Loc.GetString(nameDepartment)),
|
||||
("departmentColor", department.Color.ToHex())));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (deptDiff <= 0)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString(
|
||||
"role-timer-department-too-high",
|
||||
("time", -deptDiff),
|
||||
("department", Loc.GetString(nameDepartment)),
|
||||
("departmentColor", department.Color.ToHex())));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Roles;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class OverallPlaytimeRequirement : JobRequirement
|
||||
{
|
||||
public override bool IgnoreIfAdmin => true; // WD
|
||||
|
||||
/// <inheritdoc cref="DepartmentTimeRequirement.Time"/>
|
||||
[DataField(required: true)]
|
||||
public TimeSpan Time;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
|
||||
var overallTime = playTimes.GetValueOrDefault(PlayTimeTrackingShared.TrackerOverall);
|
||||
var overallDiff = Time.TotalMinutes - overallTime.TotalMinutes;
|
||||
|
||||
if (!Inverted)
|
||||
{
|
||||
if (overallDiff <= 0 || overallTime >= Time)
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString(
|
||||
"role-timer-overall-insufficient",
|
||||
("time", Math.Ceiling(overallDiff))));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (overallDiff <= 0 || overallTime >= Time)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString("role-timer-overall-too-high",
|
||||
("time", -overallDiff)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Roles;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class RoleTimeRequirement : JobRequirement
|
||||
{
|
||||
public override bool IgnoreIfAdmin => true; // WD
|
||||
|
||||
/// <summary>
|
||||
/// What particular role they need the time requirement with.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ProtoId<PlayTimeTrackerPrototype> Role = default!;
|
||||
|
||||
/// <inheritdoc cref="DepartmentTimeRequirement.Time"/>
|
||||
[DataField(required: true)]
|
||||
public TimeSpan Time;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
|
||||
string proto = Role;
|
||||
|
||||
playTimes.TryGetValue(proto, out var roleTime);
|
||||
var roleDiff = Time.TotalMinutes - roleTime.TotalMinutes;
|
||||
var departmentColor = Color.Yellow;
|
||||
|
||||
if (entManager.EntitySysManager.TryGetEntitySystem(out SharedJobSystem? jobSystem))
|
||||
{
|
||||
var jobProto = jobSystem.GetJobPrototype(proto);
|
||||
|
||||
if (jobSystem.TryGetDepartment(jobProto, out var departmentProto))
|
||||
departmentColor = departmentProto.Color;
|
||||
}
|
||||
|
||||
if (!Inverted)
|
||||
{
|
||||
if (roleDiff <= 0)
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString(
|
||||
"role-timer-role-insufficient",
|
||||
("time", Math.Ceiling(roleDiff)),
|
||||
("job", Loc.GetString(proto)),
|
||||
("departmentColor", departmentColor.ToHex())));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (roleDiff <= 0)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString(
|
||||
"role-timer-role-too-high",
|
||||
("time", -roleDiff),
|
||||
("job", Loc.GetString(proto)),
|
||||
("departmentColor", departmentColor.ToHex())));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Preferences;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Roles;
|
||||
|
||||
/// <summary>
|
||||
/// Requires the character to be or not be on the list of specified species
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class SpeciesRequirement : JobRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public HashSet<ProtoId<SpeciesPrototype>> Species = new();
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
|
||||
if (profile is null) //the profile could be null if the player is a ghost. In this case we don't need to block the role selection for ghostrole
|
||||
return true;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("[color=yellow]");
|
||||
foreach (var s in Species)
|
||||
{
|
||||
sb.Append(Loc.GetString(protoManager.Index(s).Name) + " ");
|
||||
}
|
||||
|
||||
sb.Append("[/color]");
|
||||
|
||||
if (!Inverted)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive($"{Loc.GetString("role-timer-whitelisted-species")}\n{sb}");
|
||||
|
||||
if (!Species.Contains(profile.Species))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive($"{Loc.GetString("role-timer-blacklisted-species")}\n{sb}");
|
||||
|
||||
if (Species.Contains(profile.Species))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Roles;
|
||||
|
||||
/// <summary>
|
||||
/// Collection of job, antag, and ghost-role job requirements for per-server requirement overrides.
|
||||
/// </summary>
|
||||
[Prototype]
|
||||
public sealed partial class JobRequirementOverridePrototype : IPrototype
|
||||
{
|
||||
[ViewVariables]
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<JobPrototype>, HashSet<JobRequirement>> Jobs = new ();
|
||||
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<AntagPrototype>, HashSet<JobRequirement>> Antags = new ();
|
||||
}
|
||||
@@ -1,57 +1,226 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Roles;
|
||||
|
||||
public static class JobRequirements
|
||||
namespace Content.Shared.Roles
|
||||
{
|
||||
public static bool TryRequirementsMet(
|
||||
JobPrototype job,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason,
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
bool isAdmin)
|
||||
/// <summary>
|
||||
/// Abstract class for playtime and other requirements for role gates.
|
||||
/// </summary>
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[Serializable, NetSerializable]
|
||||
public abstract partial class JobRequirement{}
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class DepartmentTimeRequirement : JobRequirement
|
||||
{
|
||||
var sys = entManager.System<SharedRoleSystem>();
|
||||
var requirements = sys.GetJobRequirement(job);
|
||||
reason = null;
|
||||
if (requirements == null)
|
||||
return true;
|
||||
/// <summary>
|
||||
/// Which department needs the required amount of time.
|
||||
/// </summary>
|
||||
[DataField("department", customTypeSerializer: typeof(PrototypeIdSerializer<DepartmentPrototype>))]
|
||||
public string Department = default!;
|
||||
|
||||
foreach (var requirement in requirements)
|
||||
/// <summary>
|
||||
/// How long (in seconds) this requirement is.
|
||||
/// </summary>
|
||||
[DataField("time")] public TimeSpan Time;
|
||||
|
||||
/// <summary>
|
||||
/// If true, requirement will return false if playtime above the specified time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>False</c> by default.<br />
|
||||
/// <c>True</c> for invert general requirement
|
||||
/// </value>
|
||||
[DataField("inverted")] public bool Inverted;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class RoleTimeRequirement : JobRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// What particular role they need the time requirement with.
|
||||
/// </summary>
|
||||
[DataField("role", customTypeSerializer: typeof(PrototypeIdSerializer<PlayTimeTrackerPrototype>))]
|
||||
public string Role = default!;
|
||||
|
||||
/// <inheritdoc cref="DepartmentTimeRequirement.Time"/>
|
||||
[DataField("time")] public TimeSpan Time;
|
||||
|
||||
/// <inheritdoc cref="DepartmentTimeRequirement.Inverted"/>
|
||||
[DataField("inverted")] public bool Inverted;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class OverallPlaytimeRequirement : JobRequirement
|
||||
{
|
||||
/// <inheritdoc cref="DepartmentTimeRequirement.Time"/>
|
||||
[DataField("time")] public TimeSpan Time;
|
||||
|
||||
/// <inheritdoc cref="DepartmentTimeRequirement.Inverted"/>
|
||||
[DataField("inverted")] public bool Inverted;
|
||||
}
|
||||
|
||||
public static class JobRequirements
|
||||
{
|
||||
public static bool TryRequirementsMet(
|
||||
JobPrototype job,
|
||||
Dictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason,
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager prototypes)
|
||||
{
|
||||
if (isAdmin && requirement.IgnoreIfAdmin)
|
||||
continue;
|
||||
reason = null;
|
||||
if (job.Requirements == null)
|
||||
return true;
|
||||
|
||||
if (!requirement.Check(entManager, protoManager, profile, playTimes, out reason))
|
||||
return false;
|
||||
foreach (var requirement in job.Requirements)
|
||||
{
|
||||
if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
/// <summary>
|
||||
/// Returns a string with the reason why a particular requirement may not be met.
|
||||
/// </summary>
|
||||
public static bool TryRequirementMet(
|
||||
JobRequirement requirement,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason,
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager prototypes)
|
||||
{
|
||||
reason = null;
|
||||
|
||||
switch (requirement)
|
||||
{
|
||||
case DepartmentTimeRequirement deptRequirement:
|
||||
var playtime = TimeSpan.Zero;
|
||||
|
||||
// Check all jobs' departments
|
||||
var department = prototypes.Index<DepartmentPrototype>(deptRequirement.Department);
|
||||
var jobs = department.Roles;
|
||||
string proto;
|
||||
|
||||
// Check all jobs' playtime
|
||||
foreach (var other in jobs)
|
||||
{
|
||||
// The schema is stored on the Job role but we want to explode if the timer isn't found anyway.
|
||||
proto = prototypes.Index<JobPrototype>(other).PlayTimeTracker;
|
||||
|
||||
playTimes.TryGetValue(proto, out var otherTime);
|
||||
playtime += otherTime;
|
||||
}
|
||||
|
||||
var deptDiff = deptRequirement.Time.TotalMinutes - playtime.TotalMinutes;
|
||||
|
||||
if (!deptRequirement.Inverted)
|
||||
{
|
||||
if (deptDiff <= 0)
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-department-insufficient",
|
||||
("time", Math.Ceiling(deptDiff)),
|
||||
("department", Loc.GetString(deptRequirement.Department)),
|
||||
("departmentColor", department.Color.ToHex())));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (deptDiff <= 0)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-department-too-high",
|
||||
("time", -deptDiff),
|
||||
("department", Loc.GetString(deptRequirement.Department)),
|
||||
("departmentColor", department.Color.ToHex())));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case OverallPlaytimeRequirement overallRequirement:
|
||||
var overallTime = playTimes.GetValueOrDefault(PlayTimeTrackingShared.TrackerOverall);
|
||||
var overallDiff = overallRequirement.Time.TotalMinutes - overallTime.TotalMinutes;
|
||||
|
||||
if (!overallRequirement.Inverted)
|
||||
{
|
||||
if (overallDiff <= 0 || overallTime >= overallRequirement.Time)
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-overall-insufficient",
|
||||
("time", Math.Ceiling(overallDiff))));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (overallDiff <= 0 || overallTime >= overallRequirement.Time)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString("role-timer-overall-too-high", ("time", -overallDiff)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case RoleTimeRequirement roleRequirement:
|
||||
proto = roleRequirement.Role;
|
||||
|
||||
playTimes.TryGetValue(proto, out var roleTime);
|
||||
var roleDiff = roleRequirement.Time.TotalMinutes - roleTime.TotalMinutes;
|
||||
var departmentColor = Color.Yellow;
|
||||
|
||||
if (entManager.EntitySysManager.TryGetEntitySystem(out SharedJobSystem? jobSystem))
|
||||
{
|
||||
var jobProto = jobSystem.GetJobPrototype(proto);
|
||||
|
||||
if (jobSystem.TryGetDepartment(jobProto, out var departmentProto))
|
||||
departmentColor = departmentProto.Color;
|
||||
}
|
||||
|
||||
if (!roleRequirement.Inverted)
|
||||
{
|
||||
if (roleDiff <= 0)
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-role-insufficient",
|
||||
("time", Math.Ceiling(roleDiff)),
|
||||
("job", Loc.GetString(proto)),
|
||||
("departmentColor", departmentColor.ToHex())));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (roleDiff <= 0)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-role-too-high",
|
||||
("time", -roleDiff),
|
||||
("job", Loc.GetString(proto)),
|
||||
("departmentColor", departmentColor.ToHex())));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract class for playtime and other requirements for role gates.
|
||||
/// </summary>
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[Serializable, NetSerializable]
|
||||
public abstract partial class JobRequirement
|
||||
{
|
||||
[DataField]
|
||||
public bool Inverted;
|
||||
|
||||
public virtual bool IgnoreIfAdmin => false; // WD
|
||||
|
||||
public abstract bool Check(
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Ghost.Roles;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -18,30 +15,14 @@ public abstract class SharedRoleSystem : EntitySystem
|
||||
[Dependency] private readonly IPrototypeManager _prototypes = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedMindSystem _minds = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
// TODO please lord make role entities
|
||||
private readonly HashSet<Type> _antagTypes = new();
|
||||
|
||||
private JobRequirementOverridePrototype? _requirementOverride;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
// TODO make roles entities
|
||||
SubscribeLocalEvent<JobComponent, MindGetAllRolesEvent>(OnJobGetAllRoles);
|
||||
Subs.CVar(_cfg, CCVars.GameRoleTimerOverride, SetRequirementOverride, true);
|
||||
}
|
||||
|
||||
private void SetRequirementOverride(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
_requirementOverride = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_prototypes.TryIndex(value, out _requirementOverride ))
|
||||
Log.Error($"Unknown JobRequirementOverridePrototype: {value}");
|
||||
}
|
||||
|
||||
private void OnJobGetAllRoles(EntityUid uid, JobComponent component, ref MindGetAllRolesEvent args)
|
||||
@@ -205,36 +186,4 @@ public abstract class SharedRoleSystem : EntitySystem
|
||||
if (Resolve(mindId, ref mind) && mind.Session != null)
|
||||
_audio.PlayGlobal(sound, mind.Session);
|
||||
}
|
||||
|
||||
public HashSet<JobRequirement>? GetJobRequirement(JobPrototype job)
|
||||
{
|
||||
if (_requirementOverride != null && _requirementOverride.Jobs.TryGetValue(job.ID, out var req))
|
||||
return req;
|
||||
|
||||
return job.Requirements;
|
||||
}
|
||||
|
||||
public HashSet<JobRequirement>? GetJobRequirement(ProtoId<JobPrototype> job)
|
||||
{
|
||||
if (_requirementOverride != null && _requirementOverride.Jobs.TryGetValue(job, out var req))
|
||||
return req;
|
||||
|
||||
return _prototypes.Index(job).Requirements;
|
||||
}
|
||||
|
||||
public HashSet<JobRequirement>? GetAntagRequirement(ProtoId<AntagPrototype> antag)
|
||||
{
|
||||
if (_requirementOverride != null && _requirementOverride.Antags.TryGetValue(antag, out var req))
|
||||
return req;
|
||||
|
||||
return _prototypes.Index(antag).Requirements;
|
||||
}
|
||||
|
||||
public HashSet<JobRequirement>? GetAntagRequirement(AntagPrototype antag)
|
||||
{
|
||||
if (_requirementOverride != null && _requirementOverride.Antags.TryGetValue(antag.ID, out var req))
|
||||
return req;
|
||||
|
||||
return antag.Requirements;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,10 +85,8 @@ public abstract partial class SharedToolSystem
|
||||
if (!InteractionSystem.InRangeUnobstructed(user, coordinates, popup: false))
|
||||
return false;
|
||||
|
||||
var delay = tileDef.IsSubFloor ? TimeSpan.FromSeconds(4) : comp.Delay; // WD
|
||||
|
||||
var args = new TileToolDoAfterEvent(GetNetCoordinates(coordinates));
|
||||
UseTool(ent, user, ent, delay, tool.Qualities, args, out _, toolComponent: tool); // WD EDIT
|
||||
UseTool(ent, user, ent, comp.Delay, tool.Qualities, args, out _, toolComponent: tool);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem
|
||||
RestockInventoryFromPrototype(uid, component);
|
||||
}
|
||||
|
||||
public void RestockInventoryFromPrototype(EntityUid uid, VendingMachineComponent? component = null, bool restockEverything = true) // WD EDIT
|
||||
public void RestockInventoryFromPrototype(EntityUid uid, VendingMachineComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
{
|
||||
@@ -40,8 +40,6 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem
|
||||
return;
|
||||
|
||||
AddInventoryFromPrototype(uid, packPrototype.StartingInventory, InventoryType.Regular, component);
|
||||
if (!restockEverything) // WD
|
||||
return;
|
||||
AddInventoryFromPrototype(uid, packPrototype.EmaggedInventory, InventoryType.Emagged, component);
|
||||
AddInventoryFromPrototype(uid, packPrototype.ContrabandInventory, InventoryType.Contraband, component);
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
|
||||
|
||||
///<summary>
|
||||
/// Data of a single message in the system, containing the ids of the sender and recipient, the text content and the time it was sent.
|
||||
///</summary>
|
||||
[Serializable, NetSerializable]
|
||||
public struct MessagesMessageData
|
||||
{
|
||||
public int SenderId;
|
||||
public int ReceiverId;
|
||||
public string Content;
|
||||
public TimeSpan Time;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class MessagesUserData
|
||||
{
|
||||
public string Name = Loc.GetString("messages-pda-unknown-name");
|
||||
|
||||
public string Job = Loc.GetString("messages-pda-unknown-job");
|
||||
|
||||
public string Department = "Specific";
|
||||
|
||||
public List<MessagesMessageData> Messages = [];
|
||||
|
||||
public void SetMessagesUser(string? name, string? job, string? department)
|
||||
{
|
||||
Name = name ?? Loc.GetString("messages-pda-unknown-name");
|
||||
Job = job ?? Loc.GetString("messages-pda-unknown-job");
|
||||
Department = department ?? "Specific";
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class MessagesUiMessageEvent(MessagesUiAction action, string? stringInput, int? targetChatUid) : CartridgeMessageEvent
|
||||
{
|
||||
public readonly MessagesUiAction Action = action;
|
||||
|
||||
public readonly int? TargetChatUid = targetChatUid;
|
||||
|
||||
public readonly string? StringInput = stringInput;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum MessagesUiAction : byte
|
||||
{
|
||||
Send,
|
||||
ChangeChat
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._White.CartridgeLoader.Cartridges;
|
||||
|
||||
///<summary>
|
||||
/// The state of the messages app interface.
|
||||
/// Mode switches whether the UI should display a list of other users or a particular chat.
|
||||
/// Contents contains either the names of users and their ids in the messages system or simply a list of message strings.
|
||||
///</summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class MessagesUiState(MessagesUiStateMode mode, List<(MessagesUserData, int?)>? users = null, List<(string, int?)>? messages = null, string? name = null) : BoundUserInterfaceState
|
||||
{
|
||||
public List<(MessagesUserData, int?)>? Users = users;
|
||||
public List<(string, int?)>? Messages = messages;
|
||||
public MessagesUiStateMode Mode = mode;
|
||||
public string? Name = name;
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Enum representing the modes the program's UI can be in
|
||||
///</summary>
|
||||
[Serializable, NetSerializable]
|
||||
public enum MessagesUiStateMode : byte
|
||||
{
|
||||
UserList,
|
||||
Chat,
|
||||
Error
|
||||
}
|
||||
@@ -47,6 +47,7 @@ public sealed class NarcoticEffect : EntitySystem
|
||||
|
||||
TryComp<StatusEffectsComponent>(uid, out var statusEffectsComp);
|
||||
|
||||
RaiseLocalEvent(uid, new MoodEffectEvent("Stimulator"));
|
||||
CancellationToken token = movespeedModifierComponent.CancelTokenSource.Token;
|
||||
|
||||
int timer = component.TimerInterval[_robustRandom.Next(0, component.TimerInterval.Count)];
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using Content.Shared._White.Mood;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._White.Chemistry;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed partial class NarcoticMoodEffect : ReagentEffect
|
||||
{
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
args.EntityManager.EventBus.RaiseLocalEvent(args.SolutionEntity, new MoodEffectEvent("Stimulator"));
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,17 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._White.Item.DelayedKnockdown;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
[RegisterComponent]
|
||||
public sealed partial class DelayedKnockdownOnHitComponent : Component
|
||||
{
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan Delay = TimeSpan.FromSeconds(2);
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan KnockdownTime = TimeSpan.FromSeconds(5);
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan StutterTime = TimeSpan.FromSeconds(16);
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan JitterTime = TimeSpan.FromSeconds(40);
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._White.JobRequirements;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class GenderRequirement : JobRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public HashSet<Gender> RequiredGenders;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
|
||||
if (profile is null)
|
||||
return true;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("[color=yellow]");
|
||||
foreach (var g in RequiredGenders)
|
||||
{
|
||||
sb.Append(GenderToString(g) + " ");
|
||||
}
|
||||
|
||||
sb.Append("[/color]");
|
||||
|
||||
if (!Inverted)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive($"{Loc.GetString("role-timer-gender-whitelisted")}\n{sb}");
|
||||
|
||||
if (!RequiredGenders.Contains(profile.Gender))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive($"{Loc.GetString("role-timer-gender-blacklisted")}\n{sb}");
|
||||
|
||||
if (RequiredGenders.Contains(profile.Gender))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private string GenderToString(Gender gender)
|
||||
{
|
||||
return gender switch
|
||||
{
|
||||
Gender.Male => Loc.GetString("humanoid-profile-editor-pronouns-male-text"),
|
||||
Gender.Female => Loc.GetString("humanoid-profile-editor-pronouns-female-text"),
|
||||
Gender.Epicene => Loc.GetString("humanoid-profile-editor-pronouns-epicene-text"),
|
||||
_ => Loc.GetString("humanoid-profile-editor-pronouns-neuter-text")
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._White.JobRequirements;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class SexRequirement : JobRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public Sex RequiredSex;
|
||||
|
||||
public override bool Check(IEntityManager entManager,
|
||||
IPrototypeManager protoManager,
|
||||
HumanoidCharacterProfile? profile,
|
||||
IReadOnlyDictionary<string, TimeSpan> playTimes,
|
||||
[NotNullWhen(false)] out FormattedMessage? reason)
|
||||
{
|
||||
reason = new FormattedMessage();
|
||||
|
||||
if (profile is null)
|
||||
return true;
|
||||
|
||||
if (!Inverted)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString("role-timer-sex-whitelisted",
|
||||
("sex", SexToString())));
|
||||
|
||||
if (profile.Sex != RequiredSex)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = FormattedMessage.FromMarkupPermissive(Loc.GetString("role-timer-sex-blacklisted",
|
||||
("sex", SexToString())));
|
||||
|
||||
if (profile.Sex == RequiredSex)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private string SexToString()
|
||||
{
|
||||
return RequiredSex switch
|
||||
{
|
||||
Sex.Male => Loc.GetString("role-timer-sex-male"),
|
||||
Sex.Female => Loc.GetString("role-timer-sex-female"),
|
||||
_ => Loc.GetString("role-timer-sex-unsexed")
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Content.Shared._White.Radio;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class NetworkChatComponent : Component
|
||||
{
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ using System.Numerics;
|
||||
using Content.Shared.Camera;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Item;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._White.Telescope;
|
||||
@@ -42,45 +41,19 @@ public abstract class SharedTelescopeSystem : EntitySystem
|
||||
if (!TryComp(args.User, out EyeComponent? eye))
|
||||
return;
|
||||
|
||||
if (!HasComp<ItemComponent>(ent.Owner))
|
||||
return;
|
||||
|
||||
SetOffset((args.User, eye), Vector2.Zero, ent);
|
||||
}
|
||||
|
||||
public EntityUid GetRightEntity(EntityUid? ent)
|
||||
{
|
||||
var entity = EntityUid.Invalid;
|
||||
|
||||
if (TryComp<HandsComponent>(ent, out var hands) &&
|
||||
HasComp<TelescopeComponent>(hands.ActiveHandEntity) &&
|
||||
hands.ActiveHandEntity.HasValue)
|
||||
{
|
||||
entity = hands.ActiveHandEntity.Value;
|
||||
}
|
||||
else if (HasComp<TelescopeComponent>(ent))
|
||||
{
|
||||
entity = ent.Value;
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void OnEyeOffsetChanged(EyeOffsetChangedEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity is not { } ent)
|
||||
return;
|
||||
|
||||
if (!TryComp(ent, out EyeComponent? eye))
|
||||
if (!TryComp<HandsComponent>(ent, out var hands) ||
|
||||
!TryComp<TelescopeComponent>(hands.ActiveHandEntity, out var telescope) ||
|
||||
!TryComp(ent, out EyeComponent? eye))
|
||||
return;
|
||||
|
||||
var entity = GetRightEntity(ent);
|
||||
|
||||
if (entity == EntityUid.Invalid)
|
||||
return;
|
||||
|
||||
var telescope = Comp<TelescopeComponent>(entity);
|
||||
|
||||
var offset = Vector2.Lerp(eye.Offset, msg.Offset, telescope.LerpAmount);
|
||||
|
||||
SetOffset((ent, eye), offset, telescope);
|
||||
@@ -98,19 +71,6 @@ public abstract class SharedTelescopeSystem : EntitySystem
|
||||
else
|
||||
_eye.SetOffset(ent, offset, ent);
|
||||
}
|
||||
|
||||
public void SetParameters(Entity<TelescopeComponent> ent, float? divisor = null, float? lerpAmount = null)
|
||||
{
|
||||
var telescope = ent.Comp;
|
||||
|
||||
divisor ??= telescope.Divisor;
|
||||
lerpAmount ??= telescope.LerpAmount;
|
||||
|
||||
telescope.Divisor = divisor.Value;
|
||||
telescope.LerpAmount = lerpAmount.Value;
|
||||
|
||||
Dirty(ent.Owner, telescope);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -164,7 +164,7 @@ public sealed class WhiteCVars
|
||||
*/
|
||||
|
||||
public static readonly CVarDef<bool> FanaticXenophobiaEnabled =
|
||||
CVarDef.Create("white.fanatic_xenophobia", false, CVar.SERVERONLY | CVar.ARCHIVE);
|
||||
CVarDef.Create("white.fanatic_xenophobia", true, CVar.SERVERONLY | CVar.ARCHIVE);
|
||||
|
||||
/*
|
||||
* MeatyOre
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@
|
||||
license: "CC-BY-3.0"
|
||||
copyright: "Modified from 'Meow 4.wav' by freesound user 'TRNGLE. The original audio was trimmed, split to mono, and converted from WAV to OGG format"
|
||||
source: "https://freesound.org/people/TRNGLE/sounds/368006/"
|
||||
|
||||
|
||||
- files: ["cat_meow2.ogg"]
|
||||
license: "CC-BY-3.0"
|
||||
copyright: "Created by freesound user 'TRNGLE. The original audio split to mono, and converted from WAV to OGG format"
|
||||
@@ -117,42 +117,24 @@
|
||||
license: "CC-BY-4.0"
|
||||
copyright: "Audio is recorded/created by Pfranzen 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/pfranzen/sounds/322744/"
|
||||
|
||||
|
||||
- files: ["dog_bark1.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
- files: ["dog_bark2.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
- files: ["dog_bark3.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
|
||||
- files: ["nymph_chirp.ogg"]
|
||||
license: "CC-BY-SA-3.0"
|
||||
copyright: "Taken from ParadiseSS13"
|
||||
source: "https://github.com/ParadiseSS13/Paradise/commit/a34f1054cef5a44a67fdac3b67b811137c6071dd"
|
||||
|
||||
- files:
|
||||
- fox1.ogg
|
||||
- fox2.ogg
|
||||
- fox3.ogg
|
||||
- fox4.ogg
|
||||
- fox5.ogg
|
||||
- fox6.ogg
|
||||
- fox7.ogg
|
||||
- fox8.ogg
|
||||
- fox9.ogg
|
||||
- fox10.ogg
|
||||
- fox11.ogg
|
||||
- fox12.ogg
|
||||
- fox13.ogg
|
||||
- fox14.ogg
|
||||
copyright: "Created by fujiwaranao"
|
||||
license: "CC-BY-NC-SA-4.0"
|
||||
source: "https://github.com/space-wizards/space-station-14/pull/27578"
|
||||
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user