[Transfer] Engi (#790)

* Suhariki (#4)

* init

* Porting is complete

Still WIP

* small stuff

* SmallStuff

* awawawa

* Нас рано

* Engi

* More luck

* removed some shit

(cherry picked from commit e1d745655b0e7253ea4e4814b82dd56e90153514)

* Самодельные отражайки (#6)

* Ghetto Mirror Shield

* Protorypes for ghetto mirrors

* locale

* idk, works fine on my machine

* forsenPls

(cherry picked from commit 4505739fd9430bcc578da3dec932d9aa7ca933ca)

* Шлем из ведра (#7)

* Bucket Helmet

* Code cleanup

* Squashed commit of the following:

commit 4505739fd9430bcc578da3dec932d9aa7ca933ca
Author: BIGZi0348 <118811750+BIGZi0348@users.noreply.github.com>
Date:   Sat Sep 21 17:10:02 2024 +0300

    Самодельные отражайки (#6)

    * Ghetto Mirror Shield

    * Protorypes for ghetto mirrors

    * locale

    * idk, works fine on my machine

    * forsenPls

commit 1f066876508dec8d3f21ad753dab9fcc13dc8d1a
Author: BIGZi0348 <118811750+BIGZi0348@users.noreply.github.com>
Date:   Sat Sep 21 14:57:30 2024 +0300

    Агрессивный вор (#5)

    * AggressiveThief

    * Попытка насрать обратно

commit e1d745655b0e7253ea4e4814b82dd56e90153514
Author: BIGZi0348 <118811750+BIGZi0348@users.noreply.github.com>
Date:   Sat Sep 21 14:46:38 2024 +0300

    Suhariki (#4)

    * init

    * Porting is complete

    Still WIP

    * small stuff

    * SmallStuff

    * awawawa

    * Нас рано

    * Engi

    * More luck

    * removed some shit

commit 08061b4f1fbbfd521e3a40ef53d9bc86fa140087
Author: BIGZi0348 <118811750+BIGZi0348@users.noreply.github.com>
Date:   Sat Sep 21 14:30:31 2024 +0300

    Engi rise up (#3)

commit 00e2f5c45ca7abfeff1f85d4893352d8875f8560
Author: BIGZi0348 <118811750+BIGZi0348@users.noreply.github.com>
Date:   Thu Sep 19 19:42:30 2024 +0300

    Bigzi upstream1 (#2)

    * init

    * Porting is complete

    Still WIP

    * Мелочи - Король крыс, диски, правки перевода и респрайт одеяния культа (#686)

    * Большой Крыс Отдыхает

    * Фикс размера фейк диска

    * Доработка диска очков РНД

    * Скоро перейду на райдер

    * Переводы

    * Диски одного размера

    * Респрайт робы и капюшона культа

    * Automatic changelog update

    * fix (#687)

    * Automatic changelog update

    * govno HD (#688)

    * Automatic changelog update

    * Hotfix loadouts (#689)

    * govno HD

    * hotfix loadouts

    * fuck

    * Automatic changelog update

    * Update PULL_REQUEST_TEMPLATE.md

    * Even smaller stuff (#690)

    * 45 to 44

    * Фикс ошибки перевода

    * Voice mask translate

    * Automatic changelog update

    * small stuff

    * SmallStuff

    * awawawa

    * Локализация шепелявости (#691)

    * БУМ!!!!!!!! (#692)

    * Automatic changelog update

    * Большой ребаланс милишки (#681)

    * MeleeThrowOnHit rework

    * buff baseball bat

    * better mjolnir

    * telebaton system unhardcode + refactor + transform TelescopicBatonComponent to KnockDownOnHitComponent

    * fix telebaton prototype

    * darova

    * fix KnockDownOnHitSystem

    * chaplain weapons rebalance

    * fix nullrod hit sound

    * BloodstreamSystem cleanup

    * bleeding rebalance

    * damage rebalance

    * small baseball bat fix

    * Automatic changelog update

    * Chaplain armor fix (#693)

    * Фикс описания (#696)

    * No passengers on this military complex (#695)

    * Automatic changelog update

    * Переводы (#698)

    * Пепеводы

    * Очепятки

    * Фикс прожектора и открутка цифр (#697)

    * Melochi

    * Фикс хамелеона

    * Переводы денег мне на карту

    * Automatic changelog update

    * Нас рано

    * Фикс пополнения зарядов РЦД используя стаки ресурсов (#699)

    * Фиксики

    * Спасли Валеру от банкротства

    * Very hot man (#700)

    * Automatic changelog update

    * reverted illegal code added by oniks

    ---------

    Co-authored-by: RavmorganButOnCocaine <valtos@nextmail.ru>
    Co-authored-by: Spatison <137375981+Spatison@users.noreply.github.com>
    Co-authored-by: Valtos <valtos@spaces.ru>
    Co-authored-by: Jabak <163307958+Jabaks@users.noreply.github.com>
    Co-authored-by: ThereDrD <88589686+ThereDrD0@users.noreply.github.com>

* ВЕДРО!!!

* Funny

* Oppsie

(cherry picked from commit 92ce631b0c0187678b6d1eea34d3c0830b9b0fac)

* Yes (#8)

(cherry picked from commit 3d083befca212455cffcae56b84ee55050ad62be)

* Small Fix

То чувство, когда можешь срать прямо в мэйн

(cherry picked from commit 8fa7cfb678711a55bf6704ced30f7ed9b4b1e8c4)

* bababooey (#9)

(cherry picked from commit f7ed9d287f6798c7d39ac437a2f969ec0dc10309)

* GoodLooking (#10)

(cherry picked from commit 1617dce502b71db22a6b736ac879c04c07ec54a0)

* Dadka scazal (#11)

(cherry picked from commit 50da866354952628185bb396f359c2f533d57340)

* Сортировка эксклюзива енги + респрайт деревянных столов и дверей (#12)

* Massive

* Чейндлок

(cherry picked from commit 4dc165e4c1aa75e8fd22f14db95ac72bf50c77f5)

* Big Zi bucket helmet fix

* Опять насрал в мастер

(cherry picked from commit bd866e0cd87770b1509885f66ec5c562dda3fd91)

* Боевые Молоты (#14)

(cherry picked from commit 64df6b4b91050273218007365cf81a45c3ea74a8)

* хотфикс сухариков

(cherry picked from commit a98265c22dc7de467693f501cf3a5d8577e94a54)

* funny sword (#15)

(cherry picked from commit 231aaa1b33b7e4edf00506c6ebdbd389257cf1ca)

* funny hammer

(cherry picked from commit 1e58eaa146cc95f34358d97d6c436ba4705d09a1)

* Добавил админ логирование PacifiedOnChaplainActionSystem (#19)

Update PacifiedOnChaplainActionSystem.cs

(cherry picked from commit f6aa42eab7cce294336aec14f7dfb6f0671267cf)

* Small refactor

(cherry picked from commit b38ad7e7b8afa35a22c84c2fb8836bf13736dfb3)

* Команда для отправки цели для станции (#21)

* Команда для отправки цели для станции

* Правки

(cherry picked from commit 93a79c4952e3a75c32ff5cc4d07df4018a9bf7db)

* Больше целей

(cherry picked from commit c3d34d6a4e000d8af66c8f53d60a898cfae0a454)

* Music for events

(cherry picked from commit 4a7214634b3e77caefd011bf5900f581055a0ac8)

* Санитизация

* unused

---------

Co-authored-by: BIGZi0348 <118811750+bigzi0348@users.noreply.github.com>
Co-authored-by: BIGZi0348 <svalker0348@gmail.com>
This commit is contained in:
keslik
2024-11-27 05:25:36 +03:00
committed by GitHub
parent 4ef3b2837e
commit 92dd279988
49 changed files with 1267 additions and 12 deletions

View File

@@ -135,6 +135,7 @@ namespace Content.Client.Entry
_prototypeManager.RegisterIgnore("wireLayout"); _prototypeManager.RegisterIgnore("wireLayout");
_prototypeManager.RegisterIgnore("alertLevels"); _prototypeManager.RegisterIgnore("alertLevels");
_prototypeManager.RegisterIgnore("nukeopsRole"); _prototypeManager.RegisterIgnore("nukeopsRole");
_prototypeManager.RegisterIgnore("stationGoal"); // WD
_prototypeManager.RegisterIgnore("ghostRoleRaffleDecider"); _prototypeManager.RegisterIgnore("ghostRoleRaffleDecider");
//WD-EDIT //WD-EDIT

View File

@@ -22,6 +22,7 @@ using Content.Shared._White.MagGloves;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Content.Shared._White._Engi.BucketHelmet;
namespace Content.Server.Strip namespace Content.Server.Strip
{ {
@@ -135,6 +136,16 @@ namespace Content.Server.Strip
} }
// WD EDIT END // WD EDIT END
// WD EDIT START
if (args.Slot == "ears" && TryComp(strippable, out PreventStrippingFromEarsComponent? _))
{
var message = Loc.GetString("buckethelmet-cant-strip");
_popupSystem.PopupEntity(message, user, user);
return;
}
// WD EDIT END
if (args.IsHand) if (args.IsHand)
{ {
StripHand((user, userHands), (strippable.Owner, null), args.Slot, strippable); StripHand((user, userHands), (strippable.Owner, null), args.Slot, strippable);
@@ -605,7 +616,7 @@ namespace Content.Server.Strip
if (ev.Event.InventoryOrHand) if (ev.Event.InventoryOrHand)
{ {
if ( ev.Event.InsertOrRemove && !CanStripInsertInventory((entity.Owner, entity.Comp), args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName) || if (ev.Event.InsertOrRemove && !CanStripInsertInventory((entity.Owner, entity.Comp), args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName) ||
!ev.Event.InsertOrRemove && !CanStripRemoveInventory(entity.Owner, args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName)) !ev.Event.InsertOrRemove && !CanStripRemoveInventory(entity.Owner, args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName))
{ {
ev.Cancel(); ev.Cancel();
@@ -613,7 +624,7 @@ namespace Content.Server.Strip
} }
else else
{ {
if ( ev.Event.InsertOrRemove && !CanStripInsertHand((entity.Owner, entity.Comp), args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName) || if (ev.Event.InsertOrRemove && !CanStripInsertHand((entity.Owner, entity.Comp), args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName) ||
!ev.Event.InsertOrRemove && !CanStripRemoveHand(entity.Owner, args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName)) !ev.Event.InsertOrRemove && !CanStripRemoveHand(entity.Owner, args.Target.Value, args.Used.Value, ev.Event.SlotOrHandName))
{ {
ev.Cancel(); ev.Cancel();
@@ -634,14 +645,14 @@ namespace Content.Server.Strip
if (ev.InventoryOrHand) if (ev.InventoryOrHand)
{ {
if (ev.InsertOrRemove) if (ev.InsertOrRemove)
StripInsertInventory((entity.Owner, entity.Comp), ev.Target.Value, ev.Used.Value, ev.SlotOrHandName); StripInsertInventory((entity.Owner, entity.Comp), ev.Target.Value, ev.Used.Value, ev.SlotOrHandName);
else StripRemoveInventory(entity.Owner, ev.Target.Value, ev.Used.Value, ev.SlotOrHandName, ev.Args.Hidden); else StripRemoveInventory(entity.Owner, ev.Target.Value, ev.Used.Value, ev.SlotOrHandName, ev.Args.Hidden);
} }
else else
{ {
if (ev.InsertOrRemove) if (ev.InsertOrRemove)
StripInsertHand((entity.Owner, entity.Comp), ev.Target.Value, ev.Used.Value, ev.SlotOrHandName, ev.Args.Hidden); StripInsertHand((entity.Owner, entity.Comp), ev.Target.Value, ev.Used.Value, ev.SlotOrHandName, ev.Args.Hidden);
else StripRemoveHand((entity.Owner, entity.Comp), ev.Target.Value, ev.Used.Value, ev.SlotOrHandName, ev.Args.Hidden); else StripRemoveHand((entity.Owner, entity.Comp), ev.Target.Value, ev.Used.Value, ev.SlotOrHandName, ev.Args.Hidden);
} }
} }
} }

View File

@@ -0,0 +1,30 @@
using Content.Shared.Inventory.Events;
using Content.Shared._White._Engi.BucketHelmet;
namespace Content.Server._White._Engi.BucketHelmet;
/// <summary>
/// WD.
/// This handles placemet of PreventStrippingFromEarsComponent when bucket helmet is in use.
/// </summary>
public sealed class BucketHelmetSystem : EntitySystem
{
public override void Initialize()
{
SubscribeLocalEvent<BucketHelmetComponent, GotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<BucketHelmetComponent, GotUnequippedEvent>(OnGotUnequipped);
}
public void OnGotUnequipped(EntityUid uid, BucketHelmetComponent component, GotUnequippedEvent args)
{
RemComp<PreventStrippingFromEarsComponent>(args.Equipee);
}
public void OnGotEquipped(EntityUid uid, BucketHelmetComponent component, GotEquippedEvent args)
{
if (args.Slot == "head")
EnsureComp<PreventStrippingFromEarsComponent>(args.Equipee);
}
}

View File

@@ -0,0 +1,15 @@
using Robust.Shared.Audio;
namespace Content.Server._White._Engi.PacifiedOnChaplainAction
{
/// <summary>
/// WD.
/// Adds verb for chaplain to pacify entity.
/// </summary>
[RegisterComponent]
public sealed partial class PacifiedOnChaplainActionComponent : Component
{
[DataField]
public SoundSpecifier ActionSound = new SoundPathSpecifier("/Audio/Effects/holy.ogg");
}
}

View File

@@ -0,0 +1,113 @@
using Content.Shared.ActionBlocker;
using Content.Server.Popups;
using Robust.Shared.Audio.Systems;
using Content.Shared.Interaction;
using Content.Shared.Verbs;
using Content.Server.Bible.Components;
using Content.Shared.Timing;
using Content.Shared.CombatMode.Pacification;
using Content.Server.Administration.Logs;
using Content.Shared.Database;
namespace Content.Server._White._Engi.PacifiedOnChaplainAction
{
/// <summary>
/// WD
/// </summary>
public sealed class PacifiedOnChaplainAction : EntitySystem
{
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly UseDelaySystem _delay = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PacifiedOnChaplainActionComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<PacifiedOnChaplainActionComponent, GetVerbsEvent<AlternativeVerb>>(AddPacifiedOnChaplainVerb);
}
private void Action(PacifiedOnChaplainActionComponent component, EntityUid target, EntityUid user)
{
var popup = "";
if (HasComp<PacifiedComponent>(target))
{
popup = "unpacified-by-chaplain";
RemComp<PacifiedComponent>(target);
}
else
{
popup = "pacified-by-chaplain";
EnsureComp<PacifiedComponent>(target);
}
_adminLogger.Add(LogType.Verb,
LogImpact.Medium,
$"{ToPrettyString(target):target} {popup} {ToPrettyString(user):user}");
_popupSystem.PopupEntity(Loc.GetString(popup, ("target", target)), user, user);
_audio.PlayPvs(component.ActionSound, user);
}
private void OnAfterInteract(EntityUid uid, PacifiedOnChaplainActionComponent component, AfterInteractEvent args)
{
if (!args.CanReach)
return;
if (!TryComp(uid, out UseDelayComponent? useDelay) || _delay.IsDelayed((uid, useDelay)))
return;
if (args.Target == null)
return;
if (!HasComp<BibleUserComponent>(args.User))
return;
Action(component, (EntityUid) args.Target, args.User);
_delay.TryResetDelay((uid, useDelay));
return;
}
private void AddPacifiedOnChaplainVerb(EntityUid uid, PacifiedOnChaplainActionComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanInteract || !args.CanAccess)
return;
if (!HasComp<BibleUserComponent>(args.User))
return;
if (!_blocker.CanInteract(args.User, uid))
return;
var verbName = "";
if (HasComp<PacifiedComponent>(args.Target))
verbName = Loc.GetString("unpacify-by-chaplain");
else
verbName = Loc.GetString("pacify-by-chaplain");
AlternativeVerb verb = new()
{
Act = () =>
{
if (!TryComp(uid, out UseDelayComponent? useDelay) || _delay.IsDelayed((uid, useDelay)))
return;
Action(component, args.Target, args.User);
_delay.TryResetDelay((uid, useDelay));
},
Text = verbName,
Priority = 2
};
args.Verbs.Add(verb);
}
}
}

View File

@@ -0,0 +1,66 @@
using System.Linq;
using Content.Server.Administration;
using Content.Server.Commands;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.Prototypes;
namespace Content.Server._White._Engi.StationGoal
{
[AdminCommand(AdminFlags.Fun)]
public sealed class StationGoalCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entManager = default!;
public string Command => "sendstationgoal";
public string Description => Loc.GetString("send-station-goal-command-description");
public string Help => Loc.GetString("send-station-goal-command-help-text", ("command", Command));
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 2)
{
shell.WriteError(Loc.GetString("shell-wrong-arguments-number"));
return;
}
if (!NetEntity.TryParse(args[0], out var euidNet) || !_entManager.TryGetEntity(euidNet, out var euid))
{
shell.WriteError($"Failed to parse euid '{args[0]}'.");
return;
}
var protoId = args[1];
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
if (!prototypeManager.TryIndex<StationGoalPrototype>(protoId, out var proto))
{
shell.WriteError($"No station goal found with ID {protoId}!");
return;
}
var stationGoalPaper = IoCManager.Resolve<IEntityManager>().System<StationGoalPaperSystem>();
if (!stationGoalPaper.SendStationGoal(euid, protoId))
{
shell.WriteError("Station goal was not sent");
return;
}
}
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
switch (args.Length)
{
case 1:
var stations = ContentCompletionHelper.StationIds(_entManager);
return CompletionResult.FromHintOptions(stations, "[StationId]");
case 2:
var options = IoCManager.Resolve<IPrototypeManager>()
.EnumeratePrototypes<StationGoalPrototype>()
.Select(p => new CompletionOption(p.ID));
return CompletionResult.FromHintOptions(options, Loc.GetString("send-station-goal-command-arg-id"));
}
return CompletionResult.Empty;
}
}
}

View File

@@ -0,0 +1,15 @@
using Robust.Shared.Prototypes;
namespace Content.Server._White._Engi.StationGoal
{
/// <summary>
/// WD.
/// If attached to a station prototype, will send the station a random goal from the list.
/// </summary>
[RegisterComponent]
public sealed partial class StationGoalComponent : Component
{
[DataField]
public List<ProtoId<StationGoalPrototype>> Goals = new();
}
}

View File

@@ -0,0 +1,11 @@
namespace Content.Server._White._Engi.StationGoal
{
/// <summary>
/// WD.
/// Paper with a written station goal in it.
/// </summary>
[RegisterComponent]
public sealed partial class StationGoalPaperComponent : Component
{
}
}

View File

@@ -0,0 +1,132 @@
using Content.Server.Fax;
using Content.Server.GameTicking.Events;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared.Fax.Components;
using Content.Shared.Paper;
using Robust.Server.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Content.Server.RandomMetadata;
namespace Content.Server._White._Engi.StationGoal
{
/// <summary>
/// WD.
/// System to spawn paper with station goal.
/// </summary>
public sealed class StationGoalPaperSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly FaxSystem _fax = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly RandomMetadataSystem _randomMeta = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStarting);
}
private void OnRoundStarting(RoundStartingEvent ev)
{
var playerCount = _playerManager.PlayerCount;
var query = EntityQueryEnumerator<StationGoalComponent>();
while (query.MoveNext(out var uid, out var station))
{
var tempGoals = new List<ProtoId<StationGoalPrototype>>(station.Goals);
StationGoalPrototype? selGoal = null;
while (tempGoals.Count > 0)
{
var goalId = _random.Pick(tempGoals);
var goalProto = _proto.Index(goalId);
if (playerCount > goalProto.MaxPlayers ||
playerCount < goalProto.MinPlayers)
{
tempGoals.Remove(goalId);
continue;
}
selGoal = goalProto;
break;
}
if (selGoal is null)
return;
if (SendStationGoal(uid, selGoal))
{
Log.Info($"Goal {selGoal.ID} has been sent to station {MetaData(uid).EntityName}");
}
}
}
public bool SendStationGoal(EntityUid? ent, ProtoId<StationGoalPrototype> goal)
{
return SendStationGoal(ent, _proto.Index(goal));
}
/// <summary>
/// Send a station goal on selected station to all faxes which are authorized to receive it.
/// </summary>
/// <returns>True if at least one fax received paper</returns>
public bool SendStationGoal(EntityUid? ent, StationGoalPrototype goal)
{
if (ent is null)
return false;
if (!TryComp<StationDataComponent>(ent, out var stationData))
return false;
var today = DateTime.Today.ToString("dd.MM");
var namesList = new List<string>
{
"names_first_male",
"names_last_male"
};
var operatorName = _randomMeta.GetRandomFromSegments(namesList, " ");
var faxContent = Loc.GetString("engi-station-goal-form",
("station", MetaData(ent.Value).EntityName),
("date", today),
("operator", operatorName),
("text", Loc.GetString(goal.Text)));
var printout = new FaxPrintout(
faxContent,
Loc.GetString("engi-station-goal-fax-paper-name"),
null,
null,
"paper_stamp-centcom",
new List<StampDisplayInfo>
{
new() { StampedName = Loc.GetString("stamp-component-stamped-name-centcom"), StampedColor = Color.FromHex("#006600") },
});
var wasSent = false;
var query = EntityQueryEnumerator<FaxMachineComponent>();
while (query.MoveNext(out var faxUid, out var fax))
{
if (!fax.ReceiveStationGoal)
continue;
var largestGrid = _station.GetLargestGrid(stationData);
var grid = Transform(faxUid).GridUid;
if (grid is not null && largestGrid == grid.Value)
{
_fax.Receive(faxUid, printout, null, fax);
foreach (var spawnEnt in goal.Spawns)
{
SpawnAtPosition(spawnEnt, Transform(faxUid).Coordinates);
}
wasSent = true;
}
}
return wasSent;
}
}
}

View File

@@ -0,0 +1,29 @@
using Robust.Shared.Prototypes;
namespace Content.Server._White._Engi.StationGoal
{
/// <summary>
/// WD
/// </summary>
[Serializable, Prototype("stationGoal")]
public sealed class StationGoalPrototype : IPrototype
{
[IdDataField]
public string ID { get; } = default!;
[DataField]
public string Text { get; set; } = string.Empty;
[DataField]
public int? MinPlayers;
[DataField]
public int? MaxPlayers;
/// <summary>
/// Goal may require certain items to complete. These items will appear near the receving fax machine at the start of the round.
/// </summary>
[DataField]
public List<EntProtoId> Spawns = new();
}
}

View File

@@ -59,6 +59,14 @@ public sealed partial class FaxMachineComponent : Component
[DataField] [DataField]
public bool ReceiveNukeCodes { get; set; } = false; public bool ReceiveNukeCodes { get; set; } = false;
/// <summary>
/// WD.
/// Should that fax receive station goal info
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("receiveStationGoal")]
public bool ReceiveStationGoal { get; set; } = false;
/// <summary> /// <summary>
/// Sound to play when fax has been emagged /// Sound to play when fax has been emagged
/// </summary> /// </summary>

View File

@@ -0,0 +1,11 @@
namespace Content.Shared._White._Engi.BucketHelmet;
/// <summary>
/// WD.
/// This is used for bucket helmet.
/// </summary>
[RegisterComponent]
public sealed partial class BucketHelmetComponent : Component
{
}

View File

@@ -0,0 +1,11 @@
namespace Content.Shared._White._Engi.BucketHelmet;
/// <summary>
/// WD.
/// This is used to block stripping headsets when bucket helmet is on.
/// </summary>
[RegisterComponent]
public sealed partial class PreventStrippingFromEarsComponent : Component
{
}

View File

@@ -0,0 +1,26 @@
using Content.Shared.Damage;
using Robust.Shared.GameStates;
namespace Content.Shared._White._Engi.DamageableClothing;
/// <summary>
/// WD.
/// This component goes on an equippable item that should take damage while in use.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class DamageableClothingComponent : Component
{
/// <summary>
/// The entity that's wearing the item.
/// </summary>
[ViewVariables, AutoNetworkedField]
public EntityUid? User;
/// <summary>
/// The damage modifier to use on item.
/// </summary>
[DataField]
public DamageModifierSet DamageModifier = default!;
}

View File

@@ -0,0 +1,16 @@
namespace Content.Shared._White._Engi.DamageableClothing;
/// <summary>
/// WD.
/// This component gets dynamically added to an Entity via the <see cref="DamageableClothing"/>.
/// </summary>
[RegisterComponent]
public sealed partial class DamageableClothingUserComponent : Component
{
/// <summary>
/// The entity that's also being damaged.
/// </summary>
[DataField]
public EntityUid? ItemId;
}

View File

@@ -0,0 +1,46 @@
using Robust.Shared.Timing;
using Content.Shared.Inventory.Events;
namespace Content.Shared._White._Engi.DamageableClothing;
/// <summary>
/// WD
/// </summary>
public sealed partial class DamageableClothingSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
public override void Initialize()
{
base.Initialize();
InitializeUser();
SubscribeLocalEvent<DamageableClothingComponent, GotEquippedEvent>(OnEquipped);
SubscribeLocalEvent<DamageableClothingComponent, GotUnequippedEvent>(OnUnequipped);
SubscribeLocalEvent<DamageableClothingComponent, ComponentShutdown>(OnShutdown);
}
private void OnEquipped(EntityUid uid, DamageableClothingComponent component, GotEquippedEvent args)
{
if (_gameTiming.ApplyingState)
return;
component.User = args.Equipee;
var userComp = EnsureComp<DamageableClothingUserComponent>(args.Equipee);
userComp.ItemId = args.Equipment;
}
private void OnUnequipped(EntityUid uid, DamageableClothingComponent component, GotUnequippedEvent args)
{
RemCompDeferred<DamageableClothingUserComponent>(args.Equipee);
component.User = null;
}
private void OnShutdown(EntityUid uid, DamageableClothingComponent component, ComponentShutdown args)
{
if (component.User != null)
{
RemCompDeferred<DamageableClothingUserComponent>(component.User.Value);
component.User = null;
}
}
}

View File

@@ -0,0 +1,49 @@
using Content.Shared.Damage;
namespace Content.Shared._White._Engi.DamageableClothing;
/// <summary>
/// WD
/// </summary>
public sealed partial class DamageableClothingSystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
private void InitializeUser()
{
SubscribeLocalEvent<DamageableClothingUserComponent, DamageModifyEvent>(OnUserDamageModified);
SubscribeLocalEvent<DamageableClothingComponent, DamageModifyEvent>(OnDamageModified);
SubscribeLocalEvent<DamageableClothingUserComponent, EntityTerminatingEvent>(OnEntityTerminating);
}
private void OnUserDamageModified(EntityUid uid, DamageableClothingUserComponent component, DamageModifyEvent args)
{
if (TryComp<DamageableClothingComponent>(component.ItemId, out var blocking))
{
if (args.Damage.GetTotal() <= 0)
return;
if (!TryComp<DamageableComponent>(component.ItemId, out var dmgComp))
return;
var blockFraction = 1;
blockFraction = Math.Clamp(blockFraction, 0, 1);
_damageable.TryChangeDamage(component.ItemId, blockFraction * args.OriginalDamage);
}
}
private void OnDamageModified(EntityUid uid, DamageableClothingComponent component, DamageModifyEvent args)
{
var modifier = component.DamageModifier;
args.Damage = DamageSpecifier.ApplyModifierSet(args.Damage, modifier);
}
private void OnEntityTerminating(EntityUid uid, DamageableClothingUserComponent component, ref EntityTerminatingEvent args)
{
if (!TryComp<DamageableClothingComponent>(component.ItemId, out var blockingComponent))
return;
RemCompDeferred<DamageableClothingUserComponent>(uid);
}
}

View File

@@ -0,0 +1,4 @@
ent-ClothingHeadBucketHelmet = шлем из ведра
.desc = Обычное ведро с двумя прорезями для глаз. При ношении на голове что-то липкое внутри цепляется за гарнитуру.
buckethelmet-cant-strip = Шлем из ведра не позволяет это сделать

View File

@@ -0,0 +1,2 @@
ent-ClothingOuterArmorReflectiveGhetto = самодельный отражающий жилет
.desc = Два зеркала соединённые проводами для сомнительной защиты от лазеров.

View File

@@ -0,0 +1,2 @@
ent-MirrorShieldGhetto = самодельный зеркальный щит
.desc = Сделанное на скорую руку зеркало с рукояткой для использования как сомнительная защита от лазеров.

View File

@@ -0,0 +1,5 @@
pacified-by-chaplain = {$target} пасифицирован.
unpacified-by-chaplain = {$target} освобождён.
pacify-by-chaplain = Пасифицировать
unpacify-by-chaplain = Освободить

View File

@@ -0,0 +1,3 @@
ghost-role-information-possessed-blade-name = Одержимый Клинок
ghost-role-information-possessed-blade-description = Вы - Одержимый Клинок. Подчиняйтесь своему владельцу.
ghost-role-information-possessed-blade-rules = Вы не имеете право атаковать своего владельца. Право собственности может быть передано только вашим владельцем.

View File

@@ -0,0 +1,251 @@
ent-StationGoalPaper = цель станции от Центком
.desc = Похоже у вас будет много работы.
engi-station-goal-fax-paper-name = цель станции от Центком
engi-station-goal-form = Постановление Центрального Командования
---------------------------------------------------------------------
Утверждение цели и задачи для станции { $station }
Центральным Командованием № 2562-CU-2
Дата: { $date }.2562 года
---------------------------------------------------------------------
Утвердить следующие цели для космической станции:
{ $text }
---------------------------------------------------------------------
1. Командование станции обязано строго следовать данной цели и заданию, а также предоставить все необходимые ресурсы и усилия для успешного выполнения миссии.
2. Право отменить данное постановление имеет исключительно Центральное Командование.
3. Сотрудникам станции запрещено покидать объект до момента выполнения цели. Исключение - станция находится в критическом состоянии и не является пригодной для жизни.
---------------------------------------------------------------------
Данное Постановление выписано:
И.Ф: { $operator }
Должность: Оператор Центрального Командования
Печать:
engi-station-goal-singularity = [bold]Постройка генератора, основанного на сингулярности.[/bold]
Все детали для цели должны быть заказаны или собраны на станции. Категорически запрещено использовать уже имеющиеся компоненты.
Для успешного выполнения цели необходимо сделать запуск сингулярности.
После окончания смены вся конструкция будет отсоединена от станции и транспортирована на другой объект.
engi-station-goal-solar-panels = [bold]Постройка сети солнечных панелей.[/bold]
Требования:
- Сеть должна состоять из минимум двух ветвей, расположенных на противоположных концах станции.
- Каждая ветвь должна состоять из минимум 36 солнечных панелей.
- Каждая ветвь должна иметь минимум два СМЭСа, несоединённых со станцией.
engi-station-goal-artifacts = [bold]Нахождение и исследование артефактов.[/bold]
Экипаж станции должен найти минимум три артефакта любым способом, отличным от покупки.
Сотрудники научного отдела должны изучить найденные артефакты и задокументировать их свойства.
В качестве документации могут быть приняты отчёты о каждом узле (печатаются на специальной консоли) и отдельный документ с описанием в доступной форме схемы артефакта.
Каждый документ должен быть подтверждён печатью научного руководителя или капитана. Артефакты с документацией должны быть доставлены на станцию центрального командования.
engi-station-goal-bank = [bold]Постройка орбитального хранилища с припасами и технологиями.[/bold]
Хранилище должно быть размещено в космосе, отдельно от основной станции, защищено от метеоритов и иметь автономное питание.
В хранилище должно быть минимум четыре ящика:
- ящик с продвинутыми медикаментами;
- ящик с запасами лучших семян;
- ящик-холодильник еды с высокой питательной ценностью;
- ящик с ценными, но не уникальными платами.
engi-station-goal-zoo = [bold]Улучшение рекреации персонала станции.[/bold]
Для этого инженерный отдел должен построить зоопарк с как минимум 3 (тремя) вольерами. На каждый вольер один вид. Каждый вольер должен быть обеспечен едой для конкретного вида и роботом-уборщиком. Площадь каждого вольера как минимум 16 м².
Животные должны быть заказаны в отделе снабжения.
engi-station-goal-mining-outpost = [bold]Постройка орбитального шахтёрского аванпоста.[/bold]
Аванпост должен быть размещен в космосе, отдельно от основной станции, защищён от метеоритов и иметь автономное питание, гравитацию и атмосферу.
Аванпост должен иметь как минимум две жилые комнаты с освещением и окнами. Оборудование для проведения работ: как минимум по две кирки, сумки для руды. Как минимум два шахтёрских скафандра.
На территории аванпоста должен быть склад для размещения добытого сырья и припасов: как минимум 500u (пятьсот единиц) пива в ящике-холодильнике для закусок. Как минимум по четыре набора медикаментов от механических повреждений.
engi-station-goal-tesla = [bold]Постройка генератора, основанного на Тесле.[/bold]
Все детали для цели должны быть заказаны или собраны на станции. Категорически запрещено использовать уже имеющиеся компоненты.
Для успешного выполнения цели необходимо сделать запуск Теслы.
После окончания смены вся конструкция будет отсоединена от станции и транспортирована на другой объект.
engi-station-goal-security = [bold]Постройка и снабжение тренировочного комплекса для Службы Безопасности, с последующей проверкой состава.[/bold]
В будущем данная станция будет передислоцирована в сектор граничащий с небезопасным.
Задачей Инженерного отдела является постройка тренировочного комплекса, представляющего из себя полосу препятствий. Минимальное время на прохождение среднестатистического, подготовленного офицера, примерно 30 секунд.
Данная полоса должна включать в себя следующее:
- Змееобразные коридоры стекла.
- Различные препятствия для перелезания.
- Деревянную постройку с мишенями, имитирующую захват случайного отдела.
Инженерный отдел в праве строить и другие безопасные виды препятствий.
Задачей Медицинского отдела является изготовление партии таблеток Эфедрина, дозировкой 10u каждая, в минимальном количестве 10 шт, с последующей передачей на хранение в защищенном контейнере Смотрителю станции.
Задачей Службы Безопасности является проведение для каждого члена своего отдела тренировки на данной полосе с письменной фиксацией результатов. В результатах должно быть описано Имя и Фамилия сотрудника, а так же время за которое им была пройдена полоса. Лучшие сотрудники получат шанс на контракт о последующей работе на следующей смене данной станции. Результаты каждого сотрудника будет необходимо указать в отчете о состоянии цели.
engi-station-goal-shuttle-med = [bold]Постройка пилотируемого медицинского шаттла.[/bold]
Шаттл должен соответствовать следующим требованиям:
1. Обеспечен стабильным источником питания и резервной батареей СМЭС.
2. Уметь совершать следующие движения: крен, тангаж и рысканье.
3. Доступ к используемому оборудованию внутри отсеков не должен быть затруднён.
4. Иметь на борту химическую лабораторию с соответствующим оборудованием, рассчитанным минимум на одного сотрудника.
5. Иметь отсек для медицинских коек, рассчитанным минимум на десять человек.
6. Иметь на борту отсек с запасами медикаментов и провизии.
Справочная информация для неквалифицированного персонала:
Крен — вращательное движение.
Тангаж — поступательное движение "вперёд" и "назад".
Рысканье — поступательное движение "боком".
engi-station-goal-shuttle-sec = [bold]Постройка пилотируемого десантного шаттла.[/bold]
Шаттл должен соответствовать следующим требованиям:
1. Обеспечен стабильным источником питания и резервной батареей СМЭС.
2. Уметь совершать следующие движения: крен, тангаж и рысканье.
3. Доступ к используемому оборудованию внутри отсеков не должен быть затруднён.
4. Иметь на борту места и снаряжение как минимум на пять офицеров СБ.
Снаряжение для каждого офицера должно представлять из себя хотя бы один вид легального огнестрельного оружия, полученного не из арсенала, бронежилет, шлем, униформу.
5. Иметь на борту отсек с запасами медикаментов и провизии минимум на пять человек.
Справочная информация для неквалифицированного персонала:
Крен — вращательное движение.
Тангаж — поступательное движение "вперёд" и "назад".
Рысканье — поступательное движение "боком".
engi-station-goal-shuttle-rnd = [bold]Постройка пилотируемого исследовательского шаттла.[/bold]
Шаттл должен соответствовать следующим требованиям:
1. Обеспечен стабильным источником питания и резервной батареей СМЭС.
2. Уметь совершать следующие движения: крен, тангаж и рысканье.
3. Доступ к используемому оборудованию внутри отсеков не должен быть затруднён.
4. Иметь на борту следующие устройства и снаряжение: М.А.К.А.К. (x1), М.А.Р.Т.Ы.Х. (х2), синхронизатор аномалий (x1), магнитные сапоги (х2) и экспериментальный сосуд аномалии (х1), а также как минимум два скафандра EVA и два костюма радиационной защиты.
Справочная информация для неквалифицированного персонала:
Крен — вращательное движение.
Тангаж — поступательное движение "вперёд" и "назад".
Рысканье — поступательное движение "боком".
engi-station-goal-shuttle-srv = [bold]Постройка пилотируемого пассажирского шаттла.[/bold]
Шаттл должен соответствовать следующим требованиям:
1. Обеспечен стабильным источником питания и резервной батареей СМЭС.
2. Уметь совершать следующие движения: крен, тангаж и рысканье.
3. Доступ к используемому оборудованию внутри отсеков не должен быть затруднён.
4. Иметь на борту полностью обустроенный бар, в котором должен быть раздатчик безалкоголя, раздатчик алкоголя, бочка кваса, ящик барных принадлежностей, ящик пополнения раздатчика алкоголя, ящик пополнения раздатчика безалкоголя.
5. Иметь на борту обустроенную кухню, в которой должен быть ящик кухонных припасов и ящик кухонных принадлежностей. А также один гидропонный лоток и холодильник.
6. На борту должны быть приватные комнаты для комфортного проживания как минимум четверых человек.
7. На борту должен быть музыкальный автомат и ящик настольных игр.
Справочная информация для неквалифицированного персонала:
Крен — вращательное движение.
Тангаж — поступательное движение "вперёд" и "назад".
Рысканье — поступательное движение "боком".
engi-station-goal-shuttle-emergency = [bold]Постройка пилотируемого спасательного шаттла.[/bold]
Шаттл должен соответствовать следующим требованиям:
1. Обеспечен стабильным источником питания и резервной батареей СМЭС.
2. Уметь совершать следующие движения: крен, тангаж и рысканье.
3. Доступ к используемому оборудованию внутри отсеков не должен быть затруднён.
4. Иметь на борту ящик медицинских припасов, продвинутый аварийный набор, два ящика с наборами EVA, ящик стекла, два ящика стали, ящик пластали, ящик джетпаков, ящик ИРП.
Справочная информация для неквалифицированного персонала:
Крен — вращательное движение.
Тангаж — поступательное движение "вперёд" и "назад".
Рысканье — поступательное движение "боком".
engi-station-goal-theatre = [bold]Постройка театральной зоны.[/bold]
На данной станции пройдут переговоры с крупными компаниями для заключения партнёрских соглашений.
Театральная зона должна включать в себя:
1. Сцена с минимальным размером в 28м².
2. Минимальная вместимость зала в 21 персону.
3. Закулисье с различными нарядами, музыкальными инструментами, несколькими ящиками игрушек и мехом модели Х.О.Н.К.
4. Комнату или комнаты для четырех актеров. На каждого актера должно приходится по пять любых пирогов.
Материалы для клоунских скафандров вы можете получить из ящика театрального снаряжения.
В случае проведения тестового представления сервисный отдел и командование станции получат вознаграждение по прибытию на Станцию ЦК.
По окончании работ ЦК может прислать представителя для проведения тестового представления.
engi-station-goal-ai = [bold]Постройка автономного отсека ИИ.[/bold]
По окончанию строительства отсек должен быть отстыкован от станции и отправлен дрейфовать в космосе.
Требования:
1. Автономное питание на солнечных панелях или РИТЭГ, подключенные к СМЭС и Подстанции.
2. Иметь отсек для позитронного мозга.
3. Консоль сканера массы.
4. Два борга без позитронного мозга: инженерного и научного назначения.
5. Шлюз в отсек с командным доступом.
6. Сервер коммуникации и маршрутизатор проводных камер.
7. Снаружи отсек должен быть окружён контуром охлаждения.
Контур охлаждения должен представлять собой канал, шириной не менее одного метра, полностью заполненный любым газом, кроме обычной воздушной смеси, при температуре ниже -100 градусов по Цельсию и давлении как минимум в 3 раза превышающем атмосферное. Контур должен опоясывать не менее 80% модуля.
Рекомендуется предпринять дополнительные меры безопасности:
- Защиту от метеоритов.
- Сеть вокруг отсека под высоким напряжением.
engi-station-goal-botany = [bold]Постройка теплиц и выведение приспособленных к температуре растений.[/bold]
На станции или вблизи неё требуется построить три отсека с контролируемым климатом:
- Отсек с температурой 5 градусов Цельсия.
- Отсек с температурой 25 градусов Цельсия.
- Отсек с температурой 45 градусов Цельсия.
Каждый отсек необходимо снабдить минимум шестью гидропонными лотками и полным резервуаром с водой.
В каждом отсеке должно находится хотя бы одно растение, приспособленное к температуре отсека.
engi-station-goal-bunker = [bold]Приспособить станцию к мощным гиперэнергетическим потокам.[/bold]
Необходимо пристроить каждому отделу комнату, далее именуемой “бункер”, в которой экипаж станции мог бы укрыться от последствий гиперэнергетических потоков.
Требования к бункеру:
1. Минимальный размер 25м².
2. Укреплённые стены.
3. Вход через два непрозрачных шлюза с соответствующим отделу доступом.
4. От четырех кресел пилота.
5. Содержать базовые лекарства в виде таблеток со справкой о их назначении и наборы от механических повреждений.
6. Запасы провизии с расчетом на четыре человека, на срок от 72 часов.
7. Автономное питание и канистры с воздухом и кислородом.
8. Шкафчики со снаряжением для биологической и радиационной защиты. Так же аварийные скафандры EVA и костюм сапёра.
9. Интерком с общим ключом шифрования.
engi-station-goal-circus = [bold]Постройка полноценного цирка хомяков.[/bold]
На данной станции пройдут переговоры с крупными компаниями для заключения партнёрских соглашений.
Цирковая зона должна включать в себя:
1. Сцена с минимальным размером в 10м².
2. Минимальная вместимость зала в 10 персон.
3. Закулисье с различными нарядами, музыкальными инструментами и несколькими ящиками игрушек.
4. Комнату дял клеток с хомяками. На каждого актера должно приходится по два уникальных костюма.
В случае проведения тестового представления сервисный отдел и командование станции получат вознаграждение по прибытию на Станцию ЦК.
По окончании работ ЦК может прислать представителя для проведения тестового представления.
station-goal-biodome = [bold]Постройка биокупола для исследования и выращивания аномальных организмов.[/bold]
Требования к проекту:
- Купол с регулируемой атмосферой для выращивания и изучения аномалии "Плоть" и/или "Цветок".
- Наличие системы безопасного входа/выхода для Купола.
- Наличие системы безопасности для защиты от биологических угроз и утечки опасных веществ.
- Наличие системы экстренной отчистки Купола от биологического материала.
- Создание научной группы для проведения экспериментов и анализов собранных образцов.
Проект считается завершённым при успешной реализации созданной Куполом продукции на 10000 (десять тысяч) кредитов.

View File

@@ -1,3 +1,3 @@
send-station-goal-command-description = Отправляет выбранную цель станции на всех факсы способные её принять send-station-goal-command-description = WD. Отправляет выбранную цель станции на все факсы способные её принять
send-station-goal-command-help-text = Использование: { $command } <id-цели> send-station-goal-command-help-text = Использование: { $command } <id-цели>
send-station-goal-command-arg-id = <ID цели> send-station-goal-command-arg-id = <ID цели>

View File

@@ -66,3 +66,7 @@
- type: PhysicalComposition - type: PhysicalComposition
materialComposition: materialComposition:
Plastic: 50 Plastic: 50
- type: Construction # WD
deconstructionTarget: null
graph: ClothingHeadBucketHelmet
node: start

View File

@@ -28,3 +28,7 @@
storedRotation: -44 # WD storedRotation: -44 # WD
shape: # WD shape: # WD
- 0,0,1,3 - 0,0,1,3
- type: KnockDownOnHit
knockDownBehavior: NoDrop
knockdownTime: 0.8
requireWield: true

View File

@@ -39,3 +39,7 @@
isBloodDagger: false isBloodDagger: false
- type: UseDelay - type: UseDelay
delay: 1 delay: 1
- type: KnockDownOnHit
knockDownBehavior: NoDrop
knockdownTime: 0.8
requireWield: true

View File

@@ -82,6 +82,7 @@
- type: FaxMachine - type: FaxMachine
name: "Central Command" name: "Central Command"
notifyAdmins: true notifyAdmins: true
receiveStationGoal: true # WD
- type: entity - type: entity
parent: FaxMachineBase parent: FaxMachineBase
@@ -109,5 +110,6 @@
- type: FaxMachine - type: FaxMachine
name: "Captain's Office" name: "Captain's Office"
receiveNukeCodes: true receiveNukeCodes: true
receiveStationGoal: true # WD
- type: StealTarget - type: StealTarget
stealGroup: FaxMachineCaptain stealGroup: FaxMachineCaptain

View File

@@ -263,11 +263,11 @@
sprite: White/Objects/Weapons/Chaplain/scythe-inhands.rsi sprite: White/Objects/Weapons/Chaplain/scythe-inhands.rsi
- type: Sharp - type: Sharp
# Может пиздеть # Может пиздеть и может давать пизды
- type: entity - type: entity
parent: HolyKatana parent: HolyKatana
id: PossessedBlade id: PossessedBlade
name: одержимый клинок name: Одержимый Клинок
description: Когда на станции царит хаос, приятно иметь рядом друга. description: Когда на станции царит хаос, приятно иметь рядом друга.
components: components:
- type: Sprite - type: Sprite
@@ -281,9 +281,9 @@
- suitStorage - suitStorage
- type: GhostRole - type: GhostRole
allowSpeech: true allowSpeech: true
name: Одержимый Клинок name: ghost-role-information-possessed-blade-name
description: Вы - одержимый клинок. Подчиняйтесь своему владельцу. description: ghost-role-information-possessed-blade-description
rules: ghost-role-component-default-rules rules: ghost-role-information-possessed-blade-rules
- type: GhostTakeoverAvailable - type: GhostTakeoverAvailable
- type: Examiner - type: Examiner
- type: Item - type: Item
@@ -292,6 +292,14 @@
shape: shape:
- 0, 0, 1, 3 - 0, 0, 1, 3
sprite: White/Objects/Weapons/Chaplain/possessed.rsi sprite: White/Objects/Weapons/Chaplain/possessed.rsi
- type: DamageOtherOnHit
damage:
types:
Slash: 13
- type: CombatMode
- type: UseDelay
delay: 2.0
- type: PacifiedOnChaplainAction
# Приклеен к руке, быстро и громко бьет # Приклеен к руке, быстро и громко бьет
- type: entity - type: entity
@@ -494,6 +502,9 @@
soundSwing: soundSwing:
collection: HammerMiss collection: HammerMiss
- type: DisarmMalus - type: DisarmMalus
- type: KnockDownOnHit
knockDownBehavior: NoDrop
knockdownTime: 0.4
# Имеет все инструменты в себе, но работает медленно и почти не наносит урона # Имеет все инструменты в себе, но работает медленно и почти не наносит урона
- type: entity - type: entity

View File

@@ -0,0 +1,26 @@
- type: entity
parent: ClothingHeadBase
id: ClothingHeadBucketHelmet
name: bucket helmet
description: A regular bucket with two eye holes. When worn on the head, something sticky inside latches on the earpiece.
components:
- type: Sprite
sprite: White/_Engi/Clothing/Head/bucketHelmet.rsi
- type: Clothing
sprite: White/_Engi/Clothing/Head/bucketHelmet.rsi
- type: IdentityBlocker
- type: Armor
modifiers:
coefficients:
Blunt: 0.95
- type: Tag
tags:
- HidesHair
- WhitelistChameleon
- type: Construction
deconstructionTarget: start
graph: ClothingHeadBucketHelmet
node: helmet
- type: Item
size: Normal
- type: BucketHelmet

View File

@@ -0,0 +1,53 @@
- type: entity
parent: ClothingOuterArmorBasic
id: ClothingOuterArmorReflectiveGhetto
name: makeshift reflective vest
description: Two mirrors connected by wires for dubious laser protection.
components:
- type: Sprite
sprite: White/_Engi/Clothing/OuterClothing/armor_reflect_ghetto.rsi
state: icon
- type: Clothing
sprite: White/_Engi/Clothing/OuterClothing/armor_reflect_ghetto.rsi
- type: Armor
modifiers:
coefficients:
Slash: 0.9
Heat: 0.7
- type: Reflect
reflectProb: 0.7
innate: true
placement:
- Body
reflects:
- Energy
- type: Construction
graph: ClothingOuterArmorReflectiveGhetto
node: vest
- type: DamageableClothing
damageModifier:
coefficients:
Blunt: 2
Slash: 0.9
Piercing: 1.5
Heat: .5
flatReductions:
Heat: 0.5
- type: Damageable
damageContainer: Shield
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 60
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
ShardGlass:
min: 3
max: 5

View File

@@ -0,0 +1,62 @@
- type: entity
name: makeshift mirror shield
parent: BaseItem
id: MirrorShieldGhetto
description: A makeshift mirror with a handle, used as dubious laser protection.
components:
- type: Sprite
sprite: White/_Engi/Objects/Weapons/ghetto_mirror_shield.rsi
state: icon
- type: Item
sprite: White/_Engi/Objects/Weapons/ghetto_mirror_shield.rsi
size: Ginormous
- type: Tag
tags:
- MirrorShieldGhetto
- type: Reflect
reflectProb: 0.7
innate: true
reflects:
- Energy
- type: Blocking
passiveBlockModifier:
coefficients:
Blunt: 2
Slash: 0.9
Piercing: 1.5
Heat: .6
activeBlockModifier:
coefficients:
Blunt: 2
Slash: 0.9
Piercing: 1.5
Heat: .3
flatReductions:
Heat: 0.5
blockSound: !type:SoundPathSpecifier
path: /Audio/Effects/glass_step.ogg
- type: MeleeBlock
- type: Damageable
damageContainer: Shield
- type: Construction
graph: MirrorShieldGhetto
node: shield
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 40
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
ShardGlass:
min: 2
max: 3
- type: StaticPrice
price: 50
- type: DisarmMalus

View File

@@ -0,0 +1,21 @@
- type: constructionGraph
id: ClothingHeadBucketHelmet
start: start
graph:
- node: start
entity: Bucket
edges:
- to: helmet
conditions:
- !type:SolutionEmpty
solution: bucket
steps:
- tool: Cutting
doAfter: 5
- node: helmet
entity: ClothingHeadBucketHelmet
edges:
- to: start
steps:
- tool: Welding
doAfter: 5

View File

@@ -0,0 +1,42 @@
- type: constructionGraph
id: MirrorShieldGhetto
start: start
graph:
- node: start
edges:
- to: shield
steps:
- material: Glass
amount: 5
doAfter: 3
- material: Steel
amount: 3
doAfter: 3
- node: shield
entity: MirrorShieldGhetto
- type: constructionGraph
id: ClothingOuterArmorReflectiveGhetto
start: start
graph:
- node: start
edges:
- to: vest
steps:
- material: Cable
amount: 5
- tag: MirrorShieldGhetto
name: самодельный зеркальный щит
icon:
sprite: White/_Engi/Objects/Weapons/ghetto_mirror_shield.rsi
state: icon
amount: 1
- tag: MirrorShieldGhetto
name: самодельный зеркальный щит
icon:
sprite: White/_Engi/Objects/Weapons/ghetto_mirror_shield.rsi
state: icon
amount: 1
doAfter: 6
- node: vest
entity: ClothingOuterArmorReflectiveGhetto

View File

@@ -0,0 +1,25 @@
- type: construction
name: самодельный зеркальный щит
id: MirrorShieldGhetto
graph: MirrorShieldGhetto
startNode: start
targetNode: shield
category: construction-category-weapons
objectType: Item
description: Сделанное на скорую руку зеркало с рукояткой для использования как сомнительная защита от лазеров.
icon:
sprite: White/_Engi/Objects/Weapons/ghetto_mirror_shield.rsi
state: icon
- type: construction
name: самодельный отражающий жилет
id: ClothingOuterArmorReflectiveGhetto
graph: ClothingOuterArmorReflectiveGhetto
startNode: start
targetNode: vest
category: construction-category-clothing
objectType: Item
description: Два зеркала соединённые проводами для сомнительной защиты от лазеров.
icon:
sprite: White/_Engi/Clothing/OuterClothing/armor_reflect_ghetto.rsi
state: icon

View File

@@ -0,0 +1,75 @@
- type: stationGoal
id: Singularity
text: engi-station-goal-singularity
- type: stationGoal
id: SolarPanels
text: engi-station-goal-solar-panels
- type: stationGoal
id: Artifacts
text: engi-station-goal-artifacts
- type: stationGoal
id: Bank
text: engi-station-goal-bank
- type: stationGoal
id: Zoo
text: engi-station-goal-zoo
- type: stationGoal
id: MiningOutpost
text: engi-station-goal-mining-outpost
- type: stationGoal
id: Tesla
text: engi-station-goal-tesla
- type: stationGoal
id: SecurityTraining
text: engi-station-goal-security
- type: stationGoal
id: ShuttleMed
text: engi-station-goal-shuttle-med
- type: stationGoal
id: ShuttleSec
text: engi-station-goal-shuttle-sec
- type: stationGoal
id: ShuttleRnd
text: engi-station-goal-shuttle-rnd
- type: stationGoal
id: ShuttleSrv
text: engi-station-goal-shuttle-srv
- type: stationGoal
id: ShuttleEmergency
text: engi-station-goal-shuttle-emergency
- type: stationGoal
id: Theatre
text: engi-station-goal-theatre
- type: stationGoal
id: CellAI
text: engi-station-goal-ai
- type: stationGoal
id: Botany
text: engi-station-goal-botany
- type: stationGoal
id: Bunker
text: engi-station-goal-bunker
- type: stationGoal
id: HamsterСircus
text: engi-station-goal-circus
- type: stationGoal
id: Biodome
text: station-goal-biodome

View File

@@ -120,3 +120,6 @@
- type: Tag - type: Tag
id: VoiceActivatedBombImplant id: VoiceActivatedBombImplant
- type: Tag
id: MirrorShieldGhetto

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,18 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "stepppasha",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-HELMET",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

View File

@@ -0,0 +1,26 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "stepppasha",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-OUTERCLOTHING",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

View File

@@ -0,0 +1,22 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from https://github.com/Citadel-Station-13/Citadel-Station-13/commit/84223c65f5caf667a84f3c0f49bc2a41cdc6c4e3",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "inhand-right",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
}
]
}