diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index 1fe038096392..fcd38a4d27aa 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -63,6 +63,7 @@ public static void SetupContexts(IInputContextContainer contexts) human.AddFunction(ContentKeyFunctions.AltUseItemInHand); human.AddFunction(ContentKeyFunctions.OpenCharacterMenu); human.AddFunction(ContentKeyFunctions.OpenEmotesMenu); + human.AddFunction(ContentKeyFunctions.OpenLanguageMenu); // Forge-change: Einstein Engines - Language human.AddFunction(ContentKeyFunctions.ActivateItemInWorld); human.AddFunction(ContentKeyFunctions.ThrowItemInHand); human.AddFunction(ContentKeyFunctions.AltActivateItemInWorld); diff --git a/Content.Client/Lobby/ClientPreferencesManager.cs b/Content.Client/Lobby/ClientPreferencesManager.cs index 63a12a99bf2d..1b28a80ee886 100644 --- a/Content.Client/Lobby/ClientPreferencesManager.cs +++ b/Content.Client/Lobby/ClientPreferencesManager.cs @@ -6,6 +6,7 @@ using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Utility; +using Content.Shared._Mono.Company; // Forge-change namespace Content.Client.Lobby { @@ -62,6 +63,21 @@ public void SelectCharacter(int slot) public void UpdateCharacter(ICharacterProfile profile, int slot) { var collection = IoCManager.Instance!; + + // Forge-change-start + // Verify company exists if this is a humanoid profile + if (profile is HumanoidCharacterProfile humanoidProfile) + { + var protoManager = IoCManager.Resolve(); + if (!string.IsNullOrEmpty(humanoidProfile.Company) && + humanoidProfile.Company != "None" && + !protoManager.HasIndex(humanoidProfile.Company)) + { + profile = humanoidProfile.WithCompany("None"); + } + } + // Forge-change-end + profile.EnsureValid(_playerManager.LocalSession!, collection); var characters = new Dictionary(Preferences.Characters) {[slot] = profile}; Preferences = new PlayerPreferences(characters, Preferences.SelectedCharacterIndex, Preferences.AdminOOCColor, Preferences.ConstructionFavorites); diff --git a/Content.Client/Lobby/LobbyUIController.cs b/Content.Client/Lobby/LobbyUIController.cs index d07ae222d10d..d2db3e399e0f 100644 --- a/Content.Client/Lobby/LobbyUIController.cs +++ b/Content.Client/Lobby/LobbyUIController.cs @@ -25,6 +25,7 @@ using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Utility; +using Content.Shared._Mono.Company; // Forge-change namespace Content.Client.Lobby; @@ -186,6 +187,7 @@ private void RefreshLobbyPreview() PreviewPanel.SetSprite(EntityUid.Invalid); PreviewPanel.SetSummaryText(string.Empty); PreviewPanel.SetBankBalanceText(string.Empty); // Frontier + PreviewPanel.SetCompanyText(string.Empty); // Forge-change Company Display return; } @@ -193,6 +195,18 @@ private void RefreshLobbyPreview() PreviewPanel.SetSprite(dummy); PreviewPanel.SetSummaryText(humanoid.Summary); PreviewPanel.SetBankBalanceText(humanoid.BankBalanceText); // Frontier + + // Forge-change-start: Company Display + var companyId = humanoid.Company; + if (_prototypeManager.TryIndex(companyId, out var company)) + { + PreviewPanel.SetCompanyText($"[color={company.Color.ToHex()}]{company.Name}[/color]"); + } + else + { + PreviewPanel.SetCompanyText(Loc.GetString("humanoid-profile-editor-company-label") + $" [color=yellow]{companyId}[/color]"); + } + // Forge-change-end } private void RefreshProfileEditor() diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml index e7a48ab6e429..99775c7bb2b6 100644 --- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml +++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml @@ -140,6 +140,13 @@ + + + + + + + diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs index 37da2497045c..017ab0befadc 100644 --- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs +++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs @@ -39,6 +39,9 @@ using Robust.Shared.Prototypes; using Robust.Shared.Utility; using Direction = Robust.Shared.Maths.Direction; +using Content.Shared._Mono.Company; // Forge-change +using Content.Client._Forge.Company.UI; // Forge-change +using Content.Client.UserInterface.Controls; // Forge-changeL _Mono:2522 namespace Content.Client.Lobby.UI { @@ -108,6 +111,8 @@ public sealed partial class HumanoidProfileEditor : BoxContainer private ColorSelectorSliders _rgbSkinColorSelector; + private CompanySelectControl? _companySelect; // Forge-change + private bool _isDirty; [ValidatePrototypeId] @@ -144,6 +149,7 @@ public HumanoidProfileEditor( _controller = UserInterfaceManager.GetUIController(); _sprite = _entManager.System(); _sponsorMan = sponsorMan; + _companySelect = new CompanySelectControl(); // Forge-change _maxNameLength = _cfgManager.GetCVar(CCVars.MaxNameLength); _allowFlavorText = _cfgManager.GetCVar(CCVars.FlavorText); @@ -441,11 +447,48 @@ public HumanoidProfileEditor( RefreshTraits(); + // Forge-change-start: take _Mono company + #region Company + + TabContainer.SetTabTitle(3, Loc.GetString("humanoid-profile-editor-company-tab")); + + var username = _playerManager.LocalPlayer?.Session?.Name; + var companies = _prototypeManager.EnumeratePrototypes() + .Where(c => !c.Disabled || (username != null && c.Logins.Contains(username))) + .OrderBy(c => c.Name) + .ToList(); + + // Переносим "None" в начало списка + var noneIndex = companies.FindIndex(c => c.ID == "None"); + if (noneIndex != -1) + { + var none = companies[noneIndex]; + companies.RemoveAt(noneIndex); + companies.Insert(0, none); + } + + _companySelect?.Populate(companies, Profile?.Company); + + if (_companySelect != null) + { + _companySelect.OnCompanySelected += companyId => + { + // Сохраняем выбор сразу + Profile = Profile?.WithCompany(companyId); + SetDirty(); + }; + } + + CompanyContainer.AddChild(_companySelect!); + + #endregion Company + // Forge-change-end + TabContainer.SetTabTitle(2, Loc.GetString("humanoid-profile-editor-traits-tab")); // Frontier: 3<2 #region Markings - TabContainer.SetTabTitle(3, Loc.GetString("humanoid-profile-editor-markings-tab")); // Frontier: 4<3 + TabContainer.SetTabTitle(4, Loc.GetString("humanoid-profile-editor-markings-tab")); // Forge-change Markings.OnMarkingAdded += OnMarkingChange; Markings.OnMarkingRemoved += OnMarkingChange; @@ -483,6 +526,7 @@ public HumanoidProfileEditor( SpeciesInfoButton.OnPressed += OnSpeciesInfoButtonPressed; UpdateSpeciesGuidebookIcon(); + UpdateCompanyControls(); // Forge-change IsDirty = false; } @@ -574,6 +618,8 @@ public void RefreshTraits() { TraitsList.DisposeAllChildren(); + EnforceSpeciesTraitRestrictions(); // Forge-change: _Mono:2522 + var traits = _prototypeManager.EnumeratePrototypes().OrderBy(t => Loc.GetString(t.Name)).ToList(); // TabContainer.SetTabTitle(2, Loc.GetString("humanoid-profile-editor-traits-tab")); // Frontier: 3<2 @@ -587,11 +633,50 @@ public void RefreshTraits() return; } + // Forge-change-start: take from _Monolith 37 & 2522 + // Dictionary to store category buttons - moved up before it's used + Dictionary categoryButtons = new(); + + var clearAllButton = new ConfirmButton + { + Text = Loc.GetString("humanoid-profile-editor-clear-all-traits-button"), + ConfirmationText = Loc.GetString("humanoid-profile-editor-clear-all-traits-confirm"), + MinSize = new Vector2(0, 30) + }; + clearAllButton.OnPressed += _ => + { + if (Profile == null) + return; + + Profile = Profile.WithoutAllTraitPreferences(); + SetDirty(); + RefreshTraits(); + }; + TraitsList.AddChild(clearAllButton); + + // Add expand/collapse all buttons + var expandCollapseButtons = new TraitExpandCollapseButtons(); + expandCollapseButtons.OnExpandCollapseAll += expanded => + { + // Set the static dictionary state + TraitCategoryButton.SetAllExpanded(expanded); + + // Update all visible category buttons + foreach (var button in categoryButtons.Values) + { + button.SetExpanded(expanded); + } + }; + TraitsList.AddChild(expandCollapseButtons); + // Forge-change-end + // Setup model Dictionary> traitGroups = new(); List defaultTraits = new(); traitGroups.Add(TraitCategoryPrototype.Default, defaultTraits); + var allSelectors = new Dictionary, TraitPreferenceSelector>(); // Forge-change: take from _Monolith 37 & 2522 + foreach (var trait in traits) { if (trait.Category == null) @@ -610,20 +695,56 @@ public void RefreshTraits() // Create UI view from model foreach (var (categoryId, categoryTraits) in traitGroups) { + // Forge-change-start: take from _Monolith 37 & 2522 + // Skip the default category if it has no traits + if (categoryId == TraitCategoryPrototype.Default && categoryTraits.Count == 0) + continue; + TraitCategoryPrototype? category = null; + string categoryName; + int? maxTraitPoints = null; + // Forge-change-end if (categoryId != TraitCategoryPrototype.Default) { + // Forge-change-start: take from _Monolith 37 & 2522 category = _prototypeManager.Index(categoryId); // Label - TraitsList.AddChild(new Label - { - Text = Loc.GetString(category.Name), - Margin = new Thickness(0, 10, 0, 0), - StyleClasses = { StyleBase.StyleClassLabelHeading }, - }); + // TraitsList.AddChild(new Label + // { + // Text = Loc.GetString(category.Name), + // Margin = new Thickness(0, 10, 0, 0), + // StyleClasses = { StyleBase.StyleClassLabelHeading }, + // }); + categoryName = Loc.GetString(category.Name); + maxTraitPoints = category.MaxTraitPoints; + } + else + { + categoryName = Loc.GetString("humanoid-profile-editor-traits-default-category"); } + categoryTraits.Sort((a, b) => + { + var traitA = _prototypeManager.Index(a); + var traitB = _prototypeManager.Index(b); + + var costCompare = traitA.Cost.CompareTo(traitB.Cost); + if (costCompare != 0) + return costCompare; + + var traitNameA = Loc.GetString(traitA.Name); + var traitNameB = Loc.GetString(traitB.Name); + return string.Compare(traitNameA, traitNameB, StringComparison.CurrentCulture); + }); + + // Create category button + var categoryButton = new TraitCategoryButton(categoryName); + categoryButtons[categoryId] = categoryButton; + TraitsList.AddChild(categoryButton); + // Forge-change-end + + List selectors = new(); var selectionCount = 0; @@ -636,11 +757,79 @@ public void RefreshTraits() if (selector.Preference) selectionCount += trait.Cost; + // Forge-change-start: take from _Monolith 37 & 2522 + { + var tooltipParts = new List(); + if (trait.Description is { } tdesc) + tooltipParts.Add(Loc.GetString(tdesc)); + + if (trait.MutuallyExclusiveTraits.Count > 0) + { + var names = new List(); + foreach (var exId in trait.MutuallyExclusiveTraits) + { + if (_prototypeManager.TryIndex(exId, out var exProto)) + names.Add($"[color=#ADD8E6]{Loc.GetString(exProto.Name)}[/color]"); + } + if (names.Count > 0) + tooltipParts.Add(Loc.GetString("humanoid-profile-editor-traits-not-have", ("names", string.Join(", ", names)))); + } + + if (trait.SpeciesBlacklist.Count > 0) + { + var names = new List(); + foreach (var speciesId in trait.SpeciesBlacklist) + { + if (_prototypeManager.TryIndex(speciesId, out var speciesProto)) + names.Add($"[color=#087209]{Loc.GetString(speciesProto.Name)}[/color]"); + } + if (names.Count > 0) + tooltipParts.Add(Loc.GetString("humanoid-profile-editor-traits-not-be", ("names", string.Join(", ", names)))); + } + + if (tooltipParts.Count > 0) + selector.SetTooltip(string.Join("\n", tooltipParts)); + } + + allSelectors[trait.ID] = selector; + selector.PreferenceChanged += preference => { if (preference) { + // Calculate current points for this category before adding the new trait + var currentPoints = 0; + if (category != null && category.MaxTraitPoints >= 0) + { + foreach (var existingTraitId in Profile?.TraitPreferences ?? new HashSet>()) + { + if (!_prototypeManager.TryIndex(existingTraitId, out var existingProto)) + continue; + + if (existingProto.Category == categoryId) + currentPoints += existingProto.Cost; + } + + // Check if adding this trait would exceed the maximum points + if (currentPoints + trait.Cost > category.MaxTraitPoints) + { + // Reset the selection without triggering the event + selector.Preference = false; + return; + } + } + + var oldProfile = Profile; Profile = Profile?.WithTraitPreference(trait.ID, _prototypeManager); + + // If the profile didn't change, it means the trait couldn't be added (e.g., due to point limits) + if (Profile == oldProfile) + { + // Reset the selection without triggering the event + selector.Preference = false; + return; + } + // Forge-change-end } else { @@ -648,7 +837,68 @@ public void RefreshTraits() } SetDirty(); - RefreshTraits(); // If too many traits are selected, they will be reset to the real value. + // Forge-change-start: take from _Monolith 37 & 2522 + // RefreshTraits(); // If too many traits are selected, they will be reset to the real value. + + UpdateTraitIncompatibilityVisibility(allSelectors); + + // Instead of refreshing the entire UI, just update the point counter if needed + if (category is { MaxTraitPoints: >= 0 }) + { + // Recalculate points for this category + var currentPoints = 0; + foreach (var traitId in Profile?.TraitPreferences ?? new HashSet>()) + { + if (!_prototypeManager.TryIndex(traitId, out var proto)) + continue; + + if (proto.Category == category.ID) + currentPoints += proto.Cost; + } + + // Find and update the point counter label + if (categoryButton.TraitsContainer.ChildCount >= 2) + { + var maxPoints = category.MaxTraitPoints.Value; + float pointsLeft = maxPoints - currentPoints; + if (categoryButton.TraitsContainer.GetChild(0) is ProgressBar progressBar) + { + progressBar.Value = pointsLeft; + float percentRemaining = pointsLeft / maxPoints; + + Color barColor; + + if (percentRemaining > 0.5f) + { + barColor = Color.FromHex("#33FF33"); + } + else if (percentRemaining > 0.25f) + { + barColor = Color.FromHex("#FFFF33"); + } + else + { + barColor = Color.FromHex("#FF3333"); + } + + if (progressBar.ForegroundStyleBoxOverride is StyleBoxFlat styleBox) + { + styleBox.BackgroundColor = barColor; + } + } + + if (categoryButton.TraitsContainer.GetChild(1) is Label pointsLabel) + { + pointsLabel.Text = Loc.GetString("humanoid-profile-editor-trait-count-hint", + ("current", pointsLeft), + ("max", category.MaxTraitPoints)); + } + } + + // Update all trait colors based on the new point total + RefreshTraitColors(categoryButton, category, currentPoints); + } + // Forge-change-end }; selectors.Add(selector); } @@ -656,9 +906,45 @@ public void RefreshTraits() // Selection counter if (category is { MaxTraitPoints: >= 0 }) { - TraitsList.AddChild(new Label + // Forge-change-start: take from _Monolith 37 & 2522 + var maxPoints = category.MaxTraitPoints.Value; + var progressBar = new ProgressBar + { + MinHeight = 4, + SetHeight = 4f, + MinValue = 0, + MaxValue = maxPoints, + Value = Math.Max(0, maxPoints - selectionCount), + Margin = new Thickness(0, 0, 0, 2) + }; + + float pointsLeft = Math.Max(0, maxPoints - selectionCount); + float percentRemaining = pointsLeft / maxPoints; + + Color barColor; + if (percentRemaining > 0.5f) + { + barColor = Color.FromHex("#33FF33"); + } + else if (percentRemaining > 0.25f) + { + barColor = Color.FromHex("#FFFF33"); + } + else + { + barColor = Color.FromHex("#FF3333"); + } + + progressBar.ForegroundStyleBoxOverride = new StyleBoxFlat + { + BackgroundColor = barColor, + }; + + categoryButton.AddTrait(progressBar); + + categoryButton.AddTrait(new Label { - Text = Loc.GetString("humanoid-profile-editor-trait-count-hint", ("current", selectionCount), ("max", category.MaxTraitPoints)), + Text = Loc.GetString("humanoid-profile-editor-trait-count-hint", ("current", pointsLeft), ("max", category.MaxTraitPoints)), FontColorOverride = Color.Gray }); } @@ -668,16 +954,117 @@ public void RefreshTraits() if (selector == null) continue; - if (category is { MaxTraitPoints: >= 0 } && - selector.Cost + selectionCount > category.MaxTraitPoints) + // if (category is { MaxTraitPoints: >= 0 } && + // selector.Cost + selectionCount > category.MaxTraitPoints) + // Color traits red if they would exceed the point limit + if (category is { MaxTraitPoints: >= 0 }) + { + // selector.Checkbox.Label.FontColorOverride = Color.Red; + // If this trait would exceed the limit by itself + if (selector.Cost > category.MaxTraitPoints) + { + selector.SetUnavailable(true); + } + // If this trait would exceed the limit when added to current selection + else if (!selector.Preference && selector.Cost + selectionCount > category.MaxTraitPoints) + { + selector.SetUnavailable(true); + } + // If this trait is already selected but would exceed the limit if added now + else if (selector.Preference && selectionCount - selector.Cost + selector.Cost > category.MaxTraitPoints) + { + // This shouldn't happen normally, but just in case + selector.SetUnavailable(true); + } + } + + // TraitsList.AddChild(selector); + categoryButton.AddTrait(selector); + } + UpdateTraitIncompatibilityVisibility(allSelectors); + } + } + + // Helper method to refresh trait colors when points change + private void RefreshTraitColors(TraitCategoryButton categoryButton, TraitCategoryPrototype category, int currentPoints) + { + // Skip the first child which is the points label + for (int i = 1; i < categoryButton.TraitsContainer.ChildCount; i++) + { + if (categoryButton.TraitsContainer.GetChild(i) is TraitPreferenceSelector selector) + { + // Reset color + selector.TraitButton.ModulateSelfOverride = null; + selector.SetUnavailable(false); + + // If this trait would exceed the limit by itself + if (selector.Cost > category.MaxTraitPoints) + { + selector.SetUnavailable(true); + } + // If this trait would exceed the limit when added to current selection + else if (!selector.Preference && selector.Cost + currentPoints > category.MaxTraitPoints) + { + selector.SetUnavailable(true); + } + // Enable traits that can now be selected + else if (!selector.Preference && selector.Cost + currentPoints <= category.MaxTraitPoints) + { + selector.SetUnavailable(false); + } + } + } + } + + private void UpdateTraitIncompatibilityVisibility(Dictionary, TraitPreferenceSelector> allSelectors) + { + var selected = Profile?.TraitPreferences ?? new HashSet>(); + var currentSpecies = Profile?.Species; + + foreach (var (traitId, selector) in allSelectors) + { + var hide = false; + + if (selected.Contains(traitId)) + { + selector.Visible = true; + continue; + } + + if (!_prototypeManager.TryIndex(traitId, out var thisProto)) + { + selector.Visible = false; + continue; + } + + if (currentSpecies != null) + { + ProtoId speciesId = currentSpecies.Value; + if (thisProto.SpeciesBlacklist.Contains(speciesId)) { - selector.Checkbox.Label.FontColorOverride = Color.Red; + hide = true; } + } + + if (!hide) + { + foreach (var sel in selected) + { + if (!_prototypeManager.TryIndex(sel, out var selProto)) + continue; - TraitsList.AddChild(selector); + if (selProto.MutuallyExclusiveTraits.Contains(traitId) || thisProto.MutuallyExclusiveTraits.Contains(sel)) + { + hide = true; + break; + } + } } + + selector.Visible = !hide; } } + // Forge-change-end /// /// Refreshes the species selector. @@ -788,15 +1175,37 @@ public void RefreshAntags() private void SetDirty() { // If it equals default then reset the button. - if (Profile == null || - _preferencesManager.Preferences?.SelectedCharacter.MemberwiseEquals(Profile, out _) == true) // Forge-Change + // if (Profile == null || + // _preferencesManager.Preferences?.SelectedCharacter.MemberwiseEquals(Profile, out _) == true) // Forge-Change + // If profile is null, we can't be dirty + if (Profile == null) { IsDirty = false; return; } // TODO: Check if profile matches default. - IsDirty = true; + // IsDirty = true; + + // If we have no selected character to compare against, we're dirty + if (_preferencesManager.Preferences?.SelectedCharacter == null) + { + IsDirty = true; + return; + } + + // Get the selected character for comparison + var selectedCharacter = (HumanoidCharacterProfile)_preferencesManager.Preferences.SelectedCharacter; + + // Check explicitly if company changed + if (selectedCharacter.Company != Profile.Company) + { + IsDirty = true; + return; + } + + // Check if entire profile matches + IsDirty = !selectedCharacter.MemberwiseEquals(Profile, out _); } /// @@ -864,6 +1273,7 @@ public void SetProfile(HumanoidCharacterProfile? profile, int? slot) UpdateHairPickers(); UpdateCMarkingsHair(); UpdateCMarkingsFacialHair(); + UpdateCompanyControls(); RefreshAntags(); RefreshJobs(); @@ -1340,6 +1750,7 @@ private void SetSpecies(string newSpecies) Profile = Profile?.WithSpecies(newSpecies); OnSkinColorOnValueChanged(); // Species may have special color prefs, make sure to update it. Markings.SetSpecies(newSpecies); // Repopulate the markings tab as well. + EnforceSpeciesTraitRestrictions(); // In case there's job restrictions for the species RefreshJobs(); // In case there's species restrictions for loadouts @@ -1351,6 +1762,34 @@ private void SetSpecies(string newSpecies) ReloadPreview(); } + // Forge-change-start: take from _Monolith 37 & 2522 + private void EnforceSpeciesTraitRestrictions() + { + if (Profile == null) + return; + + var species = Profile.Species; + var toRemove = new List>(); + + foreach (var traitId in Profile.TraitPreferences) + { + if (!_prototypeManager.TryIndex(traitId, out TraitPrototype? trait)) + continue; + + if (trait.SpeciesBlacklist.Contains(species)) + toRemove.Add(traitId); + } + + foreach (var traitId in toRemove) + { + Profile = Profile.WithoutTraitPreference(traitId, _prototypeManager); + } + + if (toRemove.Count > 0) + SetDirty(); + } + // Forge-change-end + private void SetName(string newName) { Profile = Profile?.WithName(newName); @@ -1712,8 +2151,11 @@ private void UpdateEyePickers() private void UpdateSaveButton() { - SaveButton.Disabled = Profile is null || !IsDirty; - ResetButton.Disabled = Profile is null || !IsDirty; + // SaveButton.Disabled = Profile is null || !IsDirty; + // ResetButton.Disabled = Profile is null || !IsDirty; + var canSave = Profile is not null; + SaveButton.Disabled = !canSave || !IsDirty; + ResetButton.Disabled = !canSave || !IsDirty; } private void SetPreviewRotation(Direction direction) @@ -1827,5 +2269,34 @@ private void EndExport() ImportButton.Disabled = false; ExportButton.Disabled = false; } + + // Forge-change-start: take _Mono company + private void UpdateCompanyControls() + { + if (Profile is null) + return; + + var username = _playerManager.LocalPlayer?.Session?.Name; + var companies = _prototypeManager.EnumeratePrototypes() + .Where(c => !c.Disabled || (username != null && c.Logins.Contains(username))) + .OrderBy(c => c.Name) + .ToList(); + + var noneIndex = companies.FindIndex(c => c.ID == "None"); + if (noneIndex != -1) + { + var none = companies[noneIndex]; + companies.RemoveAt(noneIndex); + companies.Insert(0, none); + } + + _companySelect?.Populate(companies, Profile?.Company); + + if (Profile?.Company != null && !companies.Any(c => c.ID == Profile.Company)) + { + Profile = Profile.WithCompany("None"); + } + } + // Forge-change-end } } diff --git a/Content.Client/Lobby/UI/LobbyCharacterPreviewPanel.xaml b/Content.Client/Lobby/UI/LobbyCharacterPreviewPanel.xaml index c4ef8b457739..96a413401b12 100644 --- a/Content.Client/Lobby/UI/LobbyCharacterPreviewPanel.xaml +++ b/Content.Client/Lobby/UI/LobbyCharacterPreviewPanel.xaml @@ -11,6 +11,8 @@ + [ValidatePrototypeId] + public static readonly string UniversalPrototype = "Universal"; + + /// + /// Language used for Xenoglossy, should have same effects as Universal but with different language prototype. + /// + [ValidatePrototypeId] + public static readonly string PsychomanticPrototype = "Psychomantic"; + + /// + /// A cached instance of . + /// + public static LanguagePrototype Psychomantic { get; private set; } = default!; + + /// + /// A cached instance of + /// + public static LanguagePrototype Universal { get; private set; } = default!; + + [Dependency] protected readonly IPrototypeManager _prototype = default!; + [Dependency] protected readonly SharedGameTicker _ticker = default!; + + public override void Initialize() + { + Universal = _prototype.Index("Universal"); + // Initialize the Psychomantic prototype + Psychomantic = _prototype.Index(PsychomanticPrototype); + } + + public LanguagePrototype? GetLanguagePrototype(ProtoId id) + { + _prototype.TryIndex(id, out var proto); + return proto; + } + + /// + /// Obfuscate a message using the given language. + /// + public string ObfuscateSpeech(string message, LanguagePrototype language) + { + var builder = new StringBuilder(); + language.Obfuscation.Obfuscate(builder, message, this); + + return builder.ToString(); + } + + /// + /// Generates a stable pseudo-random number in the range (min, max) (inclusively) for the given seed. + /// One seed always corresponds to one number, however the resulting number also depends on the current round number. + /// This method is meant to be used in to provide stable obfuscation. + /// + internal int PseudoRandomNumber(int seed, int min, int max) + { + // Using RobustRandom or System.Random here is a bad idea because this method can get called hundreds of times per message. + // Each call would require us to allocate a new instance of random, which would lead to lots of unnecessary calculations. + // Instead, we use a simple but effective algorithm derived from the C language. + // It does not produce a truly random number, but for the purpose of obfuscating messages in an RP-based game it's more than alright. + seed = seed ^ (_ticker.RoundId * 127); + var random = seed * 1103515245 + 12345; + return min + Math.Abs(random) % (max - min + 1); + } +} diff --git a/Content.Shared/_EE/Language/Systems/SharedTranslatorSystem.cs b/Content.Shared/_EE/Language/Systems/SharedTranslatorSystem.cs new file mode 100644 index 000000000000..45ba83dd5a9a --- /dev/null +++ b/Content.Shared/_EE/Language/Systems/SharedTranslatorSystem.cs @@ -0,0 +1,44 @@ +using System.Linq; +using Content.Shared.Examine; +using Content.Shared.Toggleable; // Ignore, touching for REUSE Headers. +using Content.Shared._EE.Language.Components.Translators; + +namespace Content.Shared._EE.Language.Systems; + +public abstract class SharedTranslatorSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + } + + private void OnExamined(EntityUid uid, HandheldTranslatorComponent component, ExaminedEvent args) + { + var understoodLanguageNames = component.UnderstoodLanguages + .Select(it => Loc.GetString($"language-{it}-name")); + var spokenLanguageNames = component.SpokenLanguages + .Select(it => Loc.GetString($"language-{it}-name")); + var requiredLanguageNames = component.RequiredLanguages + .Select(it => Loc.GetString($"language-{it}-name")); + + args.PushMarkup(Loc.GetString("translator-examined-langs-understood", ("languages", string.Join(", ", understoodLanguageNames)))); + args.PushMarkup(Loc.GetString("translator-examined-langs-spoken", ("languages", string.Join(", ", spokenLanguageNames)))); + + args.PushMarkup(Loc.GetString(component.RequiresAllLanguages ? "translator-examined-requires-all" : "translator-examined-requires-any", + ("languages", string.Join(", ", requiredLanguageNames)))); + + args.PushMarkup(Loc.GetString(component.Enabled ? "translator-examined-enabled" : "translator-examined-disabled")); + } + + protected void OnAppearanceChange(EntityUid translator, HandheldTranslatorComponent? comp = null) + { + if (comp == null && !TryComp(translator, out comp)) + return; + + _appearance.SetData(translator, ToggleableVisuals.Enabled, comp.Enabled); // Forge-change: ToggleVisuals.Toggled>ToggleableVisuals.Enabled, Wizden#35341 compliance + } +} diff --git a/Content.Shared/_EE/Medical/CPRDoAfterEvent.cs b/Content.Shared/_EE/Medical/CPRDoAfterEvent.cs new file mode 100644 index 000000000000..8f46b75df28c --- /dev/null +++ b/Content.Shared/_EE/Medical/CPRDoAfterEvent.cs @@ -0,0 +1,7 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.Medical.CPR; + +[Serializable, NetSerializable] +public sealed partial class CPRDoAfterEvent : SimpleDoAfterEvent; diff --git a/Content.Shared/_Mono/Cargo/ItemTaxComponent.cs b/Content.Shared/_Mono/Cargo/ItemTaxComponent.cs new file mode 100644 index 000000000000..60ccd31395ab --- /dev/null +++ b/Content.Shared/_Mono/Cargo/ItemTaxComponent.cs @@ -0,0 +1,18 @@ +using Content.Shared._NF.Bank.Components; +using Content.Shared.Cargo; +using Robust.Shared.GameStates; + +namespace Content.Shared._Mono.ItemTax.Components; + +/// +/// This is used to add or substract additional money to a budget when a specific item is sold. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class ItemTaxComponent : Component +{ + /// + /// Defines the percent tax to be added to or taken from each budget on pallet crate sell. + /// + [DataField] + public Dictionary TaxAccounts = new(); +} diff --git a/Content.Shared/_Mono/Company/CompanyPrototype.cs b/Content.Shared/_Mono/Company/CompanyPrototype.cs index 1149b845b7cd..9c4caf82e739 100644 --- a/Content.Shared/_Mono/Company/CompanyPrototype.cs +++ b/Content.Shared/_Mono/Company/CompanyPrototype.cs @@ -6,6 +6,7 @@ // SPDX-License-Identifier: AGPL-3.0-or-later using Robust.Shared.Prototypes; +using Robust.Shared.Audio; // Forge-change namespace Content.Shared._Mono.Company; @@ -66,4 +67,12 @@ public sealed class CompanyPrototype : IPrototype /// [DataField("image")] public string? Image { get; private set; } + + // Forge-change + [DataField("entityIcon", required: false)] + public EntProtoId? EntityIcon { get; private set; } + + [DataField("spawnSound")] + public SoundSpecifier? SpawnSound; + // Forge-change-end } diff --git a/Content.Shared/_Mono/Ships/Components/CrewedShuttleComponent.cs b/Content.Shared/_Mono/Ships/Components/CrewedShuttleComponent.cs new file mode 100644 index 000000000000..3e40d4de2a91 --- /dev/null +++ b/Content.Shared/_Mono/Ships/Components/CrewedShuttleComponent.cs @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2025 sleepyyapril +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +namespace Content.Shared._Mono.Ships.Components; + +/// +/// This is used for knowing whether a shuttle should be forced to be crewed. +/// +[RegisterComponent] +public sealed partial class CrewedShuttleComponent : Component +{ + [DataField] + public List ShuttleConsoles; + + [DataField] + public List GunneryConsoles; +} diff --git a/Content.Shared/_Mono/Ships/Components/ShipActivityComponent.cs b/Content.Shared/_Mono/Ships/Components/ShipActivityComponent.cs new file mode 100644 index 000000000000..687bad725494 --- /dev/null +++ b/Content.Shared/_Mono/Ships/Components/ShipActivityComponent.cs @@ -0,0 +1,55 @@ +// SPDX-FileCopyrightText: 2025 sleepyyapril +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +using Robust.Shared.GameStates; + +namespace Content.Shared._Mono.Ships.Components; + +/// +/// This is used for tracking ships that are inactive. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class ShipActivityComponent : Component +{ + [ViewVariables] + public TimeSpan LastChecked { get; set; } + + [ViewVariables] + public TimeSpan CheckInterval { get; set; } = TimeSpan.FromSeconds(5); + + [ViewVariables] + public bool InactivePastThreshold { get; set; } + + [ViewVariables] + public bool InactiveLastCheck { get; set; } + + [ViewVariables] + public int TimesInactive { get; set; } + + [ViewVariables] + public int InactiveThresholdMinutes { get; set; } = 10; + + public int GetSecondsInactive() + { + // The first time does not count as 5 seconds. + var inactiveTimes = TimesInactive - 1; + + if (inactiveTimes <= 0) + return 0; + + return inactiveTimes * (int) CheckInterval.TotalSeconds; + } + + public int GetMinutesInactive() + { + // The first time does not count as 5 seconds. + var inactiveTimes = TimesInactive - 1; + + if (inactiveTimes <= 0) + return 0; + + var seconds = inactiveTimes * (int) CheckInterval.TotalSeconds; + return seconds / 60; + } +} diff --git a/Content.Shared/_Mono/Ships/Components/VesselComponent.cs b/Content.Shared/_Mono/Ships/Components/VesselComponent.cs new file mode 100644 index 000000000000..7b5f7f2555b6 --- /dev/null +++ b/Content.Shared/_Mono/Ships/Components/VesselComponent.cs @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2025 sleepyyapril +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +using Content.Shared._NF.Shipyard.Prototypes; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared._Mono.Ships.Components; + +/// +/// This is used for storing the ID of the VesselPrototype for a ship. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class VesselComponent : Component +{ + [DataField] + public ProtoId VesselId { get; set; } +} diff --git a/Content.Shared/_Mono/Shipyard/AttemptShipyardShuttlePurchaseEvent.cs b/Content.Shared/_Mono/Shipyard/AttemptShipyardShuttlePurchaseEvent.cs new file mode 100644 index 000000000000..b34e47a606da --- /dev/null +++ b/Content.Shared/_Mono/Shipyard/AttemptShipyardShuttlePurchaseEvent.cs @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2025 sleepyyapril +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +using Content.Shared._NF.Shipyard.Prototypes; + +namespace Content.Shared._Mono.Shipyard; + +[ByRefEvent] +public sealed class AttemptShipyardShuttlePurchaseEvent(EntityUid shuttle, EntityUid purchaser, VesselPrototype vessel, LocId? cancelReason = null) : CancellableEntityEventArgs +{ + public EntityUid Shuttle { get; } = shuttle; + public EntityUid Purchaser { get; } = purchaser; + public VesselPrototype Vessel { get; } = vessel; + public LocId CancelReason { get; set; } = cancelReason ?? "shipyard-console-denied"; +} diff --git a/Content.Shared/_Mono/Shipyard/ShipyardShuttlePurchaseEvent.cs b/Content.Shared/_Mono/Shipyard/ShipyardShuttlePurchaseEvent.cs new file mode 100644 index 000000000000..aa75387777a4 --- /dev/null +++ b/Content.Shared/_Mono/Shipyard/ShipyardShuttlePurchaseEvent.cs @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2025 sleepyyapril +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +namespace Content.Shared._Mono.Shipyard; + +public sealed class ShipyardShuttlePurchaseEvent(EntityUid shuttle, EntityUid purchaser) +{ + public EntityUid Shuttle { get; } = shuttle; + public EntityUid Purchaser { get; } = purchaser; +} diff --git a/Content.Shared/_Mono/Traits/Physical/BionicLegsComponent.cs b/Content.Shared/_Mono/Traits/Physical/BionicLegsComponent.cs new file mode 100644 index 000000000000..95c798571715 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/BionicLegsComponent.cs @@ -0,0 +1,4 @@ +namespace Content.Shared._Mono.Traits.Physical; + +[RegisterComponent] +public sealed partial class BionicLegsComponent : Component; diff --git a/Content.Shared/_Mono/Traits/Physical/GlassJawComponent.cs b/Content.Shared/_Mono/Traits/Physical/GlassJawComponent.cs new file mode 100644 index 000000000000..ff65902f5983 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/GlassJawComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Decreases the damage threshold required to enter the Critical state. +/// +[RegisterComponent] +public sealed partial class GlassJawComponent : Component +{ + /// + /// How much to decrease the Critical damage threshold by. + /// + [DataField] + public int CritDecrease = 10; +} diff --git a/Content.Shared/_Mono/Traits/Physical/HemophiliaComponent.cs b/Content.Shared/_Mono/Traits/Physical/HemophiliaComponent.cs new file mode 100644 index 000000000000..603f146ae9c4 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/HemophiliaComponent.cs @@ -0,0 +1,26 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Applies the Hemophilia effects. Royal disease anyone? +/// +[RegisterComponent] +public sealed partial class HemophiliaComponent : Component +{ + /// + /// Multiplier applied to BloodstreamComponent. + /// + [DataField] + public float BleedReductionMultiplier = 0.5f; + + /// + /// Multiplier applied to incoming Blunt damage. + /// + [DataField] + public float BluntDamageMultiplier = 1.10f; + + /// + /// Additional multiplier applied to bleed added from incoming damage. Cooked. + /// + [DataField] + public float ExtraBleedOnDamageMultiplier = 1.0f; +} diff --git a/Content.Shared/_Mono/Traits/Physical/IronmanComponent.cs b/Content.Shared/_Mono/Traits/Physical/IronmanComponent.cs new file mode 100644 index 000000000000..c9180251d20d --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/IronmanComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Component for the Ironman trait. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class IronmanComponent : Component; diff --git a/Content.Shared/_Mono/Traits/Physical/LethargyComponent.cs b/Content.Shared/_Mono/Traits/Physical/LethargyComponent.cs new file mode 100644 index 000000000000..b1c7251b3842 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/LethargyComponent.cs @@ -0,0 +1,28 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Decreases stamina and stamina regeneration and increases the cooldown before stamina starts regenerating. +/// +[RegisterComponent] +public sealed partial class LethargyComponent : Component +{ + /// + /// Flat penalty to stamina maximum (CritThreshold). + /// + [DataField] + public float StaminaPenalty = 15f; + + /// + /// Penalty to stamina regeneration per second (Decay). + /// + [DataField] + public float RegenerationPenalty = 0.6f; + + /// + /// Multiplier applied to stamina cooldown. 1.25 turns 3.0 seconds into 3.75 seconds. + /// + [DataField] + public float CooldownIncrease = 1.25f; +} + + diff --git a/Content.Shared/_Mono/Traits/Physical/PlateletFactoriesComponent.cs b/Content.Shared/_Mono/Traits/Physical/PlateletFactoriesComponent.cs new file mode 100644 index 000000000000..8528afe79ab1 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/PlateletFactoriesComponent.cs @@ -0,0 +1,37 @@ +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Grants slow, continuous regeneration to all present damage types. +/// +[RegisterComponent, AutoGenerateComponentPause] +public sealed partial class PlateletFactoriesComponent : Component +{ + /// + /// Seconds between regeneration ticks. + /// + [DataField] + public float IntervalSeconds = 1f; + + /// + /// Amount healed per second for each damage type present on the entity. + /// + [DataField] + public float HealPerSecond = 2f; + + /// + /// Multiplier applied to healing while the entity is in critical state. + /// + [DataField] + public float CritMultiplier = 2f; + + /// + /// The server time at which the next regeneration tick will occur. + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + [AutoPausedField] + public TimeSpan NextUpdate = TimeSpan.Zero; +} + + diff --git a/Content.Shared/_Mono/Traits/Physical/PrybarProstheticsComponent.cs b/Content.Shared/_Mono/Traits/Physical/PrybarProstheticsComponent.cs new file mode 100644 index 000000000000..3d2a74d8f00a --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/PrybarProstheticsComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Marks that this entity should have bionic arms on spawn. +/// +[RegisterComponent] +public sealed partial class PrybarProstheticsComponent : Component; diff --git a/Content.Shared/_Mono/Traits/Physical/SelfAwareComponent.cs b/Content.Shared/_Mono/Traits/Physical/SelfAwareComponent.cs new file mode 100644 index 000000000000..c784b1ee68b2 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/SelfAwareComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Adds a self-examine verb for the Self-Aware trait. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class SelfAwareComponent : Component; diff --git a/Content.Shared/_Mono/Traits/Physical/StrikingCallusesComponent.cs b/Content.Shared/_Mono/Traits/Physical/StrikingCallusesComponent.cs new file mode 100644 index 000000000000..aca8c3ff3d98 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/StrikingCallusesComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Increases unarmed strike base damage by a flat amount. +/// +[RegisterComponent] +public sealed partial class StrikingCallusesComponent : Component +{ + /// + /// Flat bonus to add to unarmed base damage (Blunt). + /// + [DataField] + public int BluntBonus = 2; +} diff --git a/Content.Shared/_Mono/Traits/Physical/TenacityComponent.cs b/Content.Shared/_Mono/Traits/Physical/TenacityComponent.cs new file mode 100644 index 000000000000..d8021c9b60be --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/TenacityComponent.cs @@ -0,0 +1,16 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Increases the damage threshold required to enter the Critical state. +/// +[RegisterComponent] +public sealed partial class TenacityComponent : Component +{ + /// + /// How much to increase the Critical damage threshold by. + /// + [DataField] + public int CritIncrease = 5; +} + + diff --git a/Content.Shared/_Mono/Traits/Physical/TrapAvoiderComponent.cs b/Content.Shared/_Mono/Traits/Physical/TrapAvoiderComponent.cs new file mode 100644 index 000000000000..101140315c8f --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/TrapAvoiderComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Step triggers will not activate when this entity steps on them. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class TrapAvoiderComponent : Component; diff --git a/Content.Shared/_Mono/Traits/Physical/TrapAvoiderSystem.cs b/Content.Shared/_Mono/Traits/Physical/TrapAvoiderSystem.cs new file mode 100644 index 000000000000..8cc2b0ababf0 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/TrapAvoiderSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.StepTrigger.Components; +using Content.Shared.StepTrigger.Systems; + +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Cancels step triggers for entities that have TrapAvoiderComponent. +/// +public sealed class TrapAvoiderSystem : EntitySystem +{ + public override void Initialize() + { + SubscribeLocalEvent(OnStepTriggerAttempt); + } + + private void OnStepTriggerAttempt(Entity ent, ref StepTriggerAttemptEvent args) + { + if (HasComp(args.Tripper)) + args.Cancelled = true; + } +} diff --git a/Content.Shared/_Mono/Traits/Physical/VigorComponent.cs b/Content.Shared/_Mono/Traits/Physical/VigorComponent.cs new file mode 100644 index 000000000000..96a5feef9ea7 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/VigorComponent.cs @@ -0,0 +1,27 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Increases stamina and stamina regeneration. +/// +[RegisterComponent] +public sealed partial class VigorComponent : Component +{ + /// + /// Flat bonus to stamina maximum (CritThreshold). + /// + [DataField] + public float StaminaBonus = 10f; + + /// + /// Bonus to stamina regeneration per second (Decay). + /// + [DataField] + public float RegenerationBonus = 0.6f; + + /// + /// Reduction to stamina cooldown (time before regen starts). + /// + [DataField] + public float CooldownReduction = 0.75f; // 3s -> 2.25s = 3 * 0.75 +} + diff --git a/Content.Shared/_Mono/Traits/Physical/VoraciousComponent.cs b/Content.Shared/_Mono/Traits/Physical/VoraciousComponent.cs new file mode 100644 index 000000000000..26cc2d7166cd --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/VoraciousComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Reduces food/drink action time by the multiplier. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class VoraciousComponent : Component +{ + /// + /// Divide the time to eat/drink by this value (e.g. 2.0 is twice as fast). + /// + [DataField] + public float ConsumptionSpeedMultiplier = 2.0f; +} diff --git a/Content.Shared/_Mono/Traits/Physical/WillToDieComponent.cs b/Content.Shared/_Mono/Traits/Physical/WillToDieComponent.cs new file mode 100644 index 000000000000..4fc64d6ac4b4 --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/WillToDieComponent.cs @@ -0,0 +1,16 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Decreases the damage threshold required to enter the Dead state. +/// +[RegisterComponent] +public sealed partial class WillToDieComponent : Component +{ + /// + /// How much to decrease the Dead damage threshold by. + /// + [DataField] + public int DeadDecrease = 15; +} + + diff --git a/Content.Shared/_Mono/Traits/Physical/WillToLiveComponent.cs b/Content.Shared/_Mono/Traits/Physical/WillToLiveComponent.cs new file mode 100644 index 000000000000..8f767343613b --- /dev/null +++ b/Content.Shared/_Mono/Traits/Physical/WillToLiveComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Shared._Mono.Traits.Physical; + +/// +/// Increases the damage threshold required to enter the Dead state. +/// +[RegisterComponent] +public sealed partial class WillToLiveComponent : Component +{ + /// + /// How much to increase the Dead damage threshold by. + /// + [DataField] + public int DeadIncrease = 10; +} diff --git a/Content.Shared/_NC/Customization/Systems/CharacterRequirements.Misc.cs b/Content.Shared/_NC/Customization/Systems/CharacterRequirements.Misc.cs new file mode 100644 index 000000000000..dab37fe0408f --- /dev/null +++ b/Content.Shared/_NC/Customization/Systems/CharacterRequirements.Misc.cs @@ -0,0 +1,56 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Preferences; +using Content.Shared.Roles; +using JetBrains.Annotations; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Utility; +using Content.Shared.CCVar; +using Robust.Shared.Configuration; + +namespace Content.Shared.Customization.Systems; + +/// +/// Requires the server to have at least a minimum number of players. +/// +[UsedImplicitly] +[Serializable, NetSerializable] +public sealed partial class MinPlayersRequirement : JobRequirement +{ + [DataField(required: true)] + public int Min; + + public override bool Check(IEntityManager entManager, + IPrototypeManager protoManager, + HumanoidCharacterProfile? profile, + IReadOnlyDictionary playTimes, + [NotNullWhen(false)] out FormattedMessage? reason) + { + var playerManager = IoCManager.Resolve(); + var playerCount = playerManager.PlayerCount; + + // CVar-флаг, чтобы можно было включать/выключать проверку + var configManager = IoCManager.Resolve(); + var enabled = configManager.GetCVar(CCVars.MinPlayersRequirement); + + reason = FormattedMessage.FromMarkupPermissive( + Loc.GetString("character-minPlayers-requirement", ("min", Min))); + + if (!enabled) + return true; + + if (!Inverted) + { + if (playerCount < Min) + return false; + } + else + { + if (playerCount >= Min) + return false; + } + + return true; + } +} diff --git a/Content.Shared/_NF/Bank/BUI/NFLedgerState.cs b/Content.Shared/_NF/Bank/BUI/NFLedgerState.cs index c3e9c7ed0362..cc21a8a867dd 100644 --- a/Content.Shared/_NF/Bank/BUI/NFLedgerState.cs +++ b/Content.Shared/_NF/Bank/BUI/NFLedgerState.cs @@ -28,9 +28,18 @@ public enum LedgerEntryType : byte VendorTax, CargoTax, MailDelivered, - ShipyardRenameFee, // Forge-change - BlackMarketAtmTax, - BlackMarketShipyardTax, + ShipyardRenameFee, + // Forge-change-start take Mono taxes + // BlackMarketAtmTax, + // BlackMarketShipyardTax, + AtmTax, + ShipyardTax, + // Mono begin + BlackMarketSales, + FrontierSales, + NFSDSales, + MedicalSales, + // Forge-change-end take Mono taxes BluespaceReward, AntiSmugglingBonus, MedicalBountyTax, @@ -41,6 +50,12 @@ public enum LedgerEntryType : byte StationDepositOther, // Expense entries MailPenalty, + // Mono Begin + BlackMarketPenalties, + FrontierPenalties, + NFSDPenalties, + MedicalPenalties, + // Mono End ShuttleRecordFees, StationWithdrawalPayroll, StationWithdrawalWorkOrder, diff --git a/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs b/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs index c9e540801605..c16e4a2590aa 100644 --- a/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs +++ b/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs @@ -31,4 +31,10 @@ public sealed partial class ShuttleDeedComponent : Component // Forge-change [DataField, AutoNetworkedField] public string? ShuttleModel = "Unknown"; + + /// + /// The ID card entity that holds this deed + /// + [DataField] + public EntityUid? DeedHolder; } diff --git a/Content.Shared/_NF/Shipyard/Prototypes/VesselPrototype.cs b/Content.Shared/_NF/Shipyard/Prototypes/VesselPrototype.cs index 73afcbf4bc31..3304140066b7 100644 --- a/Content.Shared/_NF/Shipyard/Prototypes/VesselPrototype.cs +++ b/Content.Shared/_NF/Shipyard/Prototypes/VesselPrototype.cs @@ -2,6 +2,7 @@ using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array; using Robust.Shared.Utility; +using Content.Shared.Tag; // Forge-change namespace Content.Shared._NF.Shipyard.Prototypes; @@ -95,6 +96,32 @@ public sealed class VesselPrototype : IPrototype, IInheritingPrototype [DataField] [AlwaysPushInheritance] public ComponentRegistry AddComponents { get; set; } = new(); + + // Forge-change-start: take from _Mono + + /// + /// Whether the ship should be crewed or not + /// This is automatically set to true when the ship is a Capital-class ship. + /// + [DataField] + public bool RequireCrew; + + /// + /// The amount of this ship that can active at any given time. + /// 0 for unlimited. + /// + [DataField("limit")] + public int LimitActive; + + [DataField] + public HashSet> Tags = new(); + + /// + /// The company that can buy this shuttle + /// + [DataField("requiredCompany")] + public string? RequiredCompany; + // Forge-change-end } public enum VesselSize : byte diff --git a/Resources/Audio/_EE/Effects/CPR.ogg b/Resources/Audio/_EE/Effects/CPR.ogg new file mode 100644 index 000000000000..4e43c0f16cff Binary files /dev/null and b/Resources/Audio/_EE/Effects/CPR.ogg differ diff --git a/Resources/Fonts/NotoSans/NotoSansSC-Regular.ttf b/Resources/Fonts/NotoSans/NotoSansSC-Regular.ttf new file mode 100644 index 000000000000..7056f5e97a83 Binary files /dev/null and b/Resources/Fonts/NotoSans/NotoSansSC-Regular.ttf differ diff --git a/Resources/Fonts/unifont-17.0.03.otf b/Resources/Fonts/unifont-17.0.03.otf new file mode 100644 index 000000000000..914005397523 Binary files /dev/null and b/Resources/Fonts/unifont-17.0.03.otf differ diff --git a/Resources/Locale/en-US/_EinsteinEngines/chat/managers/chat-language.ftl b/Resources/Locale/en-US/_EinsteinEngines/chat/managers/chat-language.ftl new file mode 100644 index 000000000000..2b85cdc79f02 --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/chat/managers/chat-language.ftl @@ -0,0 +1,59 @@ +chat-language-Universal-name = Universal +chat-language-Psychomantic-name = Psychomantic +chat-language-Bubblish-name = Bubblish +chat-language-RootSpeak-name = Rootspeak +chat-language-Nekomimetic-name = Neko +chat-language-Draconic-name = Sinta'Unathi +chat-language-Azaziba-name = Sinta'Azaziba +chat-language-SolCommon-name = Sol Common +chat-language-NovuNederic-name = Novu-Nederic +chat-language-NovaCygniBasic-name = Nova-Cygni Basic +chat-language-TauCetiBasic-name = Basic +chat-language-Tradeband-name = Tradeband +chat-language-Freespeak-name = Freespeak +chat-language-Elyran-name = Elyran +chat-language-Canilunzt-name = Canilunzt +chat-language-Moffic-name = Moffic +chat-language-RobotTalk-name = Binary +chat-language-Calcic-name = Calcic +chat-language-ValyrianStandard-name = Valyrian +chat-language-Sign-name = Sign +chat-language-Marish-name = Marish +chat-language-Chittin-name = Chittin +chat-language-Xeeplian-name = Xeeplian +chat-language-Hydraspeak-name = Hy'drav'tha + +# Additional languges + +chat-language-NalRasan-name = Nal'rasan +chat-language-SiikTajr-name = Siik'tajr +chat-language-SiikMaas-name = Siik'maas +chat-language-YaSsa-name = Ya'ssa +chat-language-Delvahii-name = Delvahii +chat-language-Shadowmind-name = Shadowmind +chat-language-Qiilour-name = Qiilour + +# Animal Languages + +chat-language-Cat-name = Cat +chat-language-Chicken-name = Chicken +chat-language-Cow-name = Cow +chat-language-Crab-name = Crab +chat-language-Deer-name = Deer +chat-language-Dog-name = Dog +chat-language-Duck-name = Duck +chat-language-Eldritch-name = Eldritch +chat-language-Fox-name = Fox +chat-language-Hissing-name = Hissing +chat-language-Kangaroo-name = Kangaroo +chat-language-Kobold-name = Kobold +chat-language-Monkey-name = Monkey +chat-language-Mouse-name = Mouse +chat-language-Penguin-name = Penguin +chat-language-Pig-name = Pig +chat-language-Sheep-name = Sheep +chat-language-Xeno-name = Xeno +chat-language-DroneTalk-name = Drone + +# Added here by Mono +chat-language-Blob-name = Blob diff --git a/Resources/Locale/en-US/_EinsteinEngines/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/_EinsteinEngines/chat/managers/chat-manager.ftl new file mode 100644 index 000000000000..b54ff6495188 --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/chat/managers/chat-manager.ftl @@ -0,0 +1,6 @@ +chat-speech-verb-Psychomantic-1 = resonates +chat-speech-verb-Psychomantic-2 = projects +chat-speech-verb-Psychomantic-3 = impresses +chat-speech-verb-Psychomantic-4 = radiates + +chat-speech-verb-marish = mars diff --git a/Resources/Locale/en-US/_EinsteinEngines/language/commands.ftl b/Resources/Locale/en-US/_EinsteinEngines/language/commands.ftl new file mode 100644 index 000000000000..a021ebead1cf --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/language/commands.ftl @@ -0,0 +1,34 @@ +command-list-langs-desc = List languages your current entity can speak at the current moment. +command-list-langs-help = Usage: {$command} + +command-saylang-desc = Send a message in a specific language. To choose a language, you can use either the name of the language, or its position in the list of languages. +command-saylang-help = Usage: {$command} . Example: {$command} TauCetiBasic "Hello World!". Example: {$command} 1 "Hello World!" + +command-language-select-desc = Select the currently spoken language of your entity. You can use either the name of the language, or its position in the list of languages. +command-language-select-help = Usage: {$command} . Example: {$command} 1. Example: {$command} TauCetiBasic + +command-language-spoken = Spoken: +command-language-understood = Understood: +command-language-current-entry = {$id}. {$language} - {$name} (current) +command-language-entry = {$id}. {$language} - {$name} + +command-language-invalid-number = The language number must be between 0 and {$total}. Alternatively, use the language name. +command-language-invalid-language = The language {$id} does not exist or you cannot speak it. + +# Toolshed + +command-description-language-add = Adds a new language to the piped entity. The two last arguments indicate whether it should be spoken/understood. Example: 'self language:add "Canilunzt" true true' +command-description-language-rm = Removes a language from the piped entity. Works similarly to language:add. Example: 'self language:rm "TauCetiBasic" true true'. +command-description-language-lsspoken = Lists all languages the entity can speak. Example: 'self language:lsspoken' +command-description-language-lsunderstood = Lists all languages the entity can understand. Example: 'self language:lssunderstood' + +command-description-translator-addlang = Adds a new target language to the piped translator entity. See language:add for details. +command-description-translator-rmlang = Removes a target language from the piped translator entity. See language:rm for details. +command-description-translator-addrequired = Adds a new required language to the piped translator entity. Example: 'ent 1234 translator:addrequired "TauCetiBasic"' +command-description-translator-rmrequired = Removes a required language from the piped translator entity. Example: 'ent 1234 translator:rmrequired "TauCetiBasic"' +command-description-translator-lsspoken = Lists all spoken languages for the piped translator entity. Example: 'ent 1234 translator:lsspoken' +command-description-translator-lsunderstood = Lists all understood languages for the piped translator entity. Example: 'ent 1234 translator:lssunderstood' +command-description-translator-lsrequired = Lists all required languages for the piped translator entity. Example: 'ent 1234 translator:lsrequired' + +command-language-error-this-will-not-work = This will not work. +command-language-error-not-a-translator = Entity {$entity} is not a translator. diff --git a/Resources/Locale/en-US/_EinsteinEngines/language/language-menu.ftl b/Resources/Locale/en-US/_EinsteinEngines/language/language-menu.ftl new file mode 100644 index 000000000000..c9742bd917a7 --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/language/language-menu.ftl @@ -0,0 +1,5 @@ +# Touching for REUSE Headers +language-menu-window-title = Language Menu +language-menu-current-language = Current Language: {$language} +language-menu-description-header = Description +ui-options-function-open-language-menu = Open language Menu diff --git a/Resources/Locale/en-US/_EinsteinEngines/language/languages-sign.ftl b/Resources/Locale/en-US/_EinsteinEngines/language/languages-sign.ftl new file mode 100644 index 000000000000..5579530730dd --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/language/languages-sign.ftl @@ -0,0 +1,47 @@ +chat-sign-language-message-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]{$verb} "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] +chat-sign-language-whisper-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]subtly gestures "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] + +chat-speech-verb-sign-1 = gestures +chat-speech-verb-sign-2 = signs +chat-speech-verb-sign-3 = waves + +# Tajaran stuffs +chat-sign-tajaran-language-message-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]{$verb} "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] +chat-sign-tajaran-language-whisper-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]subtly {$verb} "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] + +# Did I ever tell you the definition of insanity? +# Basically we have to get around the message formatter, and unless we decide to make an entire new system just for this language, we can't do anything else. +chat-speech-verb-sign-nalrasan-1 = moves their tail +chat-speech-verb-sign-nalrasan-2 = moves their tail briefly +chat-speech-verb-sign-nalrasan-3 = moves their tail several times in quick succession + +chat-speech-verb-sign-nalrasan-4 = flicks their ears +chat-speech-verb-sign-nalrasan-5 = flicks their ears a few times +chat-speech-verb-sign-nalrasan-6 = flicks their ears several times in quick succession + +chat-speech-verb-sign-nalrasan-7 = swivels their ears +chat-speech-verb-sign-nalrasan-8 = swivels their ears a few times +chat-speech-verb-sign-nalrasan-9 = swivels their ears several times in quick succession +chat-speech-verb-sign-nalrasan-10 = swivels their ears for a while + +chat-speech-verb-sign-nalrasan-11 = flicks their tail +chat-speech-verb-sign-nalrasan-12 = flicks their tail a few times +chat-speech-verb-sign-nalrasan-13 = flicks their tail several times in quick succession + +chat-speech-verb-sign-nalrasan-14 = shifts their ears and tail +chat-speech-verb-sign-nalrasan-15 = shifts their ears and tail briefly +chat-speech-verb-sign-nalrasan-16 = shifts their ears and tail for a while +chat-speech-verb-sign-nalrasan-17 = shifts their ears and tail several times in quick succession + +# There has to be a better way + +chat-speech-verb-sign-siiktajr-1 = moves their tail and purrs out +chat-speech-verb-sign-siiktajr-2 = moves their tail and mews +chat-speech-verb-sign-siiktajr-3 = flicks their ears and meows +chat-speech-verb-sign-siiktajr-4 = flicks their ears and mraows +chat-speech-verb-sign-siiktajr-5 = swivels their ears and purrs out +chat-speech-verb-sign-siiktajr-6 = swivels their ears and mews +chat-speech-verb-sign-siiktajr-7 = flicks their tail and meows +chat-speech-verb-sign-siiktajr-8 = flicks their tail and mraows +chat-speech-verb-sign-siiktajr-9 = shifts their ears and tail and purrs out +chat-speech-verb-sign-siiktajr-10 = shifts their ears and tail and mews diff --git a/Resources/Locale/en-US/_EinsteinEngines/language/languages.ftl b/Resources/Locale/en-US/_EinsteinEngines/language/languages.ftl new file mode 100644 index 000000000000..cc8c7ebb52d8 --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/language/languages.ftl @@ -0,0 +1,197 @@ +language-Universal-name = Universal +language-Universal-description = What are you? + +language-Psychomantic-name = Psychomantic +language-Psychomantic-description = Pure meaning, free from the tyranny of primative words and gestures. + +language-Bubblish-name = Bubblish +language-Bubblish-description = The language of Slimes. Being a mixture of bubbling noises and pops it's very difficult to speak for humans without the use of mechanical aids. + +language-RootSpeak-name = Rootspeak +language-RootSpeak-description = The strange whistling-style language spoken by the Diona. + +language-Hydraspeak-name = Hy'drav'tha +language-Hydraspeak-description = + A Mix of warbles, trills and chirps, with heavy tonal shifts and pitch changes make up this unusual language. + Due to the avian nature of hydrakin, one word can mean a million other things at the same time, which makes this language next to incomprehensible for even other birdlike races to figure out. + +language-Nekomimetic-name = Nekomimetic +language-Nekomimetic-description = To the casual observer, this language is an incomprehensible mess of broken Japanese. To the Felinids and Oni, it's somehow comprehensible. + +language-Draconic-name = Draconic +language-Draconic-description = + The common language of reptillians - composed of sibilant hisses and rattles. + +language-Azaziba-name = Azaziba +language-Azaziba-description = + A native language of Asakims consisting of a combination of spoken word and gesticulation. + +language-SolCommon-name = Sol common +language-SolCommon-description = + With its roots in Mandarin Chinese - Common evolved as the official language of the Trans-Solar Federation - with officials working to tie it together with a common tongue. + It's spoken by state officials, the armed forces, by those who either feel a sense of national pride in the Federation or otherwise fell sway to the culture. + +language-NovuNederic-name = Novu-Nederic +language-NovuNederic-description = + Once the language of seafarers and merchants, now the voice of spacers, terraformers, and pioneers - and great enjoyers of agriculture. + Spoken in the New-Netherlands, this direct and pragmatic trade language carries the sharp consonants and clipped vowels of its old-world roots. + Built on centuries of seafaring, land reclamation, and commerce, it thrives among those who shape entire worlds — just as their ancestors shaped the land from the sea. + +language-NovaCygniBasic-name = Nova-Cygni Basic +language-NovaCygniBasic-description = + A long split dialect of Sol Common, over the years it has turned into the language of the USSP. + To an outsider it sounds similar, but compared to Sol Common it sounds like gibberish. + +language-TauCetiBasic-name = Andromeda Standard +language-TauCetiBasic-description = + Established shortly after humans had colonized their local cluster, the andromeda standard has evolved rapidly with each discovery of an alien species. Changing to allow more diverse, + and a wider range of words and sounds that can be spoken by every known species. Unfortunately, this makes it almost impossible to learn if you didn't grow up surrounded by it, and learning it from a young age. + +language-Tradeband-name = Tradeband +language-Tradeband-description = + Descended from latin and romance languages of old Earth - Tradeband remains the main tongue of the upper class of humanity. + The language sounds elegant and well structured to most ears. It remains in popular use with traders - diplomats - and those seeking to hold onto a piece of a romantic past. + +language-Freespeak-name = Asher +language-Freespeak-description = + A rarely heard language outside of the colossus sector, developed over time through isolation from the main systems and lost colonies abandoned to die on this edge of civilized space. + Usually equated to slurred speach, relying more on tone to have the words mean something. + +# Mono - edited to remove mentions of elyran republic, or whatever it was +language-Elyran-name = Elyran Standard +language-Elyran-description = + Constructed using elements of Farsi - Arabic - and Turkish. + Influence from all three of these languages can be seen throughout its grammar and vocabulary. + +language-Canilunzt-name = Canilunzt +language-Canilunzt-description = + The guttural language spoken and utilized by the inhabitants of the Vazzend system, + composed of growls, barks, yaps, and heavy utilization of ears and tail movements. Vulpkanin speak this language with ease. + +language-Moffic-name = Moffic +language-Moffic-description = The language of the mothpeople borders on complete unintelligibility. + +language-RobotTalk-name = RobotTalk +language-RobotTalk-description = A language consisting of harsh binary chirps, whistles, hisses, and whines. Organic tongues cannot speak it without aid from special translators. + +language-Calcic-name = Calcic +language-Calcic-description = The bone-rattling language of Skeletons and Plasmamen. It sounds like a harmonic trousle of bones with a humerus tone, sans any off-tune ribbing. + +# Tau-Ceti Basic Sign Language - Removed prefix for better readability. +language-Sign-name = Sign Language +language-Sign-description = + Tau-Ceti Basic Sign Language. + TCB-SL for short, this sign language is prevalent among mute and deaf people. + +language-Marish-name = Marish +language-Marish-description = A language spoken only by Shadowkin, one that is unable to be replicated by normal tongues. + +language-ValyrianStandard-name = Valyrian Standard +language-ValyrianStandard-description = + A language descended from eastern european languages of old earth - Valyrian Standard is the commonly spoken tongue of Harpies brought up on their homeworld of Valyrian 4b + It is rarely spoken outside of the worlds of its native speakers, and has in modern times been supplanted by the 'Conlangs of the Trans-Solar Federation. + Its speakers are those who wish to uphold the traditions and beliefs of ancient peoples from before the colonial era. + +language-Chittin-name = Chittin +language-Chittin-description = + A language consisting of clicks, buzzes, and some variety of harsh insect sounds. + Most of what makes up their speech comes from their antennae, making it a near-impossible language for those without to learn. + +language-Xeeplian-name = Xeeplian +language-Xeeplian-description = + Our language is highly advanced, efficient and to the point. + We have taken a liking to mimic some of the inferior lifeforms' babbling in the further pursuit of Our goals. + +# Animal Languages + +language-Cat-name = Cat +language-Cat-description = Meow + +language-Deer-name = Deer +language-Deer-description = Ni! + +language-Dog-name = Dog +language-Dog-description = Bark! + +language-Fox-name = Fox +language-Fox-description = Yeeps! + +language-Xeno-name = Xeno +language-Xeno-description = Sssss! + +language-Monkey-name = Monkey +language-Monkey-description = Oooook! + +language-Mouse-name = Mouse +language-Mouse-description = Squeeek! + +language-Chicken-name = Chicken +language-Chicken-description = Coot! + +language-Duck-name = Duck +language-Duck-description = Quack! + +language-Cow-name = Cow +language-Cow-description = Moooo! + +language-Sheep-name = Sheep +language-Sheep-description = Baaah! + +language-Kangaroo-name = Kangaroo +language-Kangaroo-description = Chuu! + +language-Pig-name = Pig +language-Pig-description = Oink! + +language-Crab-name = Crab +language-Crab-description = Click! + +language-Kobold-name = Kobold +language-Kobold-description = Hiss! + +language-Hissing-name = Hissing +language-Hissing-description = Hiss! + +language-Eldritch-name = Eldritch +language-Eldritch-description = + A language that is considered to be long forgotten - now the only speakers of this profaned tongue of screeches and + mumbles are the followers of an ancient God of Blood. + +language-Penguin-name = Penguin +language-Penguin-description = Bwaap! + +language-DroneTalk-name = Drone +language-DroneTalk-description = Incomprehensible to most non-drones! + +# Tajaran and Shadow stuffs +language-SiikMaas-name = Siik'maas +language-SiikMaas-description = + The ancient religious tongue of the Tajara, now the most widely spoken and taught language on Adhomai. + +language-NalRasan-name = Nal'rasan +language-NalRasan-description = + A body-language-heavy dialect created by M'sai hunters for stealth, later adopted by rebels for covert communication during the Great War. + +language-SiikTajr-name = Siik'tajr +language-SiikTajr-description = + A revolutionary language blending Siik'maas and Nal'rasan, designed for secrecy during the overthrow of the plutocracy and used heavily in the Great War. + +language-YaSsa-name = Ya'ssa +language-YaSsa-description = + A refined Siik'maas dialect once spoken by Njarir nobility, revived by the New Kingdom of Adhomai after centuries of disuse. + +language-Delvahii-name = Delvahii +language-Delvahii-description = + A Zhan-Khazan language tied to Ma'take worship, still used in religious rites and favored by farmers resisting government control. + +language-Shadowmind-name = Shadowmind +language-Shadowmind-description = + A language spoken by the shadowlings. Not much is known about it, except that Thralls can understand it. +language-Qiilour-name = Qiilour +language-Qiilour-description = + The native and principal language of the Xelthia, Qiilour is spoken by nearly all members of their species to some degree. It is a refined fusion of several ancient tongues—such as Telenarii, Voskarn, and Old Xelthec—each now lost to history. + +# Languages Added here by Mono + +language-Blob-name = Blob +language-Blob-description = The language spoken by blobs! Glorp! diff --git a/Resources/Locale/en-US/_EinsteinEngines/language/translator.ftl b/Resources/Locale/en-US/_EinsteinEngines/language/translator.ftl new file mode 100644 index 000000000000..9d7c415d4e4c --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/language/translator.ftl @@ -0,0 +1,14 @@ +translator-component-shutoff = The {$translator} shuts off. +translator-component-turnon = The {$translator} turns on. + +translator-implanter-refuse = The {$implanter} has no effect on {$target}. +translator-implanter-success = The {$implanter} successfully injected {$target}. +translator-implanter-ready = This implanter appears to be ready to use. +translator-implanter-used = This implanter seems empty. + +translator-examined-langs-understood = It can translate from: [color=green]{$languages}[/color]. +translator-examined-langs-spoken = It can translate to: [color=green]{$languages}[/color]. +translator-examined-requires-any = It requires you to know at least one of these languages: [color=yellow]{$languages}[/color]. +translator-examined-requires-all = It requires you to know all of these languages: [color=yellow]{$languages}[/color]. +translator-examined-enabled = It appears to be [color=green]active[/color]. +translator-examined-disabled = It appears to be [color=red]turned off[/color]. diff --git a/Resources/Locale/en-US/_EinsteinEngines/technologies/technologies.ftl b/Resources/Locale/en-US/_EinsteinEngines/technologies/technologies.ftl new file mode 100644 index 000000000000..554ff32ea31e --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/technologies/technologies.ftl @@ -0,0 +1,3 @@ +# Touching for REUSE Headers. +research-technology-basic-translation = Basic Translation +research-technology-advanced-translation = Advanced Translation diff --git a/Resources/Locale/en-US/_EinsteinEngines/traits/language-traits.ftl b/Resources/Locale/en-US/_EinsteinEngines/traits/language-traits.ftl new file mode 100644 index 000000000000..9d8b73c5f656 --- /dev/null +++ b/Resources/Locale/en-US/_EinsteinEngines/traits/language-traits.ftl @@ -0,0 +1,60 @@ +# This file is only for the language traits. If we add species-specific languages to the list of traits, +# we should add them here in the order they are in the list, for organization. Maybe add more languages later. + +trait-category-languages = Languages + +trait-language-foreigner-light-name = Foreigner Light +trait-language-foreigner-light-desc = + You understand the common language, Andromeda Standard Basic, but you can't quite speak it yet. + You have a translator to help you with your basic understanding of the language, better keep it charged. + +trait-language-foreigner-name = Foreigner +trait-language-foreigner-desc = + You can't understand the common language, Andromeda Standard, and you require a translator at all times to talk. + You have a translator to help you with your understanding and speaking, make sure to keep it charged. + +trait-language-signlanguage-name = Sign Language +trait-language-signlanguage-desc = + The use of body language, hand signs, and other forms of dexterous movements to get your point across. + You can understand and use Andromeda Standard Basic Sign Language (TCB-SL). + If you are mute for any reason, you can still communicate with sign language. + +trait-language-solcommon-name = Sol Common +trait-language-solcommon-desc = + With its roots in Mandarin Chinese - Common evolved as the official language of the Trans-Solar Federation - with officials working to tie it together with a common tongue. + It's spoken by state officials, the armed forces, by those who either feel a sense of national pride in the Federation or otherwise fell sway to the culture. + +trait-language-tradeband-name = Tradeband +trait-language-tradeband-desc = + Descended from latin and romance languages of old Earth - Tradeband remains the main tongue of the upper class of humanity. + The language sounds elegant and well structured to most ears. It remains in popular use with traders - diplomats - and those seeking to hold onto a piece of a romantic past. + +trait-language-freespeak-name = Asher +trait-language-freespeak-desc = + A rarely heard language outside of the colossus sector, developed over time through isolation from the main systems and lost colonies abandoned to die on this edge of civilized space. + Usually equated to slurred speach, relying more on tone to have the words mean something. + +trait-language-elyran-name = Elyran +trait-language-elyran-desc = + Constructed using elements of Farsi - Arabic - and Turkish - influence from all three of these languages can be seen throughout its grammar and vocabulary. + +trait-language-valyrianstandard-name = Valyrian Standard +trait-language-valyrianstandard-desc = + A language descended from eastern european languages of old earth - Valyrian Standard is the commonly spoken tongue of Harpies brought up on their homeworld of Valyrian 4b + It is rarely spoken outside of the worlds of its native speakers, and has in modern times been supplanted by the 'Conlangs of the Trans-Solar Federation. + Its speakers are those who wish to uphold the traditions and beliefs of ancient peoples from before the colonial era. + +trait-language-novunederic-name = Novu-Nederic +trait-language-novunederic-desc = + Once the language of seafarers and merchants, now the voice of spacers, terraformers, and pioneers. + Spoken in the New-Netherlands, this direct and pragmatic trade language carries the sharp consonants and clipped vowels of its old-world roots. + Built on centuries of seafaring, land reclamation, and commerce, it thrives among those who shape entire worlds — just as their ancestors shaped the land from the sea. + +trait-language-azaziba-name = Sinta'Azaziba +trait-language-azaziba-desc = + A language of Moghes consisting of a combination of spoken word and gesticulation. + While waning since Moghes entered the galactic stage - it enjoys popular use by Unathi that never fell to the Hegemony's cultural dominance. + +trait-language-SiikMaas-name = Siik'maas +trait-language-SiikMaas-desc = + The ancient religious tongue of the Tajara, now the most widely spoken and taught language on Adhomai. diff --git a/Resources/Locale/en-US/_NF/cartridge-loader/cartridges.ftl b/Resources/Locale/en-US/_NF/cartridge-loader/cartridges.ftl index d30873439da5..9fea6b92a9a3 100644 --- a/Resources/Locale/en-US/_NF/cartridge-loader/cartridges.ftl +++ b/Resources/Locale/en-US/_NF/cartridge-loader/cartridges.ftl @@ -41,3 +41,14 @@ ledger-entry-type-StationWithdrawalWorkOrder = Work Orders ledger-entry-type-StationWithdrawalSupplies = Supply Expenses ledger-entry-type-StationWithdrawalBounty = Bounties ledger-entry-type-StationWithdrawalOther = Misc. Expenses + +ledger-entry-type-AtmTax = ATM Taxes +ledger-entry-type-ShipyardTax = Shipyard Taxes +ledger-entry-type-BlackMarketSales = Smuggling Sales +ledger-entry-type-ColonialOutpostSales = Cargo Crate Taxes +ledger-entry-type-TSFMCSales = Weapons Sale Taxes +ledger-entry-type-MedicalSales = Medical Sale Taxes +ledger-entry-type-BlackMarketPenalties = Asset Seizure +ledger-entry-type-ColonialOutpostPenalties = Illegaly Sold Contraband +ledger-entry-type-TSFMCPenalties = Illegaly Sold Contraband +ledger-entry-type-MedicalPenalties = Drug Control Fines diff --git a/Resources/Locale/en-US/_NF/shipyard/shipyard-console-component.ftl b/Resources/Locale/en-US/_NF/shipyard/shipyard-console-component.ftl index 68511aab499b..7cdb333fe82c 100644 --- a/Resources/Locale/en-US/_NF/shipyard/shipyard-console-component.ftl +++ b/Resources/Locale/en-US/_NF/shipyard/shipyard-console-component.ftl @@ -22,6 +22,8 @@ shipyard-console-deed-label = Registered Ship: shipyard-console-appraisal-label = Shuttle Resale Value:{" "} shipyard-console-no-voucher-redemptions = All voucher redemptions have been used. shipyard-console-invalid-voucher-type = This voucher cannot be used at this console. +shipyard-console-denied = You cannot purchase this ship at this time. +shipyard-console-limited = There are too many active shuttles of this type, try again later! shipyard-console-contraband-onboard = Smuggled contraband detected onboard. shipyard-console-station-resources = Vital station resources detected onboard. diff --git a/Resources/Locale/en-US/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/chat/managers/chat-manager.ftl index e7e55c1ea40b..7347339fa1da 100644 --- a/Resources/Locale/en-US/chat/managers/chat-manager.ftl +++ b/Resources/Locale/en-US/chat/managers/chat-manager.ftl @@ -22,11 +22,18 @@ chat-manager-server-wrap-message = [bold]{$message}[/bold] chat-manager-sender-announcement = Central Command chat-manager-sender-announcement-wrap-message = [font size=14][bold]{$sender} Announcement:[/font][font size=12] {$message}[/bold][/font] -chat-manager-entity-say-wrap-message = [BubbleHeader][bold][Name]{$entityName}[/Name][/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent]{$message}[/BubbleContent]"[/font] -chat-manager-entity-say-bold-wrap-message = [BubbleHeader][bold][Name]{$entityName}[/Name][/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent][bold]{$message}[/bold][/BubbleContent]"[/font] -chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] whispers,"[BubbleContent]{$message}[/BubbleContent]"[/italic][/font] -chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic][BubbleHeader]Someone[/BubbleHeader] whispers, "[BubbleContent]{$message}[/BubbleContent]"[/italic][/font] +# Einstein Engines - Language begin (changing colors for text based on language color in handler) +# For the message in double quotes, the font/color/bold/italic elements are repeated twice, outside the double quotes and inside. +# The outside elements are for formatting the double quotes, and the inside elements are for formatting the text in speech bubbles ([BubbleContent]). +chat-manager-entity-say-wrap-message = [BubbleHeader][bold][Name]{$entityName}[/Name][/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent][font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font][/BubbleContent]"[/font] +chat-manager-entity-say-bold-wrap-message = [BubbleHeader][bold][Name]{$entityName}[/Name][/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent][font="{$fontType}" size={$fontSize}][bold][color={$color}]{$message}[/color][/font][/bold][/BubbleContent]"[/font] + +chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] whispers, "[BubbleContent][color={$color}][font="{$fontType}"]{$message}[/font][/color][/BubbleContent][font size=11]"[/italic][/font] +chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic][BubbleHeader]Someone[/BubbleHeader] whispers, "[BubbleContent][color={$color}][font="{$fontType}"]{$message}[/color][/font][/BubbleContent][font size=11]"[/italic][/font] +# Einstein Engines - Language end + +# chat-manager-language-prefix = ({ $language }){" "} - Removed so it doesn't show up, not wanted, but part of the language system. # THE() is not used here because the entity and its name can technically be disconnected if a nameOverride is passed... chat-manager-entity-me-wrap-message = [italic]{ PROPER($entity) -> diff --git a/Resources/Locale/en-US/headset/headset-component.ftl b/Resources/Locale/en-US/headset/headset-component.ftl index 8af5fd4dca31..562ec9d562b8 100644 --- a/Resources/Locale/en-US/headset/headset-component.ftl +++ b/Resources/Locale/en-US/headset/headset-component.ftl @@ -1,6 +1,8 @@ # Chat window radio wrap (prefix and postfix) -chat-radio-message-wrap = [color={$color}]{$channel} [bold]{$name}[/bold] {$verb}, [font={$fontType} size={$fontSize}]"{$message}"[/font][/color] -chat-radio-message-wrap-bold = [color={$color}]{$channel} [bold]{$name}[/bold] {$verb}, [font={$fontType} size={$fontSize}][bold]"{$message}"[/bold][/font][/color] +# Einstein Engines - Languages begin (change text color based on language color set in handler) +chat-radio-message-wrap = [color={$color}]{$channel} [bold]{$name}[/bold] {$verb}, "[/color][font="{$fontType}" size={$fontSize}][color={$languageColor}]{$message}[/color][/font][color={$color}]"[/color] +chat-radio-message-wrap-bold = [color={$color}]{$channel} [bold]{$name}[/bold] {$verb}, "[/color][font="{$fontType}" size={$fontSize}][color={$languageColor}][bold]{$message}[/bold][/font][/color][color={$color}]"[/color] +# Einstein Engines - Languages end examine-headset-default-channel = Use {$prefix} for the default channel ([color={$color}]{$channel}[/color]). diff --git a/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl b/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl index 8345a841b153..d06c8844e1af 100644 --- a/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl +++ b/Resources/Locale/en-US/preferences/ui/humanoid-profile-editor.ftl @@ -64,3 +64,7 @@ humanoid-profile-editor-trait-count-hint = Points available: [{$current}/{$max}] trait-category-disabilities = Disabilities trait-category-speech = Speech traits trait-category-quirks = Quirks + +# Company +humanoid-profile-editor-company-tab = Company +humanoid-profile-editor-company-label = Company: diff --git a/Resources/Locale/ru-RU/_EE/crp.ftl b/Resources/Locale/ru-RU/_EE/crp.ftl new file mode 100644 index 000000000000..d422c0a1d59e --- /dev/null +++ b/Resources/Locale/ru-RU/_EE/crp.ftl @@ -0,0 +1,7 @@ +cpr-start-second-person = Вы начинаете делать сердечно-лёгочную реанимацию {CAPITALIZE($target)}. +cpr-start-second-person-patient = {CAPITALIZE(THE($user))} начинает делать вам сердечно-лёгочную реанимацию. +cpr-must-remove = Вы должны снять {THE($clothing)} с пациента. +cpr-must-remove-own-mask = Вы должны снять свою {THE($clothing)}. +cpr-target-rotting = {CAPITALIZE($entity)} безвозвратно погиб... +cpr-target-cantbreathe = Вы или {CAPITALIZE($entity)} не можете дышать! +cpr-verb = Начать СЛР diff --git a/Resources/Locale/ru-RU/_Forge/company.ftl b/Resources/Locale/ru-RU/_Forge/company.ftl new file mode 100644 index 000000000000..45ab352d88e1 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/company.ftl @@ -0,0 +1,42 @@ +# -- random staff -- +company-select-button = Выбрать +company-leave-button = Покинуть +humanoid-profile-editor-company-tab = Компании +humanoid-profile-editor-company-label = Компания: +company-examine = Состоит в: {$company} + +# Company examination text with gender-appropriate pronouns + +examine-company = {GENDER($entity) -> + [male] Он состоит в {$company}. + [female] Она состоит в {$company}. + *[other] Они состоят в {$company}. +} + +comp-pda-ui-owner-with-company = Владелец: [color=white]{$actualOwnerName}[/color] ([color={$companyColor}]{$companyName}[/color]) +company-none-description = Свобода - тоже выбор. +company-no-logins-tooltip = Вы не приглашены в компанию. + +# -- Descriptions -- + +company-nanotrasen-description = Описания не будет, идите вики читать. Его же кто-то делает, да?? ДА?? + +company-ems-description = Свободное объединение спасателей, техников, хирургов и всех, кто служит делу жизни. Общие испытания и опыт соединяют тех, кто в решающий момент обращается к человеку с простым призывом: «Не умирай». Поддержка друг друга, обмен знаниями и опытом между ветеранами и новичками, создание прочной стены помощи для тех, кто берёт на себя нелёгкую и часто неблагодарную миссию - помогать пострадавшим в секторе. Служение выражается в благотворительных делах, в обмене знаниями и умениями, а порой и в работе под огнём во время экспедиций вдали от дома. В основе всей организации — стремление идти туда, где ждут, и быть рядом с теми, кто надеется что помощь придёт. + +company-far-star-biotech-description = Где бы вы ни находились — знайте, что ваше тело в безопасности с нами. Far Star Biotech занимает уникальное положение в центральной экономике: корпорация Nanotrasen пощадила их от полного уничтожения после того, как они согласились лицензировать свою интеллектуальную собственность. Корабли FSB теперь стали привычным зрелищем на рубежах, а слухи ходят о возрождении боевых подразделений Bioseers — несмотря на существующие договоры, запрещающие перевооружение. + +company-lvhi-description = Основанная как альянс обанкротившихся земных индустриальных гильдий, компания выжила, сменив профиль с планетарной добычи на космическую. Их прорывом стал контракт по спасению и утилизации разрушенной станции «Гефест». Подход «ремонтировать сваркой, а не заменять» и умение создавать производство из подручного хлама принесли им известность. Этот успех позволил компании выкупить патенты на ряд устаревших, но чрезвычайно надежных технологий жизнеобеспечения и двигателей. С тех пор «Langstad-Voigt Heavy Industries» занимается полным циклом освоения рубежей: от поиска ресурсов и строительства аванпостов до производства оборудования и сборки собственных утилитарных, «неубиваемых» кораблей. Их репутация — это репутация грубых прагматиков. Их станции и суда лишены изящества, но работают в условиях, где более технологичные конкуренты отказывают. Они не продают будущее — они продают результат. + +company-nexus-description = Галактический торговый альянс созданный множеством компаний и корпораций. Во главе альянса находится сильно раздробленный совет “Три Колонны”. Центр альянса «Нексус» представляет собой единую точку входа для покупателей и мощную поддержку для производителей, сам альянс при этом не владеет заводами. С недавнего времени альянс появился на арене дальнего космоса. Как крупный, но далеко не доминирующий торговый представитель. К особенностям NCS относятся гибкая система контрактов, подразумевающая единый контракт на сделку - вы заключаете с альянсом договор, и можете использовать его для покупки или производства любого товара. Такая система создает множество каналов сбыта, юридический щит и многопоточную логистику для компаний производителей заключивших контракт. + +company-daybreak-description = «Мы разные, но всегда вооружены.» «Рассвет» - это не классическая ЧВК, а сеть наёмнических групп, действующих под единым флагом. Каждый отряд сохраняет собственный стиль ведения боя и внутреннюю иерархию, что делает организацию непредсказуемой и хаотичной. Первые группы «Рассвета» возникли как спонтанные союзы наёмников и авантюристов, которым было выгодно выступать под одним именем. В какой-то момент Департамент Службы Безопасности Фронтира признал «Рассвет» официально, выдав им разрешение на использование специальных боевых модификаций шаттлов. Внутри сети нет единого командования - решения принимаются на сборе лидеров отрядов, где каждый тянет одеяло на себя. Это делает «Рассвет» одновременно гибким и опасным: никто не может предсказать, как поведёт себя та или иная группа. Хаотичность структуры стала проблемой: разные отряды «Рассвета» часто действуют на грани дозволенного, что вызвало резкое охлаждение отношений с ДСБФ. + +company-ardente-description = Ardente Group - это полу-хаотичные группы наёмников, действующие под флагом Ardente Advanced Manufacturing. Они служат живой рекламой продукции компании: кораблей и корабельных орудий. В боевых контрактах и охранных миссиях эти отряды демонстрируют надёжность и мощь технологий AAM, превращая каждое столкновение в показательный тест для потенциальных покупателей. За свою деятельность Ardente Group получает спонсирование от AAM, а также эксклюзивные контракты на защиту газодобывающих шаттлов, работающих преимущественно под флагом Langstad-Voigt Heavy Industries. Именно эти шаттлы обеспечивают производство AAM необходимыми ресурсами, а присутствие Ardente Group гарантирует их безопасность. В секторе Жандер Ardente Group стала главным инструментом продвижения бренда AAM. Поскольку сама Ardente Advanced Manufacturing является молодой компанией на этом рынке и только начинает завоёвывать репутацию и позиции, её наёмники играют роль живой витрины, демонстрируя силу и эффективность технологий корпорации. Хаотичная структура и разнообразие отрядов создают образ независимой силы, но на деле они тесно связаны с интересами AAM. Для местных жителей и конкурентов это означает, что появление Ardente Group почти всегда предвещает расширение влияния Ardente Advanced Manufacturing. + +company-ardente-manufacture-description = Ardente Advanced Manufacturing начинала как небольшая мастерская по ремонту шаттлов. Со временем компания перешла к более амбициозной деятельности: скупала старые боевые корабли, восстанавливала их и перепродавала. После постройки полноценной «Верфи Арденте» AAM начала активно приобретать чертежи и лицензии устаревших боевых судов, модифицировать их и выводить на рынок. Аналогично компания занимается торговлей корабельными орудиями, покупая лицензии и продавая модернизированные версии. На других рынках Фронтира Ardente Advanced Manufacturing уже успела закрепиться как надёжный поставщик вооружённых кораблей и технологий. Теперь компания начинает покорять сектор Жандер, стремясь занять здесь столь же прочные позиции и доказать конкурентам свою силу. + +company-gobliniade-description = Возродим великий Гоблинат! Из мусора - в оружие, из хлама - в будущее! Мы - дети свалки, а каждый ржавый болт это наш манифест. Пусть Жандер дрожат: гоблины идут, чтобы построить новый порядок из старого металлолома! «Надо переписать, не круто» + +company-ussp-description = Тут пока нет описания. Увы. + +company-techniclogistic-description = TechnicLogistic — автономная мегакорпорация, обладает собственной территорией, флотом и независимой армией. В TechnicLogistic преобладает жесткая иерархическая система с четким разделением обязанностей. Сама корпорация является сеткой из множества департаментов и советов во главе которой стоит Совет девяти - группа из девяти самых влиятельных членов корпорации, совместно контролирующих ~60% акций компании. В организации также есть система званий схожая с имперской, последние можно получить за успешную работу в компании или идя по военной сфере за соответствующие заслуги. TechnicLogistic имеет один из крупнейших флотов, сравнимый с флотами небольших государственных формирований. Корпорация ведет тесное сотрудничество с NanoTrasen, благодаря этому обладает рядом передовых технологий в области исследований Блюспейса. На текущий момент находится в состоянии замороженного вооруженного конфликта с группой компаний Гефест. diff --git a/Resources/Locale/ru-RU/_Forge/customization/character-requirements.ftl b/Resources/Locale/ru-RU/_Forge/customization/character-requirements.ftl new file mode 100644 index 000000000000..f20d368bf24c --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/customization/character-requirements.ftl @@ -0,0 +1 @@ +character-minPlayers-requirement = Роль доступна от {$min} игроков в сети. diff --git a/Resources/Locale/ru-RU/_Forge/language/commands.ftl b/Resources/Locale/ru-RU/_Forge/language/commands.ftl new file mode 100644 index 000000000000..a021ebead1cf --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/language/commands.ftl @@ -0,0 +1,34 @@ +command-list-langs-desc = List languages your current entity can speak at the current moment. +command-list-langs-help = Usage: {$command} + +command-saylang-desc = Send a message in a specific language. To choose a language, you can use either the name of the language, or its position in the list of languages. +command-saylang-help = Usage: {$command} . Example: {$command} TauCetiBasic "Hello World!". Example: {$command} 1 "Hello World!" + +command-language-select-desc = Select the currently spoken language of your entity. You can use either the name of the language, or its position in the list of languages. +command-language-select-help = Usage: {$command} . Example: {$command} 1. Example: {$command} TauCetiBasic + +command-language-spoken = Spoken: +command-language-understood = Understood: +command-language-current-entry = {$id}. {$language} - {$name} (current) +command-language-entry = {$id}. {$language} - {$name} + +command-language-invalid-number = The language number must be between 0 and {$total}. Alternatively, use the language name. +command-language-invalid-language = The language {$id} does not exist or you cannot speak it. + +# Toolshed + +command-description-language-add = Adds a new language to the piped entity. The two last arguments indicate whether it should be spoken/understood. Example: 'self language:add "Canilunzt" true true' +command-description-language-rm = Removes a language from the piped entity. Works similarly to language:add. Example: 'self language:rm "TauCetiBasic" true true'. +command-description-language-lsspoken = Lists all languages the entity can speak. Example: 'self language:lsspoken' +command-description-language-lsunderstood = Lists all languages the entity can understand. Example: 'self language:lssunderstood' + +command-description-translator-addlang = Adds a new target language to the piped translator entity. See language:add for details. +command-description-translator-rmlang = Removes a target language from the piped translator entity. See language:rm for details. +command-description-translator-addrequired = Adds a new required language to the piped translator entity. Example: 'ent 1234 translator:addrequired "TauCetiBasic"' +command-description-translator-rmrequired = Removes a required language from the piped translator entity. Example: 'ent 1234 translator:rmrequired "TauCetiBasic"' +command-description-translator-lsspoken = Lists all spoken languages for the piped translator entity. Example: 'ent 1234 translator:lsspoken' +command-description-translator-lsunderstood = Lists all understood languages for the piped translator entity. Example: 'ent 1234 translator:lssunderstood' +command-description-translator-lsrequired = Lists all required languages for the piped translator entity. Example: 'ent 1234 translator:lsrequired' + +command-language-error-this-will-not-work = This will not work. +command-language-error-not-a-translator = Entity {$entity} is not a translator. diff --git a/Resources/Locale/ru-RU/_Forge/language/language-menu.ftl b/Resources/Locale/ru-RU/_Forge/language/language-menu.ftl new file mode 100644 index 000000000000..331038beba46 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/language/language-menu.ftl @@ -0,0 +1,5 @@ +# Touching for REUSE Headers +language-menu-window-title = Языки +language-menu-current-language = Текущий: {$language} +language-menu-description-header = Описание +ui-options-function-open-language-menu = Открыть меню языков diff --git a/Resources/Locale/ru-RU/_Forge/language/language-traits.ftl b/Resources/Locale/ru-RU/_Forge/language/language-traits.ftl new file mode 100644 index 000000000000..b27e55545a96 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/language/language-traits.ftl @@ -0,0 +1,57 @@ +# This file is only for the language traits. If we add species-specific languages to the list of traits, +# we should add them here in the order they are in the list, for organization. Maybe add more languages later. + +trait-category-languages = Языки + +trait-language-foreigner-light-name = Начинающий +trait-language-foreigner-light-desc = + Вы понимаете Общегалактический язык, но пока не можете свободно говорить. + У вас есть переводчик, который помогает говорить на нём. Лучше держите его заряженным. + +trait-language-foreigner-name = Незнающий +trait-language-foreigner-desc = + Вы не понимаете Общегалактический язык. И вам всегда требуется переводчик для общения. + Переводчик помогает вам понимать и говорить на нём. Лучше держите его заряженным. + +trait-language-signlanguage-name = Язык жестов +trait-language-signlanguage-desc = + Использование языка тела, жестов руками и других форм ловких движений для передачи смысла. + Вы можете понимать и использовать базовый язык жестов Общегалактического стандарта (НЖ-7.1). + Если вы немы по какой-либо причине, вы всё равно сможете общаться с помощью жестов. + +trait-language-forgeearth-name = Соларный +trait-language-forgeearth-desc = + Соларный стал официальным языком ОПЗ, объединяя множество земных наречий в единый язык. + Им пользуются государственные чиновники, вооружённые силы, а также те, кто испытывает национальную гордость за Землю + или оказался под влиянием её культуры. + +trait-language-forgetradeband-name = Торговый +trait-language-forgetradeband-desc = + Потомок латинских и романских языков старой Земли - Торговый остаётся основным языком высших слоёв. + Для большинства он звучит элегантно и стройно. Язык широко используется торговцами, дипломатами и теми, + кто стремится сохранить частицу романтического прошлого. + +trait-language-forgeashen-name = Пепельный +trait-language-forgeashen-desc = + Редко встречающийся язык за пределами Фронтира, сформировавшийся в изоляции от центра + и забытых колоний на краю космоса. + Его часто сравнивают с невнятной речью, где смысл слов определяется скорее интонацией, чем чётким произношением. + +trait-language-forgesibera-name = Сибера +trait-language-forgesibera-desc = + Ответвившийся диалект Соларного, ставший официальным языком Союза Советских Социалистических Планет. + Для своих он звучит привычно и строго, но постороннему кажется грубым и холодным. + Им пользуются государственные структуры, военные и жители окраинных миров, + сохраняя суровый характер и отчуждённость в интонациях. + +trait-language-valyrian-name = Валирийский +trait-language-valyrian-desc = + Язык, происходящий от восточноевропейских языков древней Земли. + Валирийский стандарт - основной язык гарпий, выросших на их родном мире Валирия. + Редко используется за пределами родных миров и в современности вытеснен. + +trait-language-fhydraspeak-name = Пустотный +trait-language-fhydraspeak-desc = + Мы не знаем, что это за язык и откуда он появился. Его звуки - словно эхо из иных миров: обрывки шёпотов, + переливы тона и странные вибрации, которые невозможно до конца понять. Каждое слово может быть ключом + или ловушкой, а смысл ускользает, оставляя лишь ощущение тайны и угрозы. diff --git a/Resources/Locale/ru-RU/_Forge/language/languages-sign.ftl b/Resources/Locale/ru-RU/_Forge/language/languages-sign.ftl new file mode 100644 index 000000000000..59234ce27e14 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/language/languages-sign.ftl @@ -0,0 +1,47 @@ +chat-sign-language-message-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]{$verb} "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] +chat-sign-language-whisper-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]незаметно жестами показывает "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] + +chat-speech-verb-sign-1 = жестикулирует +chat-speech-verb-sign-2 = показывает +chat-speech-verb-sign-3 = машет + +# Tajaran stuffs +chat-sign-tajaran-language-message-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]{$verb} "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] +chat-sign-tajaran-language-whisper-wrap = [italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] [BubbleContent]незаметно {$verb} "[font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font]"[/italic][/BubbleContent] + +# Did I ever tell you the definition of insanity? +# Basically we have to get around the message formatter, and unless we decide to make an entire new system just for this language, we can't do anything else. +chat-speech-verb-sign-nalrasan-1 = двигает хвостом +chat-speech-verb-sign-nalrasan-2 = слегка двигает хвостом +chat-speech-verb-sign-nalrasan-3 = быстро двигает хвостом несколько раз + +chat-speech-verb-sign-nalrasan-4 = дергает ушами +chat-speech-verb-sign-nalrasan-5 = дергает ушами пару раз +chat-speech-verb-sign-nalrasan-6 = дергает ушами несколько раз подряд + +chat-speech-verb-sign-nalrasan-7 = поворачивает уши +chat-speech-verb-sign-nalrasan-8 = поворачивает уши пару раз +chat-speech-verb-sign-nalrasan-9 = поворачивает уши несколько раз подряд +chat-speech-verb-sign-nalrasan-10 = поворачивает уши какое-то время + +chat-speech-verb-sign-nalrasan-11 = дергает хвостом +chat-speech-verb-sign-nalrasan-12 = дергает хвостом пару раз +chat-speech-verb-sign-nalrasan-13 = дергает хвостом несколько раз подряд + +chat-speech-verb-sign-nalrasan-14 = двигает ушами и хвостом +chat-speech-verb-sign-nalrasan-15 = слегка двигает ушами и хвостом +chat-speech-verb-sign-nalrasan-16 = двигает ушами и хвостом какое-то время +chat-speech-verb-sign-nalrasan-17 = двигает ушами и хвостом несколько раз подряд + +# There has to be a better way + +chat-speech-verb-sign-siiktajr-1 = двигает хвостом и мурлычет +chat-speech-verb-sign-siiktajr-2 = двигает хвостом и мяукает +chat-speech-verb-sign-siiktajr-3 = дергает ушами и мяукает +chat-speech-verb-sign-siiktajr-4 = дергает ушами и мрау-кает +chat-speech-verb-sign-siiktajr-5 = поворачивает уши и мурлычет +chat-speech-verb-sign-siiktajr-6 = поворачивает уши и мяукает +chat-speech-verb-sign-siiktajr-7 = дергает хвостом и мяукает +chat-speech-verb-sign-siiktajr-8 = дергает хвостом и мрау-кает +chat-speech-verb-sign-siiktajr-9 = двигает ушами и хвостом, мурлычет +chat-speech-verb-sign-siiktajr-10 = двигает ушами и хвостом, мяукает diff --git a/Resources/Locale/ru-RU/_Forge/language/languages.ftl b/Resources/Locale/ru-RU/_Forge/language/languages.ftl new file mode 100644 index 000000000000..9edc2c950ec8 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/language/languages.ftl @@ -0,0 +1,230 @@ +language-Universal-name = Универсальный +language-Universal-description = Что ты? + +language-Psychomantic-name = Психомантический +language-Psychomantic-description = Язык чистого смысла, свободный от ограничений слов и жестов. + +# Species +language-Bubblish-name = Пузырчатый +language-Bubblish-description = + Язык слаймов. Представляет собой смесь пузырящихся звуков и хлопков. + Для людей он крайне труден в произношении без использования механических средств. + +language-RootSpeak-name = Корневая речь +language-RootSpeak-description = + Странный язык, основанный на свистах и переливчатых звуках. + Им общаются дионы, используя вибрации и резонанс своих тел. + +language-Nekomimetic-name = Некотетик +language-Nekomimetic-description = + Для случайного слушателя этот язык кажется хаотичной смесью испорченного японского. + Однако для фелинидов и они он каким-то образом остаётся понятным и логичным. + +language-Draconic-name = Драконий +language-Draconic-description = + Общий язык унатхов - состоит из шипящих звуков и глухих тресков. + Его интонации напоминают шипение и грохот, что делает его грозным и выразительным. + +language-Canilunzt-name = Канилунцт +language-Canilunzt-description = + Гортанный язык, состоящий из рычаний, лая, визгов и активного использования ушей и хвоста. + Вулпакины говорят на нём с лёгкостью. + +language-Moffic-name = Моффик +language-Moffic-description = Язык ниан, граничащий с полной непонятностью для других. + +language-Chittin-name = Читтин +language-Chittin-description = + Язык, состоящий из щелчков, жужжания и резких насекомых звуков. + Основу речи составляют антенны, что делает его почти невозможным для изучения тем, у кого их нет. + +language-Xeeplian-name = Кспилиан +language-Xeeplian-description = + Наш язык высокоразвит, эффективен и предельно точен. + Мы взяли за привычку подражать бормотанию низших форм жизни в стремлении к нашим целям. + +language-RobotTalk-name = РоботСпик +language-RobotTalk-description = Язык, состоящий из резких бинарных щелчков, свистов, шипений и писков. + Органические существа не могут говорить на нём без специальных переводчиков. + +language-Calcic-name = Кальцик +language-Calcic-description = Костяной язык скелетов. + Звучит как гармоничный звон костей с юмористическим оттенком, + без фальшивых нот. + +language-Marish-name = Мариш +language-Marish-description = Язык, на котором говорят только Тенерождённые. Нормальные языки не способны его воспроизвести. + +language-Azaziba-name = Азазиба +language-Azaziba-description = + Родной язык асакимов, состоящий из сочетания устной речи и жестов. + +language-Hydraspeak-name = Пустотный +language-Hydraspeak-description = + Мы не знаем, что это за язык и откуда он появился. Его звуки - словно эхо из иных миров: обрывки шёпотов, + переливы тона и странные вибрации, которые невозможно до конца понять. Каждое слово может быть ключом + или ловушкой, а смысл ускользает, оставляя лишь ощущение тайны и угрозы. + + + +# == General's == +language-ForgeGalacticStandard-name = Общегалактический +language-ForgeGalacticStandard-description = + Универсальный язык, используемый во всех уголках галактики. + Прост в изучении, лишён сложных грамматических конструкций и служит основным средством общения между представителями разных рас и культур. + +language-ForgeEarthClassic-name = Соларный +language-ForgeEarthClassic-description = + Язык, возникший на Земле после смешения множества национальных языков. + В его основе лежат идеи китайского, арабского, индийского и европейских языков. + Считается «классическим» земным языком, сохранившим культурное наследие человечества. + +language-ForgeTradeband-name = Торговый +language-ForgeTradeband-description = + Язык купцов, аристократов и торговых домов. Сочетает в себе архаичные формы речи. + Звучит витиевато и благородно, подчёркивая статус говорящего. + Часто используется торговцами и дипломатами. + +language-ForgeAshen-name = Пепельный +language-ForgeAshen-description = + Редко встречающийся язык за пределами Фронтира, сформировавшийся со временем в условиях изоляции + от основных систем и забытых колоний, оставленных выживать на краю космоса. + Его часто сравнивают с невнятной, «смазанной» речью, где смысл слов определяется скорее интонацией, + чем чётким произношением. + +language-ForgeSibera-name = Сибера +language-ForgeSibera-description = + Ответвившийся диалект Соларного, со временем ставший языком Союза Советских Социалистических Планет. + Внутри он воспринимается как естественная речь, но для постороннего звучит грубо и отстранённо. + Его интонации резкие, рубленые, а слова кажутся смазанными и суровыми - + создавая ощущение строгости и отчуждённости. + +language-Eldritch-name = Эльдритч +language-Eldritch-description = + Язык, считающийся давно забытым. Теперь единственные его носители - + последователи древнего Бога, произносящие его скрежещущие и бормочущие слова. + + + +# == Special == +language-SecurityCodebase-name = Боевая кодировка +language-SecurityCodebase-description = Строгий военный шифр, используемый службой безопасности. + Короткие команды, цифро-буквенные блоки и радиокоды создают язык дисциплины и приказов. + +language-WarCode-name = Военная кодировка +language-WarCode-description = Каждая комбинация слогов - это боевой знак, зашифрованный приказ или предвестие смерти. + Язык Жнецов лишён привычных слов и жестов: он состоит из кодов, символов и искажённых звуков, понятных лишь посвящённым. + В нём скрыта угроза, тайна и сила подполья — каждое произнесённое сочетание может быть паролем, вызовом или смертным приговором. + +language-Blob-name = Блоб +language-Blob-description = Язык, на котором говорят.. иногда. Блорп! + + + +# == Other == + +language-Sign-name = Язык жестов +language-Sign-description = + Базовый язык жестов стандарта НЖ-7.1. + Распространён среди глухих и немых людей. + +language-DroneTalk-name = ДронСпик +language-DroneTalk-description = Непостижим для большинства недронов! + +language-ValyrianStandard-name = Валирийский +language-ValyrianStandard-description = + Язык, происходящий от восточноевропейских языков древней Земли. + Валирийский стандарт - основной язык гарпий, выросших на их родном мире Валирия. + Редко используется за пределами родных миров и в современности вытеснен. + Его носители - те, кто стремится сохранить традиции и верования древних народов до колониальной эпохи. + + + +# == Animal == +language-Cat-name = Кошачий +language-Cat-description = Мяу + +language-Deer-name = Олень +language-Deer-description = Ни! + +language-Dog-name = Собачий +language-Dog-description = Гав! + +language-Fox-name = Лисий +language-Fox-description = Йип! + +language-Xeno-name = Ксено +language-Xeno-description = Шшшссс! + +language-Monkey-name = Обезьяний +language-Monkey-description = Ууук! + +language-Mouse-name = Мышиный +language-Mouse-description = Писк! + +language-Chicken-name = Курицын +language-Chicken-description = Ко-ко! + +language-Duck-name = Утиный +language-Duck-description = Кря! + +language-Cow-name = Коровий +language-Cow-description = Мууу! + +language-Sheep-name = Овечий +language-Sheep-description = Бее! + +language-Kangaroo-name = Кенгурячий +language-Kangaroo-description = Чуу! + +language-Pig-name = Свиной +language-Pig-description = Хрю! + +language-Crab-name = Крабий +language-Crab-description = Щёлк! + +language-Kobold-name = Кобольдский +language-Kobold-description = Шип! + +language-Hissing-name = Шипящий +language-Hissing-description = Шшш! + +language-Penguin-name = Пингвинский +language-Penguin-description = Бваап! + + + +# == Tajaran and Shadow stuff == +language-SiikMaas-name = Сиик'маас +language-SiikMaas-description = + Древний религиозный язык таяран, ныне самый распространённый и преподаваемый. + +language-NalRasan-name = Нал'расан +language-NalRasan-description = + Диалект, насыщенный жестами, созданный охотниками М'Сай для скрытности, + позже принятый повстанцами для тайной связи во время Великой войны. + +language-SiikTajr-name = Сиик'тайр +language-SiikTajr-description = + Революционный язык, объединяющий Сиик'маас и Нал'расан. + Создан для секретности при свержении плутократии и активно использовался в Великой войне. + +language-YaSsa-name = Я'сса +language-YaSsa-description = + Утончённый диалект Сиик'маас, некогда используемый нярирской знатью. + Возрождён Новым Королевством Адхомая после веков забвения. + +language-Delvahii-name = Делвахии +language-Delvahii-description = + Язык жхан-хазан, связанный с поклонением Ма'таке. + Всё ещё используется в религиозных обрядах и любим фермерами, сопротивляющимися контролю правительства. + +language-Shadowmind-name = Тенемысль +language-Shadowmind-description = + Язык, на котором говорят шадоулинги. + О нём мало что известно, кроме того, что трэллы способны его понимать. + +language-Qiilour-name = Киилор +language-Qiilour-description = + Родной и основной язык кселтиян. На нём говорит почти каждый представитель их вида. + Это утончённое слияние нескольких древних языков - Теленаарии, Воскарна и Старого Кселтека - каждый из которых ныне утрачен. diff --git a/Resources/Locale/ru-RU/_Forge/language/translator.ftl b/Resources/Locale/ru-RU/_Forge/language/translator.ftl new file mode 100644 index 000000000000..b9a77c7f9275 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/language/translator.ftl @@ -0,0 +1,14 @@ +translator-component-shutoff = {$translator} отключен. +translator-component-turnon = {$translator} работает. + +translator-implanter-refuse = {$implanter} не оказывает никакого эффекта на {$target}. +translator-implanter-success = {$implanter} успешно внедрён в {$target}. +translator-implanter-ready = Этот имплантер, похоже, готов к использованию. +translator-implanter-used = Этот имплантер, похоже, пуст. + +translator-examined-langs-understood = Переводит с: [color=green]{$languages}[/color]. +translator-examined-langs-spoken = Переводит на: [color=green]{$languages}[/color]. +translator-examined-requires-any = Необходимо знать один из этих языков: [color=yellow]{$languages}[/color]. +translator-examined-requires-all = Необходимо знать все эти языки: [color=yellow]{$languages}[/color]. +translator-examined-enabled = Похоже, он [color=green]работает[/color]. +translator-examined-disabled = Похоже, он [color=red]отключён[/color]. diff --git a/Resources/Locale/ru-RU/_Forge/materials/materials.ftl b/Resources/Locale/ru-RU/_Forge/materials/materials.ftl new file mode 100644 index 000000000000..0e84e8eee8d1 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/materials/materials.ftl @@ -0,0 +1,11 @@ +# Ores +materials-raw-magmite = магмитовая руда + +# Metals +materials-magmite = магмитовая сталь +materials-plastitanium = пластитан +materials-titanium = титан + +# Stack +stack-plastitanium = пластитан +stack-titanium = титан diff --git a/Resources/Locale/ru-RU/_Forge/traits/traits.ftl b/Resources/Locale/ru-RU/_Forge/traits/traits.ftl new file mode 100644 index 000000000000..c4d2c81d9af2 --- /dev/null +++ b/Resources/Locale/ru-RU/_Forge/traits/traits.ftl @@ -0,0 +1,20 @@ +trait-category-skills = Навыки + +trait-crp-name = СЛР +trait-crp-desc = Вы владеете навыком сердечно-лёгочной реанимации. Иногда это действительно может спасти чью-то жизнь. + +trait-advcrp-name = Продвинутый СЛР +trait-advcrp-desc = Вы проводите сердечно-лёгочную реанимацию быстрее и эффективнее, значительно повышая шансы на спасение пациента. + +trait-thieving-name = Ловкость рук +trait-thieving-desc = Ты умеешь убеждать людей расстаться со своими вещами при помощи ловкости рук. + Ты можешь определять предметы в карманах, воровать тише и примерно на треть быстрее. + +trait-trap-avoider-name = Избегание ловушек +trait-trap-avoider-desc = У тебя врождённое чувство ловушек, и ты бессознательно их избегаешь. + Ты никогда не активируешь напольные ловушки, такие как мины, растяжки, мышеловки (если ты достаточно мал), и т. д. + +trait-self-aware-name = Самоосмотр +trait-self-aware-desc = У тебя развитая интуиция тела и чувств. + Ты можешь точно оценить тяжесть ран и ожогов, как медицинский анализатор, + а также определить наличие токсинов или нехватки воздуха. diff --git a/Resources/Locale/ru-RU/_Mono/shipyard.ftl b/Resources/Locale/ru-RU/_Mono/shipyard.ftl new file mode 100644 index 000000000000..eeee718d7b43 --- /dev/null +++ b/Resources/Locale/ru-RU/_Mono/shipyard.ftl @@ -0,0 +1,14 @@ +shipyard-direction-message = Ваш {$shipName} находится примерно в {$distance} метрах на {$direction}! +ship-access-denied = Вам нужен акт на корабль, чтобы получить доступ. +shipyard-console-capital-limited = Вы не можете иметь больше одного активного капитального судна! + +shipyard-console-denied = Вы не можете приобрести этот шаттл в данный момент. +shipyard-console-limited = Слишком много активных шаттлов этого типа. Попробуйте позже! + +shipyard-console-unassign-deed = Отвязать +shipyard-console-deed-unassigned = Шаттл был успешно отвязан от ID карты. +shipyard-console-confirm-unassign = Вы уверены? +shipyard-console-unassign-cooldown = Подождите {$minutes} минут, прежде чем отвязать шаттл. +shipyard-console-rename-label = Переименовать +shipyard-console-rename-placeholder = Название +shipyard-console-name-empty = Название не может быть пустым diff --git a/Resources/Locale/ru-RU/_Mono/shuttles/shuttle-console.ftl b/Resources/Locale/ru-RU/_Mono/shuttles/shuttle-console.ftl new file mode 100644 index 000000000000..0dcdfa949f82 --- /dev/null +++ b/Resources/Locale/ru-RU/_Mono/shuttles/shuttle-console.ftl @@ -0,0 +1 @@ +shuttle-console-crewed = Вы не сможете использовать консоль управления и консоль орудий виесте на этом шаттле.. Найдите ещё одного! diff --git a/Resources/Locale/ru-RU/_Mono/traits/self-aware.ftl b/Resources/Locale/ru-RU/_Mono/traits/self-aware.ftl new file mode 100644 index 000000000000..d5a2a583789a --- /dev/null +++ b/Resources/Locale/ru-RU/_Mono/traits/self-aware.ftl @@ -0,0 +1,5 @@ +self-aware-verb-text = Самоосмотр +self-aware-total = Общий урон: [color=#ff6347]{$amount}[/color] +self-aware-no-damage = [color=#f0fff0]Нет повреждений[/color]. +self-aware-group-line = {$group}: [color=#ff6347]{$amount}[/color] +self-aware-type-subline = · {$type}: [color=#ff6347]{$amount}[/color] diff --git a/Resources/Locale/ru-RU/_Mono/traits/traits.ftl b/Resources/Locale/ru-RU/_Mono/traits/traits.ftl new file mode 100644 index 000000000000..e895c210940b --- /dev/null +++ b/Resources/Locale/ru-RU/_Mono/traits/traits.ftl @@ -0,0 +1,58 @@ +humanoid-profile-editor-traits-not-have = Вы не должны иметь одну из этих черт: { $names } +humanoid-profile-editor-traits-not-be = Вы не должны быть: { $names } +humanoid-profile-editor-traits-expand-all = Развернуть всё +humanoid-profile-editor-traits-collapse-all = Свернуть всё + +# Physical +trait-prybar-prosthetics-name = Руки-ломы +trait-prybar-prosthetics-desc = Твои руки усилены сталью и гидравликой. Ты можешь силой выбираться из неприятных ситуаций. + +trait-vigor-name = Выносливость +trait-vigor-desc = Благодаря решимости, физической форме или бионическим улучшениям твоя выносливость повышена. + +trait-lethargy-name = Вялость +trait-lethargy-desc = Ты устаёшь быстрее других, становясь более уязвимым к истощению и усталости. + Твоя выносливость снижена на 15. + Восстановление выносливости в секунду снижено на 0.6. + Восстановление выносливости теперь начинается через 3.75 секунды после получения урона по выносливости, вместо 3 секунд. + +trait-glass-jaw-name = Хрупкая челюсть +trait-glass-jaw-desc = Твоё тело более хрупкое, чем у других, и ты сильнее подвержен критическим травмам. + Порог урона для перехода в критическое состояние снижен на 10. + +trait-tenacity-name = Упорство +trait-tenacity-desc = Благодаря силе духа, воле или лёгким бионическим улучшениям ты крепче других. + Порог урона для перехода в критическое состояние повышен на 5. + +trait-will-to-live-name = Воля к жизни +trait-will-to-live-desc = У тебя необычайно сильная воля к жизни, и ты сопротивляешься смерти больше других. + Порог урона для перехода в состояние "Мёртв" повышен на 10. + +trait-will-to-die-name = Воля к смерти +trait-will-to-die-desc = У тебя необычайно слабая воля к жизни, и ты быстрее поддаёшься травмам. + Порог урона для перехода в состояние "Мёртв" снижен на 15. + +trait-bionic-legs-name = Бионические ноги +trait-bionic-legs-desc = Одна или несколько твоих конечностей заменены дорогим, современным бионическим протезом. Это может быть как реалистичная синтплоть, так и очевидная металлическая конечность. Этот протез увеличивает скорость, позволяя быстрее убегать или добираться до места. + +trait-osteogenesis-imperfecta-name = Несовершенный остеогенез +trait-osteogenesis-imperfecta-desc = Также известен как "болезнь хрупких костей". С этим генетическим заболеванием кости легко ломаются, зачастую просто при движении. + Порог урона для перехода в критическое состояние снижен на 50. + +trait-hemophilia-name = Гемофилия +trait-hemophilia-desc = Способность твоего организма образовывать тромбы нарушена. + Ты кровоточишь примерно вдвое дольше и легче получаешь синяки, получая на 10% больше урона от тупых ударов. + +trait-voracious-name = Прожорливость +trait-voracious-desc = Ничто не стоит между тобой и едой. + Ты ешь и пьёшь в два раза быстрее. + +trait-bionic-spinarette-name = Бионическая паутинница +trait-bionic-spinarette-desc = Этот выращенный в чане орган продаётся как универсальное улучшение и доступен в клиниках по всему известному космосу. Модуль имплантируется под запястье, поглощает липиды организма и превращает их в натуральный шёлк. Маленькое отверстие в ладони позволяет "прясть" нить. + +trait-feeble-name = Слабость +trait-feeble-desc = Твоё тело плохо переносит травмы, и урон сильнее влияет на твоё движение. Для большинства видов этот эффект замедляет движение на 30% при 45 урона и на 54% при 65 урона. + +trait-ironman-name = Железный человек +trait-ironman-desc = Вы живёте исключительно на наличные. + Вы не можете снимать деньги со своего банковского счёта.. Удачи. diff --git a/Resources/Locale/ru-RU/_NF/cartridge-loader/cartridges.ftl b/Resources/Locale/ru-RU/_NF/cartridge-loader/cartridges.ftl index 20de5fc95340..822b95d8746f 100644 --- a/Resources/Locale/ru-RU/_NF/cartridge-loader/cartridges.ftl +++ b/Resources/Locale/ru-RU/_NF/cartridge-loader/cartridges.ftl @@ -13,20 +13,20 @@ ledger-no-expenses = Нет ledger-balance = Баланс: ledger-no-balance = N/A -ledger-tab-Frontier = Аванпост Фронтира +ledger-tab-Frontier = Аванпост ledger-tab-Nfsd = ДСБФ -ledger-tab-Medical = Медицинский Аванпост -Expensesledger-tab-Edison = Электростанция Эдиссона +ledger-tab-Medical = Госпиталь +Expensesledger-tab-Edison = Эдисон # Fallback, if this displays, something's wrong. ledger-tab-Unknown = Неизвестно -ledger-entry-type-TickingIncome = NT Субсидии +ledger-entry-type-TickingIncome = Субсидии ledger-entry-type-VendorTax = Налоги с продаж ledger-entry-type-CargoTax = Налоги с Карго ledger-entry-type-MailDelivered = Почтовые выплаты -ledger-entry-type-BlackMarketAtmTax = Анонимные Пожертвования -ledger-entry-type-BlackMarketShipyardTax = Анонимная перепродажа металлолома -ledger-entry-type-BluespaceReward = Выплаты за несение службы +ledger-entry-type-BlackMarketAtmTax = Пожертвования +ledger-entry-type-BlackMarketShipyardTax = Перепродажа металлолома +ledger-entry-type-BluespaceReward = Выплаты за службу ledger-entry-type-MedicalBountyTax = Медицинские выплаты ledger-entry-type-AntiSmugglingBonus = Борьба с контрабандой ledger-entry-type-StationDepositFines = Начисленные штрафы @@ -44,3 +44,16 @@ ledger-entry-type-StationWithdrawalOther = Прочее ledger-entry-type-PowerTransmission = Экспорт энергии ledger-entry-type-ShipyardRenameFee = Верфь + +ledger-tab-BlackMarket = Неизвестно +ledger-tab-Edison = Эдисон +ledger-entry-type-AtmTax = Налоги с банкоматов +ledger-entry-type-ShipyardTax = Налоги с верфи +ledger-entry-type-BlackMarketSales = Продажа кексов +ledger-entry-type-ColonialOutpostSales = Налоги на грузы +ledger-entry-type-NFSDSales = Налоги с оружия +ledger-entry-type-MedicalSales = Налоги с медикаментов +ledger-entry-type-BlackMarketPenalties = Конфискация имущества +ledger-entry-type-FrontierPenalties = Оборот контрабанды +ledger-entry-type-NFSDPenalties = Оборот контрабанды +ledger-entry-type-MedicalPenalties = Наркоконтроль diff --git a/Resources/Locale/ru-RU/_NF/shipyard/shipyard-console-component.ftl b/Resources/Locale/ru-RU/_NF/shipyard/shipyard-console-component.ftl index edc90b2131c9..862a021c6186 100644 --- a/Resources/Locale/ru-RU/_NF/shipyard/shipyard-console-component.ftl +++ b/Resources/Locale/ru-RU/_NF/shipyard/shipyard-console-component.ftl @@ -82,14 +82,6 @@ shipyard-console-dangerous-materials = На борту обнаружены оп shipyard-console-invalid-voucher-type = Этот ваучер не может быть использован на этой консоли. shipyard-console-fallback-prevent-sale = Обнаружены ошибки класса YML на борту. Пожалуйста, отправьте отчет об ошибке, когда это возможно. -shipyard-console-unassign-deed = Отвязать -shipyard-console-deed-unassigned = Шаттл был успешно отвязан от ID карты. -shipyard-console-confirm-unassign = Вы уверены? -shipyard-console-unassign-cooldown = Подождите {$minutes} минут, прежде чем отвязать шаттл. -shipyard-console-rename-label = Переименовать -shipyard-console-rename-placeholder = Название -shipyard-console-name-empty = Название не может быть пустым - shipyard-console-name-too-long = Имя корабля не может превышать { $max } символов. shipyard-console-rename-success = Шаттл переименован в «{ $name }». shipyard-console-rename-failed = Не удалось переименовать шаттл. diff --git a/Resources/Locale/ru-RU/_NF/tips.ftl b/Resources/Locale/ru-RU/_NF/tips.ftl index 8cdf6ca0e5fa..eb5204e2c589 100644 --- a/Resources/Locale/ru-RU/_NF/tips.ftl +++ b/Resources/Locale/ru-RU/_NF/tips.ftl @@ -14,7 +14,7 @@ nf-tips-dataset-13 = Не забывайте выходить на улицу и nf-tips-dataset-14 = Вы можете использовать клавишу «Активировать в мире» (по умолчанию E), чтобы взаимодействовать с объектами, не беря их в руки. nf-tips-dataset-15 = Здравый смысл помогает избежать конфликтов. nf-tips-dataset-16 = Каждый другой игрок в игре — это тоже человек. -nf-tips-dataset-17 = Химикаты не реагируют, находясь в буфере ХимМастера. +nf-tips-dataset-17 = Представитель Фронтира, Диспетчер, Представитель ЮД и Детектив понимают язык жестов. Учитывайте это при разговоре со своим подельником. nf-tips-dataset-18 = Не зли бармена, бросая его стаканы! Вежливо ставьте их на стол, нажав Q. nf-tips-dataset-19 = Вы можете удерживать клавишу SPACE (по умолчанию), чтобы замедлить движение шаттла во время пилотирования, что позволит совершать точные манёвры или даже полностью остановиться. nf-tips-dataset-20 = У каждого члена экипажа в аварийном наборе есть медицинский автоинжектор с эпинефрином и транексамовой кислотой. diff --git a/Resources/Locale/ru-RU/chat/managers/chat-manager.ftl b/Resources/Locale/ru-RU/chat/managers/chat-manager.ftl index cbacb932e90f..980f58afb1fc 100644 --- a/Resources/Locale/ru-RU/chat/managers/chat-manager.ftl +++ b/Resources/Locale/ru-RU/chat/managers/chat-manager.ftl @@ -20,10 +20,22 @@ chat-manager-server-wrap-message = [bold]{ $message }[/bold] chat-manager-sender-announcement = Управления Секторальным Флотом chat-manager-sender-announcement-wrap-message = [font size=14][bold]Объявление { $sender }:[/font][font size=12] { $message }[/bold][/font] -chat-manager-entity-say-wrap-message = [BubbleHeader][bold][Name]{ $entityName }[/Name][/bold][/BubbleHeader] { $verb }, [font={ $fontType } size={ $fontSize } ]"[BubbleContent]{ $message }[/BubbleContent]"[/font] -chat-manager-entity-say-bold-wrap-message = [BubbleHeader][bold][Name]{ $entityName }[/Name][/bold][/BubbleHeader] { $verb }, [font={ $fontType } size={ $fontSize }]"[BubbleContent][bold]{ $message }[/bold][/BubbleContent]"[/font] -chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader][Name]{ $entityName }[/Name][/BubbleHeader] шепчет,"[BubbleContent]{ $message }[/BubbleContent]"[/italic][/font] -chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic][BubbleHeader]Кто-то[/BubbleHeader] шепчет, "[BubbleContent]{ $message }[/BubbleContent]"[/italic][/font] + +# chat-manager-entity-say-wrap-message = [BubbleHeader][bold][Name]{ $entityName }[/Name][/bold][/BubbleHeader] { $verb }, [font={ $fontType } size={ $fontSize } ]"[BubbleContent]{ $message }[/BubbleContent]"[/font] +# chat-manager-entity-say-bold-wrap-message = [BubbleHeader][bold][Name]{ $entityName }[/Name][/bold][/BubbleHeader] { $verb }, [font={ $fontType } size={ $fontSize }]"[BubbleContent][bold]{ $message }[/bold][/BubbleContent]"[/font] +# chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader][Name]{ $entityName }[/Name][/BubbleHeader] шепчет,"[BubbleContent]{ $message }[/BubbleContent]"[/italic][/font] +# chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic][BubbleHeader]Кто-то[/BubbleHeader] шепчет, "[BubbleContent]{ $message }[/BubbleContent]"[/italic][/font] + +# Einstein Engines - Language begin (changing colors for text based on language color in handler) +# For the message in double quotes, the font/color/bold/italic elements are repeated twice, outside the double quotes and inside. +# The outside elements are for formatting the double quotes, and the inside elements are for formatting the text in speech bubbles ([BubbleContent]). +chat-manager-entity-say-wrap-message = [BubbleHeader][bold][Name]{$entityName}[/Name][/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent][font="{$fontType}" size={$fontSize}][color={$color}]{$message}[/color][/font][/BubbleContent]"[/font] +chat-manager-entity-say-bold-wrap-message = [BubbleHeader][bold][Name]{$entityName}[/Name][/bold][/BubbleHeader] {$verb}, [font={$fontType} size={$fontSize}]"[BubbleContent][font="{$fontType}" size={$fontSize}][bold][color={$color}]{$message}[/color][/font][/bold][/BubbleContent]"[/font] + +chat-manager-entity-whisper-wrap-message = [font size=11][italic][BubbleHeader][Name]{$entityName}[/Name][/BubbleHeader] шепчет, "[BubbleContent][color={$color}][font="{$fontType}"]{$message}[/font][/color][/BubbleContent][font size=11]"[/italic][/font] +chat-manager-entity-whisper-unknown-wrap-message = [font size=11][italic][BubbleHeader]Кто-то[/BubbleHeader] шепчет, "[BubbleContent][color={$color}][font="{$fontType}"]{$message}[/color][/font][/BubbleContent][font size=11]"[/italic][/font] +# Einstein Engines - Language end + # THE() is not used here because the entity and its name can technically be disconnected if a nameOverride is passed... chat-manager-entity-me-wrap-message = [italic]{ $entityName } { $message }[/italic] chat-manager-entity-looc-wrap-message = LOOC: [bold]{ $entityName }:[/bold] { $message } diff --git a/Resources/Locale/ru-RU/headset/headset-component.ftl b/Resources/Locale/ru-RU/headset/headset-component.ftl index ef1e2614b958..3f479e4d2cae 100644 --- a/Resources/Locale/ru-RU/headset/headset-component.ftl +++ b/Resources/Locale/ru-RU/headset/headset-component.ftl @@ -1,7 +1,14 @@ # Chat window radio wrap (prefix and postfix) -chat-radio-message-wrap = [color={ $color }]{ $channel } [bold]{ $name }[/bold] { $verb }, [font={ $fontType } size={ $fontSize }]"{ $message }"[/font][/color] -chat-radio-message-wrap-bold = [color={ $color }]{ $channel } [bold]{ $name }[/bold] { $verb }, [font={ $fontType } size={ $fontSize }][bold]"{ $message }"[/bold][/font][/color] +# chat-radio-message-wrap = [color={ $color }]{ $channel } [bold]{ $name }[/bold] { $verb }, [font={ $fontType } size={ $fontSize }]"{ $message }"[/font][/color] +# chat-radio-message-wrap-bold = [color={ $color }]{ $channel } [bold]{ $name }[/bold] { $verb }, [font={ $fontType } size={ $fontSize }][bold]"{ $message }"[/bold][/font][/color] + +# Einstein Engines - Languages begin (change text color based on language color set in handler) +chat-radio-message-wrap = [color={$color}]{$channel} [bold]{$name}[/bold] {$verb}, "[/color][font="{$fontType}" size={$fontSize}][color={$languageColor}]{$message}[/color][/font][color={$color}]"[/color] +chat-radio-message-wrap-bold = [color={$color}]{$channel} [bold]{$name}[/bold] {$verb}, "[/color][font="{$fontType}" size={$fontSize}][color={$languageColor}][bold]{$message}[/bold][/font][/color][color={$color}]"[/color] +# Einstein Engines - Languages end + examine-headset-default-channel = Отображается, что каналом по умолчанию этой гарнитуры является [color={ $color }]{ $channel }[/color]. + chat-radio-common = Общий chat-radio-centcom = УСФ chat-radio-command = Командный diff --git a/Resources/Locale/ru-RU/materials/materials.ftl b/Resources/Locale/ru-RU/materials/materials.ftl index 920353b54a1c..7a46e33bbfd1 100644 --- a/Resources/Locale/ru-RU/materials/materials.ftl +++ b/Resources/Locale/ru-RU/materials/materials.ftl @@ -4,7 +4,6 @@ materials-reinforced-glass = бронестекло materials-plasma-glass = плазменное стекло materials-reinforced-plasma-glass = плазменное бронестекло # Metals -materials-magmite = магмитовая сталь materials-steel = сталь materials-gold = золото materials-silver = серебро @@ -27,7 +26,6 @@ materials-coal = уголь materials-diamond = алмазы materials-gunpowder = чёрный порох # Ores -materials-raw-magmite = магмитовая руда materials-raw-iron = руда железа materials-raw-quartz = руда кварца materials-raw-gold = руда золота diff --git a/Resources/Locale/ru-RU/preferences/ui/humanoid-profile-editor.ftl b/Resources/Locale/ru-RU/preferences/ui/humanoid-profile-editor.ftl index 98d57aa12ef7..f1681639d8a1 100644 --- a/Resources/Locale/ru-RU/preferences/ui/humanoid-profile-editor.ftl +++ b/Resources/Locale/ru-RU/preferences/ui/humanoid-profile-editor.ftl @@ -53,5 +53,11 @@ humanoid-profile-editor-traits-tab = Черты персонажа humanoid-profile-editor-no-traits = Нет доступных черт humanoid-profile-editor-trait-count-hint = Доступно очков: [{ $current }/{ $max }] trait-category-disabilities = Ограничения -trait-category-speech = Черты речи +trait-category-speech = Акцент trait-category-quirks = Причуды + +# Mono +humanoid-profile-editor-clear-all-traits-button = Очистить всё +humanoid-profile-editor-clear-all-traits-confirm = Подтвердить + +trait-category-physical = Физические diff --git a/Resources/Locale/ru-RU/shuttles/console.ftl b/Resources/Locale/ru-RU/shuttles/console.ftl index 8fb10d0cecb5..7b3b37986daa 100644 --- a/Resources/Locale/ru-RU/shuttles/console.ftl +++ b/Resources/Locale/ru-RU/shuttles/console.ftl @@ -20,6 +20,7 @@ shuttle-console-nav-settings = Настройки shuttle-console-iff-toggle = Показ системы опознавания shuttle-console-dock-toggle = Показ стыковочных портов shuttle-console-iffshuttles-toggle = Показать шаттлы +shuttle-console-extra-info-toggle = Показать доп. информацию # MAP @@ -50,3 +51,4 @@ shuttle-console-orientation-value = {$angle} shuttle-console-linear-velocity-value = {$X}, {$Y} shuttle-console-angular-velocity-value = {$angularVelocity} shuttle-console-ftl-state-Invalid = Неверный +shuttle-console-undock-all-label = Отстыковать все diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_EE/objects/devices.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_EE/objects/devices.ftl new file mode 100644 index 000000000000..69ff11a57bfe --- /dev/null +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_EE/objects/devices.ftl @@ -0,0 +1,66 @@ +ent-Translator = переводчик + .desc = Специальный переводчик, помогающий понимать предустановленный язык. + +ent-TranslatorUnpowered = { ent-Translator } + .desc = { ent-Translator.desc } + +ent-TranslatorPoweredBase = { ent-Translator } + .desc = { ent-Translator.desc } + +ent-TranslatorForeigner = { ent-Translator } + .desc = Специальный переводчик, помогающий иностранцам говорить и понимать Общегалактический. + .suffix = Не использовать, Новичковый + +ent-CanilunztTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Канилунцт +ent-BubblishTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Пузырчатый +ent-NekomimeticTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Некотетик +ent-DraconicTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Драконий +ent-RootSpeakTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Корневая речь +ent-MofficTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Моффик +ent-XenoTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Кспилиан +ent-AnimalTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Животные +ent-ValyrianStandardTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Валирийский +ent-AzazibaTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Не использовать, Азазиба +ent-ChittinTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Читтин +ent-SiikMaasTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Сиик'маас +ent-MarishTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Мариш + +# Forge-change add +ent-ForgeEarthClassicTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Соларный +ent-ForgeSiberaTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Сибера +ent-ForgeAshenTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Пепельный +ent-ForgeTradebandTranslator = { ent-Translator } + .desc = { ent-Translator.desc } + .suffix = Торговый \ No newline at end of file diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/_Forge/entities/objects/materials/metal.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/_Forge/entities/objects/materials/metal.ftl new file mode 100644 index 000000000000..96f188253ad7 --- /dev/null +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/_Forge/entities/objects/materials/metal.ftl @@ -0,0 +1,27 @@ +ent-SheetMagmite = магмитовая сталь + .suffix = Полный + .desc = Лист крайне плотной и сложной в производстве магмитовой стали. +ent-SheetMagmite1 = магмитовая сталь + .suffix = Один + .desc = Лист крайне плотной и сложной в производстве магмитовой стали. + +ent-SheetPlastitanium = пластитан + .desc = Высокопрочный сплав, изготовление которого требует немалых затрат. + .suffix = Полный, 30 +ent-SheetPlastitanium1 = пластитан + .desc = Высокопрочный сплав, изготовление которого требует немалых затрат. + .suffix = 1 +ent-SheetPlastitanium10 = пластитан + .desc = Высокопрочный сплав, изготовление которого требует немалых затрат. + .suffix = 10 + +ent-SheetTitanium = титан + .desc = Прочный и лёгкий металл, ценимый за устойчивость к коррозии и долговечность. + .suffix = Полный, 30 +ent-SheetTitanium1 = титан + .desc = Прочный и лёгкий металл, ценимый за устойчивость к коррозии и долговечность. + .suffix = 1 +ent-SheetTitanium10 = титан + .desc = Прочный и лёгкий металл, ценимый за устойчивость к коррозии и долговечность. + .suffix = 10 + diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/materials/sheets/metal.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/materials/sheets/metal.ftl index 6ac2221ab432..0986687078be 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/materials/sheets/metal.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/materials/sheets/metal.ftl @@ -30,9 +30,3 @@ ent-SheetPlasteel10 = пласталь ent-SheetPlasteel1 = пласталь .suffix = Один .desc = { ent-SheetPlasteel.desc } -ent-SheetMagmite = магмитовая сталь - .suffix = Полный - .desc = Лист крайне плотной и сложной в производстве магмитовой стали. -ent-SheetMagmite1 = магмитовая сталь - .suffix = Один - .desc = Лист крайне плотной и сложной в производстве магмитовой стали. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/walls/walls.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/walls/walls.ftl index 5d1259ffde2e..33dc00081a11 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/walls/walls.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/walls/walls.ftl @@ -27,7 +27,7 @@ ent-WallPlastitaniumIndestructible = пластитановая стена .suffix = Неразрушимый .desc = { ent-BaseWall.desc } ent-WallPlastitanium = пластитановая стена - .desc = { ent-WallPlastitaniumIndestructible } + .desc = { ent-WallPlastitaniumIndestructible.desc } ent-WallPlastitaniumDiagonal = пластитановая стена .suffix = Диагональ .desc = { ent-WallShuttleDiagonal.desc } diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 08c5aca2f7f2..8e205fc49b45 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -503,3 +503,10 @@ - type: InteractionPopup interactSuccessSound: path: /Audio/Ambience/Objects/periodic_beep.ogg + - type: LanguageKnowledge # Einstein Engines - Languages + speaks: + - ForgeGalacticStandard + - RobotTalk + understands: + - ForgeGalacticStandard + - RobotTalk diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 6c82fb07ce7a..712a3c04ed7a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -52,8 +52,13 @@ flavorKind: station-event-random-sentience-flavor-organic - type: Bloodstream bloodMaxVolume: 50 - - type: ReplacementAccent - accent: mouse + # - type: ReplacementAccent + # accent: mouse + - type: LanguageKnowledge # Einstein Engines - Language + speaks: + - Mouse + understands: + - Mouse - type: MeleeWeapon soundHit: path: /Audio/Effects/bite.ogg @@ -269,8 +274,13 @@ eggSpawn: - id: FoodEggLaid # Frontier: FoodEgg> 4 + replacement: #Mono: Expanded just o and k with a more monke syllable set + # Forge-change + # - A + # - AA + # - AH + # - HA + # - HH + # - O + # - OO + # - OOK + # - OKO + - А + - Аа + - Ах + - У + - Хя + - О + - УО + - УУК + - ОКУ + - УУ + - ОУ + +- type: language + id: Mouse + obfuscation: + !type:SyllableObfuscation + minSyllables: 2 + maxSyllables: 3 + replacement: + # Forge-change + # - squ + # - eak + # - pi + # - ep + # - chuu + # - ee + # - fwi + # - he + - пис + - пии + - чии + - чуу + - иии + - фви + - сквик + - эп + +- type: language + id: Chicken + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - co + # - coo + # - ot + - ко + - коо + - курр + - кок + +- type: language + id: Duck + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - qu + # - ack + # - quack + - кря + - кряк + - квак + +- type: language + id: Cow + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - moo + # - mooo + - му + - муу + - мууу + +- type: language + id: Sheep + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - ba + # - baa + # - aa + - бе + - бее + - мее + +- type: language + id: Kangaroo + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - shre + # - ack + # - chuu + # - choo + - шрр + - ак + - чуу + - чо + - хоп + +- type: language + id: Pig + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - oink # Please someone come up with something better + - хрю + - хрюк + - оинк + +- type: language + id: Crab + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - click + # - clack + # - ti + # - pi + # - tap + # - cli + # - ick + - щелк + - клац + - клак + - тик + - пи + - тап + - клик + +- type: language + id: Kobold + obfuscation: + !type:SyllableObfuscation + minSyllables: 2 + maxSyllables: 4 + replacement: + # Forge-change + # - yip + # - yap + # - gar + # - grr + # - ar + # - scre + # - et + # - gronk + # - hiss + # - ss + # - ee + - йип + - йап + - гар + - грр + - ар + - скре + - ет + - гронак + - хисс + - сс + - еэ + +- type: language + id: Hissing + obfuscation: + !type:SyllableObfuscation + minSyllables: 2 + maxSyllables: 4 + replacement: + # Forge-change + # - hss + # - iss + # - ss + # - is + - хсс + - исс + - ссс + - иш + +- type: language + id: Penguin + obfuscation: + !type:SyllableObfuscation + minSyllables: 2 + maxSyllables: 3 + replacement: # I'm out of ideas + # Forge-change + # - pen + # - peng + # - won + # - wonk + # - wong + - пен + - пенг + - пинг + - понг + - пнг + - вонк + - вунк + - уинк + +- type: language # Goobstation - For Deer + id: Deer + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 3 + replacement: + # Forge-change + # - neigh + # - ni + # - brr + - мее + - ни + - брр + - бру diff --git a/Resources/Prototypes/_EE/Language/genericlanguages.yml b/Resources/Prototypes/_EE/Language/genericlanguages.yml new file mode 100644 index 000000000000..1ebe6460e369 --- /dev/null +++ b/Resources/Prototypes/_EE/Language/genericlanguages.yml @@ -0,0 +1,334 @@ +# The universal language. This is technically used as a fallback for simulating the pre-languages +# style of Chat, and is not normally accessible by players. +- type: language + id: Universal + obfuscation: + !type:ReplacementObfuscation + replacement: + - "*incomprehensible*" # Never actually used. + +# Used by Robots. +# TODO: Replace this with much better languages. Yes, robots can have languages. +- type: language + id: RobotTalk + isVisibleLanguage: true + speech: + fontId: Monospace + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 10 # Crazy + replacement: + - 0 + - 1 + +# Insanely long. +- type: language + id: DroneTalk + isVisibleLanguage: true + speech: + fontId: Monospace + obfuscation: + !type:SyllableObfuscation + minSyllables: 1 + maxSyllables: 10 + replacement: + - 00 + - 01 + - 02 + - 03 + - 04 + - 05 + - 06 + - 07 + - 08 + - 09 + - 0A + - 0B + - 0C + - 0D + - 0E + - 0F + - 10 + - 11 + - 12 + - 13 + - 14 + - 15 + - 16 + - 17 + - 18 + - 19 + - 1A + - 1B + - 1C + - 1D + - 1E + - 1F + - 20 + - 21 + - 22 + - 23 + - 24 + - 25 + - 26 + - 27 + - 28 + - 29 + - 2A + - 2B + - 2C + - 2D + - 2E + - 2F + - 30 + - 31 + - 32 + - 33 + - 34 + - 35 + - 36 + - 37 + - 38 + - 39 + - 3A + - 3B + - 3C + - 3D + - 3E + - 3F + - 40 + - 41 + - 42 + - 43 + - 44 + - 45 + - 46 + - 47 + - 48 + - 49 + - 4A + - 4B + - 4C + - 4D + - 4E + - 4F + - 50 + - 51 + - 52 + - 53 + - 54 + - 55 + - 56 + - 57 + - 58 + - 59 + - 5A + - 5B + - 5C + - 5D + - 5E + - 5F + - 60 + - 61 + - 62 + - 63 + - 64 + - 65 + - 66 + - 67 + - 68 + - 69 + - 6A + - 6B + - 6C + - 6D + - 6E + - 6F + - 70 + - 71 + - 72 + - 73 + - 74 + - 75 + - 76 + - 77 + - 78 + - 79 + - 7A + - 7B + - 7C + - 7D + - 7E + - 7F + - 80 + - 81 + - 82 + - 83 + - 84 + - 85 + - 86 + - 87 + - 88 + - 89 + - 8A + - 8B + - 8C + - 8D + - 8E + - 8F + - 90 + - 91 + - 92 + - 93 + - 94 + - 95 + - 96 + - 97 + - 98 + - 99 + - 9A + - 9B + - 9C + - 9D + - 9E + - 9F + - A0 + - A1 + - A2 + - A3 + - A4 + - A5 + - A6 + - A7 + - A8 + - A9 + - AA + - AB + - AC + - AD + - AE + - AF + - B0 + - B1 + - B2 + - B3 + - B4 + - B5 + - B6 + - B7 + - B8 + - B9 + - BA + - BB + - BC + - BD + - BE + - BF + - C0 + - C1 + - C2 + - C3 + - C4 + - C5 + - C6 + - C7 + - C8 + - C9 + - CA + - CB + - CC + - CD + - CE + - CF + - D0 + - D1 + - D2 + - D3 + - D4 + - D5 + - D6 + - D7 + - D8 + - D9 + - DA + - DB + - DC + - DD + - DE + - DF + - E0 + - E1 + - E2 + - E3 + - E4 + - E5 + - E6 + - E7 + - E8 + - E9 + - EA + - EB + - EC + - ED + - EE + - EF + - F0 + - F1 + - F2 + - F3 + - F4 + - F5 + - F6 + - F7 + - F8 + - F9 + - FA + - FB + - FC + - FD + - FE + - FF + +# Example of a sign language. Used by the Sign Language trait. +- type: language + id: Sign + speech: + allowRadio: false + requireSpeech: false + color: "#dddddd" + messageWrapOverrides: + Speak: chat-sign-language-message-wrap + Whisper: chat-sign-language-whisper-wrap + speechVerbOverrides: + - chat-speech-verb-sign-1 + - chat-speech-verb-sign-2 + - chat-speech-verb-sign-3 + obfuscation: + !type:ReplacementObfuscation + replacement: + # Forge-change + # - something + # - a cryptic message + # - a signal + # - a message + - что-то + - загадочный жест + - сигнал + - послание + + #Used for Xenoglossy, and anything else with the UniversalLanguageSpeaker component +- type: language + id: Psychomantic + speech: + color: "#C29EFF" # a nice psychic purple, a bit lighter than Ya'ssa + # fontId: Megrim # Experimental and alien, but still hopefully clean enough to read #* FONTS NOT ALREADY HERE ARE NOT BEING ADDED + speechVerbOverrides: + - chat-speech-verb-Psychomantic-1 + - chat-speech-verb-Psychomantic-2 + - chat-speech-verb-Psychomantic-3 + - chat-speech-verb-Psychomantic-4 + obfuscation: + !type:ReplacementObfuscation + replacement: + - "*incomprehensible*" # Never actually used diff --git a/Resources/Prototypes/_EE/Objects/Devices/translators.yml b/Resources/Prototypes/_EE/Objects/Devices/translators.yml new file mode 100644 index 000000000000..9edfd5da29fa --- /dev/null +++ b/Resources/Prototypes/_EE/Objects/Devices/translators.yml @@ -0,0 +1,428 @@ +# Translator that doesn't need power to work. +- type: entity + categories: [ HideSpawnMenu ] + id: TranslatorUnpowered + parent: BaseItem + name: translator + description: Translates speech. + components: + - type: Sprite + sprite: _EE/Objects/Devices/translator.rsi + state: icon + layers: + - state: icon + - state: translator + shader: unshaded + # visible: false + map: [ "enum.ToggleableVisuals.Enabled", "enum.PowerDeviceVisualLayers.Powered" ] + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleableVisuals.Enabled: + enum.PowerDeviceVisualLayers.Powered: + True: { visible: true } + False: { visible: false } + - type: HandheldTranslator + enabled: false + - type: Clothing # To allow equipping translators on the neck slot. + slots: [neck] + equipDelay: 0.3 + unequipDelay: 0.3 + quickEquip: false # Would conflict + +# Base translator that uses a power cell. Starts with an empty slot. +- type: entity + categories: [ HideSpawnMenu ] + id: TranslatorPoweredBase + parent: [ TranslatorUnpowered, PowerCellSlotSmallItem ] # Forge-change: PowerCellSlotSmallItem