diff --git a/Content.Client/ADT/Language/LanguageMenuUIController.cs b/Content.Client/ADT/Language/LanguageMenuUIController.cs new file mode 100644 index 0000000000..791b616bb3 --- /dev/null +++ b/Content.Client/ADT/Language/LanguageMenuUIController.cs @@ -0,0 +1,51 @@ +using Content.Client.ADT.Language; +using Content.Client.Gameplay; +using Content.Shared.Language; +using Robust.Client.UserInterface.Controllers; +using Robust.Client.UserInterface.Controls; +using static Content.Shared.Language.Systems.SharedLanguageSystem; + +namespace Content.Client.ADT.Language; + +public sealed class LanguageMenuUIController : UIController, IOnStateEntered, IOnStateExited +{ + public LanguageMenuWindow? _languageWindow; + + public override void Initialize() + { + EntityManager.EventBus.SubscribeLocalEvent(OnActionMenu); + EntityManager.EventBus.SubscribeEvent(EventSource.Network, this, OnStateUpdate); + } + + private void OnStateUpdate(LanguageMenuStateMessage ev) + { + if (_languageWindow == null) + return; + + _languageWindow.UpdateState(ev); + } + + private void OnActionMenu(EntityUid uid, LanguageSpeakerComponent component, LanguageMenuActionEvent args) + { + if (_languageWindow == null) + return; + + if (!_languageWindow.IsOpen) + { + _languageWindow.Open(); + EntityManager.EntityNetManager?.SendSystemNetworkMessage(new RequestLanguageMenuStateMessage()); + } + } + + public void OnStateEntered(GameplayState state) + { + _languageWindow = UIManager.CreateWindow(); + LayoutContainer.SetAnchorPreset(_languageWindow, LayoutContainer.LayoutPreset.Center); + } + + public void OnStateExited(GameplayState state) + { + _languageWindow?.Dispose(); + _languageWindow = null; + } +} diff --git a/Content.Client/ADT/Language/LanguageMenuWindow.xaml b/Content.Client/ADT/Language/LanguageMenuWindow.xaml new file mode 100644 index 0000000000..188b3bc3b5 --- /dev/null +++ b/Content.Client/ADT/Language/LanguageMenuWindow.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/Content.Client/ADT/Language/LanguageMenuWindow.xaml.cs b/Content.Client/ADT/Language/LanguageMenuWindow.xaml.cs new file mode 100644 index 0000000000..0a795aebbd --- /dev/null +++ b/Content.Client/ADT/Language/LanguageMenuWindow.xaml.cs @@ -0,0 +1,124 @@ +using Content.Client.Language.Systems; +using Content.Shared.Language; +using Content.Shared.Language.Systems; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Console; +using Robust.Shared.Utility; +using static Content.Shared.Language.Systems.SharedLanguageSystem; + +namespace Content.Client.ADT.Language; // This EXACT class must have the _NF part because of xaml linking + +[GenerateTypedNameReferences] +public sealed partial class LanguageMenuWindow : DefaultWindow +{ + [Dependency] private readonly IConsoleHost _consoleHost = default!; + private readonly LanguageSystem _language; + + private readonly List _entries = new(); + + public LanguageMenuWindow() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + _language = IoCManager.Resolve().GetEntitySystem(); + + Title = Loc.GetString("language-menu-window-title"); + } + + public void UpdateState(LanguageMenuStateMessage state) + { + var clanguage = _language.GetLanguage(state.CurrentLanguage); + CurrentLanguageLabel.Text = Loc.GetString("language-menu-current-language", ("language", clanguage?.LocalizedName ?? "")); + + OptionsList.RemoveAllChildren(); + _entries.Clear(); + + foreach (var language in state.Options) + { + AddLanguageEntry(language); + } + + // Disable the button for the currently chosen language + foreach (var entry in _entries) + { + if (entry.button != null) + entry.button.Disabled = entry.language == state.CurrentLanguage; + } + } + + private void AddLanguageEntry(string language) + { + var proto = _language.GetLanguage(language); + var state = new EntryState { language = language }; + + var container = new BoxContainer(); + container.Orientation = BoxContainer.LayoutOrientation.Vertical; + + // Create and add a header with the name and the button to select the language + { + var header = new BoxContainer(); + header.Orientation = BoxContainer.LayoutOrientation.Horizontal; + + header.Orientation = BoxContainer.LayoutOrientation.Horizontal; + header.HorizontalExpand = true; + header.SeparationOverride = 2; + + var name = new Label(); + name.Text = proto?.LocalizedName ?? ""; + name.MinWidth = 50; + name.HorizontalExpand = true; + + var button = new Button(); + button.Text = "Выбрать"; + button.OnPressed += _ => OnLanguageChosen(language); + state.button = button; + + header.AddChild(name); + header.AddChild(button); + + container.AddChild(header); + } + + // Create and add a collapsible description + { + var body = new CollapsibleBody(); + body.HorizontalExpand = true; + body.Margin = new Thickness(4f, 4f); + + var description = new RichTextLabel(); + description.SetMessage(proto?.LocalizedDescription ?? ""); + description.HorizontalExpand = true; + + body.AddChild(description); + + var collapser = new Collapsible(Loc.GetString("language-menu-description-header"), body); + collapser.Orientation = BoxContainer.LayoutOrientation.Vertical; + collapser.HorizontalExpand = true; + + container.AddChild(collapser); + } + + // Before adding, wrap the new container in a PanelContainer to give it a distinct look + var wrapper = new PanelContainer(); + wrapper.StyleClasses.Add("PdaBorderRect"); + + wrapper.AddChild(container); + OptionsList.AddChild(wrapper); + + _entries.Add(state); + } + + private void OnLanguageChosen(string id) + { + _consoleHost.ExecuteCommand("lsselectlang " + id); + } + + private struct EntryState + { + public string language; + public Button? button; + } +} diff --git a/Content.Client/ADT/Language/Systems/LanguageSystem.cs b/Content.Client/ADT/Language/Systems/LanguageSystem.cs new file mode 100644 index 0000000000..4d603a700a --- /dev/null +++ b/Content.Client/ADT/Language/Systems/LanguageSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Language.Systems; + +namespace Content.Client.Language.Systems; + +public sealed class LanguageSystem : SharedLanguageSystem +{ + +} diff --git a/Content.Client/ADT/Language/Systems/TranslatorImplanterSystem.cs b/Content.Client/ADT/Language/Systems/TranslatorImplanterSystem.cs new file mode 100644 index 0000000000..bbe28d24f5 --- /dev/null +++ b/Content.Client/ADT/Language/Systems/TranslatorImplanterSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Language.Systems; + +namespace Content.Client.Language.Systems; + +public sealed class TranslatorImplanterSystem : SharedTranslatorImplanterSystem +{ + +} diff --git a/Content.Server/ADT/Language/Commands/ListLanguagesCommand.cs b/Content.Server/ADT/Language/Commands/ListLanguagesCommand.cs new file mode 100644 index 0000000000..eda7030b9b --- /dev/null +++ b/Content.Server/ADT/Language/Commands/ListLanguagesCommand.cs @@ -0,0 +1,39 @@ +using System.Linq; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.Enums; + +namespace Content.Server.Language.Commands; + +[AnyCommand] +public sealed class ListLanguagesCommand : IConsoleCommand +{ + public string Command => "lslangs"; + public string Description => "List languages your current entity can speak at the current moment."; + public string Help => "lslangs"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not { } player) + { + shell.WriteError("This command cannot be run from the server."); + return; + } + + if (player.Status != SessionStatus.InGame) + return; + + if (player.AttachedEntity is not { } playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } + + var languages = IoCManager.Resolve().GetEntitySystem(); + + var (spokenLangs, knownLangs) = languages.GetAllLanguages(playerEntity); + + shell.WriteLine("Spoken: " + string.Join(", ", spokenLangs)); + shell.WriteLine("Understood: " + string.Join(", ", knownLangs)); + } +} diff --git a/Content.Server/ADT/Language/Commands/SayLanguageCommand.cs b/Content.Server/ADT/Language/Commands/SayLanguageCommand.cs new file mode 100644 index 0000000000..711c2c5fbf --- /dev/null +++ b/Content.Server/ADT/Language/Commands/SayLanguageCommand.cs @@ -0,0 +1,53 @@ +using Content.Server.Chat.Systems; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.Enums; + +namespace Content.Server.Language.Commands; + +[AnyCommand] +public sealed class SayLanguageCommand : IConsoleCommand +{ + public string Command => "lsay"; + public string Description => "Send chat languages to the local channel or a specific chat channel, in a specific language."; + public string Help => "lsay "; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not { } player) + { + shell.WriteError("This command cannot be run from the server."); + return; + } + + if (player.Status != SessionStatus.InGame) + return; + + if (player.AttachedEntity is not { } playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } + + if (args.Length < 2) + return; + + var languageId = args[0]; + var message = string.Join(" ", args, startIndex: 1, count: args.Length - 1).Trim(); + + if (string.IsNullOrEmpty(message)) + return; + + var languages = IoCManager.Resolve().GetEntitySystem(); + var chats = IoCManager.Resolve().GetEntitySystem(); + + var language = languages.GetLanguage(languageId); + if (language == null || !languages.CanSpeak(playerEntity, language.ID)) + { + shell.WriteError($"Language {languageId} is invalid or you cannot speak it!"); + return; + } + + chats.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Speak, ChatTransmitRange.Normal, false, shell, player, languageOverride: language); + } +} diff --git a/Content.Server/ADT/Language/Commands/SelectLanguageCommand.cs b/Content.Server/ADT/Language/Commands/SelectLanguageCommand.cs new file mode 100644 index 0000000000..72336747fa --- /dev/null +++ b/Content.Server/ADT/Language/Commands/SelectLanguageCommand.cs @@ -0,0 +1,48 @@ +using System.Linq; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.Enums; + +namespace Content.Server.Language.Commands; + +[AnyCommand] +public sealed class SelectLanguageCommand : IConsoleCommand +{ + public string Command => "lsselectlang"; + public string Description => "Open a menu to select a langauge to speak."; + public string Help => "lsselectlang"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not { } player) + { + shell.WriteError("This command cannot be run from the server."); + return; + } + + if (player.Status != SessionStatus.InGame) + return; + + if (player.AttachedEntity is not { } playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } + + if (args.Length < 1) + return; + + var languageId = args[0]; + + var languages = IoCManager.Resolve().GetEntitySystem(); + + var language = languages.GetLanguage(languageId); + if (language == null || !languages.CanSpeak(playerEntity, language.ID)) + { + shell.WriteError($"Language {languageId} is invalid or you cannot speak it!"); + return; + } + + languages.SetLanguage(playerEntity, language.ID); + } +} diff --git a/Content.Server/ADT/Language/LanguageSystem.Windows.cs b/Content.Server/ADT/Language/LanguageSystem.Windows.cs new file mode 100644 index 0000000000..52b5e7cbf4 --- /dev/null +++ b/Content.Server/ADT/Language/LanguageSystem.Windows.cs @@ -0,0 +1,40 @@ +using Content.Shared.Language; +using Robust.Server.GameObjects; +using Robust.Shared.Player; + +namespace Content.Server.Language; + +public sealed partial class LanguageSystem +{ + [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + + public void InitializeWindows() + { + SubscribeNetworkEvent(OnLanguagesRequest); + SubscribeLocalEvent(OnLanguageSwitch); + } + + private void OnLanguagesRequest(RequestLanguageMenuStateMessage args, EntitySessionEventArgs session) + { + var uid = session.SenderSession.AttachedEntity; + if (uid == null) + return; + + var langs = GetLanguages(uid.Value); + if (langs == null) + return; + + var state = new LanguageMenuStateMessage(langs.CurrentLanguage, langs.SpokenLanguages); + RaiseNetworkEvent(state, uid.Value); + } + + private void OnLanguageSwitch(EntityUid uid, LanguageSpeakerComponent component, LanguagesUpdateEvent args) + { + var langs = GetLanguages(uid); + if (langs == null) + return; + + var state = new LanguageMenuStateMessage(langs.CurrentLanguage, langs.SpokenLanguages); + RaiseNetworkEvent(state, uid); + } +} diff --git a/Content.Server/ADT/Language/LanguageSystem.cs b/Content.Server/ADT/Language/LanguageSystem.cs new file mode 100644 index 0000000000..e76ce23cd3 --- /dev/null +++ b/Content.Server/ADT/Language/LanguageSystem.cs @@ -0,0 +1,319 @@ +using System.Linq; +using System.Text; +using Content.Shared.GameTicking; +using Content.Shared.Language; +using Content.Shared.Language.Systems; +using Robust.Shared.Random; +using Robust.Shared.Player; +using Robust.Server.GameObjects; +using UniversalLanguageSpeakerComponent = Content.Shared.Language.Components.UniversalLanguageSpeakerComponent; + +namespace Content.Server.Language; + +public sealed partial class LanguageSystem : SharedLanguageSystem +{ + /// + /// A random number added to each pseudo-random number's seed. Changes every round. + /// + public int RandomRoundSeed { get; private set; } + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInitLanguageSpeaker); + SubscribeAllEvent(it => RandomRoundSeed = _random.Next()); + SubscribeLocalEvent(OnUnknow); + + InitializeWindows(); + } + + private void OnInitLanguageSpeaker(EntityUid uid, LanguageSpeakerComponent component, ComponentInit args) + { + if (string.IsNullOrEmpty(component.CurrentLanguage)) + { + component.CurrentLanguage = component.SpokenLanguages.FirstOrDefault(UniversalPrototype); + } + } + + private void OnUnknow(EntityUid uid, UnknowLanguageComponent unknow, MapInitEvent args) + { + TryComp(uid, out var component); + + if (component != null) + { + component.SpokenLanguages.Remove(unknow.LanguageToForgot); + component.UnderstoodLanguages.Remove(unknow.LanguageToForgot); + component.CurrentLanguage = component.SpokenLanguages.FirstOrDefault(UniversalPrototype); + } + else + return; + + } + + /// + /// Obfuscate speech of the given entity, or using the given language. + /// + /// The speaker whose message needs to be obfuscated. Must not be null if "language" is not set. + /// The language for obfuscation. Must not be null if "source" is null. + public string ObfuscateSpeech(EntityUid? source, string message, LanguagePrototype? language = null) + { + if (language == null) + { + if (source is not { Valid: true }) + { + throw new NullReferenceException("Either source or language must be set."); + } + language = GetLanguage(source.Value); + } + + var builder = new StringBuilder(); + if (language.ObfuscateSyllables) + { + ObfuscateSyllables(builder, message, language); + } + else + { + ObfuscatePhrases(builder, message, language); + } + + //_sawmill.Info($"Got {message}, obfuscated to {builder}. Language: {language.ID}"); + + return builder.ToString(); + } + + private void ObfuscateSyllables(StringBuilder builder, string message, LanguagePrototype language) + { + // Go through each word. Calculate its hash sum and count the number of letters. + // Replicate it with pseudo-random syllables of pseudo-random (but similar) length. Use the hash code as the seed. + // This means that identical words will be obfuscated identically. Simple words like "hello" or "yes" in different langs can be memorized. + var wordBeginIndex = 0; + var hashCode = 0; + for (var i = 0; i < message.Length; i++) + { + var ch = char.ToLower(message[i]); + // A word ends when one of the following is found: a space, a sentence end, or EOM + if (char.IsWhiteSpace(ch) || IsSentenceEnd(ch) || i == message.Length - 1) + { + var wordLength = i - wordBeginIndex; + if (wordLength > 0) + { + var newWordLength = PseudoRandomNumber(hashCode, 1, 4); + + for (var j = 0; j < newWordLength; j++) + { + var index = PseudoRandomNumber(hashCode + j, 0, language.Replacement.Count); + builder.Append(language.Replacement[index]); + } + } + + builder.Append(ch); + hashCode = 0; + wordBeginIndex = i + 1; + } + else + { + hashCode = hashCode * 31 + ch; + } + } + } + + private void ObfuscatePhrases(StringBuilder builder, string message, LanguagePrototype language) + { + // In a similar manner, each phrase is obfuscated with a random number of conjoined obfuscation phrases. + // However, the number of phrases depends on the number of characters in the original phrase. + var sentenceBeginIndex = 0; + for (var i = 0; i < message.Length; i++) + { + var ch = char.ToLower(message[i]); + if (IsSentenceEnd(ch) || i == message.Length - 1) + { + var length = i - sentenceBeginIndex; + if (length > 0) + { + var newLength = (int) Math.Clamp(Math.Cbrt(length) - 1, 1, 4); // 27+ chars for 2 phrases, 64+ for 3, 125+ for 4. + + for (var j = 0; j < newLength; j++) + { + var phrase = _random.Pick(language.Replacement); + builder.Append(phrase); + } + } + sentenceBeginIndex = i + 1; + + if (IsSentenceEnd(ch)) + builder.Append(ch).Append(" "); + } + } + } + + public bool CanUnderstand(EntityUid listener, + LanguagePrototype language, + LanguageSpeakerComponent? listenerLanguageComp = null) + { + if (language.ID == UniversalPrototype || HasComp(listener)) + return true; + + var listenerLanguages = GetLanguages(listener, listenerLanguageComp)?.UnderstoodLanguages; + + return listenerLanguages?.Contains(language.ID, StringComparer.Ordinal) ?? false; + } + + public bool CanSpeak(EntityUid speaker, string language, LanguageSpeakerComponent? speakerComp = null) + { + if (HasComp(speaker)) + return true; + + var langs = GetLanguages(speaker, speakerComp)?.UnderstoodLanguages; + return langs?.Contains(language, StringComparer.Ordinal) ?? false; + } + + // + // Returns the current language of the given entity. Assumes Universal if not specified. + // + public LanguagePrototype GetLanguage(EntityUid speaker, LanguageSpeakerComponent? languageComp = null) + { + var id = GetLanguages(speaker, languageComp)?.CurrentLanguage; + if (id == null) + return Universal; // Fallback + + _prototype.TryIndex(id, out LanguagePrototype? proto); + + return proto ?? Universal; + } + + // + // Set the CurrentLanguage of the given entity. + // + public void SetLanguage(EntityUid speaker, string language, LanguageSpeakerComponent? languageComp = null) + { + if (!CanSpeak(speaker, language)) + return; + + if (languageComp == null && !TryComp(speaker, out languageComp)) + return; + + if (languageComp.CurrentLanguage == language) + return; + + languageComp.CurrentLanguage = language; + + RaiseLocalEvent(speaker, new LanguagesUpdateEvent(), true); + } + + /// + /// Adds a new language to the lists of understood and/or spoken languages of the given component. + /// + public void AddLanguage(LanguageSpeakerComponent comp, string language, bool addSpoken = true, bool addUnderstood = true) + { + if (addSpoken && !comp.SpokenLanguages.Contains(language, StringComparer.Ordinal)) + comp.SpokenLanguages.Add(language); + + if (addUnderstood && !comp.UnderstoodLanguages.Contains(language, StringComparer.Ordinal)) + comp.UnderstoodLanguages.Add(language); + + RaiseLocalEvent(comp.Owner, new LanguagesUpdateEvent(), true); + } + + private static bool IsSentenceEnd(char ch) + { + return ch is '.' or '!' or '?'; + } + + // This event is reused because re-allocating it each time is way too costly. + private readonly DetermineEntityLanguagesEvent _determineLanguagesEvent = new(string.Empty, new(), new()); + + /// + /// Returns a pair of (spoken, understood) languages of the given entity. + /// + public (List, List) GetAllLanguages(EntityUid speaker) + { + var languages = GetLanguages(speaker); + if (languages == null) + return (new(), new()); + + // The lists need to be copied because the internal ones are re-used for performance reasons. + return (new List(languages.SpokenLanguages), new List(languages.UnderstoodLanguages)); + } + + /// + /// Dynamically resolves the current language of the entity and the list of all languages it speaks. + /// The returned event is reused and thus must not be held as a reference anywhere but inside the caller function. + /// + private DetermineEntityLanguagesEvent? GetLanguages(EntityUid speaker, LanguageSpeakerComponent? comp = null) + { + if (comp == null && !TryComp(speaker, out comp)) + return null; + + var ev = _determineLanguagesEvent; + ev.SpokenLanguages.Clear(); + ev.UnderstoodLanguages.Clear(); + + ev.CurrentLanguage = comp.CurrentLanguage; + ev.SpokenLanguages.AddRange(comp.SpokenLanguages); + ev.UnderstoodLanguages.AddRange(comp.UnderstoodLanguages); + + RaiseLocalEvent(speaker, ev, true); + + if (ev.CurrentLanguage.Length == 0) + ev.CurrentLanguage = !string.IsNullOrEmpty(comp.CurrentLanguage) ? comp.CurrentLanguage : UniversalPrototype; // Fall back to account for admemes like admins possessing a bread + return ev; + } + + /// + /// Generates a stable pseudo-random number in the range [min, max) for the given seed. Each input seed corresponds to exactly one random number. + /// + private int PseudoRandomNumber(int seed, int min, int max) + { + // This is not a uniform distribution, but it shouldn't matter: given there's 2^31 possible random numbers, + // The bias of this function should be so tiny it will never be noticed. + seed += RandomRoundSeed; + var random = ((seed * 1103515245) + 12345) & 0x7fffffff; // Source: http://cs.uccs.edu/~cs591/bufferOverflow/glibc-2.2.4/stdlib/random_r.c + return random % (max - min) + min; + } + + /// + /// Ensures the given entity has a valid language as its current language. + /// If not, sets it to the first entry of its SpokenLanguages list, or universal if it's empty. + /// + public void EnsureValidLanguage(EntityUid entity, LanguageSpeakerComponent? comp = null) + { + if (comp == null && !TryComp(entity, out comp)) + return; + + var langs = GetLanguages(entity, comp); + + if (langs != null && !langs.SpokenLanguages.Contains(comp!.CurrentLanguage, StringComparer.Ordinal)) + { + comp.CurrentLanguage = langs.SpokenLanguages.FirstOrDefault(UniversalPrototype); + } + } + + /// + /// Raised in order to determine the language an entity speaks at the current moment, + /// as well as the list of all languages the entity may speak and understand. + /// + public sealed class DetermineEntityLanguagesEvent : EntityEventArgs + { + /// + /// The default language of this entity. If empty, remain unchanged. + /// This field has no effect if the entity decides to speak in a concrete language. + /// + public string CurrentLanguage; + /// + /// The list of all languages the entity may speak. Must NOT be held as a reference! + /// + public List SpokenLanguages; + /// + /// The list of all languages the entity may understand. Must NOT be held as a reference! + /// + public List UnderstoodLanguages; + + public DetermineEntityLanguagesEvent(string currentLanguage, List spokenLanguages, List understoodLanguages) + { + CurrentLanguage = currentLanguage; + SpokenLanguages = spokenLanguages; + UnderstoodLanguages = understoodLanguages; + } + } +} diff --git a/Content.Server/ADT/Language/TranslatorImplanterSystem.cs b/Content.Server/ADT/Language/TranslatorImplanterSystem.cs new file mode 100644 index 0000000000..f24a013cc2 --- /dev/null +++ b/Content.Server/ADT/Language/TranslatorImplanterSystem.cs @@ -0,0 +1,79 @@ +using System.Linq; +using Content.Server.Administration.Logs; +using Content.Server.Popups; +using Content.Shared.Database; +using Content.Shared.Interaction; +using Content.Shared.Language; +using Content.Shared.Language.Components; +using Content.Shared.Language.Systems; +using Content.Shared.Mobs.Components; + +namespace Content.Server.Language; + +public sealed class TranslatorImplanterSystem : SharedTranslatorImplanterSystem +{ + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly LanguageSystem _language = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnImplant); + } + + private void OnImplant(EntityUid implanter, TranslatorImplanterComponent component, AfterInteractEvent args) + { + if (component.Used || !args.CanReach || args.Target is not { Valid: true } target) + return; + + if (!TryComp(target, out var speaker)) + return; + + if (component.MobsOnly && !HasComp(target)) + { + _popup.PopupEntity("translator-implanter-refuse", component.Owner); + return; + } + + var (_, understood) = _language.GetAllLanguages(target); + if (component.RequiredLanguages.Count > 0 && !component.RequiredLanguages.Any(lang => understood.Contains(lang))) + { + RefusesPopup(implanter, target); + return; + } + + var intrinsic = EnsureComp(target); + intrinsic.Enabled = true; + + foreach (var lang in component.SpokenLanguages.Where(lang => !intrinsic.SpokenLanguages.Contains(lang))) + intrinsic.SpokenLanguages.Add(lang); + + foreach (var lang in component.UnderstoodLanguages.Where(lang => !intrinsic.UnderstoodLanguages.Contains(lang))) + intrinsic.UnderstoodLanguages.Add(lang); + + component.Used = true; + SuccessPopup(implanter, target); + + _adminLogger.Add(LogType.Action, LogImpact.Medium, + $"{ToPrettyString(args.User):player} used {ToPrettyString(implanter):implanter} to give {ToPrettyString(target):target} the following languages:" + + $"\nSpoken: {string.Join(", ", component.SpokenLanguages)}; Understood: {string.Join(", ", component.UnderstoodLanguages)}"); + + OnAppearanceChange(implanter, component); + RaiseLocalEvent(target, new SharedLanguageSystem.LanguagesUpdateEvent(), true); + } + + private void RefusesPopup(EntityUid implanter, EntityUid target) + { + _popup.PopupEntity( + Loc.GetString("translator-implanter-refuse", ("implanter", implanter), ("target", target)), + implanter); + } + + private void SuccessPopup(EntityUid implanter, EntityUid target) + { + _popup.PopupEntity( + Loc.GetString("translator-implanter-success", ("implanter", implanter), ("target", target)), + implanter); + } +} diff --git a/Content.Server/ADT/Language/TranslatorSystem.cs b/Content.Server/ADT/Language/TranslatorSystem.cs new file mode 100644 index 0000000000..e19b2b29d7 --- /dev/null +++ b/Content.Server/ADT/Language/TranslatorSystem.cs @@ -0,0 +1,243 @@ +using System.Linq; +using Content.Server.Popups; +using Content.Server.PowerCell; +using Content.Shared.Hands; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; +using Content.Shared.Inventory; +using Content.Shared.Inventory.Events; +using Content.Shared.Language; +using Content.Shared.Language.Components; +using Content.Shared.Language.Systems; +using Content.Shared.PowerCell; +using static Content.Server.Language.LanguageSystem; +using HandheldTranslatorComponent = Content.Shared.Language.Components.HandheldTranslatorComponent; +using HoldsTranslatorComponent = Content.Shared.Language.Components.HoldsTranslatorComponent; +using IntrinsicTranslatorComponent = Content.Shared.Language.Components.IntrinsicTranslatorComponent; + +namespace Content.Server.Language; + +// this does not support holding multiple translators at once yet. +// that should not be an issue for now, but it better get fixed later. +public sealed class TranslatorSystem : SharedTranslatorSystem +{ + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly LanguageSystem _language = default!; + [Dependency] private readonly PowerCellSystem _powerCell = default!; + + private ISawmill _sawmill = default!; + + public override void Initialize() + { + base.Initialize(); + _sawmill = Logger.GetSawmill("translator"); + + // I wanna die. But my death won't help us discover polymorphism. + SubscribeLocalEvent(ApplyTranslation); + SubscribeLocalEvent(ApplyTranslation); + SubscribeLocalEvent(ApplyTranslation); + // TODO: make this thing draw power + // SubscribeLocalEvent(...); + + SubscribeLocalEvent(OnTranslatorToggle); + SubscribeLocalEvent(OnPowerCellSlotEmpty); + + SubscribeLocalEvent( + (uid, component, args) => TranslatorEquipped(args.User, uid, component)); + SubscribeLocalEvent( + (uid, component, args) => TranslatorUnequipped(args.User, uid, component)); + } + + private void ApplyTranslation(EntityUid uid, IntrinsicTranslatorComponent component, + DetermineEntityLanguagesEvent ev) + { + if (!component.Enabled) + return; + + if (!_powerCell.HasActivatableCharge(uid)) + return; + + var addUnderstood = true; + var addSpoken = true; + if (component.RequiredLanguages.Count > 0) + { + if (component.RequiresAllLanguages) + { + // Add langs when the wielder has all of the required languages + foreach (var language in component.RequiredLanguages) + { + if (!ev.SpokenLanguages.Contains(language, StringComparer.Ordinal)) + addSpoken = false; + + if (!ev.UnderstoodLanguages.Contains(language, StringComparer.Ordinal)) + addUnderstood = false; + } + } + else + { + // Add langs when the wielder has at least one of the required languages + addUnderstood = false; + addSpoken = false; + foreach (var language in component.RequiredLanguages) + { + if (ev.SpokenLanguages.Contains(language, StringComparer.Ordinal)) + addSpoken = true; + + if (ev.UnderstoodLanguages.Contains(language, StringComparer.Ordinal)) + addUnderstood = true; + } + } + } + + if (addSpoken) + { + foreach (var language in component.SpokenLanguages) + { + AddIfNotExists(ev.SpokenLanguages, language); + } + + if (component.CurrentSpeechLanguage != null && ev.CurrentLanguage.Length == 0) + { + ev.CurrentLanguage = component.CurrentSpeechLanguage; + } + } + + if (addUnderstood) + { + foreach (var language in component.UnderstoodLanguages) + { + AddIfNotExists(ev.UnderstoodLanguages, language); + } + } + } + + private void TranslatorEquipped(EntityUid holder, EntityUid translator, HandheldTranslatorComponent component) + { + if (!EntityManager.HasComponent(holder)) + return; + + var intrinsic = EntityManager.EnsureComponent(holder); + UpdateBoundIntrinsicComp(component, intrinsic, component.Enabled); + + UpdatedLanguages(holder); + } + + private void TranslatorUnequipped(EntityUid holder, EntityUid translator, HandheldTranslatorComponent component) + { + if (!EntityManager.TryGetComponent(holder, out var intrinsic)) + return; + + if (intrinsic.Issuer == component) + { + + intrinsic.Enabled = false; + EntityManager.RemoveComponent(holder, intrinsic); + } + + _language.EnsureValidLanguage(holder); + + UpdatedLanguages(holder); + } + + private void OnTranslatorToggle(EntityUid translator, HandheldTranslatorComponent component, ActivateInWorldEvent args) + { + if (!component.ToggleOnInteract) + return; + + var hasPower = _powerCell.HasDrawCharge(translator); + + if (Transform(args.Target).ParentUid is { Valid: true } holder && EntityManager.HasComponent(holder)) + { + // This translator is held by a language speaker and thus has an intrinsic counterpart bound to it. Make sure it's up-to-date. + var intrinsic = EntityManager.EnsureComponent(holder); + var isEnabled = !component.Enabled; + if (intrinsic.Issuer != component) + { + // The intrinsic comp wasn't owned by this handheld component, so this comp wasn't the active translator. + // Thus it needs to be turned on regardless of its previous state. + intrinsic.Issuer = component; + isEnabled = true; + } + + isEnabled &= hasPower; + UpdateBoundIntrinsicComp(component, intrinsic, isEnabled); + component.Enabled = isEnabled; + _powerCell.SetPowerCellDrawEnabled(translator, isEnabled); + + _language.EnsureValidLanguage(holder); + UpdatedLanguages(holder); + } + else + { + // This is a standalone translator (e.g. lying on the ground). Simply toggle its state. + component.Enabled = !component.Enabled && hasPower; + _powerCell.SetPowerCellDrawEnabled(translator, !component.Enabled && hasPower); + } + + OnAppearanceChange(translator, component); + + // HasPower shows a popup when there's no power, so we do not proceed in that case + if (hasPower) + { + var message = + Loc.GetString(component.Enabled ? "translator-component-turnon" : "translator-component-shutoff", ("translator", component.Owner)); + _popup.PopupEntity(message, component.Owner, args.User); + } + } + + private void OnPowerCellSlotEmpty(EntityUid translator, HandheldTranslatorComponent component, PowerCellSlotEmptyEvent args) + { + component.Enabled = false; + _powerCell.SetPowerCellDrawEnabled(translator, false); + OnAppearanceChange(translator, component); + + if (Transform(translator).ParentUid is { Valid: true } holder && EntityManager.HasComponent(holder)) + { + if (!EntityManager.TryGetComponent(holder, out var intrinsic)) + return; + + if (intrinsic.Issuer == component) + { + intrinsic.Enabled = false; + EntityManager.RemoveComponent(holder, intrinsic); + } + + _language.EnsureValidLanguage(holder); + UpdatedLanguages(holder); + } + } + + /// + /// Copies the state from the handheld [comp] to the [intrinsic] comp, using [isEnabled] as the enabled state. + /// + private void UpdateBoundIntrinsicComp(HandheldTranslatorComponent comp, HoldsTranslatorComponent intrinsic, bool isEnabled) + { + if (isEnabled) + { + intrinsic.SpokenLanguages = new List(comp.SpokenLanguages); + intrinsic.UnderstoodLanguages = new List(comp.UnderstoodLanguages); + intrinsic.CurrentSpeechLanguage = comp.CurrentSpeechLanguage; + } + else + { + intrinsic.SpokenLanguages.Clear(); + intrinsic.UnderstoodLanguages.Clear(); + intrinsic.CurrentSpeechLanguage = null; + } + + intrinsic.Enabled = isEnabled; + intrinsic.Issuer = comp; + } + + private static void AddIfNotExists(List list, string item) + { + if (list.Contains(item)) + return; + list.Add(item); + } + + private void UpdatedLanguages(EntityUid uid) + { + RaiseLocalEvent(uid, new SharedLanguageSystem.LanguagesUpdateEvent(), true); + } +} diff --git a/Content.Server/ADT/SwitchableWeapon/SwitchableWeapon/SwitchableWeaponSystem.cs b/Content.Server/ADT/SwitchableWeapon/SwitchableWeapon/SwitchableWeaponSystem.cs new file mode 100644 index 0000000000..f359681cf5 --- /dev/null +++ b/Content.Server/ADT/SwitchableWeapon/SwitchableWeapon/SwitchableWeaponSystem.cs @@ -0,0 +1,83 @@ +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Events; +using Content.Shared.Examine; +using Content.Shared.Interaction.Events; +using Content.Shared.Item; +using Content.Shared.ADT.SwitchableWeapon; +using Content.Shared.Toggleable; +using Content.Shared.Weapons.Melee.Events; +using Robust.Shared.Audio.Systems; + +namespace Content.Server.ADT.SwitchableWeapon; + +public sealed class SwitchableWeaponSystem : EntitySystem +{ + [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(Toggle); + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnStaminaHitAttempt); + SubscribeLocalEvent(OnGetMeleeDamage); + SubscribeLocalEvent(OnComponentAdded); + } + + private void OnComponentAdded(EntityUid uid, SwitchableWeaponComponent component, ComponentAdd args) + { + UpdateState(uid, component); + } + + //Non-stamina damage + private void OnGetMeleeDamage(EntityUid uid, SwitchableWeaponComponent component, ref GetMeleeDamageEvent args) + { + args.Damage = component.IsOpen ? component.DamageOpen : component.DamageFolded; + } + + private void OnStaminaHitAttempt(EntityUid uid, SwitchableWeaponComponent component, ref StaminaDamageOnHitAttemptEvent args) + { + if (!component.IsOpen) + return; + + //args.HitSoundOverride = component.BonkSound; + } + + private void OnExamined(EntityUid uid, SwitchableWeaponComponent comp, ExaminedEvent args) + { + var msg = comp.IsOpen + ? Loc.GetString("comp-switchable-examined-on") + : Loc.GetString("comp-switchable-examined-off"); + args.PushMarkup(msg); + } + + private void UpdateState(EntityUid uid, SwitchableWeaponComponent comp) + { + if (TryComp(comp.Owner, out var item)) + { + _item.SetSize(item.Owner, comp.IsOpen ? comp.SizeOpened : comp.SizeClosed, item); + _item.SetHeldPrefix(comp.Owner, comp.IsOpen ? "on" : "off", false, item); + } + + if (TryComp(comp.Owner, out var appearance)) + _appearance.SetData(comp.Owner, ToggleVisuals.Toggled, comp.IsOpen, appearance); + + // Change stamina damage according to state + if (TryComp(uid, out var stamComp)) + { + stamComp.Damage = comp.IsOpen ? comp.StaminaDamageOpen : comp.StaminaDamageFolded; + } + } + + private void Toggle(EntityUid uid, SwitchableWeaponComponent comp, UseInHandEvent args) + { + comp.IsOpen = !comp.IsOpen; + UpdateState(uid, comp); + + var soundToPlay = comp.IsOpen ? comp.OpenSound : comp.CloseSound; + _audio.PlayPvs(soundToPlay, args.User); + } +} diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 38d485458b..93818d0df6 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -11,6 +11,7 @@ using Content.Server.Speech.EntitySystems; using Content.Server.Station.Components; using Content.Server.Station.Systems; +using Content.Server.Language; using Content.Shared.ActionBlocker; using Content.Shared.Administration; using Content.Shared.CCVar; @@ -26,6 +27,7 @@ using Content.Shared.Radio; using Content.Shared.Speech; using Content.Shared.Whitelist; +using Content.Shared.Language; using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; @@ -64,6 +66,7 @@ public sealed partial class ChatSystem : SharedChatSystem [Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly ExamineSystemShared _examineSystem = default!; + [Dependency] private readonly LanguageSystem _language = default!; // Corvax-TTS-Start: Moved from Server to Shared // public const int VoiceRange = 10; // how far voice goes in world units @@ -177,8 +180,8 @@ public void TrySendInGameICMessage( ICommonSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, - bool ignoreActionBlocker = false - ) + bool ignoreActionBlocker = false, + LanguagePrototype? languageOverride = null) // Frontier - languages mechanic { if (HasComp(source)) { @@ -253,10 +256,10 @@ public void TrySendInGameICMessage( switch (desiredType) { case InGameICChatType.Speak: - SendEntitySpeak(source, message, range, nameOverride, hideLog, ignoreActionBlocker); + SendEntitySpeak(source, message, range, nameOverride, hideLog, ignoreActionBlocker, languageOverride: languageOverride); break; case InGameICChatType.Whisper: - SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker); + SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker, languageOverride: languageOverride); break; case InGameICChatType.Emote: SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, ignoreActionBlocker: ignoreActionBlocker); @@ -387,7 +390,8 @@ private void SendEntitySpeak( ChatTransmitRange range, string? nameOverride, bool hideLog = false, - bool ignoreActionBlocker = false + bool ignoreActionBlocker = false, + LanguagePrototype? languageOverride = null // Frontier: languages mechanic ) { if (!_actionBlocker.CanSpeak(source) && !ignoreActionBlocker) @@ -416,18 +420,30 @@ private void SendEntitySpeak( speech = proto; } + // Frontier - languages mechanic + var language = languageOverride ?? _language.GetLanguage(source); + name = FormattedMessage.EscapeText(name); + // Frontier: languages mechanic ADT Upd start + if (TryComp(source, out var lang) && lang.CurrentLanguage != "GalacticCommon" && lang.CurrentLanguage != "Universal") + name = $"{lang.LocalizedID}|{name}"; + // Frontier: languages mechanic ADT Upd end + var wrappedMessage = Loc.GetString(speech.Bold ? "chat-manager-entity-say-bold-wrap-message" : "chat-manager-entity-say-wrap-message", ("entityName", name), ("verb", Loc.GetString(_random.Pick(speech.SpeechVerbStrings))), ("fontType", speech.FontId), ("fontSize", speech.FontSize), ("message", FormattedMessage.EscapeText(message))); + + var encodedMessage = _language.ObfuscateSpeech(source, message, language); + var wrappedEncodedMessage = WrapPublicMessage(source, name, encodedMessage); - SendInVoiceRange(ChatChannel.Local, message, wrappedMessage, source, range); + // Frontier: languages mechanic + SendInVoiceRange(ChatChannel.Local, message, wrappedMessage, encodedMessage, wrappedEncodedMessage, source, range, languageOverride: language); - var ev = new EntitySpokeEvent(source, message, originalMessage, null, null); + var ev = new EntitySpokeEvent(source, message, originalMessage, encodedMessage, null, language, null); RaiseLocalEvent(source, ev, true); // To avoid logging any messages sent by entities that are not players, like vendors, cloning, etc. @@ -460,7 +476,8 @@ private void SendEntityWhisper( RadioChannelPrototype? channel, string? nameOverride, bool hideLog = false, - bool ignoreActionBlocker = false + bool ignoreActionBlocker = false, + LanguagePrototype? languageOverride = null // Frontier: languages mechanic ) { if (!_actionBlocker.CanSpeak(source) && !ignoreActionBlocker) @@ -487,16 +504,15 @@ private void SendEntityWhisper( name = nameEv.Name; } name = FormattedMessage.EscapeText(name); + + // Frontier: languages mechanic ADT Upd start + if (TryComp(source, out var lang) && lang.CurrentLanguage != "GalacticCommon" && lang.CurrentLanguage != "Universal") + name = $"{lang.LocalizedID}|{name}"; + // Frontier: languages mechanic ADT Upd end - var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", - ("entityName", name), ("message", FormattedMessage.EscapeText(message))); - - var wrappedobfuscatedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", - ("entityName", nameIdentity), ("message", FormattedMessage.EscapeText(obfuscatedMessage))); - - var wrappedUnknownMessage = Loc.GetString("chat-manager-entity-whisper-unknown-wrap-message", - ("message", FormattedMessage.EscapeText(obfuscatedMessage))); - + // Frontier - languages mechanic (+ everything in the foreach loop) + var language = languageOverride ?? _language.GetLanguage(source); + var languageEncodedMessage = _language.ObfuscateSpeech(source, message, language); foreach (var (session, data) in GetRecipients(source, WhisperMuffledRange)) { @@ -509,19 +525,42 @@ private void SendEntityWhisper( if (MessageRangeCheck(session, data, range) != MessageRangeCheckResult.Full) continue; // Won't get logged to chat, and ghosts are too far away to see the pop-up, so we just won't send it to them. + var canUnderstand = _language.CanUnderstand(listener, language); + var _message = canUnderstand ? message : languageEncodedMessage; + if (data.Range <= WhisperClearRange) - _chatManager.ChatMessageToOne(ChatChannel.Whisper, message, wrappedMessage, source, false, session.Channel); + { + var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", + ("entityName", name), ("message", FormattedMessage.EscapeText(_message))); + + _chatManager.ChatMessageToOne(ChatChannel.Whisper, _message, wrappedMessage, source, false, session.Channel); + } //If listener is too far, they only hear fragments of the message else if (_examineSystem.InRangeUnOccluded(source, listener, WhisperMuffledRange)) - _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedobfuscatedMessage, source, false, session.Channel); + { + var _obfuscatedMessage = ObfuscateMessageReadability(_message, 0.2f); + + var wrappedobfuscatedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", + ("entityName", nameIdentity), ("message", FormattedMessage.EscapeText(_obfuscatedMessage))); + _chatManager.ChatMessageToOne(ChatChannel.Whisper, _obfuscatedMessage, wrappedobfuscatedMessage, source, false, session.Channel); + } //If listener is too far and has no line of sight, they can't identify the whisperer's identity else - _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedUnknownMessage, source, false, session.Channel); + { + var _obfuscatedMessage = ObfuscateMessageReadability(_message, 0.2f); + + var wrappedUnknownMessage = Loc.GetString("chat-manager-entity-whisper-unknown-wrap-message", + ("message", FormattedMessage.EscapeText(_obfuscatedMessage))); + _chatManager.ChatMessageToOne(ChatChannel.Whisper, _obfuscatedMessage, wrappedUnknownMessage, source, false, session.Channel); + } } - _replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); + var replayWrap = Loc.GetString("chat-manager-entity-whisper-wrap-message", + ("entityName", name), + ("message", FormattedMessage.EscapeText(message))); + _replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, replayWrap, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); - var ev = new EntitySpokeEvent(source, message, originalMessage, channel, obfuscatedMessage); + var ev = new EntitySpokeEvent(source, message, originalMessage, languageEncodedMessage, channel, language, obfuscatedMessage); RaiseLocalEvent(source, ev, true); if (!hideLog) if (originalMessage == message) @@ -568,7 +607,7 @@ private void SendEntityEmote( if (checkEmote) TryEmoteChatInput(source, action); - SendInVoiceRange(ChatChannel.Emotes, action, wrappedMessage, source, range, author); + SendInVoiceRange(ChatChannel.Emotes, action, wrappedMessage,encodedMessage: string.Empty, wrappedEncodedMessage: string.Empty, source, range, author); if (!hideLog) if (name != Name(source)) _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Emote from {ToPrettyString(source):user} as {name}: {action}"); @@ -595,7 +634,12 @@ private void SendLOOC(EntityUid source, ICommonSession player, string message, b ("entityName", name), ("message", FormattedMessage.EscapeText(message))); - SendInVoiceRange(ChatChannel.LOOC, message, wrappedMessage, source, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, player.UserId); + SendInVoiceRange(ChatChannel.LOOC, message, wrappedMessage, + encodedMessage: string.Empty, + wrappedEncodedMessage: string.Empty, + source, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, + player.UserId, + languageOverride: LanguageSystem.Universal); _adminLogger.Add(LogType.Chat, LogImpact.Low, $"LOOC from {player:Player}: {message}"); } @@ -676,15 +720,31 @@ private MessageRangeCheckResult MessageRangeCheck(ICommonSession session, ICChat /// /// Sends a chat message to the given players in range of the source entity. /// - private void SendInVoiceRange(ChatChannel channel, string message, string wrappedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null) + private void SendInVoiceRange(ChatChannel channel, string message, string wrappedMessage, string encodedMessage, string wrappedEncodedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null, LanguagePrototype? languageOverride = null) { + + var language = languageOverride ?? _language.GetLanguage(source); // frontier + foreach (var (session, data) in GetRecipients(source, VoiceRange)) { var entRange = MessageRangeCheck(session, data, range); if (entRange == MessageRangeCheckResult.Disallowed) continue; var entHideChat = entRange == MessageRangeCheckResult.HideChat; - _chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.Channel, author: author); + + // Frontier - languages mechanic + if (session.AttachedEntity is not { Valid: true } playerEntity) + continue; + EntityUid listener = session.AttachedEntity.Value; + + if (channel == ChatChannel.LOOC || channel == ChatChannel.Emotes || _language.CanUnderstand(listener, language)) + { + _chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.ConnectedClient, author: author); + } + else + { + _chatManager.ChatMessageToOne(channel, encodedMessage, wrappedEncodedMessage, source, entHideChat, session.ConnectedClient, author: author); + } } _replay.RecordServerMessage(new ChatMessage(channel, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); @@ -794,6 +854,19 @@ public string SanitizeMessageReplaceWords(string message) return msg; } + // Frontier - languages mechanic + public string WrapPublicMessage(EntityUid source, string name, string message) + { + var speech = GetSpeechVerb(source, message); + var verbName = Loc.GetString(_random.Pick(speech.SpeechVerbStrings)); + return Loc.GetString(speech.Bold ? "chat-manager-entity-say-bold-wrap-message" : "chat-manager-entity-say-wrap-message", + ("entityName", name), + ("verb", verbName), + ("fontType", speech.FontId), + ("fontSize", speech.FontSize), + ("message", FormattedMessage.EscapeText(message))); + } + /// /// Returns list of players and ranges for all players withing some range. Also returns observers with a range of -1. /// @@ -930,7 +1003,9 @@ public sealed class EntitySpokeEvent : EntityEventArgs public readonly EntityUid Source; public readonly string Message; public readonly string OriginalMessage; - public readonly string? ObfuscatedMessage; // not null if this was a whisper + public readonly string LanguageEncodedMessage; + public readonly string? ObfuscatedMessage; // not null if this was a + public readonly LanguagePrototype Language; /// /// If the entity was trying to speak into a radio, this was the channel they were trying to access. If a radio @@ -938,13 +1013,15 @@ public sealed class EntitySpokeEvent : EntityEventArgs /// public RadioChannelPrototype? Channel; - public EntitySpokeEvent(EntityUid source, string message, string originalMessage, RadioChannelPrototype? channel, string? obfuscatedMessage) + public EntitySpokeEvent(EntityUid source, string message, string originalMessage, string languageEncodedMessage, RadioChannelPrototype? channel, LanguagePrototype language, string? obfuscatedMessage) { Source = source; Message = message; OriginalMessage = originalMessage; // Corvax-TTS: Spec symbol sanitize + LanguageEncodedMessage = languageEncodedMessage; Channel = channel; ObfuscatedMessage = obfuscatedMessage; + Language = language; } } diff --git a/Content.Shared/ADT/Language/Components/CommonLangUnknown.cs b/Content.Shared/ADT/Language/Components/CommonLangUnknown.cs new file mode 100644 index 0000000000..bac1230704 --- /dev/null +++ b/Content.Shared/ADT/Language/Components/CommonLangUnknown.cs @@ -0,0 +1,14 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language; + +[RegisterComponent] +public sealed partial class UnknowLanguageComponent : Component +{ + [DataField("language")] + public string LanguageToForgot = "GalacticCommon"; +} diff --git a/Content.Shared/ADT/Language/Components/LanguageSpeakerComponent.cs b/Content.Shared/ADT/Language/Components/LanguageSpeakerComponent.cs new file mode 100644 index 0000000000..2d3953f78c --- /dev/null +++ b/Content.Shared/ADT/Language/Components/LanguageSpeakerComponent.cs @@ -0,0 +1,53 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language; + +[RegisterComponent, AutoGenerateComponentState] +public sealed partial class LanguageSpeakerComponent : Component +{ + /// + /// The current language the entity may use to speak. + /// Other listeners will hear the entity speak in this language. + /// + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] + public string CurrentLanguage = default!; + + /// + /// чтоб в чате видно было не айди, а название. + /// + public string LocalizedID => Loc.GetString("language-" + CurrentLanguage); + + + /// + /// List of languages this entity can speak. + /// + [ViewVariables] + [DataField("speaks", customTypeSerializer: typeof(PrototypeIdListSerializer), required: true)] + public List SpokenLanguages = new(); + + /// + /// List of languages this entity can understand. + /// + [ViewVariables] + [DataField("understands", customTypeSerializer: typeof(PrototypeIdListSerializer), required: true)] + public List UnderstoodLanguages = new(); + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("languageMenuAction", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string LanguageMenuAction = "ActionLanguageMenu"; + + [DataField] public EntityUid? Action; +} + +[Serializable, NetSerializable] +public enum LanguageMenuUiKey : byte +{ + Key +} + +public sealed partial class LanguageMenuActionEvent : InstantActionEvent { } diff --git a/Content.Shared/ADT/Language/Components/TranslatorComponent.cs b/Content.Shared/ADT/Language/Components/TranslatorComponent.cs new file mode 100644 index 0000000000..a5fac7d2ff --- /dev/null +++ b/Content.Shared/ADT/Language/Components/TranslatorComponent.cs @@ -0,0 +1,93 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language.Components; + +public abstract partial class BaseTranslatorComponent : Component +{ + /// + /// The language this translator changes the speaker's language to when they don't specify one. + /// If null, does not modify the default language. + /// + [DataField("default-language")] + [ViewVariables(VVAccess.ReadWrite)] + public string? CurrentSpeechLanguage = null; + + /// + /// The list of additional languages this translator allows the wielder to speak. + /// + [DataField("spoken", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [ViewVariables(VVAccess.ReadWrite)] + public List SpokenLanguages = new(); + + /// + /// The list of additional languages this translator allows the wielder to understand. + /// + [DataField("understood", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [ViewVariables(VVAccess.ReadWrite)] + public List UnderstoodLanguages = new(); + + /// + /// The languages the wielding MUST know in order for this translator to have effect. + /// The field [RequiresAllLanguages] indicates whether all of them are required, or just one. + /// + [DataField("requires", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [ViewVariables(VVAccess.ReadWrite)] + public List RequiredLanguages = new(); + + /// + /// If true, the wielder must understand all languages in [RequiredLanguages] to speak [SpokenLanguages], + /// and understand all languages in [RequiredLanguages] to understand [UnderstoodLanguages]. + /// + /// Otherwise, at least one language must be known (or the list must be empty). + /// + [DataField("requires-all")] + [ViewVariables(VVAccess.ReadWrite)] + public bool RequiresAllLanguages = false; + + [DataField("enabled")] + public bool Enabled = true; +} + +/// +/// A translator that must be held in a hand or a pocket of an entity in order ot have effect. +/// +[RegisterComponent] +public sealed partial class HandheldTranslatorComponent : BaseTranslatorComponent +{ + /// + /// Whether or not interacting with this translator + /// toggles it on or off. + /// + [DataField("toggleOnInteract")] + public bool ToggleOnInteract = true; +} + +/// +/// A translator attached to an entity that translates its speech. +/// An example is a translator implant that allows the speaker to speak another language. +/// +[RegisterComponent, Virtual] +public partial class IntrinsicTranslatorComponent : BaseTranslatorComponent +{ +} + +/// +/// Applied internally to the holder of [HandheldTranslatorComponent]. +/// Do not use directly. Use [HandheldTranslatorComponent] instead. +/// +[RegisterComponent] +public sealed partial class HoldsTranslatorComponent : IntrinsicTranslatorComponent +{ + public Component? Issuer = null; +} + +/// +/// Applied to entities who were injected with a translator implant. +/// +[RegisterComponent] +public sealed partial class ImplantedTranslatorComponent : IntrinsicTranslatorComponent +{ +} diff --git a/Content.Shared/ADT/Language/Components/TranslatorImplanterComponent.cs b/Content.Shared/ADT/Language/Components/TranslatorImplanterComponent.cs new file mode 100644 index 0000000000..28ed4cce18 --- /dev/null +++ b/Content.Shared/ADT/Language/Components/TranslatorImplanterComponent.cs @@ -0,0 +1,34 @@ +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language.Components; + +/// +/// An item that, when used on a mob, adds an intrinsic translator to it. +/// +[RegisterComponent] +public sealed partial class TranslatorImplanterComponent : Component +{ + [DataField("spoken", customTypeSerializer: typeof(PrototypeIdListSerializer)), ViewVariables] + public List SpokenLanguages = new(); + + [DataField("understood", customTypeSerializer: typeof(PrototypeIdListSerializer)), ViewVariables] + public List UnderstoodLanguages = new(); + + /// + /// The list of languages the mob must understand in order for this translator to have effect. + /// Knowing one language is enough. + /// + [DataField("requires", customTypeSerializer: typeof(PrototypeIdListSerializer)), ViewVariables] + public List RequiredLanguages = new(); + + /// + /// If true, only allows to use this implanter on mobs. + /// + [DataField("mobs-only")] + public bool MobsOnly = true; + + /// + /// Whether this implant has been used already. + /// + public bool Used = false; +} diff --git a/Content.Shared/ADT/Language/Components/UniversalLanguageSpeacerComponent.cs b/Content.Shared/ADT/Language/Components/UniversalLanguageSpeacerComponent.cs new file mode 100644 index 0000000000..7ef609e6ba --- /dev/null +++ b/Content.Shared/ADT/Language/Components/UniversalLanguageSpeacerComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Shared.Language.Components; + +// +// Signifies that this entity can speak and understand any language. +// Applies to such entities as ghosts. +// +[RegisterComponent] +public sealed partial class UniversalLanguageSpeakerComponent : Component +{ + +} diff --git a/Content.Shared/ADT/Language/LanguagePrototype.cs b/Content.Shared/ADT/Language/LanguagePrototype.cs new file mode 100644 index 0000000000..c160187bf6 --- /dev/null +++ b/Content.Shared/ADT/Language/LanguagePrototype.cs @@ -0,0 +1,28 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Language; + +[Prototype("language")] +public sealed class LanguagePrototype : IPrototype +{ + [IdDataField] + public string ID { get; private set; } = default!; + + // + // If true, obfuscated phrases of creatures speaking this language will have their syllables replaced with "replacement" syllables. + // Otherwise entire sentences will be replaced. + // + [DataField("obfuscateSyllables", required: true)] + public bool ObfuscateSyllables { get; private set; } = false; + + // + // Lists all syllables that are used to obfuscate a message a listener cannot understand if obfuscateSyllables is true, + // Otherwise uses all possible phrases the creature can make when trying to say anything. + // + [DataField("replacement", required: true)] + public List Replacement = new(); + + public string LocalizedName => Loc.GetString("language-" + ID + "-name"); + + public string LocalizedDescription => Loc.GetString("language-" + ID + "-description"); +} diff --git a/Content.Shared/ADT/Language/Systems/SharedLanguageSystem.cs b/Content.Shared/ADT/Language/Systems/SharedLanguageSystem.cs new file mode 100644 index 0000000000..54c33fc185 --- /dev/null +++ b/Content.Shared/ADT/Language/Systems/SharedLanguageSystem.cs @@ -0,0 +1,73 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Serialization; + +namespace Content.Shared.Language.Systems; + +public abstract class SharedLanguageSystem : EntitySystem +{ + [ValidatePrototypeId] + public static readonly string GalacticCommonPrototype = "GalacticCommon"; + [ValidatePrototypeId] + public static readonly string UniversalPrototype = "Universal"; + public static LanguagePrototype GalacticCommon { get; private set; } = default!; + public static LanguagePrototype Universal { get; private set; } = default!; + + [Dependency] private readonly SharedActionsSystem _action = default!; + [Dependency] protected readonly IPrototypeManager _prototype = default!; + [Dependency] protected readonly IRobustRandom _random = default!; + protected ISawmill _sawmill = default!; + + public override void Initialize() + { + GalacticCommon = _prototype.Index("GalacticCommon"); + Universal = _prototype.Index("Universal"); + _sawmill = Logger.GetSawmill("language"); + + SubscribeLocalEvent(OnInit); + } + + public LanguagePrototype? GetLanguage(string id) + { + _prototype.TryIndex(id, out var proto); + return proto; + } + + private void OnInit(EntityUid uid, LanguageSpeakerComponent component, MapInitEvent args) + { + _action.AddAction(uid, ref component.Action, component.LanguageMenuAction, uid); + } + + /// + /// Raised on an entity when its list of languages changes. + /// + public sealed class LanguagesUpdateEvent : EntityEventArgs + { + } + + /// + /// Sent when a client wants to update its language menu. + /// + [Serializable, NetSerializable] + public sealed class RequestLanguageMenuStateMessage : EntityEventArgs + { + } + + /// + /// Sent by the server when the client needs to update its language menu, + /// or directly after [RequestLanguageMenuStateMessage]. + /// + [Serializable, NetSerializable] + public sealed class LanguageMenuStateMessage : EntityEventArgs + { + public string CurrentLanguage; + public List Options; + + public LanguageMenuStateMessage(string currentLanguage, List options) + { + CurrentLanguage = currentLanguage; + Options = options; + } + } +} diff --git a/Content.Shared/ADT/Language/Systems/SharedTranslatorImplanterSystem.cs b/Content.Shared/ADT/Language/Systems/SharedTranslatorImplanterSystem.cs new file mode 100644 index 0000000000..5a602d03c5 --- /dev/null +++ b/Content.Shared/ADT/Language/Systems/SharedTranslatorImplanterSystem.cs @@ -0,0 +1,36 @@ +using Content.Shared.Examine; +using Content.Shared.Implants.Components; +using Content.Shared.Language.Components; +using Robust.Shared.Serialization; + +namespace Content.Shared.Language.Systems; + +public abstract class SharedTranslatorImplanterSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + } + + private void OnExamined(EntityUid uid, TranslatorImplanterComponent component, ExaminedEvent args) + { + if (!args.IsInDetailsRange) + return; + + var text = !component.Used + ? Loc.GetString("translator-implanter-ready") + : Loc.GetString("translator-implanter-used"); + + args.PushText(text); + } + + protected void OnAppearanceChange(EntityUid implanter, TranslatorImplanterComponent component) + { + var used = component.Used; + _appearance.SetData(implanter, ImplanterVisuals.Full, !used); + } +} diff --git a/Content.Shared/ADT/Language/Systems/SharedTranslatorSystem.cs b/Content.Shared/ADT/Language/Systems/SharedTranslatorSystem.cs new file mode 100644 index 0000000000..540744139d --- /dev/null +++ b/Content.Shared/ADT/Language/Systems/SharedTranslatorSystem.cs @@ -0,0 +1,34 @@ +using Content.Shared.Examine; +using Content.Shared.Language.Components; +using Content.Shared.Toggleable; + +namespace Content.Shared.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 state = Loc.GetString(component.Enabled + ? "translator-enabled" + : "translator-disabled"); + + args.PushMarkup(state); + } + + protected void OnAppearanceChange(EntityUid translator, HandheldTranslatorComponent? comp = null) + { + if (comp == null && !TryComp(translator, out comp)) + return; + + _appearance.SetData(translator, ToggleVisuals.Toggled, comp.Enabled); + } +} diff --git a/Content.Shared/ADT/SwitchableWeapon/SwitchableWeaponComponent.cs b/Content.Shared/ADT/SwitchableWeapon/SwitchableWeaponComponent.cs new file mode 100644 index 0000000000..c4020bcd5a --- /dev/null +++ b/Content.Shared/ADT/SwitchableWeapon/SwitchableWeaponComponent.cs @@ -0,0 +1,51 @@ + +using Content.Shared.Damage; +using Content.Shared.Item; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Shared.ADT.SwitchableWeapon; + +[RegisterComponent] +public sealed partial class SwitchableWeaponComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite)][DataField("damageFolded")] + public DamageSpecifier DamageFolded = new(){ + DamageDict = new() + { + { "Blunt", 0.0f }, + } + }; + + [ViewVariables(VVAccess.ReadWrite)][DataField("damageOpen")] + public DamageSpecifier DamageOpen = new(){ + DamageDict = new() + { + { "Blunt", 4.0f }, + } + }; + + [ViewVariables(VVAccess.ReadWrite)][DataField("staminaDamageFolded")] + public float StaminaDamageFolded = 0; + + [ViewVariables(VVAccess.ReadWrite)][DataField("staminaDamageOpen")] + public float StaminaDamageOpen = 28; + + [ViewVariables(VVAccess.ReadWrite)][DataField("isOpen")] + public bool IsOpen = false; + + [ViewVariables(VVAccess.ReadWrite)][DataField("openSound")] + public SoundSpecifier? OpenSound; + + [ViewVariables(VVAccess.ReadWrite)][DataField("closeSound")] + public SoundSpecifier? CloseSound; + + [ViewVariables(VVAccess.ReadWrite)][DataField("bonkSound")] + public SoundSpecifier? BonkSound; + + [ViewVariables(VVAccess.ReadWrite)][DataField("sizeOpened")] + public ProtoId SizeOpened = "Normal"; + + [ViewVariables(VVAccess.ReadWrite)][DataField("sizeClosed")] + public ProtoId SizeClosed = "Normal"; +} diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index 825eca17cf..a563d39639 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -35,6 +35,11 @@ public string GetName(string species, Gender? gender = null) case SpeciesNaming.FirstDashFirst: return Loc.GetString("namepreset-firstdashfirst", ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender))); + // Start ADT Tweak: Drask naming + case SpeciesNaming.FirstDashFirstDashFirst: + return Loc.GetString("namepreset-firstdashfirstdashfirst", + ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender)), ("first3", GetFirstName(speciesProto, gender))); + // End ADT Tweak case SpeciesNaming.FirstLast: default: return Loc.GetString("namepreset-firstlast", diff --git a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs index e91785114c..1405c4b5a9 100644 --- a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs @@ -140,5 +140,8 @@ public enum SpeciesNaming : byte First, FirstLast, FirstDashFirst, + // ADT Start tweak: Drask naming + FirstDashFirstDashFirst, + // ADT End tweak TheFirstofLast, } diff --git a/Resources/Audio/ADT/Drask/draskcough.ogg b/Resources/Audio/ADT/Drask/draskcough.ogg new file mode 100644 index 0000000000..613f5ddb39 Binary files /dev/null and b/Resources/Audio/ADT/Drask/draskcough.ogg differ diff --git a/Resources/Audio/ADT/Drask/draskscream.ogg b/Resources/Audio/ADT/Drask/draskscream.ogg new file mode 100644 index 0000000000..102f3e727f Binary files /dev/null and b/Resources/Audio/ADT/Drask/draskscream.ogg differ diff --git a/Resources/Audio/ADT/Drask/drasksneeze.ogg b/Resources/Audio/ADT/Drask/drasksneeze.ogg new file mode 100644 index 0000000000..36080e03ee Binary files /dev/null and b/Resources/Audio/ADT/Drask/drasksneeze.ogg differ diff --git a/Resources/Audio/ADT/Drask/drasktalk.ogg b/Resources/Audio/ADT/Drask/drasktalk.ogg new file mode 100644 index 0000000000..8a22bf3545 Binary files /dev/null and b/Resources/Audio/ADT/Drask/drasktalk.ogg differ diff --git a/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg b/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg new file mode 100644 index 0000000000..227ce64529 Binary files /dev/null and b/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg differ diff --git a/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/open_telescopichka.ogg b/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/open_telescopichka.ogg new file mode 100644 index 0000000000..a812baff65 Binary files /dev/null and b/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/open_telescopichka.ogg differ diff --git a/Resources/Locale/en-US/ADT/Body/Parts/demon.ftl b/Resources/Locale/en-US/ADT/Body/Parts/demon.ftl new file mode 100644 index 0000000000..48a7c98fb8 --- /dev/null +++ b/Resources/Locale/en-US/ADT/Body/Parts/demon.ftl @@ -0,0 +1,22 @@ +ent-PartDemon = demon body part + .desc = { ent-BaseItem.desc } +ent-TorsoDemon = demon torso + .desc = { ent-PartDemon.desc } +ent-HeadDemon = demon head + .desc = { ent-PartDemon.desc } +ent-LeftArmDemon = left demon arm + .desc = { ent-PartDemon.desc } +ent-RightArmDemon = right demon arm + .desc = { ent-PartDemon.desc } +ent-LeftHandDemon = left demon hand + .desc = { ent-PartDemon.desc } +ent-RightHandDemon = right demon hand + .desc = { ent-PartDemon.desc } +ent-LeftLegDemon = left demon leg + .desc = { ent-PartDemon.desc } +ent-RightLegDemon = right demon leg + .desc = { ent-PartDemon.desc } +ent-LeftFootDemon = left demon foot + .desc = { ent-PartDemon.desc } +ent-RightFootDemon = right demon foot + .desc = { ent-PartDemon.desc } diff --git a/Resources/Locale/en-US/ADT/Entities/Mobs/Species/demon.ftl b/Resources/Locale/en-US/ADT/Entities/Mobs/Species/demon.ftl new file mode 100644 index 0000000000..d07b87e90b --- /dev/null +++ b/Resources/Locale/en-US/ADT/Entities/Mobs/Species/demon.ftl @@ -0,0 +1,4 @@ +ent-BaseMobDemon = Urisst' Mzhand Demon + .desc = { ent-BaseMobSpecies.desc } +ent-MobDemonDummy = Urist McHands + .desc = A dummy reptilian meant to be used in character setup. diff --git a/Resources/Locale/en-US/species/namepreset.ftl b/Resources/Locale/en-US/species/namepreset.ftl index 5a42c87b78..092d0b6d62 100644 --- a/Resources/Locale/en-US/species/namepreset.ftl +++ b/Resources/Locale/en-US/species/namepreset.ftl @@ -1,4 +1,7 @@ namepreset-first = {$first} namepreset-firstlast = {$first} {$last} namepreset-firstdashfirst = {$first1}-{$first2} +# Start ADT tweak: Drask +namepreset-firstdashfirstdashfirst = { $first1 }-{ $first2 }-{ $first3 } +# End ADT tweak namepreset-thefirstoflast = The {$first} of {$last} diff --git a/Resources/Locale/ru-RU/ADT/Actions/language-menu.ftl b/Resources/Locale/ru-RU/ADT/Actions/language-menu.ftl new file mode 100644 index 0000000000..56833276de --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Actions/language-menu.ftl @@ -0,0 +1,6 @@ +language-menu-window-title = Выбор языка +language-menu-current-language = Выбранный язык: {$language} +language-menu-description-header = Описание +choose-lang-button = Выбрать +language-menu-action = Меню языков +language-menu-action-desc = Открыть меню выбора языка. diff --git a/Resources/Locale/ru-RU/ADT/Body/Organs/demon.ftl b/Resources/Locale/ru-RU/ADT/Body/Organs/demon.ftl new file mode 100644 index 0000000000..a216c9d900 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Organs/demon.ftl @@ -0,0 +1,2 @@ +ent-OrganDemonStomach = { ent-OrganAnimalStomach } + .desc = { ent-OrganAnimalStomach.desc } diff --git a/Resources/Locale/ru-RU/ADT/Body/Organs/drask.ftl b/Resources/Locale/ru-RU/ADT/Body/Organs/drask.ftl new file mode 100644 index 0000000000..63dfb61b32 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Organs/drask.ftl @@ -0,0 +1,10 @@ +ent-OrganDraskEyes = глаза + .desc = Я тебя вижу! +ent-OrganDraskLungs = лёгкие + .desc = Фильтрует кислород из атмосферы, который затем поступает в кровь для использования в качестве переносчика электронов. +ent-OrganDraskHeart = сердце + .desc = Мне жаль того бессердечного ублюдка, который его потерял. +ent-OrganDraskInnards = внутренности + .desc = Мерзость. +ent-OrganDraskKidneys = почки + .desc = Выводят токсины из кровеносной системы. diff --git a/Resources/Locale/ru-RU/ADT/Body/Parts/demon.ftl b/Resources/Locale/ru-RU/ADT/Body/Parts/demon.ftl new file mode 100644 index 0000000000..d3d5b5e8ae --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Parts/demon.ftl @@ -0,0 +1,22 @@ +ent-PartDemon = часть тела арканы + .desc = { ent-BaseItem.desc } +ent-TorsoDemon = торс арканы + .desc = { ent-PartDemon.desc } +ent-HeadDemon = голова арканы + .desc = { ent-PartDemon.desc } +ent-LeftArmDemon = левая рука арканы + .desc = { ent-PartDemon.desc } +ent-RightArmDemon = правая рука арканы + .desc = { ent-PartDemon.desc } +ent-LeftHandDemon = левая кисть арканы + .desc = { ent-PartDemon.desc } +ent-RightHandDemon = правая кисть арканы + .desc = { ent-PartDemon.desc } +ent-LeftLegDemon = левая нога арканы + .desc = { ent-PartDemon.desc } +ent-RightLegDemon = правая нога арканы + .desc = { ent-PartDemon.desc } +ent-LeftFootDemon = левая стопа арканы + .desc = { ent-PartDemon.desc } +ent-RightFootDemon = правая стопа арканы + .desc = { ent-PartDemon.desc } diff --git a/Resources/Locale/ru-RU/ADT/Body/Parts/drask.ftl b/Resources/Locale/ru-RU/ADT/Body/Parts/drask.ftl new file mode 100644 index 0000000000..5dd856b7d7 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Parts/drask.ftl @@ -0,0 +1,2 @@ +marking-DraskArmRight = правая рука +marking-DraskArmLeft = левая рука diff --git a/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl b/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl similarity index 55% rename from Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl rename to Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl index 7a17abf365..c7d9b2badd 100644 --- a/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl +++ b/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl @@ -9,3 +9,12 @@ metabolizer-type-plant = Растение metabolizer-type-dwarf = Дварф metabolizer-type-moth = Ниан metabolizer-type-arachnid = Арахнид +metabolizer-type-drask = Драск +metabolizer-type-demon = Аркана +metabolizer-type-novakid = Новакид +metabolizer-type-shark = Акула +metabolizer-type-vulpkanin = Вульпканин +metabolizer-type-tajaran = Таяран +metabolizer-type-reptilian = Унатх +metabolizer-type-ursus = Урс +metabolizer-type-felinid = Фелинид diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/demon.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/demon.ftl new file mode 100644 index 0000000000..c9f0b371ae --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/demon.ftl @@ -0,0 +1,2 @@ +ent-MobDemon = { ent-BaseMobDemon } + .desc = { ent-BaseMobDemon.desc } diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/drask.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/drask.ftl new file mode 100644 index 0000000000..19a7093e9f --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/drask.ftl @@ -0,0 +1,2 @@ +ent-MobDrask = { ent-BaseMobDrask } + .desc = { ent-BaseMobDrask.desc } diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/demon.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/demon.ftl new file mode 100644 index 0000000000..ae5d1f883b --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/demon.ftl @@ -0,0 +1,5 @@ +ent-BaseMobDemon = Урист МакАркана + .desc = { ent-BaseMobSpeciesOrganic.desc } + .suffix = Аркана +ent-MobDemonDummy = { ent-BaseSpeciesDummy } + .desc = { ent-BaseSpeciesDummy.desc } diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/drask.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/drask.ftl new file mode 100644 index 0000000000..1d985504e9 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/drask.ftl @@ -0,0 +1,5 @@ +ent-BaseMobDrask = Урист МакДраск + .desc = { ent-BaseMobSpeciesOrganic.desc } + .suffix = Драск +ent-MobDraskDummy = { ent-BaseSpeciesDummy } + .desc = { ent-BaseSpeciesDummy.desc } diff --git a/Resources/Locale/ru-RU/ADT/Entities/Objects/Device/translators.ftl b/Resources/Locale/ru-RU/ADT/Entities/Objects/Device/translators.ftl new file mode 100644 index 0000000000..5ae89edec3 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Objects/Device/translators.ftl @@ -0,0 +1,61 @@ +translator-component-shutoff = {$translator} выключается. +translator-component-turnon = The {$translator} включается. +translator-enabled = Оно включено. +translator-disabled = Оно выключено. + +ent-TranslatorUnpowered = переводчик + .desc = Переводит речь. + +ent-Translator = переводчик + .desc = Переводит речь. + +ent-VulpTranslator = переводчик вульпканинов + .desc = Используется вульпканинами, для понимания Общегалактического языка в случае его незнания. + +ent-CanilunztTranslator = переводчик Каннилунц + .desc = Используется для взаимного перевода Общегалактического языка и языка Каннилунц. + +ent-BubblishTranslator = переводчик Пузырчатого языка + .desc = Используется для взаимного перевода Общегалактического и Пузырчатого языков. + +ent-NekomimeticTranslator = переводчик некоязыка + .desc = Используется для взаимного перевода Общегалактического и неко-языков. + +ent-DraconicTranslator = переводчик Синта'унати + .desc = Используется для взаимного перевода Общегалактического языка и Синта'унати. + +ent-SolCommonTranslator = переводчик Солнечного языка + .desc = Используется для взаимного перевода Общегалактического и Солнечного языков. + +ent-RootSpeakTranslator = переводчик Песни Корней + .desc = Используется для взаимного перевода Общегалактического языка и Песни Корней. + +ent-MofficTranslator = переводчик Паучьего языка + .desc = Используется для взаимного перевода Общегалактического и Паучьего языков. + +ent-XenoTranslator = переводчик языка ксено + .desc = Используется для общения с наименее агрессивными ксеноморфами. + +ent-AnimalTranslator = переводчик для животных + .desc = Используется для общения с животными. + +ent-DraskTranslator = переводчик языка Орлуум + .desc = Используется для взаимного перевода Общегалактического языка и языка Орлуум. + +ent-SikTajTranslator = переводчик Сик'тайр + .desc = Используется для взаимного перевода Общегалактического языка и Сик'тайр. + +ent-CintaTajTranslator = переводчик Синта’Тайр + .desc = Используется для взаимного перевода Общегалактического языка и Синта’тайр. + +ent-ArkaneTranslator = переводчик языка Каукиттен + .desc = Используется для взаимного перевода Общегалактического языка и Каукиттен. + +ent-ShadowkinTranslator = переводчик языка Миар + .desc = Используется для взаимного перевода Общегалактического языка и Миар. + +ent-NianTranslator = переводчик Ткачьего языка + .desc = Используется для взаимного перевода Общегалактического и Ткачьего языков. + +ent-FireTranslator = переводчик Огненного языка + .desc = Используется для взаимного перевода Общегалактического и Огненного языков. diff --git a/Resources/Locale/ru-RU/ADT/Entities/Objects/Misc/implanters.ftl b/Resources/Locale/ru-RU/ADT/Entities/Objects/Misc/implanters.ftl new file mode 100644 index 0000000000..ae8e374fb5 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Objects/Misc/implanters.ftl @@ -0,0 +1,68 @@ +translator-implanter-refuse = {$implanter} не возымел эффекта для {$target}. +translator-implanter-success = {$implanter} успешно имплантирован в {$target}. +translator-implanter-ready = Имплантер готов к использованию. +translator-implanter-used = Имплантер пуст. + +ent-BasicGalaticCommonTranslatorImplanter = базовый языковой имплант Общегалактического языка + .desc = Имплант, позволяющий понимать Общегалактический язык. + +ent-AdvancedGalaticCommonTranslatorImplanter = полноценный языковой имплант Общегалактического языка + .desc = Имплант, позволяющий понимать и общаться на Общегалактическом языке. + +ent-BubblishTranslatorImplanter = полноценный языковой имплант Пузырчатого языка + .desc = Имплант, позволяющий понимать и общаться на Пузырчатом языке. + +ent-NekomimeticTranslatorImplanter = полноценный языковой имплант некоязыка + .desc = Имплант, позволяющий понимать и общаться на некоязыке. + +ent-DraconicTranslatorImplanter = полноценный языковой имплант Синта'унати + .desc = Имплант, позволяющий понимать и общаться на Синта'унати. + +ent-CanilunztTranslatorImplanter = полноценный языковой имплант Канилунц + .desc = Имплант, позволяющий понимать и общаться на языке Канилунц. + +ent-SolCommonTranslatorImplanter = полноценный языковой имплант Солнечного языка + .desc = Имплант, позволяющий понимать и общаться на Солнечном языке. + +ent-RootSpeakTranslatorImplanter = базовый языковой имплант Песни корней + .desc = Имплант, позволяющий понимать Песнь корней. + +ent-MofficTranslatorImplanter = полноценный языковой имплант Паучьего языка + .desc = Имплант, позволяющий понимать и общаться на Паучьем языке. + +ent-CodeSpeakImplanter = полноценный языковой имплант Кодового языка + .desc = Имплант, позволяющий понимать и общаться на Кодовом языке. + +ent-SikTajTranslatorImplanter = полноценный языковой имплант языка Сик'тайр + .desc = Имплант, позволяющий понимать и общаться на Сик'тайре. + +ent-CintaTajTranslatorImplanter = полноценный языковой имплант языка Синта’Тайр + .desc = Имплант, позволяющий понимать и общаться на Синта’тайре. + +ent-NianTranslatorImplanter = полноценный языковой имплант Ткачьего языка + .desc = Имплант, позволяющий понимать и общаться на Ткачьем языке. + +ent-FireTranslatorImplanter = базовый языковой имплант Огненного языка + .desc = Имплант, позволяющий понимать Огненный язык. + +ent-DraskTranslatorImplanter = полноценный языковой имплант Орлуум + .desc = Имплант, позволяющий понимать и общаться на языке Орлуум. + +ent-UrsTranslatorImplanter = полноценный языковой имплант Рыкрур + .desc = Имплант, позволяющий понимать и общаться на языке Рыкрур. + +ent-ArkaneTranslatorImplanter = полноценный языковой имплант Каукиттен + .desc = Имплант, позволяющий понимать и общаться на языке Каукиттен. + +ent-ShadowkinTranslatorImplanter = полноценный языковой имплант Миар + .desc = Имплант, позволяющий понимать и общаться на языке Миар. + +ent-BorgTranslatorImplanter = полноценный языковой имплант двоичного кода + .desc = Имплант, позволяющий понимать и общаться на двоичном коде. + +ent-SyndUniversalTranslatorImplanter = универсальный языковой имплант + .desc = Имплант, позволяющий (только) понимать все расовые языки. + +ent-DevTranslatorImplanter = имплант языка разработчика + .desc = Опять чинить апстрим? + .suffix = АДМЕМЫ diff --git a/Resources/Locale/ru-RU/ADT/Entities/Objects/Weapons/Melee/melee.ftl b/Resources/Locale/ru-RU/ADT/Entities/Objects/Weapons/Melee/melee.ftl new file mode 100644 index 0000000000..2e24b4cba2 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Objects/Weapons/Melee/melee.ftl @@ -0,0 +1,9 @@ +ent-ADTtelescopicBaton = Телескопическая дубинка + .desc = "Большая, опасная и выдвижная дубинка. Может храниться в карманах в сложенном состоянии." + .suffix = { "" } +ent-ADTtelescopicBatonBob = Телескопическая дубинка Боба + .desc = "Эксклюзивная телескопическая дубинка, полностью из золота." + .suffix = { "" } +ent-ADTtelescopicBatonKon = Телескопическая дубинка Йохана + .desc = "Непонятно, кровь это или цвет дубинки.." + .suffix = { "" } diff --git a/Resources/Locale/ru-RU/ADT/Languages/languages.ftl b/Resources/Locale/ru-RU/ADT/Languages/languages.ftl new file mode 100644 index 0000000000..f1cdbe6c92 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Languages/languages.ftl @@ -0,0 +1,133 @@ +language-Universal-name = Универсальный +language-Universal-description = Что ты такое? +language-GalacticCommon-name = Общегалактический +language-GalacticCommon-description = Обычно используется для межвидового общения и официальных целей. +language-Bubblish-name = Пузырчатый +language-Bubblish-description = Язык слаймолюдов. Это смесь булькающих звуков и хлюпов. Человеку очень трудно говорить без механической помощи. +language-RootSpeak-name = Песнь корней +language-RootSpeak-description = Странный шелестящий язык, на котором говорят дионы. +language-CodeSpeak-name = Кодовый язык +language-CodeSpeak-description = Оперативники синдиката могут использовать серию кодовых слов для передачи сложной информации, в то время как для любого слушателя они звучат как случайные понятия и напитки. +language-Nekomimetic-name = Некоязык +language-Nekomimetic-description = Для стороннего наблюдателя этот язык представляет собой непонятную смесь ломаного японского. Для фелинидов он каким-то образом понятен. +language-Draconic-name = Синта'унати +language-Draconic-description = Общий язык унатхов с преобладающими шипящими звуками. +language-Canilunzt-name = Канилунц +language-Canilunzt-description = Гортанный язык, на котором говорят и используют обитатели системы Ваззенда, состоящий из рычания, лая, тявканья и интенсивного использования движений ушей и хвоста, вулпканины говорят на этом языке с легкостью. + +language-SikTaj-name = Сик'тайр +language-SikTaj-description = Язык, на котором говорят и используют обитатели системы Адомай. Таяры говорят на этом языке с легкостью. + +language-Nian-name = Ткачий +language-Nian-description = Язык, состоящий из жужжащих звуков, на котором говорят и используют нианы. + +language-Fire-name = Огненный +language-Fire-description = Звуки огня, что каким-то образом складываются в осмысленную речь. + +language-SolCommon-name = Солнечный язык +language-SolCommon-description = Общий язык, на котором говорят обитатели солнечной системы. +language-Cat-name = Кошачий +language-Cat-description = Примитивные звуки, издаваемые кошками. Каким-то образом они передают смысл! + +language-Dog-name = Собачий +language-Dog-description = Лающие и рычащие звуки, используемые для передачи примитивных значений. + +language-Mothroach-name = Молиный +language-Mothroach-description = Милые пищащие звуки, из которых иногда складываются осмысленные фразы. + +language-Xeno-name = Ксено +language-Xeno-description = Давно забытый язык ксеноморфов. + +language-RobotTalk-name = Троичный +language-RobotTalk-description = Это не язык сам по себе, но он используется роботами и КПБ для обмена данными. + +language-Monkey-name = Обезьяний +language-Monkey-description = Набор звуков и жестов, издаваемых приматами с целью общения. + +language-Bee-name = Пчелиный +language-Bee-description = Странный язык, основанный на движениях, которые пчелы используют для общения. + +language-Mouse-name = Мышиный +language-Mouse-description = Милые пищащие звуки, которые мыши используют, чтобы выпрашивать еду. + +# These ones are half-assed because these creatures are almost never played as. +language-Chicken-name = Animal chicken +language-Chicken-description = A collection of sounds made by chickens. + +language-Duck-name = Animal duck +language-Duck-description = A collection of sounds made by ducks. + +language-Cow-name = Animal cow +language-Cow-description = A collection of sounds made by cows. + +language-Sheep-name = Animal sheep +language-Sheep-description = A collection of sounds made by sheep. + +language-Kangaroo-name = Animal kangaroo +language-Kangaroo-description = A collection of sounds made by kangaroos. + +language-Pig-name = Animal pig +language-Pig-description = A collection of sounds made by pigs. + +language-Moffic-name = Паучий +language-Moffic-description = Древний язык, на котором говорят арахниды. + +language-Drask-name = Орлуум +language-Drask-description = Монотонный, вибрирующий язык драсков. Он чем-то напоминает китовую песню. + +language-BorgTalk-name = Двоичный +language-BorgTalk-description = Нули и единицы, передающие массивные и не очень данные. + +language-Urs-name = Рыкрур +language-Urs-description = Басистый и рычащий язык, на котором говорят урсы. + +language-Arkane-name = Каукиттен +language-Arkane-description = Протяжный, чем-то напоминающий Солнечный язык, на котором говорят арканы. + +language-Shadowkin-name = Миар +language-Shadowkin-description = Загадочный язык, на котором говорят сумеречники. + +language-Dwarf-name = Шахтёрский +language-Dwarf-description = Rock and stone! + +language-Dev-name = Разработческий +language-Dev-description = Больше звучит как ругань покрытая кодом, чем язык. + +language-CintaTaj-name = Синта’Тайр +language-CintaTaj-description = Язык, разработанный таярами и унатхами для общения между двумя расами, представляет собой смесь шипений и слов. + +language-GalacticCommon = Общ. +language-Bubblish = Пузырчатый +language-RootSpeak = Песнь корней +language-CodeSpeak = Кодовый +language-Nekomimetic = Неко +language-Draconic = Синта'унати +language-Canilunzt = Канилунц +language-SikTaj = Сик'тайр +language-Nian = Ткачий +language-Fire = Огненный +language-SolCommon = Солнечный +language-Cat = Кошачий +language-Dog = Собачий +language-Mothroach = Молиный +language-Xeno = Ксено +language-RobotTalk = Троичный +language-Monkey = Обезьяний +language-Bee = Пчелиный +language-Mouse = Мышиный +language-Drask = Орлуум +# These ones are half-assed because these creatures are almost never played as. +language-Chicken = Animal chicken +language-Duck = Animal duck +language-Cow = Animal cow +language-Sheep = Animal sheep +language-Kangaroo = Animal kangaroo +language-Pig = Animal pig +language-Moffic = Паучий +language-BorgTalk = Двоичный +language-Urs = Рыкрур +language-Arkane = Каукиттен +language-Shadowkin = Миар +language-Dev = Разраб +language-Dwarf = Шахт +language-CintaTaj = Синта’тайр diff --git a/Resources/Locale/ru-RU/ADT/Research/translators.ftl b/Resources/Locale/ru-RU/ADT/Research/translators.ftl new file mode 100644 index 0000000000..13ef329422 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Research/translators.ftl @@ -0,0 +1,3 @@ +research-technology-basic-translation = Технология базовых переводчиков + +research-technology-advanced-translation = Технология продвинутых переводчиков diff --git a/Resources/Locale/ru-RU/ADT/Species/demon.ftl b/Resources/Locale/ru-RU/ADT/Species/demon.ftl new file mode 100644 index 0000000000..903d09dfbd --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Species/demon.ftl @@ -0,0 +1 @@ +species-name-demon = Аркана diff --git a/Resources/Locale/ru-RU/ADT/Species/drask.ftl b/Resources/Locale/ru-RU/ADT/Species/drask.ftl new file mode 100644 index 0000000000..5cdbc67a20 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Species/drask.ftl @@ -0,0 +1 @@ +species-name-drask = Драск diff --git a/Resources/Locale/ru-RU/ADT/Species/kobolt.ftl b/Resources/Locale/ru-RU/ADT/Species/kobolt.ftl new file mode 100644 index 0000000000..c3a413cdb8 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Species/kobolt.ftl @@ -0,0 +1 @@ +species-name-kobolt = Кобольд diff --git a/Resources/Prototypes/ADT/Actions/language.yml b/Resources/Prototypes/ADT/Actions/language.yml new file mode 100644 index 0000000000..222a73c9ba --- /dev/null +++ b/Resources/Prototypes/ADT/Actions/language.yml @@ -0,0 +1,12 @@ +- type: entity + id: ActionLanguageMenu + name: language-menu-action + description: language-menu-action-desc + noSpawn: true + components: + - type: InstantAction + checkCanInteract: false + icon: _NF/Interface/Actions/language.png + event: !type:LanguageMenuActionEvent + useDelay: 2 + priority: -97 diff --git a/Resources/Prototypes/ADT/Body/Organs/Drask.yml b/Resources/Prototypes/ADT/Body/Organs/Drask.yml new file mode 100644 index 0000000000..53a6c3b096 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Organs/Drask.yml @@ -0,0 +1,103 @@ +- type: entity + id: OrganDraskEyes + parent: BaseHumanOrgan + suffix: "drask" + name: eyes + description: "I see you!" + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: eyes + +- type: entity + id: OrganDraskLungs + parent: BaseHumanOrgan + suffix: "drask" + name: lungs + description: "Filters oxygen from an atmosphere, which is then sent into the bloodstream to be used as an electron carrier." + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: lungs + - type: Lung + - type: Metabolizer + removeEmpty: true + solutionOnBody: false + solution: "Lung" + metabolizerTypes: [ Drask ] + groups: + - id: Gas + rateModifier: 100.0 + - type: SolutionContainerManager + solutions: + organ: + reagents: + - ReagentId: Nutriment + Quantity: 10 + Lung: + maxVol: 100.0 + canReact: false + food: + maxVol: 5 + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 5 + +- type: entity + id: OrganDraskHeart + parent: BaseHumanOrgan + suffix: "drask" + name: heart + description: "I feel bad for the heartless bastard who lost this." + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: heart_on + - type: Metabolizer + maxReagents: 2 + metabolizerTypes: [ Drask ] + groups: + - id: Medicine + - id: Poison + - id: Narcotic + +- type: entity + id: OrganDraskInnards + parent: BaseHumanOrgan + suffix: "drask" + name: innards + description: "Ew innards." + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: innards + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 50 + food: + maxVol: 5 + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 5 + - type: Stomach + - type: Metabolizer + maxReagents: 3 + metabolizerTypes: [ Drask ] + groups: + - id: Food + - id: Drink + +- type: entity + id: OrganDraskKidneys + parent: BaseHumanOrgan + suffix: "drask" + name: kidneys + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: kidneys + - type: Metabolizer + maxReagents: 5 + metabolizerTypes: [ Drask ] + removeEmpty: true diff --git a/Resources/Prototypes/ADT/Body/Organs/demon.yml b/Resources/Prototypes/ADT/Body/Organs/demon.yml new file mode 100644 index 0000000000..544df0ff96 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Organs/demon.yml @@ -0,0 +1,21 @@ +- type: entity + id: OrganDemonStomach + parent: OrganAnimalStomach + noSpawn: true + components: + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 50 + +- type: entity + id: OrganDemonHeart + parent: OrganAnimalHeart + components: + - type: Metabolizer + maxReagents: 2 + metabolizerTypes: [ Demon ] + groups: + - id: Medicine + - id: Poison + - id: Narcotic diff --git a/Resources/Prototypes/ADT/Body/Organs/fill.txt b/Resources/Prototypes/ADT/Body/Organs/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Body/Organs/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Body/Parts/Drask.yml b/Resources/Prototypes/ADT/Body/Parts/Drask.yml new file mode 100644 index 0000000000..bceb64a62b --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Parts/Drask.yml @@ -0,0 +1,190 @@ +# TODO: Add descriptions (many) +# TODO BODY: Part damage +- type: entity + id: PartDrask + parent: BaseItem + name: "drask body part" + abstract: true + components: + - type: Damageable + damageContainer: Biological + - type: BodyPart + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + +- type: entity + id: TorsoDrask + name: "drask torso" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "torso_m" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "torso_m" + - type: BodyPart + partType: Torso + +- type: entity + id: HeadDrask + name: "drask head" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "head_m" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "head_m" + - type: BodyPart + partType: Head + vital: true + - type: Input + context: "ghost" + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: InputMover + - type: GhostOnMove + - type: Tag + tags: + - Head + +- type: entity + id: LeftArmDrask + name: "left drask arm" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_arm" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_arm" + - type: BodyPart + partType: Arm + symmetry: Left + +- type: entity + id: RightArmDrask + name: "right drask arm" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_arm" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_arm" + - type: BodyPart + partType: Arm + symmetry: Right + +- type: entity + id: LeftHandDrask + name: "left drask hand" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_hand" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_hand" + - type: BodyPart + partType: Hand + symmetry: Left + +- type: entity + id: RightHandDrask + name: "right drask hand" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_hand" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_hand" + - type: BodyPart + partType: Hand + symmetry: Right + +- type: entity + id: LeftLegDrask + name: "left drask leg" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_leg" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_leg" + - type: BodyPart + partType: Leg + symmetry: Left + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: RightLegDrask + name: "right drask leg" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_leg" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_leg" + - type: BodyPart + partType: Leg + symmetry: Right + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: LeftFootDrask + name: "left drask foot" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_foot" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_foot" + - type: BodyPart + partType: Foot + symmetry: Left + +- type: entity + id: RightFootDrask + name: "right drask foot" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_foot" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_foot" + - type: BodyPart + partType: Foot + symmetry: Right diff --git a/Resources/Prototypes/ADT/Body/Parts/demon.yml b/Resources/Prototypes/ADT/Body/Parts/demon.yml new file mode 100644 index 0000000000..ddc0a23bd8 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Parts/demon.yml @@ -0,0 +1,193 @@ +# TODO: Add descriptions (many) +# TODO BODY: Part damage +- type: entity + id: PartDemon + parent: BaseItem + name: "demon body part" + abstract: true + components: + - type: Damageable + damageContainer: Biological + - type: BodyPart + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + - type: Tag + tags: + - Trash + +- type: entity + id: TorsoDemon + name: "demon torso" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "torso_m" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "torso_m" + - type: BodyPart + partType: Torso + +- type: entity + id: HeadDemon + name: "demon head" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "head_m" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "head_m" + - type: BodyPart + partType: Head + vital: true + - type: Input + context: "ghost" + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: InputMover + - type: GhostOnMove + - type: Tag + tags: + - Head + +- type: entity + id: LeftArmDemon + name: "left demon arm" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_arm" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_arm" + - type: BodyPart + partType: Arm + symmetry: Left + +- type: entity + id: RightArmDemon + name: "right demon arm" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_arm" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_arm" + - type: BodyPart + partType: Arm + symmetry: Right + +- type: entity + id: LeftHandDemon + name: "left demon hand" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_hand" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_hand" + - type: BodyPart + partType: Hand + symmetry: Left + +- type: entity + id: RightHandDemon + name: "right demon hand" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_hand" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_hand" + - type: BodyPart + partType: Hand + symmetry: Right + +- type: entity + id: LeftLegDemon + name: "left demon leg" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_leg" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_leg" + - type: BodyPart + partType: Leg + symmetry: Left + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: RightLegDemon + name: "right demon leg" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_leg" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_leg" + - type: BodyPart + partType: Leg + symmetry: Right + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: LeftFootDemon + name: "left demon foot" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_foot" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_foot" + - type: BodyPart + partType: Foot + symmetry: Left + +- type: entity + id: RightFootDemon + name: "right demon foot" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_foot" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_foot" + - type: BodyPart + partType: Foot + symmetry: Right diff --git a/Resources/Prototypes/ADT/Body/Parts/fill.txt b/Resources/Prototypes/ADT/Body/Parts/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Body/Parts/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Body/Prototypes/Drask.yml b/Resources/Prototypes/ADT/Body/Prototypes/Drask.yml new file mode 100644 index 0000000000..cdf4b04568 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Prototypes/Drask.yml @@ -0,0 +1,49 @@ +- type: body + name: "drask" + id: Drask + root: torso + slots: + head: + part: HeadDrask + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganDraskEyes + heart: OrganDraskHeart + torso: + part: TorsoDrask + organs: + lungs: OrganDraskLungs + stomach: OrganDraskInnards + liver: OrganHumanLiver + kidneys: OrganDraskKidneys + connections: + - left arm + - right arm + - left leg + - right leg + right arm: + part: RightArmDrask + connections: + - right hand + left arm: + part: LeftArmDrask + connections: + - left hand + right hand: + part: RightHandDrask + left hand: + part: LeftHandDrask + right leg: + part: RightLegDrask + connections: + - right foot + left leg: + part: LeftLegDrask + connections: + - left foot + right foot: + part: RightFootDrask + left foot: + part: LeftFootDrask diff --git a/Resources/Prototypes/ADT/Body/Prototypes/demon.yml b/Resources/Prototypes/ADT/Body/Prototypes/demon.yml new file mode 100644 index 0000000000..ab2d8e2bdb --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Prototypes/demon.yml @@ -0,0 +1,49 @@ +- type: body + name: "demon" + id: Demon + root: torso + slots: + head: + part: HeadDemon + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganHumanEyes + torso: + part: TorsoDemon + organs: + heart: OrganDemonHeart + lungs: OrganHumanLungs + stomach: OrganDemonStomach + liver: OrganAnimalLiver + kidneys: OrganHumanKidneys + connections: + - left arm + - right arm + - left leg + - right leg + right arm: + part: RightArmDemon + connections: + - right hand + left arm: + part: LeftArmDemon + connections: + - left hand + right hand: + part: RightHandDemon + left hand: + part: LeftHandDemon + right leg: + part: RightLegDemon + connections: + - right foot + left leg: + part: LeftLegDemon + connections: + - left foot + right foot: + part: RightFootDemon + left foot: + part: LeftFootDemon diff --git a/Resources/Prototypes/Chemistry/metabolizer_types.yml b/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml similarity index 54% rename from Resources/Prototypes/Chemistry/metabolizer_types.yml rename to Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml index 3f7bf05b35..a492dde8d0 100644 --- a/Resources/Prototypes/Chemistry/metabolizer_types.yml +++ b/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml @@ -1,4 +1,4 @@ -# If your species wants to metabolize stuff differently, +# If your species wants to metabolize stuff differently, # you'll likely have to tag its metabolizers with something other than Human. - type: metabolizerType @@ -44,3 +44,39 @@ - type: metabolizerType id: Arachnid name: metabolizer-type-arachnid + +- type: metabolizerType + id: Novakid + name: metabolizer-type-novakid + +- type: metabolizerType + id: Demon + name: metabolizer-type-demon + +- type: metabolizerType + id: Shark + name: metabolizer-type-shark + +- type: metabolizerType + id: Vulpkanin + name: metabolizer-type-vulpkanin + +- type: metabolizerType + id: Tajaran + name: metabolizer-type-tajaran + +- type: metabolizerType + id: Reptilian + name: metabolizer-type-reptilian + +- type: metabolizerType + id: Ursus + name: metabolizer-type-ursus + +- type: metabolizerType + id: Drask + name: metabolizer-type-drask + +- type: metabolizerType + id: Felinid + name: metabolizer-type-felinid diff --git a/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml b/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml new file mode 100644 index 0000000000..17be8eafaa --- /dev/null +++ b/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml @@ -0,0 +1,190 @@ +- type: damageModifierSet + id: Fur # 1) - ебучий годспид, балансим уроном. 2) - шерсть должна гореть + coefficients: + Blunt: 1 + Piercing: 1.2 + Slash: 1.2 + Cold: 0.6 + Heat: 1.5 + Poison: 1 + +- type: damageModifierSet + id: Kobalt # мне даже жаль кобальдов, но жизнь такова какова она какова и больше не какова + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 1.0 + Cold: 1.5 + Heat: 0.9 + Poison: 1 + Bloodloss: 0.3 + +- type: damageModifierSet + id: Demon # они вообще то мутанты, но кого ебёт так? + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 1.0 + Cold: 0.8 + Heat: 0.8 + Poison: 0.8 + Cellular: 1.5 + +- type: damageModifierSet + id: Shadowkin # пупупу + coefficients: + Blunt: 1.2 + Piercing: 1.2 + Slash: 1.2 + Cold: 0.8 + Heat: 0.8 + Poison: 1 + Cellular: 1 + +- type: damageModifierSet + id: Drask # саморезы + coefficients: + Heat: 1.5 + Asphyxiation: 2.0 + +- type: damageModifierSet + id: Felinid # мяу + coefficients: + Blunt: 1.0 + Piercing: 1.15 + Slash: 1.30 + Cold: 1.5 + Heat: 2.0 + Poison: 1.1 + +- type: damageModifierSet + id: CyborgMetallic + coefficients: + Blunt: 0.8 + Slash: 0.7 + Piercing: 0.8 + Heat: 1.2 + Shock: 1.5 + flatReductions: + Blunt: 5 + Slash: 5 + Piercing: 5 + Heat: 5 + + +- type: damageModifierSet + id: CyborgMetallicStrong + coefficients: + Blunt: 0.6 + Slash: 0.6 + Piercing: 0.6 + Heat: 0.8 + Shock: 1.1 + flatReductions: + Blunt: 9 + Slash: 9 + Piercing: 9 + Heat: 9 + +- type: damageModifierSet + id: Ursus # мишк + coefficients: + Blunt: 1.0 + +- type: damageModifierSet + id: AshWalker # Груба кожа = умно ящериц + coefficients: + Blunt: 0.8 + +- type: damageModifierSet + id: ADTAntagDroneIPCDamageModSet + coefficients: + Blunt: 0.75 + Slash: 0.75 + Piercing: 0.55 + Heat: 0.80 + #Explosive: 0.25 + Structural: 0 + # zap + Shock: 0.5 + Cold: 0 + Caustic: 0.3 + +- type: damageModifierSet + id: ADTSecurityCybDamagModSet + coefficients: + Blunt: 0.5 + Slash: 0.4 + Piercing: 0.45 + # fire and lasers burn it good + Heat: 1.0 + # zap + Shock: 1.2 + Cold: 0 + Caustic: 0.4 + +- type: damageModifierSet + id: distorted + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 1.0 + Cold: 0.5 + Heat: 0.5 + Poison: 0.5 + Bloodloss: 1 + +- type: damageModifierSet + id: echo + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 0.4 + Cold: 0.6 + Heat: 0.6 + Poison: 1.0 + Bloodloss: 1 + +- type: damageModifierSet + id: grant + coefficients: + Blunt: 0.5 + Piercing: 0.7 + Slash: 0.5 + Cold: 0.7 + Heat: 0.7 + Poison: 0.7 + Bloodloss: 1 + +- type: damageModifierSet + id: hunter + coefficients: + Blunt: 0.45 + Piercing: 0.6 + Slash: 0.45 + Cold: 0.6 + Heat: 0.45 + Poison: 0.6 + Bloodloss: 1 + +- type: damageModifierSet + id: soldier + coefficients: + Blunt: 0.8 + Piercing: 0.8 + Slash: 0.8 + Cold: 0.8 + Heat: 0.8 + Poison: 0.8 + Bloodloss: 1 + +- type: damageModifierSet + id: wrecker + coefficients: + Blunt: 0.4 + Piercing: 0.55 + Slash: 0.4 + Cold: 0.55 + Heat: 0.65 + Poison: 0.55 + Bloodloss: 1 diff --git a/Resources/Prototypes/ADT/Datasets/Names/name_drask.yml b/Resources/Prototypes/ADT/Datasets/Names/name_drask.yml new file mode 100644 index 0000000000..e277f4313c --- /dev/null +++ b/Resources/Prototypes/ADT/Datasets/Names/name_drask.yml @@ -0,0 +1,20 @@ +- type: dataset + id: Draskfrist + values: + - Овв + - Оумн + - Мноо + - Румум + - Ваар + - Дромнн + - Руум + - Гоом + - Фмонг + - Оорм + - Гаар + - Хоорб + - Саар + - Ссооумн + - Гнии + - Вииск + - Вррм diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/Drask.yml b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/Drask.yml new file mode 100644 index 0000000000..242111d6d6 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/Drask.yml @@ -0,0 +1,43 @@ +- type: marking + id: DraskArmRight + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [DraskSpecies] + sponsorOnly: false + coloring: + default: + type: + !type:CategoryColoring + category: Hair + fallbackTypes: + - !type:SkinColoring + layers: + r_arm: + type: + !type:SimpleColoring + color: "#171717" + sprites: + - sprite: ADT/Mobs/Drask/custom.rsi + state: r_arm + +- type: marking + id: DraskArmLeft + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [DraskSpecies] + sponsorOnly: false + coloring: + default: + type: + !type:CategoryColoring + category: Hair + fallbackTypes: + - !type:SkinColoring + layers: + l_arm: + type: + !type:SimpleColoring + color: "#171717" + sprites: + - sprite: ADT/Mobs/Drask/custom.rsi + state: l_arm diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/demon.yml b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/demon.yml new file mode 100644 index 0000000000..bb197ca124 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/demon.yml @@ -0,0 +1,133 @@ +- type: marking + id: DemomTail1 + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: demon_tail + +- type: marking + id: DemomTailLong + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: long + +- type: marking + id: DemomTailUp + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: up + +- type: marking + id: DemonCowEars + bodyPart: HeadSide + markingCategory: HeadSide + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: cow_ears + +- type: marking + id: DemonEars + bodyPart: HeadSide + markingCategory: HeadSide + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: demon_ears + +- type: marking + id: DemonCowHorns + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: cow_horns + +- type: marking + id: DemonHornsDeer + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: deer_antlers_horns + +- type: marking + id: DemonHornsSmall + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: small_horns + +- type: marking + id: DemonChestCowSpots + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: cow_spots + +- type: marking + id: DemonChestGuard + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: guards_stripes + +- type: marking + id: DemonChestLinesEmperos + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: lines_emperos + +- type: marking + id: DemonChestQueenLines + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: queen_lines + +- type: marking + id: DemonChestTreeLines + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: tree_lines + +- type: marking + id: DemonChestTrinitySpots + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: trinity_spots + +- type: marking + id: DemonGoatee + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: goatee diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/fill.txt b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml b/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml new file mode 100644 index 0000000000..04c38254a1 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml @@ -0,0 +1,50 @@ +- type: entity + save: false + name: Urisst' Mzhand Demon + parent: BaseMobDemon + id: MobDemon + components: + - type: CombatMode + - type: InteractionPopup + successChance: 1 + interactSuccessString: hugging-success-generic + interactSuccessSound: /Audio/Effects/thudswoosh.ogg + messagePerceivedByOthers: hugging-success-generic-others + - type: MindContainer + showExamineInfo: true + - type: Input + context: "human" + - type: MobMover + - type: InputMover + - type: Alerts + - type: Eye + - type: CameraRecoil + - type: Examiner + - type: CanHostGuardian + + # ОТКОММЕНТИТЬ ПРИ ПЕРЕНОСЕ ЯЗЫКОВ И РАЗМЕРОВ + # - type: LanguageSpeaker + # speaks: + # - GalacticCommon + # - Arkane + # understands: + # - GalacticCommon + # - Arkane + + - type: NpcFactionMember + factions: + - NanoTrasen + - type: Respirator + damage: + types: + Asphyxiation: 1.0 + damageRecovery: + types: + Asphyxiation: -1.0 + # - type: SizeAttributeWhitelist # Frontier + # tall: true + # tallscale: 1.1 + # short: true + # shortscale: 0.9 + +#Weh diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Player/fill.txt b/Resources/Prototypes/ADT/Entities/Mobs/Player/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Entities/Mobs/Player/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/Drask.yml b/Resources/Prototypes/ADT/Entities/Mobs/Species/Drask.yml new file mode 100644 index 0000000000..72556b70a2 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Species/Drask.yml @@ -0,0 +1,81 @@ +- type: entity + parent: BaseMobSpeciesOrganic + id: BaseMobDrask + name: Urist McDrask + abstract: true + components: + - type: HumanoidAppearance + species: DraskSpecies + - type: Hunger + starvationDamage: + types: + Cold: 0.05 + Bloodloss: 0.05 + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: full + - type: Thirst + - type: Perishable + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatHuman + amount: 5 + - type: Body + prototype: Drask + requiredLegs: 2 + - type: MeleeWeapon + soundHit: + path: /Audio/Weapons/pierce.ogg + angle: 30 + animation: WeaponArcPunch + damage: + types: + Blunt: 10 + - type: Bloodstream + bloodReagent: Cryoxadone + - type: Temperature + heatDamageThreshold: 330 + coldDamageThreshold: 0 + currentTemperature: 273.15 + coldDamage: #per second, scales with temperature & other constants + types: + Cold : 0 + specificHeat: 42 + heatDamage: #per second, scales with temperature & other constants + types: + Heat : 0.4 + - type: ThermalRegulator + normalBodyTemperature: 273.15 + - type: DamageVisuals + damageOverlayGroups: + Brute: + sprite: Mobs/Effects/brute_damage.rsi + color: "#0091ff" + Burn: + sprite: Mobs/Effects/burn_damage.rsi + - type: Speech + speechSounds: Drask + - type: Vocal + sounds: + Male: MaleDrask + Female: FemaleDrask + Unsexed: MaleDrask + - type: Damageable + damageContainer: Biological + damageModifierSet: Drask + +- type: entity + save: false + name: Urist McDrask + parent: MobHumanDummy + id: MobDraskDummy + noSpawn: true + components: + - type: HumanoidAppearance + species: DraskSpecies + + + + + diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/demon.yml b/Resources/Prototypes/ADT/Entities/Mobs/Species/demon.yml new file mode 100644 index 0000000000..6f99d51300 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Species/demon.yml @@ -0,0 +1,66 @@ +- type: entity + save: false + name: Urisst' Mzhand Demon + parent: BaseMobSpeciesOrganic + id: BaseMobDemon + abstract: true + components: + - type: HumanoidAppearance + species: DemonSpecies + - type: Hunger + - type: Thirst + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: full_m + - type: Sprite + netsync: false + noRot: true + drawdepth: Mobs + - type: Body + prototype: Demon + requiredLegs: 2 + - type: Speech + speechSounds: Lizard + - type: Vocal + sounds: + Male: MaleHuman + Female: FemaleHuman + Unsexed: FemaleHuman + - type: Damageable + damageContainer: Biological + damageModifierSet: Demon + - type: MeleeWeapon + # hidden: true + soundHit: + path: /Audio/Weapons/pierce.ogg + angle: 30 + animation: WeaponArcPunch + damage: + types: + Piercing: 5 + - type: Temperature + heatDamageThreshold: 400 + coldDamageThreshold: 193 #starting temperature damage treshold + currentTemperature: 310.15 + specificHeat: 46 + coldDamage: + types: + Cold : 0.1 #per second, scales with temperature & other constants + heatDamage: + types: + Heat : 0.3 #per second, scales with temperature & other constants + - type: MovementSpeedModifier + baseWalkSpeed : 2.5 + baseSprintSpeed : 4.5 + - type: Perishable + +- type: entity + save: false + name: Urist McHands + parent: MobHumanDummy + id: MobDemonDummy + noSpawn: true + description: A dummy reptilian meant to be used in character setup. + components: + - type: HumanoidAppearance + species: DemonSpecies diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/fill.txt b/Resources/Prototypes/ADT/Entities/Mobs/Species/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Entities/Mobs/Species/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Entities/Mobs/player/Drask.yml b/Resources/Prototypes/ADT/Entities/Mobs/player/Drask.yml new file mode 100644 index 0000000000..e962cd24e1 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/player/Drask.yml @@ -0,0 +1,46 @@ +- type: entity + save: false + name: "Urisst' McDrask" + parent: BaseMobDrask + id: MobDrask + components: + - type: CombatMode + - type: InteractionPopup + successChance: 1 + interactSuccessString: hugging-success-generic + interactSuccessSound: /Audio/Effects/thudswoosh.ogg + messagePerceivedByOthers: hugging-success-generic-others + - type: MindContainer + showExamineInfo: true + - type: Input + context: "human" + - type: MobMover + - type: InputMover + - type: Alerts + - type: Eye + - type: CameraRecoil + - type: Examiner + - type: CanHostGuardian + - type: NpcFactionMember + factions: + - NanoTrasen + - type: Respirator + damage: + types: + Asphyxiation: 1.0 + damageRecovery: + types: + Asphyxiation: -1.0 +# ОТКОММЕНТИТЬ ПРИ ПЕРЕНОСЕ ЯЗЫКОВ И РАЗМЕРОВ + # - type: LanguageSpeaker + # speaks: + # - GalacticCommon + # - Drask + # understands: + # - GalacticCommon + # - Drask + # - type: SizeAttributeWhitelist # Frontier + # tall: true + # tallscale: 1.15 + # short: true + # shortscale: 1 diff --git a/Resources/Prototypes/ADT/Entities/Objects/Device/translators.yml b/Resources/Prototypes/ADT/Entities/Objects/Device/translators.yml new file mode 100644 index 0000000000..97280e5348 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Objects/Device/translators.yml @@ -0,0 +1,386 @@ +- type: entity + id: TranslatorUnpowered + parent: [ BaseItem ] + name: Translator + description: "Translates speech." + components: + - type: Item + sprite: _NF/Objects/Devices/translator.rsi + inhandVisuals: + left: + - state: inhand-left + right: + - state: inhand-right + - type: Sprite + sprite: _NF/Objects/Devices/translator.rsi + state: icon + layers: + - state: icon + - state: translator + shader: unshaded + visible: false + map: [ "enum.ToggleVisuals.Layer", "enum.PowerDeviceVisualLayers.Powered" ] + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: { visible: true } + False: { visible: false } + - type: HandheldTranslator + enabled: false + - type: ToggleableLightVisuals + spriteLayer: translator + inhandVisuals: + left: + - state: inhand-left-translator + shader: unshaded + right: + - state: inhand-right-translator + shader: unshaded + +- type: entity + id: Translator + parent: [ TranslatorUnpowered, PowerCellSlotMediumItem ] + suffix: Powered + components: + - type: PowerCellDraw + drawRate: 1 + +- type: entity + id: TranslatorEmtpy + parent: [ Translator ] + suffix: Empty + components: + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + +- type: entity + id: VulpTranslator + parent: [ Translator ] + name: Vulpkanin translator + description: "Used only by Vulpkanin to understand and speak with Galatic Common speakers." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + understood: + - GalacticCommon + requires: + - Canilunzt + requires-all: false + - type: PowerCellDraw + drawRate: 0.1 + - type: StaticPrice + price: 35 + +- type: entity + id: CanilunztTranslator + parent: [ TranslatorEmtpy ] + name: Canilunzt translator + description: "Translates speech between Canilunzt and Galactic Common. Commonly used by Vulpkanin to communicate with galactic common speakers" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Canilunzt + understood: + - GalacticCommon + - Canilunzt + requires: + - GalacticCommon + - Canilunzt + requires-all: false + +- type: entity + id: BubblishTranslator + parent: [ TranslatorEmtpy ] + name: Bubblish translator + description: "Translates speech between Bubblish and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Bubblish + understood: + - GalacticCommon + - Bubblish + requires: + - GalacticCommon + - Bubblish + requires-all: false + +- type: entity + id: NekomimeticTranslator + parent: [ TranslatorEmtpy ] + name: Nekomimetic translator + description: "Translates speech between Nekomimetic and Galactic Common. Why would you want that?" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Nekomimetic + understood: + - GalacticCommon + - Nekomimetic + requires: + - GalacticCommon + - Nekomimetic + requires-all: false + +- type: entity + id: DraconicTranslator + parent: [ TranslatorEmtpy ] + name: Draconic translator + description: "Translates speech between Draconic and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Draconic + understood: + - GalacticCommon + - Draconic + requires: + - GalacticCommon + - Draconic + requires-all: false + +- type: entity + id: SolCommonTranslator + parent: [ TranslatorEmtpy ] + name: Sol Common translator + description: "Translates speech between Sol Common and Galactic Common. Like a true Earthman!" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - SolCommon + understood: + - GalacticCommon + - SolCommon + requires: + - GalacticCommon + - SolCommon + requires-all: false + +- type: entity + id: RootSpeakTranslator + parent: [ TranslatorEmtpy ] + name: RootSpeak translator + description: "Translates speech between RootSpeak and Galactic Common. Like a true plant?" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - RootSpeak + understood: + - GalacticCommon + - RootSpeak + requires: + - GalacticCommon + - RootSpeak + requires-all: false + +- type: entity + id: MofficTranslator + parent: [ TranslatorEmtpy ] + name: Moffic translator + description: "Translates speech between Moffic and Galactic Common. Like a true moth... or bug?" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Moffic + understood: + - GalacticCommon + - Moffic + requires: + - GalacticCommon + - Moffic + requires-all: false + +- type: entity + id: XenoTranslator + parent: [ TranslatorEmtpy ] + name: Xeno translator + description: "Translates speech between Xeno and Galactic Common. Not sure if that will help." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Xeno + understood: + - GalacticCommon + - Xeno + requires: + - GalacticCommon + +- type: entity + id: AnimalTranslator + parent: [ TranslatorEmtpy ] + name: Animal translator + description: "Translates all the cutes nosies that animals make into a more understandable form!" + components: + - type: HandheldTranslator + understood: + - Cat + - Dog + - Mothroach + - Monkey + - Bee + - Mouse + - Chicken + - Duck + - Cow + - Sheep + - Kangaroo + - Pig + requires: + - GalacticCommon + requires-all: false + +- type: entity + id: DraskTranslator + parent: [ TranslatorEmtpy ] + name: Orluum translator + description: "Translates speech between Orluum and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Drask + understood: + - GalacticCommon + - Drask + requires: + - GalacticCommon + - Drask + requires-all: false + + +- type: entity + id: ShadowkinTranslator + parent: [ TranslatorEmtpy ] + name: Shadowkin translator + description: "Translates speech between Shadowkin lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Shadowkin + understood: + - GalacticCommon + - Shadowkin + requires: + - GalacticCommon + - Shadowkin + requires-all: false + +- type: entity + id: ArkaneTranslator + parent: [ TranslatorEmtpy ] + name: Arkane translator + description: "Translates speech between Arkane lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Arkane + understood: + - GalacticCommon + - Arkane + requires: + - GalacticCommon + - Arkane + requires-all: false + +- type: entity + id: NianTranslator + parent: [ TranslatorEmtpy ] + name: Nian translator + description: "Translates speech between Nian lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Nian + understood: + - GalacticCommon + - Nian + requires: + - GalacticCommon + - Nian + requires-all: false + +- type: entity + id: FireTranslator + parent: [ TranslatorEmtpy ] + name: Fire translator + description: "Translates speech between Shadowkin lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Fire + understood: + - GalacticCommon + - Fire + requires: + - GalacticCommon + - Fire + requires-all: false + +- type: entity + id: SikTajTranslator + parent: [ TranslatorEmtpy ] + name: SikTaj translator + description: "Translates speech between SikTaj and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - SikTaj + understood: + - GalacticCommon + - SikTaj + requires: + - GalacticCommon + - SikTaj + requires-all: false + +- type: entity + id: CintaTajTranslator + parent: [ TranslatorEmtpy ] + name: CintaTajTaj translator + description: "Translates speech between CintaTaj and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - CintaTaj + understood: + - GalacticCommon + - CintaTaj + requires: + - GalacticCommon + - CintaTaj + requires-all: false diff --git a/Resources/Prototypes/ADT/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/ADT/Entities/Objects/Misc/implanters.yml new file mode 100644 index 0000000000..3ebd7c9036 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Objects/Misc/implanters.yml @@ -0,0 +1,287 @@ +- type: entity + id: BaseTranslatorImplanter + parent: [ BaseItem ] + name: Basic translator implant + description: "Translates speech." + abstract: true + components: + - type: Sprite + sprite: Objects/Specific/Medical/implanter.rsi + state: implanter0 + layers: + - state: implanter1 + map: [ "implantFull" ] + visible: true + - state: implanter0 + map: [ "implantBroken" ] + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ImplanterVisuals.Full: + implantFull: + True: {visible: true} + False: {visible: false} + implantBroken: + True: {visible: false} + False: {visible: true} + +- type: entity + id: BasicGalaticCommonTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Basic Galatic Common translator implant + description: "An implant giving the ability to understand Galatic Common." + components: + - type: TranslatorImplanter + understood: + - GalacticCommon + +- type: entity + id: AdvancedGalaticCommonTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Advanced Galatic Common translator implant + description: "An implant giving the ability to understand and speak Galatic Common." + components: + - type: TranslatorImplanter + spoken: + - GalacticCommon + understood: + - GalacticCommon + +- type: entity + id: BubblishTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Bubblish translator implant + description: "An implant giving the ability to understand and speak Bubblish." + components: + - type: TranslatorImplanter + spoken: + - Bubblish + understood: + - Bubblish + +- type: entity + id: NekomimeticTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Nekomimetic translator implant + description: "An implant giving the ability to understand and speak Nekomimetic, Nya~!" + components: + - type: TranslatorImplanter + spoken: + - Nekomimetic + understood: + - Nekomimetic + +- type: entity + id: DraconicTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Draconic translator implant + description: "An implant giving the ability to understand and speak Draconic." + components: + - type: TranslatorImplanter + spoken: + - Draconic + understood: + - Draconic + +- type: entity + id: CanilunztTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Canilunzt translator implant + description: "An implant giving the ability to understand and speak Canilunzt, Yeeps!" + components: + - type: TranslatorImplanter + spoken: + - Canilunzt + understood: + - Canilunzt + +- type: entity + id: SolCommonTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: SolCommon translator implant + description: "An implant giving the ability to understand and speak SolCommon, raaagh!" + components: + - type: TranslatorImplanter + spoken: + - SolCommon + understood: + - SolCommon + +- type: entity + id: RootSpeakTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: RootSpeak translator implant + description: "An implant giving the ability to understand and speak RootSpeak." + components: + - type: TranslatorImplanter + understood: + - RootSpeak + +- type: entity + id: MofficTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Moffic translator implant + description: "An implant giving the ability to understand and speak Moffic." + components: + - type: TranslatorImplanter + spoken: + - Moffic + understood: + - Moffic + +- type: entity + id: CodeSpeakImplanter + parent: [ BaseTranslatorImplanter ] + name: CodeSpeak Implanter + description: "\"CodeSpeak(tm) - Secure your communication with metaphors so elaborate, they seem randomly generated!\"" + components: + - type: TranslatorImplanter + spoken: + - CodeSpeak + understood: + - CodeSpeak + - type: StaticPrice + price: 150 + +- type: entity + id: SikTajTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: SikTaj translator implant + description: "An implant giving the ability to understand and speak SikTaj." + components: + - type: TranslatorImplanter + spoken: + - SikTaj + understood: + - SikTaj + +- type: entity + id: NianTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Nian translator implant + description: "An implant giving the ability to understand and speak Nian." + components: + - type: TranslatorImplanter + spoken: + - Nian + understood: + - Nian + +- type: entity + id: FireTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Nian translator implant + description: "An implant giving the ability to understand and speak Nian." + components: + - type: TranslatorImplanter + understood: + - Fire + +- type: entity + id: DraskTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Orluum translator implant + description: "An implant giving the ability to understand and speak Orluum." + components: + - type: TranslatorImplanter + spoken: + - Drask + understood: + - Drask + +- type: entity + id: UrsTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Urs translator implant + description: "An implant giving the ability to understand and speak Ursus language." + components: + - type: TranslatorImplanter + spoken: + - Urs + understood: + - Urs + +- type: entity + id: ArkaneTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Arkane translator implant + description: "An implant giving the ability to understand and speak Arcane language." + components: + - type: TranslatorImplanter + spoken: + - Arkane + understood: + - Arkane + +- type: entity + id: ShadowkinTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Shadowkin translator implant + description: "An implant giving the ability to understand and speak Shadowkin language." + components: + - type: TranslatorImplanter + spoken: + - Shadowkin + understood: + - Shadowkin + +- type: entity + id: BorgTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Borg translator implant + description: "An implant giving the ability to understand and speak Binary." + components: + - type: TranslatorImplanter + spoken: + - BorgTalk + understood: + - BorgTalk + +- type: entity + id: CintaTajTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: CintaTaj translator implant + description: "An implant giving the ability to understand and speak CintaTaj." + components: + - type: TranslatorImplanter + spoken: + - CintaTaj + understood: + - CintaTaj + + +- type: entity + id: SyndUniversalTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: universal translator implant + description: "An implant giving the ability to understand any racial language." + components: + - type: TranslatorImplanter + understood: + - RobotTalk + - Shadowkin + - Arkane + - Urs + - Drask + - Fire + - Nian + - SikTaj + - Moffic + - RootSpeak + - SolCommon + - Canilunzt + - Draconic + - Bubblish + - Nekomimetic + +- type: entity + id: DevTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Dev translator implant + description: "e" + components: + - type: TranslatorImplanter + spoken: + - Dev + understood: + - Dev diff --git a/Resources/Prototypes/ADT/Entities/Objects/Weapons/Melee/telescopic_baton.yml b/Resources/Prototypes/ADT/Entities/Objects/Weapons/Melee/telescopic_baton.yml new file mode 100644 index 0000000000..2ea7b069e2 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Objects/Weapons/Melee/telescopic_baton.yml @@ -0,0 +1,135 @@ +- type: entity + name: TelescopicBaton + parent: BaseItem + id: ADTtelescopicBaton + description: Big, dangerous telescopic baton. Can be stored in pockets when turned off. + components: + - type: Sprite + sprite: ADT/Objects/Weapons/Melee/telescopic_baton.rsi + layers: + - state: telescope_off + map: [ "enum.ToggleVisuals.Layer" ] + - type: SwitchableWeapon + openSound: "/Audio/ADT/Entities/Objects/Weapons/Melee/open_telescopichka.ogg" + closeSound: "/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg" + #bonkSound: "/Audio/ADT/bonk_dubinka.ogg" + damageOpen: + types: + Blunt: 2.4 + damageFolded: + types: + Blunt: 0 + staminaDamageFolded: 0 + staminaDamageOpen: 35 + sizeOpened: Normal + sizeClosed: Small + - type: StaminaDamageOnHit + damage: 0 + - type: MeleeWeapon + damage: + types: + Blunt: 2.4 + - type: Item + size: Small + sprite: ADT/Objects/Weapons/Melee/telescopic_baton.rsi + - type: UseDelay + delay: 1.0 + - type: DisarmMalus + malus: 0 + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: {state: telescope_on} + False: {state: telescope_off} + +- type: entity + name: TelescopicBatonBob + parent: ADTtelescopicBaton + id: ADTtelescopicBatonBob + description: Big, dangerous telescopic baton. Can be stored in pockets when turned off. + components: + - type: Sprite + sprite: ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi + layers: + - state: telescope_off + map: [ "enum.ToggleVisuals.Layer" ] + - type: SwitchableWeapon + openSound: "/Audio/ADT/Entities/Objects/Weapons/Melee/open_telescopichka.ogg" + closeSound: "/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg" + #bonkSound: "/Audio/ADT/bonk_dubinka.ogg" + damageOpen: + types: + Blunt: 2.4 + damageFolded: + types: + Blunt: 0 + staminaDamageFolded: 0 + staminaDamageOpen: 35 + - type: StaminaDamageOnHit + damage: 0 + - type: MeleeWeapon + damage: + types: + Blunt: 2.4 + - type: Item + size: Small + sprite: ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi + - type: UseDelay + delay: 1.0 + - type: DisarmMalus + malus: 0 + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: {state: telescope_on} + False: {state: telescope_off} + + + +- type: entity + name: TelescopicBatonKon + parent: ADTtelescopicBaton + id: ADTtelescopicBatonKon + description: Big, dangerous telescopic baton. Can be stored in pockets when turned off. + components: + - type: Sprite + sprite: ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi + layers: + - state: telescope_off + map: [ "enum.ToggleVisuals.Layer" ] + - type: SwitchableWeapon + openSound: "/Audio/ADT/Entities/Objects/Weapons/Melee/open_telescopichka.ogg" + closeSound: "/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg" + #bonkSound: "/Audio/ADT/bonk_dubinka.ogg" + damageOpen: + types: + Blunt: 2.4 + damageFolded: + types: + Blunt: 0 + staminaDamageFolded: 0 + staminaDamageOpen: 35 + - type: StaminaDamageOnHit + damage: 0 + - type: MeleeWeapon + damage: + types: + Blunt: 2.4 + - type: Item + size: Small + sprite: ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi + - type: UseDelay + delay: 1.0 + - type: DisarmMalus + malus: 0 + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: {state: telescope_on} + False: {state: telescope_off} diff --git a/Resources/Prototypes/ADT/Languages/languages.yml b/Resources/Prototypes/ADT/Languages/languages.yml new file mode 100644 index 0000000000..10dde690b5 --- /dev/null +++ b/Resources/Prototypes/ADT/Languages/languages.yml @@ -0,0 +1,949 @@ +# The universal language, assumed if the entity has a UniversalLanguageSpeakerComponent. +# Do not use otherwise. Try to use the respective component instead of this language. +- type: language + id: Universal + obfuscateSyllables: false + replacement: + - "*incomprehensible*" + +# The common galactic tongue. +- type: language + id: GalacticCommon + obfuscateSyllables: true + replacement: + - Бла + - Бла + - Бла + - динг-донг + - динг + - донг + - жиббер-жаббер + - жуббр + - бле + - зиппти + - зуп + - виббл + - воббл + - виггл + - яда + - мех + - нех + - нах + - вах + +# Spoken by slimes. +- type: language + id: Bubblish + obfuscateSyllables: true + replacement: + - блоб + - плоп + - поп + - боп + - буп + - блюп + - бульп + - блеб + +# Spoken by moths. +- type: language + id: Moffic + obfuscateSyllables: true + replacement: + - år + - i + - går + - sek + - mo + - ff + - ok + - gj + - ø + - gå + - la + - le + - lit + - ygg + - van + - dår + - næ + - møt + - idd + - hvo + - ja + - på + - han + - så + - ån + - det + - att + - nå + - gö + - bra + - int + - tyc + - om + - när + - två + - må + - dag + - sjä + - vii + - vuo + - eil + - tun + - käyt + - teh + - vä + - hei + - huo + - suo + - ää + - ten + - ja + - heu + - stu + - uhr + - kön + - we + - hön + + # Spoken by dionas. +- type: language + id: RootSpeak + obfuscateSyllables: true + replacement: + - хс + - зт + - кр + - ст + - ш + - шш + +# Syndicate operatives can use a series of codewords to convey complex information. +- type: language + id: CodeSpeak + obfuscateSyllables: true + replacement: + - Белый русский + - Представитель станции + - Шериф + - Депутат + - Хранилище + - Фронтир + - Станция + - Безопасность + - Кофе + - Кола + - Вода + - Инженерный + - Капитан + - Вызываю друга + - Атмос + - Робототехника + - Медицинский + - ИИ + - Человек + - Вульпканин + - Унатх + - Ниан + - Чай + - Стул + - Кресло + - Корабль + - Шаттл + - Оружие + - Пушки + - Лазер + - Карп + - Космический Карп + - Ксено + - Ксеноморф + - Биоугроза + - Деньги + - Космос + - Опасность + - Обезьяна + - Пун-пун + - Внутри + - Бежит + - Убивает + - Убить + - Спасти + - Жизнь + - Дракон + - Ниндзя + - Секрет + +# A mess of broken Japanese, spoken by Felinds and Oni +- type: language + id: Nekomimetic + obfuscateSyllables: true + replacement: + - неко + - нян + - мими + - ми + - мофу + - фува + - кьяя + - кавай + - пока + - муня + - пуни + - мунью + - уфуфу + - ича + - доки + - кьюн + - кусу + - ня + - няя + - десу + - кис + - ама + - чуу + - бака + - хево + - буп + - гато + - кит + - сюн + - йори + - соу + - бака + - чан + - сан + - кун + - махо + - йатта + - сукки + - усаги + - домо + - ори + - ува + - заазаа + - шику + - пуру + - ира + - хето + - етто + +# Spoken by the Lizard race. +- type: language + id: Draconic + obfuscateSyllables: true + replacement: + - za + - az + - ze + - ez + - zi + - iz + - zo + - oz + - zu + - uz + - zs + - sz + - ha + - ah + - he + - eh + - hi + - ih + - ho + - oh + - hu + - uh + - hs + - sh + - la + - al + - le + - el + - li + - il + - lo + - ol + - lu + - ul + - ls + - sl + - ka + - ak + - ke + - ek + - ki + - ik + - ko + - ok + - ku + - uk + - ks + - sk + - sa + - as + - se + - es + - si + - is + - so + - os + - su + - us + - ss + - ss + - ra + - ar + - re + - er + - ri + - ir + - ro + - or + - ru + - ur + - rs + - sr + - a + - a + - e + - e + - i + - i + - o + - o + - u + - u + - s + - s + +# Spoken by the Vulpkanin race. +- type: language + id: Canilunzt + obfuscateSyllables: true + replacement: + - rur + - ya + - cen + - rawr + - bar + - kuk + - tek + - qat + - uk + - wu + - vuh + - tah + - tch + - schz + - auch + - ist + - ein + - entch + - zwichs + - tut + - mir + - wo + - bis + - es + - vor + - nic + - gro + - lll + - enem + - zandt + - tzch + - noch + - hel + - ischt + - far + - wa + - baram + - iereng + - tech + - lach + - sam + - mak + - lich + - gen + - or + - ag + - eck + - gec + - stag + - onn + - bin + - ket + - jarl + - vulf + - einech + - cresthz + - azunein + - ghzth + +# Spoken by the Tajaran race. +- type: language + id: SikTaj + obfuscateSyllables: true + replacement: + - rae + - ye + - cen + - prr + - mer + - kuk + - tek + - qar + - ud + - wu + - wuh + - "taj'" + - tch + - ser + - "'aerch" + - it + - ei + - endr + - zeihs + - tet + - mir + - wo + - bis + - es + - voj + - jic + - fro + - rrr + - ener + - zajet + - th + - nort + - hel + - ist + - far + - wa + - bara + - ierg + - tech + - lach + - sam + - mak + - "'lirch" + - get + - or + - "jag'" + - eck + - gec + - stag + - "'onn" + - bin + - ket + - "jart'" + - vul + - einech + - cres + - "'eirr" + - ghh + +# Spoken by the Nian race. +- type: language + id: Nian + obfuscateSyllables: true + replacement: + - жз + - эзз + - ззе + - ржез + - зшусж + - жсса + - жж + - жжс + - еж + - шшз + - ззуш + - жашшз + - ззис + - ссж + - ужжс + - сз + - жш + - эшзз + - жесш + - шжш + - жуж + - ж + - ш + - з + - ззз + - зсе + - фжж + - зсжу + +# Spoken by the Novakid race. +- type: language + id: Fire + obfuscateSyllables: true + replacement: + - шш + - вшш + - шжшш + - сшшшс + - шсжсс + - ссш + - сс + - жжс + - жшж + + +# The common language of the Sol system. +- type: language + id: SolCommon + obfuscateSyllables: true + replacement: + - тао + - ши + - тзу + - йи + - ком + - би + - ис + - я + - оп + - ви + - эд + - лек + - мо + - кле + - те + - дис + - ее + +# Languages spoken by various critters. +- type: language + id: Cat + obfuscateSyllables: true + replacement: + - мурр + - мяу + - мурр + - мрау + +- type: language + id: Dog + obfuscateSyllables: true + replacement: + - вуф + - гав + - гаф + - рафф + - гарр + +- type: language + id: Mothroach + obfuscateSyllables: false + replacement: + - Бзз + - Чрик + - Скуик + - Пип + - Ииии + - Иип + +- type: language + id: Xeno + obfuscateSyllables: true + replacement: + - ссс + - сСс + - ССС +# IPC +- type: language + id: RobotTalk + obfuscateSyllables: true + replacement: + - "0" + - "1" + - "2" +# Borgs +- type: language + id: BorgTalk + obfuscateSyllables: true + replacement: + - "0" + - "1" + +- type: language + id: Monkey + obfuscateSyllables: true + replacement: + - аг + - ааг + - аааг + - ааааг + - аааааг + +- type: language + id: Bee + obfuscateSyllables: false + replacement: + - Бз + - Бзз + - Бззз + - Бзззз + - Бззззз + +- type: language + id: Mouse + obfuscateSyllables: false + replacement: + - Скуик + - Пип + - Чуу + - Ииии + - Пип + +- type: language + id: Chicken + obfuscateSyllables: false + replacement: + - Coo + - Coot + - Cooot + +- type: language + id: Duck + obfuscateSyllables: false + replacement: + - Quack + +- type: language + id: Cow + obfuscateSyllables: false + replacement: + - Moo + - Mooo + +- type: language + id: Sheep + obfuscateSyllables: false + replacement: + - Ba + - Baa + - Baaa + +- type: language + id: Kangaroo + obfuscateSyllables: false + replacement: + - Shreak + - Chuu + +- type: language + id: Pig + obfuscateSyllables: false + replacement: + - Oink + +# Spoken by the Drask race. +- type: language + id: Drask + obfuscateSyllables: true + replacement: + - овв + - оумн + - мноо + - румум + - ваар + - дромнн + - руум + - гоом + - фмонг + - оорм + - гаар + - хоорб + - саар + - ссооумн + - гнии + - вииск + - вррм + +# Spoken by the Ursus race. +- type: language + id: Urs + obfuscateSyllables: true + replacement: + - раа + - ишш + - тзуур + - арр + - кромм + - би + - инн + - рр + - оот + - вирр + - эк + - лерр + - мои + - крр + - тее + - ррс + - аа + - ир + - ррэк + - ер + - маа + - ке + - етт + +# Spoken by the Arkane race. +- type: language + id: Arkane + obfuscateSyllables: true + replacement: + - рииа + - инн + - тлаа + - айр + - коо + - бии + - иинта + - реаа + - онт + - виер + - энк + - лааир + - оии + - кееа + - теу + - риина + - ин + +# Spoken by the Shadowkin race. +- type: language + id: Shadowkin + obfuscateSyllables: true + replacement: + - mia + - ar + - ren + - naar + - mae + - tre + - ien + - trr + - ou + - rin + - nae + - ena + - oi + - kerr + - que + - uoh + - een + +# Spoken by the Dwarf race. +- type: language + id: Dwarf + obfuscateSyllables: true + replacement: + - арр + - рок + - стн + - шахт + - руд + - трэ + - кирк + - диг + - йи + - мыэ + - молл + - бур + - пив + - стн + - дрг + - эйе + +# Spoken by the Dwarf race. +- type: language + id: CintaTaj + obfuscateSyllables: true + replacement: + - za + - az + - ze + - ez + - zi + - iz + - zo + - oz + - zu + - uz + - zs + - sz + - ha + - ah + - he + - eh + - hi + - ih + - ho + - oh + - hu + - uh + - hs + - sh + - la + - al + - le + - el + - li + - il + - lo + - ol + - lu + - ul + - ls + - sl + - ka + - ak + - ke + - ek + - ki + - ik + - ko + - ok + - ku + - uk + - ks + - sk + - sa + - as + - se + - es + - si + - is + - so + - os + - su + - us + - ss + - ss + - ra + - ar + - re + - er + - ri + - ir + - ro + - or + - ru + - ur + - rs + - sr + - a + - a + - e + - e + - i + - i + - o + - o + - u + - u + - s + - s + - rae + - ye + - cen + - prr + - mer + - kuk + - tek + - qar + - ud + - wu + - wuh + - "taj'" + - tch + - ser + - "'aerch" + - it + - ei + - endr + - zeihs + - tet + - mir + - wo + - bis + - es + - voj + - jic + - fro + - rrr + - ener + - zajet + - th + - nort + - hel + - ist + - far + - wa + - bara + - ierg + - tech + - lach + - sam + - mak + - "'lirch" + - get + - or + - "jag'" + - eck + - gec + - stag + - "'onn" + - bin + - ket + - "jart'" + - vul + - einech + - cres + - "'eirr" + - ghh + +# Here goes admeme languages. +- type: language + id: Dev + obfuscateSyllables: true + replacement: + - су + - ка + - офф + - ямл + - бл + - пид + - рас + - о + - виз + - код + - с# + - мета + - билд + - сук + - гни + - эмис + - баг + - да + - бля + - гит + - мердж + - пулл + - ПР + - огг + - пнг + - робст + - релз + - дебаг diff --git a/Resources/Prototypes/ADT/Recipes/Lathes/translators.yml b/Resources/Prototypes/ADT/Recipes/Lathes/translators.yml new file mode 100644 index 0000000000..233acfe64d --- /dev/null +++ b/Resources/Prototypes/ADT/Recipes/Lathes/translators.yml @@ -0,0 +1,358 @@ +# Translators +- type: latheRecipe + id: CanilunztTranslator + result: CanilunztTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: BubblishTranslator + result: BubblishTranslator + completetime: 2 + materials: + Steel: 500 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: NekomimeticTranslator + result: NekomimeticTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: DraconicTranslator + result: DraconicTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: SolCommonTranslator + result: SolCommonTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: RootSpeakTranslator + result: RootSpeakTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: MofficTranslator + result: MofficTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: BasicGalaticCommonTranslatorImplanter + result: BasicGalaticCommonTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: XenoTranslator + result: XenoTranslator + completetime: 2 + materials: + Steel: 200 + Plastic: 50 + Gold: 50 + Plasma: 50 + Silver: 50 + +- type: latheRecipe + id: AdvancedGalaticCommonTranslatorImplanter + result: AdvancedGalaticCommonTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: BubblishTranslatorImplanter + result: BubblishTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: NekomimeticTranslatorImplanter + result: NekomimeticTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: DraconicTranslatorImplanter + result: DraconicTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: CanilunztTranslatorImplanter + result: CanilunztTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: SolCommonTranslatorImplanter + result: SolCommonTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: RootSpeakTranslatorImplanter + result: RootSpeakTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: MofficTranslatorImplanter + result: MofficTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: AnimalTranslator + result: AnimalTranslator + completetime: 2 + materials: + Steel: 200 + Plastic: 50 + Gold: 50 + Plasma: 50 + Silver: 5 + +- type: latheRecipe + id: SikTajTranslatorImplanter + result: SikTajTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: NianTranslatorImplanter + result: NianTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: FireTranslatorImplanter + result: FireTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: DraskTranslator + result: DraskTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: DraskTranslatorImplanter + result: DraskTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: UrsTranslatorImplanter + result: UrsTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: ArkaneTranslatorImplanter + result: ArkaneTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: ShadowkinTranslatorImplanter + result: ShadowkinTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: CintaTajTranslatorImplanter + result: CintaTajTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +#- type: latheRecipe +# id: UrsTranslator +# result: UrsTranslator +# completetime: 2 +# materials: +# Steel: 500 +# Glass: 100 +# Plastic: 50 +# Gold: 50 + +- type: latheRecipe + id: ArkaneTranslator + result: ArkaneTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: ShadowkinTranslator + result: ShadowkinTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: NianTranslator + result: NianTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: FireTranslator + result: FireTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: SikTajTranslator + result: SikTajTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: CintaTajTranslator + result: CintaTajTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 diff --git a/Resources/Prototypes/ADT/Research/translators.yml b/Resources/Prototypes/ADT/Research/translators.yml new file mode 100644 index 0000000000..a687d06a53 --- /dev/null +++ b/Resources/Prototypes/ADT/Research/translators.yml @@ -0,0 +1,59 @@ +# Tier 2 - entrypoint to translators +- type: technology + id: BasicTranslation + name: research-technology-basic-translation + icon: + sprite: _NF/Objects/Devices/translator.rsi + state: icon + discipline: CivilianServices + tier: 2 + cost: 10000 + recipeUnlocks: + - CanilunztTranslator + - BubblishTranslator + - NekomimeticTranslator + - DraconicTranslator + - SolCommonTranslator + - RootSpeakTranslator + - BasicGalaticCommonTranslatorImplanter + - MofficTranslator + - DraskTranslator +# - UrsTranslator # Закомменчено до раундстарт урсов + - ArkaneTranslator + - ShadowkinTranslator + - NianTranslator + - FireTranslator + - SikTajTranslator + - CintaTajTranslator + + +# Frontier - languages mechanic +- type: technology + id: AdvancedTranslation + name: research-technology-advanced-translation + icon: + sprite: _NF/Objects/Devices/translator.rsi + state: icon + discipline: CivilianServices + tier: 3 + cost: 15000 + recipeUnlocks: + - XenoTranslator + - AdvancedGalaticCommonTranslatorImplanter + - BubblishTranslatorImplanter + - NekomimeticTranslatorImplanter + - DraconicTranslatorImplanter + - CanilunztTranslatorImplanter + - SolCommonTranslatorImplanter + - RootSpeakTranslatorImplanter + - AnimalTranslator + - MofficTranslatorImplanter + - DraskTranslatorImplanter + - SikTajTranslatorImplanter + - NianTranslatorImplanter + - FireTranslatorImplanter + - DraskTranslatorImplanter +# - UrsTranslatorImplanter # Закомменчено до раундстарт урсов + - ArkaneTranslatorImplanter + - ShadowkinTranslatorImplanter + - CintaTajTranslatorImplanter diff --git a/Resources/Prototypes/ADT/SoundCollections/emotes.yml b/Resources/Prototypes/ADT/SoundCollections/emotes.yml new file mode 100644 index 0000000000..3f6d324548 --- /dev/null +++ b/Resources/Prototypes/ADT/SoundCollections/emotes.yml @@ -0,0 +1,16 @@ +- type: soundCollection + id: DraskCough + files: + - /Audio/ADT/Drask/draskcough.ogg +- type: soundCollection + id: DraskScream + files: + - /Audio/ADT/Drask/draskscream.ogg +- type: soundCollection + id: DraskSneeze + files: + - /Audio/ADT/Drask/drasksneeze.ogg +- type: soundCollection + id: DraskTalk + files: + - /Audio/ADT/Drask/drasktalk.ogg diff --git a/Resources/Prototypes/ADT/Species/demon.yml b/Resources/Prototypes/ADT/Species/demon.yml new file mode 100644 index 0000000000..82bbe62c59 --- /dev/null +++ b/Resources/Prototypes/ADT/Species/demon.yml @@ -0,0 +1,157 @@ +- type: species + id: DemonSpecies + name: species-name-demon + roundStart: true + prototype: MobDemon + sprites: MobDemonSprites + defaultSkinTone: "#34a223" + markingLimits: MobDemonMarkingLimits + dollPrototype: MobDemonDummy + skinColoration: Hues + maleFirstNames: names_first_male + femaleFirstNames: names_first_female + maleLastNames: names_last_male + femaleLastNames: names_last_female + naming: firstlast + +- type: speciesBaseSprites + id: MobDemonSprites + sprites: + Head: MobDemonHead + Hair: MobHumanoidAnyMarking + FacialHair: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking + Chest: MobDemonTorso + HeadTop: MobHumanoidAnyMarking + HeadSide: MobHumanoidAnyMarking + Tail: MobDemonTail + Eyes: MobHumanoidEyes + LArm: MobDemonLArm + RArm: MobDemonRArm + LHand: MobDemonLHand + RHand: MobDemonRHand + LLeg: MobDemonLLeg + RLeg: MobDemonRLeg + LFoot: MobDemonLFoot + RFoot: MobDemonRFoot + +- type: markingPoints + id: MobDemonMarkingLimits + points: + Hair: + points: 1 + required: false + FacialHair: + points: 1 + required: false + HeadTop: + points: 1 + required: false + HeadSide: + points: 1 + required: false + Chest: + points: 1 + required: false + Tail: + points: 1 + required: false + Snout: + points: 1 + required: false + Legs: + points: 2 + required: false + Arms: + points: 2 + required: false + +- type: humanoidBaseSprite + id: MobDemonHead + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDemonHeadMale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDemonHeadFemale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobDemonTorso + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDemonTorsoMale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDemonTorsoFemale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobDemonLLeg + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobDemonLHand + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobDemonLArm + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobDemonLFoot + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobDemonRLeg + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobDemonRHand + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobDemonRArm + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobDemonRFoot + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_foot + +- type: humanoidBaseSprite + id: MobDemonTail + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: tail diff --git a/Resources/Prototypes/ADT/Species/drask.yml b/Resources/Prototypes/ADT/Species/drask.yml new file mode 100644 index 0000000000..8c75d513ae --- /dev/null +++ b/Resources/Prototypes/ADT/Species/drask.yml @@ -0,0 +1,158 @@ +- type: species + id: DraskSpecies + name: species-name-drask + roundStart: true + prototype: MobDrask + sprites: MobDraskSprites + defaultSkinTone: "#a3d4eb" + markingLimits: MobDraskMarkingLimits + dollPrototype: MobDraskDummy + skinColoration: Hues + maleFirstNames: Draskfrist + femaleFirstNames: Draskfrist + maleLastNames: Draskfrist + femaleLastNames: Draskfrist + naming: FirstDashFirstDashFirst + +- type: speciesBaseSprites + id: MobDraskSprites + sprites: + Head: MobDraskHead + Eyes: MobDraskEyes + Hair: MobHumanoidAnyMarking + HeadTop: MobHumanoidAnyMarking + HeadSide: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking + Chest: MobDraskTorso + LArm: MobDraskLArm + RArm: MobDraskRArm + LHand: MobDraskLHand + RHand: MobDraskRHand + LLeg: MobDraskLLeg + RLeg: MobDraskRLeg + LFoot: MobDraskLFoot + RFoot: MobDraskRFoot + +- type: markingPoints + id: MobDraskMarkingLimits + onlyWhitelisted: true + points: + Head: + points: 1 + required: false + Hair: + points: 1 + required: false + HeadTop: + points: 1 + required: true + HeadSide: + points: 1 + required: true + Chest: + points: 1 + required: true + Tail: + points: 1 + required: false + Snout: + points: 1 + required: false + Legs: + points: 2 + required: false + Arms: + points: 2 + required: false + defaultMarkings: [DraskArmRight,DraskArmLeft] + + +- type: humanoidBaseSprite + id: MobDraskEyes + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: eyes + +- type: humanoidBaseSprite + id: MobDraskHead + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDraskHeadMale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDraskHeadFemale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobDraskTorso + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDraskTorsoMale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDraskTorsoFemale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobDraskLLeg + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobDraskLHand + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobDraskLArm + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobDraskLFoot + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobDraskRLeg + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobDraskRHand + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobDraskRArm + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobDraskRFoot + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_foot diff --git a/Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml b/Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml new file mode 100644 index 0000000000..8eb673d93f --- /dev/null +++ b/Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml @@ -0,0 +1,67 @@ +- type: emoteSounds + id: MaleDrask + params: + variation: 0.125 + sounds: + Scream: + collection: DraskScream + Laugh: + collection: MaleLaugh + Sneeze: + collection: DraskSneeze + Cough: + collection: DraskCough + CatMeow: + collection: CatMeows + CatHisses: + collection: CatHisses + MonkeyScreeches: + collection: MonkeyScreeches + RobotBeep: + collection: RobotBeeps + Yawn: + collection: MaleYawn + Snore: + collection: Snores + Honk: + collection: BikeHorn + Sigh: + collection: MaleSigh + Crying: + collection: MaleCry + Whistle: + collection: Whistles + +- type: emoteSounds + id: FemaleDrask + params: + variation: 0.125 + sounds: + Scream: + collection: DraskScream + Laugh: + collection: FemaleLaugh + Sneeze: + collection: DraskSneeze + Cough: + collection: DraskCough + CatMeow: + collection: CatMeows + CatHisses: + collection: CatHisses + MonkeyScreeches: + collection: MonkeyScreeches + RobotBeep: + collection: RobotBeeps + Yawn: + collection: FemaleYawn + Snore: + collection: Snores + Honk: + collection: CluwneHorn + Sigh: + collection: FemaleSigh + Crying: + collection: FemaleCry + Whistle: + collection: Whistles diff --git a/Resources/Prototypes/ADT/Voice/speech_sounds.yml b/Resources/Prototypes/ADT/Voice/speech_sounds.yml new file mode 100644 index 0000000000..224f49ef3a --- /dev/null +++ b/Resources/Prototypes/ADT/Voice/speech_sounds.yml @@ -0,0 +1,8 @@ +- type: speechSounds + id: Drask + saySound: + path: /Audio/ADT/Drask/drasktalk.ogg + askSound: + path: /Audio/ADT/Drask/drasktalk.ogg + exclaimSound: + path: /Audio/ADT/Drask/drasktalk.ogg diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index a79fbfbf24..baf7d7ade0 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -62,6 +62,11 @@ - type: Tag tags: - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - Mouse - type: entity name: bee @@ -1046,6 +1051,11 @@ - type: HTN rootTask: task: SimpleHostileCompound + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - Monkey - type: entity name: kangaroo @@ -1282,6 +1292,11 @@ Burn: 3 clumsySound: path: /Audio/Animals/monkey_scream.ogg + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - Monkey - type: entity name: monkey @@ -1312,6 +1327,12 @@ - type: GhostTakeoverAvailable - type: Loadout prototypes: [SyndicateOperativeGearMonkey] + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - GalacticCommon + - Monkey - type: entity id: MobMonkeySyndicateAgent @@ -1471,6 +1492,9 @@ - Syndicate - type: Loadout prototypes: [SyndicateOperativeGearMonkey] + - type: LanguageSpeaker # Frontier + understands: + - GalacticCommon - type: entity id: MobKoboldSyndicateAgent @@ -1655,6 +1679,11 @@ - type: FireVisuals sprite: Mobs/Effects/onfire.rsi normalState: Mouse_burning + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - Mouse - type: entity parent: MobMouse @@ -2613,6 +2642,11 @@ - type: Tag tags: - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - Dog - type: entity name: corrupted corgi @@ -2766,6 +2800,11 @@ - type: Tag tags: - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - Cat - type: entity name: calico cat @@ -3161,6 +3200,11 @@ - type: FireVisuals sprite: Mobs/Effects/onfire.rsi normalState: Mouse_burning + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - Mouse - type: entity name: pig diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 4436ebc612..fe265c7cb6 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -36,6 +36,12 @@ - VimPilot - type: StealTarget stealGroup: AnimalIan + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - GalacticCommon + - Dog - type: entity name: Old Ian @@ -121,6 +127,12 @@ tags: - CannotSuicide - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - GalacticCommon + - Cat - type: entity name: Exception @@ -139,6 +151,12 @@ tags: - CannotSuicide - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - GalacticCommon + - Cat - type: entity name: Floppa @@ -164,6 +182,12 @@ tags: - CannotSuicide - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - GalacticCommon + - Cat - type: entity name: Bandito @@ -295,6 +319,12 @@ - VimPilot - type: StealTarget stealGroup: AnimalMcGriff + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - GalacticCommon + - Dog - type: entity name: Paperwork @@ -388,6 +418,12 @@ - VimPilot - type: StealTarget stealGroup: AnimalWalter + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - GalacticCommon + - Dog - type: entity name: Morty @@ -577,6 +613,12 @@ - Hamster - VimPilot - ChefPilot + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - GalacticCommon + - Mouse - type: entity name: Shiva @@ -781,6 +823,12 @@ attributes: proper: true gender: male + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - GalacticCommon + - Monkey - type: entity name: Tropico diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml index d63afd4fa4..eefaedb47f 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml @@ -97,3 +97,8 @@ - RevenantTheme - type: Speech speechVerb: Ghost + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + understands: + - GalacticCommon diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index 1686b723b5..28758fb95b 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -109,6 +109,13 @@ - type: StepTriggerImmune - type: NoSlip - type: Insulated + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - BorgTalk + understands: + - GalacticCommon + - BorgTalk - type: entity parent: MobSiliconBase diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml index c50ad70ea2..d4970d88de 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml @@ -112,6 +112,11 @@ speechSounds: Slime - type: TypingIndicator proto: slime + - type: LanguageSpeaker # Frontier + speaks: + - Bubblish + understands: + - Bubblish - type: entity name: basic slime diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 9fb0be02ae..3cf6fc69f5 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -119,6 +119,11 @@ molsPerSecondPerUnitMass: 0.0005 - type: Speech speechVerb: LargeMob + - type: LanguageSpeaker # Frontier + speaks: + - Xeno + understands: + - Xeno - type: entity name: Praetorian diff --git a/Resources/Prototypes/Entities/Mobs/Player/observer.yml b/Resources/Prototypes/Entities/Mobs/Player/observer.yml index 85be42cc02..0f826936a5 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/observer.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/observer.yml @@ -48,6 +48,7 @@ - type: Tag tags: - BypassInteractionRangeChecks + - type: UniversalLanguageSpeaker # Frontier / Ghosts should understand any language. - type: entity id: ActionGhostBoo diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml index 8b3c66d5dd..e1ec78b419 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml @@ -122,6 +122,13 @@ sprite: "Effects/creampie.rsi" state: "creampie_arachnid" visible: false + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Moffic + understands: + - GalacticCommon + - Moffic - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index d956f1871d..ee19b937ce 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -221,6 +221,12 @@ - CanPilot - FootstepSound - DoorBumpOpener + # Frontier - languages mechanic + - type: LanguageSpeaker + speaks: + - GalacticCommon + understands: + - GalacticCommon - type: entity save: false diff --git a/Resources/Prototypes/Entities/Mobs/Species/diona.yml b/Resources/Prototypes/Entities/Mobs/Species/diona.yml index ba1a2cbf76..98341e8d12 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/diona.yml @@ -102,6 +102,13 @@ actionPrototype: DionaGibAction allowedStates: - Dead + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - RootSpeak + understands: + - GalacticCommon + - RootSpeak - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml b/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml index 5a54b56c48..d332914399 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml @@ -56,6 +56,13 @@ hideLayersOnEquip: - Hair - Snout + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Dwarf + understands: + - GalacticCommon + - Dwarf - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 6716d3902b..1152f654da 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -20,6 +20,13 @@ hideLayersOnEquip: - Hair - Snout + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - SolCommon + understands: + - GalacticCommon + - SolCommon - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml index f6fde849ef..a2730b6d7e 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml @@ -118,6 +118,13 @@ sprite: "Effects/creampie.rsi" state: "creampie_moth" visible: false + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Nian + understands: + - GalacticCommon + - Nian - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml index ad543620cf..4d09690201 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml @@ -62,6 +62,15 @@ types: Heat : 1.5 #per second, scales with temperature & other constants - type: Wagging + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Draconic + - CintaTaj + understands: + - GalacticCommon + - Draconic + - CintaTaj - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index caa3690e5d..7c76d34222 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -110,6 +110,13 @@ types: Asphyxiation: -1.0 maxSaturation: 15 + - type: LanguageSpeaker + speaks: + - GalacticCommon + - Bubblish + understands: + - GalacticCommon + - Bubblish - type: entity parent: MobHumanDummy diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index d973c5c607..c3b4bbbb82 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -46,6 +46,11 @@ - type: TTS # Corvax-TTS - type: RequireProjectileTarget active: False + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + understands: + - GalacticCommon # Used for mobs that have health and can take damage. - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 8021d39028..28f5796c71 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -333,6 +333,42 @@ - FauxTileAstroSnow - OreBagOfHolding - DeviceQuantumSpinInverter + # vv Frontier - languages mechanic vv + - CanilunztTranslator + - BubblishTranslator + - NekomimeticTranslator + - DraconicTranslator + - SolCommonTranslator + - RootSpeakTranslator + - XenoTranslator + - DraskTranslator + - BasicGalaticCommonTranslatorImplanter + - AdvancedGalaticCommonTranslatorImplanter + - BubblishTranslatorImplanter + - NekomimeticTranslatorImplanter + - DraconicTranslatorImplanter + - CanilunztTranslatorImplanter + - SolCommonTranslatorImplanter + - RootSpeakTranslatorImplanter + - AnimalTranslator + - MofficTranslatorImplanter + - MofficTranslator + - SikTajTranslatorImplanter + - NianTranslatorImplanter + - FireTranslatorImplanter + - DraskTranslatorImplanter +# - UrsTranslatorImplanter # Закомменчено до раундстарт урсов + - ArkaneTranslatorImplanter + - ShadowkinTranslatorImplanter + - CintaTajTranslatorImplanter +# - UrsTranslator # Закомменчено до раундстарт урсов + - ArkaneTranslator + - ShadowkinTranslator + - NianTranslator + - FireTranslator + - SikTajTranslator + - CintaTajTranslator + # ^^ Frontier - languages mechanic ^^ - type: EmagLatheRecipes emagDynamicRecipes: - BoxBeanbag diff --git a/Resources/Prototypes/Reagents/gases.yml b/Resources/Prototypes/Reagents/gases.yml index 9ef508feea..2087d88655 100644 --- a/Resources/Prototypes/Reagents/gases.yml +++ b/Resources/Prototypes/Reagents/gases.yml @@ -14,6 +14,12 @@ conditions: - !type:OrganType type: Human + # Start ADT tweak: Drask + - !type:Oxygenate + conditions: + - !type:OrganType + type: Drask + # End ADT tweak - !type:Oxygenate conditions: - !type:OrganType diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_ears.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_ears.png new file mode 100644 index 0000000000..6c7c43592a Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_ears.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_horns.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_horns.png new file mode 100644 index 0000000000..9475831ceb Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_horns.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_spots.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_spots.png new file mode 100644 index 0000000000..f6e3dbc945 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_spots.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/deer_antlers_horns.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/deer_antlers_horns.png new file mode 100644 index 0000000000..2341a2e340 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/deer_antlers_horns.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_ears.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_ears.png new file mode 100644 index 0000000000..14e05f4b54 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_ears.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_tail.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_tail.png new file mode 100644 index 0000000000..53bb821fa8 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_tail.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/goatee.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/goatee.png new file mode 100644 index 0000000000..98a511a24a Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/goatee.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/guards_stripes.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/guards_stripes.png new file mode 100644 index 0000000000..0c55c27d6f Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/guards_stripes.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/lines_emperos.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/lines_emperos.png new file mode 100644 index 0000000000..5e8536c75c Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/lines_emperos.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/long.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/long.png new file mode 100644 index 0000000000..af7875e2fb Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/long.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/meta.json b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/meta.json new file mode 100644 index 0000000000..5c76f5ca41 --- /dev/null +++ b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/meta.json @@ -0,0 +1,71 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by discord:lunalita", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "cow_ears", + "directions": 4 + }, + { + "name": "demon_ears", + "directions": 4 + }, + { + "name": "goatee", + "directions": 4 + }, + { + "name": "cow_horns", + "directions": 4 + }, + { + "name": "cow_spots", + "directions": 4 + }, + { + "name": "deer_antlers_horns", + "directions": 4 + }, + { + "name": "guards_stripes", + "directions": 4 + }, + { + "name": "lines_emperos", + "directions": 4 + }, + { + "name": "queen_lines", + "directions": 4 + }, + { + "name": "small_horns", + "directions": 4 + }, + { + "name": "tree_lines", + "directions": 4 + }, + { + "name": "trinity_spots", + "directions": 4 + }, + { + "name": "demon_tail", + "directions": 4 + }, + { + "name": "long", + "directions": 4 + }, + { + "name": "up", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/queen_lines.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/queen_lines.png new file mode 100644 index 0000000000..0e30ea261a Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/queen_lines.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/small_horns.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/small_horns.png new file mode 100644 index 0000000000..44618403c9 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/small_horns.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/tree_lines.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/tree_lines.png new file mode 100644 index 0000000000..4a555c4d11 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/tree_lines.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/trinity_spots.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/trinity_spots.png new file mode 100644 index 0000000000..1fec0d2cad Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/trinity_spots.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/up.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/up.png new file mode 100644 index 0000000000..898e7d4b91 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/up.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_f.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_f.png new file mode 100644 index 0000000000..f9eec1209b Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_f.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_m.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_m.png new file mode 100644 index 0000000000..f8f1bbbcf6 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_m.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_t.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_t.png new file mode 100644 index 0000000000..3c71c7d8c3 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_t.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_f.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_f.png new file mode 100644 index 0000000000..1285b693dc Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_f.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_m.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_m.png new file mode 100644 index 0000000000..181643e9dd Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_m.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_t.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_t.png new file mode 100644 index 0000000000..1285b693dc Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_t.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_arm.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_arm.png new file mode 100644 index 0000000000..0b124d8c83 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_arm.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_foot.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_foot.png new file mode 100644 index 0000000000..d7fa72f6b5 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_foot.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_hand.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_hand.png new file mode 100644 index 0000000000..ff61ecd0cf Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_hand.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_leg.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_leg.png new file mode 100644 index 0000000000..2125370c5b Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_leg.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/meta.json b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/meta.json new file mode 100644 index 0000000000..7aa4c0b100 --- /dev/null +++ b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/meta.json @@ -0,0 +1,80 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by discord:lunalita", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full_f" + }, + { + "name": "full_m" + }, + { + "name": "full_t" + }, + { + "name": "head_f", + "directions": 4 + }, + { + "name": "head_m", + "directions": 4 + }, + { + "name": "head_t", + "directions": 4 + }, + { + "name": "l_arm", + "directions": 4 + }, + { + "name": "l_foot", + "directions": 4 + }, + { + "name": "l_hand", + "directions": 4 + }, + { + "name": "l_leg", + "directions": 4 + }, + { + "name": "r_arm", + "directions": 4 + }, + { + "name": "r_foot", + "directions": 4 + }, + { + "name": "r_hand", + "directions": 4 + }, + { + "name": "r_leg", + "directions": 4 + }, + { + "name": "torso_f", + "directions": 4 + }, + { + "name": "torso_m", + "directions": 4 + }, + { + "name": "torso_t", + "directions": 4 + }, + { + "name": "tail", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_arm.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_arm.png new file mode 100644 index 0000000000..3b88f4ec6a Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_arm.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_foot.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_foot.png new file mode 100644 index 0000000000..92cc25101d Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_foot.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_hand.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_hand.png new file mode 100644 index 0000000000..74b5130e82 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_hand.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_leg.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_leg.png new file mode 100644 index 0000000000..020edfde73 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_leg.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/tail.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/tail.png new file mode 100644 index 0000000000..cd8f833d5d Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/tail.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_f.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_f.png new file mode 100644 index 0000000000..c7c0027daf Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_f.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_m.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_m.png new file mode 100644 index 0000000000..bfef26f5c2 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_m.png differ diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_t.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_t.png new file mode 100644 index 0000000000..3987d31531 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_t.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/custom.rsi/l_arm.png b/Resources/Textures/ADT/Mobs/Drask/custom.rsi/l_arm.png new file mode 100644 index 0000000000..f63177c4db Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/custom.rsi/l_arm.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/custom.rsi/meta.json b/Resources/Textures/ADT/Mobs/Drask/custom.rsi/meta.json new file mode 100644 index 0000000000..b53ab8a93a --- /dev/null +++ b/Resources/Textures/ADT/Mobs/Drask/custom.rsi/meta.json @@ -0,0 +1,19 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "ADT Team", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "l_arm", + "directions": 4 + }, + { + "name": "r_arm", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/ADT/Mobs/Drask/custom.rsi/r_arm.png b/Resources/Textures/ADT/Mobs/Drask/custom.rsi/r_arm.png new file mode 100644 index 0000000000..fdc1220e42 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/custom.rsi/r_arm.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/eyes.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/eyes.png new file mode 100644 index 0000000000..c976b9b9d3 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/eyes.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/heart_on.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/heart_on.png new file mode 100644 index 0000000000..89b2dba915 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/heart_on.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/innards.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/innards.png new file mode 100644 index 0000000000..894a29e4b8 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/innards.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/kidneys.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/kidneys.png new file mode 100644 index 0000000000..793f341da9 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/kidneys.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/lungs.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/lungs.png new file mode 100644 index 0000000000..512f2b7448 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/lungs.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/meta.json b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/meta.json new file mode 100644 index 0000000000..9997297c35 --- /dev/null +++ b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "ADT Team", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "eyes" + }, + { + "name": "kidneys" + }, + { + "name": "innards" + }, + { + "name": "lungs" + }, + { + "name": "heart_on", + "delays": [ + [ + 0.6, + 0.1, + 0.1 + ] + ] + } + ] +} diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/eyes.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/eyes.png new file mode 100644 index 0000000000..75928b1c77 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/eyes.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/full.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/full.png new file mode 100644 index 0000000000..33f6f187dc Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/full.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_f.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_f.png new file mode 100644 index 0000000000..756ebb9ffb Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_f.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_m.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_m.png new file mode 100644 index 0000000000..267f0540e5 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_m.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_arm.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_arm.png new file mode 100644 index 0000000000..7b411c4d1c Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_arm.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_foot.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_foot.png new file mode 100644 index 0000000000..4fbef47ded Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_foot.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_hand.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_hand.png new file mode 100644 index 0000000000..9a89e6bb8f Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_hand.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_leg.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_leg.png new file mode 100644 index 0000000000..975fa51edb Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_leg.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/meta.json b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/meta.json new file mode 100644 index 0000000000..1c9ef4963a --- /dev/null +++ b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/meta.json @@ -0,0 +1,66 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "ADT Team", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "eyes", + "directions": 4 + }, + { + "name": "head_f", + "directions": 4 + }, + { + "name": "head_m", + "directions": 4 + }, + { + "name": "l_arm", + "directions": 4 + }, + { + "name": "l_foot", + "directions": 4 + }, + { + "name": "l_hand", + "directions": 4 + }, + { + "name": "l_leg", + "directions": 4 + }, + { + "name": "r_arm", + "directions": 4 + }, + { + "name": "r_foot", + "directions": 4 + }, + { + "name": "r_hand", + "directions": 4 + }, + { + "name": "r_leg", + "directions": 4 + }, + { + "name": "torso_f", + "directions": 4 + }, + { + "name": "torso_m", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_arm.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_arm.png new file mode 100644 index 0000000000..6959b2c7f5 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_arm.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_foot.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_foot.png new file mode 100644 index 0000000000..ebaf3c833b Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_foot.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_hand.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_hand.png new file mode 100644 index 0000000000..57140e922e Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_hand.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_leg.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_leg.png new file mode 100644 index 0000000000..475e31b7d4 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_leg.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_f.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_f.png new file mode 100644 index 0000000000..75f8571969 Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_f.png differ diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_m.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_m.png new file mode 100644 index 0000000000..8f0186106f Binary files /dev/null and b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_m.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/meta.json b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/meta.json new file mode 100644 index 0000000000..9ce465ccac --- /dev/null +++ b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-3.0", + "copyright": "Sprited by mixnikita", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "telescope_on" + }, + { + "name": "telescope_off" + }, + { + "name": "off-inhand-left", + "directions": 4 + }, + { + "name": "off-inhand-right", + "directions": 4 + }, + { + "name": "on-inhand-left", + "directions": 4 + }, + { + "name": "on-inhand-right", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-left.png new file mode 100644 index 0000000000..d60eba8d49 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-left.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-right.png new file mode 100644 index 0000000000..86e67af478 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-right.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-left.png new file mode 100644 index 0000000000..48ffcd51d4 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-left.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-right.png new file mode 100644 index 0000000000..9cea4086c4 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-right.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_off.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_off.png new file mode 100644 index 0000000000..e0875d24f5 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_off.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_on.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_on.png new file mode 100644 index 0000000000..e253f25f0e Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_on.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/meta.json b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/meta.json new file mode 100644 index 0000000000..9ce465ccac --- /dev/null +++ b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-3.0", + "copyright": "Sprited by mixnikita", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "telescope_on" + }, + { + "name": "telescope_off" + }, + { + "name": "off-inhand-left", + "directions": 4 + }, + { + "name": "off-inhand-right", + "directions": 4 + }, + { + "name": "on-inhand-left", + "directions": 4 + }, + { + "name": "on-inhand-right", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-left.png new file mode 100644 index 0000000000..7da0323b47 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-left.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-right.png new file mode 100644 index 0000000000..95b859847c Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-right.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-left.png new file mode 100644 index 0000000000..10512d90a3 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-left.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-right.png new file mode 100644 index 0000000000..f150a01e58 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-right.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_off.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_off.png new file mode 100644 index 0000000000..a456a690e9 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_off.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_on.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_on.png new file mode 100644 index 0000000000..0df0ef1f98 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_on.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/meta.json b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/meta.json new file mode 100644 index 0000000000..9ce465ccac --- /dev/null +++ b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-3.0", + "copyright": "Sprited by mixnikita", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "telescope_on" + }, + { + "name": "telescope_off" + }, + { + "name": "off-inhand-left", + "directions": 4 + }, + { + "name": "off-inhand-right", + "directions": 4 + }, + { + "name": "on-inhand-left", + "directions": 4 + }, + { + "name": "on-inhand-right", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-left.png new file mode 100644 index 0000000000..be086e63ec Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-left.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-right.png new file mode 100644 index 0000000000..431831404e Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-right.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-left.png new file mode 100644 index 0000000000..a9b1a91c6b Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-left.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-right.png new file mode 100644 index 0000000000..199b35af1e Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-right.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_off.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_off.png new file mode 100644 index 0000000000..27a930b652 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_off.png differ diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_on.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_on.png new file mode 100644 index 0000000000..4971a110b8 Binary files /dev/null and b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_on.png differ diff --git a/Resources/Textures/_NF/Interface/Actions/language.png b/Resources/Textures/_NF/Interface/Actions/language.png new file mode 100644 index 0000000000..51962871ac Binary files /dev/null and b/Resources/Textures/_NF/Interface/Actions/language.png differ diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/icon.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/icon.png new file mode 100644 index 0000000000..92c3c4ab24 Binary files /dev/null and b/Resources/Textures/_NF/Objects/Devices/translator.rsi/icon.png differ diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left-translator.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left-translator.png new file mode 100644 index 0000000000..84add80f41 Binary files /dev/null and b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left-translator.png differ diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left.png new file mode 100644 index 0000000000..7e46e55fb4 Binary files /dev/null and b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left.png differ diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right-translator.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right-translator.png new file mode 100644 index 0000000000..76a1db299d Binary files /dev/null and b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right-translator.png differ diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right.png new file mode 100644 index 0000000000..f6c8e44768 Binary files /dev/null and b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right.png differ diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/meta.json b/Resources/Textures/_NF/Objects/Devices/translator.rsi/meta.json new file mode 100644 index 0000000000..fbf835d924 --- /dev/null +++ b/Resources/Textures/_NF/Objects/Devices/translator.rsi/meta.json @@ -0,0 +1,43 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Created by discord:auriss093 для Времени Приключений MRP", + "states": [ + { + "name": "icon" + }, + { + "name": "translator", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-left-translator", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "inhand-right-translator", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/translator.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/translator.png new file mode 100644 index 0000000000..9a9efb9842 Binary files /dev/null and b/Resources/Textures/_NF/Objects/Devices/translator.rsi/translator.png differ