diff --git a/Content.Server/Administration/Commands/SetOutfitCommand.cs b/Content.Server/Administration/Commands/SetOutfitCommand.cs index a9f1f6a8e4..762d9234b9 100644 --- a/Content.Server/Administration/Commands/SetOutfitCommand.cs +++ b/Content.Server/Administration/Commands/SetOutfitCommand.cs @@ -12,6 +12,9 @@ using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Prototypes; +using Content.Shared.Radio.Components; // Parkstation-IPC +using Content.Shared.Containers; // Parkstation-IPC +using Robust.Shared.Containers; // Parkstation-IPC namespace Content.Server.Administration.Commands { @@ -128,6 +131,35 @@ public static bool SetOutfit(EntityUid target, string gear, IEntityManager entit } } + // Parkstation-IPC-Start + // Pretty much copied from StationSpawningSystem.SpawnStartingGear + if (entityManager.TryGetComponent(target, out var keyHolderComp)) + { + var earEquipString = startingGear.GetGear("ears", profile); + var containerMan = entityManager.System(); + + if (!string.IsNullOrEmpty(earEquipString)) + { + var earEntity = entityManager.SpawnEntity(earEquipString, entityManager.GetComponent(target).Coordinates); + + if (entityManager.TryGetComponent(earEntity, out _) && // I had initially wanted this to spawn the headset, and simply move all the keys over, but the headset didn't seem to have any keys in it when spawned... + entityManager.TryGetComponent(earEntity, out var fillComp) && + fillComp.Containers.TryGetValue(EncryptionKeyHolderComponent.KeyContainerName, out var defaultKeys)) + { + containerMan.CleanContainer(keyHolderComp.KeyContainer); + + foreach (var key in defaultKeys) + { + var keyEntity = entityManager.SpawnEntity(key, entityManager.GetComponent(target).Coordinates); + keyHolderComp.KeyContainer.Insert(keyEntity, force: true); + } + } + + entityManager.QueueDeleteEntity(earEntity); + } + } + // Parkstation-IPC-End + return true; } } diff --git a/Content.Server/Bed/BedSystem.cs b/Content.Server/Bed/BedSystem.cs index 9791eb2621..3cdcf1124c 100644 --- a/Content.Server/Bed/BedSystem.cs +++ b/Content.Server/Bed/BedSystem.cs @@ -16,6 +16,7 @@ using Content.Shared.Mobs.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Timing; +using Content.Shared.SimpleStation14.Silicon.Components; // Parkstation-IPCs // I shouldn't have to modify this. namespace Content.Server.Bed { @@ -74,7 +75,7 @@ public override void Update(float frameTime) foreach (var healedEntity in strapComponent.BuckledEntities) { - if (_mobStateSystem.IsDead(healedEntity)) + if (_mobStateSystem.IsDead(healedEntity) || HasComp(healedEntity)) // Parkstation-IPCs // I shouldn't have to modify this. continue; var damage = bedComponent.Damage; diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index afb53499c3..4943cca654 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -54,7 +54,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem private const string DamageType = "Shock"; // Yes, this is absurdly small for a reason. - private const float ElectrifiedDamagePerWatt = 0.0015f; + public const float ElectrifiedDamagePerWatt = 0.0015f; // Parkstation-IPC // This information is allowed to be public, and was needed in BatteryElectrocuteChargeSystem.cs private const float RecursiveDamageMultiplier = 0.75f; private const float RecursiveTimeMultiplier = 0.8f; @@ -292,7 +292,7 @@ public bool TryDoElectrocution( || !DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects)) return false; - RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true); + RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient, shockDamage), true); // Parkstation-IPC return true; } @@ -338,7 +338,7 @@ private bool TryDoElectrocutionPowered( electrocutionComponent.Electrocuting = uid; electrocutionComponent.Source = sourceUid; - RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true); + RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient, shockDamage), true); // Parkstation-IPC return true; } diff --git a/Content.Server/Nyanotrasen/Borgs/CyborgComponent.cs b/Content.Server/Nyanotrasen/Borgs/CyborgComponent.cs index 6796715f53..d2f74ff00c 100644 --- a/Content.Server/Nyanotrasen/Borgs/CyborgComponent.cs +++ b/Content.Server/Nyanotrasen/Borgs/CyborgComponent.cs @@ -1,6 +1,7 @@ namespace Content.Server.Borgs { + [Obsolete("CyborgComponent is unused on Parkstation, see SiliconComponent")] // Parkstation-IPCs [RegisterComponent] public sealed class CyborgComponent : Component {} -} \ No newline at end of file +} diff --git a/Content.Server/Nyanotrasen/Borgs/CyborgSystem.cs b/Content.Server/Nyanotrasen/Borgs/CyborgSystem.cs index cb96057459..fbac68189a 100644 --- a/Content.Server/Nyanotrasen/Borgs/CyborgSystem.cs +++ b/Content.Server/Nyanotrasen/Borgs/CyborgSystem.cs @@ -5,6 +5,7 @@ namespace Content.Server.Borgs { + [Obsolete("'Cyborg' should be unused on Parkstation, see SiliconSystem")] // Parkstation-IPCs public sealed class Cyborg : EntitySystem { [Dependency] private readonly ChatSystem _chatSystem = default!; @@ -15,7 +16,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnChangeState); } - + private void OnChangeState(EntityUid uid, CyborgComponent component, MobStateChangedEvent args) { if (args.NewMobState == MobState.Dead){ @@ -27,7 +28,7 @@ private void OnChangeState(EntityUid uid, CyborgComponent component, MobStateCha // Stop dead borg from being movable AA cards by removing their ability to bump doors. _tagSystem.RemoveTag(uid, "DoorBumpOpener"); - + } else if(args.NewMobState == MobState.Alive && args.OldMobState == MobState.Dead) { @@ -38,4 +39,4 @@ private void OnChangeState(EntityUid uid, CyborgComponent component, MobStateCha return; } } -} \ No newline at end of file +} diff --git a/Content.Server/Radio/Components/IntrinsicRadioTransmitterComponent.cs b/Content.Server/Radio/Components/IntrinsicRadioTransmitterComponent.cs index eb28bac4ec..cae812eb6c 100644 --- a/Content.Server/Radio/Components/IntrinsicRadioTransmitterComponent.cs +++ b/Content.Server/Radio/Components/IntrinsicRadioTransmitterComponent.cs @@ -13,5 +13,5 @@ namespace Content.Server.Radio.Components; public sealed class IntrinsicRadioTransmitterComponent : Component { [DataField("channels", customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] - public readonly HashSet Channels = new() { SharedChatSystem.CommonChannel }; + public HashSet Channels = new() { SharedChatSystem.CommonChannel }; // Parkstation-IPC // Did this really need to be readonly? :prerealization: } diff --git a/Content.Server/SimpleStation14/Power/Components/BatteryDrinkerComponent.cs b/Content.Server/SimpleStation14/Power/Components/BatteryDrinkerComponent.cs new file mode 100644 index 0000000000..8587f6a89c --- /dev/null +++ b/Content.Server/SimpleStation14/Power/Components/BatteryDrinkerComponent.cs @@ -0,0 +1,31 @@ +namespace Content.Server.SimpleStation14.Power; + +[RegisterComponent] +public sealed class BatteryDrinkerComponent : Component +{ + /// + /// Is this drinker allowed to drink batteries not tagged as ? + /// + [DataField("drinkAll"), ViewVariables(VVAccess.ReadWrite)] + public bool DrinkAll = false; + + /// + /// How long it takes to drink from a battery, in seconds. + /// Is multiplied by the source. + /// + [DataField("drinkSpeed"), ViewVariables(VVAccess.ReadWrite)] + public float DrinkSpeed = 1.5f; + + /// + /// The multiplier for the amount of power to attempt to drink. + /// Default amount is 1000 + /// + [DataField("drinkMultiplier"), ViewVariables(VVAccess.ReadWrite)] + public float DrinkMultiplier = 5f; + + /// + /// The multiplier for how long it takes to drink a non-source battery, if is true. + /// + [DataField("drinkAllMultiplier"), ViewVariables(VVAccess.ReadWrite)] + public float DrinkAllMultiplier = 2.5f; +} diff --git a/Content.Server/SimpleStation14/Power/Components/RandomBatteryChargeComponent.cs b/Content.Server/SimpleStation14/Power/Components/RandomBatteryChargeComponent.cs new file mode 100644 index 0000000000..c13239cbe5 --- /dev/null +++ b/Content.Server/SimpleStation14/Power/Components/RandomBatteryChargeComponent.cs @@ -0,0 +1,26 @@ +using System.Numerics; + +namespace Content.Server.SimpleStation14.Power.Components; + +[RegisterComponent] +public sealed class RandomBatteryChargeComponent : Component +{ + /// + /// The minimum and maximum max charge the battery can have. + /// + [DataField("batteryMaxMinMax")] + public Vector2 BatteryMaxMinMax = new(0.85f, 1.15f); + + /// + /// The minimum and maximum current charge the battery can have. + /// + [DataField("batteryChargeMinMax")] + public Vector2 BatteryChargeMinMax = new(1f, 1f); + + /// + /// False if the randomized charge of the battery should be a multiple of the preexisting current charge of the battery. + /// True if the randomized charge of the battery should be a multiple of the max charge of the battery post max charge randomization. + /// + [DataField("basedOnMaxCharge")] + public bool BasedOnMaxCharge = true; +} diff --git a/Content.Server/SimpleStation14/Power/Components/SiliconEmitSoundOnDrainedComponent.cs b/Content.Server/SimpleStation14/Power/Components/SiliconEmitSoundOnDrainedComponent.cs new file mode 100644 index 0000000000..58b9ac88ba --- /dev/null +++ b/Content.Server/SimpleStation14/Power/Components/SiliconEmitSoundOnDrainedComponent.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; +using Robust.Shared.Audio; +using Content.Server.Sound.Components; + +namespace Content.Server.SimpleStation14.Silicon; + +/// +/// Applies a to a Silicon when its battery is drained, and removes it when it's not. +/// +[RegisterComponent] +public sealed class SiliconEmitSoundOnDrainedComponent : Component +{ + [DataField("sound"), Required] + public SoundSpecifier Sound = default!; + + [DataField("interval")] + public float Interval = 8f; + + [DataField("playChance")] + public float PlayChance = 1f; + + [DataField("popUp")] + public string? PopUp; +} diff --git a/Content.Server/SimpleStation14/Power/Systems/BatteryDrinkerSystem.cs b/Content.Server/SimpleStation14/Power/Systems/BatteryDrinkerSystem.cs new file mode 100644 index 0000000000..902a198f4a --- /dev/null +++ b/Content.Server/SimpleStation14/Power/Systems/BatteryDrinkerSystem.cs @@ -0,0 +1,146 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Server.Power.Components; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.DoAfter; +using Content.Shared.PowerCell.Components; +using Content.Shared.SimpleStation14.Silicon; +using Content.Shared.Verbs; +using Robust.Shared.Utility; +using Content.Server.SimpleStation14.Silicon.Charge; +using Content.Server.Power.EntitySystems; +using Content.Server.Popups; + +namespace Content.Server.SimpleStation14.Power; + +public sealed class BatteryDrinkerSystem : EntitySystem +{ + [Dependency] private readonly ItemSlotsSystem _slots = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly SiliconChargeSystem _silicon = default!; + [Dependency] private readonly PopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(AddAltVerb); + + SubscribeLocalEvent(OnDoAfter); + } + + private void AddAltVerb(EntityUid uid, BatteryComponent batteryComponent, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + if (!TryComp(args.User, out var drinkerComp) || + !TestDrinkableBattery(uid, drinkerComp) || + !TryGetFillableBattery(args.User, out var drinkerBattery, out _)) + return; + + AlternativeVerb verb = new() + { + Act = () => DrinkBattery(uid, args.User, drinkerComp), + Text = Loc.GetString("battery-drinker-verb-drink"), + Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/smite.svg.192dpi.png")), + }; + + args.Verbs.Add(verb); + } + + private bool TestDrinkableBattery(EntityUid target, BatteryDrinkerComponent drinkerComp) + { + if (!drinkerComp.DrinkAll && !HasComp(target)) + return false; + + return true; + } + + private bool TryGetFillableBattery(EntityUid uid, [NotNullWhen(true)] out BatteryComponent? battery, [NotNullWhen(true)] out EntityUid batteryUid) + { + if (_silicon.TryGetSiliconBattery(uid, out battery, out batteryUid)) + return true; + + if (TryComp(uid, out battery)) + return true; + + if (TryComp(uid, out var powerCellSlot) && + _slots.TryGetSlot(uid, powerCellSlot.CellSlotId, out var slot) && + slot.Item != null && + TryComp(slot.Item.Value, out battery)) + { + batteryUid = slot.Item.Value; + return true; + } + + return false; + } + + private void DrinkBattery(EntityUid target, EntityUid user, BatteryDrinkerComponent drinkerComp) + { + var doAfterTime = drinkerComp.DrinkSpeed; + + if (TryComp(target, out var sourceComp)) + doAfterTime *= sourceComp.DrinkSpeedMulti; + else + doAfterTime *= drinkerComp.DrinkAllMultiplier; + + var args = new DoAfterArgs(user, doAfterTime, new BatteryDrinkerDoAfterEvent(), user, target) // TODO: Make this doafter loop, once we merge Upstream. + { + BreakOnDamage = true, + BreakOnTargetMove = true, + Broadcast = false, + DistanceThreshold = 1.35f, + RequireCanInteract = true, + CancelDuplicate = false + }; + + _doAfter.TryStartDoAfter(args); + } + + private void OnDoAfter(EntityUid uid, BatteryDrinkerComponent drinkerComp, DoAfterEvent args) + { + if (args.Cancelled || args.Target == null) + return; + + var source = args.Target.Value; + var drinker = uid; + var sourceBattery = Comp(source); + + TryGetFillableBattery(drinker, out var drinkerBattery, out var drinkerBatteryUid); + + TryComp(source, out var sourceComp); + + DebugTools.AssertNotNull(drinkerBattery); + + if (drinkerBattery == null) + return; + + var amountToDrink = drinkerComp.DrinkMultiplier * 1000; + + amountToDrink = MathF.Min(amountToDrink, sourceBattery.CurrentCharge); + amountToDrink = MathF.Min(amountToDrink, drinkerBattery.MaxCharge - drinkerBattery.CurrentCharge); + + if (sourceComp != null && sourceComp.MaxAmount > 0) + amountToDrink = MathF.Min(amountToDrink, (float) sourceComp.MaxAmount); + + if (amountToDrink <= 0) + { + _popup.PopupEntity(Loc.GetString("battery-drinker-empty", ("target", source)), drinker, drinker); + return; + } + + if (_battery.TryUseCharge(source, amountToDrink, sourceBattery)) + _battery.SetCharge(drinkerBatteryUid, drinkerBattery.Charge + amountToDrink, drinkerBattery); + else + { + _battery.SetCharge(drinker, sourceBattery.Charge + drinkerBattery.Charge, drinkerBattery); + _battery.SetCharge(source, 0, sourceBattery); + } + + if (sourceComp != null && sourceComp.DrinkSound != null) + _audio.PlayPvs(sourceComp.DrinkSound, source); + } +} diff --git a/Content.Server/SimpleStation14/Power/Systems/BatteryElectrocuteChargeSystem.cs b/Content.Server/SimpleStation14/Power/Systems/BatteryElectrocuteChargeSystem.cs new file mode 100644 index 0000000000..86238aab6c --- /dev/null +++ b/Content.Server/SimpleStation14/Power/Systems/BatteryElectrocuteChargeSystem.cs @@ -0,0 +1,38 @@ +using Content.Server.Electrocution; +using Content.Server.Popups; +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Shared.Electrocution; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.SimpleStation14.Power.Systems; + +public sealed class BatteryElectrocuteChargeSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly BatterySystem _battery = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnElectrocuted); + } + + private void OnElectrocuted(EntityUid uid, BatteryComponent battery, ElectrocutedEvent args) + { + if (args.ShockDamage == null || args.ShockDamage <= 0) + return; + + var damagePerWatt = ElectrocutionSystem.ElectrifiedDamagePerWatt * 2; + + var damage = args.ShockDamage.Value * args.SiemensCoefficient; + var charge = Math.Min(damage / damagePerWatt, battery.MaxCharge * 0.25f) * _random.NextFloat(0.75f, 1.25f); + + _battery.SetCharge(uid, battery.CurrentCharge + charge); + + _popup.PopupEntity(Loc.GetString("battery-electrocute-charge"), uid, uid); + } +} diff --git a/Content.Server/SimpleStation14/Power/Systems/RandomBatteryChargeSystem.cs b/Content.Server/SimpleStation14/Power/Systems/RandomBatteryChargeSystem.cs new file mode 100644 index 0000000000..eb3b53628a --- /dev/null +++ b/Content.Server/SimpleStation14/Power/Systems/RandomBatteryChargeSystem.cs @@ -0,0 +1,43 @@ +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Server.SimpleStation14.Power.Components; +using Robust.Shared.Random; +using Robust.Shared.Utility; + +namespace Content.Server.SimpleStation14.Power.Systems; + +public sealed class RandomBatteryFillSystem : EntitySystem +{ + [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnBatteryInit); + } + + private void OnBatteryInit(EntityUid uid, RandomBatteryChargeComponent component, ComponentInit args) + { + var batteryComp = Comp(uid); + DebugTools.AssertNotNull(batteryComp); + + if (batteryComp == null) + return; + + var (minMaxMod, maxMaxMod) = component.BatteryMaxMinMax; + var (minChargeMod, maxChargeMod) = component.BatteryChargeMinMax; + + var newMax = batteryComp.MaxCharge * _random.NextFloat(minMaxMod, maxMaxMod); + float newCharge; + + if (component.BasedOnMaxCharge) + newCharge = newMax * _random.NextFloat(minChargeMod, maxChargeMod); + else + newCharge = batteryComp.CurrentCharge * _random.NextFloat(minChargeMod, maxChargeMod); + + _battery.SetMaxCharge(uid, newMax); + _battery.SetCharge(uid, newCharge); + } +} diff --git a/Content.Server/SimpleStation14/Power/Systems/SiliconEmitSoundOnDrainedSystem.cs b/Content.Server/SimpleStation14/Power/Systems/SiliconEmitSoundOnDrainedSystem.cs new file mode 100644 index 0000000000..a9a29fed37 --- /dev/null +++ b/Content.Server/SimpleStation14/Power/Systems/SiliconEmitSoundOnDrainedSystem.cs @@ -0,0 +1,40 @@ +using Content.Server.SimpleStation14.Silicon.Death; +using Content.Server.Sound.Components; +using Content.Shared.Mobs; +using Content.Shared.SimpleStation14.Silicon.Systems; + +namespace Content.Server.SimpleStation14.Silicon; + +public sealed class EmitSoundOnCritSystem : EntitySystem +{ + public override void Initialize() + { + SubscribeLocalEvent(OnDeath); + SubscribeLocalEvent(OnAlive); + SubscribeLocalEvent(OnStateChange); + } + + private void OnDeath(EntityUid uid, SiliconEmitSoundOnDrainedComponent component, SiliconChargeDeathEvent args) + { + var spamComp = EnsureComp(uid); + + spamComp.Accumulator = 0f; + spamComp.RollInterval = component.Interval; + spamComp.PlayChance = component.PlayChance; + spamComp.PopUp = component.PopUp; + spamComp.Enabled = true; + spamComp.Sound = component.Sound; + } + + private void OnAlive(EntityUid uid, SiliconEmitSoundOnDrainedComponent component, SiliconChargeAliveEvent args) + { + RemComp(uid); // This component is bad and I don't feel like making a janky work around because of it. + // If you give something the SiliconEmitSoundOnDrainedComponent, know that it can't have the SpamEmitSoundComponent, and any other systems that play with it will just be broken. + } + + public void OnStateChange(EntityUid uid, SiliconEmitSoundOnDrainedComponent component, MobStateChangedEvent args) + { + if (args.NewMobState == MobState.Dead) + RemComp(uid); + } +} diff --git a/Content.Server/SimpleStation14/Radio/IntrinsicRadioKeySystem.cs b/Content.Server/SimpleStation14/Radio/IntrinsicRadioKeySystem.cs new file mode 100644 index 0000000000..32dad9f078 --- /dev/null +++ b/Content.Server/SimpleStation14/Radio/IntrinsicRadioKeySystem.cs @@ -0,0 +1,32 @@ +using Content.Server.Radio.Components; +using Content.Shared.Radio; +using Content.Shared.Radio.Components; + +namespace Content.Server.SimpleStation14.Radio; + +public sealed class IntrinsicRadioKeySystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnTransmitterChannelsChanged); + SubscribeLocalEvent(OnReceiverChannelsChanged); + } + + private void OnTransmitterChannelsChanged(EntityUid uid, IntrinsicRadioTransmitterComponent component, EncryptionChannelsChangedEvent args) + { + UpdateChannels(uid, args.Component, ref component.Channels); + } + + private void OnReceiverChannelsChanged(EntityUid uid, ActiveRadioComponent component, EncryptionChannelsChangedEvent args) + { + UpdateChannels(uid, args.Component, ref component.Channels); + } + + private void UpdateChannels(EntityUid _, EncryptionKeyHolderComponent keyHolderComp, ref HashSet channels) + { + channels.Clear(); + channels.UnionWith(keyHolderComp.Channels); + } +} diff --git a/Content.Server/SimpleStation14/Silicon/Charge/Components/BatteryDrinkerSourceComponent.cs b/Content.Server/SimpleStation14/Silicon/Charge/Components/BatteryDrinkerSourceComponent.cs new file mode 100644 index 0000000000..0a89f151e7 --- /dev/null +++ b/Content.Server/SimpleStation14/Silicon/Charge/Components/BatteryDrinkerSourceComponent.cs @@ -0,0 +1,27 @@ +using Robust.Shared.Audio; + +namespace Content.Server.SimpleStation14.Silicon.Charge; + +[RegisterComponent] +public sealed class BatteryDrinkerSourceComponent : Component +{ + /// + /// The max amount of power this source can provide in one sip. + /// No limit if null. + /// + [DataField("maxAmount"), ViewVariables(VVAccess.ReadWrite)] + public int? MaxAmount = null; + + /// + /// The multiplier for the drink speed. + /// + [DataField("drinkSpeedMulti"), ViewVariables(VVAccess.ReadWrite)] + public float DrinkSpeedMulti = 1f; + + /// + /// The sound to play when the battery gets drunk from. + /// Can be null. + /// + [DataField("drinkSound")] + public SoundSpecifier? DrinkSound = null; +} diff --git a/Content.Server/SimpleStation14/Silicon/Charge/Components/SiliconDownOnDeadComponent.cs b/Content.Server/SimpleStation14/Silicon/Charge/Components/SiliconDownOnDeadComponent.cs new file mode 100644 index 0000000000..d5410b14ba --- /dev/null +++ b/Content.Server/SimpleStation14/Silicon/Charge/Components/SiliconDownOnDeadComponent.cs @@ -0,0 +1,34 @@ +using System.Threading; + +namespace Content.Server.SimpleStation14.Silicon.Death; + +/// +/// Marks a Silicon as becoming incapacitated when they run out of battery charge. +/// +/// +/// Uses the Silicon System's charge states to do so, so make sure they're a battery powered Silicon. +/// +[RegisterComponent] +public sealed class SiliconDownOnDeadComponent : Component +{ + /// + /// Cancellation token for the silicon's wake timer. + /// + public CancellationTokenSource? WakeToken { get; set; } + + /// + /// The time it will take for a Silicon to "wake up" after leaving the Dead state, in seconds. + /// + /// + /// If not zero, the Silicon will not actually come back to life until after this much time has passed. + /// This can prevent 'flickering' between the two states. + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("deadBuffer")] + public float DeadBuffer { get; set; } = 2.5f; + + /// + /// Is this Silicon currently dead? + /// + public bool Dead { get; set; } = false; +} diff --git a/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargeDeathSystem.cs b/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargeDeathSystem.cs new file mode 100644 index 0000000000..78f37c0919 --- /dev/null +++ b/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargeDeathSystem.cs @@ -0,0 +1,138 @@ +using Content.Server.Power.Components; +using Content.Shared.SimpleStation14.Silicon.Systems; +using Content.Server.Bed.Sleep; +using Content.Shared.Bed.Sleep; +using Content.Server.Sound.Components; +using Content.Server.SimpleStation14.Silicon.Charge; +using System.Threading; +using Timer = Robust.Shared.Timing.Timer; + +namespace Content.Server.SimpleStation14.Silicon.Death; + +public sealed class SiliconDeathSystem : EntitySystem +{ + [Dependency] private readonly SleepingSystem _sleep = default!; + [Dependency] private readonly SiliconChargeSystem _silicon = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSiliconChargeStateUpdate); + } + + private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, SiliconChargeStateUpdateEvent args) + { + _silicon.TryGetSiliconBattery(uid, out var batteryComp, out var batteryUid); + + if (args.ChargeState == ChargeState.Dead && siliconDeadComp.Dead) + { + siliconDeadComp.WakeToken?.Cancel(); + return; + } + + if (args.ChargeState == ChargeState.Dead && !siliconDeadComp.Dead) + SiliconDead(uid, siliconDeadComp, batteryComp, batteryUid); + else if (args.ChargeState != ChargeState.Dead && siliconDeadComp.Dead) + { + if (siliconDeadComp.DeadBuffer > 0) + { + siliconDeadComp.WakeToken?.Cancel(); // This should never matter, but better safe than loose timers. + + var wakeToken = new CancellationTokenSource(); + siliconDeadComp.WakeToken = wakeToken; + + // If battery is dead, wait the dead buffer time and then wake it up. + Timer.Spawn(TimeSpan.FromSeconds(siliconDeadComp.DeadBuffer), () => + { + if (wakeToken.IsCancellationRequested) + return; + + SiliconUnDead(uid, siliconDeadComp, batteryComp, batteryUid); + }, wakeToken.Token); + } + else + SiliconUnDead(uid, siliconDeadComp, batteryComp, batteryUid); + } + } + + private void SiliconDead(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, BatteryComponent? batteryComp, EntityUid batteryUid) + { + var deadEvent = new SiliconChargeDyingEvent(uid, batteryComp, batteryUid); + RaiseLocalEvent(uid, deadEvent); + + if (deadEvent.Cancelled) + return; + + EntityManager.EnsureComponent(uid); + EntityManager.EnsureComponent(uid); + + siliconDeadComp.Dead = true; + + RaiseLocalEvent(uid, new SiliconChargeDeathEvent(uid, batteryComp, batteryUid)); + } + + private void SiliconUnDead(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, BatteryComponent? batteryComp, EntityUid batteryUid) + { + _sleep.TryWaking(uid, null, true); + + siliconDeadComp.Dead = false; + + RaiseLocalEvent(uid, new SiliconChargeAliveEvent(uid, batteryComp, batteryUid)); + } +} + +/// +/// A cancellable event raised when a Silicon is about to go down due to charge. +/// +/// +/// This probably shouldn't be modified unless you intend to fill the Silicon's battery, +/// as otherwise it'll just be triggered again next frame. +/// +public sealed class SiliconChargeDyingEvent : CancellableEntityEventArgs +{ + public EntityUid SiliconUid { get; } + public BatteryComponent? BatteryComp { get; } + public EntityUid BatteryUid { get; } + + public SiliconChargeDyingEvent(EntityUid siliconUid, BatteryComponent? batteryComp, EntityUid batteryUid) + { + SiliconUid = siliconUid; + BatteryComp = batteryComp; + BatteryUid = batteryUid; + } +} + +/// +/// An event raised after a Silicon has gone down due to charge. +/// +public sealed class SiliconChargeDeathEvent : EntityEventArgs +{ + public EntityUid SiliconUid { get; } + public BatteryComponent? BatteryComp { get; } + public EntityUid BatteryUid { get; } + + public SiliconChargeDeathEvent(EntityUid siliconUid, BatteryComponent? batteryComp, EntityUid batteryUid) + { + SiliconUid = siliconUid; + BatteryComp = batteryComp; + BatteryUid = batteryUid; + } +} + +/// +/// An event raised after a Silicon has reawoken due to an increase in charge. +/// +public sealed class SiliconChargeAliveEvent : EntityEventArgs +{ + public EntityUid SiliconUid { get; } + public BatteryComponent? BatteryComp { get; } + public EntityUid BatteryUid { get; } + + public SiliconChargeAliveEvent(EntityUid siliconUid, BatteryComponent? batteryComp, EntityUid batteryUid) + { + SiliconUid = siliconUid; + BatteryComp = batteryComp; + BatteryUid = batteryUid; + } +} diff --git a/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargeSystem.cs b/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargeSystem.cs new file mode 100644 index 0000000000..de72042425 --- /dev/null +++ b/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargeSystem.cs @@ -0,0 +1,212 @@ +using Robust.Shared.Random; +using Content.Shared.SimpleStation14.Silicon.Components; +using Content.Server.Power.Components; +using Content.Shared.Mobs.Systems; +using Content.Server.Temperature.Components; +using Content.Server.Atmos.Components; +using Content.Server.Atmos.EntitySystems; +using Content.Server.Popups; +using Content.Shared.Popups; +using Content.Shared.SimpleStation14.Silicon.Systems; +using Content.Shared.Movement.Systems; +using Content.Server.Body.Components; +using Content.Server.Power.EntitySystems; +using Robust.Shared.Containers; +using System.Diagnostics.CodeAnalysis; +using Robust.Shared.Timing; +using Content.Shared.SimpleStation14.CCVar; +using Robust.Shared.Configuration; +using Robust.Shared.Utility; + +namespace Content.Server.SimpleStation14.Silicon.Charge; + +public sealed class SiliconChargeSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly FlammableSystem _flammable = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly MovementSpeedModifierSystem _moveMod = default!; + [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IConfigurationManager _config = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSiliconStartup); + } + + public bool TryGetSiliconBattery(EntityUid silicon, [NotNullWhen(true)] out BatteryComponent? batteryComp, out EntityUid batteryUid) + { + batteryComp = null; + batteryUid = silicon; + + if (!EntityManager.TryGetComponent(silicon, out SiliconComponent? siliconComp)) + return false; + + if (siliconComp.BatteryContainer != null && + siliconComp.BatteryContainer.ContainedEntities.Count > 0 && + TryComp(siliconComp.BatteryContainer.ContainedEntities[0], out batteryComp)) + { + batteryUid = siliconComp.BatteryContainer.ContainedEntities[0]; + return true; + } + + if (TryComp(silicon, out batteryComp)) + return true; + + return false; + } + + private void OnSiliconStartup(EntityUid uid, SiliconComponent component, ComponentStartup args) + { + if (component.BatterySlot == null) + return; + + var container = _container.GetContainer(uid, component.BatterySlot); + component.BatteryContainer = container; + + if (component.EntityType.GetType() != typeof(SiliconType)) + DebugTools.Assert("SiliconComponent.EntityType is not a SiliconType enum."); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + // For each siliconComp entity with a battery component, drain their charge. + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var silicon, out var siliconComp)) + { + if (!siliconComp.BatteryPowered) + continue; + + // Check if the Silicon is an NPC, and if so, follow the delay as specified in the CVAR. + if (siliconComp.EntityType.Equals(SiliconType.Npc)) + { + var updateTime = _config.GetCVar(SimpleStationCCVars.SiliconNpcUpdateTime); + if (_timing.CurTime - siliconComp.LastDrainTime < TimeSpan.FromSeconds(updateTime)) + continue; + + siliconComp.LastDrainTime = _timing.CurTime; + } + + // If you can't find a battery, set the indicator and skip it. + if (!TryGetSiliconBattery(silicon, out var batteryComp, out var battery)) + { + UpdateChargeState(battery, ChargeState.Invalid, siliconComp); + continue; + } + + // If the silicon is dead, skip it. + if (_mobState.IsDead(silicon)) + continue; + + var drainRate = siliconComp.DrainPerSecond; + + // All multipliers will be subtracted by 1, and then added together, and then multiplied by the drain rate. This is then added to the base drain rate. + // This is to stop exponential increases, while still allowing for less-than-one multipliers. + var drainRateFinalAddi = 0f; + + // TODO: Devise a method of adding multis where other systems can alter the drain rate. + // Maybe use something similar to refreshmovespeedmodifiers, where it's stored in the component. + // Maybe it doesn't matter, and stuff should just use static drain? + if (!siliconComp.EntityType.Equals(SiliconType.Npc)) // Don't bother checking heat if it's an NPC. It's a waste of time, and it'd be delayed due to the update time. + drainRateFinalAddi += SiliconHeatEffects(silicon, frameTime) - 1; // This will need to be changed at some point if we allow external batteries, since the heat of the Silicon might not be applicable. + + // Ensures that the drain rate is at least 10% of normal, + // and would allow at least 4 minutes of life with a max charge, to prevent cheese. + drainRate += Math.Clamp(drainRateFinalAddi, drainRate * -0.9f, batteryComp.MaxCharge / 240); + + // Drain the battery. + _battery.UseCharge(battery, frameTime * drainRate, batteryComp); + + // Figure out the current state of the Silicon. + var chargePercent = batteryComp.CurrentCharge / batteryComp.MaxCharge; + + var currentState = chargePercent switch + { + var x when x > siliconComp.ChargeThresholdMid => ChargeState.Full, + var x when x > siliconComp.ChargeThresholdLow => ChargeState.Mid, + var x when x > siliconComp.ChargeThresholdCritical => ChargeState.Low, + var x when x > 0 || siliconComp.ChargeThresholdCritical == 0 => ChargeState.Critical, + _ => ChargeState.Dead, + }; + + UpdateChargeState(silicon, currentState, siliconComp); + } + } + + /// + /// Checks if anything needs to be updated, and updates it. + /// + public void UpdateChargeState(EntityUid uid, ChargeState state, SiliconComponent component) + { + if (component.ChargeState == state) + return; + + component.ChargeState = state; + + RaiseLocalEvent(uid, new SiliconChargeStateUpdateEvent(state)); + + _moveMod.RefreshMovementSpeedModifiers(uid); + } + + private float SiliconHeatEffects(EntityUid silicon, float frameTime) + { + if (!EntityManager.TryGetComponent(silicon, out var temperComp) || + !EntityManager.TryGetComponent(silicon, out var thermalComp)) + { + return 0; + } + + var siliconComp = EntityManager.GetComponent(silicon); + + // If the Silicon is hot, drain the battery faster, if it's cold, drain it slower, capped. + var upperThresh = thermalComp.NormalBodyTemperature + thermalComp.ThermalRegulationTemperatureThreshold; + var upperThreshHalf = thermalComp.NormalBodyTemperature + thermalComp.ThermalRegulationTemperatureThreshold * 0.5f; + + // Check if the silicon is in a hot environment. + if (temperComp.CurrentTemperature > upperThreshHalf) + { + // Divide the current temp by the max comfortable temp capped to 4, then add that to the multiplier. + var hotTempMulti = Math.Min(temperComp.CurrentTemperature / upperThreshHalf, 4); + + // If the silicon is hot enough, it has a chance to catch fire. + + siliconComp.OverheatAccumulator += frameTime; + if (siliconComp.OverheatAccumulator >= 5) + { + siliconComp.OverheatAccumulator -= 5; + + if (EntityManager.TryGetComponent(silicon, out var flamComp) && + temperComp.CurrentTemperature > temperComp.HeatDamageThreshold && + !flamComp.OnFire && + _random.Prob(Math.Clamp(temperComp.CurrentTemperature / (upperThresh * 5), 0.001f, 0.9f))) + { + _flammable.Ignite(silicon, flamComp); + } + else if ((flamComp == null || !flamComp.OnFire) && + _random.Prob(Math.Clamp(temperComp.CurrentTemperature / upperThresh, 0.001f, 0.75f))) + { + _popup.PopupEntity(Loc.GetString("silicon-overheating"), silicon, silicon, PopupType.SmallCaution); + } + } + + return hotTempMulti; + } + + // Check if the silicon is in a cold environment. + if (temperComp.CurrentTemperature < thermalComp.NormalBodyTemperature) + { + var coldTempMulti = 0.5f + temperComp.CurrentTemperature / thermalComp.NormalBodyTemperature * 0.5f; + + return coldTempMulti; + } + + return 0; + } +} diff --git a/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargerSystem.cs b/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargerSystem.cs new file mode 100644 index 0000000000..6ba644d268 --- /dev/null +++ b/Content.Server/SimpleStation14/Silicon/Charge/Systems/SiliconChargerSystem.cs @@ -0,0 +1,325 @@ +using System.Linq; +using Content.Server.Construction; +using Content.Server.Explosion.Components; +using Content.Server.Explosion.EntitySystems; +using Content.Server.Hands.Systems; +using Content.Server.Popups; +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Server.Storage.Components; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Damage; +using Content.Shared.Damage.Prototypes; +using Content.Shared.Hands.Components; +using Content.Shared.Interaction.Components; +using Content.Shared.Inventory; +using Content.Shared.Popups; +using Content.Shared.PowerCell.Components; +using Content.Shared.SimpleStation14.Silicon; +using Content.Shared.SimpleStation14.Silicon.Charge; +using Content.Shared.StepTrigger.Components; +using Robust.Shared.Physics.Events; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.SimpleStation14.Silicon.Charge; + +public sealed class SiliconChargerSystem : EntitySystem +{ + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + [Dependency] private readonly DamageableSystem _damageable = default!; + [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly HandsSystem _hands = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly ExplosionSystem _explosion = default!; + [Dependency] private readonly SharedSiliconChargerSystem _sharedCharger = default!; + [Dependency] private readonly BatterySystem _battery = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SiliconChargeSystem _silicon = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRefreshParts); + SubscribeLocalEvent(OnExamineParts); + + SubscribeLocalEvent(OnStartCollide); + SubscribeLocalEvent(OnEndCollide); + + SubscribeLocalEvent(OnChargerShutdown); + } + + // TODO: Potentially refactor this so it chaches all found entities upon the storage being closed, or stepped on, etc. + // Perhaps a variable for it? Open chargers like the pad wouldn't update to things picked up, but it seems silly to redo it each frame for closed ones. + public override void Update(float frameTime) + { + base.Update(frameTime); + + #region Entity Storage Chargers + // Check for any chargers with the EntityStorageComponent. + var entityStorageQuery = EntityQueryEnumerator(); + while (entityStorageQuery.MoveNext(out var uid, out var chargerComp, out var entStorage)) + { + var wasActive = chargerComp.Active; + chargerComp.Active = false; + + if (TryComp(uid, out var powerComp) && !powerComp.Powered) + { + if (chargerComp.Active != wasActive) + _sharedCharger.UpdateState(uid, chargerComp); + + continue; + } + + foreach (var entity in entStorage.Contents.ContainedEntities) + { + chargerComp.Active = true; + + var chargeRate = chargerComp.ChargeMulti * frameTime * 10; + + HandleChargingEntity(entity, chargeRate, chargerComp, uid, frameTime); + + // Heat up the air in the charger. + if (entStorage.Airtight) + { + var curTemp = entStorage.Air.Temperature; + + entStorage.Air.Temperature += curTemp < chargerComp.TargetTemp ? frameTime * chargerComp.ChargeMulti / 100 : 0; + } + } + + if (chargerComp.Active != wasActive) + _sharedCharger.UpdateState(uid, chargerComp); + } + #endregion Entity Storage Chargers + + #region Step Trigger Chargers + // Check for any chargers with the StepTriggerComponent. + var stepQuery = EntityQueryEnumerator(); + while (stepQuery.MoveNext(out var uid, out var chargerComp, out _)) + { + if (chargerComp.PresentEntities.Count == 0 || + TryComp(uid, out var powerComp) && !powerComp.Powered) + { + if (chargerComp.Active) + { + chargerComp.Active = false; + _sharedCharger.UpdateState(uid, chargerComp); + } + continue; + } + + if (!chargerComp.Active) + { + chargerComp.Active = true; + _sharedCharger.UpdateState(uid, chargerComp); + } + + var chargeRate = frameTime * chargerComp.ChargeMulti / chargerComp.PresentEntities.Count; + + foreach (var entity in chargerComp.PresentEntities.ToList()) + { + HandleChargingEntity(entity, chargeRate, chargerComp, uid, frameTime); + } + } + #endregion Step Trigger Chargers + } + + // Cleanup the sound stream when the charger is destroyed. + private void OnChargerShutdown(EntityUid uid, SiliconChargerComponent component, ComponentShutdown args) + { + component.SoundStream?.Stop(); + } + + /// + /// Handles working out what entities need to have their batteries charged, or be burnt. + /// + private void HandleChargingEntity(EntityUid entity, float chargeRate, SiliconChargerComponent chargerComp, EntityUid chargerUid, float frameTime, bool burn = true) + { + var entitiesToCharge = SearchThroughEntities(entity, burn); + + if (entitiesToCharge.Count == 0) + return; + + chargeRate *= chargerComp.PartsChargeMulti; + + var entitiesToChargeCount = entitiesToCharge.Count; + + foreach (var (entityToCharge, batteryComp) in entitiesToCharge.ToList()) + { + if (batteryComp != null && batteryComp.CurrentCharge >= batteryComp.MaxCharge) + entitiesToChargeCount--; // Remove any full batteries from the count, so they don't impact charge rate. + } + + // Now we charge the entities we found. + chargeRate /= entitiesToChargeCount; + + foreach (var (entityToCharge, batteryComp) in entitiesToCharge.ToList()) + { + if (batteryComp != null) + ChargeBattery(entityToCharge, batteryComp, chargeRate, chargerComp, chargerUid); + else if (TryComp(entityToCharge, out var damageComp)) + BurnEntity(entityToCharge, damageComp, frameTime, chargerComp, chargerUid); + } + } + + private List<(EntityUid, BatteryComponent?)> SearchThroughEntities(EntityUid entity, bool burn = true) + { + var entitiesToCharge = new List<(EntityUid, BatteryComponent?)>(); + + // If the given entity is a silicon, charge their respective battery. + if (_silicon.TryGetSiliconBattery(entity, out var siliconBatteryComp, out var siliconBatteryUid)) + { + entitiesToCharge.Add((siliconBatteryUid, siliconBatteryComp)); + } + + // Or if the given entity has a battery, charge it. + else if (!HasComp(entity) && // Should probably be charged by the entity holding it. Might be too small to be safe. + TryComp(entity, out var batteryComp)) + { + entitiesToCharge.Add((entity, batteryComp)); + } + + // Or if the given entity contains a battery, charge it. + else if (!HasComp(entity) && // Should probably be charged by the entity holding it. Might be too small to be safe. + TryComp(entity, out var cellSlotComp) && + _itemSlots.TryGetSlot(entity, cellSlotComp.CellSlotId, out var slot) && + TryComp(slot.Item, out var cellBattComp)) + { + entitiesToCharge.Add((slot.Item.Value, cellBattComp)); + } + + // Or if the given entity is fleshy, burn the fucker. + else if (burn && + TryComp(entity, out var damageComp) && + damageComp.DamageContainerID == "Biological") + { + entitiesToCharge.Add((entity, null)); + } + + // Now the weird part, we check for any inventories the entities contained may have, and run this function on any entities contained, for a recursive charging effect. + if (TryComp(entity, out var handsComp)) + { + foreach (var heldEntity in _hands.EnumerateHeld(entity, handsComp)) + { + entitiesToCharge.AddRange(SearchThroughEntities(heldEntity)); + } + } + if (TryComp(entity, out var inventoryComp)) + { + foreach (var slot in _inventory.GetSlots(entity, inventoryComp)) + { + if (_inventory.TryGetSlotEntity(entity, slot.Name, out var slotItem)) + entitiesToCharge.AddRange(SearchThroughEntities(slotItem.Value)); + } + } + if (TryComp(entity, out var storageComp)) + { + foreach (var containedEntity in storageComp.StoredEntities!) + { + entitiesToCharge.AddRange(SearchThroughEntities(containedEntity)); + } + } + if (TryComp(entity, out var entStorage)) + { + foreach (var containedEntity in entStorage.Contents.ContainedEntities) + { + entitiesToCharge.AddRange(SearchThroughEntities(containedEntity)); + } + } + + return entitiesToCharge; + } + + private void ChargeBattery(EntityUid entity, BatteryComponent batteryComp, float chargeRate, SiliconChargerComponent chargerComp, EntityUid chargerUid) + { + // Do some math so a charger never charges a battery from zero to full in less than the minimum time, just for the effect of it. + if (chargerComp.ChargeMulti * 10 > batteryComp.MaxCharge / chargerComp.MinChargeTime) + chargeRate /= chargerComp.ChargeMulti * 10 / (batteryComp.MaxCharge / chargerComp.MinChargeTime); + + if (batteryComp.CurrentCharge + chargeRate < batteryComp.MaxCharge) + _battery.SetCharge(entity, batteryComp.CurrentCharge + chargeRate, batteryComp); + else + _battery.SetCharge(entity, batteryComp.MaxCharge, batteryComp); + + // If the battery is too small, explode it. + if ((batteryComp.MaxCharge - batteryComp.CurrentCharge) * 1.2 + batteryComp.MaxCharge < chargerComp.MinChargeSize) + { + if (TryComp(entity, out var explosiveComp)) + _explosion.TriggerExplosive(entity, explosiveComp); + else + _explosion.QueueExplosion(entity, "Default", batteryComp.MaxCharge / 50, 1.5f, 200, user: chargerUid); + } + } + + private void BurnEntity(EntityUid entity, DamageableComponent damageComp, float frameTime, SiliconChargerComponent chargerComp, EntityUid chargerUid) + { + var damage = new DamageSpecifier(_prototypes.Index(chargerComp.DamageType), frameTime * chargerComp.ChargeMulti / 100); + var damageDealt = _damageable.TryChangeDamage(entity, damage, false, true, damageComp, chargerUid); + + if (damageDealt != null && damageDealt.Total > 0 && chargerComp.WarningTime < _timing.CurTime) + { + var popupBurn = Loc.GetString(chargerComp.OverheatString); + _popup.PopupEntity(popupBurn, entity, PopupType.MediumCaution); + + chargerComp.WarningTime = TimeSpan.FromSeconds(_random.Next(3, 7)) + _timing.CurTime; + } + } + + private void OnRefreshParts(EntityUid uid, SiliconChargerComponent component, RefreshPartsEvent args) + { + var chargeMod = args.PartRatings[component.ChargeSpeedPart]; + var efficiencyMod = args.PartRatings[component.ChargeEfficiencyPart]; + + component.PartsChargeMulti = chargeMod * component.UpgradePartsMulti; + // TODO: Variable power draw, with efficiency. + } + + private void OnExamineParts(EntityUid uid, SiliconChargerComponent component, UpgradeExamineEvent args) + { + args.AddPercentageUpgrade("silicon-charger-chargerate-string", component.PartsChargeMulti); + // TODO: Variable power draw, with efficiency. + } + + #region Charger specific + #region Step Trigger Chargers + // When an entity starts colliding with the charger, add it to the list of entities present on the charger if it has the StepTriggerComponent. + private void OnStartCollide(EntityUid uid, SiliconChargerComponent component, ref StartCollideEvent args) + { + if (!HasComp(uid)) + return; + + var target = args.OtherEntity; + + if (component.PresentEntities.Contains(target)) + return; + + if (component.PresentEntities.Count >= component.MaxEntities) + { + _popup.PopupEntity(Loc.GetString("silicon-charger-list-full", ("charger", args.OurEntity)), target, target); + return; + } + + component.PresentEntities.Add(target); + } + + // When an entity stops colliding with the charger, remove it from the list of entities present on the charger. + private void OnEndCollide(EntityUid uid, SiliconChargerComponent component, ref EndCollideEvent args) + { + if (!HasComp(uid)) + return; + + var target = args.OtherEntity; + + if (component.PresentEntities.Contains(target)) + { + component.PresentEntities.Remove(target); + } + } + #endregion Step Trigger Chargers + #endregion Charger specific +} diff --git a/Content.Server/SimpleStation14/Silicon/Systems/SiliconMiscSystem.cs b/Content.Server/SimpleStation14/Silicon/Systems/SiliconMiscSystem.cs new file mode 100644 index 0000000000..d331d8908e --- /dev/null +++ b/Content.Server/SimpleStation14/Silicon/Systems/SiliconMiscSystem.cs @@ -0,0 +1,20 @@ +using Content.Shared.SimpleStation14.Silicon.Components; +using Content.Shared.Bed.Sleep; + +namespace Content.Server.SimpleStation14.Silicon.Misc; + +// This entire thing is fucking stupid and I hate it. +public sealed class SiliconMiscSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnTryingToSleep); + } + + private void OnTryingToSleep(EntityUid uid, SiliconComponent component, ref TryingToSleepEvent args) + { + args.Cancelled = true; + } +} diff --git a/Content.Server/Station/Systems/StationSpawningSystem.cs b/Content.Server/Station/Systems/StationSpawningSystem.cs index c8245362f5..42c753fc65 100644 --- a/Content.Server/Station/Systems/StationSpawningSystem.cs +++ b/Content.Server/Station/Systems/StationSpawningSystem.cs @@ -24,6 +24,9 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; +using Content.Shared.Radio.Components; // Parkstation-IPC +using Content.Shared.Containers; // Parkstation-IPC +using Robust.Shared.Containers; // Parkstation-IPC namespace Content.Server.Station.Systems; @@ -187,6 +190,39 @@ public void EquipStartingGear(EntityUid entity, StartingGearPrototype startingGe } } + // Parkstation-IPC-Start + // This is kinda gross, and weird, and very hardcoded, but it's the best way I could think of to do it. + // This is replicated in SetOutfitCommand.SetOutfit. + // If they have an EncryptionKeyHolderComponent, spawn in their headset, find the + // EncryptionKeyHolderComponent on it, move the keys over, and delete the headset. + if (TryComp(entity, out var keyHolderComp)) + { + var containerMan = EntityManager.System(); + + var earEquipString = startingGear.GetGear("ears", profile); + + if (!string.IsNullOrEmpty(earEquipString)) + { + var earEntity = Spawn(earEquipString, Transform(entity).Coordinates); + + if (TryComp(earEntity, out _) && // I had initially wanted this to spawn the headset, and simply move all the keys over, but the headset didn't seem to have any keys in it when spawned... + TryComp(earEntity, out var fillComp) && + fillComp.Containers.TryGetValue(EncryptionKeyHolderComponent.KeyContainerName, out var defaultKeys)) + { + containerMan.CleanContainer(keyHolderComp.KeyContainer); + + foreach (var key in defaultKeys) + { + var keyEntity = Spawn(key, Transform(entity).Coordinates); + keyHolderComp.KeyContainer.Insert(keyEntity, force: true); + } + } + + EntityManager.QueueDeleteEntity(earEntity); + } + } + // Parkstation-IPC-End + if (!TryComp(entity, out HandsComponent? handsComponent)) return; diff --git a/Content.Server/Temperature/Systems/TemperatureSystem.cs b/Content.Server/Temperature/Systems/TemperatureSystem.cs index 6e422765e0..0a79643123 100644 --- a/Content.Server/Temperature/Systems/TemperatureSystem.cs +++ b/Content.Server/Temperature/Systems/TemperatureSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Administration.Logs; using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; +using Content.Server.Body.Components; // Parkstation-IPCs using Content.Server.Temperature.Components; using Content.Shared.Alert; using Content.Shared.Damage; @@ -37,7 +38,7 @@ public override void Initialize() { SubscribeLocalEvent(EnqueueDamage); SubscribeLocalEvent(OnAtmosExposedUpdate); - SubscribeLocalEvent(ServerAlert); + SubscribeLocalEvent(ServerAlertNotDumb); // Parkstation-IPCs // See ServerAlert for how upstream handled it. SubscribeLocalEvent>( OnTemperatureChangeAttempt); @@ -128,7 +129,7 @@ private void OnAtmosExposedUpdate(EntityUid uid, TemperatureComponent temperatur private void ServerAlert(EntityUid uid, AlertsComponent status, OnTemperatureChangeEvent args) { - switch (args.CurrentTemperature) + switch (args.CurrentTemperature) // Why the hell would you do temperature alerts like this?? - Parkstation. { // Cold strong. case <= 260: @@ -167,6 +168,81 @@ private void ServerAlert(EntityUid uid, AlertsComponent status, OnTemperatureCha } } + // Parkstation-IPCs-Start + /// + /// Finds the TemperatureComponent and the ThermalRegulatorComponent, and uses _alertsSystem to set the alert level based on the range of temperatures as allowed by those components. + /// Does some math to determine the alert level based on the current temperature and the range of temperatures allowed by the ThermalRegulatorComponent. + /// + private void ServerAlertNotDumb(EntityUid uid, AlertsComponent status, OnTemperatureChangeEvent args) + { + if (!EntityManager.TryGetComponent(uid, out TemperatureComponent? temperatureComponent)) + return; + + var temp = args.CurrentTemperature; + var minSafeTemp = temperatureComponent.ColdDamageThreshold; + var maxSafeTemp = temperatureComponent.HeatDamageThreshold; + + if (!EntityManager.TryGetComponent(uid, out ThermalRegulatorComponent? thermalRegulator)) + { + // If the entity does not have a ThermalRegularComponent, set the alert to 1 at 90% of the DamageThresholds, 2 at 130% of the DamageThresholds, and 3 at 180% of the DamageThresholds. + if (temp >= maxSafeTemp * 0.9) + { + short alertLevel = (short) (temp >= maxSafeTemp * 1.6 ? 3 : + temp >= maxSafeTemp * 1.2 ? 2 : + 1); + + _alertsSystem.ShowAlert(uid, AlertType.Hot, alertLevel); + return; + } + + if (temp <= minSafeTemp * 1.1) + { + short alertLevel = (short) (temp <= minSafeTemp * 0.4 ? 3 : + temp <= minSafeTemp * 0.8 ? 2 : + 1); + + _alertsSystem.ShowAlert(uid, AlertType.Cold, alertLevel); + return; + } + + _alertsSystem.ClearAlertCategory(uid, AlertCategory.Temperature); + return; + } + + var minComfTemp = thermalRegulator.NormalBodyTemperature - thermalRegulator.ThermalRegulationTemperatureThreshold; + var maxComfTemp = thermalRegulator.NormalBodyTemperature + thermalRegulator.ThermalRegulationTemperatureThreshold; + + // If the temperature is within the range of temperatures allowed by the ThermalRegulatorComponent, clear the alert. + if (temp >= minSafeTemp && temp <= maxSafeTemp) + { + _alertsSystem.ClearAlertCategory(uid, AlertCategory.Temperature); + return; + } + + // If the temperature is below the minimum temperature allowed by the ThermalRegulatorComponent, set the alert to Cold. + if (temp < minComfTemp) + { + short alertLevel = (short) (temp <= minSafeTemp * 0.75 ? 3 : + temp <= minSafeTemp ? 2 : + Math.Max(Math.Floor(temp / minComfTemp), 2)); + + _alertsSystem.ShowAlert(uid, AlertType.Cold, alertLevel); + return; + } + + // If the temperature is above the maximum temperature allowed by the ThermalRegulatorComponent, set the alert to Hot. + if (temp > maxComfTemp) + { + short alertLevel = (short) (temp >= maxSafeTemp * 1.25 ? 3 : + temp >= maxSafeTemp ? 2 : + Math.Max(Math.Floor(temp / maxComfTemp), 2)); + + _alertsSystem.ShowAlert(uid, AlertType.Hot, alertLevel); + return; + } + } + /// Parkstation-IPCs-End + private void EnqueueDamage(EntityUid uid, TemperatureComponent component, OnTemperatureChangeEvent args) { ShouldUpdateDamage.Add(component); diff --git a/Content.Server/Zombies/ZombifyOnDeathSystem.cs b/Content.Server/Zombies/ZombifyOnDeathSystem.cs index c61a55c117..45a90eac73 100644 --- a/Content.Server/Zombies/ZombifyOnDeathSystem.cs +++ b/Content.Server/Zombies/ZombifyOnDeathSystem.cs @@ -33,6 +33,7 @@ using Content.Shared.Nutrition.Components; using Content.Shared.Popups; using Content.Shared.Roles; +using Content.Shared.SimpleStation14.Silicon.Components; // Parkstation-IPCs using Content.Shared.Weapons.Melee; using Content.Shared.Zombies; using Robust.Shared.Prototypes; @@ -101,10 +102,10 @@ public void ZombifyEntity(EntityUid target, MobStateComponent? mobState = null) if (HasComp(target)) return; - // Begin Nyano-code: Don't zombify cyborg - if (HasComp(target)) + // Parkstation-IPC-Start + if (HasComp(target)) return; - // End Nyano-code. + // Parkstation-IPC-End if (!Resolve(target, ref mobState, logMissing: false)) return; diff --git a/Content.Shared/Alert/AlertType.cs b/Content.Shared/Alert/AlertType.cs index 3b6d974637..0bcd5fae7d 100644 --- a/Content.Shared/Alert/AlertType.cs +++ b/Content.Shared/Alert/AlertType.cs @@ -27,6 +27,7 @@ public enum AlertType : byte Starving, Thirsty, Parched, + Charge, // Parkstation-IPC Stamina, Pulled, Pulling, @@ -44,7 +45,7 @@ public enum AlertType : byte Debug3, Debug4, Debug5, - Debug6 + Debug6, } } diff --git a/Content.Shared/Electrocution/ElectrocutionEvents.cs b/Content.Shared/Electrocution/ElectrocutionEvents.cs index fe5753c7fb..8f87f7149b 100644 --- a/Content.Shared/Electrocution/ElectrocutionEvents.cs +++ b/Content.Shared/Electrocution/ElectrocutionEvents.cs @@ -24,12 +24,14 @@ public sealed class ElectrocutedEvent : EntityEventArgs public readonly EntityUid TargetUid; public readonly EntityUid? SourceUid; public readonly float SiemensCoefficient; + public readonly float? ShockDamage = null; // Parkstation-IPC - public ElectrocutedEvent(EntityUid targetUid, EntityUid? sourceUid, float siemensCoefficient) + public ElectrocutedEvent(EntityUid targetUid, EntityUid? sourceUid, float siemensCoefficient, float shockDamage) // Parkstation-IPC { TargetUid = targetUid; SourceUid = sourceUid; SiemensCoefficient = siemensCoefficient; + ShockDamage = shockDamage; // Parkstation-IPC } } } diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index ae3a8b3ae1..ee6b525d47 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -35,6 +35,11 @@ public string GetName(string species, Gender? gender = null) case SpeciesNaming.XnoY: return Loc.GetString("namepreset-x-no-y", ("first", GetFirstName(speciesProto, gender)), ("last", GetLastName(speciesProto))); + // Parkstation-IPC-Start + case SpeciesNaming.FirstDashLast: + return Loc.GetString("namepreset-firstdashlast", + ("first", GetFirstName(speciesProto, gender)), ("last", GetLastName(speciesProto))); + // Parkstation-IPC-End case SpeciesNaming.FirstLast: default: return Loc.GetString("namepreset-firstlast", diff --git a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs index 0ae135773d..688740350e 100644 --- a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs @@ -127,5 +127,6 @@ public enum SpeciesNaming : byte FirstLast, FirstDashFirst, XnoY, - TheFirstofLast + TheFirstofLast, + FirstDashLast, // Parkstation-IPC } diff --git a/Content.Shared/Humanoid/SkinColor.cs b/Content.Shared/Humanoid/SkinColor.cs index e03f049f42..6e6fc543b1 100644 --- a/Content.Shared/Humanoid/SkinColor.cs +++ b/Content.Shared/Humanoid/SkinColor.cs @@ -117,10 +117,15 @@ public static bool VerifyHumanSkinTone(Color color) /// Tinted hue color public static Color TintedHues(Color color) { - var newColor = Color.ToHsv(color); - newColor.Y = .1f; + // Parkstation-IPC-Start + var hsv = Color.ToHsv(color); + + hsv.Y = Math.Min(hsv.Y, 0.6f); + + hsv.Z = Math.Max(hsv.Z, 0.25f); - return Color.FromHsv(newColor); + return Color.FromHsv(hsv); + // Parkstation-IPC-End } /// @@ -130,8 +135,11 @@ public static Color TintedHues(Color color) /// True if valid, false otherwise public static bool VerifyTintedHues(Color color) { - // tinted hues just ensures saturation is always .1, or 10% saturation at all times - return Color.ToHsv(color).Y != .1f; + // Parkstation-IPC-Start + var hsv = Color.ToHsv(color); + + return hsv.Y <= 0.6 && hsv.Z >= 0.25; + // Parkstation-IPC-End } public static bool VerifySkinColor(HumanoidSkinColor type, Color color) diff --git a/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs b/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs index ca5d1f647a..81ddb23a00 100644 --- a/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs +++ b/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs @@ -42,6 +42,15 @@ public sealed class EncryptionKeyHolderComponent : Component public Container KeyContainer = default!; public const string KeyContainerName = "key_slots"; + // Parkstation-IPC-Start + /// + /// Whether or not the headset can be examined to see the encryption keys while the keys aren't accessible. + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("examineWhileLocked")] + public bool ExamineWhileLocked = true; + // Parkstation-IPC-End + /// /// Combined set of radio channels provided by all contained keys. /// diff --git a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs index 31f7933099..47b829b32a 100644 --- a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs +++ b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs @@ -175,6 +175,14 @@ private void OnHolderExamined(EntityUid uid, EncryptionKeyHolderComponent compon if (!args.IsInDetailsRange) return; + // Parkstation-IPC-Start + if (!component.ExamineWhileLocked && !component.KeysUnlocked) + return; + + if (!component.ExamineWhileLocked && TryComp(uid, out var panel) && !panel.Open) + return; + // Parkstation-IPC-End + if (component.KeyContainer.ContainedEntities.Count == 0) { args.PushMarkup(Loc.GetString("encryption-keys-no-keys")); diff --git a/Content.Shared/SimpleStation14/CCVar/CCVars.cs b/Content.Shared/SimpleStation14/CCVar/CCVars.cs index 91fdb6529a..1baaad6ec5 100644 --- a/Content.Shared/SimpleStation14/CCVar/CCVars.cs +++ b/Content.Shared/SimpleStation14/CCVar/CCVars.cs @@ -30,7 +30,7 @@ public sealed class SimpleStationCCVars /// public static readonly CVarDef BloodLostThreshold = CVarDef.Create("eorstats.bloodlost_threshold", 300f, CVar.SERVERONLY); - #endregion + #endregion BloodLost #region CuffedTime /// @@ -41,7 +41,7 @@ public sealed class SimpleStationCCVars /// public static readonly CVarDef CuffedTimeThreshold = CVarDef.Create("eorstats.cuffedtime_threshold", 8, CVar.SERVERONLY); - #endregion + #endregion CuffedTime #region EmitSound /// @@ -52,7 +52,7 @@ public sealed class SimpleStationCCVars /// public static readonly CVarDef EmitSoundThreshold = CVarDef.Create("eorstats.emitsound_threshold", 80, CVar.SERVERONLY); - #endregion + #endregion EmitSound #region InstrumentPlayed /// @@ -63,7 +63,7 @@ public sealed class SimpleStationCCVars /// public static readonly CVarDef InstrumentPlayedThreshold = CVarDef.Create("eorstats.instrumentplayed_threshold", 8, CVar.SERVERONLY); - #endregion + #endregion InstrumentPlayed #region MopUsed /// @@ -89,7 +89,7 @@ public sealed class SimpleStationCCVars /// public static readonly CVarDef MopUsedTopMopperCount = CVarDef.Create("eorstats.mopused_topmoppercount", 3, CVar.SERVERONLY); - #endregion + #endregion MopUsed #region ShotsFired /// @@ -106,7 +106,7 @@ public sealed class SimpleStationCCVars /// public static readonly CVarDef ShotsFiredDisplayNone = CVarDef.Create("eorstats.shotsfired_displaynone", true, CVar.SERVERONLY); - #endregion + #endregion ShotsFired #region SlippedCount /// @@ -129,6 +129,17 @@ public sealed class SimpleStationCCVars /// public static readonly CVarDef SlippedCountTopSlipper = CVarDef.Create("eorstats.slippedcount_topslipper", true, CVar.SERVERONLY); - #endregion - #endregion + #endregion SlippedCount + #endregion EndOfRoundStats + + /* + * Silicons + */ + #region Silicons + /// + /// The amount of time between NPC Silicons draining their battery in seconds. + /// + public static readonly CVarDef SiliconNpcUpdateTime = + CVarDef.Create("silicon.npcupdatetime", 1.5f, CVar.SERVERONLY); + #endregion Silicons } diff --git a/Content.Shared/SimpleStation14/Silicon/BatteryDrinkerEvent.cs b/Content.Shared/SimpleStation14/Silicon/BatteryDrinkerEvent.cs new file mode 100644 index 0000000000..adf9570401 --- /dev/null +++ b/Content.Shared/SimpleStation14/Silicon/BatteryDrinkerEvent.cs @@ -0,0 +1,12 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.SimpleStation14.Silicon; + +[Serializable, NetSerializable] +public sealed class BatteryDrinkerDoAfterEvent : SimpleDoAfterEvent +{ + public BatteryDrinkerDoAfterEvent() + { + } +} diff --git a/Content.Shared/SimpleStation14/Silicon/Components/SiliconChargerComponent.cs b/Content.Shared/SimpleStation14/Silicon/Components/SiliconChargerComponent.cs new file mode 100644 index 0000000000..9dd8649fa8 --- /dev/null +++ b/Content.Shared/SimpleStation14/Silicon/Components/SiliconChargerComponent.cs @@ -0,0 +1,124 @@ +using Content.Shared.Storage.Components; +using Content.Shared.StepTrigger.Components; +using Robust.Shared.Audio; + +namespace Content.Shared.SimpleStation14.Silicon; + +[RegisterComponent] +public sealed class SiliconChargerComponent : Component +{ + /// + /// Is the charger currently active? + /// + public bool Active = false; + + /// + /// The currently playing audio stream. + /// + public IPlayingAudioStream? SoundStream { get; set; } + + /// + /// Counter for handing out warnings to burning entities. + /// + public TimeSpan WarningTime = TimeSpan.Zero; + + /// + /// The current parts multiplier. + /// + public float PartsChargeMulti = 1.2f; + + + /// + /// The sound to play when the charger is active. + /// + [DataField("soundLoop")] + public SoundSpecifier SoundLoop = new SoundPathSpecifier("/Audio/Machines/microwave_loop.ogg"); + + /// + /// The multiplier for the charge rate. + /// For reference, an IPC drains at 50. + /// + [DataField("chargeMulti"), ViewVariables(VVAccess.ReadWrite)] + public float ChargeMulti = 50f; + + /// + /// The minimum size of a battery to be charged. + /// + /// + /// Charging a battery too small will detonate it, becoming more likely as it fills. + /// + [DataField("minChargeSize"), ViewVariables(VVAccess.ReadWrite)] + public int MinChargeSize = 1000; + + /// + /// The minimum amount of time it will take to charge a battery, in seconds. + /// + /// + /// Note that this is from empty. A battery that is already half full will take half as long as this value to reach full, if it would've been faster from empty. + /// This is for the sake of feeling cooler- It's lame to just charge instantly. + /// + [DataField("minChargeTime"), ViewVariables(VVAccess.ReadWrite)] + public float MinChargeTime = 10f; + + /// + /// The temperature the charger will stop heating up at. + /// + /// + /// Used specifically for chargers with the . + /// + [DataField("targetTemp"), ViewVariables(VVAccess.ReadWrite)] + public float TargetTemp = 373.15f; + + /// + /// The damage type to deal when a Biological entity is burned. + /// + [DataField("damageType")] + public string DamageType = "Shock"; + + /// + /// The modifier to apply to a used parts rating. + /// + /// + /// 0.6 is the default as it provides a nice range where 2 is about normal, and 4 is about two and a half. + /// + [DataField("upgradePartsMulti"), ViewVariables(VVAccess.ReadWrite)] + public float UpgradePartsMulti = 0.6f; + + /// + /// The part to be used for the charge speed. + /// + [DataField("chargeSpeedPart")] + public string ChargeSpeedPart = "Capacitor"; + + /// + /// The part to be used for the charge efficiency. + /// + [DataField("chargeEfficiencyPart")] + public string ChargeEfficiencyPart = "Manipulator"; + + + /// + /// Charger overheat string + /// + [DataField("overheatString")] + public string OverheatString = "silicon-charger-overheatwarning"; + + + /// + /// The list of entities currently stood on a charger. + /// + /// + /// Used specifically for chargers with the . + /// + [ViewVariables(VVAccess.ReadOnly)] + public List PresentEntities = new List(); + + /// + /// The number of entities that can be stood on a charger at once. + /// + /// + /// Used specifically for chargers with the . + /// + [DataField("maxEntities"), ViewVariables(VVAccess.ReadWrite)] + public int MaxEntities = 1; +} diff --git a/Content.Shared/SimpleStation14/Silicon/Components/SiliconComponent.cs b/Content.Shared/SimpleStation14/Silicon/Components/SiliconComponent.cs new file mode 100644 index 0000000000..2a4683dc31 --- /dev/null +++ b/Content.Shared/SimpleStation14/Silicon/Components/SiliconComponent.cs @@ -0,0 +1,104 @@ +using Robust.Shared.GameStates; +using Content.Shared.SimpleStation14.Silicon.Systems; +using Robust.Shared.Serialization.TypeSerializers.Implementations; +using Robust.Shared.Containers; + +namespace Content.Shared.SimpleStation14.Silicon.Components; + +/// +/// Component for defining a mob as a robot. +/// +[RegisterComponent, NetworkedComponent] +public sealed class SiliconComponent : Component +{ + [ViewVariables(VVAccess.ReadOnly)] + public ChargeState ChargeState = ChargeState.Full; + + [ViewVariables(VVAccess.ReadOnly)] + public float OverheatAccumulator = 0.0f; + + /// + /// The last time the Silicon was drained. + /// Used for NPC Silicons to avoid over updating. + /// + /// + /// Time between drains can be specified in + /// + /// + public TimeSpan LastDrainTime = TimeSpan.Zero; + + /// + /// The Silicon's battery slot, if it has one. + /// + public IContainer? BatteryContainer = null; + + /// + /// Is the Silicon currently dead? + /// + public bool Dead = false; + + // BatterySystem took issue with how this was used, so I'm coming back to it at a later date, when more foundational Silicon stuff is implemented. + // /// + // /// The entity to get the battery from. + // /// + // public EntityUid BatteryOverride? = EntityUid.Invalid; + + + /// + /// The type of silicon this is. + /// + /// + /// Any new types of Silicons should be added to the enum. + /// + [DataField("entityType", customTypeSerializer: typeof(EnumSerializer))] + public Enum EntityType = SiliconType.Npc; + + /// + /// Is this silicon battery powered? + /// + /// + /// If true, should go along with a battery component. One will not be added automatically. + /// + [DataField("batteryPowered"), ViewVariables(VVAccess.ReadWrite)] + public bool BatteryPowered = false; + + /// + /// Slot this entity's battery is contained in. + /// Leave null if using a battery component. + /// + [DataField("batterySlot")] + public string? BatterySlot = null; + + /// + /// How much power is drained by this Silicon every second by default. + /// + [DataField("drainPerSecond"), ViewVariables(VVAccess.ReadWrite)] + public float DrainPerSecond = 50f; + + + /// + /// The percentages at which the silicon will enter each state. + /// + /// + /// The Silicon will always be Full at 100%. + /// Setting a value to null will disable that state. + /// Setting Critical to 0 will cause the Silicon to never enter the dead state. + /// + [DataField("chargeThresholdMid"), ViewVariables(VVAccess.ReadWrite)] + public float? ChargeThresholdMid = 0.5f; + + /// + [DataField("chargeThresholdLow"), ViewVariables(VVAccess.ReadWrite)] + public float? ChargeThresholdLow = 0.25f; + + /// + [DataField("chargeThresholdCritical"), ViewVariables(VVAccess.ReadWrite)] + public float? ChargeThresholdCritical = 0.0f; + + + /// + /// The amount the Silicon will be slowed at each charge state. + /// + [DataField("speedModifierThresholds", required: true)] + public readonly Dictionary SpeedModifierThresholds = default!; +} diff --git a/Content.Shared/SimpleStation14/Silicon/SiliconChargerVisuals.cs b/Content.Shared/SimpleStation14/Silicon/SiliconChargerVisuals.cs new file mode 100644 index 0000000000..57b579e87e --- /dev/null +++ b/Content.Shared/SimpleStation14/Silicon/SiliconChargerVisuals.cs @@ -0,0 +1,17 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.SimpleStation14.Silicon; + +[Serializable, NetSerializable] +public enum SiliconChargerVisuals +{ + Lights, +} + +[Serializable, NetSerializable] +public enum SiliconChargerVisualState +{ + Normal, + NormalOpen, + Charging +} diff --git a/Content.Shared/SimpleStation14/Silicon/Systems/SharedSiliconChargerSystem.cs b/Content.Shared/SimpleStation14/Silicon/Systems/SharedSiliconChargerSystem.cs new file mode 100644 index 0000000000..c954b533bc --- /dev/null +++ b/Content.Shared/SimpleStation14/Silicon/Systems/SharedSiliconChargerSystem.cs @@ -0,0 +1,76 @@ +using Content.Shared.Power; +using Content.Shared.Storage.Components; +using Robust.Shared.Audio; +using Robust.Shared.Timing; + +namespace Content.Shared.SimpleStation14.Silicon.Charge; + +public sealed class SharedSiliconChargerSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly IGameTiming _timing = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(HandleStateOpen); + SubscribeLocalEvent(HandleStateClose); + } + + + /// + /// Updates the state of the charger when it's open or closed. + /// + private void HandleStateOpen(EntityUid uid, SiliconChargerComponent component, ref StorageAfterOpenEvent _) + { + UpdateState(uid, component); + } + + /// + private void HandleStateClose(EntityUid uid, SiliconChargerComponent component, ref StorageAfterCloseEvent _) + { + UpdateState(uid, component); + } + + /// + /// Updates the visual and auditory state of the charger based on if it's active, and/or open. + /// + public void UpdateState(EntityUid uid, SiliconChargerComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + if (component.Active) + { + _appearance.SetData(uid, PowerDeviceVisuals.VisualState, SiliconChargerVisualState.Charging); + + // If we're in prediction, return since Client doesn't have the information needed to handle this. + // Didn't seem to matter in practice, but probably for the best. + if (_timing.InPrediction) + return; + + if (component.SoundLoop != null && component.SoundStream == null) + component.SoundStream = + _audio.PlayPvs(component.SoundLoop, uid, AudioParams.Default.WithLoop(true).WithMaxDistance(5)); + } + else + { + var state = SiliconChargerVisualState.Normal; + + if (EntityManager.TryGetComponent(uid, out var storageComp) && storageComp.Open) + state = SiliconChargerVisualState.NormalOpen; + + _appearance.SetData(uid, PowerDeviceVisuals.VisualState, state); + + // If we're in prediction, return since Client doesn't have the information needed to handle this. + // Didn't seem to matter in practice, but probably for the best. + if (_timing.InPrediction) + return; + + component.SoundStream?.Stop(); + component.SoundStream = null; + } + } +} diff --git a/Content.Shared/SimpleStation14/Silicon/Systems/SharedSiliconSystem.cs b/Content.Shared/SimpleStation14/Silicon/Systems/SharedSiliconSystem.cs new file mode 100644 index 0000000000..8ddce7550b --- /dev/null +++ b/Content.Shared/SimpleStation14/Silicon/Systems/SharedSiliconSystem.cs @@ -0,0 +1,96 @@ +using Content.Shared.SimpleStation14.Silicon.Components; +using Content.Shared.Alert; +using Robust.Shared.Serialization; +using Content.Shared.Movement.Systems; + +namespace Content.Shared.SimpleStation14.Silicon.Systems; + + +public sealed class SharedSiliconChargeSystem : EntitySystem +{ + [Dependency] private readonly AlertsSystem _alertsSystem = default!; + + // Dictionary of ChargeState to Alert severity. + private static readonly Dictionary ChargeStateAlert = new() + { + {ChargeState.Full, 4}, + {ChargeState.Mid, 3}, + {ChargeState.Low, 2}, + {ChargeState.Critical, 1}, + {ChargeState.Dead, 0}, + {ChargeState.Invalid, -1}, + }; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSiliconInit); + SubscribeLocalEvent(OnSiliconChargeStateUpdate); + SubscribeLocalEvent(OnRefreshMovespeed); + } + + private void OnSiliconInit(EntityUid uid, SiliconComponent component, ComponentInit args) + { + if (component.BatteryPowered) + _alertsSystem.ShowAlert(uid, AlertType.Charge, (short) component.ChargeState); + } + + private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconComponent component, SiliconChargeStateUpdateEvent ev) + { + _alertsSystem.ShowAlert(uid, AlertType.Charge, (short) ev.ChargeState); + } + + private void OnRefreshMovespeed(EntityUid uid, SiliconComponent component, RefreshMovementSpeedModifiersEvent args) + { + if (!component.BatteryPowered) + return; + + var speedModThresholds = component.SpeedModifierThresholds; + + var closest = 0f; + + foreach (var state in speedModThresholds) + { + if (component.ChargeState >= state.Key && (float) state.Key > closest) + closest = (float) state.Key; + } + + var speedMod = speedModThresholds[(ChargeState) closest]; + + args.ModifySpeed(speedMod, speedMod); + } +} + + +public enum SiliconType +{ + Player, + GhostRole, + Npc, +} + +public enum ChargeState +{ + Invalid = -1, + Dead, + Critical, + Low, + Mid, + Full, +} + + +/// +/// Event raised when a Silicon's charge state needs to be updated. +/// +[Serializable, NetSerializable] +public sealed class SiliconChargeStateUpdateEvent : EntityEventArgs +{ + public ChargeState ChargeState { get; } + + public SiliconChargeStateUpdateEvent(ChargeState chargeState) + { + ChargeState = chargeState; + } +} diff --git a/Resources/Locale/en-US/SimpleStation14/Content/Power/batteries.ftl b/Resources/Locale/en-US/SimpleStation14/Content/Power/batteries.ftl new file mode 100644 index 0000000000..15ebafae77 --- /dev/null +++ b/Resources/Locale/en-US/SimpleStation14/Content/Power/batteries.ftl @@ -0,0 +1 @@ +battery-electrocute-charge = The battery surges with energy! diff --git a/Resources/Locale/en-US/SimpleStation14/Content/Power/batteryDrinker.ftl b/Resources/Locale/en-US/SimpleStation14/Content/Power/batteryDrinker.ftl new file mode 100644 index 0000000000..950b321d40 --- /dev/null +++ b/Resources/Locale/en-US/SimpleStation14/Content/Power/batteryDrinker.ftl @@ -0,0 +1,2 @@ +battery-drinker-verb-drink = Drain +battery-drinker-empty = {CAPATALIZE(THE($target))} is already empty! diff --git a/Resources/Locale/en-US/SimpleStation14/Content/Silicons/siliconChargers.ftl b/Resources/Locale/en-US/SimpleStation14/Content/Silicons/siliconChargers.ftl new file mode 100644 index 0000000000..df6c66346c --- /dev/null +++ b/Resources/Locale/en-US/SimpleStation14/Content/Silicons/siliconChargers.ftl @@ -0,0 +1,5 @@ +silicon-charger-overheatwarning = You feel like you're in a microwave! +silicon-charger-chargerate-string = Charge rate +silicon-charger-efficiency-string = Efficiency + +silicon-charger-list-full = {CAPITALIZE(THE($charger))} can only accommodate so many targets! diff --git a/Resources/Locale/en-US/SimpleStation14/Content/Silicons/silicons.ftl b/Resources/Locale/en-US/SimpleStation14/Content/Silicons/silicons.ftl new file mode 100644 index 0000000000..4e4d1eea8f --- /dev/null +++ b/Resources/Locale/en-US/SimpleStation14/Content/Silicons/silicons.ftl @@ -0,0 +1,6 @@ +silicon-overheating = You feel your circuits overheating! +silicon-crit = Structural integrity critical! +silicon-power-low = Power low! + +alerts-charge-name = Charge +alerts-charge-desc = Your current battery level. diff --git a/Resources/Locale/en-US/SimpleStation14/Prototypes/Entities/Mobs/Customization/ipcAntenna.ftl b/Resources/Locale/en-US/SimpleStation14/Prototypes/Entities/Mobs/Customization/ipcAntenna.ftl new file mode 100644 index 0000000000..ec3efd9f55 --- /dev/null +++ b/Resources/Locale/en-US/SimpleStation14/Prototypes/Entities/Mobs/Customization/ipcAntenna.ftl @@ -0,0 +1,10 @@ +marking-RobotAntennaTv = Tv +marking-RobotAntennaTesla = Tesla +marking-RobotAntennaLightb = Light (alt) +marking-RobotAntennaLight = Light +marking-RobotAntennaCyberhead = Cyberhead +marking-RobotAntennaSidelights = Sidelights +marking-RobotAntennaAntlers = Antlers +marking-RobotAntennaDroneeyes = Drone Eyes +marking-RobotAntennaCrowned = Crowned +marking-RobotAntennaTowers = Towers diff --git a/Resources/Locale/en-US/SimpleStation14/Prototypes/Entities/Mobs/Customization/ipcScreens.ftl b/Resources/Locale/en-US/SimpleStation14/Prototypes/Entities/Mobs/Customization/ipcScreens.ftl new file mode 100644 index 0000000000..3f53f2d3f9 --- /dev/null +++ b/Resources/Locale/en-US/SimpleStation14/Prototypes/Entities/Mobs/Customization/ipcScreens.ftl @@ -0,0 +1,39 @@ +marking-ScreenStatic = Static +marking-ScreenBlue = Blue +marking-ScreenBreakout = Breakout +marking-ScreenEight = Eight +marking-ScreenGoggles = Goggles +marking-ScreenExclaim = Exclaim +marking-ScreenHeart = Heart +marking-ScreenMonoeye = Cyclops +marking-ScreenNature = Naturalist +marking-ScreenOrange = Orange +marking-ScreenPink = Pink +marking-ScreenQuestion = Question +marking-ScreenShower = Shower +marking-ScreenYellow = Yellow +marking-ScreenScroll = Scroll +marking-ScreenConsole = Console +marking-ScreenRgb = RGB +marking-ScreenGlider = Glider +marking-ScreenRainbowhoriz = Horizontal Rainbow +marking-ScreenBsod = BSOD +marking-ScreenRedtext = Red Text +marking-ScreenSinewave = Sinewave +marking-ScreenSquarewave = Squarewave +marking-ScreenEcgwave = ECG wave +marking-ScreenEyes = Eyes +marking-ScreenEyestall = Tall Eyes +marking-ScreenEyesangry = Angry Eyes +marking-ScreenLoading = Loading... +marking-ScreenWindowsxp = Experience +marking-ScreenTetris = NT Block Game +marking-ScreenTv = Tv +marking-ScreenTextdrop = Textdrop +marking-ScreenStars = Stars +marking-ScreenRainbowdiag = Diagonal Rainbow +marking-ScreenBlank = Dead Pixel +marking-ScreenSmile = Smiley +marking-ScreenFrown = Frowny +marking-ScreenRing = Ring +marking-ScreenL = L diff --git a/Resources/Locale/en-US/species/namepreset.ftl b/Resources/Locale/en-US/species/namepreset.ftl index a52967642e..4fc4b53b55 100644 --- a/Resources/Locale/en-US/species/namepreset.ftl +++ b/Resources/Locale/en-US/species/namepreset.ftl @@ -2,3 +2,6 @@ namepreset-firstlast = {$first} {$last} namepreset-firstdashfirst = {$first1}-{$first2} namepreset-thefirstoflast = The {$first} of {$last} namepreset-x-no-y = {$last}-no-{$first} + +## Parkstation +namepreset-firstdashlast = {$first}-{$last} diff --git a/Resources/Locale/en-US/species/species.ftl b/Resources/Locale/en-US/species/species.ftl index c461f659c6..7799e7b504 100644 --- a/Resources/Locale/en-US/species/species.ftl +++ b/Resources/Locale/en-US/species/species.ftl @@ -9,3 +9,6 @@ species-name-oni = Oni species-name-arachne = Arachne species-name-diona = Diona species-name-moth = Moth + +## Parkstation Names +species-name-ipc = IPC diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index 0c80062d0d..60ecc4dea8 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -97,6 +97,31 @@ - type: Alerts - type: TypingIndicator proto: robot + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellHyper + - type: ContainerContainer + containers: + cell_slot: !type:ContainerSlot + - type: Silicon + batterySlot: cell_slot + entityType: enum.SiliconType.Npc + batteryPowered: true + drainPerSecond: 0.67 + chargeThresholdMid: 0 + chargeThresholdLow: 0 + chargeThresholdCritical: 0.12 + speedModifierThresholds: + 4: 1 + 3: 1 + 2: 1 + 1: 0.20 + 0: 0.00 + - type: SiliconDownOnDead - type: entity parent: MobSiliconBase diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index 2353cd7892..307b3ecb16 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -1,267 +1,267 @@ -- type: entity - save: false - abstract: true - id: PlayerSiliconBase #for player controlled silicons - components: - - type: Reactive - groups: - Acidic: [Touch] - - type: Input - context: "human" - - type: InputMover - - type: MobMover - - type: DamageOnHighSpeedImpact - damage: - types: - Blunt: 5 - soundHit: - path: /Audio/Effects/hit_kick.ogg - - type: Clickable - - type: Damageable - damageContainer: Inorganic - - type: Bloodstream - bloodReagent: MotorOil - bloodlossDamage: - types: - Bloodloss: - 1 - bloodlossHealDamage: - types: - Bloodloss: - -1 - - type: InteractionOutline - - type: Fixtures - fixtures: - fix1: - shape: - # Circles, cuz rotation of rectangles looks very bad - !type:PhysShapeCircle - radius: 0.35 - density: 50 - mask: - - MobMask - layer: - - MobLayer - - type: MovementSpeedModifier - baseWalkSpeed : 4 - baseSprintSpeed : 3 - - type: Sprite - noRot: true - drawdepth: Mobs - - type: Physics - bodyType: KinematicController - - type: Hands - showInHands: false - - type: Body - prototype: Drone - - type: DoAfter - - type: Pullable - - type: Examiner - - type: Puller - - type: StandingState - - type: Alerts - - type: Tag - tags: - - ShoesRequiredStepTriggerImmune +# - type: entity +# save: false +# abstract: true +# id: PlayerSiliconBase #for player controlled silicons +# components: +# - type: Reactive +# groups: +# Acidic: [Touch] +# - type: Input +# context: "human" +# - type: InputMover +# - type: MobMover +# - type: DamageOnHighSpeedImpact +# damage: +# types: +# Blunt: 5 +# soundHit: +# path: /Audio/Effects/hit_kick.ogg +# - type: Clickable +# - type: Damageable +# damageContainer: Inorganic +# - type: Bloodstream +# bloodReagent: MotorOil +# bloodlossDamage: +# types: +# Bloodloss: +# 1 +# bloodlossHealDamage: +# types: +# Bloodloss: +# -1 +# - type: InteractionOutline +# - type: Fixtures +# fixtures: +# fix1: +# shape: +# # Circles, cuz rotation of rectangles looks very bad +# !type:PhysShapeCircle +# radius: 0.35 +# density: 50 +# mask: +# - MobMask +# layer: +# - MobLayer +# - type: MovementSpeedModifier +# baseWalkSpeed : 4 +# baseSprintSpeed : 3 +# - type: Sprite +# noRot: true +# drawdepth: Mobs +# - type: Physics +# bodyType: KinematicController +# - type: Hands +# showInHands: false +# - type: Body +# prototype: Drone +# - type: DoAfter +# - type: Pullable +# - type: Examiner +# - type: Puller +# - type: StandingState +# - type: Alerts +# - type: Tag +# tags: +# - ShoesRequiredStepTriggerImmune -- type: entity - name: drone - id: Drone - parent: PlayerSiliconBase - components: - - type: Drone - - type: InnateTool - tools: - - id: ClothingBackpackSatchelDrone - - id: trayScanner - - id: Omnitool - - id: WelderExperimental - - type: Eye - - type: Inventory - templateId: drone - - type: InventorySlots - - type: Strippable - - type: UserInterface - interfaces: - - key: enum.StrippingUiKey.Key - type: StrippableBoundUserInterface - - key: enum.LawsUiKey.Key - type: LawsBoundUserInterface - - type: GhostRole - makeSentient: true - name: Maintenance Drone - description: Maintain the station. Ignore other beings except drones. - rules: | - You are bound by these laws both in-game and out-of-character: - 1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone. - 2. You may not harm any being, regardless of intent or circumstance. - 3. Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals. - - type: IgnoreHumanoidsOverlay - - type: Laws - canState: false - laws: - - You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone. - - You may not harm any being, regardless of intent or circumstance. - - Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals. - - You may accept orders received via the binary channel, regardless of the nature of the being issuing them, so long as they do not conflict with Law Two or Law Three. - - type: GhostTakeoverAvailable - - type: MovementSpeedModifier - baseWalkSpeed : 5 - baseSprintSpeed : 5 - - type: MobState - allowedStates: - - Alive - - Dead - - type: MobThresholds - thresholds: - 0: Alive - 60: Dead - - type: Flashable - - type: NoSlip - - type: StatusEffects - allowed: - - Stun - - KnockedDown - - SlowedDown - - type: SlowOnDamage - speedModifierThresholds: - 30: 0.7 - 50: 0.5 - - type: Temperature - heatDamageThreshold: 5000 - currentTemperature: 310.15 - specificHeat: 42 - heatDamage: - types: - Heat : 1 #per second, scales with temperature & other constants - - type: Sprite - drawdepth: SmallMobs - layers: - - state: shell - sprite: Mobs/Silicon/drone.rsi - map: ["base"] - - type: MovementIgnoreGravity - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeCircle - radius: 0.35 - density: 50 - mask: - - SmallMobMask - layer: - - SmallMobLayer - - type: Appearance - - type: GenericVisualizer - visuals: - enum.DroneVisuals.Status: - base: - Off: { state: shell } - On: { state: drone } - - type: ReplacementAccent - accent: silicon - - type: Repairable - fuelcost: 15 - doAfterDelay: 8 - - type: Actions - - type: UnpoweredFlashlight - toggleAction: - name: action-name-toggle-light - description: action-description-toggle-light - icon: { sprite: Objects/Tools/flashlight.rsi, state: flashlight } - iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png - event: !type:ToggleActionEvent - - type: PointLight - enabled: false - radius: 3.5 - softness: 1 - mask: /Textures/Effects/LightMasks/cone.png - autoRot: true - - type: Tag - tags: - - ShoesRequiredStepTriggerImmune - - CannotSuicide - - type: Hands - showInHands: false - - type: IntrinsicUI - uis: - - key: enum.LawsUiKey.Key - toggleAction: - name: action-name-show-laws - description: action-description-show-laws - icon: Structures/Wallmounts/posters.rsi/poster11_legit.png #someone wanna make new icons? - iconOn: Structures/Wallmounts/posters.rsi/poster11_legit.png - keywords: [ "AI", "console", "interface", "laws", "borg" ] - priority: -3 - event: !type:ToggleIntrinsicUIEvent - - type: IntrinsicRadioReceiver - channels: - - Binary - - type: ActiveRadio - channels: - - Binary +# - type: entity +# name: drone +# id: Drone +# parent: PlayerSiliconBase +# components: +# - type: Drone +# - type: InnateTool +# tools: +# - id: ClothingBackpackSatchelDrone +# - id: trayScanner +# - id: Omnitool +# - id: WelderExperimental +# - type: Eye +# - type: Inventory +# templateId: drone +# - type: InventorySlots +# - type: Strippable +# - type: UserInterface +# interfaces: +# - key: enum.StrippingUiKey.Key +# type: StrippableBoundUserInterface +# - key: enum.LawsUiKey.Key +# type: LawsBoundUserInterface +# - type: GhostRole +# makeSentient: true +# name: Maintenance Drone +# description: Maintain the station. Ignore other beings except drones. +# rules: | +# You are bound by these laws both in-game and out-of-character: +# 1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone. +# 2. You may not harm any being, regardless of intent or circumstance. +# 3. Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals. +# - type: IgnoreHumanoidsOverlay +# - type: Laws +# canState: false +# laws: +# - You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone. +# - You may not harm any being, regardless of intent or circumstance. +# - Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals. +# - You may accept orders received via the binary channel, regardless of the nature of the being issuing them, so long as they do not conflict with Law Two or Law Three. +# - type: GhostTakeoverAvailable +# - type: MovementSpeedModifier +# baseWalkSpeed : 5 +# baseSprintSpeed : 5 +# - type: MobState +# allowedStates: +# - Alive +# - Dead +# - type: MobThresholds +# thresholds: +# 0: Alive +# 60: Dead +# - type: Flashable +# - type: NoSlip +# - type: StatusEffects +# allowed: +# - Stun +# - KnockedDown +# - SlowedDown +# - type: SlowOnDamage +# speedModifierThresholds: +# 30: 0.7 +# 50: 0.5 +# - type: Temperature +# heatDamageThreshold: 5000 +# currentTemperature: 310.15 +# specificHeat: 42 +# heatDamage: +# types: +# Heat : 1 #per second, scales with temperature & other constants +# - type: Sprite +# drawdepth: SmallMobs +# layers: +# - state: shell +# sprite: Mobs/Silicon/drone.rsi +# map: ["base"] +# - type: MovementIgnoreGravity +# - type: Fixtures +# fixtures: +# fix1: +# shape: +# !type:PhysShapeCircle +# radius: 0.35 +# density: 50 +# mask: +# - SmallMobMask +# layer: +# - SmallMobLayer +# - type: Appearance +# - type: GenericVisualizer +# visuals: +# enum.DroneVisuals.Status: +# base: +# Off: { state: shell } +# On: { state: drone } +# - type: ReplacementAccent +# accent: silicon +# - type: Repairable +# fuelcost: 15 +# doAfterDelay: 8 +# - type: Actions +# - type: UnpoweredFlashlight +# toggleAction: +# name: action-name-toggle-light +# description: action-description-toggle-light +# icon: { sprite: Objects/Tools/flashlight.rsi, state: flashlight } +# iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png +# event: !type:ToggleActionEvent +# - type: PointLight +# enabled: false +# radius: 3.5 +# softness: 1 +# mask: /Textures/Effects/LightMasks/cone.png +# autoRot: true +# - type: Tag +# tags: +# - ShoesRequiredStepTriggerImmune +# - CannotSuicide +# - type: Hands +# showInHands: false +# - type: IntrinsicUI +# uis: +# - key: enum.LawsUiKey.Key +# toggleAction: +# name: action-name-show-laws +# description: action-description-show-laws +# icon: Structures/Wallmounts/posters.rsi/poster11_legit.png #someone wanna make new icons? +# iconOn: Structures/Wallmounts/posters.rsi/poster11_legit.png +# keywords: [ "AI", "console", "interface", "laws", "borg" ] +# priority: -3 +# event: !type:ToggleIntrinsicUIEvent +# - type: IntrinsicRadioReceiver +# channels: +# - Binary +# - type: ActiveRadio +# channels: +# - Binary -- type: entity - name: onestar mecha - id: Onestar - parent: PlayerSiliconBase - components: - - type: InnateTool - tools: - - id: WeaponMinigun - - id: EnergySword - - id: WeaponLauncherMultipleRocket - - id: WeaponXrayCannon - - type: UserInterface - interfaces: - - key: enum.StrippingUiKey.Key - type: StrippableBoundUserInterface - - type: GhostRole - makeSentient: true - name: ghost-role-information-onestar-mecha-name - description: ghost-role-information-onestar-mecha-description - rules: ghost-role-information-onestar-mecha-rules - - type: GhostTakeoverAvailable - - type: MovementSpeedModifier - baseWalkSpeed : 3 - baseSprintSpeed : 2 - - type: MobState - allowedStates: - - Alive - - Dead - - type: MobThresholds - thresholds: - 0: Alive - 1000: Dead - - type: Sprite - drawdepth: Mobs - layers: - - state: onestar_boss - sprite: Mobs/Silicon/onestar.rsi - - state: onestar_boss_screen - sprite: Mobs/Silicon/onestar.rsi - shader: unshaded - - type: FootstepModifier - footstepSoundCollection: - path: /Audio/Mecha/sound_mecha_powerloader_step.ogg - - type: MovementIgnoreGravity - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeCircle - radius: 1 - density: 160 - mask: - - LargeMobMask - layer: - - MobLayer - - type: Appearance - - type: CombatMode - - type: Hands - showInHands: false - - type: Tag - tags: - - FootstepSound +# - type: entity +# name: onestar mecha +# id: Onestar +# parent: PlayerSiliconBase +# components: +# - type: InnateTool +# tools: +# - id: WeaponMinigun +# - id: EnergySword +# - id: WeaponLauncherMultipleRocket +# - id: WeaponXrayCannon +# - type: UserInterface +# interfaces: +# - key: enum.StrippingUiKey.Key +# type: StrippableBoundUserInterface +# - type: GhostRole +# makeSentient: true +# name: ghost-role-information-onestar-mecha-name +# description: ghost-role-information-onestar-mecha-description +# rules: ghost-role-information-onestar-mecha-rules +# - type: GhostTakeoverAvailable +# - type: MovementSpeedModifier +# baseWalkSpeed : 3 +# baseSprintSpeed : 2 +# - type: MobState +# allowedStates: +# - Alive +# - Dead +# - type: MobThresholds +# thresholds: +# 0: Alive +# 1000: Dead +# - type: Sprite +# drawdepth: Mobs +# layers: +# - state: onestar_boss +# sprite: Mobs/Silicon/onestar.rsi +# - state: onestar_boss_screen +# sprite: Mobs/Silicon/onestar.rsi +# shader: unshaded +# - type: FootstepModifier +# footstepSoundCollection: +# path: /Audio/Mecha/sound_mecha_powerloader_step.ogg +# - type: MovementIgnoreGravity +# - type: Fixtures +# fixtures: +# fix1: +# shape: +# !type:PhysShapeCircle +# radius: 1 +# density: 160 +# mask: +# - LargeMobMask +# layer: +# - MobLayer +# - type: Appearance +# - type: CombatMode +# - type: Hands +# showInHands: false +# - type: Tag +# tags: +# - FootstepSound diff --git a/Resources/Prototypes/Entities/Structures/Power/apc.yml b/Resources/Prototypes/Entities/Structures/Power/apc.yml index 2aa0e92541..6268fb786e 100644 --- a/Resources/Prototypes/Entities/Structures/Power/apc.yml +++ b/Resources/Prototypes/Entities/Structures/Power/apc.yml @@ -126,6 +126,8 @@ lowVoltageNode: output - type: DynamicPrice price: 500 + - type: BatteryDrinkerSource + maxAmount: 10000 # APC under construction - type: entity @@ -189,6 +191,8 @@ - type: Battery maxCharge: 50000 startingCharge: 50000 + - type: BatteryDrinkerSource + maxAmount: 5000 - type: entity parent: BaseAPC @@ -198,6 +202,8 @@ - type: Battery maxCharge: 100000 startingCharge: 100000 + - type: BatteryDrinkerSource + maxAmount: 12000 - type: entity parent: BaseAPC @@ -207,6 +213,8 @@ - type: Battery maxCharge: 150000 startingCharge: 150000 + - type: BatteryDrinkerSource + maxAmount: 18000 - type: entity parent: BaseAPC @@ -216,3 +224,5 @@ - type: Battery maxCharge: 200000 startingCharge: 200000 + - type: BatteryDrinkerSource + maxAmount: 26000 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/robots.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/robots.yml index 13cbeecd58..01d085fc51 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/robots.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Player/robots.yml @@ -186,6 +186,20 @@ False: { visible: false } - type: TypingIndicator proto: robot + - type: Battery + maxCharge: 50000 + - type: Silicon + entityType: enum.SiliconType.Player + batteryPowered: true + drainPerSecond: 15 + chargeThresholdMid: 0.60 + chargeThresholdLow: 0.30 + chargeThresholdCritical: 0 + speedModifierThresholds: + 4: 1 + 3: 1 + 2: 0.75 + 1: 0.15 - type: entity parent: PlayerRobotBase @@ -244,6 +258,14 @@ - NanoTrasen - type: TypingIndicator proto: robot + - type: ThermalRegulator # Better for extreme temperatures + metabolismHeat: 700 + radiatedHeat: 450 + implicitHeatRegulation: 350 + sweatHeatRegulation: 1200 + shiveringHeatRegulation: 1200 + normalBodyTemperature: 350 + thermalRegulationTemperatureThreshold: 325 - type: entity parent: PlayerRobotBase diff --git a/Resources/Prototypes/SimpleStation14/Alerts/alerts.yml b/Resources/Prototypes/SimpleStation14/Alerts/alerts.yml new file mode 100644 index 0000000000..24515f1e88 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Alerts/alerts.yml @@ -0,0 +1,19 @@ +- type: alert + id: Charge + icons: + - sprite: /Textures/SimpleStation14/Interface/Alerts/charge.rsi + state: charge-empty + - sprite: /Textures/SimpleStation14/Interface/Alerts/charge.rsi + state: charge0 + - sprite: /Textures/SimpleStation14/Interface/Alerts/charge.rsi + state: charge1 + - sprite: /Textures/SimpleStation14/Interface/Alerts/charge.rsi + state: charge2 + - sprite: /Textures/SimpleStation14/Interface/Alerts/charge.rsi + state: charge3 + - sprite: /Textures/SimpleStation14/Interface/Alerts/charge.rsi + state: charge4 + name: alerts-charge-name + description: alerts-charge-desc + minSeverity: -1 + maxSeverity: 4 diff --git a/Resources/Prototypes/SimpleStation14/Body/Organs/ipc.yml b/Resources/Prototypes/SimpleStation14/Body/Organs/ipc.yml new file mode 100644 index 0000000000..d44ed39fc7 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Body/Organs/ipc.yml @@ -0,0 +1,90 @@ +- type: entity + id: BaseIPCOrgan + parent: BaseItem + abstract: true + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/organs.rsi + - type: Organ + # - type: Food + # - type: Extractable + # grindableSolutionName: organ + - type: SolutionContainerManager + solutions: + organ: + reagents: + - ReagentId: MotorOil + Quantity: 10 + +- type: entity + id: OrganIPCBrain + parent: BaseIPCOrgan + name: positronic brain + description: "The source of as much controversy as the existence of the soul." + components: + - type: Sprite + state: brain + - type: Organ + - type: Input + context: "ghost" + - type: InputMover + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: GhostOnMove + - type: Brain + +- type: entity + id: OrganIPCEyes + parent: BaseIPCOrgan + name: robotic eyes + description: "01001001 00100000 01110011 01100101 01100101 00100000 01111001 01101111 01110101 00100001" + components: + - type: Sprite + layers: + - state: eyeball-l + - state: eyeball-r + - type: Organ + +- type: entity + id: OrganIPCTongue + parent: BaseIPCOrgan + name: vocal modulator + description: "A vocal modulator, used to produce speech." + components: + - type: Sprite + state: tongue + - type: Organ + +- type: entity + id: OrganIPCEars + parent: BaseIPCOrgan + name: "sonic receptors" + description: + components: + - type: Sprite + state: ears + - type: Organ + +- type: entity + id: OrganIPCPump + parent: BaseIPCOrgan + name: micro pump + description: "A micro pump, used to circulate coolant." + components: + - type: Sprite + state: heart-on + - type: Organ + # The heart 'metabolizes' medicines and poisons that aren't filtered out by other organs. + # This is done because these chemicals need to have some effect even if they aren't being filtered out of your body. + # You're technically 'immune to poison' without a heart, but.. uhh, you'll have bigger problems on your hands. + + # This is fine? + # - type: Metabolizer + # maxReagents: 2 + # metabolizerTypes: [Human] + # groups: + # - id: Medicine + # - id: Poison + # - id: Narcotic diff --git a/Resources/Prototypes/SimpleStation14/Body/Parts/ipc.yml b/Resources/Prototypes/SimpleStation14/Body/Parts/ipc.yml new file mode 100644 index 0000000000..b46c6997a9 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Body/Parts/ipc.yml @@ -0,0 +1,186 @@ +- type: entity + id: PartIPC + parent: BaseItem + name: "ipc body part" + abstract: true + components: + - type: Damageable + damageContainer: Inorganic + - type: BodyPart + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + - type: DynamicPrice + price: 100 + +- type: entity + id: TorsoIPC + name: "ipc torso" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "torso_m" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "torso_m" + - type: BodyPart + partType: Torso + +- type: entity + id: HeadIPC + name: "ipc head" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "head_m" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "head_m" + - type: BodyPart + partType: Head + vital: true + - type: Input + context: "ghost" + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: InputMover + - type: GhostOnMove + - type: Tag + tags: + - Head + +- type: entity + id: LeftArmIPC + name: "left ipc arm" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_arm" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_arm" + - type: BodyPart + partType: Arm + symmetry: Left + +- type: entity + id: RightArmIPC + name: "right ipc arm" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_arm" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_arm" + - type: BodyPart + partType: Arm + symmetry: Right + +- type: entity + id: LeftHandIPC + name: "left ipc hand" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_hand" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_hand" + - type: BodyPart + partType: Hand + symmetry: Left + +- type: entity + id: RightHandIPC + name: "right ipc hand" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_hand" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_hand" + - type: BodyPart + partType: Hand + symmetry: Right + +- type: entity + id: LeftLegIPC + name: "left ipc leg" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_leg" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_leg" + - type: BodyPart + partType: Leg + symmetry: Left + - type: MovementBodyPart + +- type: entity + id: RightLegIPC + name: "right ipc leg" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_leg" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_leg" + - type: BodyPart + partType: Leg + symmetry: Right + - type: MovementBodyPart + +- type: entity + id: LeftFootIPC + name: "left ipc foot" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_foot" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "l_foot" + - type: BodyPart + partType: Foot + symmetry: Left + +- type: entity + id: RightFootIPC + name: "right ipc foot" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_foot" + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: "r_foot" + - type: BodyPart + partType: Foot + symmetry: Right diff --git a/Resources/Prototypes/SimpleStation14/Body/Prototypes/ipc.yml b/Resources/Prototypes/SimpleStation14/Body/Prototypes/ipc.yml new file mode 100644 index 0000000000..ac19b7a09e --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Body/Prototypes/ipc.yml @@ -0,0 +1,45 @@ +- type: body + id: IPC + name: "ipc" + root: torso + slots: + head: + part: HeadIPC + connections: + - torso + organs: + eyes: OrganIPCEyes + torso: + part: TorsoIPC + connections: + - left arm + - right arm + - left leg + - right leg + organs: + brain: OrganIPCBrain + heart: OrganIPCPump + right arm: + part: RightArmIPC + connections: + - right hand + left arm: + part: LeftArmIPC + connections: + - left hand + right hand: + part: RightHandIPC + left hand: + part: LeftHandIPC + right leg: + part: RightLegIPC + connections: + - right foot + left leg: + part: LeftLegIPC + connections: + - left foot + right foot: + part: RightFootIPC + left foot: + part: LeftFootIPC diff --git a/Resources/Prototypes/SimpleStation14/Damage/modifier_sets.yml b/Resources/Prototypes/SimpleStation14/Damage/modifier_sets.yml new file mode 100644 index 0000000000..500d55549e --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Damage/modifier_sets.yml @@ -0,0 +1,18 @@ +- type: damageModifierSet + id: BloodlossIPC + coefficients: + Blunt: 1 + Slash: 0.6 + Piercing: 1.85 + Shock: 0.0 + Cold: 0.0 + Heat: 0 # heat damage doesn't cauterize metal! + Poison: 0.0 + Radiation: 0.0 + Asphyxiation: 0.0 + Bloodloss: 0.0 # no double dipping + Cellular: 0.0 + flatReductions: # Gotta crack a few borgs to get some coolant... + Blunt: 15 + Slash: 15 + Piercing: 15 diff --git a/Resources/Prototypes/SimpleStation14/Datasets/Names/ipc_names.yml b/Resources/Prototypes/SimpleStation14/Datasets/Names/ipc_names.yml new file mode 100644 index 0000000000..76a963dc51 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Datasets/Names/ipc_names.yml @@ -0,0 +1,1107 @@ +- type: dataset + id: IpcFirst + values: + - ABEX + - ANCL + - ANTR + - ARMA + - AURA + - BGB + - CBOS + - CDB + - CHOC + - CHRI + - COI + - CRUX + - CYBR + - DRSD + - DUNC + - EBIX + - EXOS + - FIRC + - FIZZ + - FRE + - FXMC + - GIGA + - GOOF + - GRIN + - GUN + - HBL + - HG + - HIU + - HOG + - INC + - JADE + - JJR + - JLLO + - JNLG + - JRD + - JUNO + - KALE + - KANO + - KAZA + - KENT + - KIV + - KOR + - KORA + - KOS + - LUMA + - LUNA + - LYNX + - MET + - MIW + - MNOS + - MRPR + - MSO + - NANO + - NEST + - NEXO + - NOVA + - ORNG + - OSI + - PBU + - PHL + - PKP + - PKR + - PLEX + - PLEXO + - PLIX + - QUES + - QUIN + - QWER + - RIFT + - RR + - RYNO + - RZH + - SINA + - SLI + - STLP + - TKRG + - TRIX + - VERA + - VEXA + - VITA + - VIVE + - VOLT + - WAVE + - WISP + - WJ + - WREN + - XAL + - XENA + - XIS + - XSI + - XYLO + - YAGO + - YPT + - ZACK + - ZARG + - ZEON + - ZOLT + - ZUMA + - ZYLO + - ZYVA + +- type: dataset + id: IpcLast + values: + - 000 + - 001 + - 002 + - 003 + - 004 + - 005 + - 006 + - 007 + - 008 + - 009 + - 010 + - 011 + - 012 + - 013 + - 014 + - 015 + - 016 + - 017 + - 018 + - 019 + - 020 + - 021 + - 022 + - 023 + - 024 + - 025 + - 026 + - 027 + - 028 + - 029 + - 030 + - 031 + - 032 + - 033 + - 034 + - 035 + - 036 + - 037 + - 038 + - 039 + - 040 + - 041 + - 042 + - 043 + - 044 + - 045 + - 046 + - 047 + - 048 + - 049 + - 050 + - 051 + - 052 + - 053 + - 054 + - 055 + - 056 + - 057 + - 058 + - 059 + - 060 + - 061 + - 062 + - 063 + - 064 + - 065 + - 066 + - 067 + - 068 + - 069 + - 070 + - 071 + - 072 + - 073 + - 074 + - 075 + - 076 + - 077 + - 078 + - 079 + - 080 + - 081 + - 082 + - 083 + - 084 + - 085 + - 086 + - 087 + - 088 + - 089 + - 090 + - 091 + - 092 + - 093 + - 094 + - 095 + - 096 + - 097 + - 098 + - 099 + - 100 + - 101 + - 102 + - 103 + - 104 + - 105 + - 106 + - 107 + - 108 + - 109 + - 110 + - 111 + - 112 + - 113 + - 114 + - 115 + - 116 + - 117 + - 118 + - 119 + - 120 + - 121 + - 122 + - 123 + - 124 + - 125 + - 126 + - 127 + - 128 + - 129 + - 130 + - 131 + - 132 + - 133 + - 134 + - 135 + - 136 + - 137 + - 138 + - 139 + - 140 + - 141 + - 142 + - 143 + - 144 + - 145 + - 146 + - 147 + - 148 + - 149 + - 150 + - 151 + - 152 + - 153 + - 154 + - 155 + - 156 + - 157 + - 158 + - 159 + - 160 + - 161 + - 162 + - 163 + - 164 + - 165 + - 166 + - 167 + - 168 + - 169 + - 170 + - 171 + - 172 + - 173 + - 174 + - 175 + - 176 + - 177 + - 178 + - 179 + - 180 + - 181 + - 182 + - 183 + - 184 + - 185 + - 186 + - 187 + - 188 + - 189 + - 190 + - 191 + - 192 + - 193 + - 194 + - 195 + - 196 + - 197 + - 198 + - 199 + - 200 + - 201 + - 202 + - 203 + - 204 + - 205 + - 206 + - 207 + - 208 + - 209 + - 210 + - 211 + - 212 + - 213 + - 214 + - 215 + - 216 + - 217 + - 218 + - 219 + - 220 + - 221 + - 222 + - 223 + - 224 + - 225 + - 226 + - 227 + - 228 + - 229 + - 230 + - 231 + - 232 + - 233 + - 234 + - 235 + - 236 + - 237 + - 238 + - 239 + - 240 + - 241 + - 242 + - 243 + - 244 + - 245 + - 246 + - 247 + - 248 + - 249 + - 250 + - 251 + - 252 + - 253 + - 254 + - 255 + - 256 + - 257 + - 258 + - 259 + - 260 + - 261 + - 262 + - 263 + - 264 + - 265 + - 266 + - 267 + - 268 + - 269 + - 270 + - 271 + - 272 + - 273 + - 274 + - 275 + - 276 + - 277 + - 278 + - 279 + - 280 + - 281 + - 282 + - 283 + - 284 + - 285 + - 286 + - 287 + - 288 + - 289 + - 290 + - 291 + - 292 + - 293 + - 294 + - 295 + - 296 + - 297 + - 298 + - 299 + - 300 + - 301 + - 302 + - 303 + - 304 + - 305 + - 306 + - 307 + - 308 + - 309 + - 310 + - 311 + - 312 + - 313 + - 314 + - 315 + - 316 + - 317 + - 318 + - 319 + - 320 + - 321 + - 322 + - 323 + - 324 + - 325 + - 326 + - 327 + - 328 + - 329 + - 330 + - 331 + - 332 + - 333 + - 334 + - 335 + - 336 + - 337 + - 338 + - 339 + - 340 + - 341 + - 342 + - 343 + - 344 + - 345 + - 346 + - 347 + - 348 + - 349 + - 350 + - 351 + - 352 + - 353 + - 354 + - 355 + - 356 + - 357 + - 358 + - 359 + - 360 + - 361 + - 362 + - 363 + - 364 + - 365 + - 366 + - 367 + - 368 + - 369 + - 370 + - 371 + - 372 + - 373 + - 374 + - 375 + - 376 + - 377 + - 378 + - 379 + - 380 + - 381 + - 382 + - 383 + - 384 + - 385 + - 386 + - 387 + - 388 + - 389 + - 390 + - 391 + - 392 + - 393 + - 394 + - 395 + - 396 + - 397 + - 398 + - 399 + - 400 + - 401 + - 402 + - 403 + - 404 + - 405 + - 406 + - 407 + - 408 + - 409 + - 410 + - 411 + - 412 + - 413 + - 414 + - 415 + - 416 + - 417 + - 418 + - 419 + - 420 + - 421 + - 422 + - 423 + - 424 + - 425 + - 426 + - 427 + - 428 + - 429 + - 430 + - 431 + - 432 + - 433 + - 434 + - 435 + - 436 + - 437 + - 438 + - 439 + - 440 + - 441 + - 442 + - 443 + - 444 + - 445 + - 446 + - 447 + - 448 + - 449 + - 450 + - 451 + - 452 + - 453 + - 454 + - 455 + - 456 + - 457 + - 458 + - 459 + - 460 + - 461 + - 462 + - 463 + - 464 + - 465 + - 466 + - 467 + - 468 + - 469 + - 470 + - 471 + - 472 + - 473 + - 474 + - 475 + - 476 + - 477 + - 478 + - 479 + - 480 + - 481 + - 482 + - 483 + - 484 + - 485 + - 486 + - 487 + - 488 + - 489 + - 490 + - 491 + - 492 + - 493 + - 494 + - 495 + - 496 + - 497 + - 498 + - 499 + - 500 + - 501 + - 502 + - 503 + - 504 + - 505 + - 506 + - 507 + - 508 + - 509 + - 510 + - 511 + - 512 + - 513 + - 514 + - 515 + - 516 + - 517 + - 518 + - 519 + - 520 + - 521 + - 522 + - 523 + - 524 + - 525 + - 526 + - 527 + - 528 + - 529 + - 530 + - 531 + - 532 + - 533 + - 534 + - 535 + - 536 + - 537 + - 538 + - 539 + - 540 + - 541 + - 542 + - 543 + - 544 + - 545 + - 546 + - 547 + - 548 + - 549 + - 550 + - 551 + - 552 + - 553 + - 554 + - 555 + - 556 + - 557 + - 558 + - 559 + - 560 + - 561 + - 562 + - 563 + - 564 + - 565 + - 566 + - 567 + - 568 + - 569 + - 570 + - 571 + - 572 + - 573 + - 574 + - 575 + - 576 + - 577 + - 578 + - 579 + - 580 + - 581 + - 582 + - 583 + - 584 + - 585 + - 586 + - 587 + - 588 + - 589 + - 590 + - 591 + - 592 + - 593 + - 594 + - 595 + - 596 + - 597 + - 598 + - 599 + - 600 + - 601 + - 602 + - 603 + - 604 + - 605 + - 606 + - 607 + - 608 + - 609 + - 610 + - 611 + - 612 + - 613 + - 614 + - 615 + - 616 + - 617 + - 618 + - 619 + - 620 + - 621 + - 622 + - 623 + - 624 + - 625 + - 626 + - 627 + - 628 + - 629 + - 630 + - 631 + - 632 + - 633 + - 634 + - 635 + - 636 + - 637 + - 638 + - 639 + - 640 + - 641 + - 642 + - 643 + - 644 + - 645 + - 646 + - 647 + - 648 + - 649 + - 650 + - 651 + - 652 + - 653 + - 654 + - 655 + - 656 + - 657 + - 658 + - 659 + - 660 + - 661 + - 662 + - 663 + - 664 + - 665 + - 666 + - 667 + - 668 + - 669 + - 670 + - 671 + - 672 + - 673 + - 674 + - 675 + - 676 + - 677 + - 678 + - 679 + - 680 + - 681 + - 682 + - 683 + - 684 + - 685 + - 686 + - 687 + - 688 + - 689 + - 690 + - 691 + - 692 + - 693 + - 694 + - 695 + - 696 + - 697 + - 698 + - 699 + - 700 + - 701 + - 702 + - 703 + - 704 + - 705 + - 706 + - 707 + - 708 + - 709 + - 710 + - 711 + - 712 + - 713 + - 714 + - 715 + - 716 + - 717 + - 718 + - 719 + - 720 + - 721 + - 722 + - 723 + - 724 + - 725 + - 726 + - 727 + - 728 + - 729 + - 730 + - 731 + - 732 + - 733 + - 734 + - 735 + - 736 + - 737 + - 738 + - 739 + - 740 + - 741 + - 742 + - 743 + - 744 + - 745 + - 746 + - 747 + - 748 + - 749 + - 750 + - 751 + - 752 + - 753 + - 754 + - 755 + - 756 + - 757 + - 758 + - 759 + - 760 + - 761 + - 762 + - 763 + - 764 + - 765 + - 766 + - 767 + - 768 + - 769 + - 770 + - 771 + - 772 + - 773 + - 774 + - 775 + - 776 + - 777 + - 778 + - 779 + - 780 + - 781 + - 782 + - 783 + - 784 + - 785 + - 786 + - 787 + - 788 + - 789 + - 790 + - 791 + - 792 + - 793 + - 794 + - 795 + - 796 + - 797 + - 798 + - 799 + - 800 + - 801 + - 802 + - 803 + - 804 + - 805 + - 806 + - 807 + - 808 + - 809 + - 810 + - 811 + - 812 + - 813 + - 814 + - 815 + - 816 + - 817 + - 818 + - 819 + - 820 + - 821 + - 822 + - 823 + - 824 + - 825 + - 826 + - 827 + - 828 + - 829 + - 830 + - 831 + - 832 + - 833 + - 834 + - 835 + - 836 + - 837 + - 838 + - 839 + - 840 + - 841 + - 842 + - 843 + - 844 + - 845 + - 846 + - 847 + - 848 + - 849 + - 850 + - 851 + - 852 + - 853 + - 854 + - 855 + - 856 + - 857 + - 858 + - 859 + - 860 + - 861 + - 862 + - 863 + - 864 + - 865 + - 866 + - 867 + - 868 + - 869 + - 870 + - 871 + - 872 + - 873 + - 874 + - 875 + - 876 + - 877 + - 878 + - 879 + - 880 + - 881 + - 882 + - 883 + - 884 + - 885 + - 886 + - 887 + - 888 + - 889 + - 890 + - 891 + - 892 + - 893 + - 894 + - 895 + - 896 + - 897 + - 898 + - 899 + - 900 + - 901 + - 902 + - 903 + - 904 + - 905 + - 906 + - 907 + - 908 + - 909 + - 910 + - 911 + - 912 + - 913 + - 914 + - 915 + - 916 + - 917 + - 918 + - 919 + - 920 + - 921 + - 922 + - 923 + - 924 + - 925 + - 926 + - 927 + - 928 + - 929 + - 930 + - 931 + - 932 + - 933 + - 934 + - 935 + - 936 + - 937 + - 938 + - 939 + - 940 + - 941 + - 942 + - 943 + - 944 + - 945 + - 946 + - 947 + - 948 + - 949 + - 950 + - 951 + - 952 + - 953 + - 954 + - 955 + - 956 + - 957 + - 958 + - 959 + - 960 + - 961 + - 962 + - 963 + - 964 + - 965 + - 966 + - 967 + - 968 + - 969 + - 970 + - 971 + - 972 + - 973 + - 974 + - 975 + - 976 + - 977 + - 978 + - 979 + - 980 + - 981 + - 982 + - 983 + - 984 + - 985 + - 986 + - 987 + - 988 + - 989 + - 990 + - 991 + - 992 + - 993 + - 994 + - 995 + - 996 + - 997 + - 998 + - 999 diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/antenna.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/antenna.yml new file mode 100644 index 0000000000..ec58320e7b --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/antenna.yml @@ -0,0 +1,89 @@ +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaTv + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_tv + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaTesla + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_tesla + +# - type: marking +# speciesRestriction: [IPC] +# id: RobotAntennaLightb +# bodyPart: Hair +# markingCategory: Hair +# sprites: +# - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi +# state: ipc_antenna_lightb + +# - type: marking +# speciesRestriction: [IPC] +# id: RobotAntennaLight +# bodyPart: Hair +# markingCategory: Hair +# sprites: +# - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi +# state: ipc_antenna_light + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaCyberhead + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_cyberhead + +# - type: marking +# speciesRestriction: [IPC] +# id: RobotAntennaSidelights +# bodyPart: Hair +# markingCategory: Hair +# sprites: +# - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi +# state: ipc_antenna_sidelights + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaAntlers + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_antlers + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaDroneeyes + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_droneeyes + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaCrowned + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_crowned + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaTowers + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_towers diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/screens.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/screens.yml new file mode 100644 index 0000000000..d50a5bcf53 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Customization/screens.yml @@ -0,0 +1,350 @@ +- type: marking + speciesRestriction: [IPC] + id: ScreenStatic + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_static + +- type: marking + speciesRestriction: [IPC] + id: ScreenBlue + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_blue + +- type: marking + speciesRestriction: [IPC] + id: ScreenBreakout + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_breakout + +- type: marking + speciesRestriction: [IPC] + id: ScreenEight + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eight + +- type: marking + speciesRestriction: [IPC] + id: ScreenGoggles + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_goggles + +- type: marking + speciesRestriction: [IPC] + id: ScreenExclaim + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_exclaim + +- type: marking + speciesRestriction: [IPC] + id: ScreenHeart + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_heart + +- type: marking + speciesRestriction: [IPC] + id: ScreenMonoeye + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_monoeye + +- type: marking + speciesRestriction: [IPC] + id: ScreenNature + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_nature + +- type: marking + speciesRestriction: [IPC] + id: ScreenOrange + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_orange + +- type: marking + speciesRestriction: [IPC] + id: ScreenPink + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_pink + +- type: marking + speciesRestriction: [IPC] + id: ScreenQuestion + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_question + +- type: marking + speciesRestriction: [IPC] + id: ScreenShower + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_shower + +- type: marking + speciesRestriction: [IPC] + id: ScreenYellow + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_yellow + +- type: marking + speciesRestriction: [IPC] + id: ScreenScroll + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_scroll + +- type: marking + speciesRestriction: [IPC] + id: ScreenConsole + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_console + +- type: marking + speciesRestriction: [IPC] + id: ScreenRgb + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_rgb + +- type: marking + speciesRestriction: [IPC] + id: ScreenGlider + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_glider + +- type: marking + speciesRestriction: [IPC] + id: ScreenRainbowhoriz + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_rainbowhoriz + +- type: marking + speciesRestriction: [IPC] + id: ScreenBsod + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_bsod + +- type: marking + speciesRestriction: [IPC] + id: ScreenRedtext + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_redtext + +- type: marking + speciesRestriction: [IPC] + id: ScreenSinewave + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_sinewave + +- type: marking + speciesRestriction: [IPC] + id: ScreenSquarewave + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_squarewave + +- type: marking + speciesRestriction: [IPC] + id: ScreenEcgwave + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_ecgwave + +- type: marking + speciesRestriction: [IPC] + id: ScreenEyes + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eyes + +- type: marking + speciesRestriction: [IPC] + id: ScreenEyestall + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eyestall + +- type: marking + speciesRestriction: [IPC] + id: ScreenEyesangry + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eyesangry + +- type: marking + speciesRestriction: [IPC] + id: ScreenLoading + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_loading + +- type: marking + speciesRestriction: [IPC] + id: ScreenWindowsxp + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_windowsxp + +- type: marking + speciesRestriction: [IPC] + id: ScreenTetris + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_tetris + +- type: marking + speciesRestriction: [IPC] + id: ScreenTv + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_tv + +- type: marking + speciesRestriction: [IPC] + id: ScreenTextdrop + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_textdrop + +- type: marking + speciesRestriction: [IPC] + id: ScreenStars + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_stars + +- type: marking + speciesRestriction: [IPC] + id: ScreenRainbowdiag + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_rainbowdiag + +- type: marking + speciesRestriction: [IPC] + id: ScreenBlank + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_blank + +- type: marking + speciesRestriction: [IPC] + id: ScreenSmile + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_smile + +- type: marking + speciesRestriction: [IPC] + id: ScreenFrown + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_frown + +- type: marking + speciesRestriction: [IPC] + id: ScreenRing + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_ring + +- type: marking + speciesRestriction: [IPC] + id: ScreenL + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: SimpleStation14/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_l diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/ipc.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/ipc.yml new file mode 100644 index 0000000000..f129e703d1 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/ipc.yml @@ -0,0 +1,84 @@ +- type: entity + id: MobIPC + parent: PlayerSiliconHumanoidBase + name: Urist McPositronic + description: A positronic brain in a metal body. + components: + - type: SiliconEmitSoundOnDrained + sound: "/Audio/Weapons/Guns/EmptyAlarm/smg_empty_alarm.ogg" + interval: 15 + playChance: 1 + popUp: "silicon-power-low" + - type: MobState + allowedStates: + - Alive + - Critical + - Dead + - type: MobThresholds + thresholds: + 0: Alive + 140: Critical + 180: Dead + - type: TypingIndicator + proto: robot + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 400 + behaviors: + - !type:GibBehavior { } + - type: SlowOnDamage + speedModifierThresholds: + 60: 0.7 + 90: 0.5 + 120: 0.3 + - type: SiliconDownOnDead + - type: Inventory + templateId: ipc + - type: EyeProtection + protectionTime: 12 + - type: Battery + maxCharge: 150000 + - type: RandomBatteryCharge + batteryMaxMinMax: 0.85, 1.15 + batteryChargeMinMax: 0.40, 0.90 + - type: Silicon + entityType: enum.SiliconType.Player + batteryPowered: true + drainPerSecond: 60 + chargeThresholdMid: 0.80 + chargeThresholdLow: 0.35 + chargeThresholdCritical: 0.10 + speedModifierThresholds: + 4: 1 + 3: 1 + 2: 0.80 + 1: 0.45 + 0: 0.00 + - type: Carriable + - type: BatteryDrinker + - type: EncryptionKeyHolder + keySlots: 3 + examineWhileLocked: false + keysExtractionMethod: Cutting + - type: ActiveRadio + - type: IntrinsicRadioReceiver + - type: IntrinsicRadioTransmitter + - type: Wires + BoardName: "IPC" + LayoutId: IPC + +- type: entity + save: false + name: Urist McPositronic + parent: MobHumanDummy + id: MobIPCDummy + noSpawn: true + description: A dummy IPC meant to be used in character setup. + components: + - type: HumanoidAppearance + species: IPC + - type: Inventory + templateId: ipc diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/silicon_base.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/silicon_base.yml new file mode 100644 index 0000000000..703db6b958 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/silicon_base.yml @@ -0,0 +1,372 @@ +- type: entity + save: false + abstract: true + id: PlayerSiliconBase # For player controlled silicons + components: + - type: Reactive + groups: + Acidic: [Touch] + - type: Input + context: "human" + - type: InputMover + - type: MobMover + - type: DamageOnHighSpeedImpact + damage: + types: + Blunt: 5 + soundHit: + path: /Audio/Effects/hit_kick.ogg + - type: Clickable + - type: Damageable + damageContainer: Inorganic + # - type: Bloodstream # This is left commented out because it's not necessary for a robot, but you may want it. + # bloodReagent: MotorOil + # bloodlossDamage: + # types: + # Bloodloss: + # 1 + # bloodlossHealDamage: + # types: + # Bloodloss: + # -0.25 + - type: InteractionOutline + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.35 + density: 50 + mask: + - MobMask + layer: + - MobLayer + - type: MovementSpeedModifier + baseWalkSpeed: 4 + baseSprintSpeed: 3 + - type: Sprite + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: full + noRot: true + drawdepth: Mobs + - type: Physics + bodyType: KinematicController + - type: Body + prototype: Drone + - type: DoAfter + - type: Examiner + # - type: Recyclable + # safe: false + - type: StandingState + - type: Alerts + # - type: EyeProtection # You'll want this if your robot can't wear glasses, like an IPC. + # protectionTime: 12 + - type: Silicon + entityType: enum.SiliconType.Player + batteryPowered: false # Needs to also have a battery! + chargeThresholdMid: 0.60 + chargeThresholdLow: 0.30 + chargeThresholdCritical: 0 + speedModifierThresholds: + 4: 1 + 3: 1 + 2: 0.80 + 1: 0.45 + 0: 0.00 + - type: RadiationReceiver + - type: AtmosExposed + - type: Temperature + heatDamageThreshold: 700 + coldDamageThreshold: 0 + currentTemperature: 400 + specificHeat: 24 + coldDamage: + types: + Cold: 0.1 #per second, scales with temperature & other constants + heatDamage: + types: + Heat: 0.25 #per second, scales with temperature & other constants + atmosTemperatureTransferEfficiency: 0.05 + - type: ThermalRegulator + metabolismHeat: 600 + radiatedHeat: 350 + implicitHeatRegulation: 350 + sweatHeatRegulation: 0 # This might end up being a problem if they can't cool themselves down? + shiveringHeatRegulation: 1200 + normalBodyTemperature: 400 + thermalRegulationTemperatureThreshold: 125 + +- type: entity + parent: PlayerSiliconBase + id: PlayerSiliconHumanoidBase + abstract: true + components: + - type: MobState + allowedStates: + - Alive + - Dead + - type: MobThresholds + thresholds: + 0: Alive + 165: Dead + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 500 + behaviors: + - !type:GibBehavior {} + - type: Icon + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: full + - type: Sprite + noRot: true + drawdepth: Mobs + layers: + - map: ["enum.HumanoidVisualLayers.Chest"] + - map: ["enum.HumanoidVisualLayers.Head"] + - map: ["enum.HumanoidVisualLayers.Snout"] + - map: ["enum.HumanoidVisualLayers.Eyes"] + - map: ["enum.HumanoidVisualLayers.RArm"] + - map: ["enum.HumanoidVisualLayers.LArm"] + - map: ["enum.HumanoidVisualLayers.RLeg"] + - map: ["enum.HumanoidVisualLayers.LLeg"] + - shader: StencilClear + sprite: Mobs/Species/Human/parts.rsi + state: l_leg + - shader: StencilMask + map: ["enum.HumanoidVisualLayers.StencilMask"] + sprite: Mobs/Customization/masking_helpers.rsi + state: female_full + visible: false + - map: ["enum.HumanoidVisualLayers.LFoot"] + - map: ["enum.HumanoidVisualLayers.RFoot"] + - map: ["socks"] + - map: ["underpants"] + - map: ["undershirt"] + - map: ["jumpsuit"] + - map: ["enum.HumanoidVisualLayers.LHand"] + - map: ["enum.HumanoidVisualLayers.RHand"] + - map: ["enum.HumanoidVisualLayers.Handcuffs"] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: ["id"] + - map: ["gloves"] + - map: ["shoes"] + - map: ["ears"] + - map: ["outerClothing"] + - map: ["eyes"] + - map: ["belt"] + - map: ["neck"] + - map: ["back"] + - map: ["enum.HumanoidVisualLayers.FacialHair"] + - map: ["enum.HumanoidVisualLayers.Hair"] + - map: ["enum.HumanoidVisualLayers.HeadSide"] + - map: ["enum.HumanoidVisualLayers.HeadTop"] + - map: ["mask"] + - map: ["head"] + - map: ["pocket1"] + - map: ["pocket2"] + - map: ["enum.HumanoidVisualLayers.Tail"] + - map: ["enum.HumanoidVisualLayers.Wings"] + - map: ["clownedon"] # Dynamically generated + sprite: "Effects/creampie.rsi" + state: "creampie_human" + visible: false + - type: Repairable + fuelcost: 60 + doAfterDelay: 32 + - type: Bloodstream + damageBleedModifiers: BloodlossIPC + bloodReagent: Water + bleedReductionAmount: 0 + bloodMaxVolume: 500 + chemicalMaxVolume: 0 + bleedPuddleThreshold: 3 + bleedRefreshAmount: 0 + bloodLossThreshold: 0 + maxBleedAmount: 14 + bloodlossDamage: + types: + Burn: 1.5 + bloodlossHealDamage: + types: + Burn: 0 + - type: Flammable + fireSpread: true + canResistFire: true + damage: + types: + Heat: 0.75 #per second, scales with number of fire 'stacks' + # - type: Barotrauma # Not particularly modifiable. In the future, some response to pressure changes would be nice. + # damage: + # types: + # Blunt: 0.28 #per second, scales with pressure and other constants. + - type: Temperature + heatDamageThreshold: 320 + coldDamageThreshold: 255 + currentTemperature: 280 + specificHeat: 50 + coldDamage: + types: + Cold: 0.1 #per second, scales with temperature & other constants + heatDamage: + types: + Heat: 0.15 #per second, scales with temperature & other constants + atmosTemperatureTransferEfficiency: 0.4 + - type: ThermalRegulator + metabolismHeat: 1000 # Increase once we have more ways to regulate temperature + radiatedHeat: 800 + implicitHeatRegulation: 600 + sweatHeatRegulation: 0 + shiveringHeatRegulation: 12000 # Overclocking, yo + normalBodyTemperature: 280 + thermalRegulationTemperatureThreshold: 32 + - type: Polymorphable + - type: Identity + - type: MovedByPressure + - type: DamageOnHighSpeedImpact + damage: + types: + Blunt: 5 + soundHit: + path: /Audio/Effects/metalbreak.ogg + - type: LagCompensation + - type: RangedDamageSound + soundGroups: + Brute: + collection: MetalBulletImpact + soundTypes: + Heat: + collection: MetalLaserImpact + - type: Tag + tags: + - CanPilot + - FootstepSound + - DoorBumpOpener + - type: Hands + - type: Inventory + templateId: human + - type: InventorySlots + - type: Appearance + - type: GenericVisualizer + visuals: + enum.CreamPiedVisuals.Creamed: + clownedon: # Not 'creampied' bc I can already see Skyrat complaining about conflicts. + True: { visible: true } + False: { visible: false } + - type: RotationVisuals + - type: FloatingVisuals + - type: FireVisuals + sprite: Mobs/Effects/onfire.rsi + normalState: Generic_mob_burning + alternateState: Standing + fireStackAlternateState: 3 + - type: CombatMode + canDisarm: true + - type: Climbing + - type: Cuffable + state: icon + - type: AnimationPlayer + - type: Buckle + - type: CreamPied + - type: Stripping + - type: Strippable + - type: UserInterface + interfaces: + - key: enum.VoiceMaskUIKey.Key + type: VoiceMaskBoundUserInterface + - key: enum.HumanoidMarkingModifierKey.Key + type: HumanoidMarkingModifierBoundUserInterface + - key: enum.StrippingUiKey.Key + type: StrippableBoundUserInterface + - type: Emoting + - type: Grammar + attributes: + proper: true + - type: StandingState + - type: CanEscapeInventory + - type: HumanoidAppearance + species: IPC + - type: Body + prototype: IPC + requiredLegs: 2 + - type: Ensnareable + sprite: Objects/Misc/ensnare.rsi + - type: Speech + speechSounds: Pai + - type: Vocal + sounds: + Male: MaleHuman + Female: FemaleHuman + Unsexed: MaleHuman + - type: MeleeWeapon + hidden: true + soundHit: + collection: Punch + angle: 30 + animation: WeaponArcFist + attackRate: 1 + damage: + types: + Blunt: 6 # It's tough. + - type: MobPrice + price: 1500 # Kidnapping a living person and selling them for cred is a good move. + deathPenalty: 0.01 # However they really ought to be living and intact, otherwise they're worth 100x less. + - type: Pullable + - type: Puller + - type: Reactive + groups: + Flammable: [Touch] + Extinguish: [Touch] + Acidic: [Touch, Ingestion] + reactions: + - reagents: [Water, SpaceCleaner] + methods: [Touch] + effects: + - !type:WashCreamPieReaction + - type: BodyEmotes + soundsId: GeneralBodyEmotes + - type: DamageVisuals + thresholds: [20, 40, 100] + targetLayers: + - "enum.HumanoidVisualLayers.Chest" + - "enum.HumanoidVisualLayers.Head" + - "enum.HumanoidVisualLayers.LArm" + - "enum.HumanoidVisualLayers.LLeg" + - "enum.HumanoidVisualLayers.RArm" + - "enum.HumanoidVisualLayers.RLeg" + damageOverlayGroups: + Brute: + sprite: Mobs/Effects/brute_damage.rsi + color: "#DD8822" + Burn: + sprite: Mobs/Effects/burn_damage.rsi + # Organs + - type: IdExaminable + - type: HealthExaminable + examinableTypes: + - Blunt + - Slash + - Piercing + - Heat + - Shock + - type: StatusEffects + allowed: + - Stun + - KnockedDown + - SlowedDown + - Stutter + - SeeingRainbows + - Electrocution + # - Drunk + - SlurredSpeech + - PressureImmunity + - Muted + # - ForcedSleep + - TemporaryBlindness + - Pacified + # - PsionicsDisabled + # - PsionicallyInsulated + - type: Blindable diff --git a/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/silicon_ghost.yml b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/silicon_ghost.yml new file mode 100644 index 0000000000..e3af0abbdb --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Mobs/Player/silicon_ghost.yml @@ -0,0 +1,153 @@ +- type: entity + id: PlayerSiliconGhostBase + parent: PlayerSiliconBase + abstract: true + components: + - type: GhostTakeoverAvailable + makeSentient: true + name: Maintenance Drone + description: Maintain the station. Ignore other beings except drones. + rules: | + You are bound by these laws both in-game and out-of-character: + 1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone. + 2. You may not harm any being, regardless of intent or circumstance. + 3. Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals. + - type: Hands + showInHands: false + - type: Tag + tags: + - ShoesRequiredStepTriggerImmune + +- type: entity + name: drone + id: Drone + parent: PlayerSiliconGhostBase + components: + - type: Drone + - type: InnateTool + tools: + - id: ClothingBackpackSatchelDrone + - id: trayScanner + - id: Omnitool + - id: WelderExperimental + - type: Eye + - type: Inventory + templateId: drone + - type: Strippable + - type: UserInterface + interfaces: + - key: enum.StrippingUiKey.Key + type: StrippableBoundUserInterface + - key: enum.LawsUiKey.Key + type: LawsBoundUserInterface + - type: GhostTakeoverAvailable + name: Maintenance Drone + description: Maintain the station. Ignore other beings except drones. + rules: | + You are bound by these laws both in-game and out-of-character: + 1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone. + 2. You may not harm any being, regardless of intent or circumstance. + 3. Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals. + - type: IgnoreHumanoidsOverlay + - type: Laws + canState: false + laws: + - You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone. + - You may not harm any being, regardless of intent or circumstance. + - Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals. + - You may accept orders received via the binary channel, regardless of the nature of the being issuing them, so long as they do not conflict with Law Two or Law Three. + - type: MovementSpeedModifier + baseWalkSpeed: 5 + baseSprintSpeed: 5 + - type: MobState + allowedStates: + - Alive + - Dead + - type: MobThresholds + thresholds: + 0: Alive + 60: Dead + - type: Flashable + - type: NoSlip + - type: StatusEffects + allowed: + - Stun + - KnockedDown + - SlowedDown + - type: SlowOnDamage + speedModifierThresholds: + 30: 0.7 + 50: 0.5 + - type: Temperature + heatDamageThreshold: 5000 + currentTemperature: 310.15 + specificHeat: 42 + heatDamage: + types: + Heat: 1 #per second, scales with temperature & other constants + - type: Sprite + drawdepth: SmallMobs + layers: + - state: shell + sprite: Mobs/Silicon/drone.rsi + map: ["base"] + - type: MovementIgnoreGravity + - type: Fixtures + fixtures: + fix1: + shape: !type:PhysShapeCircle + radius: 0.35 + density: 50 + mask: + - SmallMobMask + layer: + - SmallMobLayer + - type: Appearance + - type: GenericVisualizer + visuals: + enum.DroneVisuals.Status: + base: + Off: { state: shell } + On: { state: drone } + - type: ReplacementAccent + accent: silicon + - type: Repairable + fuelcost: 15 + doAfterDelay: 8 + - type: Actions + - type: UnpoweredFlashlight + toggleAction: + name: action-name-toggle-light + description: action-description-toggle-light + icon: { sprite: Objects/Tools/flashlight.rsi, state: flashlight } + iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png + event: !type:ToggleActionEvent + - type: PointLight + enabled: false + radius: 3.5 + softness: 1 + mask: /Textures/Effects/LightMasks/cone.png + autoRot: true + - type: Tag + tags: + - ShoesRequiredStepTriggerImmune + - CannotSuicide + - type: Hands + showInHands: false + - type: IntrinsicUI + uis: + - key: enum.LawsUiKey.Key + toggleAction: + name: action-name-show-laws + description: action-description-show-laws + icon: Structures/Wallmounts/posters.rsi/poster11_legit.png #someone wanna make new icons? + iconOn: Structures/Wallmounts/posters.rsi/poster11_legit.png + keywords: ["AI", "console", "interface", "laws", "borg"] + priority: -3 + event: !type:ToggleIntrinsicUIEvent + - type: IntrinsicRadioReceiver + channels: + - Binary + - type: ActiveRadio + channels: + - Binary diff --git a/Resources/Prototypes/SimpleStation14/Entities/Objects/Devices/Circuitboards/siliconchargers.yml b/Resources/Prototypes/SimpleStation14/Entities/Objects/Devices/Circuitboards/siliconchargers.yml new file mode 100644 index 0000000000..9acf92dcec --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Objects/Devices/Circuitboards/siliconchargers.yml @@ -0,0 +1,34 @@ +- type: entity + id: IndustrialChargerCircuitboard + parent: BaseMachineCircuitboard + name: industrial charger machine board + description: A machine printed circuit board for an industrial charger + components: + - type: Sprite + state: engineering + - type: MachineBoard + prototype: SiliconChargerIndustrial + requirements: + Capacitor: 8 + Manipulator: 2 + materialRequirements: + Plastic: 6 + CableHV: 4 + CableMV: 8 + +- type: entity + id: ChargingPadCircuitboard + parent: BaseMachineCircuitboard + name: charging pad machine board + description: A machine printed circuit board for a charging pad + components: + - type: Sprite + state: engineering + - type: MachineBoard + prototype: SiliconChargerChargePad + requirements: + Capacitor: 3 + Laser: 5 + materialRequirements: + CableHV: 2 + CableMV: 2 diff --git a/Resources/Prototypes/SimpleStation14/Entities/Structures/Machines/silicon_chargers.yml b/Resources/Prototypes/SimpleStation14/Entities/Structures/Machines/silicon_chargers.yml new file mode 100644 index 0000000000..09ba684655 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Entities/Structures/Machines/silicon_chargers.yml @@ -0,0 +1,202 @@ +- type: entity + id: SiliconChargerIndustrial + parent: BaseMachinePowered + name: industrial charger + description: A heavy duty machine for inductively charging robotic beings. Gets extremely hot! + components: + - type: Sprite + sprite: SimpleStation14/Structures/Machines/borgcharger.rsi + noRot: true + layers: + - state: base + - state: closed + map: ["enum.StorageVisualLayers.Door"] + - state: borgcharger_closed_unlit + shader: unshaded + map: ["enum.SiliconChargerVisuals.Lights"] + - type: EntityStorageVisuals + stateDoorOpen: open + stateDoorClosed: closed + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.VisualState: + enum.SiliconChargerVisuals.Lights: + Normal: { state: "borgcharger_closed_unlit" } + NormalOpen: { state: "borgcharger_open_unlit" } + Charging: { state: "borgcharger_active_unlit" } + enum.PowerDeviceVisuals.Powered: + enum.SiliconChargerVisuals.Lights: + True: { visible: true } + False: { visible: false } + - type: Icon + sprite: SimpleStation14/Structures/Machines/borgcharger.rsi + state: icon + - type: Physics + bodyType: Static + fixtures: + - shape: + - !type:PhysShapeAabb + bounds: "-0.45,-0.5,0.45,0.5" + density: 190 + mask: + - MachineMask + layer: + - MachineLayer + - type: ApcPowerReceiver + powerLoad: 500 + - type: DynamicPrice + price: 600 + - type: EntityStorage + capacity: 1 + isCollidableWhenOpen: true + openOnMove: false + enteringOffset: 0, -0.5 + openSound: /Audio/Effects/gen_hit.ogg + closeSound: /Audio/Effects/gen_hit.ogg + - type: Appearance + visuals: + - type: StorageVisualizer + state_open: open + state_closed: closed + - type: ContainerContainer + containers: + machine_board: !type:Container + machine_parts: !type:Container + entity_storage: !type:Container + - type: SiliconCharger + chargeMulti: 1000 + targetTemp: 390 + - type: Construction + graph: Machine + node: machine + containers: + - machine_board + - machine_parts + - type: Machine + board: IndustrialChargerCircuitboard + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 350 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] + +- type: entity + id: SiliconChargerChargePad + parent: BaseMachinePowered + name: charging pad + description: A charging pad for inductively charging smaller robotic beings. + components: + - type: Sprite + netsync: false + sprite: SimpleStation14/Structures/Machines/charging_pad.rsi + drawdepth: FloorObjects + layers: + - state: offline + - state: idle + shader: unshaded + map: ["enum.SiliconChargerVisuals.Lights"] + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.VisualState: + enum.SiliconChargerVisuals.Lights: + Normal: { state: "idle" } + Charging: { state: "beam" } + enum.PowerDeviceVisuals.Powered: + enum.SiliconChargerVisuals.Lights: + True: { visible: true } + False: { visible: false } + - type: ApcPowerReceiver + powerLoad: 150 + - type: DynamicPrice + price: 200 + - type: Physics + canCollide: true + - type: Appearance + - type: Fixtures + fixtures: + fix1: + shape: !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" + id: "slips" + hard: false + layer: + - SlipLayer + fix2: + shape: !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" + density: 10 + mask: + - MachineMask + - type: StepTrigger + - type: SiliconCharger + chargeMylti: 150 + - type: ContainerContainer + containers: + machine_board: !type:Container + machine_parts: !type:Container + - type: Construction + graph: Machine + node: machine + containers: + - machine_board + - machine_parts + - type: Machine + board: IndustrialChargerCircuitboard + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 350 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] + + # Generated, maybe good? + # + # - type: Machine + # board: SiliconChargerMachineCircuitboard + # - type: Construction + # graph: Machine + # node: machine + # containers: + # - machine_board + # - machine_parts + # - type: ContainerContainer + # containers: + # machine_board: !type:Container + # machine_parts: !type:Container + # - type: SignalReceiver + # inputs: + # SiliconChargerReceiver: [] + # - type: EmptyOnMachineDeconstruct + # containers: + # - machine_board + # - machine_parts + # - type: Destructible + # thresholds: + # - trigger: + # - !type:DamageTrigger + # damage: 150 + # behaviors: + # - !type:ChangeConstructionNodeBehavior + # node: machineFrame + # - !type:DoActsBehavior + # acts: ["Destruction"] + # - type: Wires + # BoardName: "SiliconCharger" + # LayoutId: SiliconCharger + # - type: Appearance + # visuals: + # - type: GenericEnumVisualizer + # key: enum.SiliconChargerVisuals.Status + # layer: 0 + # states: + # enum.SiliconChargerStatus.Charging: machine + # enum.SiliconChargerStatus.Idle: machine diff --git a/Resources/Prototypes/SimpleStation14/InventoryTemplates/ipc_inventory_template.yml b/Resources/Prototypes/SimpleStation14/InventoryTemplates/ipc_inventory_template.yml new file mode 100644 index 0000000000..77d568299e --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/InventoryTemplates/ipc_inventory_template.yml @@ -0,0 +1,140 @@ +- type: inventoryTemplate + id: ipc + slots: + - name: shoes + slotTexture: shoes + slotFlags: FEET + stripTime: 3 + uiWindowPos: 1,3 + strippingWindowPos: 1,3 + displayName: Shoes + - name: jumpsuit + slotTexture: uniform + slotFlags: INNERCLOTHING + stripTime: 6 + uiWindowPos: 0,2 + strippingWindowPos: 0,2 + displayName: Jumpsuit + - name: outerClothing + slotTexture: suit + slotFlags: OUTERCLOTHING + slotGroup: MainHotbar + stripTime: 6 + uiWindowPos: 1,2 + strippingWindowPos: 1,2 + displayName: Suit + # Underwear + # - name: undershirt + # slotTexture: undershirt + # slotFlags: UNDERSHIRT + # stripTime: 8 + # uiWindowPos: 4,1 + # strippingWindowPos: 3,1 + # displayName: Undershirt + # - name: underpants + # slotTexture: underpants + # slotFlags: UNDERPANTS + # stripTime: 12 + # uiWindowPos: 4,0 + # strippingWindowPos: 3,2 + # displayName: Underpants + # - name: socks + # slotTexture: socks + # slotFlags: SOCKS + # stripTime: 8 + # uiWindowPos: 4,2 + # strippingWindowPos: 3,3 + # displayName: Socks + - name: gloves + slotTexture: gloves + slotFlags: GLOVES + uiWindowPos: 2,2 + strippingWindowPos: 2,2 + displayName: Gloves + - name: neck + slotTexture: neck + slotFlags: NECK + uiWindowPos: 0,1 + strippingWindowPos: 0,1 + displayName: Neck + # - name: mask + # slotTexture: mask + # slotFlags: MASK + # uiWindowPos: 1,1 + # strippingWindowPos: 1,1 + # displayName: Mask + # offset: 0.5, 1.5 + # - name: eyes + # slotTexture: glasses + # slotFlags: EYES + # stripTime: 3 + # uiWindowPos: 0,0 + # strippingWindowPos: 0,0 + # displayName: Eyes + # - name: ears + # slotTexture: ears + # slotFlags: EARS + # stripTime: 3 + # uiWindowPos: 2,0 + # strippingWindowPos: 2,0 + # displayName: Ears + - name: head + slotTexture: head + slotFlags: HEAD + uiWindowPos: 1,0 + strippingWindowPos: 1,0 + displayName: Head + offset: 0, 0 + - name: pocket1 + slotTexture: pocket + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 0,3 + strippingWindowPos: 0,4 + dependsOn: jumpsuit + displayName: Pocket 1 + stripHidden: true + - name: pocket2 + slotTexture: pocket + slotFlags: POCKET + slotGroup: MainHotbar + stripTime: 3 + uiWindowPos: 2,3 + strippingWindowPos: 1,4 + dependsOn: jumpsuit + displayName: Pocket 2 + stripHidden: true + - name: suitstorage + slotTexture: suit_storage + slotFlags: SUITSTORAGE + stripTime: 3 + uiWindowPos: 2,0 + strippingWindowPos: 2,5 + dependsOn: outerClothing + displayName: Suit Storage + - name: id + slotTexture: id + slotFlags: IDCARD + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 2,1 + strippingWindowPos: 2,4 + dependsOn: jumpsuit + displayName: ID + - name: belt + slotTexture: belt + slotFlags: BELT + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 3,1 + strippingWindowPos: 1,5 + displayName: Belt + - name: back + slotTexture: back + slotFlags: BACK + slotGroup: SecondHotbar + stripTime: 6 + uiWindowPos: 3,0 + strippingWindowPos: 0,5 + displayName: Back diff --git a/Resources/Prototypes/SimpleStation14/Species/ipc.yml b/Resources/Prototypes/SimpleStation14/Species/ipc.yml new file mode 100644 index 0000000000..46a8ed1758 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Species/ipc.yml @@ -0,0 +1,141 @@ +- type: species + id: IPC + name: species-name-ipc + roundStart: true + prototype: MobIPC + sprites: MobIPCSprites + markingLimits: MobIPCMarkingLimits + dollPrototype: MobIPCDummy + skinColoration: TintedHues + minAge: 1 + maxAge: 240 + oldAge: 50 + youngAge: 50 + maleFirstNames: IpcFirst + femaleFirstNames: IpcFirst + lastNames: IpcLast + naming: FirstDashLast + sexes: + - Unsexed + +# The lack of a layer means that +# this person cannot have round-start anything +# applied to that layer. It has to instead +# be defined as a 'custom base layer' +# in either the mob's starting marking prototype, +# or it has to be added in C#. +- type: speciesBaseSprites + id: MobIPCSprites + sprites: + Head: MobIPCHead + Hair: MobHumanoidMarkingMatchSkin + FacialHair: MobIPCScreen + Chest: MobIPCTorso + LArm: MobIPCLArm + RArm: MobIPCRArm + LHand: MobIPCLHand + RHand: MobIPCRHand + LLeg: MobIPCLLeg + RLeg: MobIPCRLeg + LFoot: MobIPCLFoot + RFoot: MobIPCRFoot + +- type: markingPoints + id: MobIPCMarkingLimits + points: + Chest: + points: 0 + required: false + Legs: + points: 0 + required: false + Arms: + points: 0 + required: false + +- type: humanoidBaseSprite + id: MobIPCScreen + +- type: humanoidBaseSprite + id: MobIPCHead + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobIPCHeadMale + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobIPCHeadFemale + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobIPCTorso + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobIPCTorsoMale + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobIPCTorsoFemale + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobIPCLLeg + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobIPCLArm + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobIPCLHand + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobIPCLFoot + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobIPCRLeg + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobIPCRArm + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobIPCRHand + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobIPCRFoot + baseSprite: + sprite: SimpleStation14/Mobs/Species/IPC/parts.rsi + state: r_foot diff --git a/Resources/Prototypes/Species/diona.yml b/Resources/Prototypes/Species/diona.yml index db58e3a06e..ac30afc7c9 100644 --- a/Resources/Prototypes/Species/diona.yml +++ b/Resources/Prototypes/Species/diona.yml @@ -6,7 +6,7 @@ sprites: MobDionaSprites markingLimits: MobDionaMarkingLimits dollPrototype: MobDionaDummy - skinColoration: TintedHues + skinColoration: None maleFirstNames: DionaFirst femaleFirstNames: DionaFirst lastNames: DionaLast diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge-empty.png b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge-empty.png new file mode 100644 index 0000000000..13a8ca9070 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge-empty.png differ diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge0.png b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge0.png new file mode 100644 index 0000000000..ae55294dc4 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge0.png differ diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge1.png b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge1.png new file mode 100644 index 0000000000..46d304d776 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge1.png differ diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge2.png b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge2.png new file mode 100644 index 0000000000..cd7f73756b Binary files /dev/null and b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge2.png differ diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge3.png b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge3.png new file mode 100644 index 0000000000..0745be8ff2 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge3.png differ diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge4.png b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge4.png new file mode 100644 index 0000000000..1557455a41 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/charge4.png differ diff --git a/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/meta.json b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/meta.json new file mode 100644 index 0000000000..ee07837524 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Interface/Alerts/charge.rsi/meta.json @@ -0,0 +1,35 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from Yogstation at https://github.com/yogstation13/Yogstation/commit/aaaed39293dd0b9edace6e2fe2017203e7352ef2", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "charge0" + }, + { + "name": "charge1", + "delays": [ + [ + 0.5, + 0.5 + ] + ] + }, + { + "name": "charge2" + }, + { + "name": "charge3" + }, + { + "name": "charge4" + }, + { + "name": "charge-empty" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_antlers.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_antlers.png new file mode 100644 index 0000000000..125f9cf913 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_antlers.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_crowned.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_crowned.png new file mode 100644 index 0000000000..2fd0cdd06d Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_crowned.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_cyberhead.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_cyberhead.png new file mode 100644 index 0000000000..c3d1111199 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_cyberhead.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_droneeyes.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_droneeyes.png new file mode 100644 index 0000000000..5b2a67a813 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_droneeyes.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_light.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_light.png new file mode 100644 index 0000000000..91f5fd25e7 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_light.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_lightb.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_lightb.png new file mode 100644 index 0000000000..bc1133d8d3 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_lightb.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_sidelights.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_sidelights.png new file mode 100644 index 0000000000..7a1c31e45e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_sidelights.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tesla.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tesla.png new file mode 100644 index 0000000000..98cb10d3cb Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tesla.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_towers.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_towers.png new file mode 100644 index 0000000000..f971130b8e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_towers.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tv.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tv.png new file mode 100644 index 0000000000..ae53b4762e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tv.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/meta.json new file mode 100644 index 0000000000..68759a1b40 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_antenna.rsi/meta.json @@ -0,0 +1,107 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA 3.0", + "copyright": "Taken from Yogstation at https://github.com/yogstation13/Yogstation/commit/9c046aa5327c71f9e93e45a34283b3a4aff58bd1", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "ipc_antenna_tv", + "directions": 4 + }, + { + "name": "ipc_antenna_tesla", + "directions": 4, + "delays": [ + [ + 4, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 4, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 4, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 4, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_antenna_lightb", + "directions": 4, + "delays": [ + [ + 4, + 0.5, + 0.1, + 0.5 + ], + [ + 4, + 0.5, + 0.1, + 0.5 + ], + [ + 4, + 0.5, + 0.1, + 0.5 + ], + [ + 4, + 0.5, + 0.1, + 0.5 + ] + ] + }, + { + "name": "ipc_antenna_light", + "directions": 4 + }, + { + "name": "ipc_antenna_cyberhead", + "directions": 4 + }, + { + "name": "ipc_antenna_sidelights", + "directions": 4 + }, + { + "name": "ipc_antenna_antlers", + "directions": 4 + }, + { + "name": "ipc_antenna_droneeyes", + "directions": 4 + }, + { + "name": "ipc_antenna_crowned", + "directions": 4 + }, + { + "name": "ipc_antenna_towers", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_blank.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_blank.png new file mode 100644 index 0000000000..4361a36c1e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_blank.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_blue.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_blue.png new file mode 100644 index 0000000000..f156884880 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_blue.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_breakout.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_breakout.png new file mode 100644 index 0000000000..54a282bd95 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_breakout.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_bsod.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_bsod.png new file mode 100644 index 0000000000..7d7a8efb62 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_bsod.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_console.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_console.png new file mode 100644 index 0000000000..dfed44e10c Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_console.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_ecgwave.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_ecgwave.png new file mode 100644 index 0000000000..2d2c405734 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_ecgwave.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eight.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eight.png new file mode 100644 index 0000000000..8421ae30bd Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eight.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_exclaim.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_exclaim.png new file mode 100644 index 0000000000..e280615e50 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_exclaim.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyes.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyes.png new file mode 100644 index 0000000000..42ee79361b Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyes.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyesangry.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyesangry.png new file mode 100644 index 0000000000..8a7e45c7e8 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyesangry.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyestall.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyestall.png new file mode 100644 index 0000000000..d8c03fa324 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyestall.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_frown.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_frown.png new file mode 100644 index 0000000000..f297c401a1 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_frown.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_glider.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_glider.png new file mode 100644 index 0000000000..afd5349ee6 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_glider.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_goggles.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_goggles.png new file mode 100644 index 0000000000..422a603cc7 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_goggles.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_heart.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_heart.png new file mode 100644 index 0000000000..77578d774e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_heart.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_l.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_l.png new file mode 100644 index 0000000000..902845f11f Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_l.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_loading.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_loading.png new file mode 100644 index 0000000000..9a1f705a0d Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_loading.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_monoeye.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_monoeye.png new file mode 100644 index 0000000000..4e5056528d Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_monoeye.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_nature.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_nature.png new file mode 100644 index 0000000000..6425fe2b51 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_nature.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_orange.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_orange.png new file mode 100644 index 0000000000..f4c98278e1 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_orange.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_pink.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_pink.png new file mode 100644 index 0000000000..dc50eb693d Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_pink.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_question.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_question.png new file mode 100644 index 0000000000..f90dcc94ab Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_question.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowdiag.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowdiag.png new file mode 100644 index 0000000000..37274191d3 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowdiag.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowhoriz.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowhoriz.png new file mode 100644 index 0000000000..9b6192dd6d Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowhoriz.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_redtext.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_redtext.png new file mode 100644 index 0000000000..c180b8e674 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_redtext.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rgb.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rgb.png new file mode 100644 index 0000000000..36f48e75d7 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_rgb.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_ring.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_ring.png new file mode 100644 index 0000000000..e545422160 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_ring.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_scroll.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_scroll.png new file mode 100644 index 0000000000..cbf936810a Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_scroll.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_shower.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_shower.png new file mode 100644 index 0000000000..1546c8dbf1 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_shower.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_sinewave.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_sinewave.png new file mode 100644 index 0000000000..c976f42179 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_sinewave.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_smile.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_smile.png new file mode 100644 index 0000000000..7ecd324e89 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_smile.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_squarewave.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_squarewave.png new file mode 100644 index 0000000000..04211f366e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_squarewave.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_stars.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_stars.png new file mode 100644 index 0000000000..8feda85c42 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_stars.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_static.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_static.png new file mode 100644 index 0000000000..08e96db150 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_static.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_tetris.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_tetris.png new file mode 100644 index 0000000000..d4ea13ea39 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_tetris.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_textdrop.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_textdrop.png new file mode 100644 index 0000000000..c71ba6d24e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_textdrop.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_tv.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_tv.png new file mode 100644 index 0000000000..5b9b25dcd9 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_tv.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_windowsxp.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_windowsxp.png new file mode 100644 index 0000000000..595ab8444b Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_windowsxp.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_yellow.png b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_yellow.png new file mode 100644 index 0000000000..bbf4c92cb3 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/ipc_screen_yellow.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/meta.json new file mode 100644 index 0000000000..d2caf7765a --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Customization/ipc_screens.rsi/meta.json @@ -0,0 +1,1363 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA 3.0", + "copyright": "Taken from Yogstation at https://github.com/yogstation13/Yogstation/commit/9c046aa5327c71f9e93e45a34283b3a4aff58bd1", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "ipc_screen_static", + "directions": 4, + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15 + ], + [ + 0.15, + 0.15, + 0.15, + 0.15 + ], + [ + 0.15, + 0.15, + 0.15, + 0.15 + ], + [ + 0.15, + 0.15, + 0.15, + 0.15 + ] + ] + }, + { + "name": "ipc_screen_blue", + "directions": 4, + "delays": [ + [ + 2.4, + 2.4, + 2.4, + 2.4, + 2.4, + 2.4 + ], + [ + 2.4, + 2.4, + 2.4, + 2.4, + 2.4, + 2.4 + ], + [ + 2.4, + 2.4, + 2.4, + 2.4, + 2.4, + 2.4 + ], + [ + 2.4, + 2.4, + 2.4, + 2.4, + 2.4, + 2.4 + ] + ] + }, + { + "name": "ipc_screen_breakout", + "directions": 4, + "delays": [ + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ] + ] + }, + { + "name": "ipc_screen_eight", + "directions": 4, + "delays": [ + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ] + ] + }, + { + "name": "ipc_screen_goggles", + "directions": 4, + "delays": [ + [ + 0.2, + 4 + ], + [ + 0.2, + 4 + ], + [ + 0.2, + 4 + ], + [ + 0.2, + 4 + ] + ] + }, + { + "name": "ipc_screen_exclaim", + "directions": 4, + "delays": [ + [ + 0.6, + 0.6 + ], + [ + 0.6, + 0.6 + ], + [ + 0.6, + 0.6 + ], + [ + 0.6, + 0.6 + ] + ] + }, + { + "name": "ipc_screen_heart", + "directions": 4, + "delays": [ + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ] + ] + }, + { + "name": "ipc_screen_monoeye", + "directions": 4, + "delays": [ + [ + 4, + 0.1, + 0.1, + 0.1 + ], + [ + 4, + 0.1, + 0.1, + 0.1 + ], + [ + 4, + 0.1, + 0.1, + 0.1 + ], + [ + 4, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_nature", + "directions": 4, + "delays": [ + [ + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 10, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_orange", + "directions": 4, + "delays": [ + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ] + ] + }, + { + "name": "ipc_screen_pink", + "directions": 4, + "delays": [ + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ] + ] + }, + { + "name": "ipc_screen_question", + "directions": 4, + "delays": [ + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ], + [ + 0.8, + 0.8 + ] + ] + }, + { + "name": "ipc_screen_shower", + "directions": 4, + "delays": [ + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ], + [ + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8, + 0.8 + ] + ] + }, + { + "name": "ipc_screen_yellow", + "directions": 4, + "delays": [ + [ + 2, + 2 + ], + [ + 2, + 2 + ], + [ + 2, + 2 + ], + [ + 2, + 2 + ] + ] + }, + { + "name": "ipc_screen_scroll", + "directions": 4, + "delays": [ + [ + 0.125, + 0.125, + 0.125, + 0.125, + 0.125 + ], + [ + 0.125, + 0.125, + 0.125, + 0.125, + 0.125 + ], + [ + 0.125, + 0.125, + 0.125, + 0.125, + 0.125 + ], + [ + 0.125, + 0.125, + 0.125, + 0.125, + 0.125 + ] + ] + }, + { + "name": "ipc_screen_console", + "directions": 4, + "delays": [ + [ + 1, + 1 + ], + [ + 1, + 1 + ], + [ + 1, + 1 + ], + [ + 1, + 1 + ] + ] + }, + { + "name": "ipc_screen_rgb", + "directions": 4, + "delays": [ + [ + 2, + 2, + 2 + ], + [ + 2, + 2, + 2 + ], + [ + 2, + 2, + 2 + ], + [ + 2, + 2, + 2 + ] + ] + }, + { + "name": "ipc_screen_glider", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "ipc_screen_rainbowhoriz", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_bsod", + "directions": 4, + "delays": [ + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1, + 0.4, + 0.1, + 0.1, + 0.1 + ], + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1, + 0.4, + 0.1, + 0.1, + 0.1 + ], + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1, + 0.4, + 0.1, + 0.1, + 0.1 + ], + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1, + 0.4, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_redtext", + "directions": 4, + "delays": [ + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.4, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_sinewave", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_squarewave", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_ecgwave", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_eyes", + "directions": 4, + "delays": [ + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ] + ] + }, + { + "name": "ipc_screen_eyestall", + "directions": 4, + "delays": [ + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ] + ] + }, + { + "name": "ipc_screen_eyesangry", + "directions": 4, + "delays": [ + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ], + [ + 3, + 0.5 + ] + ] + }, + { + "name": "ipc_screen_loading", + "directions": 4, + "delays": [ + [ + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ], + [ + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ], + [ + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ], + [ + 0.2, + 0.1, + 0.2, + 0.1, + 0.2 + ] + ] + }, + { + "name": "ipc_screen_windowsxp", + "directions": 4, + "delays": [ + [ + 0.25, + 0.19, + 0.120000005, + 0.1, + 0.16, + 0.22 + ], + [ + 0.25, + 0.19, + 0.120000005, + 0.1, + 0.16, + 0.22 + ], + [ + 0.25, + 0.19, + 0.120000005, + 0.1, + 0.16, + 0.22 + ], + [ + 0.25, + 0.19, + 0.120000005, + 0.1, + 0.16, + 0.22 + ] + ] + }, + { + "name": "ipc_screen_tetris", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "ipc_screen_tv", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_textdrop", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_stars", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_rainbowdiag", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ipc_screen_blank", + "directions": 4 + }, + { + "name": "ipc_screen_smile", + "directions": 4 + }, + { + "name": "ipc_screen_frown", + "directions": 4 + }, + { + "name": "ipc_screen_ring", + "directions": 4 + }, + { + "name": "ipc_screen_l", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain-inhand-left.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain-inhand-left.png new file mode 100644 index 0000000000..cf6e4684e9 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain-inhand-left.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain-inhand-right.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain-inhand-right.png new file mode 100644 index 0000000000..978d4f3c5f Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain-inhand-right.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain.png new file mode 100644 index 0000000000..f69ff1aa3e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/brain.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/ears.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/ears.png new file mode 100644 index 0000000000..9966cc2ac2 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/ears.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/eyeball-l.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/eyeball-l.png new file mode 100644 index 0000000000..09b98e316f Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/eyeball-l.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/eyeball-r.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/eyeball-r.png new file mode 100644 index 0000000000..f1ff37a002 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/eyeball-r.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/heart-off.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/heart-off.png new file mode 100644 index 0000000000..7dda0d3a8e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/heart-off.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/heart-on.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/heart-on.png new file mode 100644 index 0000000000..676a641989 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/heart-on.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/meta.json new file mode 100644 index 0000000000..0b865543fa --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/meta.json @@ -0,0 +1,72 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "heart-off" + }, + { + "name": "heart-on", + "delays": [ + [ + 0.6, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "brain", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "eyeball-r" + }, + { + "name": "tongue" + }, + { + "name": "eyeball-l" + }, + { + "name": "microcell", + "delays": [ + [ + 0.5, + 0.5 + ] + ] + }, + { + "name": "ears" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/microcell.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/microcell.png new file mode 100644 index 0000000000..18b692a5a9 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/microcell.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/tongue.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/tongue.png new file mode 100644 index 0000000000..dee2ed3b99 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/organs.rsi/tongue.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/full.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/full.png new file mode 100644 index 0000000000..7faae4a077 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/full.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/head_f.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/head_f.png new file mode 100644 index 0000000000..31d77176c9 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/head_f.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/head_m.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/head_m.png new file mode 100644 index 0000000000..53d6069a28 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/head_m.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_arm.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_arm.png new file mode 100644 index 0000000000..4f042bf40e Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_arm.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_foot.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_foot.png new file mode 100644 index 0000000000..bb9bede218 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_foot.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_hand.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_hand.png new file mode 100644 index 0000000000..5b6c2df090 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_hand.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_leg.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_leg.png new file mode 100644 index 0000000000..788f2769d4 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/l_leg.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/meta.json b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/meta.json new file mode 100644 index 0000000000..9ccb451f20 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/meta.json @@ -0,0 +1,62 @@ +{ + "version": 2, + "license": "CC-BY-SA 3.0", + "copyright": "Original drawn by @robustyanka on Discord, modified by @pspritechologist", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "head_m", + "directions": 4 + }, + { + "name": "head_f", + "directions": 4 + }, + { + "name": "torso_m", + "directions": 4 + }, + { + "name": "torso_f", + "directions": 4 + }, + { + "name": "r_arm", + "directions": 4 + }, + { + "name": "l_arm", + "directions": 4 + }, + { + "name": "r_hand", + "directions": 4 + }, + { + "name": "l_hand", + "directions": 4 + }, + { + "name": "r_leg", + "directions": 4 + }, + { + "name": "l_leg", + "directions": 4 + }, + { + "name": "r_foot", + "directions": 4 + }, + { + "name": "l_foot", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_arm.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_arm.png new file mode 100644 index 0000000000..6c1ff1ec9c Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_arm.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_foot.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_foot.png new file mode 100644 index 0000000000..2389c30aea Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_foot.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_hand.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_hand.png new file mode 100644 index 0000000000..3ec4fab037 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_hand.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_leg.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_leg.png new file mode 100644 index 0000000000..f424b2efbc Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/r_leg.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/torso_f.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/torso_f.png new file mode 100644 index 0000000000..b36a2eed8c Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/torso_f.png differ diff --git a/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/torso_m.png b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/torso_m.png new file mode 100644 index 0000000000..df2588b562 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Mobs/Species/IPC/parts.rsi/torso_m.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/base.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/base.png new file mode 100644 index 0000000000..dcd8ca51df Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/base.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_1.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_1.png new file mode 100644 index 0000000000..f254109f0c Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_1.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_2.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_2.png new file mode 100644 index 0000000000..f602224e5a Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_2.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_active_unlit.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_active_unlit.png new file mode 100644 index 0000000000..18357d1eb9 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_active_unlit.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_closed_unlit.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_closed_unlit.png new file mode 100644 index 0000000000..99eec2b981 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_closed_unlit.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_open_unlit.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_open_unlit.png new file mode 100644 index 0000000000..9f52b9154a Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_open_unlit.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_panel.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_panel.png new file mode 100644 index 0000000000..95f7dd49e9 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_panel.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_unlit.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_unlit.png new file mode 100644 index 0000000000..586fe93f3b Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/borgcharger_unlit.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/closed.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/closed.png new file mode 100644 index 0000000000..7025ddb43f Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/closed.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/icon.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/icon.png new file mode 100644 index 0000000000..4da2fc20ec Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/icon.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/meta.json new file mode 100644 index 0000000000..3559f7508e --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/meta.json @@ -0,0 +1,52 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA 3.0", + "copyright": "Taken from Yogstation at commit https://github.com/yogstation13/Yogstation/commit/159e6bf846e911590ab27f15272ec2ebc465c1da", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "base" + }, + { + "name": "open" + }, + { + "name": "closed" + }, + { + "name": "borgcharger_open_unlit" + }, + { + "name": "borgcharger_closed_unlit" + }, + { + "name": "borgcharger_unlit" + }, + { + "name": "borgcharger_active_unlit", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.15 + ] + ] + }, + { + "name": "borgcharger_panel" + }, + { + "name": "borgcharger_1" + }, + { + "name": "borgcharger_2" + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/open.png b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/open.png new file mode 100644 index 0000000000..eb22e35d97 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/borgcharger.rsi/open.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/beam.png b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/beam.png new file mode 100644 index 0000000000..33c35c84ae Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/beam.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/idle.png b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/idle.png new file mode 100644 index 0000000000..8921c02a92 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/idle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/meta.json new file mode 100644 index 0000000000..161d2b9a7b --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/meta.json @@ -0,0 +1,37 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from /vg/station at commit 5c50dee8fb2a55d6be3b3c9c90a782a618a5506e Cut out for unshaded by metalgearsloth", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "beam", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "idle", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "offline" + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/offline.png b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/offline.png new file mode 100644 index 0000000000..e701d9994d Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Machines/charging_pad.rsi/offline.png differ