Merge remote-tracking branch 'WD-core/master' into upstream-5
@@ -1,5 +1,6 @@
|
||||
using Content.Shared._White.Mood;
|
||||
using Content.Shared.Dataset;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.NPC.Prototypes;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Roles;
|
||||
@@ -34,7 +35,25 @@ public sealed partial class TraitorRuleComponent : Component
|
||||
|
||||
[DataField]
|
||||
public ProtoId<DatasetPrototype> ObjectiveIssuers = "TraitorCorporations";
|
||||
// WD EDIT START AHEAD OF WIZDEN UPSTREAM
|
||||
/// <summary>
|
||||
/// Give this traitor an Uplink on spawn.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool GiveUplink = true;
|
||||
|
||||
/// <summary>
|
||||
/// Give this traitor the codewords.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool GiveCodewords = true;
|
||||
|
||||
/// <summary>
|
||||
/// Give this traitor a briefing in chat.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool GiveBriefing = true;
|
||||
// WD EDIT END AHEAD OF WIZDEN UPSTREAM
|
||||
// WD edit start
|
||||
[DataField]
|
||||
public ProtoId<MoodEffectPrototype> MoodBuffEffect = "TraitorFocused";
|
||||
@@ -77,7 +96,7 @@ public sealed partial class TraitorRuleComponent : Component
|
||||
/// The amount of TC traitors start with.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int StartingBalance = 20;
|
||||
public FixedPoint2 StartingBalance = 20; // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
|
||||
[DataField]
|
||||
public int MaxDifficulty = 5;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.Objectives;
|
||||
using Content.Server.PDA.Ringer;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.Traitor.Uplink;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.NPC.Systems;
|
||||
using Content.Shared.Objectives.Components;
|
||||
@@ -74,7 +75,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
}
|
||||
}
|
||||
|
||||
public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveUplink = true, bool giveObjectives = true)
|
||||
public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool giveObjectives = true) // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
{
|
||||
//Grab the mind if it wasnt provided
|
||||
if (!_mindSystem.TryGetMind(traitor, out var mindId, out var mind))
|
||||
@@ -83,39 +84,46 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
// WD START
|
||||
var richAspect = _gameTicker.GetActiveGameRules().Where(HasComp<TraitorRichAspectComponent>).Any();
|
||||
// WD END
|
||||
// WD EDIT START AHEAD OF WIZDEN UPSTREAM
|
||||
var briefing = "";
|
||||
|
||||
var briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords)));
|
||||
if (component.GiveCodewords)
|
||||
briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords)));
|
||||
// WD EDIT END AHEAD OF WIZDEN UPSTREAM
|
||||
var issuer = _random.Pick(_prototypeManager.Index(component.ObjectiveIssuers).Values);
|
||||
|
||||
Note[]? code = null;
|
||||
if (giveUplink)
|
||||
if (component.GiveUplink) // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
{
|
||||
// Calculate the amount of currency on the uplink.
|
||||
var startingBalance = component.StartingBalance;
|
||||
if (_jobs.MindTryGetJob(mindId, out _, out var prototype))
|
||||
startingBalance = Math.Max(startingBalance - prototype.AntagAdvantage, 0);
|
||||
// WD EDIT START START AHEAD OF WIZDEN UPSTREAM
|
||||
{
|
||||
if (startingBalance < prototype.AntagAdvantage) // Can't use Math functions on FixedPoint2
|
||||
startingBalance = 0;
|
||||
else
|
||||
startingBalance = startingBalance - prototype.AntagAdvantage;
|
||||
}
|
||||
|
||||
if (richAspect)
|
||||
{
|
||||
startingBalance += 10;
|
||||
}
|
||||
|
||||
// creadth: we need to create uplink for the antag.
|
||||
// PDA should be in place already
|
||||
var pda = _uplink.FindUplinkTarget(traitor);
|
||||
if (pda == null || !_uplink.AddUplink(traitor, startingBalance))
|
||||
return false;
|
||||
|
||||
// Give traitors their codewords and uplink code to keep in their character info menu
|
||||
code = EnsureComp<RingerUplinkComponent>(pda.Value).Code;
|
||||
|
||||
// If giveUplink is false the uplink code part is omitted
|
||||
briefing = string.Format("{0}\n{1}", briefing,
|
||||
Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#"))));
|
||||
// Choose and generate an Uplink, and return the uplink code if applicable
|
||||
var uplinkParams = RequestUplink(traitor, startingBalance, briefing);
|
||||
code = uplinkParams.Item1;
|
||||
briefing = uplinkParams.Item2;
|
||||
}
|
||||
|
||||
_antag.SendBriefing(traitor, GenerateBriefing(component.Codewords, code, issuer), null, component.GreetSoundNotification);
|
||||
string[]? codewords = null;
|
||||
if (component.GiveCodewords)
|
||||
codewords = component.Codewords;
|
||||
|
||||
if (component.GiveBriefing)
|
||||
_antag.SendBriefing(traitor, GenerateBriefing(codewords, code, issuer), null, component.GreetSoundNotification);
|
||||
// WD EDIT END AHEAD OF WIZDEN UPSTREAM
|
||||
component.TraitorMinds.Add(mindId);
|
||||
|
||||
// Assign briefing
|
||||
@@ -146,7 +154,33 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
|
||||
return true;
|
||||
}
|
||||
// WD EDIT START AHEAD OF WIZDEN UPSTREAM
|
||||
private (Note[]?, string) RequestUplink(EntityUid traitor, FixedPoint2 startingBalance, string briefing)
|
||||
{
|
||||
var pda = _uplink.FindUplinkTarget(traitor);
|
||||
Note[]? code = null;
|
||||
|
||||
var uplinked = _uplink.AddUplink(traitor, startingBalance, pda, true);
|
||||
|
||||
if (pda is not null && uplinked)
|
||||
{
|
||||
// Codes are only generated if the uplink is a PDA
|
||||
code = EnsureComp<RingerUplinkComponent>(pda.Value).Code;
|
||||
|
||||
// If giveUplink is false the uplink code part is omitted
|
||||
briefing = string.Format("{0}\n{1}",
|
||||
briefing,
|
||||
Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", code).Replace("sharp", "#"))));
|
||||
return (code, briefing);
|
||||
}
|
||||
else if (pda is null && uplinked)
|
||||
{
|
||||
briefing += "\n" + Loc.GetString("traitor-role-uplink-implant-short");
|
||||
}
|
||||
|
||||
return (null, briefing);
|
||||
}
|
||||
// WD EDIT END AHEAD OF WIZDEN UPSTREAM
|
||||
private void OnObjectivesTextGetInfo(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextGetInfoEvent args)
|
||||
{
|
||||
args.Minds = _antag.GetAntagMindEntityUids(uid);
|
||||
@@ -158,13 +192,16 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
args.Text += "\n" + Loc.GetString("traitor-round-end-codewords", ("codewords", string.Join(", ", comp.Codewords)));
|
||||
}
|
||||
|
||||
private string GenerateBriefing(string[] codewords, Note[]? uplinkCode, string? objectiveIssuer = null)
|
||||
private string GenerateBriefing(string[]? codewords, Note[]? uplinkCode, string? objectiveIssuer = null)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(Loc.GetString("traitor-role-greeting", ("corporation", objectiveIssuer ?? Loc.GetString("objective-issuer-unknown"))));
|
||||
sb.AppendLine(Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", codewords))));
|
||||
if (codewords != null) // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
sb.AppendLine(Loc.GetString("traitor-role-codewords", ("codewords", string.Join(", ", codewords))));
|
||||
if (uplinkCode != null)
|
||||
sb.AppendLine(Loc.GetString("traitor-role-uplink-code-short", ("code", string.Join("-", uplinkCode).Replace("sharp", "#"))));
|
||||
else // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
sb.AppendLine(Loc.GetString("traitor-role-uplink-implant"));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server.Traitor.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Traitor.Components;
|
||||
|
||||
@@ -9,14 +10,8 @@ namespace Content.Server.Traitor.Components;
|
||||
public sealed partial class AutoTraitorComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether to give the traitor an uplink or not.
|
||||
/// The traitor profile to use
|
||||
/// </summary>
|
||||
[DataField("giveUplink"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool GiveUplink = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to give the traitor objectives or not.
|
||||
/// </summary>
|
||||
[DataField("giveObjectives"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool GiveObjectives = true;
|
||||
[DataField]
|
||||
public EntProtoId Profile = "Traitor"; // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@ public sealed class AutoTraitorSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AntagSelectionSystem _antag = default!;
|
||||
|
||||
[ValidatePrototypeId<EntityPrototype>]
|
||||
private const string DefaultTraitorRule = "Traitor";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -24,6 +21,6 @@ public sealed class AutoTraitorSystem : EntitySystem
|
||||
|
||||
private void OnMindAdded(EntityUid uid, AutoTraitorComponent comp, MindAddedMessage args)
|
||||
{
|
||||
_antag.ForceMakeAntag<AutoTraitorComponent>(args.Mind.Comp.Session, DefaultTraitorRule);
|
||||
_antag.ForceMakeAntag<AutoTraitorComponent>(args.Mind.Comp.Session, comp.Profile); // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
}
|
||||
}
|
||||
|
||||
7
Content.Server/Traitor/Uplink/UplinkComponent.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Content.Server.Traitor.Uplink;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for identifying something as a hidden uplink and showing the UI.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class UplinkComponent : Component;
|
||||
@@ -1,94 +1,130 @@
|
||||
using Content.Server.Store.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Implants;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Store;
|
||||
using Content.Server.Store.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Traitor.Uplink
|
||||
namespace Content.Server.Traitor.Uplink;
|
||||
|
||||
public sealed class UplinkSystem : EntitySystem // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
{
|
||||
public sealed class UplinkSystem : EntitySystem
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly StoreSystem _store = default!;
|
||||
[Dependency] private readonly SharedSubdermalImplantSystem _subdermalImplant = default!;
|
||||
|
||||
[ValidatePrototypeId<CurrencyPrototype>]
|
||||
public const string TelecrystalCurrencyPrototype = "Telecrystal";
|
||||
private const string FallbackUplinkImplant = "UplinkImplant";
|
||||
private const string FallbackUplinkCatalog = "UplinkUplinkImplanter";
|
||||
|
||||
/// <summary>
|
||||
/// Adds an uplink to the target
|
||||
/// </summary>
|
||||
/// <param name="user">The person who is getting the uplink</param>
|
||||
/// <param name="balance">The amount of currency on the uplink. If null, will just use the amount specified in the preset.</param>
|
||||
/// <param name="uplinkEntity">The entity that will actually have the uplink functionality. Defaults to the PDA if null.</param>
|
||||
/// <param name="giveDiscounts">Marker that enables discounts for uplink items.</param>
|
||||
/// <returns>Whether or not the uplink was added successfully</returns>
|
||||
public bool AddUplink(
|
||||
EntityUid user,
|
||||
FixedPoint2 balance,
|
||||
EntityUid? uplinkEntity = null,
|
||||
bool giveDiscounts = false)
|
||||
{
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly StoreSystem _store = default!;
|
||||
// Try to find target item if none passed
|
||||
uplinkEntity ??= FindUplinkTarget(user);
|
||||
if (uplinkEntity == null)
|
||||
return ImplantUplink(user, balance, giveDiscounts);
|
||||
|
||||
[ValidatePrototypeId<CurrencyPrototype>]
|
||||
public const string TelecrystalCurrencyPrototype = "Telecrystal";
|
||||
EnsureComp<UplinkComponent>(uplinkEntity.Value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of TC on an "uplink"
|
||||
/// Mostly just here for legacy systems based on uplink.
|
||||
/// </summary>
|
||||
/// <param name="component"></param>
|
||||
/// <returns>the amount of TC</returns>
|
||||
public int GetTCBalance(StoreComponent component)
|
||||
SetUplink(user, uplinkEntity.Value, balance, giveDiscounts);
|
||||
|
||||
// TODO add BUI. Currently can't be done outside of yaml -_-
|
||||
// ^ What does this even mean?
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure TC for the uplink
|
||||
/// </summary>
|
||||
private void SetUplink(EntityUid user, EntityUid uplink, FixedPoint2 balance, bool giveDiscounts)
|
||||
{
|
||||
var store = EnsureComp<StoreComponent>(uplink);
|
||||
store.AccountOwner = user;
|
||||
_store.InitializeFromPreset("StorePresetUplink", uplink, store); // WD
|
||||
store.Balance.Clear();
|
||||
_store.TryAddCurrency(new Dictionary<string, FixedPoint2> { { TelecrystalCurrencyPrototype, balance } },
|
||||
uplink,
|
||||
store);
|
||||
// WD REMOVED UNTIL PROPER UPSTREAM
|
||||
// var uplinkInitializedEvent = new StoreInitializedEvent(
|
||||
// TargetUser: user,
|
||||
// Store: uplink,
|
||||
// UseDiscounts: giveDiscounts,
|
||||
// Listings: _store.GetAvailableListings(user, uplink, store)
|
||||
// .ToArray());
|
||||
// RaiseLocalEvent(ref uplinkInitializedEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implant an uplink as a fallback measure if the traitor had no PDA
|
||||
/// </summary>
|
||||
private bool ImplantUplink(EntityUid user, FixedPoint2 balance, bool giveDiscounts)
|
||||
{
|
||||
var implantProto = new string(FallbackUplinkImplant);
|
||||
|
||||
if (!_proto.TryIndex<ListingPrototype>(FallbackUplinkCatalog, out var catalog))
|
||||
return false;
|
||||
|
||||
if (!catalog.Cost.TryGetValue(TelecrystalCurrencyPrototype, out var cost))
|
||||
return false;
|
||||
|
||||
if (balance < cost) // Can't use Math functions on FixedPoint2
|
||||
balance = 0;
|
||||
else
|
||||
balance = balance - cost;
|
||||
|
||||
var implant = _subdermalImplant.AddImplant(user, implantProto);
|
||||
|
||||
if (!HasComp<StoreComponent>(implant))
|
||||
return false;
|
||||
|
||||
SetUplink(user, implant.Value, balance, giveDiscounts);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the entity that can hold an uplink for a user.
|
||||
/// Usually this is a pda in their pda slot, but can also be in their hands. (but not pockets or inside bag, etc.)
|
||||
/// </summary>
|
||||
public EntityUid? FindUplinkTarget(EntityUid user)
|
||||
{
|
||||
// Try to find PDA in inventory
|
||||
if (_inventorySystem.TryGetContainerSlotEnumerator(user, out var containerSlotEnumerator))
|
||||
{
|
||||
FixedPoint2? tcBalance = component.Balance.GetValueOrDefault(TelecrystalCurrencyPrototype);
|
||||
return tcBalance?.Int() ?? 0;
|
||||
while (containerSlotEnumerator.MoveNext(out var pdaUid))
|
||||
{
|
||||
if (!pdaUid.ContainedEntity.HasValue)
|
||||
continue;
|
||||
if (HasComp<PdaComponent>(pdaUid.ContainedEntity.Value) || HasComp<StoreComponent>(pdaUid.ContainedEntity.Value))
|
||||
return pdaUid.ContainedEntity.Value;
|
||||
}
|
||||
}
|
||||
// Also check hands
|
||||
foreach (var item in _handsSystem.EnumerateHeld(user))
|
||||
{
|
||||
if (HasComp<PdaComponent>(item) || HasComp<StoreComponent>(item))
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an uplink to the target
|
||||
/// </summary>
|
||||
/// <param name="user">The person who is getting the uplink</param>
|
||||
/// <param name="balance">The amount of currency on the uplink. If null, will just use the amount specified in the preset.</param>
|
||||
/// <param name="uplinkPresetId">The id of the storepreset</param>
|
||||
/// <param name="uplinkEntity">The entity that will actually have the uplink functionality. Defaults to the PDA if null.</param>
|
||||
/// <returns>Whether or not the uplink was added successfully</returns>
|
||||
public bool AddUplink(EntityUid user, FixedPoint2? balance, string uplinkPresetId = "StorePresetUplink", EntityUid? uplinkEntity = null)
|
||||
{
|
||||
// Try to find target item
|
||||
if (uplinkEntity == null)
|
||||
{
|
||||
uplinkEntity = FindUplinkTarget(user);
|
||||
if (uplinkEntity == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
var store = EnsureComp<StoreComponent>(uplinkEntity.Value);
|
||||
_store.InitializeFromPreset(uplinkPresetId, uplinkEntity.Value, store);
|
||||
store.AccountOwner = user;
|
||||
store.Balance.Clear();
|
||||
|
||||
if (balance != null)
|
||||
{
|
||||
store.Balance.Clear();
|
||||
_store.TryAddCurrency(new Dictionary<string, FixedPoint2> { { TelecrystalCurrencyPrototype, balance.Value } }, uplinkEntity.Value, store);
|
||||
}
|
||||
|
||||
// TODO add BUI. Currently can't be done outside of yaml -_-
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the entity that can hold an uplink for a user.
|
||||
/// Usually this is a pda in their pda slot, but can also be in their hands. (but not pockets or inside bag, etc.)
|
||||
/// </summary>
|
||||
public EntityUid? FindUplinkTarget(EntityUid user)
|
||||
{
|
||||
// Try to find PDA in inventory
|
||||
if (_inventorySystem.TryGetContainerSlotEnumerator(user, out var containerSlotEnumerator))
|
||||
{
|
||||
while (containerSlotEnumerator.MoveNext(out var pdaUid))
|
||||
{
|
||||
if (!pdaUid.ContainedEntity.HasValue) continue;
|
||||
|
||||
if (HasComp<PdaComponent>(pdaUid.ContainedEntity.Value) || HasComp<StoreComponent>(pdaUid.ContainedEntity.Value))
|
||||
return pdaUid.ContainedEntity.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// Also check hands
|
||||
foreach (var item in _handsSystem.EnumerateHeld(user))
|
||||
{
|
||||
if (HasComp<PdaComponent>(item) || HasComp<StoreComponent>(item))
|
||||
return item;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,22 +108,38 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem
|
||||
/// </summary>
|
||||
public void AddImplants(EntityUid uid, IEnumerable<String> implants)
|
||||
{
|
||||
var coords = Transform(uid).Coordinates;
|
||||
foreach (var id in implants)
|
||||
{
|
||||
var ent = Spawn(id, coords);
|
||||
if (TryComp<SubdermalImplantComponent>(ent, out var implant))
|
||||
{
|
||||
ForceImplant(uid, ent, implant);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning($"Found invalid starting implant '{id}' on {uid} {ToPrettyString(uid):implanted}");
|
||||
Del(ent);
|
||||
}
|
||||
AddImplant(uid, id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a single implant to a person, and returns the implant.
|
||||
/// Logs any implant ids that don't have <see cref="SubdermalImplantComponent"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The implant, if it was successfully created. Otherwise, null.
|
||||
/// </returns>>
|
||||
public EntityUid? AddImplant(EntityUid uid, String implantId) // WD EDIT AHEAD OF WIZDEN UPSTREAM
|
||||
{
|
||||
var coords = Transform(uid).Coordinates;
|
||||
var ent = Spawn(implantId, coords);
|
||||
|
||||
if (TryComp<SubdermalImplantComponent>(ent, out var implant))
|
||||
{
|
||||
ForceImplant(uid, ent, implant);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning($"Found invalid starting implant '{implantId}' on {uid} {ToPrettyString(uid):implanted}");
|
||||
Del(ent);
|
||||
return null;
|
||||
}
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces an implant into a person
|
||||
/// Good for on spawn related code or admin additions
|
||||
@@ -184,7 +200,7 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem
|
||||
var relayEv = new ImplantRelayEvent<T>(args);
|
||||
foreach (var implant in implantContainer.ContainedEntities)
|
||||
{
|
||||
if (args is HandledEntityEventArgs { Handled : true })
|
||||
if (args is HandledEntityEventArgs { Handled: true })
|
||||
return;
|
||||
|
||||
RaiseLocalEvent(implant, relayEv);
|
||||
@@ -223,7 +239,7 @@ public abstract class SharedSubdermalImplantSystem : EntitySystem
|
||||
// Remove the implant from the donor's implant container
|
||||
_container.Remove(donorImplant, donorImplantContainer, force: true);
|
||||
|
||||
if(!TryComp<SubdermalImplantComponent>(donorImplant, out var subdermal))
|
||||
if (!TryComp<SubdermalImplantComponent>(donorImplant, out var subdermal))
|
||||
return;
|
||||
|
||||
// Insert the implant into the recipient's implant container
|
||||
|
||||
@@ -1,50 +1,4 @@
|
||||
Entries:
|
||||
- author: KettlebellOfCreation
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0430 \u0430\u043D\u0442\
|
||||
\u0438\u0441\u043F\u0430\u043C \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430\
|
||||
, \u0438 \u043A\u0443\u043B\u0434\u0430\u0443\u043D \u043D\u0430 \u043B\u044E\
|
||||
\u0431\u044B\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F"
|
||||
type: Add
|
||||
id: 108
|
||||
time: '2023-03-06T20:39:24.0000000+00:00'
|
||||
- author: rhailrake
|
||||
changes:
|
||||
- message: "\u0424\u0438\u043A\u0441 \u043F\u043E\u0447\u0438\u043D\u043A\u0438\
|
||||
\ \u0431\u043E\u0440\u0433\u043E\u0432! \u0410\u0411\u0423\u0417 \u041F\u0420\
|
||||
\u0418\u041D\u042F\u041B \u0418\u0421\u041B\u0410\u041C"
|
||||
type: Fix
|
||||
id: 109
|
||||
time: '2023-03-09T15:17:32.0000000+00:00'
|
||||
- author: Valtos
|
||||
changes:
|
||||
- message: "\u0420\u0430\u0437\u0434\u0435\u043B\u044C\u043D\u044B\u0435 \u0431\u0430\
|
||||
\u043D\u044B \u0434\u043B\u044F \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u0438\
|
||||
\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u0432. \u0421\u0442\u0430\u0440\
|
||||
\u044B\u0435 \u0431\u0430\u043D\u044B \u0432\u0441\u0451 \u0435\u0449\u0451\
|
||||
\ \u0440\u0430\u0431\u043E\u0442\u0430\u044E\u0442 \u043D\u0430 \u0432\u0441\
|
||||
\u0435\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445."
|
||||
type: Add
|
||||
- message: "\u0420\u0430\u0437\u0434\u0435\u043B\u044C\u043D\u044B\u0435 \u043F\u0435\
|
||||
\u0434\u0430\u043B\u0438 \u0434\u043B\u044F \u043A\u0430\u0436\u0434\u043E\u0433\
|
||||
\u043E \u0438\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u0432. \u0421\
|
||||
\u0442\u0430\u0440\u044B\u0435 \u043F\u0435\u0434\u0430\u043B\u0438 \u0432\u0441\
|
||||
\u0451 \u0435\u0449\u0451 \u0440\u0430\u0431\u043E\u0442\u0430\u044E\u0442 \u043D\
|
||||
\u0430 \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445\
|
||||
."
|
||||
type: Add
|
||||
id: 110
|
||||
time: '2023-03-28T18:48:59.0000000+00:00'
|
||||
- author: NCast-Hops
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D \u0425\u0410\u0419\u0417\
|
||||
\u0415\u041D\u0411\u0423\u0420\u0413\u0415\u0420. \u0420\u0435\u0446\u0435\u043F\
|
||||
\u0442: 1 \u0431\u0443\u043B\u043E\u0447\u043A\u0430, 1 \u0441\u044B\u0440\u043E\
|
||||
\u0435 \u043C\u044F\u0441\u043E, 5 \u043C\u0435\u0442\u044B (\u0432 \u0440\u0435\
|
||||
\u0430\u0433\u0435\u043D\u0442\u0430\u0445)"
|
||||
type: Add
|
||||
id: 111
|
||||
time: '2023-04-02T20:18:54.0000000+00:00'
|
||||
- author: Gersoon
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u0441\u0435\u0440\
|
||||
@@ -8874,3 +8828,50 @@
|
||||
id: 607
|
||||
time: '2024-11-18T04:54:23.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/784
|
||||
- author: BIG_Zi_348
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u043D\u0435\u0434\
|
||||
\u043E\u0441\u0442\u0430\u044E\u0449\u0438\u0435 \u043F\u0435\u0440\u0435\u0432\
|
||||
\u043E\u0434\u044B \u043C\u0435\u043B\u043E\u0447\u0435\u0439."
|
||||
type: Add
|
||||
- message: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u044B \u043F\u0435\
|
||||
\u0440\u0435\u0432\u043E\u0434\u044B \u043C\u0435\u043B\u043E\u0447\u0435\u0439\
|
||||
."
|
||||
type: Fix
|
||||
- message: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D \u0441\u043F\u0440\
|
||||
\u0430\u0439\u0442 \u043A\u043E\u0431\u0440\u044B \u0432 \u0440\u0443\u043A\u0430\
|
||||
\u0445."
|
||||
type: Fix
|
||||
id: 608
|
||||
time: '2024-11-19T13:00:22.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/785
|
||||
- author: BIG_Zi_348
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u043D\u0435\u0434\
|
||||
\u043E\u0441\u0442\u0430\u044E\u0449\u0438\u0435 \u043F\u0435\u0440\u0435\u0432\
|
||||
\u043E\u0434\u044B \u043C\u0435\u043B\u043E\u0447\u0435\u0439."
|
||||
type: Add
|
||||
id: 609
|
||||
time: '2024-11-21T19:55:51.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/786
|
||||
- author: BIG_Zi_348
|
||||
changes:
|
||||
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D \u0442\u0440\u0430\u0432\
|
||||
\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0439 \u0434\u0440\u043E\
|
||||
\u0431\u043E\u0432\u0438\u043A \u0434\u043B\u044F \u043F\u043E\u043A\u0443\u043F\
|
||||
\u043A\u0438 \u0432 \u043A\u0430\u0440\u0433\u043E."
|
||||
type: Add
|
||||
id: 610
|
||||
time: '2024-11-21T19:56:31.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/787
|
||||
- author: BIG_Zi_348
|
||||
changes:
|
||||
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u043F\u0440\u0435\u0434\u0430\u0442\
|
||||
\u0435\u043B\u0438 \u0431\u0435\u0437 \u041F\u0414\u0410 \u043F\u043E\u043B\u0443\
|
||||
\u0447\u0430\u044E\u0442 \u0438\u043C\u043F\u043B\u0430\u043D\u0442\u0438\u0440\
|
||||
\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0430\u043F\u043B\u0438\u043D\u043A\
|
||||
."
|
||||
type: Tweak
|
||||
id: 611
|
||||
time: '2024-11-22T19:21:34.0000000+00:00'
|
||||
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/788
|
||||
|
||||
@@ -26,7 +26,7 @@ traitor-death-match-end-round-description-entry = {$originalName}'s PDA, with {$
|
||||
traitor-role-greeting =
|
||||
You are an agent sent by {$corporation} on behalf of The Syndicate.
|
||||
Your objectives and codewords are listed in the character menu.
|
||||
Use the uplink loaded into your PDA to buy the tools you'll need for this mission.
|
||||
Use your uplink to buy the tools you'll need for this mission.
|
||||
Death to Nanotrasen!
|
||||
traitor-role-codewords =
|
||||
The codewords are:
|
||||
@@ -36,9 +36,13 @@ traitor-role-codewords =
|
||||
traitor-role-uplink-code =
|
||||
Set your ringtone to the notes {$code} to lock or unlock your uplink.
|
||||
Remember to lock it after, or the stations crew will easily open it too!
|
||||
traitor-role-uplink-implant =
|
||||
Your uplink implant has been activated, access it from your hotbar.
|
||||
The uplink is secure unless someone removes it from your body.
|
||||
|
||||
# don't need all the flavour text for character menu
|
||||
traitor-role-codewords-short =
|
||||
The codewords are:
|
||||
{$codewords}.
|
||||
traitor-role-uplink-code-short = Your uplink code is {$code}. Set it as your PDA ringtone to access uplink.
|
||||
traitor-role-uplink-implant-short = Your uplink was implanted. Access it from your hotbar.
|
||||
|
||||
@@ -38,6 +38,8 @@ ent-Stairs = лестница
|
||||
.suffix = Steel
|
||||
ent-Cobweb1 = паутина
|
||||
.desc = Кто-нибудь должен убрать это.
|
||||
ent-Cobweb2 = паутина
|
||||
.desc = Кто-нибудь должен убрать это.
|
||||
ent-CryogenicSleepUnitSpawner = { ent-CryogenicSleepUnit }
|
||||
.desc = { ent-CryogenicSleepUnit.desc }
|
||||
ent-CryogenicSleepUnitSpawnerLateJoin = { ent-CryogenicSleepUnit }
|
||||
|
||||
@@ -2,6 +2,12 @@ ent-PsychBed = кушетка психолога
|
||||
.desc = Мягкая кровать для психологической помощи пациентам.
|
||||
ent-BenchComfy = удобная скамья
|
||||
.desc = Скамья с очень удобной спинкой.
|
||||
ent-BenchRedComfy = { ent-BenchComfy }
|
||||
.desc = { ent-BenchComfy.desc }
|
||||
ent-BenchColorfulComfy = { ent-BenchComfy }
|
||||
.desc = { ent-BenchComfy.desc }
|
||||
ent-BenchBlueComfy = { ent-BenchComfy }
|
||||
.desc = { ent-BenchComfy.desc }
|
||||
ent-ChairGreyscale = стул
|
||||
.desc = стул
|
||||
.suffix = Белый
|
||||
|
||||
@@ -31,7 +31,10 @@ ent-GasPipeBroken = сломанная труба
|
||||
.desc = Раньше в ней был газ.
|
||||
ent-SpaceHeater = космический обогреватель
|
||||
.desc = Устройство технологии синего пространства, изменяющее локальную температуру. Обычно его называют "Космический обогреватель".
|
||||
.suffix = Unanchored
|
||||
ent-SpaceHeaterAnchored = { ent-SpaceHeater }
|
||||
.desc = { ent-SpaceHeater.desc }
|
||||
ent-SpaceHeaterEnabled = { ent-SpaceHeater }
|
||||
.desc = { ent-SpaceHeater.desc }
|
||||
ent-BaseGasCondenser = конденсатор
|
||||
.desc = Конденсирует газы в жидкости. Теперь нам нужны только трубы.
|
||||
ent-DisposalSignalRouter = маршрутизатор сигналов утилизации
|
||||
|
||||
@@ -7,7 +7,9 @@ ent-ShelfBar = барная полка
|
||||
ent-ShelfKitchen = кухонная полка
|
||||
.desc = Вместит ножи, специи и все самое приятное!
|
||||
ent-ShelfChemistry = полка для химикатов
|
||||
.desc = Хранит все ваши химикаты в безопасности и вне до- эээ, публичных рук!
|
||||
.desc = Хранит все ваши химикаты в безопасности и вне доступности клоу... эээ, публичных рук!
|
||||
ent-ShelfChemistryChemistrySecure = { ent-ShelfChemistry }
|
||||
.desc = { ent-ShelfChemistry.desc }
|
||||
ent-ShotGunCabinet = шкаф для дробовика
|
||||
.desc = На нем есть маленькая этикетка с надписью "Только для аварийных случаев" с описанием безопасного использования дробовика. Как будто.
|
||||
ent-ShotGunCabinetFilled = { ent-ShotGunCabinet }
|
||||
@@ -17,13 +19,13 @@ ent-ShotGunCabinetFilledOpen = { ent-ShotGunCabinet }
|
||||
ent-ShotGunCabinetOpen = { ent-ShotGunCabinet }
|
||||
.desc = { ent-ShotGunCabinet.desc }
|
||||
ent-SignalSwitchDirectional = сигнальный выключатель
|
||||
.desc = сигнальный выключатель
|
||||
.desc = Это переключатель питания устройств.
|
||||
.suffix = направленный
|
||||
ent-SignalButtonDirectional = сигнальная кнопка
|
||||
.desc = сигнальная кнопка
|
||||
.desc = Эта кнопка что-то активирует.
|
||||
.suffix = направленный
|
||||
ent-ApcNetSwitchDirectional = коммутатор сети АПЦ
|
||||
.desc = коммутатор сети АПЦ
|
||||
ent-ApcNetSwitchDirectional = переключатель сети АПЦ
|
||||
.desc = Это переключатель источников света, использующих локальный контроллер питания.
|
||||
.suffix = направленный
|
||||
ent-CleanerDispenser = дозатор для космического чистящего средства
|
||||
.desc = Настенный дозатор реагентов.
|
||||
|
||||
@@ -32,6 +32,12 @@ ent-WallRockChromite = хромит
|
||||
.desc = хромит
|
||||
ent-WallRockAndesite = андезит
|
||||
.desc = андезит
|
||||
ent-FenceMetalCorner = сетка-рабица
|
||||
.desc = Металлическое ограждение, отгораживающее что-то, вероятно, очень важное.
|
||||
ent-FenceMetalEnd = { ent-FenceMetalCorner }
|
||||
.desc = { ent-FenceMetalCorner.desc }
|
||||
ent-FenceMetalStraight = { ent-FenceMetalCorner }
|
||||
.desc = { ent-FenceMetalCorner.desc }
|
||||
ent-FenceMetalBroken = сломанный забор из цепной сетки
|
||||
.desc = Кто-то очень сильно разозлился на неодушевленный предмет.
|
||||
ent-FenceMetalGate = ворота из цепной сетки
|
||||
@@ -40,3 +46,11 @@ ent-FenceWoodHighGate = деревянные ворота
|
||||
.desc = Тебе известно, что тебя ждет за этими воротами? Это может быть как туалет, так и роскошный особняк. Но ты продолжаешь любить своих эмо-мальчиков.
|
||||
ent-FenceWoodSmallGate = деревянные ворота
|
||||
.desc = Глядя на эти ворота, в голове всплывает знакомый образ. Где моя свинка?
|
||||
ent-FenceWoodSmallCorner = малый деревянный забор
|
||||
.desc = Малый деревянный забор. Лучшая защита для ограждения частной территории!
|
||||
ent-FenceWoodSmallEnd = { ent-FenceWoodSmallCorner }
|
||||
.desc = { ent-FenceWoodSmallCorner.desc }
|
||||
ent-FenceWoodSmallStraight = { ent-FenceWoodSmallCorner }
|
||||
.desc = { ent-FenceWoodSmallCorner.desc }
|
||||
ent-FenceWoodSmallTJunction = { ent-FenceWoodSmallCorner }
|
||||
.desc = { ent-FenceWoodSmallCorner.desc }
|
||||
|
||||
@@ -33,8 +33,8 @@ ent-ClothingEyesGlassesSunglassesMeaty = солнцезащитные очки
|
||||
.desc = Полезны как для безопасности, так и для каргонии.
|
||||
ent-ClothingEyesGlassesChemical = очки для химического анализа
|
||||
.desc = Очки, которые могут сканировать химический состав раствора.
|
||||
ent-ClothingEyesVisorNinja = шлем ниндзя
|
||||
.desc = Усовершенствованный шлем, защищающий глаза ниндзя от вспышек света.
|
||||
ent-ClothingEyesVisorNinja = визор ниндзя
|
||||
.desc = Усовершенствованный визор, защищающий глаза ниндзя от вспышек света.
|
||||
ent-ClothingEyesHudSyndicate = визор синдиката
|
||||
.desc = Профессиональный дисплей синдиката, предназначенный для лучшего обнаружения гуманоидов и их последующего уничтожения.
|
||||
ent-ClothingEyesHudSyndicateAgent = визор агента синдиката
|
||||
|
||||
@@ -25,7 +25,7 @@ traitor-death-match-end-round-description-entry = ПДА { $originalName }, с {
|
||||
traitor-role-greeting =
|
||||
Вы - агент Синдиката.
|
||||
Ваши цели и кодовые слова перечислены в меню персонажа.
|
||||
Воспользуйтесь аплинком, встроенным в ваш ПДА, чтобы приобрести всё необходимое для выполнения работы.
|
||||
Воспользуйтесь аплинком, чтобы приобрести всё необходимое для выполнения работы.
|
||||
Смерть НаноТрейзен!
|
||||
|
||||
traitor-role-codewords =
|
||||
@@ -37,6 +37,9 @@ traitor-role-codewords =
|
||||
traitor-role-uplink-code =
|
||||
Установите мелодия рингтона на {$code} чтобы разблокировать аплинк.
|
||||
Не забудьте заблокировать его после этого, иначе сотрудники станции тоже легко откроют его!
|
||||
traitor-role-uplink-implant =
|
||||
Ваш имплант аплинк активирован, воспользуйтесь им из хотбара.
|
||||
Аплинк надежно защищён, пока кто-нибудь не извлечёт его из вашего тела.
|
||||
|
||||
# don't need all the flavour text for character menu
|
||||
traitor-role-codewords-short =
|
||||
@@ -44,3 +47,4 @@ traitor-role-codewords-short =
|
||||
{$codewords}.
|
||||
|
||||
traitor-role-uplink-code-short = Код от вашего аплинка - {$code}. Установите его в качестве рингтона на своём ПДА для доступа к аплинку.
|
||||
traitor-role-uplink-implant-short = Ваш аплинк был имплантирован. Воспользуйтесь им из хотбара.
|
||||
|
||||
5
Resources/Locale/ru-RU/geras/geras.ftl
Normal file
@@ -0,0 +1,5 @@
|
||||
geras-popup-morph-message-user = Ты трансформируешься в малую версию себя!
|
||||
geras-popup-morph-message-others = {CAPITALIZE($entity)} трансформировался в слизня!
|
||||
|
||||
ent-MobSlimesGeras = герас
|
||||
.desc = Герас - особая форма слаймолюда.
|
||||
@@ -1,5 +1,7 @@
|
||||
ent-BaseWhistle = свисток
|
||||
.desc = Кто-то явно забыл выключить чайник!
|
||||
ent-Whistle = свисток
|
||||
.desc = Кто-то явно забыл выключить чайник!
|
||||
ent-SecurityWhistle = свисток
|
||||
.desc = От одного звука становится страшно.
|
||||
ent-TurboItemRecharger = турбо зарядник
|
||||
|
||||
@@ -14,7 +14,7 @@ reagent-desc-thc-oil = Чистое масло ТГК, полученное из
|
||||
reagent-name-bananadine = бананадин
|
||||
reagent-desc-bananadine = Слабый психоделик, содержащийся в небольших в шкурках от бананов.
|
||||
|
||||
reagent-name-nicotine = никотинколичествах
|
||||
reagent-name-nicotine = никотин
|
||||
reagent-desc-nicotine = Опасен и вызывает сильное привыкание.
|
||||
reagent-name-impedrezene = импедризин
|
||||
reagent-desc-impedrezene = Наркотик, который лишает человека дееспособности, замедляя высшие функции клеток мозга. Вызывает обширные повреждения мозга.
|
||||
|
||||
@@ -5,6 +5,9 @@ ent-MobBee = пчела
|
||||
ent-MobAngryBee = пчела
|
||||
.desc = Какая милая пчелка. О нет, она выглядит злой и хочет мою пиццу.
|
||||
.suffix = Злая
|
||||
ent-MobTemporaryAngryBee = { ent-MobAngryBee }
|
||||
.desc = { ent-MobAngryBee.desc }
|
||||
.suffix = Злая, Временная
|
||||
ent-MobChicken = курица
|
||||
.desc = Была раньше яйца, динозавром!
|
||||
ent-MobChicken1 = { ent-MobChicken }
|
||||
|
||||
@@ -15,4 +15,6 @@ ent-BoxShotgunIncendiary = коробка ружейных патронов (з
|
||||
ent-BoxShotgunPractice = коробка ружейных патронов (учебные)
|
||||
.desc = Полная коробка учебных ружейных патронов.
|
||||
ent-BoxShellTranquilizer = коробка ружейных патронов (транквилизаторы)
|
||||
.desc = Полная коробка ружейных патронов-транквилизаторов.
|
||||
.desc = Полная коробка ружейных патронов-транквилизаторов.
|
||||
ent-BoxRubberShot = коробка ружейных патронов (резиновые).
|
||||
.desc = Полная коробка резиновых ружейных патронов.
|
||||
|
||||
@@ -14,9 +14,8 @@ ent-AlwaysPoweredLightLED = { ent-AlwaysPoweredWallLight }
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
ent-PoweredlightExterior = { ent-Poweredlight }
|
||||
.desc = Осветительный прибор. Потребляет энергию и излучает свет, если оснащен лампой-трубкой.
|
||||
.suffix = Синий
|
||||
ent-AlwaysPoweredLightExterior = { ent-AlwaysPoweredWallLight }
|
||||
.suffix = Всегда запитанный, Синий
|
||||
.suffix = Всегда запитанный
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
ent-PoweredlightSodium = { ent-Poweredlight }
|
||||
.desc = Осветительный прибор. Потребляет энергию и излучает свет, если оснащен лампой-трубкой.
|
||||
@@ -34,3 +33,27 @@ ent-PoweredSmallLight = { ent-PoweredSmallLightEmpty }
|
||||
.desc = { ent-PoweredSmallLightEmpty.desc }
|
||||
ent-EmergencyLight = аварийная лампа
|
||||
.desc = Маленькая лампочка с внутренним аккумулятором, которая включается, как только перестает получать питание извне. Технология НаноТрейзен позволяет ей адаптировать свой цвет для оповещения экипажа об обстановке на станции.
|
||||
ent-PoweredlightBlue = { ent-Poweredlight }
|
||||
.desc = { ent-Poweredlight.desc }
|
||||
ent-PoweredlightCyan = { ent-Poweredlight }
|
||||
.desc = { ent-Poweredlight.desc }
|
||||
ent-PoweredlightGreen = { ent-Poweredlight }
|
||||
.desc = { ent-Poweredlight.desc }
|
||||
ent-PoweredlightOrange = { ent-Poweredlight }
|
||||
.desc = { ent-Poweredlight.desc }
|
||||
ent-PoweredlightPink = { ent-Poweredlight }
|
||||
.desc = { ent-Poweredlight.desc }
|
||||
ent-PoweredlightRed = { ent-Poweredlight }
|
||||
.desc = { ent-Poweredlight.desc }
|
||||
ent-AlwaysPoweredlightBlue = { ent-AlwaysPoweredWallLight }
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
ent-AlwaysPoweredlightCyan = { ent-AlwaysPoweredWallLight }
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
ent-AlwaysPoweredlightGreen = { ent-AlwaysPoweredWallLight }
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
ent-AlwaysPoweredlightOrange = { ent-AlwaysPoweredWallLight }
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
ent-AlwaysPoweredlightPink = { ent-AlwaysPoweredWallLight }
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
ent-AlwaysPoweredlightRed = { ent-AlwaysPoweredWallLight }
|
||||
.desc = { ent-AlwaysPoweredWallLight.desc }
|
||||
|
||||
@@ -7,6 +7,8 @@ ent-DebugThruster = ракетный двигатель
|
||||
.suffix = DEBUG
|
||||
ent-Gyroscope = гироскоп
|
||||
.desc = Увеличивает потенциальное угловое вращение шаттла.
|
||||
ent-GyroscopeUnanchored = { ent-Gyroscope }
|
||||
.desc = { ent-Gyroscope.desc }
|
||||
ent-DebugGyroscope = гироскоп
|
||||
.desc = Увеличивает потенциальное угловое вращение шаттла.
|
||||
.suffix = DEBUG
|
||||
|
||||
@@ -6,3 +6,112 @@ ent-ApcNetSwitch = переключатель сети АПЦ
|
||||
.desc = Это переключатель источников света, использующих локальный контроллер питания.
|
||||
ent-TwoWayLever = двухпозиционный рычаг
|
||||
.desc = Двухпозиционный рычаг.
|
||||
ent-LockableButton = кнопка с замком
|
||||
.desc = { ent-SignalButtonDirectional.desc }
|
||||
ent-LockableButtonCaptain = { ent-LockableButton }
|
||||
.suffix = Капитан
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonHeadOfPersonnel = { ent-LockableButton }
|
||||
.suffix = Глава персонала
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonChiefEngineer = { ent-LockableButton }
|
||||
.suffix = Старший инженер
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonChiefMedicalOfficer = { ent-LockableButton }
|
||||
.suffix = Главный врач
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonHeadOfSecurity = { ent-LockableButton }
|
||||
.suffix = Глава службы безопасности
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonResearchDirector = { ent-LockableButton }
|
||||
.suffix = Научный руководитель
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonCommand = { ent-LockableButton }
|
||||
.suffix = Командование
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonCryogenics = { ent-LockableButton }
|
||||
.suffix = Криогеника
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonSecurity = { ent-LockableButton }
|
||||
.suffix = Служба безопасности
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonDetective = { ent-LockableButton }
|
||||
.suffix = Детектив
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonArmory = { ent-LockableButton }
|
||||
.suffix = Оружейная
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonBrig = { ent-LockableButton }
|
||||
.suffix = Бриг
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonLawyer = { ent-LockableButton }
|
||||
.suffix = Юридический
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonEngineering = { ent-LockableButton }
|
||||
.suffix = Инженерный
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonMedical = { ent-LockableButton }
|
||||
.suffix = Медицинский
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonQuartermaster = { ent-LockableButton }
|
||||
.suffix = Квартирмейстер
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonSalvage = { ent-LockableButton }
|
||||
.suffix = Утилизаторы
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonCargo = { ent-LockableButton }
|
||||
.suffix = Снабжение
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonResearch = { ent-LockableButton }
|
||||
.suffix = Научный
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonService = { ent-LockableButton }
|
||||
.suffix = Сервисный
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonMaintenance = { ent-LockableButton }
|
||||
.suffix = Техобслуживание
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonExternal = { ent-LockableButton }
|
||||
.suffix = Внешний
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonJanitor = { ent-LockableButton }
|
||||
.suffix = Уборщик
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonTheatre = { ent-LockableButton }
|
||||
.suffix = Театр
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonBar = { ent-LockableButton }
|
||||
.suffix = Бар
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonChemistry = { ent-LockableButton }
|
||||
.suffix = Химия
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonKitchen = { ent-LockableButton }
|
||||
.suffix = Кухня
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonChapel = { ent-LockableButton }
|
||||
.suffix = Церковь
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonHydroponics = { ent-LockableButton }
|
||||
.suffix = Гидропоника
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-LockableButtonAtmospherics = { ent-LockableButton }
|
||||
.suffix = Атмосферный
|
||||
.desc = { ent-LockableButton.desc }
|
||||
ent-ButtonFrame = каркас кнопки
|
||||
.desc = Это каркас, помогающий визуально различать переключатели.
|
||||
ent-ButtonFrameGrey = { ent-ButtonFrame }
|
||||
.suffix = Серый
|
||||
.desc = { ent-ButtonFrame.desc }
|
||||
ent-ButtonFrameCaution = { ent-ButtonFrame }
|
||||
.suffix = Внимание
|
||||
.desc = { ent-ButtonFrame.desc }
|
||||
ent-ButtonFrameCautionSecurity = { ent-ButtonFrame }
|
||||
.suffix = Внимание, Служба безопасности
|
||||
.desc = { ent-ButtonFrame.desc }
|
||||
ent-ButtonFrameExit = { ent-ButtonFrame }
|
||||
.suffix = Выход
|
||||
.desc = { ent-ButtonFrame.desc }
|
||||
ent-ButtonFrameJanitor = { ent-ButtonFrame }
|
||||
.suffix = Уборщик
|
||||
.desc = { ent-ButtonFrame.desc }
|
||||
|
||||
@@ -1335,8 +1335,7 @@
|
||||
components:
|
||||
# make the player a traitor once its taken
|
||||
- type: AutoTraitor
|
||||
giveUplink: false
|
||||
giveObjectives: false
|
||||
profile: TraitorReinforcement
|
||||
|
||||
- type: entity
|
||||
id: MobMonkeySyndicateAgentNukeops # Reinforcement exclusive to nukeops uplink
|
||||
@@ -1491,8 +1490,7 @@
|
||||
components:
|
||||
# make the player a traitor once its taken
|
||||
- type: AutoTraitor
|
||||
giveUplink: false
|
||||
giveObjectives: false
|
||||
profile: TraitorReinforcement
|
||||
|
||||
- type: entity
|
||||
id: MobKoboldSyndicateAgentNukeops # Reinforcement exclusive to nukeops uplink
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
components:
|
||||
# make the player a traitor once its taken
|
||||
- type: AutoTraitor
|
||||
giveUplink: false
|
||||
giveObjectives: false
|
||||
profile: TraitorReinforcement
|
||||
|
||||
- type: entity
|
||||
parent: MobHumanSyndicateAgentBase
|
||||
|
||||
@@ -163,6 +163,20 @@
|
||||
- type: TraitorRole
|
||||
prototype: Traitor
|
||||
|
||||
- type: entity # WD AHEAD OF WIZDEN UPSTREAM
|
||||
id: TraitorReinforcement
|
||||
parent: Traitor
|
||||
components:
|
||||
- type: TraitorRule
|
||||
giveUplink: false
|
||||
giveCodewords: false # It would actually give them a different set of codewords than the regular traitors, anyway
|
||||
giveBriefing: false
|
||||
- type: AntagSelection
|
||||
definitions:
|
||||
- prefRoles: [ Traitor ]
|
||||
mindRoles:
|
||||
- MindRoleTraitor
|
||||
|
||||
- type: entity
|
||||
id: Revolutionary
|
||||
parent: BaseGameRule
|
||||
|
||||
@@ -277,22 +277,22 @@
|
||||
category: Security
|
||||
group: market
|
||||
|
||||
- type: cargoProduct # WD ahead of wd upstream
|
||||
- type: cargoProduct
|
||||
id: cargoBoxesRubberShot
|
||||
icon:
|
||||
sprite: Objects/Storage/boxes.rsi
|
||||
state: shellRubber
|
||||
state: shellrubber
|
||||
product: CrateBoxesRubberShot
|
||||
cost: 3000
|
||||
category: cargoproduct-category-name-armory
|
||||
cost: 800
|
||||
category: Security
|
||||
group: market
|
||||
|
||||
- type: cargoProduct
|
||||
id: cargoRubberShotgun
|
||||
icon:
|
||||
sprite: _Honk/Objects/Weapons/Guns/Shotguns/pump.rsi
|
||||
sprite: White/Objects/Weapons/Guns/Shotguns/rubber_pump.rsi
|
||||
state: icon
|
||||
product: CrateRubberShotgun
|
||||
cost: 4000
|
||||
category: cargoproduct-category-name-armory
|
||||
cost: 2000
|
||||
category: Security
|
||||
group: market
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- type: entity # WD ahead of wd upstream
|
||||
- type: entity
|
||||
id: CrateBoxesRubberShot
|
||||
parent: CrateWeaponSecure
|
||||
name: ящик с коробками резиновой дроби
|
||||
|
||||
|
Before Width: | Height: | Size: 509 B After Width: | Height: | Size: 509 B |
|
Before Width: | Height: | Size: 509 B After Width: | Height: | Size: 509 B |
|
Before Width: | Height: | Size: 966 B After Width: | Height: | Size: 966 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |