Merge remote-tracking branch 'upstream/master' into upstream
@@ -12,7 +12,6 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Bwoink
|
namespace Content.Client.Administration.UI.Bwoink
|
||||||
@@ -49,39 +48,11 @@ namespace Content.Client.Administration.UI.Bwoink
|
|||||||
ChannelSelector.OnSelectionChanged += sel =>
|
ChannelSelector.OnSelectionChanged += sel =>
|
||||||
{
|
{
|
||||||
_currentPlayer = sel;
|
_currentPlayer = sel;
|
||||||
SwitchToChannel(sel?.SessionId);
|
SwitchToChannel(sel.SessionId);
|
||||||
ChannelSelector.PlayerListContainer.DirtyList();
|
ChannelSelector.PlayerListContainer.DirtyList();
|
||||||
};
|
};
|
||||||
|
|
||||||
ChannelSelector.OverrideText += (info, text) =>
|
ChannelSelector.OverrideText += (info, _) => FormatTabTitle(info);
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
if (info.Connected)
|
|
||||||
sb.Append('●');
|
|
||||||
else
|
|
||||||
sb.Append(info.ActiveThisRound ? '○' : '·');
|
|
||||||
|
|
||||||
sb.Append(' ');
|
|
||||||
if (AHelpHelper.TryGetChannel(info.SessionId, out var panel) && panel.Unread > 0)
|
|
||||||
{
|
|
||||||
if (panel.Unread < 11)
|
|
||||||
sb.Append(new Rune('➀' + (panel.Unread-1)));
|
|
||||||
else
|
|
||||||
sb.Append(new Rune(0x2639)); // ☹
|
|
||||||
sb.Append(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.Antag && info.ActiveThisRound)
|
|
||||||
sb.Append(new Rune(0x1F5E1)); // 🗡
|
|
||||||
|
|
||||||
if (info.OverallPlaytime <= TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.NewPlayerThreshold)))
|
|
||||||
sb.Append(new Rune(0x23F2)); // ⏲
|
|
||||||
|
|
||||||
sb.AppendFormat("\"{0}\"", text);
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
};
|
|
||||||
|
|
||||||
ChannelSelector.Comparison = (a, b) =>
|
ChannelSelector.Comparison = (a, b) =>
|
||||||
{
|
{
|
||||||
@@ -166,11 +137,10 @@ namespace Content.Client.Administration.UI.Bwoink
|
|||||||
ChannelSelector.PopulateList();
|
ChannelSelector.PopulateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SelectChannel(NetUserId channel)
|
public void SelectChannel(NetUserId channel)
|
||||||
{
|
{
|
||||||
if (!ChannelSelector.PlayerInfo.TryFirstOrDefault(
|
if (!ChannelSelector.PlayerInfo.TryFirstOrDefault(
|
||||||
i => i.SessionId == channel, out var info))
|
i => i.SessionId == channel, out var info))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// clear filter if we're trying to select a channel for a player that isn't currently filtered
|
// clear filter if we're trying to select a channel for a player that isn't currently filtered
|
||||||
@@ -208,33 +178,33 @@ namespace Content.Client.Administration.UI.Bwoink
|
|||||||
Follow.Disabled = !Follow.Visible || disabled;
|
Follow.Disabled = !Follow.Visible || disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FormatTabTitle(ItemList.Item li, PlayerInfo? pl = default)
|
private string FormatTabTitle(PlayerInfo info)
|
||||||
{
|
{
|
||||||
pl ??= (PlayerInfo) li.Metadata!;
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append(pl.Connected ? '●' : '○');
|
sb.Append(info.Connected ? '●' :
|
||||||
|
info.ActiveThisRound ? '○' : '·'
|
||||||
|
);
|
||||||
|
|
||||||
sb.Append(' ');
|
sb.Append(' ');
|
||||||
if (AHelpHelper.TryGetChannel(pl.SessionId, out var panel) && panel.Unread > 0)
|
if (AHelpHelper.TryGetChannel(info.SessionId, out var panel) && panel.Unread > 0)
|
||||||
{
|
{
|
||||||
if (panel.Unread < 11)
|
sb.Append(panel.Unread < 11 ? new Rune('➀' + (panel.Unread - 1)) : new Rune(0x2639)); // ☹
|
||||||
sb.Append(new Rune('➀' + (panel.Unread-1)));
|
|
||||||
else
|
|
||||||
sb.Append(new Rune(0x2639)); // ☹
|
|
||||||
sb.Append(' ');
|
sb.Append(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pl.Antag)
|
if (info.Antag)
|
||||||
sb.Append(new Rune(0x1F5E1)); // 🗡
|
sb.Append(new Rune(0x1F5E1)); // 🗡
|
||||||
|
|
||||||
if (pl.OverallPlaytime <= TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.NewPlayerThreshold)))
|
if (info.OverallPlaytime <= TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.NewPlayerThreshold)))
|
||||||
sb.Append(new Rune(0x23F2)); // ⏲
|
sb.Append(new Rune(0x23F2)); // ⏲
|
||||||
|
|
||||||
sb.AppendFormat("\"{0}\"", pl.CharacterName);
|
sb.Append($"\"{info.CharacterName}\"");
|
||||||
|
|
||||||
if (pl.IdentityName != pl.CharacterName && pl.IdentityName != string.Empty)
|
if (info.IdentityName != info.CharacterName && info.IdentityName != string.Empty)
|
||||||
sb.Append(' ').AppendFormat("[{0}]", pl.IdentityName);
|
sb.Append(' ').Append($"[{info.IdentityName}]");
|
||||||
|
|
||||||
sb.Append(' ').Append(pl.Username);
|
sb.Append(' ').Append(info.Username);
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -257,4 +227,4 @@ namespace Content.Client.Administration.UI.Bwoink
|
|||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.Administration.Systems;
|
using Content.Client.Administration.Systems;
|
||||||
|
using Content.Client.Stylesheets;
|
||||||
using Content.Client.UserInterface.Controls;
|
using Content.Client.UserInterface.Controls;
|
||||||
using Content.Client.Verbs.UI;
|
using Content.Client.Verbs.UI;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
@@ -26,15 +28,18 @@ namespace Content.Client.Administration.UI.CustomControls
|
|||||||
public Func<PlayerInfo, string, string>? OverrideText;
|
public Func<PlayerInfo, string, string>? OverrideText;
|
||||||
public Comparison<PlayerInfo>? Comparison;
|
public Comparison<PlayerInfo>? Comparison;
|
||||||
|
|
||||||
private IEntityManager _entManager;
|
private readonly IEntityManager _entManager;
|
||||||
private IUserInterfaceManager _uiManager;
|
private readonly IUserInterfaceManager _uiManager;
|
||||||
|
|
||||||
private PlayerInfo? _selectedPlayer;
|
private PlayerInfo? _selectedPlayer;
|
||||||
|
|
||||||
|
private readonly Font _fontOverride;
|
||||||
|
|
||||||
public PlayerListControl()
|
public PlayerListControl()
|
||||||
{
|
{
|
||||||
_entManager = IoCManager.Resolve<IEntityManager>();
|
_entManager = IoCManager.Resolve<IEntityManager>();
|
||||||
_uiManager = IoCManager.Resolve<IUserInterfaceManager>();
|
_uiManager = IoCManager.Resolve<IUserInterfaceManager>();
|
||||||
|
_fontOverride = IoCManager.Resolve<IResourceCache>().NotoStack(size: 12);
|
||||||
_adminSystem = _entManager.System<AdminSystem>();
|
_adminSystem = _entManager.System<AdminSystem>();
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
// Fill the Option data
|
// Fill the Option data
|
||||||
@@ -137,6 +142,7 @@ namespace Content.Client.Administration.UI.CustomControls
|
|||||||
new Label
|
new Label
|
||||||
{
|
{
|
||||||
ClipText = true,
|
ClipText = true,
|
||||||
|
FontOverride = _fontOverride,
|
||||||
Text = GetText(info)
|
Text = GetText(info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Robust.Client.ResourceManagement;
|
|||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Replays;
|
using Robust.Shared.Replays;
|
||||||
@@ -30,6 +31,7 @@ namespace Content.Client.Popups
|
|||||||
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||||
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
|
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||||
|
[Dependency] private readonly IClientNetManager _clientNet = default!;
|
||||||
|
|
||||||
public IReadOnlyList<WorldPopupLabel> WorldLabels => _aliveWorldLabels;
|
public IReadOnlyList<WorldPopupLabel> WorldLabels => _aliveWorldLabels;
|
||||||
public IReadOnlyList<CursorPopupLabel> CursorLabels => _aliveCursorLabels;
|
public IReadOnlyList<CursorPopupLabel> CursorLabels => _aliveCursorLabels;
|
||||||
@@ -99,12 +101,14 @@ namespace Content.Client.Popups
|
|||||||
{ PopupType.LargeCaution, "15" }
|
{ PopupType.LargeCaution, "15" }
|
||||||
};
|
};
|
||||||
|
|
||||||
var fontsize = fontSizeDict.ContainsKey(type) ? fontSizeDict[type] : "10";
|
var fontsize = fontSizeDict.GetValueOrDefault(type, "10");
|
||||||
var fontcolor = (type == PopupType.LargeCaution || type == PopupType.MediumCaution || type == PopupType.SmallCaution) ? "c62828" : "aeabc4";
|
var fontcolor = type is PopupType.LargeCaution or PopupType.MediumCaution or PopupType.SmallCaution ? "c62828" : "aeabc4";
|
||||||
|
|
||||||
if (isLogging)
|
if (isLogging)
|
||||||
{
|
{
|
||||||
_chatManager.SendMessage($"notice [font size={fontsize}][color=#{fontcolor}]{message}[/color][/font]", ChatSelectChannel.Console);
|
var wrappedMEssage = $"[font size={fontsize}][color=#{fontcolor}]{message}[/color][/font]";
|
||||||
|
var chatMsg = new ChatMessage(ChatChannel.Emotes, message, wrappedMEssage, GetNetEntity(EntityUid.Invalid), null);
|
||||||
|
_clientNet.DispatchLocalNetMessage(new MsgChatMessage { Message = chatMsg });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
67
Content.Client/_White/Overlays/ShowMindslaveIconsSystem.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using Content.Client.Overlays;
|
||||||
|
using Content.Shared._White.Implants.Mindslave.Components;
|
||||||
|
using Content.Shared.StatusIcon;
|
||||||
|
using Content.Shared.StatusIcon.Components;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Client._White.Overlays;
|
||||||
|
|
||||||
|
public sealed class ShowMindslaveIconsSystem : EquipmentHudSystem<MindSlaveComponent>
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _player = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<MindSlaveComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetStatusIconsEvent(
|
||||||
|
EntityUid uid,
|
||||||
|
MindSlaveComponent mindSlaveComponent,
|
||||||
|
ref GetStatusIconsEvent args)
|
||||||
|
{
|
||||||
|
if (!IsActive || args.InContainer)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var localEnt = _player.LocalEntity;
|
||||||
|
if (!TryComp(localEnt, out MindSlaveComponent? ownerMindSlave))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mindSlaveIcon = MindslaveIcon(uid, ownerMindSlave);
|
||||||
|
|
||||||
|
args.StatusIcons.AddRange(mindSlaveIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<StatusIconPrototype> MindslaveIcon(EntityUid uid, MindSlaveComponent mindSlave)
|
||||||
|
{
|
||||||
|
var result = new List<StatusIconPrototype>();
|
||||||
|
|
||||||
|
string? iconType;
|
||||||
|
if (GetEntity(mindSlave.Master) == uid)
|
||||||
|
{
|
||||||
|
iconType = mindSlave.MasterStatusIcon;
|
||||||
|
}
|
||||||
|
else if (mindSlave.Slaves.Contains(GetNetEntity(uid)))
|
||||||
|
{
|
||||||
|
iconType = mindSlave.SlaveStatusIcon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_prototype.TryIndex<StatusIconPrototype>(iconType, out var mindslaveIcon))
|
||||||
|
{
|
||||||
|
result.Add(mindslaveIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
85
Content.Server/_White/Implants/Mindslave/MindslaveSystem.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using Content.Server.Chat.Managers;
|
||||||
|
using Content.Server.Roles;
|
||||||
|
using Content.Server.Roles.Jobs;
|
||||||
|
using Content.Shared._White.Implants.Mindslave;
|
||||||
|
using Content.Shared._White.Implants.Mindslave.Components;
|
||||||
|
using Content.Shared.Chat;
|
||||||
|
using Content.Shared.Implants;
|
||||||
|
using Content.Shared.Implants.Components;
|
||||||
|
|
||||||
|
namespace Content.Server._White.Implants.Mindslave;
|
||||||
|
|
||||||
|
public sealed class MindslaveSystem : SharedMindslaveSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly RoleSystem _role = default!;
|
||||||
|
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||||
|
[Dependency] private readonly JobSystem _job = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<SubdermalImplantComponent, SubdermalImplantInserted>(OnMindslaveInserted);
|
||||||
|
SubscribeLocalEvent<SubdermalImplantComponent, SubdermalImplantRemoved>(OnMindslaveRemoved);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMindslaveInserted(Entity<SubdermalImplantComponent> ent, ref SubdermalImplantInserted args)
|
||||||
|
{
|
||||||
|
if (!Tag.HasTag(ent.Owner, MindslaveTag))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slaveComponent = EnsureComp<MindSlaveComponent>(args.Target);
|
||||||
|
slaveComponent.Slaves.Add(GetNetEntity(args.Target));
|
||||||
|
slaveComponent.Master = GetNetEntity(args.User);
|
||||||
|
|
||||||
|
var masterComponent = EnsureComp<MindSlaveComponent>(args.User);
|
||||||
|
masterComponent.Slaves.Add(GetNetEntity(args.Target));
|
||||||
|
masterComponent.Master = GetNetEntity(args.User);
|
||||||
|
|
||||||
|
Dirty(args.Target, masterComponent);
|
||||||
|
|
||||||
|
if (!Mind.TryGetMind(args.Target, out var targetMindId, out var targetMind) || targetMind.Session is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var jobName = _job.MindTryGetJobName(args.User);
|
||||||
|
|
||||||
|
// send message to chat
|
||||||
|
var message = Loc.GetString("mindslave-chat-message", ("player", args.User), ("role", jobName));
|
||||||
|
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
|
||||||
|
_chatManager.ChatMessageToOne(ChatChannel.Server, message, wrappedMessage, default, false,
|
||||||
|
targetMind.Session.Channel, Color.FromHex("#5e9cff"));
|
||||||
|
|
||||||
|
// add briefing in character menu
|
||||||
|
if (TryComp<RoleBriefingComponent>(targetMindId, out var roleBriefing))
|
||||||
|
{
|
||||||
|
roleBriefing.Briefing += Loc.GetString("mindslave-briefing", ("player", args.User), ("role", jobName));
|
||||||
|
Dirty(targetMindId, roleBriefing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_role.MindAddRole(targetMindId, new RoleBriefingComponent
|
||||||
|
{
|
||||||
|
Briefing = Loc.GetString("mindslave-briefing", ("player", args.User), ("role", jobName))
|
||||||
|
}, targetMind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMindslaveRemoved(Entity<SubdermalImplantComponent> ent, ref SubdermalImplantRemoved args)
|
||||||
|
{
|
||||||
|
if (!TryComp(args.Target, out MindSlaveComponent? mindslave))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Mind.TryGetMind(args.Target, out var mindId, out _))
|
||||||
|
{
|
||||||
|
_role.MindTryRemoveRole<RoleBriefingComponent>(mindId);
|
||||||
|
Popup.PopupEntity(Loc.GetString("mindslave-freed", ("player", mindslave.Master)), args.Target, args.Target);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemComp<MindSlaveComponent>(args.Target);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,7 +72,7 @@ public sealed class SelfHealSystem: EntitySystem
|
|||||||
// Logic to determine the whether or not to repeat the healing action
|
// Logic to determine the whether or not to repeat the healing action
|
||||||
args.Repeat = (HasDamage(component, healing) && !dontRepeat);
|
args.Repeat = (HasDamage(component, healing) && !dontRepeat);
|
||||||
if (!args.Repeat && !dontRepeat)
|
if (!args.Repeat && !dontRepeat)
|
||||||
_popupSystem.PopupEntity(Loc.GetString("self-heal-finished-using", ("verb", Loc.GetString("self-heal-lick")), ("name", uid)), uid, args.User);
|
_popupSystem.PopupEntity(Loc.GetString("self-heal-finished-using", ("name", uid)), uid, args.User);
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|
||||||
@@ -90,8 +90,8 @@ public sealed class SelfHealSystem: EntitySystem
|
|||||||
var targetString = EntityManager.ToPrettyString(uid);
|
var targetString = EntityManager.ToPrettyString(uid);
|
||||||
|
|
||||||
var healMessage = uid != args.User
|
var healMessage = uid != args.User
|
||||||
? $"{userString:user} healed {targetString:target} for {total:damage} with {Loc.GetString("self-heal-lick")}"
|
? $"{userString:user} healed {targetString:target} for {total:damage} by licking"
|
||||||
: $"{userString:user} healed themselves for {total:damage} with {Loc.GetString("self-heal-lick")}";
|
: $"{userString:user} healed themselves for {total:damage} by licking";
|
||||||
_adminLogger.Add(LogType.Healed, $"{healMessage}");
|
_adminLogger.Add(LogType.Healed, $"{healMessage}");
|
||||||
|
|
||||||
if (TryComp<SelfHealComponent>(args.User, out var selfHealComponent))
|
if (TryComp<SelfHealComponent>(args.User, out var selfHealComponent))
|
||||||
@@ -100,7 +100,7 @@ public sealed class SelfHealSystem: EntitySystem
|
|||||||
var audioParams = new AudioParams().WithVariation(2f).WithVolume(-5f);
|
var audioParams = new AudioParams().WithVariation(2f).WithVolume(-5f);
|
||||||
|
|
||||||
_audio.PlayPvs(audio, args.User, audioParams);
|
_audio.PlayPvs(audio, args.User, audioParams);
|
||||||
_popupSystem.PopupEntity(Loc.GetString("self-heal-using-other", ("name", uid), ("verb", Loc.GetString("self-heal-lick"))), uid);
|
_popupSystem.PopupEntity(Loc.GetString("self-heal-using-other", ("user", args.Args.User), ("target", uid)), uid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,8 +114,7 @@ public sealed class SelfHealSystem: EntitySystem
|
|||||||
|
|
||||||
if (!HasDamage(targetDamage, component))
|
if (!HasDamage(targetDamage, component))
|
||||||
{
|
{
|
||||||
var popup = Loc.GetString("self-heal-cant-use", ("verb", Loc.GetString("self-heal-lick")),
|
var popup = Loc.GetString("self-heal-cant-use", ("name", target));
|
||||||
("name", target));
|
|
||||||
_popupSystem.PopupEntity(popup, user, user);
|
_popupSystem.PopupEntity(popup, user, user);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -128,7 +127,7 @@ public sealed class SelfHealSystem: EntitySystem
|
|||||||
EntityManager.TryGetComponent<IngestionBlockerComponent>(blockedClothing, out var blocker) &&
|
EntityManager.TryGetComponent<IngestionBlockerComponent>(blockedClothing, out var blocker) &&
|
||||||
blocker.Enabled)
|
blocker.Enabled)
|
||||||
{
|
{
|
||||||
var popup = Loc.GetString("self-heal-cant-use-clothing", ("verb", Loc.GetString("self-heal-lick")), ("clothing", blockedClothing));
|
var popup = Loc.GetString("self-heal-cant-use-clothing", ("clothing", blockedClothing));
|
||||||
_popupSystem.PopupEntity(popup, user, user);
|
_popupSystem.PopupEntity(popup, user, user);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -141,7 +140,7 @@ public sealed class SelfHealSystem: EntitySystem
|
|||||||
{
|
{
|
||||||
if (_inventorySystem.TryGetSlotEntity(target, clothing, out var blockedClothing))
|
if (_inventorySystem.TryGetSlotEntity(target, clothing, out var blockedClothing))
|
||||||
{
|
{
|
||||||
var popup = Loc.GetString("self-heal-cant-use-clothing-other", ("verb", Loc.GetString("self-heal-lick")), ("name", target), ("clothing", blockedClothing));
|
var popup = Loc.GetString("self-heal-cant-use-clothing-other", ("name", target), ("clothing", blockedClothing));
|
||||||
_popupSystem.PopupEntity(popup, user, user);
|
_popupSystem.PopupEntity(popup, user, user);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
|
||||||
using Content.Shared.Containers.ItemSlots;
|
using Content.Shared.Containers.ItemSlots;
|
||||||
using Content.Shared.DoAfter;
|
using Content.Shared.DoAfter;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
@@ -15,24 +14,46 @@ using Robust.Shared.Utility;
|
|||||||
namespace Content.Shared.Implants;
|
namespace Content.Shared.Implants;
|
||||||
|
|
||||||
//WD EDIT START
|
//WD EDIT START
|
||||||
public class SubdermalImplantInserted
|
public sealed class SubdermalImplantInserted
|
||||||
{
|
{
|
||||||
public EntityUid Entity;
|
/// <summary>
|
||||||
|
/// Entity who implants
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid User;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entity being implanted
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid Target;
|
||||||
|
|
||||||
public SubdermalImplantComponent Component;
|
public SubdermalImplantComponent Component;
|
||||||
public SubdermalImplantInserted(EntityUid entity, SubdermalImplantComponent component)
|
|
||||||
|
public SubdermalImplantInserted(EntityUid user, EntityUid target, SubdermalImplantComponent component)
|
||||||
{
|
{
|
||||||
Entity = entity;
|
User = user;
|
||||||
|
Target = target;
|
||||||
Component = component;
|
Component = component;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SubdermalImplantRemoved
|
public sealed class SubdermalImplantRemoved
|
||||||
{
|
{
|
||||||
public EntityUid Entity;
|
/// <summary>
|
||||||
|
/// Entity who removes implant
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid User;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entity which implant is removing
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid Target;
|
||||||
|
|
||||||
public SubdermalImplantComponent Component;
|
public SubdermalImplantComponent Component;
|
||||||
public SubdermalImplantRemoved(EntityUid entity, SubdermalImplantComponent component)
|
|
||||||
|
public SubdermalImplantRemoved(EntityUid user, EntityUid target, SubdermalImplantComponent component)
|
||||||
{
|
{
|
||||||
Entity = entity;
|
User = user;
|
||||||
|
Target = target;
|
||||||
Component = component;
|
Component = component;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,10 +111,11 @@ public abstract class SharedImplanterSystem : EntitySystem
|
|||||||
|
|
||||||
if (component.ImplanterSlot.ContainerSlot != null)
|
if (component.ImplanterSlot.ContainerSlot != null)
|
||||||
_container.Remove(implant.Value, component.ImplanterSlot.ContainerSlot);
|
_container.Remove(implant.Value, component.ImplanterSlot.ContainerSlot);
|
||||||
|
|
||||||
implantComp.ImplantedEntity = target;
|
implantComp.ImplantedEntity = target;
|
||||||
implantContainer.OccludesLight = false;
|
implantContainer.OccludesLight = false;
|
||||||
_container.Insert(implant.Value, implantContainer);
|
_container.Insert(implant.Value, implantContainer);
|
||||||
RaiseLocalEvent(new SubdermalImplantInserted(implantComp.ImplantedEntity!.Value, implantComp)); //WD EDIT
|
RaiseLocalEvent(implant.Value, new SubdermalImplantInserted(user, target, implantComp)); //WD EDIT
|
||||||
|
|
||||||
if (component.CurrentMode == ImplanterToggleMode.Inject && !component.ImplantOnly)
|
if (component.CurrentMode == ImplanterToggleMode.Inject && !component.ImplantOnly)
|
||||||
DrawMode(implanter, component);
|
DrawMode(implanter, component);
|
||||||
@@ -103,7 +125,7 @@ public abstract class SharedImplanterSystem : EntitySystem
|
|||||||
var ev = new TransferDnaEvent { Donor = target, Recipient = implanter };
|
var ev = new TransferDnaEvent { Donor = target, Recipient = implanter };
|
||||||
RaiseLocalEvent(target, ref ev);
|
RaiseLocalEvent(target, ref ev);
|
||||||
|
|
||||||
Dirty(component);
|
Dirty(implanter, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanImplant(
|
public bool CanImplant(
|
||||||
@@ -146,45 +168,47 @@ public abstract class SharedImplanterSystem : EntitySystem
|
|||||||
|
|
||||||
var permanentFound = false;
|
var permanentFound = false;
|
||||||
|
|
||||||
if (_container.TryGetContainer(target, ImplanterComponent.ImplantSlotId, out var implantContainer))
|
if (!_container.TryGetContainer(target, ImplanterComponent.ImplantSlotId, out var implantContainer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var implantCompQuery = GetEntityQuery<SubdermalImplantComponent>();
|
||||||
|
|
||||||
|
foreach (var implant in implantContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
var implantCompQuery = GetEntityQuery<SubdermalImplantComponent>();
|
if (!implantCompQuery.TryGetComponent(implant, out var implantComp))
|
||||||
|
continue;
|
||||||
|
|
||||||
foreach (var implant in implantContainer.ContainedEntities)
|
//Don't remove a permanent implant and look for the next that can be drawn
|
||||||
|
if (!_container.CanRemove(implant, implantContainer))
|
||||||
{
|
{
|
||||||
if (!implantCompQuery.TryGetComponent(implant, out var implantComp))
|
var implantName = Identity.Entity(implant, EntityManager);
|
||||||
continue;
|
var targetName = Identity.Entity(target, EntityManager);
|
||||||
|
var failedPermanentMessage = Loc.GetString("implanter-draw-failed-permanent",
|
||||||
|
("implant", implantName), ("target", targetName));
|
||||||
|
|
||||||
//Don't remove a permanent implant and look for the next that can be drawn
|
_popup.PopupEntity(failedPermanentMessage, target, user);
|
||||||
if (!_container.CanRemove(implant, implantContainer))
|
|
||||||
{
|
|
||||||
var implantName = Identity.Entity(implant, EntityManager);
|
|
||||||
var targetName = Identity.Entity(target, EntityManager);
|
|
||||||
var failedPermanentMessage = Loc.GetString("implanter-draw-failed-permanent",
|
|
||||||
("implant", implantName), ("target", targetName));
|
|
||||||
_popup.PopupEntity(failedPermanentMessage, target, user);
|
|
||||||
permanentFound = implantComp.Permanent;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
_container.Remove(implant, implantContainer);
|
|
||||||
RaiseLocalEvent(new SubdermalImplantRemoved(implantComp.ImplantedEntity!.Value, implantComp)); // WD EDIT
|
|
||||||
implantComp.ImplantedEntity = null;
|
|
||||||
_container.Insert(implant, implanterContainer);
|
|
||||||
permanentFound = implantComp.Permanent;
|
permanentFound = implantComp.Permanent;
|
||||||
|
continue;
|
||||||
var ev = new TransferDnaEvent { Donor = target, Recipient = implanter };
|
|
||||||
RaiseLocalEvent(target, ref ev);
|
|
||||||
|
|
||||||
//Break so only one implant is drawn
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.CurrentMode == ImplanterToggleMode.Draw && !component.ImplantOnly && !permanentFound)
|
RaiseLocalEvent(implant, new SubdermalImplantRemoved(user, target, implantComp)); // WD EDIT
|
||||||
ImplantMode(implanter, component);
|
_container.Remove(implant, implantContainer);
|
||||||
|
|
||||||
Dirty(component);
|
implantComp.ImplantedEntity = null;
|
||||||
|
_container.Insert(implant, implanterContainer);
|
||||||
|
permanentFound = implantComp.Permanent;
|
||||||
|
|
||||||
|
var ev = new TransferDnaEvent { Donor = target, Recipient = implanter };
|
||||||
|
RaiseLocalEvent(target, ref ev);
|
||||||
|
|
||||||
|
//Break so only one implant is drawn
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (component.CurrentMode == ImplanterToggleMode.Draw && !component.ImplantOnly && !permanentFound)
|
||||||
|
ImplantMode(implanter, component);
|
||||||
|
|
||||||
|
Dirty(implanter, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImplantMode(EntityUid uid, ImplanterComponent component)
|
private void ImplantMode(EntityUid uid, ImplanterComponent component)
|
||||||
@@ -204,26 +228,24 @@ public abstract class SharedImplanterSystem : EntitySystem
|
|||||||
if (!TryComp<AppearanceComponent>(uid, out var appearance))
|
if (!TryComp<AppearanceComponent>(uid, out var appearance))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool implantFound;
|
var implantFound = component.ImplanterSlot.HasItem;
|
||||||
|
|
||||||
if (component.ImplanterSlot.HasItem)
|
switch (component.CurrentMode)
|
||||||
implantFound = true;
|
|
||||||
|
|
||||||
else
|
|
||||||
implantFound = false;
|
|
||||||
|
|
||||||
if (component.CurrentMode == ImplanterToggleMode.Inject && !component.ImplantOnly)
|
|
||||||
_appearance.SetData(uid, ImplanterVisuals.Full, implantFound, appearance);
|
|
||||||
|
|
||||||
else if (component.CurrentMode == ImplanterToggleMode.Inject && component.ImplantOnly)
|
|
||||||
{
|
{
|
||||||
_appearance.SetData(uid, ImplanterVisuals.Full, implantFound, appearance);
|
case ImplanterToggleMode.Inject when !component.ImplantOnly:
|
||||||
_appearance.SetData(uid, ImplanterImplantOnlyVisuals.ImplantOnly, component.ImplantOnly,
|
_appearance.SetData(uid, ImplanterVisuals.Full, implantFound, appearance);
|
||||||
appearance);
|
break;
|
||||||
}
|
case ImplanterToggleMode.Inject when component.ImplantOnly:
|
||||||
|
_appearance.SetData(uid, ImplanterVisuals.Full, implantFound, appearance);
|
||||||
|
_appearance.SetData(uid, ImplanterImplantOnlyVisuals.ImplantOnly, component.ImplantOnly,
|
||||||
|
appearance);
|
||||||
|
|
||||||
else
|
break;
|
||||||
_appearance.SetData(uid, ImplanterVisuals.Full, implantFound, appearance);
|
case ImplanterToggleMode.Draw:
|
||||||
|
default:
|
||||||
|
_appearance.SetData(uid, ImplanterVisuals.Full, implantFound, appearance);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem
|
|||||||
var implantContainer = implantedComp.ImplantContainer;
|
var implantContainer = implantedComp.ImplantContainer;
|
||||||
|
|
||||||
component.ImplantedEntity = target;
|
component.ImplantedEntity = target;
|
||||||
RaiseLocalEvent(new SubdermalImplantInserted(target, component));
|
RaiseLocalEvent(implant, new SubdermalImplantInserted(target, target, component));
|
||||||
_container.Insert(implant, implantContainer);
|
_container.Insert(implant, implantContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using Content.Shared.StatusIcon;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
|
namespace Content.Shared._White.Implants.Mindslave.Components;
|
||||||
|
|
||||||
|
[RegisterComponent, AutoGenerateComponentState, NetworkedComponent]
|
||||||
|
public sealed partial class MindSlaveComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
|
||||||
|
public List<NetEntity> Slaves = new();
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
|
||||||
|
public NetEntity Master;
|
||||||
|
|
||||||
|
[DataField("slaveStatusIcon", customTypeSerializer: typeof(PrototypeIdSerializer<StatusIconPrototype>))]
|
||||||
|
public string SlaveStatusIcon = "SlaveMindslaveIcon";
|
||||||
|
|
||||||
|
[DataField("masterStatusIcon", customTypeSerializer: typeof(PrototypeIdSerializer<StatusIconPrototype>))]
|
||||||
|
public string MasterStatusIcon = "MasterMindslaveIcon";
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using Content.Shared._White.Cult.Components;
|
||||||
|
using Content.Shared._White.Implants.Mindslave.Components;
|
||||||
|
using Content.Shared.Implants;
|
||||||
|
using Content.Shared.Mind;
|
||||||
|
using Content.Shared.Mind.Components;
|
||||||
|
using Content.Shared.Mindshield.Components;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Tag;
|
||||||
|
|
||||||
|
namespace Content.Shared._White.Implants.Mindslave;
|
||||||
|
|
||||||
|
public abstract class SharedMindslaveSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] protected readonly TagSystem Tag = default!;
|
||||||
|
[Dependency] protected readonly SharedMindSystem Mind = default!;
|
||||||
|
[Dependency] protected readonly SharedPopupSystem Popup = default!;
|
||||||
|
|
||||||
|
protected const string MindslaveTag = "MindSlave";
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<MindContainerComponent, AddImplantAttemptEvent>(OnTryInsertMindslave);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTryInsertMindslave(Entity<MindContainerComponent> ent, ref AddImplantAttemptEvent args)
|
||||||
|
{
|
||||||
|
if (!Tag.HasTag(args.Implant, MindslaveTag))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string message;
|
||||||
|
string wrappedMessage;
|
||||||
|
if (args.Target == args.User)
|
||||||
|
{
|
||||||
|
message = Loc.GetString("mindslave-target-self");
|
||||||
|
wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
|
||||||
|
Popup.PopupClient(wrappedMessage, args.Implanter, args.User);
|
||||||
|
args.Cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasComp<MindShieldComponent>(args.Target) ||
|
||||||
|
HasComp<MindSlaveComponent>(args.Target) ||
|
||||||
|
HasComp<CultistComponent>(args.Target) ||
|
||||||
|
HasComp<Revolutionary.Components.RevolutionaryComponent>(args.Target))
|
||||||
|
{
|
||||||
|
message = Loc.GetString("mindslave-cant-insert");
|
||||||
|
wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
|
||||||
|
Popup.PopupClient(wrappedMessage, args.Implanter, args.User);
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1871,3 +1871,46 @@
|
|||||||
id: 175
|
id: 175
|
||||||
time: '2024-03-02T09:10:00.0000000+00:00'
|
time: '2024-03-02T09:10:00.0000000+00:00'
|
||||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/160
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/160
|
||||||
|
- author: Remuchi
|
||||||
|
changes:
|
||||||
|
- message: "\u0438\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u044B \u043E\u0442\
|
||||||
|
\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0430\u043D\u0442\u0430\
|
||||||
|
\u0436\u043A\u0438, \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0438 \u043F\
|
||||||
|
\u043E\u0434\u043E\u0431\u043D\u043E\u0433\u043E \u0432 \u0430\u0445\u0435\u043B\
|
||||||
|
\u043F\u0435."
|
||||||
|
type: Fix
|
||||||
|
- message: "\u043D\u043E\u0442\u0435\u0441\u044B, \u043E\u0442\u043F\u0440\u0430\
|
||||||
|
\u0432\u043B\u044F\u0435\u043C\u044B\u0435 \u0432 \u0447\u0430\u0442, \u0431\
|
||||||
|
\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\
|
||||||
|
\u043B\u044F\u044E\u0442\u0441\u044F \u0435\u0449\u0451 \u0438 \u0432 \u043A\
|
||||||
|
\u043E\u043D\u0441\u043E\u043B\u044C."
|
||||||
|
type: Fix
|
||||||
|
- message: "\u0442\u0435\u043A\u0441\u0442\u0443\u0440\u0430 \u0441\u0435\u043A\u0440\
|
||||||
|
\u0435\u0442\u043D\u043E\u0439 \u0434\u0432\u0435\u0440\u0438 \u0431\u044B\u043B\
|
||||||
|
\u0430 \u043F\u0435\u0440\u0435\u0440\u0438\u0441\u043E\u0432\u0430\u043D\u0430\
|
||||||
|
\ \u0434\u043B\u044F \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\
|
||||||
|
\u0438\u044F \u0441 \u0430\u043A\u0442\u0443\u0430\u043B\u044C\u043D\u044B\u043C\
|
||||||
|
\u0438 \u0442\u0435\u043A\u0441\u0442\u0443\u0440\u0430\u043C\u0438 \u0441\u0442\
|
||||||
|
\u0435\u043D"
|
||||||
|
type: Fix
|
||||||
|
- message: "\u0438\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u044B \u043E\u0448\
|
||||||
|
\u0438\u0431\u043A\u0438 \u043F\u0435\u0440\u0435\u0432\u043E\u0434\u0430 \u043F\
|
||||||
|
\u0440\u0438 \u0432\u044B\u043B\u0438\u0437\u044B\u0432\u0430\u043D\u0438\u0438\
|
||||||
|
\ \u0440\u0430\u043D \u0437\u0430 \u0444\u0435\u043B\u0438\u043D\u0438\u0434\
|
||||||
|
\u0430"
|
||||||
|
type: Fix
|
||||||
|
- message: "\u043F\u0435\u0440\u0435\u0432\u043E\u0434\u044B \u0434\u043B\u044F\
|
||||||
|
\ \u0441\u0435\u043A\u0440\u0435\u0442\u043D\u043E\u0439 \u0434\u0432\u0435\u0440\
|
||||||
|
\u0438"
|
||||||
|
type: Add
|
||||||
|
id: 176
|
||||||
|
time: '2024-03-02T14:16:27.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/161
|
||||||
|
- author: Remuchi
|
||||||
|
changes:
|
||||||
|
- message: "\u0418\u043C\u043F\u043B\u0430\u043D\u0442 \u043F\u043E\u0434\u0447\u0438\
|
||||||
|
\u043D\u0435\u043D\u0438\u044F \u0432 \u0430\u043F\u043B\u0438\u043D\u043A."
|
||||||
|
type: Add
|
||||||
|
id: 177
|
||||||
|
time: '2024-03-02T14:17:52.0000000+00:00'
|
||||||
|
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/152
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
self-heal-finished-using = You have finished {$verb}ing all {$name}`s wounds
|
self-heal-finished-using = You have finished licking all {$name}`s wounds
|
||||||
self-heal-cant-use = There is no damage you can heal by {$verb}ing {$name}
|
self-heal-cant-use = There is no damage you can heal by licking {$name}
|
||||||
self-heal-stop-bleeding = They have stopped bleeding
|
self-heal-cant-use-clothing = You cant lick yourself while wearing a {$clothing}
|
||||||
self-heal-lick = lick
|
self-heal-cant-use-clothing-other = You cant lick {$name} while {$name} is wearing a {$clothing}
|
||||||
self-heal-cant-use-clothing = You cant {$verb}ing yourself while wearing a {$clothing}
|
|
||||||
self-heal-cant-use-clothing-other = You cant {$verb}ing {$name} while {$name} is wearing a {$clothing}
|
|
||||||
self-heal-action = Lick the wounds
|
self-heal-action = Lick the wounds
|
||||||
self-heal-using-other = {$name} have {$verb}ed some of {$name} wounds
|
self-heal-using-other = {$user} have licked some of {$target} wounds
|
||||||
|
|||||||
16
Resources/Locale/ru-RU/_white/implants/mindslave.ftl
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
mindslave-briefing = Служите и защищайте {$player}, {$role}. Выполняйте каждый их приказ. Они для вас - абсолютная власть.
|
||||||
|
mindslave-chat-message = Перед вашим глазами в мгновение пролетают осколки ваших воспоминаний, после чего сознание застилает белая пелена. Во вспышке ярко-красного света вы вспоминаете свое предназначение - служить {$player}, {$role}.
|
||||||
|
mindslave-freed = Вы больше не служите {$player}!
|
||||||
|
|
||||||
|
mindslave-target-self = Вы не можете сделать себя своим же рабом
|
||||||
|
mindslave-cant-insert = Разум данного существа уже на чем-то зациклен
|
||||||
|
|
||||||
|
uplink-mind-slave = Имплант подчинения
|
||||||
|
uplink-mind-slave-desc = Захватите разум живого существа и прикажите ему закидать капитана взрывными пирогами.
|
||||||
|
|
||||||
|
ent-MindSlaveImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = { "" }
|
||||||
|
.suffix = майдслейв
|
||||||
|
|
||||||
|
ent-MindslaveImplant = Имплант подчинения
|
||||||
|
.desc = Сделайте из кого-то свою личную куклу.
|
||||||
@@ -1,38 +1,28 @@
|
|||||||
ent-EggSpider = яичный паук
|
ent-EggSpider = яичный паук
|
||||||
.desc = Это драгоценный камень? Это яйцо? это выглядит дорого.
|
.desc = Это драгоценный камень? Это яйцо? это выглядит дорого.
|
||||||
ent-LampInterrogator = лампа следователя
|
ent-LampInterrogator = лампа следователя
|
||||||
.desc = Ультраяркая лампа для плохого полицейского
|
.desc = Ультраяркая лампа для плохого полицейского
|
||||||
ent-CultistCuffs = самодельные стяжки
|
ent-CultistCuffs = самодельные стяжки
|
||||||
.desc = Самодельные наручники из запасных тросов.
|
.desc = Самодельные наручники из запасных тросов.
|
||||||
ent-ParamedicIDCard = ID карта парамедика
|
ent-ParamedicIDCard = ID карта парамедика
|
||||||
.desc = { ent-IDCardStandard.desc }
|
.desc = { ent-IDCardStandard.desc }
|
||||||
ent-BrigmedicIDCard = ID карта бригмедика
|
ent-BrigmedicIDCard = ID карта бригмедика
|
||||||
.desc = { ent-IDCardStandard.desc }
|
.desc = { ent-IDCardStandard.desc }
|
||||||
ent-SeniorEngineerIDCard = ID карта бригадира
|
ent-SeniorEngineerIDCard = ID карта бригадира
|
||||||
.desc = { ent-IDCardStandard.desc }
|
.desc = { ent-IDCardStandard.desc }
|
||||||
ent-SeniorResearcherIDCard = ID карта ведущего исследователя
|
ent-SeniorResearcherIDCard = ID карта ведущего исследователя
|
||||||
.desc = { ent-IDCardStandard.desc }
|
.desc = { ent-IDCardStandard.desc }
|
||||||
ent-SeniorPhysicianIDCard = ID карта медицинского офицера
|
ent-SeniorPhysicianIDCard = ID карта медицинского офицера
|
||||||
.desc = { ent-IDCardStandard.desc }
|
.desc = { ent-IDCardStandard.desc }
|
||||||
ent-SeniorOfficerIDCard = ID карта ветерана СБ
|
ent-SeniorOfficerIDCard = ID карта ветерана СБ
|
||||||
.desc = { ent-IDCardStandard.desc }
|
.desc = { ent-IDCardStandard.desc }
|
||||||
ent-SeniorSalvageSpecialistIDCard = ID карта охотника карго
|
ent-SeniorSalvageSpecialistIDCard = ID карта охотника карго
|
||||||
.desc = { ent-IDCardStandard.desc }
|
.desc = { ent-IDCardStandard.desc }
|
||||||
ent-BikeHornImplanter = имплантат велосипедного гудка
|
|
||||||
.desc = ""
|
|
||||||
ent-UplinkImplanter = имплантат аплинка
|
|
||||||
.desc = ""
|
|
||||||
ent-EmpImplanter = ЭМИ-имплантат
|
|
||||||
.desc = ""
|
|
||||||
ent-DnaScramblerImplanter = имплантат скремблера ДНК
|
|
||||||
.desc = ""
|
|
||||||
ent-DeathRattleImplanter = имплантат предсмертных хрипов
|
|
||||||
.desc = ""
|
|
||||||
ent-ModularReceiver = модульный приемник
|
ent-ModularReceiver = модульный приемник
|
||||||
.desc = Жизненно важная часть, используемая в создании огнестрельного оружия.
|
.desc = Жизненно важная часть, используемая в создании огнестрельного оружия.
|
||||||
ent-RifleStock = приклад
|
ent-RifleStock = приклад
|
||||||
.desc = Прочный деревянный приклад, используемый при создании огнестрельного оружия.
|
.desc = Прочный деревянный приклад, используемый при создании огнестрельного оружия.
|
||||||
ent-MedalCase = футляр для медали
|
ent-MedalCase = футляр для медали
|
||||||
.desc = Футляр с медалями.
|
.desc = Футляр с медалями.
|
||||||
ent-SyndicateSpongeBox = коробка куба обезьяны
|
ent-SyndicateSpongeBox = коробка куба обезьяны
|
||||||
.desc = Обезьяньи кубики марки Drymate. Просто добавь воды!
|
.desc = Обезьяньи кубики марки Drymate. Просто добавь воды!
|
||||||
|
|||||||
@@ -20,16 +20,6 @@ ent-SpiderWeb = паутина
|
|||||||
.desc = Она тягучая и липкая.
|
.desc = Она тягучая и липкая.
|
||||||
ent-SpiderWebClown = клоунская паутина
|
ent-SpiderWebClown = клоунская паутина
|
||||||
.desc = Она тягучая и липкая.
|
.desc = Она тягучая и липкая.
|
||||||
ent-BikeHornImplant = имплантат велосипедного гудка
|
|
||||||
.desc = Этот имплантат позволяет пользователю сигналить в любом месте в любое время.
|
|
||||||
ent-UplinkImplant = имплантат аплинка
|
|
||||||
.desc = Этот имплант позволяет пользователю по желанию получить доступ к скрытому восходящему каналу Синдиката.
|
|
||||||
ent-EmpImplant = ЭМИ-имплантат
|
|
||||||
.desc = Этот имплантат создает электромагнитный импульс при активации.
|
|
||||||
ent-DnaScramblerImplant = имплантат скремблера ДНК
|
|
||||||
.desc = Этот имплантат позволяет пользователю один раз случайным образом изменить свой внешний вид и имя.
|
|
||||||
ent-DeathRattleImplant = имплантат предсмертных хрипов
|
|
||||||
.desc = Этот имплантат сообщит по радиоканалу Синдиката, если пользователь попадет в критическое состояние или умрет.
|
|
||||||
ent-FloorTileItemFlesh = пол из плоти
|
ent-FloorTileItemFlesh = пол из плоти
|
||||||
.desc = { ent-FloorTileItemBase.desc }
|
.desc = { ent-FloorTileItemBase.desc }
|
||||||
ent-AmeJar = топливный бак ДАМ'а
|
ent-AmeJar = топливный бак ДАМ'а
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
self-heal-finished-using = Вы закончили {$verb} все раны {$name}!
|
self-heal-finished-using = Вы закончили вылизывать все раны {$name}!
|
||||||
self-heal-cant-use = {$name} не имеет ран, которые вы могли бы {$verb}
|
self-heal-cant-use = {$name} не имеет ран, которые вы могли бы вылизать
|
||||||
self-heal-stop-bleeding = Оно перестало кровоточить
|
self-heal-cant-use-clothing = Вы не можете вылизываться, пока на вас {$clothing}
|
||||||
self-heal-lick = вылизывать
|
self-heal-cant-use-clothing-other = Вы не можете вылизать {$name}, пока {$name} носит {$clothing}
|
||||||
self-heal-cant-use-clothing = Вы не можете {$verb}, пока на вас {$clothing}
|
|
||||||
self-heal-cant-use-clothing-other = Вы не можете {$verb} {$name}, пока {$name} носит {$clothing}
|
|
||||||
self-heal-action = Зализать раны
|
self-heal-action = Зализать раны
|
||||||
self-heal-using-other = {$name} закончил {$verb} часть {$name} ран
|
self-heal-using-other = {$user} вылизывает часть ран {$target}
|
||||||
ent-SelfHealAction = Зализать раны
|
ent-SelfHealAction = Зализать раны
|
||||||
|
|||||||
@@ -1,33 +1,54 @@
|
|||||||
ent-BaseImplanter = имплантер
|
ent-BaseImplanter = имплантер
|
||||||
.desc = Специальный шприц, используемый только для имплантов.
|
.desc = Специальный шприц, используемый только для имплантов.
|
||||||
.suffix = { "" }
|
|
||||||
ent-Implanter = { ent-BaseImplanter }
|
ent-Implanter = { ent-BaseImplanter }
|
||||||
.desc = { ent-BaseImplanter.desc }
|
.desc = { ent-BaseImplanter.desc }
|
||||||
.suffix = { "" }
|
|
||||||
ent-BaseImplantOnlyImplanter = { ent-Implanter }
|
ent-BaseImplantOnlyImplanter = { ent-Implanter }
|
||||||
.desc = Одноразовый имплантер.
|
.desc = Одноразовый имплантер.
|
||||||
.suffix = { "" }
|
ent-SadTromboneImplanter = { ent-BaseImplanter }
|
||||||
ent-SadTromboneImplanter = имплантер Грустный тромбон
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий имплант, который проигрывает грустную мелодию при смерти владельца.
|
.suffix = грустный тромбон
|
||||||
.suffix = { "" }
|
ent-LightImplanter = { ent-BaseImplanter }
|
||||||
ent-LightImplanter = имплантер Свет
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий имплант, который излучает свет при активации.
|
.suffix = свет
|
||||||
.suffix = { "" }
|
ent-TrackingImplanter = { ent-BaseImplanter }
|
||||||
ent-TrackingImplanter = имплантер Отслеживание
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий имплант, постоянно передающий координаты владельца.
|
.suffix = отслеживание
|
||||||
.suffix = { "" }
|
ent-StorageImplanter = { ent-BaseImplanter }
|
||||||
ent-StorageImplanter = имплантер Хранилище
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий имплант, создающий хранилище в теле владельца.
|
.suffix = хранилище
|
||||||
.suffix = { "" }
|
ent-FreedomImplanter = { ent-BaseImplanter }
|
||||||
ent-FreedomImplanter = имплантер Свобода
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий имплант, позволяющий владельцу три раза освободиться от наручников и других ограничителей.
|
.suffix = свобода
|
||||||
.suffix = { "" }
|
ent-MicroBombImplanter = { ent-BaseImplanter }
|
||||||
ent-MicroBombImplanter = имплантер Микробомба
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий неизвлекаемый имплант, вызывающий небольшой взрыв при смерти владельца.
|
.suffix = микробомба
|
||||||
.suffix = { "" }
|
ent-MacroBombImplanter = { ent-BaseImplanter }
|
||||||
ent-MacroBombImplanter = имплантер Макробомба
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий имплант, вызывающий мощный взрыв при смерти владельца по истечении заданного времени.
|
.suffix = макробомба
|
||||||
.suffix = { "" }
|
ent-MindShieldImplanter = { ent-BaseImplanter }
|
||||||
ent-MindshieldImplanter = имплантер Защиты Разума
|
.desc = {""}
|
||||||
.desc = Одноразовый имплантер, содержащий имплант защиты разума.
|
.suffix = защита разума
|
||||||
.suffix = { "" }
|
ent-BikeHornImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = велосипедный гудок
|
||||||
|
ent-UplinkImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = аплинк
|
||||||
|
ent-EmpImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = ЭМИ
|
||||||
|
ent-DnaScramblerImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = скремблер ДНК
|
||||||
|
ent-DeathRattleImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = предсмертный хрип
|
||||||
|
ent-ScramImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = переброска
|
||||||
|
ent-DeathAcidifierImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = посмертный растворитель
|
||||||
|
ent-ImplanterAdmeme = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = адмемы
|
||||||
|
|||||||
@@ -25,3 +25,13 @@ ent-MacroBombImplant = имплант Макробомба
|
|||||||
ent-MindShieldImplant = имплант Защиты Разума
|
ent-MindShieldImplant = имплант Защиты Разума
|
||||||
.desc = Маленький имплант, который защищает мозги носителя от промывки.
|
.desc = Маленький имплант, который защищает мозги носителя от промывки.
|
||||||
.suffix = { "" }
|
.suffix = { "" }
|
||||||
|
ent-BikeHornImplant = имплант велосипедного гудка
|
||||||
|
.desc = Этот имплантат позволяет пользователю сигналить в любом месте в любое время.
|
||||||
|
ent-UplinkImplant = имплант аплинка
|
||||||
|
.desc = Этот имплант позволяет пользователю по желанию получить доступ к скрытому восходящему каналу Синдиката.
|
||||||
|
ent-EmpImplant = ЭМИ-имплант
|
||||||
|
.desc = Этот имплантат создает электромагнитный импульс при активации.
|
||||||
|
ent-DnaScramblerImplant = имплант скремблера ДНК
|
||||||
|
.desc = Этот имплантат позволяет пользователю один раз случайным образом изменить свой внешний вид и имя.
|
||||||
|
ent-DeathRattleImplant = имплант предсмертных хрипов
|
||||||
|
.desc = Этот имплантат сообщит по радиоканалу Синдиката, если пользователь попадет в критическое состояние или умрет.
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
ent-BaseSecretDoor = { ent-WallSolid }
|
||||||
|
.desc = { ent-WallSolid.desc }
|
||||||
|
.suffix = секретная дверь
|
||||||
|
|
||||||
|
ent-BaseSecretDoorAssembly = каркас секретной двери
|
||||||
|
.desc = Она открывается, закрывается, и даже может вас раздавить!
|
||||||
|
|
||||||
|
ent-SolidSecretDoor = { ent-BaseSecretDoor }
|
||||||
|
.desc = { ent-WallSolid.desc }
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ uplink-freedom-implanter-name = Имплант свободы
|
|||||||
uplink-freedom-implanter-desc = Убирайся подальше от этих мерзких офицеров с этим имплантатом!
|
uplink-freedom-implanter-desc = Убирайся подальше от этих мерзких офицеров с этим имплантатом!
|
||||||
|
|
||||||
uplink-scram-implanter-name = Имплант переброски
|
uplink-scram-implanter-name = Имплант переброски
|
||||||
uplink-scram-implanter-desc = Имплантат 2-го использования, который телепортирует вас в большом радиусе. Пытается телепортировать вас в пустое пространство. Иногда может не справиться. Страхование жизни не предусмотрено.
|
uplink-scram-implanter-desc = Имплант 2-го использования, который телепортирует вас в большом радиусе. Пытается телепортировать вас в пустое пространство. Иногда может не справиться. Страхование жизни не предусмотрено.
|
||||||
|
|
||||||
uplink-dna-scrambler-implanter-name = Имплант скремблера ДНК
|
uplink-dna-scrambler-implanter-name = Имплант скремблера ДНК
|
||||||
uplink-dna-scrambler-implanter-desc = Одноразовый имплантат, который можно активировать, чтобы изменить вашу ДНК и придать вам совершенно новый вид, также имеет функцию отмены изменений. Невозможно зашифровать уже зашифрованную ДНК.
|
uplink-dna-scrambler-implanter-desc = Одноразовый имплантат, который можно активировать, чтобы изменить вашу ДНК и придать вам совершенно новый вид, также имеет функцию отмены изменений. Невозможно зашифровать уже зашифрованную ДНК.
|
||||||
@@ -198,10 +198,10 @@ uplink-uplink-implanter-desc = Незаметно заказывайте обо
|
|||||||
uplink-deathrattle-implant-name = Коробка имплантатов предсмертного хрипа
|
uplink-deathrattle-implant-name = Коробка имплантатов предсмертного хрипа
|
||||||
uplink-deathrattle-implant-desc = Коробка с достаточным количеством предсмертных хрипов для всего отряда. Передает сообщение, содержащее вашу позицию, на канал синдиката, когда вы переходите в критическое состояние или умираете.
|
uplink-deathrattle-implant-desc = Коробка с достаточным количеством предсмертных хрипов для всего отряда. Передает сообщение, содержащее вашу позицию, на канал синдиката, когда вы переходите в критическое состояние или умираете.
|
||||||
|
|
||||||
uplink-death-acidifier-implant-name = Имплантат расплавления
|
uplink-death-acidifier-implant-name = Имплантер расплавления
|
||||||
uplink-death-acidifier-implant-desc = Полностью расплавляет пользователя и его снаряжение при использовании или смерти.
|
uplink-death-acidifier-implant-desc = Полностью расплавляет пользователя и его снаряжение при использовании или смерти.
|
||||||
|
|
||||||
uplink-micro-bomb-implanter-name = Имплантатор микро-бомбы
|
uplink-micro-bomb-implanter-name = Имплантер микро-бомбы
|
||||||
uplink-micro-bomb-implanter-desc = Взорвитесь при смерти или ручной активации с помощью этого имплантата. Уничтожает тело со всем снаряжением.
|
uplink-micro-bomb-implanter-desc = Взорвитесь при смерти или ручной активации с помощью этого имплантата. Уничтожает тело со всем снаряжением.
|
||||||
|
|
||||||
# Bundles
|
# Bundles
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
hardlight-spear-pickup-failed = Вы не можете подобрать световое копьё.
|
hardlight-spear-pickup-failed = Вы не можете подобрать световое копьё.
|
||||||
use-hardlight-spear-implant-action-name = Создать световое копьё.
|
use-hardlight-spear-implant-action-name = Создать световое копьё.
|
||||||
use-hardlight-spear-implant-action-description = Создает световое копьё в ваших руках.
|
use-hardlight-spear-implant-action-description = Создает световое копьё в ваших руках.
|
||||||
uplink-hardlight-spear-implant-name = Имплантатор световое копьё
|
uplink-hardlight-spear-implant-name = Имплантер световое копьё
|
||||||
uplink-hardlight-spear-implant-desc = Имплант, вводимый в тело и активируемый по желанию пользователя. Он вызывает копье из твердого света, с помощью которого пользователь может сеять хаос.
|
uplink-hardlight-spear-implant-desc = Имплант, вводимый в тело и активируемый по желанию пользователя. Он вызывает копье из твердого света, с помощью которого пользователь может сеять хаос.
|
||||||
|
|
||||||
ent-SpearHardlight = световое копьё
|
ent-SpearHardlight = световое копьё
|
||||||
.desc = Копьё из твердого света.
|
.desc = Копьё из твердого света.
|
||||||
|
|
||||||
ent-HardlightSpearImplanter = имплантатор световое копьё
|
ent-HardlightSpearImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = световое копьё
|
||||||
|
|
||||||
ent-HardlightSpearImplant = имплант световое копьё
|
ent-HardlightSpearImplant = имплант световое копьё
|
||||||
.desc = Этот имплант создаёт световое копьё в ваших руках.
|
.desc = Этот имплант создаёт световое копьё в ваших руках.
|
||||||
|
|
||||||
|
ent-SmokeImplanter = { ent-BaseImplanter }
|
||||||
|
.desc = {""}
|
||||||
|
.suffix = дым
|
||||||
|
|||||||
@@ -124,24 +124,24 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: SadTromboneImplanter
|
id: SadTromboneImplanter
|
||||||
name: sad trombone implanter
|
|
||||||
parent: BaseImplantOnlyImplanter
|
parent: BaseImplantOnlyImplanter
|
||||||
|
suffix: sad trombone
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: SadTromboneImplant
|
implant: SadTromboneImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: LightImplanter
|
id: LightImplanter
|
||||||
name: light implanter
|
|
||||||
parent: BaseImplantOnlyImplanter
|
parent: BaseImplantOnlyImplanter
|
||||||
|
suffix: light
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: LightImplant
|
implant: LightImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: BikeHornImplanter
|
id: BikeHornImplanter
|
||||||
name: bike horn implanter
|
|
||||||
parent: BaseImplantOnlyImplanter
|
parent: BaseImplantOnlyImplanter
|
||||||
|
suffix: bike horn
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: BikeHornImplant
|
implant: BikeHornImplant
|
||||||
@@ -150,8 +150,8 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: TrackingImplanter
|
id: TrackingImplanter
|
||||||
name: tracking implanter
|
|
||||||
parent: BaseImplantOnlyImplanter
|
parent: BaseImplantOnlyImplanter
|
||||||
|
suffix: tracking
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: TrackingImplant
|
implant: TrackingImplant
|
||||||
@@ -160,24 +160,24 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: StorageImplanter
|
id: StorageImplanter
|
||||||
name: storage implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: storage
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: StorageImplant
|
implant: StorageImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: FreedomImplanter
|
id: FreedomImplanter
|
||||||
name: freedom implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: freedom
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: FreedomImplant
|
implant: FreedomImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: UplinkImplanter
|
id: UplinkImplanter
|
||||||
name: uplink implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: uplink
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: UplinkImplant
|
implant: UplinkImplant
|
||||||
@@ -185,24 +185,24 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: EmpImplanter
|
id: EmpImplanter
|
||||||
name: EMP implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: EMP
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: EmpImplant
|
implant: EmpImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ScramImplanter
|
id: ScramImplanter
|
||||||
name: scram implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: scram
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: ScramImplant
|
implant: ScramImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: DnaScramblerImplanter
|
id: DnaScramblerImplanter
|
||||||
name: DNA scrambler implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: DNA scrambler
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: DnaScramblerImplant
|
implant: DnaScramblerImplant
|
||||||
@@ -211,32 +211,32 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: MicroBombImplanter
|
id: MicroBombImplanter
|
||||||
name: micro-bomb implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: micro-bomb
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: MicroBombImplant
|
implant: MicroBombImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: MacroBombImplanter
|
id: MacroBombImplanter
|
||||||
name: macro-bomb implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: macro-bomb
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: MacroBombImplant
|
implant: MacroBombImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: DeathRattleImplanter
|
id: DeathRattleImplanter
|
||||||
name: death rattle implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: death rattle
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: DeathRattleImplant
|
implant: DeathRattleImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: DeathAcidifierImplanter
|
id: DeathAcidifierImplanter
|
||||||
name: death acidifier implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: death acidifier
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: DeathAcidifierImplant
|
implant: DeathAcidifierImplant
|
||||||
@@ -245,8 +245,8 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: MindShieldImplanter
|
id: MindShieldImplanter
|
||||||
name: mind-shield implanter
|
|
||||||
parent: BaseImplantOnlyImplanter
|
parent: BaseImplantOnlyImplanter
|
||||||
|
suffix: mind-shield
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: MindShieldImplant
|
implant: MindShieldImplant
|
||||||
|
|||||||
@@ -204,3 +204,13 @@
|
|||||||
Telecrystal: 1
|
Telecrystal: 1
|
||||||
categories:
|
categories:
|
||||||
- UplinkAmmo
|
- UplinkAmmo
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkMindSlaveImplanter
|
||||||
|
name: uplink-mind-slave
|
||||||
|
description: uplink-mind-slave-desc
|
||||||
|
productEntity: MindSlaveImplanter
|
||||||
|
cost:
|
||||||
|
Telecrystal: 6
|
||||||
|
categories:
|
||||||
|
- UplinkImplants
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: SmokeImplanter
|
id: SmokeImplanter
|
||||||
name: имплант дыма
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: smoke
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: SmokeImplant
|
implant: SmokeImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: HardlightSpearImplanter
|
id: HardlightSpearImplanter
|
||||||
name: hardlight spear implanter
|
|
||||||
parent: BaseImplantOnlyImplanterSyndi
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: hardlight spear
|
||||||
components:
|
components:
|
||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: HardlightSpearImplant
|
implant: HardlightSpearImplant
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: MindSlaveImplanter
|
||||||
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
suffix: mindslave
|
||||||
|
components:
|
||||||
|
- type: Implanter
|
||||||
|
implant: MindslaveImplant
|
||||||
|
|||||||
@@ -23,3 +23,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: SubdermalImplant
|
- type: SubdermalImplant
|
||||||
implantAction: ActivateHardlightSpearImplant
|
implantAction: ActivateHardlightSpearImplant
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseSubdermalImplant
|
||||||
|
id: MindslaveImplant
|
||||||
|
name: mindslave implant
|
||||||
|
description: Make someone a proper doll for your use.
|
||||||
|
noSpawn: true
|
||||||
|
components:
|
||||||
|
- type: SubdermalImplant
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- MindSlave
|
||||||
|
|
||||||
|
|||||||
@@ -51,3 +51,6 @@
|
|||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: WeldedKnife
|
id: WeldedKnife
|
||||||
|
|
||||||
|
- type: Tag
|
||||||
|
id: MindSlave
|
||||||
|
|||||||
15
Resources/Prototypes/_White/StatusIcon/mindslave.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
- type: statusIcon
|
||||||
|
id: MasterMindslaveIcon
|
||||||
|
priority: 3
|
||||||
|
locationPreference: Left
|
||||||
|
icon:
|
||||||
|
sprite: /Textures/White/Overlays/mindslave.rsi
|
||||||
|
state: master
|
||||||
|
|
||||||
|
- type: statusIcon
|
||||||
|
id: SlaveMindslaveIcon
|
||||||
|
priority: 3
|
||||||
|
locationPreference: Left
|
||||||
|
icon:
|
||||||
|
sprite: /Textures/White/Overlays/mindslave.rsi
|
||||||
|
state: slave
|
||||||
|
Before Width: | Height: | Size: 305 B After Width: | Height: | Size: 859 B |
|
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 772 B |
|
Before Width: | Height: | Size: 530 B After Width: | Height: | Size: 2.9 KiB |
BIN
Resources/Textures/White/Overlays/mindslave.rsi/master.png
Normal file
|
After Width: | Height: | Size: 260 B |
17
Resources/Textures/White/Overlays/mindslave.rsi/meta.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "@JustNemo",
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "slave"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "master"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Resources/Textures/White/Overlays/mindslave.rsi/slave.png
Normal file
|
After Width: | Height: | Size: 251 B |