mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 05:27:38 +03:00
Loadouts (#45)
Description copied from my Wizard's Den PR Resolves https://github.com/Simple-Station/Einstein-Engines/issues/32 # TODO - [x] CVars - [x] Server side loadout point validation - Make tabContainer less bad - [x] Move head clothes to loadouts from lockers - [x] Move job starting equipment to loadouts - [x] Loadout item preview - [x] Fix loadouts duplicating on server restart - [x] Make sure everything is localized -- Components and Tags are an odd thing to display to the player in the whitelist and are very unrealistic to make localizations for, so.. not doing that, what do I do? - [x] Fix all items going into the bag no matter their size - [x] Add min/cur/max points to the bar - [x] Use buttons instead of checkboxes - [x] "Show Unusable" button to hide things your character currently doesn't match the whitelists for - [x] Time whitelist option - [x] Species whitelist option - [x] Trait whitelist option instead of EntityWhitelist for the sake of localization - [ ] More loadouts (filler things while waiting for review) - [ ] - Golden or themed items for Command roles with an undecided amount of playtime on their respective jobs - [x] - Goliath cloak for playing a lot of Salvage - [x] - Senior items for playing a lot of its respective role - [ ] - Varying materials of pocket watches for people with varying overall playtime - [x] Fix loadout selectors not updating to match current preferences <details><summary><h1>Media (Click Me!)</h1></summary> <p> I need to rerecord these https://github.com/space-wizards/space-station-14/assets/77995199/59713874-b043-4813-848e-56b2951b6935 https://github.com/space-wizards/space-station-14/assets/77995199/40180aee-bfe3-4f30-9df8-0f628e7e4514 </p> </details> # Changelog 🆑 - add: Added a new character customization tab for selecting items to start your shift with, loadouts! - remove: Removed some default job equipment in favor of loadouts - remove: Removed several clothing items from Command lockers in favor of loadouts --------- Co-authored-by: VMSolidus <evilexecutive@gmail.com>
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Alerts;
|
||||
using Content.Client.Humanoid;
|
||||
using Content.Client.Inventory;
|
||||
using Content.Client.Preferences;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Clothing.Loadouts.Systems;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Map;
|
||||
@@ -126,6 +124,7 @@ namespace Content.Client.Lobby.UI
|
||||
_summaryLabel.Text = selectedCharacter.Summary;
|
||||
_entityManager.System<HumanoidAppearanceSystem>().LoadProfile(_previewDummy.Value, selectedCharacter);
|
||||
GiveDummyJobClothes(_previewDummy.Value, selectedCharacter);
|
||||
GiveDummyLoadoutItems(_previewDummy.Value, selectedCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,5 +161,13 @@ namespace Content.Client.Lobby.UI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void GiveDummyLoadoutItems(EntityUid dummy, HumanoidCharacterProfile profile)
|
||||
{
|
||||
var highPriorityJobId = profile.JobPriorities.FirstOrDefault(j => j.Value == JobPriority.High).Key;
|
||||
var highPriorityJob = IoCManager.Resolve<IPrototypeManager>().Index<JobPrototype>(highPriorityJobId ?? SharedGameTicker.FallbackOverflowJob);
|
||||
|
||||
EntitySystem.Get<LoadoutSystem>().ApplyCharacterLoadout(dummy, highPriorityJob, profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed partial class JobRequirementsManager
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypes = default!;
|
||||
|
||||
private readonly Dictionary<string, TimeSpan> _roles = new();
|
||||
public readonly Dictionary<string, TimeSpan> PlayTimes = new();
|
||||
private readonly List<string> _roleBans = new();
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
@@ -45,7 +45,7 @@ public sealed partial class JobRequirementsManager
|
||||
if (e.NewLevel == ClientRunLevel.Initialize)
|
||||
{
|
||||
// Reset on disconnect, just in case.
|
||||
_roles.Clear();
|
||||
PlayTimes.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,12 +63,12 @@ public sealed partial class JobRequirementsManager
|
||||
|
||||
private void RxPlayTime(MsgPlayTime message)
|
||||
{
|
||||
_roles.Clear();
|
||||
PlayTimes.Clear();
|
||||
|
||||
// NOTE: do not assign _roles = message.Trackers due to implicit data sharing in integration tests.
|
||||
foreach (var (tracker, time) in message.Trackers)
|
||||
{
|
||||
_roles[tracker] = time;
|
||||
PlayTimes[tracker] = time;
|
||||
}
|
||||
|
||||
/*var sawmill = Logger.GetSawmill("play_time");
|
||||
@@ -96,7 +96,7 @@ public sealed partial class JobRequirementsManager
|
||||
return CheckRoleTime(job.Requirements, out reason);
|
||||
}
|
||||
|
||||
public bool CheckRoleTime(HashSet<JobRequirement>? requirements, [NotNullWhen(false)] out FormattedMessage? reason)
|
||||
public bool CheckRoleTime(HashSet<JobRequirement>? requirements, [NotNullWhen(false)] out FormattedMessage? reason, string? localePrefix = null)
|
||||
{
|
||||
reason = null;
|
||||
|
||||
@@ -106,7 +106,7 @@ public sealed partial class JobRequirementsManager
|
||||
var reasons = new List<string>();
|
||||
foreach (var requirement in requirements)
|
||||
{
|
||||
if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes, _whitelisted))
|
||||
if (JobRequirements.TryRequirementMet(requirement, PlayTimes, out var jobReason, _entManager, _prototypes, _whitelisted, localePrefix))
|
||||
continue;
|
||||
|
||||
reasons.Add(jobReason.ToMarkup());
|
||||
@@ -118,7 +118,7 @@ public sealed partial class JobRequirementsManager
|
||||
|
||||
public TimeSpan FetchOverallPlaytime()
|
||||
{
|
||||
return _roles.TryGetValue("Overall", out var overallPlaytime) ? overallPlaytime : TimeSpan.Zero;
|
||||
return PlayTimes.TryGetValue("Overall", out var overallPlaytime) ? overallPlaytime : TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public IEnumerable<KeyValuePair<string, TimeSpan>> FetchPlaytimeByRoles()
|
||||
@@ -127,7 +127,7 @@ public sealed partial class JobRequirementsManager
|
||||
|
||||
foreach (var job in jobsToMap)
|
||||
{
|
||||
if (_roles.TryGetValue(job.PlayTimeTracker, out var locJobName))
|
||||
if (PlayTimes.TryGetValue(job.PlayTimeTracker, out var locJobName))
|
||||
{
|
||||
yield return new KeyValuePair<string, TimeSpan>(job.Name, locJobName);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@ namespace Content.Client.Preferences.UI
|
||||
if (humanoid != null)
|
||||
{
|
||||
LobbyCharacterPreviewPanel.GiveDummyJobClothes(_previewDummy, humanoid);
|
||||
LobbyCharacterPreviewPanel.GiveDummyLoadoutItems(_previewDummy, humanoid);
|
||||
}
|
||||
|
||||
var isSelectedCharacter = profile == preferencesManager.Preferences?.SelectedCharacter;
|
||||
@@ -229,10 +230,8 @@ namespace Content.Client.Preferences.UI
|
||||
};
|
||||
deleteButton.OnPressed += _ =>
|
||||
{
|
||||
|
||||
deleteButton.Visible = false;
|
||||
confirmDeleteButton.Visible = true;
|
||||
|
||||
};
|
||||
|
||||
var internalHBox = new BoxContainer
|
||||
|
||||
@@ -85,6 +85,12 @@
|
||||
<Control HorizontalExpand="True"/>
|
||||
<Button Name="ShowClothes" Pressed="True" ToggleMode="True" Text="{Loc 'humanoid-profile-editor-clothing-show'}" HorizontalAlignment="Right" />
|
||||
</BoxContainer>
|
||||
<!-- Show loadouts -->
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-loadouts'}" />
|
||||
<Control HorizontalExpand="True"/>
|
||||
<Button Name="ShowLoadouts" Pressed="True" ToggleMode="True" Text="{Loc 'Show'}" HorizontalAlignment="Right" />
|
||||
</BoxContainer>
|
||||
<!-- Clothing -->
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Text="{Loc 'humanoid-profile-editor-clothing-label'}" />
|
||||
@@ -142,6 +148,15 @@
|
||||
<BoxContainer Name="CTraitsList" Orientation="Vertical" />
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
<BoxContainer Name="CLoadoutsTab" Orientation="Vertical" Margin="10">
|
||||
<!-- Loadouts -->
|
||||
<Label Name="LoadoutPointsLabel" HorizontalAlignment="Stretch" Align="Center" />
|
||||
<ProgressBar Name="LoadoutPointsBar" MaxValue="1" Value="1" MaxHeight="8" Margin="0 5" />
|
||||
|
||||
<Button Name="CHideShowUnusableButton" Text="{Loc 'humanoid-profile-editor-loadouts-show-unusable-button'}" ToolTip="{Loc 'humanoid-profile-editor-loadouts-show-unusable-button-tooltip'}" ToggleMode="True" Margin="0 0 0 5" />
|
||||
|
||||
<TabContainer Name="CLoadoutsTabs" VerticalExpand="True" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Name="CMarkingsTab" Orientation="Vertical" Margin="10">
|
||||
<!-- Markings -->
|
||||
<ScrollContainer VerticalExpand="True">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using Content.Client.Guidebook;
|
||||
using Content.Client.Humanoid;
|
||||
using Content.Client.Lobby.UI;
|
||||
@@ -9,17 +10,17 @@ using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.UserInterface.Systems.Guidebook;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Clothing.Loadouts.Prototypes;
|
||||
using Content.Shared.Clothing.Loadouts.Systems;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.StatusIcon;
|
||||
using Content.Shared.Traits;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
@@ -30,7 +31,6 @@ using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
@@ -61,6 +61,7 @@ namespace Content.Client.Preferences.UI
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly MarkingManager _markingManager;
|
||||
private readonly JobRequirementsManager _requirements;
|
||||
private readonly LoadoutSystem _loadoutSystem;
|
||||
|
||||
private LineEdit _ageEdit => CAgeEdit;
|
||||
private LineEdit _nameEdit => CNameEdit;
|
||||
@@ -83,6 +84,11 @@ namespace Content.Client.Preferences.UI
|
||||
private BoxContainer _jobList => CJobList;
|
||||
private BoxContainer _antagList => CAntagList;
|
||||
private BoxContainer _traitsList => CTraitsList;
|
||||
private Label _loadoutPointsLabel => LoadoutPointsLabel;
|
||||
private ProgressBar _loadoutPointsBar => LoadoutPointsBar;
|
||||
private Button _loadoutsShowUnusableButton => CHideShowUnusableButton;
|
||||
private BoxContainer _loadoutsTab => CLoadoutsTab;
|
||||
private TabContainer _loadoutsTabs => CLoadoutsTabs;
|
||||
private readonly List<JobPrioritySelector> _jobPriorities;
|
||||
private OptionButton _preferenceUnavailableButton => CPreferenceUnavailableButton;
|
||||
private readonly Dictionary<string, BoxContainer> _jobCategories;
|
||||
@@ -90,6 +96,7 @@ namespace Content.Client.Preferences.UI
|
||||
private readonly List<SpeciesPrototype> _speciesList;
|
||||
private readonly List<AntagPreferenceSelector> _antagPreferences;
|
||||
private readonly List<TraitPreferenceSelector> _traitPreferences;
|
||||
private readonly List<LoadoutPreferenceSelector> _loadoutPreferences;
|
||||
|
||||
private SpriteView _previewSpriteView => CSpriteView;
|
||||
private Button _previewRotateLeftButton => CSpriteRotateLeft;
|
||||
@@ -117,6 +124,7 @@ namespace Content.Client.Preferences.UI
|
||||
_preferencesManager = preferencesManager;
|
||||
_configurationManager = configurationManager;
|
||||
_markingManager = IoCManager.Resolve<MarkingManager>();
|
||||
_loadoutSystem = EntitySystem.Get<LoadoutSystem>();
|
||||
|
||||
SpeciesInfoButton.ToolTip = Loc.GetString("humanoid-profile-editor-guidebook-button-tooltip");
|
||||
|
||||
@@ -140,6 +148,7 @@ namespace Content.Client.Preferences.UI
|
||||
_tabContainer.SetTabTitle(0, Loc.GetString("humanoid-profile-editor-appearance-tab"));
|
||||
|
||||
ShowClothes.OnPressed += ToggleClothes;
|
||||
ShowLoadouts.OnPressed += ToggleClothes;
|
||||
|
||||
#region Sex
|
||||
|
||||
@@ -465,6 +474,22 @@ namespace Content.Client.Preferences.UI
|
||||
|
||||
#endregion
|
||||
|
||||
#region Loadouts
|
||||
|
||||
// Set up the loadouts tab
|
||||
_tabContainer.SetTabTitle(4, Loc.GetString("humanoid-profile-editor-loadouts-tab"));
|
||||
_loadoutPreferences = new List<LoadoutPreferenceSelector>();
|
||||
|
||||
// Show/Hide loadouts tab if they ever get enabled/disabled
|
||||
var loadoutsEnabled = _configurationManager.GetCVar(CCVars.GameLoadoutsEnabled);
|
||||
_tabContainer.SetTabVisible(4, loadoutsEnabled);
|
||||
ShowLoadouts.Visible = loadoutsEnabled;
|
||||
_configurationManager.OnValueChanged(CCVars.GameLoadoutsEnabled, enabled => LoadoutsChanged(enabled));
|
||||
|
||||
_loadoutsShowUnusableButton.OnToggled += args => UpdateLoadouts(args.Pressed);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Save
|
||||
|
||||
_saveButton.OnPressed += _ => { Save(); };
|
||||
@@ -472,7 +497,7 @@ namespace Content.Client.Preferences.UI
|
||||
#endregion Save
|
||||
|
||||
#region Markings
|
||||
_tabContainer.SetTabTitle(4, Loc.GetString("humanoid-profile-editor-markings-tab"));
|
||||
_tabContainer.SetTabTitle(5, Loc.GetString("humanoid-profile-editor-markings-tab"));
|
||||
|
||||
CMarkings.OnMarkingAdded += OnMarkingChange;
|
||||
CMarkings.OnMarkingRemoved += OnMarkingChange;
|
||||
@@ -516,6 +541,9 @@ namespace Content.Client.Preferences.UI
|
||||
|
||||
_previewDummy = _entMan.SpawnEntity(dollProto, MapCoordinates.Nullspace);
|
||||
_previewSpriteView.SetEntity(_previewDummy);
|
||||
|
||||
UpdateLoadouts(false); // Initial UpdateLoadouts call has to have a dummy to get information from
|
||||
|
||||
#endregion Dummy
|
||||
|
||||
#endregion Left
|
||||
@@ -534,6 +562,12 @@ namespace Content.Client.Preferences.UI
|
||||
IsDirty = false;
|
||||
}
|
||||
|
||||
private void LoadoutsChanged(bool enabled)
|
||||
{
|
||||
_tabContainer.SetTabVisible(4, enabled);
|
||||
ShowLoadouts.Visible = enabled;
|
||||
}
|
||||
|
||||
private void OnSpeciesInfoButtonPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
var guidebookController = UserInterfaceManager.GetUIController<GuidebookUIController>();
|
||||
@@ -781,6 +815,8 @@ namespace Content.Client.Preferences.UI
|
||||
|
||||
_requirements.Updated -= UpdateRoleRequirements;
|
||||
_preferencesManager.OnServerDataLoaded -= LoadServerData;
|
||||
|
||||
_configurationManager.UnsubValueChanged(CCVars.GameLoadoutsEnabled, enabled => LoadoutsChanged(enabled));
|
||||
}
|
||||
|
||||
private void RebuildSpriteView()
|
||||
@@ -1203,6 +1239,8 @@ namespace Content.Client.Preferences.UI
|
||||
|
||||
if (ShowClothes.Pressed)
|
||||
LobbyCharacterPreviewPanel.GiveDummyJobClothes(_previewDummy!.Value, Profile);
|
||||
if (ShowLoadouts.Pressed)
|
||||
LobbyCharacterPreviewPanel.GiveDummyLoadoutItems(_previewDummy!.Value, Profile);
|
||||
|
||||
_previewSpriteView.OverrideDirection = (Direction) ((int) _previewRotation % 4 * 2);
|
||||
}
|
||||
@@ -1225,6 +1263,8 @@ namespace Content.Client.Preferences.UI
|
||||
UpdateJobPriorities();
|
||||
UpdateAntagPreferences();
|
||||
UpdateTraitPreferences();
|
||||
UpdateLoadouts(_loadoutsShowUnusableButton.Pressed);
|
||||
UpdateLoadoutPreferences();
|
||||
UpdateMarkings();
|
||||
RebuildSpriteView();
|
||||
UpdateHairPickers();
|
||||
@@ -1418,6 +1458,253 @@ namespace Content.Client.Preferences.UI
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLoadoutPreferences()
|
||||
{
|
||||
var points = _configurationManager.GetCVar(CCVars.GameLoadoutsPoints);
|
||||
_loadoutPointsBar.Value = points;
|
||||
_loadoutPointsLabel.Text = Loc.GetString("humanoid-profile-editor-loadouts-points-label", ("points", points), ("max", points));
|
||||
|
||||
foreach (var preferenceSelector in _loadoutPreferences)
|
||||
{
|
||||
var loadoutId = preferenceSelector.Loadout.ID;
|
||||
var preference = Profile?.LoadoutPreferences.Contains(loadoutId) ?? false;
|
||||
|
||||
preferenceSelector.Preference = preference;
|
||||
|
||||
if (preference)
|
||||
{
|
||||
points -= preferenceSelector.Loadout.Cost;
|
||||
_loadoutPointsBar.Value = points;
|
||||
_loadoutPointsLabel.Text = Loc.GetString("humanoid-profile-editor-loadouts-points-label", ("points", points), ("max", _loadoutPointsBar.MaxValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLoadouts(bool showUnusable)
|
||||
{
|
||||
// Reset loadout points so you don't get -14 points or something for no reason
|
||||
var points = _configurationManager.GetCVar(CCVars.GameLoadoutsPoints);
|
||||
_loadoutPointsLabel.Text = Loc.GetString("humanoid-profile-editor-loadouts-points-label", ("points", points), ("max", points));
|
||||
_loadoutPointsBar.MaxValue = points;
|
||||
_loadoutPointsBar.Value = points;
|
||||
|
||||
// Clear current listings
|
||||
_loadoutPreferences.Clear();
|
||||
_loadoutsTabs.DisposeAllChildren();
|
||||
|
||||
|
||||
// Get the highest priority job to use for loadout filtering
|
||||
var highJob = _jobPriorities.FirstOrDefault(j => j.Priority == JobPriority.High);
|
||||
|
||||
// Get all loadout prototypes
|
||||
var enumeratedLoadouts = _prototypeManager.EnumeratePrototypes<LoadoutPrototype>().ToList();
|
||||
|
||||
// If showUnusable is false filter out loadouts that are unusable based on your current character setup
|
||||
var loadouts = enumeratedLoadouts.Where(loadout =>
|
||||
showUnusable || // Ignore everything if this is true
|
||||
_loadoutSystem.CheckRequirementsValid(
|
||||
loadout.Requirements,
|
||||
highJob?.Proto ?? new JobPrototype(),
|
||||
Profile ?? HumanoidCharacterProfile.DefaultWithSpecies(),
|
||||
new Dictionary<string, TimeSpan>(),
|
||||
_entMan,
|
||||
_prototypeManager,
|
||||
_configurationManager,
|
||||
out _
|
||||
)
|
||||
).ToList();
|
||||
|
||||
// Loadouts to highlight red when showUnusable is true
|
||||
var loadoutsUnusable = enumeratedLoadouts.Where(loadout =>
|
||||
_loadoutSystem.CheckRequirementsValid(
|
||||
loadout.Requirements,
|
||||
highJob?.Proto ?? new JobPrototype(),
|
||||
Profile ?? HumanoidCharacterProfile.DefaultWithSpecies(),
|
||||
new Dictionary<string, TimeSpan>(),
|
||||
_entMan,
|
||||
_prototypeManager,
|
||||
_configurationManager,
|
||||
out _
|
||||
)
|
||||
).ToList();
|
||||
|
||||
// Every loadout not in the loadouts list
|
||||
var otherLoadouts = enumeratedLoadouts.Where(loadout => !loadouts.Contains(loadout)).ToList();
|
||||
|
||||
|
||||
if (loadouts.Count == 0)
|
||||
{
|
||||
_loadoutsTab.AddChild(new Label { Text = Loc.GetString("humanoid-profile-editor-loadouts-no-loadouts") });
|
||||
return;
|
||||
}
|
||||
|
||||
// Make Uncategorized category
|
||||
var uncategorized = new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Vertical,
|
||||
VerticalExpand = true,
|
||||
Name = "Uncategorized_0",
|
||||
};
|
||||
|
||||
_loadoutsTabs.AddChild(uncategorized);
|
||||
_loadoutsTabs.SetTabTitle(0, Loc.GetString("humanoid-profile-editor-loadouts-uncategorized-tab"));
|
||||
|
||||
// Make categories
|
||||
var currentCategory = 1; // 1 because we already made 0 as Uncategorized, I am not not zero-indexing :)
|
||||
foreach (var loadout in loadouts.OrderBy(l => l.Category))
|
||||
{
|
||||
// Check for existing category
|
||||
BoxContainer? match = null;
|
||||
foreach (var child in _loadoutsTabs.Children)
|
||||
{
|
||||
if (match != null || child.Name == null)
|
||||
continue;
|
||||
if (child.Name.Split("_")[0] == loadout.Category)
|
||||
match = (BoxContainer) child;
|
||||
}
|
||||
|
||||
// If there is a category do nothing
|
||||
if (match != null)
|
||||
continue;
|
||||
|
||||
// If not, make it
|
||||
var box = new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Vertical,
|
||||
VerticalExpand = true,
|
||||
Name = $"{loadout.Category}_{currentCategory}",
|
||||
// I hate ScrollContainers
|
||||
Children =
|
||||
{
|
||||
new ScrollContainer
|
||||
{
|
||||
HScrollEnabled = false,
|
||||
HorizontalExpand = true,
|
||||
VerticalExpand = true,
|
||||
Children =
|
||||
{
|
||||
new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Vertical,
|
||||
HorizontalExpand = true,
|
||||
VerticalExpand = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
_loadoutsTabs.AddChild(box);
|
||||
_loadoutsTabs.SetTabTitle(currentCategory, Loc.GetString($"loadout-category-{loadout.Category}"));
|
||||
currentCategory++;
|
||||
}
|
||||
|
||||
// Fill categories
|
||||
foreach (var loadout in loadouts.OrderBy(l => l.ID))
|
||||
{
|
||||
var selector = new LoadoutPreferenceSelector(loadout, highJob?.Proto ?? new JobPrototype(),
|
||||
Profile ?? HumanoidCharacterProfile.DefaultWithSpecies(),
|
||||
loadoutsUnusable.Contains(loadout) ? "" : "ButtonColorRed", _entMan, _prototypeManager,
|
||||
_configurationManager, _loadoutSystem);
|
||||
|
||||
// Look for an existing loadout category
|
||||
BoxContainer? match = null;
|
||||
foreach (var child in _loadoutsTabs.Children)
|
||||
{
|
||||
if (match != null || child.Name == null)
|
||||
continue;
|
||||
|
||||
if (child.Name.Split("_")[0] == loadout.Category)
|
||||
match = (BoxContainer) child.Children.First().Children.First();
|
||||
}
|
||||
|
||||
// If there is no category put it in Uncategorized
|
||||
if (match?.Parent?.Parent?.Name == null)
|
||||
uncategorized.AddChild(selector);
|
||||
else
|
||||
match.AddChild(selector);
|
||||
|
||||
_loadoutPreferences.Add(selector);
|
||||
selector.PreferenceChanged += preference =>
|
||||
{
|
||||
// Make sure they have enough loadout points
|
||||
if (preference)
|
||||
{
|
||||
var temp = _loadoutPointsBar.Value - loadout.Cost;
|
||||
if (temp < 0)
|
||||
preference = false;
|
||||
else
|
||||
{
|
||||
_loadoutPointsLabel.Text = Loc.GetString("humanoid-profile-editor-loadouts-points-label",
|
||||
("points", temp), ("max", _loadoutPointsBar.MaxValue));
|
||||
_loadoutPointsBar.Value = temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_loadoutPointsLabel.Text = Loc.GetString("humanoid-profile-editor-loadouts-points-label",
|
||||
("points", _loadoutPointsBar.Value), ("max", _loadoutPointsBar.MaxValue));
|
||||
_loadoutPointsBar.Value += loadout.Cost;
|
||||
}
|
||||
// Update Preference
|
||||
Profile = Profile?.WithLoadoutPreference(loadout.ID, preference);
|
||||
IsDirty = true;
|
||||
UpdateLoadoutPreferences();
|
||||
};
|
||||
}
|
||||
|
||||
// Add the selected unusable loadouts to the point counter
|
||||
foreach (var loadout in otherLoadouts.OrderBy(l => l.ID))
|
||||
{
|
||||
var selector = new LoadoutPreferenceSelector(loadout, highJob?.Proto ?? new JobPrototype(),
|
||||
Profile ?? HumanoidCharacterProfile.DefaultWithSpecies(), "", _entMan, _prototypeManager,
|
||||
_configurationManager, _loadoutSystem);
|
||||
|
||||
_loadoutPreferences.Add(selector);
|
||||
selector.PreferenceChanged += preference =>
|
||||
{
|
||||
// Make sure they have enough loadout points
|
||||
if (preference)
|
||||
{
|
||||
var temp = _loadoutPointsBar.Value - loadout.Cost;
|
||||
if (temp < 0)
|
||||
preference = false;
|
||||
else
|
||||
{
|
||||
_loadoutPointsLabel.Text = Loc.GetString("humanoid-profile-editor-loadouts-points-label",
|
||||
("points", temp), ("max", _loadoutPointsBar.MaxValue));
|
||||
_loadoutPointsBar.Value = temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_loadoutPointsLabel.Text = Loc.GetString("humanoid-profile-editor-loadouts-points-label",
|
||||
("points", _loadoutPointsBar.Value), ("max", _loadoutPointsBar.MaxValue));
|
||||
_loadoutPointsBar.Value += loadout.Cost;
|
||||
}
|
||||
// Update Preference
|
||||
Profile = Profile?.WithLoadoutPreference(loadout.ID, preference);
|
||||
IsDirty = true;
|
||||
UpdateLoadoutPreferences();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Hide Uncategorized tab if it's empty, other tabs already shouldn't exist if they're empty
|
||||
if (!uncategorized.Children.Any())
|
||||
_loadoutsTabs.SetTabVisible(0, false);
|
||||
|
||||
// Add fake tabs until tab container is happy
|
||||
for (var i = _loadoutsTabs.ChildCount - 1; i < _loadoutsTabs.CurrentTab; i++)
|
||||
{
|
||||
_loadoutsTabs.AddChild(new BoxContainer());
|
||||
_loadoutsTabs.SetTabVisible(i + 1, false);
|
||||
}
|
||||
|
||||
UpdateLoadoutPreferences();
|
||||
}
|
||||
|
||||
|
||||
private sealed class AntagPreferenceSelector : RequirementsSelector<AntagPrototype>
|
||||
{
|
||||
// 0 is yes and 1 is no
|
||||
@@ -1456,12 +1743,12 @@ namespace Content.Client.Preferences.UI
|
||||
private sealed class TraitPreferenceSelector : Control
|
||||
{
|
||||
public TraitPrototype Trait { get; }
|
||||
private readonly CheckBox _checkBox;
|
||||
private readonly Button _button;
|
||||
|
||||
public bool Preference
|
||||
{
|
||||
get => _checkBox.Pressed;
|
||||
set => _checkBox.Pressed = value;
|
||||
get => _button.Pressed;
|
||||
set => _button.Pressed = value;
|
||||
}
|
||||
|
||||
public event Action<bool>? PreferenceChanged;
|
||||
@@ -1470,22 +1757,108 @@ namespace Content.Client.Preferences.UI
|
||||
{
|
||||
Trait = trait;
|
||||
|
||||
_checkBox = new CheckBox {Text = Loc.GetString(trait.Name)};
|
||||
_checkBox.OnToggled += OnCheckBoxToggled;
|
||||
_button = new Button {Text = Loc.GetString(trait.Name)};
|
||||
_button.ToggleMode = true;
|
||||
_button.OnToggled += OnButtonToggled;
|
||||
|
||||
if (trait.Description is { } desc)
|
||||
{
|
||||
_checkBox.ToolTip = Loc.GetString(desc);
|
||||
_button.ToolTip = Loc.GetString(desc);
|
||||
}
|
||||
|
||||
AddChild(new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Horizontal,
|
||||
Children = { _checkBox },
|
||||
Children = { _button },
|
||||
});
|
||||
}
|
||||
|
||||
private void OnCheckBoxToggled(BaseButton.ButtonToggledEventArgs args)
|
||||
private void OnButtonToggled(BaseButton.ButtonToggledEventArgs args)
|
||||
{
|
||||
PreferenceChanged?.Invoke(Preference);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class LoadoutPreferenceSelector : Control
|
||||
{
|
||||
public LoadoutPrototype Loadout { get; }
|
||||
private readonly Button _button;
|
||||
|
||||
public bool Preference
|
||||
{
|
||||
get => _button.Pressed;
|
||||
set => _button.Pressed = value;
|
||||
}
|
||||
|
||||
public event Action<bool>? PreferenceChanged;
|
||||
|
||||
public LoadoutPreferenceSelector(LoadoutPrototype loadout, JobPrototype highJob,
|
||||
HumanoidCharacterProfile profile, string style, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, LoadoutSystem loadoutSystem)
|
||||
{
|
||||
Loadout = loadout;
|
||||
|
||||
// Display the first item in the loadout as a preview
|
||||
// TODO: Maybe allow custom icons to be specified in the prototype?
|
||||
var dummyLoadoutItem = entityManager.SpawnEntity(loadout.Items.First(), MapCoordinates.Nullspace);
|
||||
|
||||
// Create a sprite preview of the loadout item
|
||||
var previewLoadout = new SpriteView
|
||||
{
|
||||
Scale = new Vector2(1, 1),
|
||||
OverrideDirection = Direction.South,
|
||||
VerticalAlignment = VAlignment.Center,
|
||||
SizeFlagsStretchRatio = 1,
|
||||
};
|
||||
previewLoadout.SetEntity(dummyLoadoutItem);
|
||||
|
||||
|
||||
// Create a checkbox to get the loadout
|
||||
_button = new Button
|
||||
{
|
||||
Text = $"[{loadout.Cost}] {(Loc.GetString($"loadout-name-{loadout.ID}") == $"loadout-name-{loadout.ID}"
|
||||
? entityManager.GetComponent<MetaDataComponent>(dummyLoadoutItem).EntityName
|
||||
: Loc.GetString($"loadout-name-{loadout.ID}"))}",
|
||||
VerticalAlignment = VAlignment.Center,
|
||||
ToggleMode = true,
|
||||
};
|
||||
_button.OnToggled += OnButtonToggled;
|
||||
_button.AddStyleClass(style);
|
||||
|
||||
var tooltip = new StringBuilder();
|
||||
// Add the loadout description to the tooltip if there is one
|
||||
var desc = !Loc.TryGetString($"loadout-description-{loadout.ID}", out var description)
|
||||
? entityManager.GetComponent<MetaDataComponent>(dummyLoadoutItem).EntityDescription
|
||||
: description;
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
tooltip.Append($"{Loc.GetString(desc)}");
|
||||
|
||||
|
||||
// Get requirement reasons
|
||||
loadoutSystem.CheckRequirementsValid(loadout.Requirements, highJob, profile, new Dictionary<string, TimeSpan>(), entityManager, prototypeManager, configManager, out var reasons);
|
||||
|
||||
// Add requirement reasons to the tooltip
|
||||
foreach (var reason in reasons)
|
||||
tooltip.Append($"\n{reason.ToMarkup()}");
|
||||
|
||||
// Combine the tooltip and format it in the checkbox supplier
|
||||
if (tooltip.Length > 0)
|
||||
{
|
||||
var formattedTooltip = new Tooltip();
|
||||
formattedTooltip.SetMessage(FormattedMessage.FromMarkupPermissive(tooltip.ToString()));
|
||||
_button.TooltipSupplier = _ => formattedTooltip;
|
||||
}
|
||||
|
||||
|
||||
// Add the loadout preview and the checkbox to the control
|
||||
AddChild(new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Horizontal,
|
||||
Children = { previewLoadout, _button },
|
||||
});
|
||||
}
|
||||
|
||||
private void OnButtonToggled(BaseButton.ButtonToggledEventArgs args)
|
||||
{
|
||||
PreferenceChanged?.Invoke(Preference);
|
||||
}
|
||||
|
||||
@@ -61,8 +61,9 @@ namespace Content.IntegrationTests.Tests.Preferences
|
||||
{SharedGameTicker.FallbackOverflowJob, JobPriority.High}
|
||||
},
|
||||
PreferenceUnavailableMode.StayInLobby,
|
||||
new List<string> (),
|
||||
new List<string>()
|
||||
antagPreferences: new List<string>(),
|
||||
traitPreferences: new List<string>(),
|
||||
loadoutPreferences: new List<string>()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
1802
Content.Server.Database/Migrations/Postgres/20240505230501_Loadouts.Designer.cs
generated
Normal file
1802
Content.Server.Database/Migrations/Postgres/20240505230501_Loadouts.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Postgres
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Loadouts : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "loadout",
|
||||
columns: table => new
|
||||
{
|
||||
loadout_id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
profile_id = table.Column<int>(type: "integer", nullable: false),
|
||||
loadout_name = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_loadout", x => x.loadout_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_loadout_profile_profile_id",
|
||||
column: x => x.profile_id,
|
||||
principalTable: "profile",
|
||||
principalColumn: "profile_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_loadout_profile_id_loadout_name",
|
||||
table: "loadout",
|
||||
columns: new[] { "profile_id", "loadout_name" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "loadout");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -604,6 +604,33 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.ToTable("job", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Loadout", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("loadout_id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("LoadoutName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("loadout_name");
|
||||
|
||||
b.Property<int>("ProfileId")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("profile_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_loadout");
|
||||
|
||||
b.HasIndex("ProfileId", "LoadoutName")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("loadout", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.PlayTime", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1509,6 +1536,18 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Loadout", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Profile", "Profile")
|
||||
.WithMany("Loadouts")
|
||||
.HasForeignKey("ProfileId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_loadout_profile_profile_id");
|
||||
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Profile", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Preference", "Preference")
|
||||
@@ -1733,6 +1772,8 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
|
||||
b.Navigation("Jobs");
|
||||
|
||||
b.Navigation("Loadouts");
|
||||
|
||||
b.Navigation("Traits");
|
||||
});
|
||||
|
||||
|
||||
1731
Content.Server.Database/Migrations/Sqlite/20240505230431_Loadouts.Designer.cs
generated
Normal file
1731
Content.Server.Database/Migrations/Sqlite/20240505230431_Loadouts.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Sqlite
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Loadouts : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "loadout",
|
||||
columns: table => new
|
||||
{
|
||||
loadout_id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
profile_id = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
loadout_name = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_loadout", x => x.loadout_id);
|
||||
table.ForeignKey(
|
||||
name: "FK_loadout_profile_profile_id",
|
||||
column: x => x.profile_id,
|
||||
principalTable: "profile",
|
||||
principalColumn: "profile_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_loadout_profile_id_loadout_name",
|
||||
table: "loadout",
|
||||
columns: new[] { "profile_id", "loadout_name" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "loadout");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -568,6 +568,31 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.ToTable("job", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Loadout", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("loadout_id");
|
||||
|
||||
b.Property<string>("LoadoutName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("loadout_name");
|
||||
|
||||
b.Property<int>("ProfileId")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("profile_id");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PK_loadout");
|
||||
|
||||
b.HasIndex("ProfileId", "LoadoutName")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("loadout", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.PlayTime", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -1440,6 +1465,18 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Loadout", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Profile", "Profile")
|
||||
.WithMany("Loadouts")
|
||||
.HasForeignKey("ProfileId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_loadout_profile_profile_id");
|
||||
|
||||
b.Navigation("Profile");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Content.Server.Database.Profile", b =>
|
||||
{
|
||||
b.HasOne("Content.Server.Database.Preference", "Preference")
|
||||
@@ -1664,6 +1701,8 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
|
||||
b.Navigation("Jobs");
|
||||
|
||||
b.Navigation("Loadouts");
|
||||
|
||||
b.Navigation("Traits");
|
||||
});
|
||||
|
||||
|
||||
@@ -56,8 +56,12 @@ namespace Content.Server.Database
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<Trait>()
|
||||
.HasIndex(p => new {HumanoidProfileId = p.ProfileId, p.TraitName})
|
||||
.IsUnique();
|
||||
.HasIndex(p => new {HumanoidProfileId = p.ProfileId, p.TraitName})
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<Loadout>()
|
||||
.HasIndex(p => new {HumanoidProfileId = p.ProfileId, p.LoadoutName})
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<Job>()
|
||||
.HasIndex(j => j.ProfileId);
|
||||
@@ -347,6 +351,7 @@ namespace Content.Server.Database
|
||||
public List<Job> Jobs { get; } = new();
|
||||
public List<Antag> Antags { get; } = new();
|
||||
public List<Trait> Traits { get; } = new();
|
||||
public List<Loadout> Loadouts { get; } = new();
|
||||
|
||||
[Column("pref_unavailable")] public DbPreferenceUnavailableMode PreferenceUnavailable { get; set; }
|
||||
|
||||
@@ -391,6 +396,15 @@ namespace Content.Server.Database
|
||||
public string TraitName { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class Loadout
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Profile Profile { get; set; } = null!;
|
||||
public int ProfileId { get; set; }
|
||||
|
||||
public string LoadoutName { get; set; } = null!;
|
||||
}
|
||||
|
||||
public enum DbPreferenceUnavailableMode
|
||||
{
|
||||
// These enum values HAVE to match the ones in PreferenceUnavailableMode in Shared.
|
||||
|
||||
49
Content.Server/Clothing/Systems/LoadoutSystem.cs
Normal file
49
Content.Server/Clothing/Systems/LoadoutSystem.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Players.PlayTimeTracking;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Storage.EntitySystems;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Server.Clothing.Systems;
|
||||
|
||||
public sealed class LoadoutSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly Shared.Clothing.Loadouts.Systems.LoadoutSystem _loadout = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly SharedStorageSystem _storage = default!;
|
||||
[Dependency] private readonly PlayTimeTrackingManager _playTimeTracking = default!;
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(OnPlayerSpawnComplete);
|
||||
}
|
||||
|
||||
|
||||
private void OnPlayerSpawnComplete(PlayerSpawnCompleteEvent ev)
|
||||
{
|
||||
if (ev.JobId == null ||
|
||||
!_configurationManager.GetCVar(CCVars.GameLoadoutsEnabled))
|
||||
return;
|
||||
|
||||
// Spawn the loadout, get a list of items that failed to equip
|
||||
var failedLoadouts = _loadout.ApplyCharacterLoadout(ev.Mob, ev.JobId, ev.Profile, _playTimeTracking.GetTrackerTimes(ev.Player));
|
||||
|
||||
// Try to find back-mounted storage apparatus
|
||||
if (!_inventory.TryGetSlotEntity(ev.Mob, "back", out var item) ||
|
||||
!EntityManager.TryGetComponent<StorageComponent>(item, out var inventory))
|
||||
return;
|
||||
|
||||
// Try inserting the entity into the storage, if it can't, it leaves the loadout item on the ground
|
||||
foreach (var loadout in failedLoadouts)
|
||||
{
|
||||
if (EntityManager.TryGetComponent<ItemComponent>(loadout, out var itemComp) &&
|
||||
_storage.CanInsert(item.Value, loadout, out _, inventory, itemComp))
|
||||
_storage.Insert(item.Value, loadout, out _, playSound: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ namespace Content.Server.Database
|
||||
.Include(p => p.Profiles).ThenInclude(h => h.Jobs)
|
||||
.Include(p => p.Profiles).ThenInclude(h => h.Antags)
|
||||
.Include(p => p.Profiles).ThenInclude(h => h.Traits)
|
||||
.Include(p => p.Profiles).ThenInclude(h => h.Loadouts)
|
||||
.AsSingleQuery()
|
||||
.SingleOrDefaultAsync(p => p.UserId == userId.UserId);
|
||||
|
||||
@@ -88,6 +89,7 @@ namespace Content.Server.Database
|
||||
.Include(p => p.Jobs)
|
||||
.Include(p => p.Antags)
|
||||
.Include(p => p.Traits)
|
||||
.Include(p => p.Loadouts)
|
||||
.AsSplitQuery()
|
||||
.SingleOrDefault(h => h.Slot == slot);
|
||||
|
||||
@@ -174,6 +176,7 @@ namespace Content.Server.Database
|
||||
var jobs = profile.Jobs.ToDictionary(j => j.JobName, j => (JobPriority) j.Priority);
|
||||
var antags = profile.Antags.Select(a => a.AntagName);
|
||||
var traits = profile.Traits.Select(t => t.TraitName);
|
||||
var loadouts = profile.Loadouts.Select(t => t.LoadoutName);
|
||||
|
||||
var sex = Sex.Male;
|
||||
if (Enum.TryParse<Sex>(profile.Sex, true, out var sexVal))
|
||||
@@ -232,7 +235,8 @@ namespace Content.Server.Database
|
||||
jobs,
|
||||
(PreferenceUnavailableMode) profile.PreferenceUnavailable,
|
||||
antags.ToList(),
|
||||
traits.ToList()
|
||||
traits.ToList(),
|
||||
loadouts.ToList()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -285,6 +289,12 @@ namespace Content.Server.Database
|
||||
.Select(t => new Trait {TraitName = t})
|
||||
);
|
||||
|
||||
profile.Loadouts.Clear();
|
||||
profile.Loadouts.AddRange(
|
||||
humanoid.LoadoutPreferences
|
||||
.Select(t => new Loadout {LoadoutName = t})
|
||||
);
|
||||
|
||||
return profile;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -341,6 +341,18 @@ namespace Content.Shared.CCVar
|
||||
public static readonly CVarDef<bool> DebugCoordinatesAdminOnly =
|
||||
CVarDef.Create("game.debug_coordinates_admin_only", true, CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to allow characters to select loadout items.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> GameLoadoutsEnabled =
|
||||
CVarDef.Create("game.loadouts_enabled", true, CVar.REPLICATED);
|
||||
|
||||
/// <summary>
|
||||
/// How many points to give to each player for loadouts.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> GameLoadoutsPoints =
|
||||
CVarDef.Create("game.loadouts_points", 14, CVar.REPLICATED);
|
||||
|
||||
#if EXCEPTION_TOLERANCE
|
||||
/// <summary>
|
||||
/// Amount of times round start must fail before the server is shut down.
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Station;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared.Clothing;
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a loadout to an entity based on the startingGear prototype
|
||||
/// </summary>
|
||||
public sealed class LoadoutSystem : EntitySystem
|
||||
{
|
||||
// Shared so we can predict it for placement manager.
|
||||
|
||||
[Dependency] private readonly SharedStationSpawningSystem _station = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LoadoutComponent, MapInitEvent>(OnMapInit);
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, LoadoutComponent component, MapInitEvent args)
|
||||
{
|
||||
if (component.Prototypes == null)
|
||||
return;
|
||||
|
||||
var proto = _protoMan.Index<StartingGearPrototype>(_random.Pick(component.Prototypes));
|
||||
_station.EquipStartingGear(uid, proto, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Clothing.Loadouts.Prototypes;
|
||||
|
||||
/// <summary>
|
||||
/// A prototype defining a valid category for <see cref="LoadoutPrototype"/>s to go into.
|
||||
/// </summary>
|
||||
[Prototype("loadoutCategory")]
|
||||
public sealed class LoadoutCategoryPrototype : IPrototype
|
||||
{
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Content.Shared.Clothing.Loadouts.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Shared.Clothing.Loadouts.Prototypes;
|
||||
|
||||
[Prototype("loadout")]
|
||||
public sealed class LoadoutPrototype : IPrototype
|
||||
{
|
||||
/// <summary>
|
||||
/// Formatted like "Loadout[Department/ShortHeadName][CommonClothingSlot][SimplifiedClothingId]", example: "LoadoutScienceOuterLabcoatSeniorResearcher"
|
||||
/// </summary>
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Which tab category to put this under
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer:typeof(PrototypeIdSerializer<LoadoutCategoryPrototype>))]
|
||||
public string Category = "Uncategorized";
|
||||
|
||||
/// <summary>
|
||||
/// The item to give
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>), required: true)]
|
||||
public List<string> Items = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The point cost of this loadout
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int Cost = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Should this item override other items in the same slot?
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Exclusive;
|
||||
|
||||
|
||||
[DataField]
|
||||
public List<LoadoutRequirement> Requirements = new();
|
||||
}
|
||||
375
Content.Shared/Clothing/Loadouts/Systems/LoadoutRequirements.cs
Normal file
375
Content.Shared/Clothing/Loadouts/Systems/LoadoutRequirements.cs
Normal file
@@ -0,0 +1,375 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using Content.Shared.Traits;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Clothing.Loadouts.Systems;
|
||||
|
||||
[ImplicitDataDefinitionForInheritors, MeansImplicitUse]
|
||||
[Serializable, NetSerializable]
|
||||
public abstract partial class LoadoutRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// If true valid requirements will be treated as invalid and vice versa
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Inverted = false;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this loadout requirement is valid for the given parameters
|
||||
/// </summary>
|
||||
/// <param name="reason">Description for the requirement, shown when not null</param>
|
||||
public abstract bool IsValid(
|
||||
JobPrototype job,
|
||||
HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes,
|
||||
IEntityManager entityManager,
|
||||
IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager,
|
||||
out FormattedMessage? reason
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#region HumanoidCharacterProfile
|
||||
|
||||
/// <summary>
|
||||
/// Requires the profile to be within an age range
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutAgeRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public int Min;
|
||||
|
||||
[DataField(required: true)]
|
||||
public int Max;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString("loadout-age-requirement",
|
||||
("min", Min), ("max", Max)));
|
||||
return profile.Age >= Min && profile.Age <= Max;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the profile to use either a Backpack, Satchel, or Duffelbag
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutBackpackTypeRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public BackpackPreference Preference;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString("loadout-backpack-type-requirement",
|
||||
("type", Loc.GetString($"humanoid-profile-editor-preference-{Preference.ToString().ToLower()}"))));
|
||||
return profile.Backpack == Preference;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the profile to use either Jumpsuits or Jumpskirts
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutClothingPreferenceRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ClothingPreference Preference;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString("loadout-clothing-preference-requirement",
|
||||
("preference", Loc.GetString($"humanoid-profile-editor-preference-{Preference.ToString().ToLower()}"))));
|
||||
return profile.Clothing == Preference;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the profile to be a certain species
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutSpeciesRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<SpeciesPrototype> Species;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString("loadout-species-requirement",
|
||||
("species", Loc.GetString($"species-name-{Species.ToString().ToLower()}"))));
|
||||
return profile.Species == Species;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the profile to have a certain trait
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutTraitRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<TraitPrototype> Trait;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString("loadout-trait-requirement",
|
||||
("trait", Loc.GetString($"trait-{Trait.ToString().ToLower()}-name"))));
|
||||
return profile.TraitPreferences.Contains(Trait.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Jobs
|
||||
|
||||
/// <summary>
|
||||
/// Requires the selected job to be a certain one
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutJobRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public List<ProtoId<JobPrototype>> Jobs;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
// Join localized job names with a comma
|
||||
var jobsString = string.Join(", ", Jobs.Select(j => Loc.GetString(prototypeManager.Index(j).Name)));
|
||||
// Form the reason message
|
||||
jobsString = Loc.GetString("loadout-job-requirement", ("job", jobsString));
|
||||
|
||||
reason = FormattedMessage.FromMarkup(jobsString);
|
||||
return Jobs.Contains(job.ID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the playtime for a department to be within a certain range
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutDepartmentTimeRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan Min = TimeSpan.MinValue;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan Max = TimeSpan.MaxValue;
|
||||
|
||||
[DataField(required: true)]
|
||||
public ProtoId<DepartmentPrototype> Department;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
// Disable the requirement if the role timers are disabled
|
||||
if (!configManager.GetCVar(CCVars.GameRoleTimers))
|
||||
{
|
||||
reason = null;
|
||||
return !Inverted;
|
||||
}
|
||||
|
||||
var department = prototypeManager.Index(Department);
|
||||
|
||||
// Combine all of this department's job playtimes
|
||||
var playtime = TimeSpan.Zero;
|
||||
foreach (var other in department.Roles)
|
||||
{
|
||||
var proto = prototypeManager.Index<JobPrototype>(other).PlayTimeTracker;
|
||||
|
||||
playTimes.TryGetValue(proto, out var otherTime);
|
||||
playtime += otherTime;
|
||||
}
|
||||
|
||||
if (playtime > Max)
|
||||
{
|
||||
// Show the reason if invalid
|
||||
reason = Inverted
|
||||
? null
|
||||
: FormattedMessage.FromMarkup(Loc.GetString("loadout-timer-department-too-high",
|
||||
("time", playtime.Minutes - Max.Minutes),
|
||||
("department", Loc.GetString($"department-{department.ID}")),
|
||||
("departmentColor", department.Color)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (playtime < Min)
|
||||
{
|
||||
// Show the reason if invalid
|
||||
reason = Inverted
|
||||
? null
|
||||
: FormattedMessage.FromMarkup(Loc.GetString("loadout-timer-department-insufficient",
|
||||
("time", Min.Minutes - playtime.Minutes),
|
||||
("department", Loc.GetString($"department-{department.ID}")),
|
||||
("departmentColor", department.Color)));
|
||||
return false;
|
||||
}
|
||||
|
||||
reason = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the player to have a certain amount of overall job time
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutOverallTimeRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan Min = TimeSpan.MinValue;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan Max = TimeSpan.MaxValue;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
// Disable the requirement if the role timers are disabled
|
||||
if (!configManager.GetCVar(CCVars.GameRoleTimers))
|
||||
{
|
||||
reason = null;
|
||||
return !Inverted;
|
||||
}
|
||||
|
||||
// Get the overall time
|
||||
var overallTime = playTimes.GetValueOrDefault(PlayTimeTrackingShared.TrackerOverall);
|
||||
|
||||
if (overallTime > Max)
|
||||
{
|
||||
// Show the reason if invalid
|
||||
reason = Inverted
|
||||
? null
|
||||
: FormattedMessage.FromMarkup(Loc.GetString("loadout-timer-overall-too-high",
|
||||
("time", overallTime.Minutes - Max.Minutes)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (overallTime < Min)
|
||||
{
|
||||
// Show the reason if invalid
|
||||
reason = Inverted
|
||||
? null
|
||||
: FormattedMessage.FromMarkup(Loc.GetString("loadout-timer-overall-insufficient",
|
||||
("time", Min.Minutes - overallTime.Minutes)));
|
||||
return false;
|
||||
}
|
||||
|
||||
reason = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requires the playtime for a tracker to be within a certain range
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class LoadoutPlaytimeRequirement : LoadoutRequirement
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan Min = TimeSpan.MinValue;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan Max = TimeSpan.MaxValue;
|
||||
|
||||
[DataField(required: true)]
|
||||
public ProtoId<PlayTimeTrackerPrototype> Tracker;
|
||||
|
||||
public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager, IPrototypeManager prototypeManager,
|
||||
IConfigurationManager configManager, out FormattedMessage? reason)
|
||||
{
|
||||
// Disable the requirement if the role timers are disabled
|
||||
if (!configManager.GetCVar(CCVars.GameRoleTimers))
|
||||
{
|
||||
reason = null;
|
||||
return !Inverted;
|
||||
}
|
||||
|
||||
// Get SharedJobSystem
|
||||
if (!entityManager.EntitySysManager.TryGetEntitySystem(out SharedJobSystem? jobSystem))
|
||||
{
|
||||
DebugTools.Assert("LoadoutRequirements: SharedJobSystem not found");
|
||||
reason = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the JobPrototype of the Tracker
|
||||
var trackerJob = jobSystem.GetJobPrototype(Tracker);
|
||||
|
||||
// Get the primary department of the Tracker
|
||||
if (!jobSystem.TryGetPrimaryDepartment(trackerJob, out var department) &&
|
||||
!jobSystem.TryGetDepartment(trackerJob, out department))
|
||||
{
|
||||
DebugTools.Assert($"LoadoutRequirements: Department not found for job {trackerJob}");
|
||||
reason = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the time for the tracker
|
||||
playTimes.TryGetValue(Tracker, out var time);
|
||||
reason = null;
|
||||
|
||||
if (time > Max)
|
||||
{
|
||||
// Show the reason if invalid
|
||||
reason = Inverted
|
||||
? null
|
||||
: FormattedMessage.FromMarkup(Loc.GetString("loadout-timer-role-too-high",
|
||||
("time", time.Minutes - Max.Minutes),
|
||||
("job", trackerJob),
|
||||
("departmentColor", department.Color)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (time < Min)
|
||||
{
|
||||
// Show the reason if invalid
|
||||
reason = Inverted
|
||||
? null
|
||||
: FormattedMessage.FromMarkup(Loc.GetString("loadout-timer-role-insufficient",
|
||||
("time", Min.Minutes - time.Minutes),
|
||||
("job", trackerJob),
|
||||
("departmentColor", department.Color)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
149
Content.Shared/Clothing/Loadouts/Systems/LoadoutSystem.cs
Normal file
149
Content.Shared/Clothing/Loadouts/Systems/LoadoutSystem.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Clothing.Loadouts.Prototypes;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Station;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Clothing.Loadouts.Systems;
|
||||
|
||||
public sealed class LoadoutSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedStationSpawningSystem _station = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LoadoutComponent, MapInitEvent>(OnMapInit);
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, LoadoutComponent component, MapInitEvent args)
|
||||
{
|
||||
if (component.Prototypes == null)
|
||||
return;
|
||||
|
||||
var proto = _prototype.Index<StartingGearPrototype>(_random.Pick(component.Prototypes));
|
||||
_station.EquipStartingGear(uid, proto, null);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc cref="ApplyCharacterLoadout(Robust.Shared.GameObjects.EntityUid,string,Content.Shared.Preferences.HumanoidCharacterProfile,System.Collections.Generic.Dictionary{string,System.TimeSpan}?)"/>
|
||||
public List<EntityUid> ApplyCharacterLoadout(EntityUid uid, string job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan>? playTimes = null)
|
||||
{
|
||||
var jobPrototype = _prototype.Index<JobPrototype>(job);
|
||||
return ApplyCharacterLoadout(uid, jobPrototype, profile, playTimes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equips entities from a <see cref="HumanoidCharacterProfile"/>'s loadout preferences to a given entity
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity to give the loadout items to</param>
|
||||
/// <param name="job">The job to use for loadout whitelist/blacklist (should be the job of the entity)</param>
|
||||
/// <param name="profile">The profile to get loadout items from (should be the entity's, or at least have the same species as the entity)</param>
|
||||
/// <param name="playTimes">Playtime for the player for use with playtime requirements</param>
|
||||
/// <returns>A list of loadout items that couldn't be equipped but passed checks</returns>
|
||||
public List<EntityUid> ApplyCharacterLoadout(EntityUid uid, JobPrototype job, HumanoidCharacterProfile profile,
|
||||
Dictionary<string, TimeSpan>? playTimes = null)
|
||||
{
|
||||
var failedLoadouts = new List<EntityUid>();
|
||||
|
||||
foreach (var loadout in profile.LoadoutPreferences)
|
||||
{
|
||||
var slot = "";
|
||||
|
||||
// Ignore loadouts that don't exist
|
||||
if (!_prototype.TryIndex<LoadoutPrototype>(loadout, out var loadoutProto))
|
||||
continue;
|
||||
|
||||
|
||||
if (!CheckRequirementsValid(loadoutProto.Requirements, job, profile,
|
||||
playTimes ?? new Dictionary<string, TimeSpan>(), EntityManager, _prototype, _configurationManager,
|
||||
out _))
|
||||
continue;
|
||||
|
||||
|
||||
// Spawn the loadout items
|
||||
var spawned = EntityManager.SpawnEntities(
|
||||
EntityManager.GetComponent<TransformComponent>(uid).Coordinates.ToMap(EntityManager),
|
||||
loadoutProto.Items!);
|
||||
|
||||
foreach (var item in spawned)
|
||||
{
|
||||
if (EntityManager.TryGetComponent<ClothingComponent>(item, out var clothingComp) &&
|
||||
_inventory.TryGetSlots(uid, out var slotDefinitions))
|
||||
{
|
||||
var deleted = false;
|
||||
foreach (var curSlot in slotDefinitions)
|
||||
{
|
||||
// If the loadout can't equip here or we've already deleted an item from this slot, skip it
|
||||
if (!clothingComp.Slots.HasFlag(curSlot.SlotFlags) || deleted)
|
||||
continue;
|
||||
|
||||
slot = curSlot.Name;
|
||||
|
||||
// If the loadout is exclusive delete the equipped item
|
||||
if (loadoutProto.Exclusive)
|
||||
{
|
||||
// Get the item in the slot
|
||||
if (!_inventory.TryGetSlotEntity(uid, curSlot.Name, out var slotItem))
|
||||
continue;
|
||||
|
||||
EntityManager.DeleteEntity(slotItem.Value);
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Equip the loadout
|
||||
if (!_inventory.TryEquip(uid, item, slot, true, !string.IsNullOrEmpty(slot), true))
|
||||
failedLoadouts.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Return a list of items that couldn't be equipped so the server can handle it if it wants
|
||||
// The server has more information about the inventory system than the client does and the client doesn't need to put loadouts in backpacks
|
||||
return failedLoadouts;
|
||||
}
|
||||
|
||||
|
||||
public bool CheckRequirementsValid(List<LoadoutRequirement> requirements, JobPrototype job,
|
||||
HumanoidCharacterProfile profile, Dictionary<string, TimeSpan> playTimes, IEntityManager entityManager,
|
||||
IPrototypeManager prototypeManager, IConfigurationManager configManager, out List<FormattedMessage> reasons)
|
||||
{
|
||||
reasons = new List<FormattedMessage>();
|
||||
var valid = true;
|
||||
|
||||
foreach (var requirement in requirements)
|
||||
{
|
||||
// Set valid to false if the requirement is invalid and not inverted, if it's inverted set it to true when it's valid
|
||||
if (!requirement.IsValid(job, profile, playTimes, entityManager, prototypeManager, configManager, out var reason))
|
||||
{
|
||||
if (valid)
|
||||
valid = requirement.Inverted;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (valid)
|
||||
valid = !requirement.Inverted;
|
||||
}
|
||||
|
||||
if (reason != null)
|
||||
{
|
||||
reasons.Add(reason);
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Clothing.Loadouts.Prototypes;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Traits;
|
||||
using Robust.Shared.Configuration;
|
||||
@@ -30,6 +29,7 @@ namespace Content.Shared.Preferences
|
||||
private readonly Dictionary<string, JobPriority> _jobPriorities;
|
||||
private readonly List<string> _antagPreferences;
|
||||
private readonly List<string> _traitPreferences;
|
||||
private readonly List<string> _loadoutPreferences;
|
||||
|
||||
private HumanoidCharacterProfile(
|
||||
string name,
|
||||
@@ -45,7 +45,8 @@ namespace Content.Shared.Preferences
|
||||
Dictionary<string, JobPriority> jobPriorities,
|
||||
PreferenceUnavailableMode preferenceUnavailable,
|
||||
List<string> antagPreferences,
|
||||
List<string> traitPreferences)
|
||||
List<string> traitPreferences,
|
||||
List<string> loadoutPreferences)
|
||||
{
|
||||
Name = name;
|
||||
FlavorText = flavortext;
|
||||
@@ -61,6 +62,7 @@ namespace Content.Shared.Preferences
|
||||
PreferenceUnavailable = preferenceUnavailable;
|
||||
_antagPreferences = antagPreferences;
|
||||
_traitPreferences = traitPreferences;
|
||||
_loadoutPreferences = loadoutPreferences;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor but with overridable references (to prevent useless copies)</summary>
|
||||
@@ -68,15 +70,19 @@ namespace Content.Shared.Preferences
|
||||
HumanoidCharacterProfile other,
|
||||
Dictionary<string, JobPriority> jobPriorities,
|
||||
List<string> antagPreferences,
|
||||
List<string> traitPreferences)
|
||||
: this(other.Name, other.FlavorText, other.Species, other.Age, other.Sex, other.Gender, other.Appearance, other.Clothing, other.Backpack, other.SpawnPriority,
|
||||
jobPriorities, other.PreferenceUnavailable, antagPreferences, traitPreferences)
|
||||
List<string> traitPreferences,
|
||||
List<string> loadoutPreferences)
|
||||
: this(other.Name, other.FlavorText, other.Species, other.Age, other.Sex, other.Gender, other.Appearance,
|
||||
other.Clothing, other.Backpack, other.SpawnPriority, jobPriorities, other.PreferenceUnavailable,
|
||||
antagPreferences, traitPreferences, loadoutPreferences)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor</summary>
|
||||
private HumanoidCharacterProfile(HumanoidCharacterProfile other)
|
||||
: this(other, new Dictionary<string, JobPriority>(other.JobPriorities), new List<string>(other.AntagPreferences), new List<string>(other.TraitPreferences))
|
||||
: this(other, new Dictionary<string, JobPriority>(other.JobPriorities),
|
||||
new List<string>(other.AntagPreferences), new List<string>(other.TraitPreferences),
|
||||
new List<string>(other.LoadoutPreferences))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -94,9 +100,12 @@ namespace Content.Shared.Preferences
|
||||
IReadOnlyDictionary<string, JobPriority> jobPriorities,
|
||||
PreferenceUnavailableMode preferenceUnavailable,
|
||||
IReadOnlyList<string> antagPreferences,
|
||||
IReadOnlyList<string> traitPreferences)
|
||||
: this(name, flavortext, species, age, sex, gender, appearance, clothing, backpack, spawnPriority, new Dictionary<string, JobPriority>(jobPriorities),
|
||||
preferenceUnavailable, new List<string>(antagPreferences), new List<string>(traitPreferences))
|
||||
IReadOnlyList<string> traitPreferences,
|
||||
IReadOnlyList<string> loadoutPreferences)
|
||||
: this(name, flavortext, species, age, sex, gender, appearance, clothing, backpack, spawnPriority,
|
||||
new Dictionary<string, JobPriority>(jobPriorities), preferenceUnavailable,
|
||||
new List<string>(antagPreferences), new List<string>(traitPreferences),
|
||||
new List<string>(loadoutPreferences))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -122,6 +131,7 @@ namespace Content.Shared.Preferences
|
||||
},
|
||||
PreferenceUnavailableMode.SpawnAsOverflow,
|
||||
new List<string>(),
|
||||
new List<string>(),
|
||||
new List<string>())
|
||||
{
|
||||
}
|
||||
@@ -150,6 +160,7 @@ namespace Content.Shared.Preferences
|
||||
},
|
||||
PreferenceUnavailableMode.SpawnAsOverflow,
|
||||
new List<string>(),
|
||||
new List<string>(),
|
||||
new List<string>());
|
||||
}
|
||||
|
||||
@@ -195,11 +206,13 @@ namespace Content.Shared.Preferences
|
||||
|
||||
var name = GetName(species, gender);
|
||||
|
||||
return new HumanoidCharacterProfile(name, "", species, age, sex, gender, HumanoidCharacterAppearance.Random(species, sex), ClothingPreference.Jumpsuit, BackpackPreference.Backpack, SpawnPriorityPreference.None,
|
||||
return new HumanoidCharacterProfile(name, "", species, age, sex, gender,
|
||||
HumanoidCharacterAppearance.Random(species, sex), ClothingPreference.Jumpsuit,
|
||||
BackpackPreference.Backpack, SpawnPriorityPreference.None,
|
||||
new Dictionary<string, JobPriority>
|
||||
{
|
||||
{SharedGameTicker.FallbackOverflowJob, JobPriority.High},
|
||||
}, PreferenceUnavailableMode.StayInLobby, new List<string>(), new List<string>());
|
||||
}, PreferenceUnavailableMode.StayInLobby, new List<string>(), new List<string>(), new List<string>());
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
@@ -225,6 +238,7 @@ namespace Content.Shared.Preferences
|
||||
public IReadOnlyDictionary<string, JobPriority> JobPriorities => _jobPriorities;
|
||||
public IReadOnlyList<string> AntagPreferences => _antagPreferences;
|
||||
public IReadOnlyList<string> TraitPreferences => _traitPreferences;
|
||||
public IReadOnlyList<string> LoadoutPreferences => _loadoutPreferences;
|
||||
public PreferenceUnavailableMode PreferenceUnavailable { get; private set; }
|
||||
|
||||
public HumanoidCharacterProfile WithName(string name)
|
||||
@@ -277,7 +291,8 @@ namespace Content.Shared.Preferences
|
||||
}
|
||||
public HumanoidCharacterProfile WithJobPriorities(IEnumerable<KeyValuePair<string, JobPriority>> jobPriorities)
|
||||
{
|
||||
return new(this, new Dictionary<string, JobPriority>(jobPriorities), _antagPreferences, _traitPreferences);
|
||||
return new(this, new Dictionary<string, JobPriority>(jobPriorities), _antagPreferences, _traitPreferences,
|
||||
_loadoutPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithJobPriority(string jobId, JobPriority priority)
|
||||
@@ -291,7 +306,7 @@ namespace Content.Shared.Preferences
|
||||
{
|
||||
dictionary[jobId] = priority;
|
||||
}
|
||||
return new(this, dictionary, _antagPreferences, _traitPreferences);
|
||||
return new(this, dictionary, _antagPreferences, _traitPreferences, _loadoutPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithPreferenceUnavailable(PreferenceUnavailableMode mode)
|
||||
@@ -301,7 +316,8 @@ namespace Content.Shared.Preferences
|
||||
|
||||
public HumanoidCharacterProfile WithAntagPreferences(IEnumerable<string> antagPreferences)
|
||||
{
|
||||
return new(this, _jobPriorities, new List<string>(antagPreferences), _traitPreferences);
|
||||
return new(this, _jobPriorities, new List<string>(antagPreferences), _traitPreferences,
|
||||
_loadoutPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithAntagPreference(string antagId, bool pref)
|
||||
@@ -321,7 +337,7 @@ namespace Content.Shared.Preferences
|
||||
list.Remove(antagId);
|
||||
}
|
||||
}
|
||||
return new(this, _jobPriorities, list, _traitPreferences);
|
||||
return new(this, _jobPriorities, list, _traitPreferences, _loadoutPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithTraitPreference(string traitId, bool pref)
|
||||
@@ -343,7 +359,28 @@ namespace Content.Shared.Preferences
|
||||
list.Remove(traitId);
|
||||
}
|
||||
}
|
||||
return new(this, _jobPriorities, _antagPreferences, list);
|
||||
return new(this, _jobPriorities, _antagPreferences, list, _loadoutPreferences);
|
||||
}
|
||||
|
||||
public HumanoidCharacterProfile WithLoadoutPreference(string loadoutId, bool pref)
|
||||
{
|
||||
var list = new List<string>(_loadoutPreferences);
|
||||
|
||||
if(pref)
|
||||
{
|
||||
if(!list.Contains(loadoutId))
|
||||
{
|
||||
list.Add(loadoutId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(list.Contains(loadoutId))
|
||||
{
|
||||
list.Remove(loadoutId);
|
||||
}
|
||||
}
|
||||
return new(this, _jobPriorities, _antagPreferences, _traitPreferences, list);
|
||||
}
|
||||
|
||||
public string Summary =>
|
||||
@@ -356,18 +393,21 @@ namespace Content.Shared.Preferences
|
||||
|
||||
public bool MemberwiseEquals(ICharacterProfile maybeOther)
|
||||
{
|
||||
if (maybeOther is not HumanoidCharacterProfile other) return false;
|
||||
if (Name != other.Name) return false;
|
||||
if (Age != other.Age) return false;
|
||||
if (Sex != other.Sex) return false;
|
||||
if (Gender != other.Gender) return false;
|
||||
if (PreferenceUnavailable != other.PreferenceUnavailable) return false;
|
||||
if (Clothing != other.Clothing) return false;
|
||||
if (Backpack != other.Backpack) return false;
|
||||
if (SpawnPriority != other.SpawnPriority) return false;
|
||||
if (!_jobPriorities.SequenceEqual(other._jobPriorities)) return false;
|
||||
if (!_antagPreferences.SequenceEqual(other._antagPreferences)) return false;
|
||||
if (!_traitPreferences.SequenceEqual(other._traitPreferences)) return false;
|
||||
if (maybeOther is not HumanoidCharacterProfile other ||
|
||||
Name != other.Name ||
|
||||
Age != other.Age ||
|
||||
Sex != other.Sex ||
|
||||
Gender != other.Gender ||
|
||||
PreferenceUnavailable != other.PreferenceUnavailable ||
|
||||
Clothing != other.Clothing ||
|
||||
Backpack != other.Backpack ||
|
||||
SpawnPriority != other.SpawnPriority ||
|
||||
!_jobPriorities.SequenceEqual(other._jobPriorities) ||
|
||||
!_antagPreferences.SequenceEqual(other._antagPreferences) ||
|
||||
!_traitPreferences.SequenceEqual(other._traitPreferences) ||
|
||||
!_loadoutPreferences.SequenceEqual(other._loadoutPreferences))
|
||||
return false;
|
||||
|
||||
return Appearance.MemberwiseEquals(other.Appearance);
|
||||
}
|
||||
|
||||
@@ -436,8 +476,8 @@ namespace Content.Shared.Preferences
|
||||
{
|
||||
// This regex replaces the first character of the first and last words of the name with their uppercase version
|
||||
name = Regex.Replace(name,
|
||||
@"^(?<word>\w)|\b(?<word>\w)(?=\w*$)",
|
||||
m => m.Groups["word"].Value.ToUpper());
|
||||
@"^(?<word>\w)|\b(?<word>\w)(?=\w*$)",
|
||||
m => m.Groups["word"].Value.ToUpper());
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(name))
|
||||
@@ -502,8 +542,25 @@ namespace Content.Shared.Preferences
|
||||
.ToList();
|
||||
|
||||
var traits = TraitPreferences
|
||||
.Where(prototypeManager.HasIndex<TraitPrototype>)
|
||||
.ToList();
|
||||
.Where(prototypeManager.HasIndex<TraitPrototype>)
|
||||
.ToList();
|
||||
|
||||
var loadouts = LoadoutPreferences
|
||||
.Where(prototypeManager.HasIndex<LoadoutPrototype>)
|
||||
.ToList();
|
||||
|
||||
var maxLoadouts = configManager.GetCVar(CCVars.GameLoadoutsPoints);
|
||||
var currentLoadouts = 0;
|
||||
|
||||
foreach (var loadout in loadouts.ToList())
|
||||
{
|
||||
var proto = prototypeManager.Index<LoadoutPrototype>(loadout);
|
||||
|
||||
if (currentLoadouts + proto.Cost > maxLoadouts)
|
||||
loadouts.Remove(loadout);
|
||||
else
|
||||
currentLoadouts += proto.Cost;
|
||||
}
|
||||
|
||||
Name = name;
|
||||
FlavorText = flavortext;
|
||||
@@ -529,6 +586,9 @@ namespace Content.Shared.Preferences
|
||||
|
||||
_traitPreferences.Clear();
|
||||
_traitPreferences.AddRange(traits);
|
||||
|
||||
_loadoutPreferences.Clear();
|
||||
_loadoutPreferences.AddRange(loadouts);
|
||||
}
|
||||
|
||||
public ICharacterProfile Validated(IConfigurationManager configManager, IPrototypeManager prototypeManager)
|
||||
@@ -568,7 +628,8 @@ namespace Content.Shared.Preferences
|
||||
PreferenceUnavailable,
|
||||
_jobPriorities,
|
||||
_antagPreferences,
|
||||
_traitPreferences
|
||||
_traitPreferences,
|
||||
_loadoutPreferences
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,8 @@ namespace Content.Shared.Roles
|
||||
[NotNullWhen(false)] out FormattedMessage? reason,
|
||||
IEntityManager entManager,
|
||||
IPrototypeManager prototypes,
|
||||
bool isWhitelisted)
|
||||
bool isWhitelisted,
|
||||
string? localePrefix = "role-timer-")
|
||||
{
|
||||
reason = null;
|
||||
|
||||
@@ -133,7 +134,7 @@ namespace Content.Shared.Roles
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-department-insufficient",
|
||||
$"{localePrefix}department-insufficient",
|
||||
("time", Math.Ceiling(deptDiff)),
|
||||
("department", Loc.GetString(deptRequirement.Department)),
|
||||
("departmentColor", department.Color.ToHex())));
|
||||
@@ -144,7 +145,7 @@ namespace Content.Shared.Roles
|
||||
if (deptDiff <= 0)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-department-too-high",
|
||||
$"{localePrefix}department-too-high",
|
||||
("time", -deptDiff),
|
||||
("department", Loc.GetString(deptRequirement.Department)),
|
||||
("departmentColor", department.Color.ToHex())));
|
||||
@@ -164,7 +165,7 @@ namespace Content.Shared.Roles
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-overall-insufficient",
|
||||
$"{localePrefix}overall-insufficient",
|
||||
("time", Math.Ceiling(overallDiff))));
|
||||
return false;
|
||||
}
|
||||
@@ -172,7 +173,7 @@ namespace Content.Shared.Roles
|
||||
{
|
||||
if (overallDiff <= 0 || overallTime >= overallRequirement.Time)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString("role-timer-overall-too-high", ("time", -overallDiff)));
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString($"{localePrefix}overall-too-high", ("time", -overallDiff)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -200,7 +201,7 @@ namespace Content.Shared.Roles
|
||||
return true;
|
||||
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-role-insufficient",
|
||||
$"{localePrefix}role-insufficient",
|
||||
("time", Math.Ceiling(roleDiff)),
|
||||
("job", Loc.GetString(proto)),
|
||||
("departmentColor", departmentColor.ToHex())));
|
||||
@@ -211,7 +212,7 @@ namespace Content.Shared.Roles
|
||||
if (roleDiff <= 0)
|
||||
{
|
||||
reason = FormattedMessage.FromMarkup(Loc.GetString(
|
||||
"role-timer-role-too-high",
|
||||
$"{localePrefix}role-too-high",
|
||||
("time", -roleDiff),
|
||||
("job", Loc.GetString(proto)),
|
||||
("departmentColor", departmentColor.ToHex())));
|
||||
|
||||
7
Resources/Locale/en-US/loadouts/categories.ftl
Normal file
7
Resources/Locale/en-US/loadouts/categories.ftl
Normal file
@@ -0,0 +1,7 @@
|
||||
# Alphabetically ordered
|
||||
loadout-category-Accessories = Accessories
|
||||
loadout-category-Items = Items
|
||||
loadout-category-Jobs = Jobs
|
||||
loadout-category-Outer = Outer
|
||||
loadout-category-Uncategorized = Uncategorized
|
||||
loadout-category-Uniform = Uniform
|
||||
2
Resources/Locale/en-US/loadouts/eyes.ftl
Normal file
2
Resources/Locale/en-US/loadouts/eyes.ftl
Normal file
@@ -0,0 +1,2 @@
|
||||
loadout-description-LoadoutEyesEyepatch = Eyewear, for the fashionista without an eye.
|
||||
loadout-description-LoadoutEyesBlindfold = Why would you want this?
|
||||
2
Resources/Locale/en-US/loadouts/head.ftl
Normal file
2
Resources/Locale/en-US/loadouts/head.ftl
Normal file
@@ -0,0 +1,2 @@
|
||||
loadout-description-LoadoutHeadBeaverHat = Gentlemen.
|
||||
loadout-description-LoadoutHeadTophat = A stylish black tophat.
|
||||
13
Resources/Locale/en-US/loadouts/items.ftl
Normal file
13
Resources/Locale/en-US/loadouts/items.ftl
Normal file
@@ -0,0 +1,13 @@
|
||||
loadout-description-LoadoutItemCig = Cool guys always have one.
|
||||
loadout-description-LoadoutItemCigsGreen = A pack a day keeps the doctor well-paid!
|
||||
loadout-description-LoadoutItemCigsRed = A pack a day keeps the doctor well-paid!
|
||||
loadout-description-LoadoutItemCigsBlue = A pack a day keeps the doctor well-paid!
|
||||
loadout-description-LoadoutItemCigsBlack = A pack a day keeps the doctor well-paid!
|
||||
loadout-description-LoadoutItemPAI = A little flakey on booting up, but a more loyal friend you won't find.
|
||||
loadout-description-LoadoutItemLighter = A basic lighter.
|
||||
loadout-description-LoadoutItemLighterCheap = A very basic lighter.
|
||||
loadout-description-LoadoutItemMatches = A box of matches.
|
||||
loadout-description-LoadoutItemPlushieSharkBlue = Dive into battle with your very own aquatic ally, the Blue Shark Plushie! It's more cuddly than fierce, but don't underestimate its ability to strike fear into the hearts of your enemies… or at least make them laugh as they're devoured by cuteness overload.
|
||||
loadout-description-LoadoutItemPlushieSharkPink = Unleash the power of pink with the Pink Shark Plushie! This rosy-hued predator might not have real teeth, but its sheer adorableness is enough to take a bite out of anyone's resolve. Watch as foes melt away in the face of its cottony charm.
|
||||
loadout-description-LoadoutItemPlushieSharkGrey = Introducing the Grey Shark Plushie, the apex predator of snuggles! With its sleek and understated design, this plushie strikes the perfect balance between cuddle companion and imaginary ocean guardian. Beware; opponents may be mesmerized by its dorsal fin's hypnotic sway!
|
||||
loadout-description-LoadoutItemPlushieCarp = Brace for extraterrestrial antics with the Purple Space Carp Plushie! A fishy invader from the cosmic deep, this plushie brings a splash of humor to zero-gravity escapades. From hostile waters to interstellar giggles, it's a cuddly contradiction that's out of this world
|
||||
1
Resources/Locale/en-US/loadouts/jobs/cargo.ftl
Normal file
1
Resources/Locale/en-US/loadouts/jobs/cargo.ftl
Normal file
@@ -0,0 +1 @@
|
||||
loadout-description-LoadoutCargoNeckGoliathCloak = For the greatest of the Salvage crew.
|
||||
5
Resources/Locale/en-US/loadouts/jobs/engineering.ftl
Normal file
5
Resources/Locale/en-US/loadouts/jobs/engineering.ftl
Normal file
@@ -0,0 +1,5 @@
|
||||
loadout-name-LoadoutEngineeringChickenSuit = eggmospheric technician suit
|
||||
loadout-description-LoadoutEngineeringChickenSuit = For the Eggmos tech who always knows where home is...
|
||||
loadout-description-LoadoutEngineeringUniformJumpskirtSenior = A skirt fit for the best of the best.
|
||||
loadout-description-LoadoutEngineeringUniformJumpsuitSenior = A suit fit for the best of the best.
|
||||
loadout-description-LoadoutEngineeringItemInflatable = A box containing inflatable walls and doors, for quickly patching up breaches.
|
||||
12
Resources/Locale/en-US/loadouts/jobs/heads/captain.ftl
Normal file
12
Resources/Locale/en-US/loadouts/jobs/heads/captain.ftl
Normal file
@@ -0,0 +1,12 @@
|
||||
loadout-description-LoadoutCommandCapNeckMantle = To show who has the authority around here.
|
||||
loadout-description-LoadoutCommandCapNeckCloak = To really show who has the authority around here.
|
||||
loadout-description-LoadoutCommandCapNeckCloakFormal = More than just to show who has the authority, it also shows who has the greatest fashion sense.
|
||||
loadout-description-LoadoutCommandCapJumpsuitFormal = The outfit is quite fancy. I am curious where the wearer could be heading to justify such a stylish look.
|
||||
loadout-description-LoadoutCommandCapJumpskirtFormal = The outfit is quite fancy. I am curious where the wearer could be heading to justify such a stylish look.
|
||||
loadout-description-LoadoutCommandCapOuterWinter = A warm coat for the cold of space.
|
||||
loadout-description-LoadoutCommandCapGloves = The gloves of the captain. They are very nice gloves.
|
||||
loadout-description-LoadoutCommandCapHat = The hat of the captain. It is a very nice hat.
|
||||
loadout-description-LoadoutCommandCapHatCapcap = The Captain's cap, pretty nice.
|
||||
loadout-description-LoadoutCommandCapHat = The Captain's beret, very nice.
|
||||
loadout-description-LoadoutCommandCapMaskGas = Why would the captain need this? I don't know, but it looks cool.
|
||||
loadout-description-LoadoutCommandCapItemDrinkFlask = The finest of flasks, for the finest of drinks.
|
||||
@@ -0,0 +1,3 @@
|
||||
loadout-description-LoadoutCommandCENeckMantle = To show who has the authority around here. It seems over-engineered.
|
||||
loadout-description-LoadoutCommandCENeckCloak = To really show who has the authority around here. It seems over-engineered.
|
||||
loadout-description-LoadoutCommandCEOuterWinter = A warm coat for the cold of space. It seems over-engineered.
|
||||
@@ -0,0 +1,5 @@
|
||||
loadout-description-LoadoutCommandCMONeckMantle = To show who has the authority around here. It seems unusually clean.
|
||||
loadout-description-LoadoutCommandCMONeckCloak = To really show who has the authority around here. It seems unusually clean.
|
||||
loadout-description-LoadoutCommandCMOOuterWinter = A warm coat for the cold of space. It seems unusually clean.
|
||||
loadout-description-LoadoutCommandCMOOuterLab = A lab coat for the CMO. It seems unusually clean.
|
||||
loadout-description-LoadoutCommandCMOHatBeret = A beret for the CMO. It seems unusually clean.
|
||||
@@ -0,0 +1,4 @@
|
||||
loadout-description-LoadoutCommandHOPNeckMantle = To show who has the authority around here.
|
||||
loadout-description-LoadoutCommandHOPNeckCloak = To really show who has the authority around here.
|
||||
loadout-description-LoadoutCommandHOPBackIan = A backpack that looks like Ian, how cute!
|
||||
loadout-description-LoadoutCommandHOPHatCap = The HOP's cap, pretty nice.
|
||||
@@ -0,0 +1,10 @@
|
||||
loadout-description-LoadoutCommandHOSNeckMantle = To really show who has the authority around here.
|
||||
loadout-description-LoadoutCommandHOSNeckCloak = To truly show who has the authority around here.
|
||||
loadout-description-LoadoutCommandHOSJumpsuitParade = A fancy uniform for a fancy officer, wonder what event they mey be attending.
|
||||
loadout-description-LoadoutCommandHOSJumpsuitFormal = The outfit is quite fancy. I am curious where the wearer could be heading to justify such a stylish look.
|
||||
loadout-description-LoadoutCommandHOSJumpskirtParade = A fancy uniform for a fancy officer, wonder what event they mey be attending.
|
||||
loadout-description-LoadoutCommandHOSJumpskirtFormal = The outfit is quite fancy. I am curious where the wearer could be heading to justify such a stylish look.
|
||||
loadout-description-LoadoutCommandHOSOuterWinter = A warm coat for the cold of space.
|
||||
loadout-description-LoadoutCommandHOSOuterTrench = A trench coat for the HOS.
|
||||
loadout-description-LoadoutCommandHOSHatBeret = A beret for the HOS.
|
||||
loadout-description-LoadoutCommandHOSHatHoshat = The HOS's hat, pretty nice.
|
||||
@@ -0,0 +1,3 @@
|
||||
loadout-description-LoadoutCommandQMNeckMantle = To show who has the authority around here. It's stained with beer.
|
||||
loadout-description-LoadoutCommandQMNeckCloak = To really show who has the authority around here. It's stained with beer. It's stained with beer. It's stained with beer.
|
||||
loadout-description-LoadoutCommandQMHeadSoft = The QM's hat. It's stained with beer.
|
||||
@@ -0,0 +1,3 @@
|
||||
loadout-description-LoadoutCommandRDNeckMantle = To show who has the authority around here.
|
||||
loadout-description-LoadoutCommandRDNeckCloak = To really show who has the authority around here.
|
||||
loadout-description-LoadoutCommandRDOuterWinter = A warm coat for the cold of space.
|
||||
3
Resources/Locale/en-US/loadouts/jobs/medical.ftl
Normal file
3
Resources/Locale/en-US/loadouts/jobs/medical.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
loadout-description-LoadoutMedicalUniformJumpskirtSenior = A skirt fit for the best of the best.
|
||||
loadout-description-LoadoutMedicalUniformJumpsuitSenior = A suit fit for the best of the best.
|
||||
loadout-description-LoadoutMedicalHeadBeretSeniorPhysician = A beret fit for the best of the best.
|
||||
3
Resources/Locale/en-US/loadouts/jobs/science.ftl
Normal file
3
Resources/Locale/en-US/loadouts/jobs/science.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
loadout-description-LoadoutScienceUniformJumpskirtSenior = A skirt fit for the best of the best.
|
||||
loadout-description-LoadoutScienceUniformJumpsuitSenior = A suit fit for the best of the best.
|
||||
loadout-description-LoadoutScienceOuterLabcoatSeniorResearcher = A labcoat fit for the best of the best.
|
||||
3
Resources/Locale/en-US/loadouts/jobs/security.ftl
Normal file
3
Resources/Locale/en-US/loadouts/jobs/security.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
loadout-description-LoadoutSecurityUniformJumpskirtSenior = A skirt fit for the best of the best.
|
||||
loadout-description-LoadoutSecurityUniformJumpsuitSenior = A suit fit for the best of the best.
|
||||
loadout-description-LoadoutSecurityShoesJackboots = A really nice, heavy, pair of black boots.
|
||||
7
Resources/Locale/en-US/loadouts/jobs/service.ftl
Normal file
7
Resources/Locale/en-US/loadouts/jobs/service.ftl
Normal file
@@ -0,0 +1,7 @@
|
||||
loadout-description-LoadoutServiceClownUniformJesterAlt = For the fool who knows their place.
|
||||
loadout-description-LoadoutServiceClownShoesJester = For the fool who knows their place.
|
||||
loadout-description-LoadoutServiceClownHeadJesterHatAlt = For the fool who knows their place.
|
||||
loadout-description-LoadoutServiceBotanistUniformOveralls = A rugged pair of overalls.
|
||||
loadout-description-LoadoutServiceReporterUniformJournalist = For the reporter on the case!
|
||||
loadout-description-LoadoutServiceReporterUniformDetectivesuit = Always reminds you of the one that got away...
|
||||
loadout-description-LoadoutServiceReporterUniformDetectiveskirt = Always reminds you of the one that got away...
|
||||
13
Resources/Locale/en-US/loadouts/loadout-requirements.ftl
Normal file
13
Resources/Locale/en-US/loadouts/loadout-requirements.ftl
Normal file
@@ -0,0 +1,13 @@
|
||||
loadout-age-requirement = You must be within {$min} and {$max} years old
|
||||
loadout-species-requirement = You must be a {$species}
|
||||
loadout-trait-requirement = You must have the trait {$trait}
|
||||
loadout-backpack-type-requirement = You must use a {$type} as your bag
|
||||
loadout-clothing-preference-requirement = You must wear a {$type}
|
||||
|
||||
loadout-job-requirement = You must be one of these jobs: {$job}
|
||||
loadout-timer-department-insufficient = You require [color=yellow]{TOSTRING($time, "0")}[/color] more minutes of [color={$departmentColor}]{$department}[/color] department playtime
|
||||
loadout-timer-department-too-high = You require [color=yellow]{TOSTRING($time, "0")}[/color] fewer minutes in [color={$departmentColor}]{$department}[/color] department
|
||||
loadout-timer-overall-insufficient = You require [color=yellow]{TOSTRING($time, "0")}[/color] more minutes of playtime
|
||||
loadout-timer-overall-too-high = You require [color=yellow]{TOSTRING($time, "0")}[/color] fewer minutes of playtime
|
||||
loadout-timer-role-insufficient = You require [color=yellow]{TOSTRING($time, "0")}[/color] more minutes with [color={$departmentColor}]{$job}[/color]
|
||||
loadout-timer-role-too-high = You require[color=yellow] {TOSTRING($time, "0")}[/color] fewer minutes with [color={$departmentColor}]{$job}[/color]
|
||||
0
Resources/Locale/en-US/loadouts/neck.ftl
Normal file
0
Resources/Locale/en-US/loadouts/neck.ftl
Normal file
5
Resources/Locale/en-US/loadouts/outerClothing.ftl
Normal file
5
Resources/Locale/en-US/loadouts/outerClothing.ftl
Normal file
@@ -0,0 +1,5 @@
|
||||
loadout-description-LoadoutOuterGhostSheet = Spooky...
|
||||
loadout-description-LoadoutOuterCoatBomberjacket = A sleek bomber jacket.
|
||||
loadout-description-LoadoutOuterCoatHoodieBlack = A warm hoodie.
|
||||
loadout-description-LoadoutOuterCoatHoodieGrey = A warm hoodie.
|
||||
loadout-description-LoadoutOuterCoatWinterCoat = For keeping nice and snug.
|
||||
10
Resources/Locale/en-US/loadouts/shoes.ftl
Normal file
10
Resources/Locale/en-US/loadouts/shoes.ftl
Normal file
@@ -0,0 +1,10 @@
|
||||
loadout-description-LoadoutShoesBlack = Step into the shadows with these sleek and stylish black shoes, perfect for ninjas or anyone looking to leave an enigmatic impression.
|
||||
loadout-description-LoadoutShoesBlue = From zero-gravity dance floors to orbital adventures, these kicks are ready to make your journey as vibrant as the cosmos.
|
||||
loadout-description-LoadoutShoesBrown = Classic and reliable, these brown shoes are like your trusted sidekick on any adventure.
|
||||
loadout-description-LoadoutShoesGreen = Embrace the essence of nature with these green shoes. Slip them on, and let the world become your lush and vibrant playground.
|
||||
loadout-description-LoadoutShoesOrange = Gear up for high-octane thrills on the space station with these vivid orange shoes.
|
||||
loadout-description-LoadoutShoesPurple = Step into the unknown with the allure of these purple shoes. Channel the mystique of space as you stroll through the station's enigmatic sectors, leaving an air of intrigue in your wake.
|
||||
loadout-description-LoadoutShoesRed = Embrace the spirit of exploration with these bold red shoes that mirror the pioneering heart of the space station's inhabitants. These shoes are not just for walking; they're a declaration of your relentless determination.
|
||||
loadout-description-LoadoutShoesWhite = Elevate your style with these pristine white shoes, a symbol of innovation and progress.
|
||||
loadout-description-LoadoutShoesYellow = Light up the space station with these radiant yellow shoes, bringing a burst of energy to your every step.
|
||||
loadout-description-LoadoutShoesSlippersDuck = Quack up your downtime with these adorable duck slippers that waddle the line between comfort and quirkiness.
|
||||
1
Resources/Locale/en-US/loadouts/uniform.ftl
Normal file
1
Resources/Locale/en-US/loadouts/uniform.ftl
Normal file
@@ -0,0 +1 @@
|
||||
loadout-description-LoadoutUniformAncientJumpsuit = The legend of the Greytide.
|
||||
@@ -3,6 +3,7 @@ humanoid-profile-editor-name-label = Name:
|
||||
humanoid-profile-editor-name-random-button = Randomize
|
||||
humanoid-profile-editor-appearance-tab = Appearance
|
||||
humanoid-profile-editor-clothing = Show clothing
|
||||
humanoid-profile-editor-loadouts = Show loadout
|
||||
humanoid-profile-editor-clothing-show = Show
|
||||
humanoid-profile-editor-sex-label = Sex:
|
||||
humanoid-profile-editor-sex-male-text = Male
|
||||
@@ -49,5 +50,14 @@ humanoid-profile-editor-job-priority-medium-button = Medium
|
||||
humanoid-profile-editor-job-priority-low-button = Low
|
||||
humanoid-profile-editor-job-priority-never-button = Never
|
||||
humanoid-profile-editor-naming-rules-warning = Warning: Offensive or LRP IC names and descriptions will lead to admin intervention on this server. Read our \[Rules\] for more.
|
||||
humanoid-profile-editor-loadouts-tab = Loadout
|
||||
humanoid-profile-editor-loadouts-uncategorized-tab = Uncategorized
|
||||
humanoid-profile-editor-loadouts-no-loadouts = No loadouts found
|
||||
humanoid-profile-editor-loadouts-points-label = You have {$points}/{$max} points
|
||||
humanoid-profile-editor-loadouts-show-unusable-button = Show Unusable
|
||||
humanoid-profile-editor-loadouts-show-unusable-button-tooltip =
|
||||
When enabled, loadouts that your current character setup cannot use will be shown highlighted in red.
|
||||
You will still not be able to use the invalid loadouts unless your character setup changes to fit the requirements.
|
||||
This may be useful if you like switching between multiple jobs and don't want to have to reselect your loadout every time.
|
||||
humanoid-profile-editor-markings-tab = Markings
|
||||
humanoid-profile-editor-flavortext-tab = Description
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
- id: SpaceCashLuckyBill # DeltaV - LO steal objective, see Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml
|
||||
- id: BoxPDACargo # Delta-V
|
||||
- id: QuartermasterIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterLogisticsOfficer #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -36,7 +35,6 @@
|
||||
- id: PinpointerNuclear
|
||||
# - id: CaptainIDCard # DeltaV - Replaced by the spare ID system
|
||||
- id: ClothingOuterHardsuitCap
|
||||
- id: ClothingMaskGasCaptain
|
||||
- id: WeaponDisabler
|
||||
- id: CommsComputerCircuitboard
|
||||
- id: ClothingHeadsetAltCommand
|
||||
@@ -51,10 +49,6 @@
|
||||
# - id: WeaponAntiqueLaser # DeltaV - Remove in favor of the glass box
|
||||
- id: JetpackCaptainFilled
|
||||
- id: MedalCase
|
||||
- id: ClothingHeadHatBeretCap # Nyanotrasen - Captain's Beret
|
||||
- id: ClothingShoesLeather # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesMiscWhite # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesBootsWinterCap #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -84,9 +78,6 @@
|
||||
- id: JetpackCaptainFilled
|
||||
- id: MedalCase
|
||||
- id: ClothingHeadHatBeretCap # Nyanotrasen - Captain's Beret
|
||||
- id: ClothingShoesLeather # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesMiscWhite # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesBootsWinterCap #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -115,9 +106,6 @@
|
||||
- id: JetpackCaptainFilled
|
||||
- id: MedalCase
|
||||
- id: ClothingHeadHatBeretCap # Nyanotrasen - Captain's Beret
|
||||
- id: ClothingShoesLeather # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesMiscWhite # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesBootsWinterCap #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -137,7 +125,6 @@
|
||||
- id: WeaponDisabler
|
||||
- id: ClothingOuterCoatHoPArmored # DeltaV
|
||||
- id: ClothingOuterArmorDuraVest # DeltaV - replaced HoP's armoured coat with a standard stabproof, pending HoPcoat resprite
|
||||
- id: ClothingOuterCoatHoPFormal # DeltaV - formal jacket
|
||||
- id: CigarGoldCase
|
||||
prob: 0.25
|
||||
# Fuck the HoP they don't deserve fucking cigars.
|
||||
@@ -147,17 +134,9 @@
|
||||
- id: RubberStampHop
|
||||
- id: BoxEncryptionKeyPassenger
|
||||
- id: BoxEncryptionKeyService
|
||||
- id: ClothingBackpackIan
|
||||
prob: 0.5
|
||||
- id: AccessConfigurator
|
||||
- id: BookIanDossier # DeltaV - HoP steal objective, see Resources/Prototypes/DeltaV/Entities/Objects/Misc/ian_dossier.yml
|
||||
- id: ClothingHandsGlovesInspection # DeltaV - Add inspection gloves for HoP.
|
||||
- id: ClothingUniformJumpsuitHoPMess # DeltaV - Add mess kit for HoP.
|
||||
- id: ClothingUniformJumpskirtHoPMess # DeltaV - Add mess kit for HoP.
|
||||
- id: ClothingUniformJumpsuitBoatswain # DeltaV - Add turtleneck for HoP.
|
||||
- id: ClothingShoesBootsLaceup # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesMiscWhite # DeltaV - add fancy shoes for HoP and cap
|
||||
- id: ClothingShoesBootsWinterHeadOfPersonel #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -186,7 +165,6 @@
|
||||
- id: RCD
|
||||
- id: RCDAmmo
|
||||
- id: CEIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterChiefEngineer #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -209,7 +187,6 @@
|
||||
- id: AccessConfigurator
|
||||
- id: BoxPDAEngineering # Delta-V
|
||||
- id: CEIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterChiefEngineer #Delta V: Add departmental winter boots
|
||||
- id: RCD
|
||||
- id: RCDAmmo
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
@@ -226,7 +203,6 @@
|
||||
- id: ClothingHandsGlovesNitrile
|
||||
- id: ClothingEyesHudMedical
|
||||
- id: ClothingHeadsetAltMedical
|
||||
- id: ClothingCloakCmo
|
||||
- id: ClothingBackpackDuffelSurgeryFilled
|
||||
- id: ClothingMaskSterile
|
||||
- id: ClothingHeadHatBeretCmo
|
||||
@@ -241,7 +217,6 @@
|
||||
- id: BoxPDAMedical # Delta-V
|
||||
- id: ClothingBeltMilitaryWebbingCMO # DeltaV - add webbing for CMO. ON THIS STATION, IT'S DRIP OR [die], CAPTAIN!
|
||||
- id: CMOIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterChiefMedicalOfficer #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -257,7 +232,6 @@
|
||||
- id: ClothingEyesHudMedical
|
||||
- id: ClothingHeadsetAltMedical
|
||||
- id: ClothingBackpackDuffelSurgeryFilled
|
||||
- id: ClothingMaskSterile
|
||||
- id: Hypospray
|
||||
- id: HandheldCrewMonitor
|
||||
- id: DoorRemoteMedical
|
||||
@@ -267,7 +241,6 @@
|
||||
- id: BoxPDAMedical # Delta-V
|
||||
- id: ClothingBeltMilitaryWebbingCMO # DeltaV - add webbing for CMO. ON THIS STATION, IT'S DRIP OR [die], CAPTAIN!
|
||||
- id: CMOIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterChiefMedicalOfficer #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -289,7 +262,6 @@
|
||||
- id: BoxEncryptionKeyScience
|
||||
- id: BoxPDAScience # Delta-V
|
||||
- id: RDIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterMystagogue #Delta V: Add departmental winter boots
|
||||
- id: ClothingHeadsetAltScience
|
||||
- id: EncryptionKeyBinary
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
@@ -312,7 +284,6 @@
|
||||
- id: BoxEncryptionKeyScience
|
||||
- id: BoxPDAScience # Delta-V
|
||||
- id: RDIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterMystagogue #Delta V: Add departmental winter boots
|
||||
- id: ClothingHeadsetAltScience
|
||||
- id: EncryptionKeyBinary
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
@@ -330,7 +301,6 @@
|
||||
- id: ClothingOuterCoatHoSTrench
|
||||
- id: ClothingMaskNeckGaiter
|
||||
- id: ClothingOuterHardsuitCombatHoS # DeltaV - ClothingOuterHardsuitSecurityRed replaced in favour of head of security's advanced combat hardsuit.
|
||||
- id: ClothingMaskGasSwat
|
||||
- id: ClothingBeltSecurityFilled
|
||||
- id: ClothingHeadsetAltSecurity
|
||||
- id: ClothingEyesGlassesSunglasses
|
||||
@@ -347,7 +317,6 @@
|
||||
- id: BoxPDASecurity # Delta-V
|
||||
- id: WeaponEnergyGunMultiphase # DeltaV - HoS Energy Gun
|
||||
- id: HoSIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterHeadOfSecurity #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
@@ -377,7 +346,6 @@
|
||||
- id: BoxPDASecurity # Delta-V
|
||||
- id: WeaponEnergyGunMultiphase # DeltaV - HoS Energy Gun
|
||||
- id: HoSIDCard # Delta-V
|
||||
- id: ClothingShoesBootsWinterHeadOfSecurity #Delta V: Add departmental winter boots
|
||||
- id: LunchboxCommandFilledRandom # Delta-V Lunchboxes!
|
||||
prob: 0.3
|
||||
|
||||
|
||||
148
Resources/Prototypes/Loadouts/Jobs/Heads/captain.yml
Normal file
148
Resources/Prototypes/Loadouts/Jobs/Heads/captain.yml
Normal file
@@ -0,0 +1,148 @@
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapNeckMantle
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingNeckMantleCap
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapNeckCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingNeckCloakCap
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapNeckCloakFormal
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingNeckCloakCapFormal
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapJumpsuitFormal
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingUniformJumpsuitCapFormal
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapJumpskirtFormal
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingUniformJumpskirtCapFormalDress
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapOuterWinter
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingOuterWinterCap
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapGloves
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingHandsGlovesCaptain
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapHat
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingHeadHatCaptain
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapHatCapcap
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingHeadHatCapcap
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapHatBeret
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingHeadHatBeretCap
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapMaskGas
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingMaskGasCaptain
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapShoesBootsWinter
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- ClothingShoesBootsWinterCap
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCapItemDrinkFlask
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Captain
|
||||
items:
|
||||
- DrinkFlask
|
||||
46
Resources/Prototypes/Loadouts/Jobs/Heads/chiefEngineer.yml
Normal file
46
Resources/Prototypes/Loadouts/Jobs/Heads/chiefEngineer.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
- type: loadout
|
||||
id: LoadoutCommandCENeckMantle
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefEngineer
|
||||
items:
|
||||
- ClothingNeckMantleCE
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCENeckCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefEngineer
|
||||
items:
|
||||
- ClothingNeckCloakCe
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCEOuterWinter
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefEngineer
|
||||
items:
|
||||
- ClothingOuterWinterCE
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCEShoesBootsWinter
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefEngineer
|
||||
items:
|
||||
- ClothingShoesBootsWinterChiefEngineer
|
||||
@@ -0,0 +1,68 @@
|
||||
- type: loadout
|
||||
id: LoadoutCommandCMONeckMantle
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingNeckMantleCMO
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCMONeckCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingCloakCmo
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCMOOuterWinter
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingOuterWinterCMO
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCMOOuterLab
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingOuterCoatLabCmo
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCMOHatBeret
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingHeadHatBeretCmo
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandCMOShoesBootsWinter
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingShoesBootsWinterChiefMedicalOfficer
|
||||
104
Resources/Prototypes/Loadouts/Jobs/Heads/headOfPersonnel.yml
Normal file
104
Resources/Prototypes/Loadouts/Jobs/Heads/headOfPersonnel.yml
Normal file
@@ -0,0 +1,104 @@
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPNeckMantle
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingNeckMantleHOP
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPNeckCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingNeckCloakHop
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPJumpsuitTurtleneckBoatswain
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingUniformJumpsuitBoatswain
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPJumpsuitMess
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingUniformJumpsuitHoPMess
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPJumpskirtMess
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingUniformJumpskirtHoPMess
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutcommandHOPOuterCoatFormal
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingOuterCoatHoPFormal
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPBackIan
|
||||
category: Jobs
|
||||
cost: 4
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingBackpackIan
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPHatCap
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingHeadHatHopcap
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOPShoesBootsWinter
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfPersonnel
|
||||
items:
|
||||
- ClothingShoesBootsWinterHeadOfPersonel
|
||||
175
Resources/Prototypes/Loadouts/Jobs/Heads/headOfSecurity.yml
Normal file
175
Resources/Prototypes/Loadouts/Jobs/Heads/headOfSecurity.yml
Normal file
@@ -0,0 +1,175 @@
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSNeckMantle
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingNeckMantleHOS
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSNeckCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingNeckCloakHos
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpsuitAlt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpsuitHoSAlt
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpsuitBlue
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpsuitHoSBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpsuitGrey
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpsuitHoSGrey
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpsuitParade
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpsuitHoSParadeMale
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpsuitFormal
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpsuitHosFormal
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpskirtAlt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpskirtHoSAlt
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpskirtParade
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpskirtHoSParadeMale
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSJumpskirtFormal
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingUniformJumpskirtHosFormal
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSOuterWinter
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingOuterWinterHoS
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSOuterTrench
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingOuterCoatHoSTrench
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSHatBeret
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingHeadHatBeretHoS
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSHatHoshat
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingHeadHatHoshat
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandHOSShoesBootsWinter
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingShoesBootsWinterHeadOfSecurity
|
||||
71
Resources/Prototypes/Loadouts/Jobs/Heads/quarterMaster.yml
Normal file
71
Resources/Prototypes/Loadouts/Jobs/Heads/quarterMaster.yml
Normal file
@@ -0,0 +1,71 @@
|
||||
# What? This isn't a thing?? :(
|
||||
# - type: loadout
|
||||
# id: LoadoutCommandQMNeckMantle
|
||||
# category: Jobs
|
||||
# cost: 2
|
||||
# exclusive: true
|
||||
# requirements:
|
||||
# - !type:LoadoutJobRequirement
|
||||
# jobs:
|
||||
# - Quartermaster
|
||||
# items:
|
||||
# - ClothingNeckMantleQM
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandQMNeckCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Quartermaster
|
||||
items:
|
||||
- ClothingNeckCloakQm
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandQMUniformTurtleneck
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Quartermaster
|
||||
items:
|
||||
- ClothingUniformJumpsuitQMTurtleneck
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandQMUniformTurtleneckSkirt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Quartermaster
|
||||
items:
|
||||
- ClothingUniformJumpskirtQMTurtleneck
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandQMHeadSoft
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Quartermaster
|
||||
items:
|
||||
- ClothingHeadHatQMsoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandQMShoesBootsWinter
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Quartermaster
|
||||
items:
|
||||
- ClothingShoesBootsWinterLogisticsOfficer
|
||||
@@ -0,0 +1,57 @@
|
||||
- type: loadout
|
||||
id: LoadoutCommandRDNeckMantle
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingNeckMantleRD
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandRDNeckCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingNeckCloakRd
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandRDOuterWinter
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingOuterWinterRD
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandRDOuterMysta
|
||||
category: Jobs
|
||||
cost: 2
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingOuterCoatRndMysta
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutCommandRDShoesBootsWinter
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingShoesBootsWinterMystagogue
|
||||
14
Resources/Prototypes/Loadouts/Jobs/cargo.yml
Normal file
14
Resources/Prototypes/Loadouts/Jobs/cargo.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
- type: loadout
|
||||
id: LoadoutCargoNeckGoliathCloak
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- SalvageSpecialist
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobSalvageSpecialist
|
||||
min: 36000 # 10 hours
|
||||
items:
|
||||
- ClothingNeckCloakGoliathCloak
|
||||
170
Resources/Prototypes/Loadouts/Jobs/engineering.yml
Normal file
170
Resources/Prototypes/Loadouts/Jobs/engineering.yml
Normal file
@@ -0,0 +1,170 @@
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringUniformHazard
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
items:
|
||||
- ClothingUniformJumpsuitEngineeringHazard
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringOuterHazard
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
items:
|
||||
- ClothingOuterVestHazard
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringUniformJumpskirtSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobAtmosphericTechnician
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobStationEngineer
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Engineering
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpskirtSeniorEngineer
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringUniformJumpsuitSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobAtmosphericTechnician
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobStationEngineer
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Engineering
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpsuitSeniorEngineer
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringChickenSuit # :)
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- AtmosphericTechnician
|
||||
items:
|
||||
- ClothingOuterSuitChicken
|
||||
- ClothingHeadHatChickenhead
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringEyesMeson
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- AtmosphericTechnician
|
||||
items:
|
||||
- ClothingEyesGlassesMeson
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringHeadBeret
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- AtmosphericTechnician
|
||||
- ChiefEngineer
|
||||
items:
|
||||
- ClothingHeadHatBeretEngineering
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringHeadHardhatBlue
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- AtmosphericTechnician
|
||||
items:
|
||||
- ClothingHeadHatHardhatBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringHeadHardhatOrange
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- AtmosphericTechnician
|
||||
items:
|
||||
- ClothingHeadHatHardhatOrange
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringHeadHardhatYellow
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- AtmosphericTechnician
|
||||
items:
|
||||
- ClothingHeadHatHardhatYellow
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringHeadHardhatWhite
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- AtmosphericTechnician
|
||||
items:
|
||||
- ClothingHeadHatHardhatWhite
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEngineeringHeadHardhatRed
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- StationEngineer
|
||||
- AtmosphericTechnician
|
||||
items:
|
||||
- ClothingHeadHatHardhatRed
|
||||
197
Resources/Prototypes/Loadouts/Jobs/medical.yml
Normal file
197
Resources/Prototypes/Loadouts/Jobs/medical.yml
Normal file
@@ -0,0 +1,197 @@
|
||||
- type: loadout
|
||||
id: LoadoutMedicalGlovesNitrile
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
- Paramedic
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingHandsGlovesNitrile
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalOuterLabcoat
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
- Chemist
|
||||
items:
|
||||
- ClothingOuterCoatLab
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalNeckStethoscope
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
- ChiefMedicalOfficer
|
||||
items:
|
||||
- ClothingNeckStethoscope
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalUniformScrubsBlue
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
items:
|
||||
- UniformScrubsColorBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalUniformScrubsGreen
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
items:
|
||||
- UniformScrubsColorGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalUniformScrubsPurple
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
items:
|
||||
- UniformScrubsColorPurple
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalOuterLabcoatChem
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Chemist
|
||||
items:
|
||||
- ClothingOuterCoatLabChem
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalItemHandLabeler
|
||||
category: Jobs
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Chemist
|
||||
items:
|
||||
- HandLabeler
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalUniformParamedicJumpsuit
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Paramedic
|
||||
items:
|
||||
- ClothingUniformJumpsuitParamedic
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalUniformParamedicJumpskirt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Paramedic
|
||||
items:
|
||||
- ClothingUniformJumpskirtParamedic
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalUniformJumpskirtSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobChemist
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobMedicalDoctor
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Medical
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpskirtSeniorPhysician
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalUniformJumpsuitSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobChemist
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobMedicalDoctor
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Medical
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpsuitSeniorPhysician
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalHeadNurse
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
items:
|
||||
- ClothingHeadNurseHat
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutMedicalHeadBeretSeniorPhysician
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- MedicalDoctor
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobChemist
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobMedicalDoctor
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Medical
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingHeadHatBeretSeniorPhysician
|
||||
86
Resources/Prototypes/Loadouts/Jobs/science.yml
Normal file
86
Resources/Prototypes/Loadouts/Jobs/science.yml
Normal file
@@ -0,0 +1,86 @@
|
||||
- type: loadout
|
||||
id: LoadoutScienceUniformJumpskirtSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Scientist
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Epistemics
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpskirtSeniorResearcher
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutScienceUniformJumpsuitSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Scientist
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Epistemics
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpsuitSeniorResearcher
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutScienceOuterCoat
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Scientist
|
||||
- ResearchAssistant
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingOuterCoatRnd
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutScienceOuterLabcoat
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Scientist
|
||||
- ResearchAssistant
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingOuterCoatLab
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutScienceOuterLabcoatSeniorResearcher
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Scientist
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Epistemics
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingOuterCoatLabSeniorResearcher
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutScienceHatBeret
|
||||
category: Jobs
|
||||
cost: 1
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Scientist
|
||||
- ResearchAssistant
|
||||
- ResearchDirector
|
||||
items:
|
||||
- ClothingHeadHatBeretRND
|
||||
89
Resources/Prototypes/Loadouts/Jobs/security.yml
Normal file
89
Resources/Prototypes/Loadouts/Jobs/security.yml
Normal file
@@ -0,0 +1,89 @@
|
||||
- type: loadout
|
||||
id: LoadoutSecurityUniformGrey
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- SecurityOfficer
|
||||
- SecurityCadet
|
||||
- Warden
|
||||
items:
|
||||
- ClothingUniformJumpsuitSecGrey
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutSecurityUniformJumpskirtSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- SecurityOfficer
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobWarden
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobDetective
|
||||
min: 7200 # 2 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobSecurityOfficer
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Security
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpskirtSeniorOfficer
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutSecurityUniformJumpsuitSenior
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- SecurityOfficer
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobWarden
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobDetective
|
||||
min: 7200 # 2 hours
|
||||
- !type:LoadoutPlaytimeRequirement
|
||||
tracker: JobSecurityOfficer
|
||||
min: 21600 # 6 hours
|
||||
- !type:LoadoutDepartmentTimeRequirement
|
||||
department: Security
|
||||
min: 216000 # 60 hours
|
||||
items:
|
||||
- ClothingUniformJumpsuitSeniorOfficer
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutSecurityMaskGasSwat
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Warden
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingMaskGasSwat
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutSecurityShoesJackboots
|
||||
category: Jobs
|
||||
cost: 1
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Detective
|
||||
- SecurityOfficer
|
||||
- SecurityCadet
|
||||
- Warden
|
||||
- HeadOfSecurity
|
||||
items:
|
||||
- ClothingShoesBootsJack
|
||||
183
Resources/Prototypes/Loadouts/Jobs/service.yml
Normal file
183
Resources/Prototypes/Loadouts/Jobs/service.yml
Normal file
@@ -0,0 +1,183 @@
|
||||
- type: loadout
|
||||
id: LoadoutServiceClownOutfitJester
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Clown
|
||||
items:
|
||||
- ClothingUniformJumpsuitJester
|
||||
- ClothingHeadHatJester
|
||||
- ClothingShoesJester
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceClownOutfitJesterAlt
|
||||
category: Jobs
|
||||
cost: 3
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Clown
|
||||
items:
|
||||
- ClothingUniformJumpsuitJesterAlt
|
||||
- ClothingHeadHatJesterAlt
|
||||
- ClothingShoesJester
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceBartenderUniformPurple
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Bartender
|
||||
items:
|
||||
- ClothingUniformJumpsuitBartenderPurple
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceBotanistUniformOveralls
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Botanist
|
||||
items:
|
||||
- ClothingUniformOveralls
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformBlueSuit
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpsuitLawyerBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformBlueSkirt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpskirtLawyerBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformRedSuit
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpsuitLawyerRed
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformRedSkirt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpskirtLawyerRed
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformPurpleSuit
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpsuitLawyerPurple
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformPurpleSkirt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpskirtLawyerPurple
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformGoodSuit
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpsuitLawyerGood
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceLawyerUniformGoodSkirt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Lawyer
|
||||
items:
|
||||
- ClothingUniformJumpskirtLawyerGood
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceReporterUniformJournalist
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Reporter
|
||||
items:
|
||||
- ClothingUniformJumpsuitJournalist
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceReporterUniformDetectivesuit
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Reporter
|
||||
items:
|
||||
- ClothingUniformJumpsuitDetective
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutServiceReporterUniformDetectiveskirt
|
||||
category: Jobs
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Reporter
|
||||
items:
|
||||
- ClothingUniformJumpskirtDetective
|
||||
18
Resources/Prototypes/Loadouts/categories.yml
Normal file
18
Resources/Prototypes/Loadouts/categories.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Alphabetically ordered
|
||||
- type: loadoutCategory
|
||||
id: Accessories
|
||||
|
||||
- type: loadoutCategory
|
||||
id: Items
|
||||
|
||||
- type: loadoutCategory
|
||||
id: Jobs
|
||||
|
||||
- type: loadoutCategory
|
||||
id: Outer
|
||||
|
||||
- type: loadoutCategory
|
||||
id: Uncategorized
|
||||
|
||||
- type: loadoutCategory
|
||||
id: Uniform
|
||||
13
Resources/Prototypes/Loadouts/eyes.yml
Normal file
13
Resources/Prototypes/Loadouts/eyes.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
- type: loadout
|
||||
id: LoadoutEyesEyepatch
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingEyesEyepatch
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutEyesBlindfold
|
||||
category: Accessories
|
||||
cost: 2
|
||||
items:
|
||||
- ClothingEyesBlindfold
|
||||
125
Resources/Prototypes/Loadouts/head.yml
Normal file
125
Resources/Prototypes/Loadouts/head.yml
Normal file
@@ -0,0 +1,125 @@
|
||||
- type: loadout
|
||||
id: LoadoutHeadBeaverHat
|
||||
category: Accessories
|
||||
cost: 2
|
||||
items:
|
||||
- ClothingHeadHatBeaverHat
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadTophat
|
||||
category: Accessories
|
||||
cost: 2
|
||||
items:
|
||||
- ClothingHeadHatTophat
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatBluesoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatBluesoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatBluesoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatBluesoftFlipped
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatCorpsoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatCorpsoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatCorpsoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatCorpsoftFlipped
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatGreensoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatGreensoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatGreensoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatGreensoftFlipped
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatGreysoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatGreysoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatGreysoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatGreysoftFlipped
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatOrangesoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatOrangesoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatOrangesoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatOrangesoftFlipped
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatPurplesoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatPurplesoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatPurplesoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatPurplesoftFlipped
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatRedsoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatRedsoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatRedsoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatRedsoftFlipped
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatYellowsoft
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatYellowsoft
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutHeadHatYellowsoftFlipped
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingHeadHatYellowsoftFlipped
|
||||
90
Resources/Prototypes/Loadouts/items.yml
Normal file
90
Resources/Prototypes/Loadouts/items.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
- type: loadout
|
||||
id: LoadoutItemCig
|
||||
category: Items
|
||||
cost: 1
|
||||
items:
|
||||
- Cigarette
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemCigsGreen
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- CigPackGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemCigsRed
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- CigPackRed
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemCigsBlue
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- CigPackBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemCigsBlack
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- CigPackBlack
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemPAI
|
||||
category: Items
|
||||
cost: 3
|
||||
items:
|
||||
- PersonalAI
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemLighter
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- Lighter
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemLighterCheap
|
||||
category: Items
|
||||
cost: 1
|
||||
items:
|
||||
- CheapLighter
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemMatches
|
||||
category: Items
|
||||
cost: 1
|
||||
items:
|
||||
- Matchbox
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemPlushieSharkBlue
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- PlushieSharkBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemPlushieSharkPink
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- PlushieSharkPink
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemPlushieSharkGrey
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- PlushieSharkGrey
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutItemPlushieCarp
|
||||
category: Items
|
||||
cost: 2
|
||||
items:
|
||||
- PlushieCarp
|
||||
27
Resources/Prototypes/Loadouts/neck.yml
Normal file
27
Resources/Prototypes/Loadouts/neck.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
- type: loadout
|
||||
id: LoadoutNeckScarfStripedRed
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingNeckScarfStripedRed
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutNeckScarfStripedBlue
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingNeckScarfStripedBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutNeckScarfStripedGreen
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingNeckScarfStripedGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutNeckScarfStripedZebra
|
||||
category: Accessories
|
||||
cost: 1
|
||||
items:
|
||||
- ClothingNeckScarfStripedZebra
|
||||
34
Resources/Prototypes/Loadouts/outerClothing.yml
Normal file
34
Resources/Prototypes/Loadouts/outerClothing.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
- type: loadout
|
||||
id: LoadoutOuterGhostSheet
|
||||
category: Outer
|
||||
cost: 2
|
||||
items:
|
||||
- ClothingOuterGhostSheet
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutOuterCoatBomberjacket
|
||||
category: Outer
|
||||
cost: 3
|
||||
items:
|
||||
- ClothingOuterCoatBomber
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutOuterCoatHoodieBlack
|
||||
category: Outer
|
||||
cost: 2
|
||||
items:
|
||||
- ClothingOuterHoodieBlack
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutOuterCoatHoodieGrey
|
||||
category: Outer
|
||||
cost: 2
|
||||
items:
|
||||
- ClothingOuterHoodieGrey
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutOuterCoatWinterCoat
|
||||
category: Outer
|
||||
cost: 3
|
||||
items:
|
||||
- ClothingOuterWinterCoat
|
||||
98
Resources/Prototypes/Loadouts/shoes.yml
Normal file
98
Resources/Prototypes/Loadouts/shoes.yml
Normal file
@@ -0,0 +1,98 @@
|
||||
# Colored
|
||||
- type: loadout
|
||||
id: LoadoutShoesBlack
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorBlack
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesBlue
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesBrown
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorBrown
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesGreen
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesOrange
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorOrange
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesPurple
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorPurple
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesRed
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorRed
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesWhite
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorWhite
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesYellow
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesColorYellow
|
||||
|
||||
|
||||
# Miscellaneous
|
||||
- type: loadout
|
||||
id: LoadoutShoesSlippersDuck
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoeSlippersDuck
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesLeather
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesLeather
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutShoesMiscWhite
|
||||
category: Accessories
|
||||
cost: 1
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingShoesMiscWhite
|
||||
261
Resources/Prototypes/Loadouts/uniform.yml
Normal file
261
Resources/Prototypes/Loadouts/uniform.yml
Normal file
@@ -0,0 +1,261 @@
|
||||
- type: loadout
|
||||
id: LoadoutUniformAncientJumpsuit
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
requirements:
|
||||
- !type:LoadoutJobRequirement
|
||||
jobs:
|
||||
- Passenger
|
||||
items:
|
||||
- ClothingUniformJumpsuitAncient
|
||||
|
||||
# Colored jumpsuits
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorBlack
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorBlack
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorBlack
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorBlack
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorBlue
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorBlue
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorGreen
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorGreen
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorOrange
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorOrange
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorOrange
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorOrange
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorPink
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorPink
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorPink
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorPink
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorRed
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorRed
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorRed
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorRed
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorWhite
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorWhite
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorWhite
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorWhite
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorYellow
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorYellow
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorYellow
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorYellow
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorDarkBlue
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorDarkBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorDarkBlue
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorDarkBlue
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorTeal
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorTeal
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorTeal
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorTeal
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorPurple
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorPurple
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorPurple
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorPurple
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorDarkGreen
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorDarkGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorDarkGreen
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorDarkGreen
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorLightBrown
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorLightBrown
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorLightBrown
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorLightBrown
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorBrown
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorBrown
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorBrown
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorBrown
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorMaroon
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpsuitColorMaroon
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpskirtColorMaroon
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformJumpskirtColorMaroon
|
||||
|
||||
- type: loadout
|
||||
id: LoadoutUniformJumpsuitColorRainbow
|
||||
category: Uniform
|
||||
cost: 2
|
||||
exclusive: true
|
||||
items:
|
||||
- ClothingUniformColorRainbow
|
||||
@@ -19,7 +19,7 @@
|
||||
coefficient: 0.3
|
||||
|
||||
- type: entity
|
||||
parent: ClothingOuterStorageBase
|
||||
parent: ClothingOuterStorageToggleableBase
|
||||
id: ClothingOuterCoatRndMysta
|
||||
name: mystagogue lab coat # Delta V - Mystagogue new coat
|
||||
description: Similar to the standard model but with more purple and gold. # Delta V - Mystagogue new coat
|
||||
@@ -32,3 +32,5 @@
|
||||
modifiers:
|
||||
coefficients:
|
||||
Caustic: 0.75
|
||||
- type: ToggleableClothing
|
||||
clothingPrototype: ClothingHeadHoodMysta
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
- type: startingGear
|
||||
id: ChiefEngineerGear
|
||||
equipment:
|
||||
head: ClothingHeadHatHardhatWhite
|
||||
jumpsuit: ClothingUniformJumpsuitChiefEngineer
|
||||
back: ClothingBackpackChiefEngineerFilled
|
||||
shoes: ClothingShoesColorBrown
|
||||
|
||||
@@ -21,11 +21,9 @@
|
||||
- type: startingGear
|
||||
id: StationEngineerGear
|
||||
equipment:
|
||||
head: ClothingHeadHatHardhatYellow
|
||||
jumpsuit: ClothingUniformJumpsuitEngineering
|
||||
back: ClothingBackpackEngineeringFilled
|
||||
shoes: ClothingShoesBootsWork
|
||||
outerClothing: ClothingOuterVestHazard
|
||||
id: EngineerPDA
|
||||
eyes: ClothingEyesGlassesMeson
|
||||
belt: ClothingBeltUtilityEngineering
|
||||
|
||||
@@ -21,11 +21,9 @@
|
||||
jumpsuit: ClothingUniformJumpsuitChemistry
|
||||
back: ClothingBackpackChemistryFilled
|
||||
shoes: ClothingShoesColorWhite
|
||||
outerClothing: ClothingOuterCoatLabChem
|
||||
id: ChemistryPDA
|
||||
ears: ClothingHeadsetMedical
|
||||
belt: ChemBag
|
||||
pocket1: HandLabeler
|
||||
# the purple glasses?
|
||||
innerClothingSkirt: ClothingUniformJumpskirtChemistry
|
||||
satchel: ClothingBackpackSatchelChemistryFilled
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
jumpsuit: ClothingUniformJumpsuitCMO
|
||||
back: ClothingBackpackCMOFilled
|
||||
shoes: ClothingShoesColorBrown
|
||||
outerClothing: ClothingOuterCoatLabCmo
|
||||
id: CMOPDA
|
||||
ears: ClothingHeadsetCMO
|
||||
belt: ClothingBeltMedicalFilled
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
jumpsuit: ClothingUniformJumpsuitMedicalDoctor
|
||||
back: ClothingBackpackMedicalFilled
|
||||
shoes: ClothingShoesColorWhite
|
||||
outerClothing: ClothingOuterCoatLab
|
||||
id: MedicalPDA
|
||||
ears: ClothingHeadsetMedical
|
||||
belt: ClothingBeltMedicalFilled
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
jumpsuit: ClothingUniformJumpsuitResearchDirector
|
||||
back: ClothingBackpackResearchDirectorFilled
|
||||
shoes: ClothingShoesColorBrown
|
||||
head: ClothingHeadHoodMysta # DeltaV - Mystagogue new hat
|
||||
outerClothing: ClothingOuterCoatRndMysta # DeltaV - Mystagogue new coat
|
||||
id: RnDPDA
|
||||
ears: ClothingHeadsetRD
|
||||
belt: BibleMystagogue # Nyanotrasen - Mystagogue book for their Ifrit
|
||||
|
||||
@@ -51,9 +51,7 @@
|
||||
jumpsuit: ClothingUniformJumpsuitHoS
|
||||
back: ClothingBackpackHOSFilled
|
||||
shoes: ClothingShoesBootsCombatFilled
|
||||
outerClothing: ClothingOuterCoatHoSTrench
|
||||
eyes: ClothingEyesGlassesSunglasses
|
||||
head: ClothingHeadHatBeretHoS
|
||||
id: HoSPDA
|
||||
gloves: ClothingHandsGlovesCombat
|
||||
ears: ClothingHeadsetAltSecurity
|
||||
|
||||
Reference in New Issue
Block a user