diff --git a/Content.IntegrationTests/Tests/GameRules/NukeOpsTest.cs b/Content.IntegrationTests/Tests/GameRules/NukeOpsTest.cs index 039c0c7b184..933357f5436 100644 --- a/Content.IntegrationTests/Tests/GameRules/NukeOpsTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/NukeOpsTest.cs @@ -23,6 +23,7 @@ using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Map.Components; +using Content.Shared._EE.Silicon.Components; // Goobstation namespace Content.IntegrationTests.Tests.GameRules; @@ -229,7 +230,8 @@ void CheckDummy(int i) for (var tick = 0; tick < totalTicks; tick += increment) { await pair.RunTicksSync(increment); - Assert.That(resp.SuffocationCycles, Is.LessThanOrEqualTo(resp.SuffocationCycleThreshold)); + if (!entMan.HasComponent(player)) // Goobstation + Assert.That(resp.SuffocationCycles, Is.LessThanOrEqualTo(resp.SuffocationCycleThreshold)); Assert.That(damage.TotalDamage, Is.EqualTo(FixedPoint2.Zero)); } diff --git a/Content.Server/Administration/Commands/SetOutfitCommand.cs b/Content.Server/Administration/Commands/SetOutfitCommand.cs index 9240e7b91b6..c08be1d1438 100644 --- a/Content.Server/Administration/Commands/SetOutfitCommand.cs +++ b/Content.Server/Administration/Commands/SetOutfitCommand.cs @@ -16,6 +16,8 @@ using Robust.Shared.Console; using Robust.Shared.Player; using Robust.Shared.Prototypes; +using Content.Server._EE.Silicon.IPC; // Goobstation +using Content.Shared.Radio.Components; // Goobstation namespace Content.Server.Administration.Commands { @@ -163,7 +165,12 @@ public static bool SetOutfit(EntityUid target, string gear, IEntityManager entit var stationSpawning = entityManager.System(); stationSpawning.EquipRoleLoadout(target, roleLoadout, jobProto); } - + + if (entityManager.HasComponent(target)) + { + var encryption = new InternalEncryptionKeySpawner(); + encryption.TryInsertEncryptionKey(target, startingGear, entityManager); + } return true; } } diff --git a/Content.Server/Bed/BedSystem.cs b/Content.Server/Bed/BedSystem.cs index 2cc8085e725..da89a012d8d 100644 --- a/Content.Server/Bed/BedSystem.cs +++ b/Content.Server/Bed/BedSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.Power; using Robust.Shared.Timing; using Robust.Shared.Utility; +using Content.Shared._EE.Silicon.Components; namespace Content.Server.Bed { @@ -70,7 +71,8 @@ public override void Update(float frameTime) foreach (var healedEntity in strapComponent.BuckledEntities) { - if (_mobStateSystem.IsDead(healedEntity)) + if (_mobStateSystem.IsDead(healedEntity) + || HasComp(healedEntity)) // Goobstation continue; var damage = bedComponent.Damage; diff --git a/Content.Server/Chat/SuicideSystem.cs b/Content.Server/Chat/SuicideSystem.cs index 7f05f143e9a..6009cdd46bd 100644 --- a/Content.Server/Chat/SuicideSystem.cs +++ b/Content.Server/Chat/SuicideSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.Popups; using Content.Shared.Tag; using Robust.Shared.Player; +using Content.Shared._EE.Silicon.Components; namespace Content.Server.Chat; @@ -164,7 +165,10 @@ private void OnDamageableSuicide(Entity victim, ref Suicide return; } - args.DamageType ??= "Bloodloss"; + if (HasComp(victim)) // Goobstation + args.DamageType ??= "Shock"; + else + args.DamageType ??= "Bloodloss"; _suicide.ApplyLethalDamage(victim, args.DamageType); args.Handled = true; } diff --git a/Content.Server/Cloning/CloningSystem.cs b/Content.Server/Cloning/CloningSystem.cs index ab593b607c8..536b87b2a10 100644 --- a/Content.Server/Cloning/CloningSystem.cs +++ b/Content.Server/Cloning/CloningSystem.cs @@ -9,6 +9,7 @@ using Content.Server.Materials; using Content.Server.Popups; using Content.Server.Power.EntitySystems; +using Content.Shared._EE.Silicon.Components; // Goobstation using Content.Server.Psionics; // DeltaV using Content.Server.Traits.Assorted; // DeltaV using Content.Shared.Atmos; @@ -171,6 +172,9 @@ public bool TryCloning(EntityUid uid, EntityUid bodyToClone, Entity(bodyToClone, out var humanoid)) return false; // whatever body was to be cloned, was not a humanoid + if (HasComp(bodyToClone)) + return false; // Goobstation: Don't clone IPCs. + // Begin Nyano-code: allow paradox anomalies to be cloned. var pref = humanoid.LastProfileLoaded; diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index eb10f8d2809..ce05da3ece7 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -62,7 +62,8 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem [ValidatePrototypeId] private const string DamageType = "Shock"; - // Multiply and shift the log scale for shock damage. + // Yes, this is absurdly small for a reason. + public const float ElectrifiedDamagePerWatt = 0.0015f; // Goobstation - 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; @@ -300,7 +301,7 @@ public override 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); // Goobstation return true; } @@ -350,7 +351,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); // Goobstation return true; } diff --git a/Content.Server/Mobs/DeathgaspComponent.cs b/Content.Server/Mobs/DeathgaspComponent.cs index cb1f02f0d97..8c459f14ae2 100644 --- a/Content.Server/Mobs/DeathgaspComponent.cs +++ b/Content.Server/Mobs/DeathgaspComponent.cs @@ -15,4 +15,10 @@ public sealed partial class DeathgaspComponent : Component /// [DataField("prototype", customTypeSerializer:typeof(PrototypeIdSerializer))] public string Prototype = "DefaultDeathgasp"; + + /// + /// Goobstation: Makes sure that the deathgasp is only displayed if the entity went critical before dying + /// + [DataField] + public bool NeedsCritical = true; } diff --git a/Content.Server/Mobs/DeathgaspSystem.cs b/Content.Server/Mobs/DeathgaspSystem.cs index c531784ea69..f15238f4189 100644 --- a/Content.Server/Mobs/DeathgaspSystem.cs +++ b/Content.Server/Mobs/DeathgaspSystem.cs @@ -21,7 +21,9 @@ public override void Initialize() private void OnMobStateChanged(EntityUid uid, DeathgaspComponent component, MobStateChangedEvent args) { // don't deathgasp if they arent going straight from crit to dead - if (args.NewMobState != MobState.Dead || args.OldMobState != MobState.Critical) + if (component.NeedsCritical // Goobstation + && args.OldMobState != MobState.Critical + || args.NewMobState != MobState.Dead) return; Deathgasp(uid, component); diff --git a/Content.Server/Objectives/Components/PickRandomPersonComponent.cs b/Content.Server/Objectives/Components/PickRandomPersonComponent.cs index 4188b1da3d2..7de6cb71468 100644 --- a/Content.Server/Objectives/Components/PickRandomPersonComponent.cs +++ b/Content.Server/Objectives/Components/PickRandomPersonComponent.cs @@ -8,4 +8,6 @@ namespace Content.Server.Objectives.Components; [RegisterComponent, Access(typeof(KillPersonConditionSystem))] public sealed partial class PickRandomPersonComponent : Component { + [DataField] + public bool NeedsOrganic; // Goobstation: Only pick non-silicon players. } diff --git a/Content.Server/PowerCell/PowerCellSystem.cs b/Content.Server/PowerCell/PowerCellSystem.cs index e78f3a597f8..dfbb02e73d6 100644 --- a/Content.Server/PowerCell/PowerCellSystem.cs +++ b/Content.Server/PowerCell/PowerCellSystem.cs @@ -228,8 +228,8 @@ private void OnCellEmpAttempt(EntityUid uid, PowerCellComponent component, EmpAt private void OnCellSlotExamined(EntityUid uid, PowerCellSlotComponent component, ExaminedEvent args) { - TryGetBatteryFromSlot(uid, out var battery); - OnBatteryExamined(uid, battery, args); + TryGetBatteryFromSlot(uid, out var batteryEnt, out var battery); // Goobstation + OnBatteryExamined(batteryEnt.GetValueOrDefault(uid), battery, args); // Goobstation } private void OnBatteryExamined(EntityUid uid, BatteryComponent? component, ExaminedEvent args) diff --git a/Content.Server/Station/Systems/StationSpawningSystem.cs b/Content.Server/Station/Systems/StationSpawningSystem.cs index 4a0225c2302..d7d293564b5 100644 --- a/Content.Server/Station/Systems/StationSpawningSystem.cs +++ b/Content.Server/Station/Systems/StationSpawningSystem.cs @@ -28,6 +28,7 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; +using Content.Server._EE.Silicon.IPC; // Goobstation namespace Content.Server.Station.Systems; @@ -50,7 +51,7 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem [Dependency] private readonly PdaSystem _pdaSystem = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _random = default!; - + [Dependency] private readonly InternalEncryptionKeySpawner _internalEncryption = default!; // Goobstation private bool _randomizeCharacters; /// @@ -178,6 +179,7 @@ public EntityUid SpawnPlayerMob( { var startingGear = _prototypeManager.Index(prototype.StartingGear); EquipStartingGear(entity.Value, startingGear, raiseEvent: false); + _internalEncryption.TryInsertEncryptionKey(entity.Value, startingGear, EntityManager); // Goobstation } var gearEquippedEv = new StartingGearEquippedEvent(entity.Value); diff --git a/Content.Server/_EE/Power/Components/BatteryDrinkerComponent.cs b/Content.Server/_EE/Power/Components/BatteryDrinkerComponent.cs new file mode 100644 index 00000000000..eccb79444ef --- /dev/null +++ b/Content.Server/_EE/Power/Components/BatteryDrinkerComponent.cs @@ -0,0 +1,31 @@ +namespace Content.Server._EE.Power.Components; + +[RegisterComponent] +public sealed partial class BatteryDrinkerComponent : Component +{ + /// + /// Is this drinker allowed to drink batteries not tagged as ? + /// + [DataField] + public bool DrinkAll; + + /// + /// How long it takes to drink from a battery, in seconds. + /// Is multiplied by the source. + /// + [DataField] + public float DrinkSpeed = 1.5f; + + /// + /// The multiplier for the amount of power to attempt to drink. + /// Default amount is 1000 + /// + [DataField] + public float DrinkMultiplier = 5f; + + /// + /// The multiplier for how long it takes to drink a non-source battery, if is true. + /// + [DataField] + public float DrinkAllMultiplier = 2.5f; +} \ No newline at end of file diff --git a/Content.Server/_EE/Power/Components/RandomBatteryChargeComponent.cs b/Content.Server/_EE/Power/Components/RandomBatteryChargeComponent.cs new file mode 100644 index 00000000000..30c25b61d41 --- /dev/null +++ b/Content.Server/_EE/Power/Components/RandomBatteryChargeComponent.cs @@ -0,0 +1,26 @@ +using System.Numerics; + +namespace Content.Server._EE.Power.Components; + +[RegisterComponent] +public sealed partial class RandomBatteryChargeComponent : Component +{ + /// + /// The minimum and maximum max charge the battery can have. + /// + [DataField] + public Vector2 BatteryMaxMinMax = new(0.85f, 1.15f); + + /// + /// The minimum and maximum current charge the battery can have. + /// + [DataField] + 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] + public bool BasedOnMaxCharge = true; +} \ No newline at end of file diff --git a/Content.Server/_EE/Power/Systems/BatteryDrinkerSystem.cs b/Content.Server/_EE/Power/Systems/BatteryDrinkerSystem.cs new file mode 100644 index 00000000000..6e2307181e7 --- /dev/null +++ b/Content.Server/_EE/Power/Systems/BatteryDrinkerSystem.cs @@ -0,0 +1,143 @@ +using System.Linq; +using Content.Server.Power.Components; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.DoAfter; +using Content.Shared.PowerCell.Components; +using Content.Shared._EE.Silicon; +using Content.Shared.Verbs; +using Robust.Shared.Utility; +using Content.Server._EE.Silicon.Charge; +using Content.Server.Power.EntitySystems; +using Content.Server.Popups; +using Content.Server.PowerCell; +using Content.Shared.Popups; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Content.Server._EE.Power.Components; +using Content.Server._EE.Silicon; + +namespace Content.Server._EE.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!; + [Dependency] private readonly PowerCellSystem _powerCell = default!; + [Dependency] private readonly SharedContainerSystem _container = 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) || + !_silicon.TryGetSiliconBattery(args.User, out var drinkerBattery)) + 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 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(EntityManager, user, doAfterTime, new BatteryDrinkerDoAfterEvent(), user, target) // TODO: Make this doafter loop, once we merge Upstream. + { + BreakOnDamage = true, + BreakOnMove = 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); + + _silicon.TryGetSiliconBattery(drinker, out var drinkerBatteryComponent); + + if (!TryComp(uid, out PowerCellSlotComponent? batterySlot)) + return; + + var container = _container.GetContainer(uid, batterySlot.CellSlotId); + var drinkerBattery = container.ContainedEntities.First(); + + 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, drinkerBatteryComponent!.MaxCharge - drinkerBatteryComponent.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)) + _battery.SetCharge(drinkerBattery, drinkerBatteryComponent.CurrentCharge + amountToDrink, drinkerBatteryComponent); + else + { + _battery.SetCharge(drinkerBattery, sourceBattery.CurrentCharge + drinkerBatteryComponent.CurrentCharge, drinkerBatteryComponent); + _battery.SetCharge(source, 0); + } + + if (sourceComp != null && sourceComp.DrinkSound != null){ + _popup.PopupEntity(Loc.GetString("ipc-recharge-tip"), drinker, drinker, PopupType.SmallCaution); + _audio.PlayPvs(sourceComp.DrinkSound, source); + Spawn("EffectSparks", Transform(source).Coordinates); + } + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Power/Systems/BatteryElectrocuteChargeSystem.cs b/Content.Server/_EE/Power/Systems/BatteryElectrocuteChargeSystem.cs new file mode 100644 index 00000000000..7bf53568a6c --- /dev/null +++ b/Content.Server/_EE/Power/Systems/BatteryElectrocuteChargeSystem.cs @@ -0,0 +1,39 @@ +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; +using Content.Server._EE.Power.Components; + +namespace Content.Server._EE.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 charge = Math.Min(args.ShockDamage.Value * args.SiemensCoefficient + / ElectrocutionSystem.ElectrifiedDamagePerWatt * 2, + 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); + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Radio/IntrinsicRadioKeySystem.cs b/Content.Server/_EE/Radio/IntrinsicRadioKeySystem.cs new file mode 100644 index 00000000000..d3d6f49366c --- /dev/null +++ b/Content.Server/_EE/Radio/IntrinsicRadioKeySystem.cs @@ -0,0 +1,32 @@ +using Content.Server.Radio.Components; +using Content.Shared.Radio; +using Content.Shared.Radio.Components; + +namespace Content.Server._EE.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); + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/BatteryLocking/BatterySlotRequiresLockComponent.cs b/Content.Server/_EE/Silicon/BatteryLocking/BatterySlotRequiresLockComponent.cs new file mode 100644 index 00000000000..eb64ac99064 --- /dev/null +++ b/Content.Server/_EE/Silicon/BatteryLocking/BatterySlotRequiresLockComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Server._EE.Silicons.BatteryLocking; + +[RegisterComponent] +public sealed partial class BatterySlotRequiresLockComponent : Component +{ + [DataField] + public string ItemSlot = string.Empty; +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/BatteryLocking/BatterySlotRequiresLockSystem.cs b/Content.Server/_EE/Silicon/BatteryLocking/BatterySlotRequiresLockSystem.cs new file mode 100644 index 00000000000..b27cb65c36b --- /dev/null +++ b/Content.Server/_EE/Silicon/BatteryLocking/BatterySlotRequiresLockSystem.cs @@ -0,0 +1,41 @@ +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Lock; +using Content.Shared.Popups; +using Content.Shared._EE.Silicon.Components; +using Content.Shared.IdentityManagement; + +namespace Content.Server._EE.Silicons.BatteryLocking; + +public sealed class BatterySlotRequiresLockSystem : EntitySystem + +{ + [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + + /// + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(LockToggled); + SubscribeLocalEvent(LockToggleAttempted); + + } + private void LockToggled(EntityUid uid, BatterySlotRequiresLockComponent component, LockToggledEvent args) + { + if (!TryComp(uid, out var lockComp) + || !TryComp(uid, out var itemslots) + || !_itemSlotsSystem.TryGetSlot(uid, component.ItemSlot, out var slot, itemslots)) + return; + + _itemSlotsSystem.SetLock(uid, slot, lockComp.Locked, itemslots); + } + + private void LockToggleAttempted(EntityUid uid, BatterySlotRequiresLockComponent component, LockToggleAttemptEvent args) + { + if (args.User == uid || !HasComp(uid)) + return; + + _popupSystem.PopupEntity(Loc.GetString("batteryslotrequireslock-component-alert-owner", ("user", Identity.Entity(args.User, EntityManager))), uid, uid, PopupType.Large); + } + +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/BlindHealing/BlindHealingComponent.cs b/Content.Server/_EE/Silicon/BlindHealing/BlindHealingComponent.cs new file mode 100644 index 00000000000..1637ad6ec8c --- /dev/null +++ b/Content.Server/_EE/Silicon/BlindHealing/BlindHealingComponent.cs @@ -0,0 +1,23 @@ +namespace Content.Server._EE.Silicon.BlindHealing; + +[RegisterComponent] +public sealed partial class BlindHealingComponent : Component +{ + [DataField] + public int DoAfterDelay = 3; + + /// + /// A multiplier that will be applied to the above if an entity is repairing themselves. + /// + [DataField] + public float SelfHealPenalty = 4f; + + /// + /// Whether or not an entity is allowed to repair itself. + /// + [DataField] + public bool AllowSelfHeal = true; + + [DataField(required: true)] + public List DamageContainers; +} diff --git a/Content.Server/_EE/Silicon/BlindHealing/BlindHealingSystem.cs b/Content.Server/_EE/Silicon/BlindHealing/BlindHealingSystem.cs new file mode 100644 index 00000000000..a6a66506ff8 --- /dev/null +++ b/Content.Server/_EE/Silicon/BlindHealing/BlindHealingSystem.cs @@ -0,0 +1,98 @@ +using Content.Server.Administration.Logs; +using Content.Server.Cargo.Components; +using Content.Server.Stack; +using Content.Shared._EE.Silicon.BlindHealing; +using Content.Shared.Damage; +using Content.Shared.Database; +using Content.Shared.DoAfter; +using Content.Shared.Eye.Blinding.Components; +using Content.Shared.Eye.Blinding.Systems; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; +using Content.Shared.Popups; +using Content.Shared.Stacks; + +namespace Content.Server._EE.Silicon.BlindHealing; + +public sealed class BlindHealingSystem : SharedBlindHealingSystem +{ + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly BlindableSystem _blindableSystem = default!; + [Dependency] private readonly StackSystem _stackSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnUse); + SubscribeLocalEvent(OnInteract); + SubscribeLocalEvent(OnHealingFinished); + } + + private void OnHealingFinished(EntityUid uid, BlindHealingComponent component, HealingDoAfterEvent args) + { + if (args.Cancelled || args.Target == null + || !TryComp(args.Target, out var blindComp) + || blindComp is { EyeDamage: 0 }) + return; + + if (TryComp(uid, out var stackComponent) + && TryComp(uid, out var stackPrice)) + _stackSystem.SetCount(uid, (int) (_stackSystem.GetCount(uid, stackComponent) - stackPrice.Price), stackComponent); + + _blindableSystem.AdjustEyeDamage((args.Target.Value, blindComp), -blindComp.EyeDamage); + + _adminLogger.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target}'s vision"); + + var str = Loc.GetString("comp-repairable-repair", + ("target", uid), + ("tool", args.Used!)); + _popup.PopupEntity(str, uid, args.User); + + } + + private bool TryHealBlindness(EntityUid uid, EntityUid user, EntityUid target, float delay) + { + var doAfterEventArgs = + new DoAfterArgs(EntityManager, user, delay, new HealingDoAfterEvent(), uid, target: target, used: uid) + { + NeedHand = true, + BreakOnMove = true, + BreakOnWeightlessMove = false, + }; + + _doAfter.TryStartDoAfter(doAfterEventArgs); + return true; + } + + private void OnInteract(EntityUid uid, BlindHealingComponent component, ref AfterInteractEvent args) + { + + if (args.Handled + || !TryComp(args.User, out var damageable) + || damageable.DamageContainerID != null && !component.DamageContainers.Contains(damageable.DamageContainerID) + || !TryComp(args.User, out var blindcomp) + || blindcomp.EyeDamage == 0 + || args.User == args.Target && !component.AllowSelfHeal) + return; + + TryHealBlindness(uid, args.User, args.User, + args.User == args.Target + ? component.DoAfterDelay * component.SelfHealPenalty + : component.DoAfterDelay); + } + + private void OnUse(EntityUid uid, BlindHealingComponent component, ref UseInHandEvent args) + { + if (args.Handled + || !TryComp(args.User, out var damageable) + || damageable.DamageContainerID != null && !component.DamageContainers.Contains(damageable.DamageContainerID) + || !TryComp(args.User, out var blindcomp) + || blindcomp.EyeDamage == 0 + || !component.AllowSelfHeal) + return; + + TryHealBlindness(uid, args.User, args.User, + component.DoAfterDelay * component.SelfHealPenalty); + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/Charge/Components/BatteryDrinkerSourceComponent.cs b/Content.Server/_EE/Silicon/Charge/Components/BatteryDrinkerSourceComponent.cs new file mode 100644 index 00000000000..e5fa6cda66f --- /dev/null +++ b/Content.Server/_EE/Silicon/Charge/Components/BatteryDrinkerSourceComponent.cs @@ -0,0 +1,26 @@ +using Robust.Shared.Audio; + +namespace Content.Server._EE.Silicon.Charge; + +[RegisterComponent] +public sealed partial class BatteryDrinkerSourceComponent : Component +{ + /// + /// The max amount of power this source can provide in one sip. + /// No limit if null. + /// + [DataField] + public int? MaxAmount = null; + + /// + /// The multiplier for the drink speed. + /// + [DataField] + public float DrinkSpeedMulti = 1f; + + /// + /// The sound to play when the battery gets drunk from. + /// + [DataField] + public SoundSpecifier? DrinkSound = new SoundCollectionSpecifier("sparks"); +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/Charge/Systems/SiliconChargeSystem.cs b/Content.Server/_EE/Silicon/Charge/Systems/SiliconChargeSystem.cs new file mode 100644 index 00000000000..7ebb0ac717f --- /dev/null +++ b/Content.Server/_EE/Silicon/Charge/Systems/SiliconChargeSystem.cs @@ -0,0 +1,201 @@ +using Robust.Shared.Random; +using Content.Shared._EE.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._EE.Silicon.Systems; +using Content.Shared.Movement.Systems; +using Content.Server.Body.Components; +using Content.Shared.Mind.Components; +using System.Diagnostics.CodeAnalysis; +using Content.Server.PowerCell; +using Robust.Shared.Timing; +using Robust.Shared.Configuration; +using Robust.Shared.Utility; +using Content.Shared.CCVar; +using Content.Shared.PowerCell.Components; +using Content.Shared.Mind; +using Content.Shared.Alert; +using Content.Server._EE.Silicon.Death; +using Content.Server._EE.Power.Components; + +namespace Content.Server._EE.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 IGameTiming _timing = default!; + [Dependency] private readonly IConfigurationManager _config = default!; + [Dependency] private readonly PowerCellSystem _powerCell = default!; + [Dependency] private readonly AlertsSystem _alerts = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSiliconStartup); + } + + public bool TryGetSiliconBattery(EntityUid silicon, [NotNullWhen(true)] out BatteryComponent? batteryComp) + { + batteryComp = null; + if (!HasComp(silicon)) + return false; + + + // try get a battery directly on the inserted entity + if (TryComp(silicon, out batteryComp) + || _powerCell.TryGetBatteryFromSlot(silicon, out batteryComp)) + return true; + + + //DebugTools.Assert("SiliconComponent does not contain Battery"); + return false; + } + + private void OnSiliconStartup(EntityUid uid, SiliconComponent component, ComponentStartup args) + { + if (!HasComp(uid)) + return; + + 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 (_mobState.IsDead(silicon) + || !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(CCVars.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)) + { + UpdateChargeState(silicon, 0, siliconComp); + if (_alerts.IsShowingAlert(silicon, siliconComp.BatteryAlert)) + { + _alerts.ClearAlert(silicon, siliconComp.BatteryAlert); + _alerts.ShowAlert(silicon, siliconComp.NoBatteryAlert); + } + continue; + } + + // If the silicon ghosted or is SSD while still being powered, skip it. + if (TryComp(silicon, out var mindContComp) + && !mindContComp.HasMind) + 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, siliconComp, 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. + _powerCell.TryUseCharge(silicon, frameTime * drainRate); + + // Figure out the current state of the Silicon. + var chargePercent = (short) MathF.Round(batteryComp.CurrentCharge / batteryComp.MaxCharge * 10f); + + UpdateChargeState(silicon, chargePercent, siliconComp); + } + } + + /// + /// Checks if anything needs to be updated, and updates it. + /// + public void UpdateChargeState(EntityUid uid, short chargePercent, SiliconComponent component) + { + component.ChargeState = chargePercent; + + RaiseLocalEvent(uid, new SiliconChargeStateUpdateEvent(chargePercent)); + + _moveMod.RefreshMovementSpeedModifiers(uid); + + // If the battery was replaced and the no battery indicator is showing, replace the indicator + if (_alerts.IsShowingAlert(uid, component.NoBatteryAlert) && chargePercent != 0) + { + _alerts.ClearAlert(uid, component.NoBatteryAlert); + _alerts.ShowAlert(uid, component.BatteryAlert, chargePercent); + } + } + + private float SiliconHeatEffects(EntityUid silicon, SiliconComponent siliconComp, float frameTime) + { + if (!TryComp(silicon, out var temperComp) + || !TryComp(silicon, out var thermalComp)) + return 0; + + // 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)) + return hotTempMulti; + + siliconComp.OverheatAccumulator -= 5; + + if (!EntityManager.TryGetComponent(silicon, out var flamComp) + || flamComp is { OnFire: true } + || !(temperComp.CurrentTemperature > temperComp.HeatDamageThreshold)) + return hotTempMulti; + + _popup.PopupEntity(Loc.GetString("silicon-overheating"), silicon, silicon, PopupType.MediumCaution); + if (!_random.Prob(Math.Clamp(temperComp.CurrentTemperature / (upperThresh * 5), 0.001f, 0.9f))) + return hotTempMulti; + + // GoobStation: Replaced by KillOnOverheatSystem + //_flammable.AdjustFireStacks(silicon, Math.Clamp(siliconComp.FireStackMultiplier, -10, 10), flamComp); + //_flammable.Ignite(silicon, silicon, flamComp); + return hotTempMulti; + } + + // Check if the silicon is in a cold environment. + if (temperComp.CurrentTemperature < thermalComp.NormalBodyTemperature) + return 0.5f + temperComp.CurrentTemperature / thermalComp.NormalBodyTemperature * 0.5f; + + return 0; + } +} diff --git a/Content.Server/_EE/Silicon/DeadStartupButton/DeadStartupButtonSystem.cs b/Content.Server/_EE/Silicon/DeadStartupButton/DeadStartupButtonSystem.cs new file mode 100644 index 00000000000..732cc84344a --- /dev/null +++ b/Content.Server/_EE/Silicon/DeadStartupButton/DeadStartupButtonSystem.cs @@ -0,0 +1,82 @@ +using Content.Server.Chat.Systems; +using Content.Server.Lightning; +using Content.Server.Popups; +using Content.Server.PowerCell; +using Content.Server._EE.Silicon.Charge; +using Content.Shared._EE.Silicon.DeadStartupButton; +using Content.Shared.Audio; +using Content.Shared.Damage; +using Content.Shared.Electrocution; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Random; + +namespace Content.Server._EE.Silicon.DeadStartupButton; + +public sealed class DeadStartupButtonSystem : SharedDeadStartupButtonSystem +{ + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly LightningSystem _lightning = default!; + [Dependency] private readonly SiliconChargeSystem _siliconChargeSystem = default!; + [Dependency] private readonly PowerCellSystem _powerCell = default!; + [Dependency] private readonly ChatSystem _chatSystem = default!; + + /// + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnDoAfter); + SubscribeLocalEvent(OnElectrocuted); + SubscribeLocalEvent(OnMobStateChanged); + + } + + private void OnDoAfter(EntityUid uid, DeadStartupButtonComponent comp, OnDoAfterButtonPressedEvent args) + { + if (args.Handled || args.Cancelled + || !TryComp(uid, out var mobStateComponent) + || !_mobState.IsDead(uid, mobStateComponent) + || !TryComp(uid, out var mobThresholdsComponent) + || !TryComp(uid, out var damageable) + || !_mobThreshold.TryGetThresholdForState(uid, MobState.Critical, out var criticalThreshold, mobThresholdsComponent)) + return; + + if (damageable.TotalDamage < criticalThreshold) + _mobState.ChangeMobState(uid, MobState.Alive, mobStateComponent); + else + { + _audio.PlayPvs(comp.BuzzSound, uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); + _popup.PopupEntity(Loc.GetString("dead-startup-system-reboot-failed", ("target", MetaData(uid).EntityName)), uid); + Spawn("EffectSparks", Transform(uid).Coordinates); + } + } + + private void OnElectrocuted(EntityUid uid, DeadStartupButtonComponent comp, ElectrocutedEvent args) + { + if (!TryComp(uid, out var mobStateComponent) + || !_mobState.IsDead(uid, mobStateComponent) + || !_siliconChargeSystem.TryGetSiliconBattery(uid, out var bateria) + || bateria.CurrentCharge <= 0) + return; + + _lightning.ShootRandomLightnings(uid, 2, 4); + _powerCell.TryUseCharge(uid, bateria.CurrentCharge); + + } + + private void OnMobStateChanged(EntityUid uid, DeadStartupButtonComponent comp, MobStateChangedEvent args) + { + if (args.NewMobState != MobState.Alive) + return; + + _popup.PopupEntity(Loc.GetString("dead-startup-system-reboot-success", ("target", MetaData(uid).EntityName)), uid); + _audio.PlayPvs(comp.Sound, uid); + } + +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/Death/Components/SiliconDownOnDeadComponent.cs b/Content.Server/_EE/Silicon/Death/Components/SiliconDownOnDeadComponent.cs new file mode 100644 index 00000000000..c635fe05dda --- /dev/null +++ b/Content.Server/_EE/Silicon/Death/Components/SiliconDownOnDeadComponent.cs @@ -0,0 +1,17 @@ +namespace Content.Server._EE.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 partial class SiliconDownOnDeadComponent : Component +{ + /// + /// Is this Silicon currently dead? + /// + [ViewVariables(VVAccess.ReadOnly)] + public bool Dead; +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/Death/Systems/SiliconChargeDeathSystem.cs b/Content.Server/_EE/Silicon/Death/Systems/SiliconChargeDeathSystem.cs new file mode 100644 index 00000000000..25a50c7187d --- /dev/null +++ b/Content.Server/_EE/Silicon/Death/Systems/SiliconChargeDeathSystem.cs @@ -0,0 +1,127 @@ +using Content.Server.Power.Components; +using Content.Shared._EE.Silicon.Systems; +using Content.Shared.Bed.Sleep; +using Content.Server._EE.Silicon.Charge; +using Content.Server._EE.Power.Components; +using Content.Server.Humanoid; +using Content.Shared.Humanoid; + +namespace Content.Server._EE.Silicon.Death; + +public sealed class SiliconDeathSystem : EntitySystem +{ + [Dependency] private readonly SleepingSystem _sleep = default!; + [Dependency] private readonly SiliconChargeSystem _silicon = default!; + [Dependency] private readonly HumanoidAppearanceSystem _humanoidAppearanceSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSiliconChargeStateUpdate); + } + + private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, SiliconChargeStateUpdateEvent args) + { + if (!_silicon.TryGetSiliconBattery(uid, out var batteryComp)) + { + SiliconDead(uid, siliconDeadComp, batteryComp, uid); + return; + } + + if (args.ChargePercent == 0 && siliconDeadComp.Dead) + return; + + if (args.ChargePercent == 0 && !siliconDeadComp.Dead) + SiliconDead(uid, siliconDeadComp, batteryComp, uid); + else if (args.ChargePercent != 0 && siliconDeadComp.Dead) + SiliconUnDead(uid, siliconDeadComp, batteryComp, uid); + } + + 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); + + if (TryComp(uid, out HumanoidAppearanceComponent? humanoidAppearanceComponent)) + { + var layers = HumanoidVisualLayersExtension.Sublayers(HumanoidVisualLayers.HeadSide); + _humanoidAppearanceSystem.SetLayersVisibility(uid, layers, false, true, humanoidAppearanceComponent); + } + + siliconDeadComp.Dead = true; + + RaiseLocalEvent(uid, new SiliconChargeDeathEvent(uid, batteryComp, batteryUid)); + } + + private void SiliconUnDead(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, BatteryComponent? batteryComp, EntityUid batteryUid) + { + RemComp(uid); + _sleep.TryWaking(uid, true, null); + + 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; + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/EmitBuzzOnCrit/EmitBuzzWhileDamagedSystem.cs b/Content.Server/_EE/Silicon/EmitBuzzOnCrit/EmitBuzzWhileDamagedSystem.cs new file mode 100644 index 00000000000..a066e7afa99 --- /dev/null +++ b/Content.Server/_EE/Silicon/EmitBuzzOnCrit/EmitBuzzWhileDamagedSystem.cs @@ -0,0 +1,58 @@ +using Content.Server.Popups; +using Content.Shared._EE.Silicon.EmitBuzzWhileDamaged; +using Content.Shared.Audio; +using Content.Shared.Damage; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Systems; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Random; +using Robust.Shared.Timing; +using Content.Shared.Mobs.Components; + +namespace Content.Server._EE.Silicon.EmitBuzzOnCrit; + +/// +/// This handles the buzzing popup and sound of a silicon based race when it is pretty damaged. +/// +public sealed class EmitBuzzWhileDamagedSystem : EntitySystem +{ + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly IRobustRandom _robustRandom = default!; + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var uid, out var emitBuzzOnCritComponent, out var mobStateComponent, out var thresholdsComponent, out var damageableComponent)) + { + + if (_mobState.IsDead(uid, mobStateComponent) + || !_mobThreshold.TryGetThresholdForState(uid, MobState.Critical, out var threshold, thresholdsComponent) + || damageableComponent.TotalDamage < threshold / 2) + continue; + + emitBuzzOnCritComponent.AccumulatedFrametime += frameTime; + + if (emitBuzzOnCritComponent.AccumulatedFrametime < emitBuzzOnCritComponent.CycleDelay) + continue; + + emitBuzzOnCritComponent.AccumulatedFrametime -= emitBuzzOnCritComponent.CycleDelay; + + if (_gameTiming.CurTime <= emitBuzzOnCritComponent.LastBuzzPopupTime + emitBuzzOnCritComponent.BuzzPopupCooldown) + continue; + + // Start buzzing + emitBuzzOnCritComponent.LastBuzzPopupTime = _gameTiming.CurTime; + _popupSystem.PopupEntity(Loc.GetString("silicon-behavior-buzz"), uid); + Spawn("EffectSparks", Transform(uid).Coordinates); + _audio.PlayPvs(emitBuzzOnCritComponent.Sound, uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); + } + } + +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/EncryptionHolderRequiresLock/EncryptionHolderRequiresLockComponent.cs b/Content.Server/_EE/Silicon/EncryptionHolderRequiresLock/EncryptionHolderRequiresLockComponent.cs new file mode 100644 index 00000000000..a018ff81855 --- /dev/null +++ b/Content.Server/_EE/Silicon/EncryptionHolderRequiresLock/EncryptionHolderRequiresLockComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Server._EE.Silicon.EncryptionHolderRequiresLock; + +[RegisterComponent] +public sealed partial class EncryptionHolderRequiresLockComponent : Component +{ +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/EncryptionHolderRequiresLock/EncryptionHolderRequiresLockSystem.cs b/Content.Server/_EE/Silicon/EncryptionHolderRequiresLock/EncryptionHolderRequiresLockSystem.cs new file mode 100644 index 00000000000..87f937e2bcf --- /dev/null +++ b/Content.Server/_EE/Silicon/EncryptionHolderRequiresLock/EncryptionHolderRequiresLockSystem.cs @@ -0,0 +1,28 @@ +using Content.Shared.Lock; +using Content.Shared.Radio.Components; +using Content.Shared.Radio.EntitySystems; + +namespace Content.Server._EE.Silicon.EncryptionHolderRequiresLock; + +public sealed class EncryptionHolderRequiresLockSystem : EntitySystem + +{ + [Dependency] private readonly EncryptionKeySystem _encryptionKeySystem = default!; + + /// + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(LockToggled); + + } + private void LockToggled(EntityUid uid, EncryptionHolderRequiresLockComponent component, LockToggledEvent args) + { + if (!TryComp(uid, out var lockComp) + || !TryComp(uid, out var keyHolder)) + return; + + keyHolder.KeysUnlocked = !lockComp.Locked; + _encryptionKeySystem.UpdateChannels(uid, keyHolder); + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/IPC/InternalEncryptionKeySpawner.cs b/Content.Server/_EE/Silicon/IPC/InternalEncryptionKeySpawner.cs new file mode 100644 index 00000000000..964b7326f6e --- /dev/null +++ b/Content.Server/_EE/Silicon/IPC/InternalEncryptionKeySpawner.cs @@ -0,0 +1,30 @@ +using Content.Shared.Roles; +using Content.Shared.Radio.Components; +using Content.Shared.Containers; +using Robust.Shared.Containers; + +namespace Content.Server._EE.Silicon.IPC; +public sealed partial class InternalEncryptionKeySpawner : EntitySystem +{ + [Dependency] private readonly SharedContainerSystem _container = default!; + public void TryInsertEncryptionKey(EntityUid target, StartingGearPrototype startingGear, IEntityManager entityManager) + { + if (!TryComp(target, out var keyHolderComp) + || !startingGear.Equipment.TryGetValue("ears", out var earEquipString) + || string.IsNullOrEmpty(earEquipString)) + return; + + var earEntity = entityManager.SpawnEntity(earEquipString, entityManager.GetComponent(target).Coordinates); + if (!entityManager.HasComponent(earEntity) + || !entityManager.TryGetComponent(earEntity, out var fillComp) + || !fillComp.Containers.TryGetValue(EncryptionKeyHolderComponent.KeyContainerName, out var defaultKeys)) + return; + + _container.CleanContainer(keyHolderComp.KeyContainer); + + foreach (var key in defaultKeys) + entityManager.SpawnInContainerOrDrop(key, target, keyHolderComp.KeyContainer.ID, out _); + + entityManager.QueueDeleteEntity(earEntity); + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/SiliconEmitSoundOnDrainedComponent.cs b/Content.Server/_EE/Silicon/SiliconEmitSoundOnDrainedComponent.cs new file mode 100644 index 00000000000..0eba69bf54e --- /dev/null +++ b/Content.Server/_EE/Silicon/SiliconEmitSoundOnDrainedComponent.cs @@ -0,0 +1,25 @@ +using Robust.Shared.Audio; + +namespace Content.Server._EE.Silicon; + +/// +/// Applies a to a Silicon when its battery is drained, and removes it when it's not. +/// +[RegisterComponent] +public sealed partial class SiliconEmitSoundOnDrainedComponent : Component +{ + [DataField] + public SoundSpecifier Sound = default!; + + [DataField] + public TimeSpan MinInterval = TimeSpan.FromSeconds(8); + + [DataField] + public TimeSpan MaxInterval = TimeSpan.FromSeconds(15); + + [DataField] + public float PlayChance = 1f; + + [DataField] + public string? PopUp; +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/SiliconEmitSoundOnDrainedSystem.cs b/Content.Server/_EE/Silicon/SiliconEmitSoundOnDrainedSystem.cs new file mode 100644 index 00000000000..0829636ac7b --- /dev/null +++ b/Content.Server/_EE/Silicon/SiliconEmitSoundOnDrainedSystem.cs @@ -0,0 +1,43 @@ +using Content.Server._EE.Silicon.Death; +using Content.Shared.Sound.Components; +using Content.Server.Sound; +using Content.Shared.Mobs; +using Content.Shared._EE.Silicon.Systems; + +namespace Content.Server._EE.Silicon; + +public sealed class EmitSoundOnCritSystem : EntitySystem +{ + [Dependency] private readonly EmitSoundSystem _emitSound = default!; + public override void Initialize() + { + SubscribeLocalEvent(OnDeath); + SubscribeLocalEvent(OnAlive); + SubscribeLocalEvent(OnStateChange); + } + + private void OnDeath(EntityUid uid, SiliconEmitSoundOnDrainedComponent component, SiliconChargeDeathEvent args) + { + var spamComp = EnsureComp(uid); + + spamComp.MinInterval = component.MinInterval; + spamComp.MaxInterval = component.MaxInterval; + spamComp.PopUp = component.PopUp; + spamComp.Sound = component.Sound; + _emitSound.SetEnabled((uid, spamComp), true); + } + + 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) + return; + + RemComp(uid); + } +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealableComponent.cs b/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealableComponent.cs new file mode 100644 index 00000000000..4eaeb18136d --- /dev/null +++ b/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealableComponent.cs @@ -0,0 +1,9 @@ +using Content.Shared.Damage; +using Content.Shared.Tools; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server._EE.Silicon.WeldingHealable +{ + [RegisterComponent] + public sealed partial class WeldingHealableComponent : Component { } +} \ No newline at end of file diff --git a/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealableSystem.cs b/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealableSystem.cs new file mode 100644 index 00000000000..14f6745264d --- /dev/null +++ b/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealableSystem.cs @@ -0,0 +1,115 @@ +using Content.Server._EE.Silicon.WeldingHealing; +using Content.Shared.Tools.Components; +using Content.Shared._EE.Silicon.WeldingHealing; +using Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Damage; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Tools; +using Content.Shared._Shitmed.Targeting; +using Content.Shared.Body.Systems; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; + +namespace Content.Server._EE.Silicon.WeldingHealable; + +public sealed class WeldingHealableSystem : SharedWeldingHealableSystem +{ + [Dependency] private readonly SharedToolSystem _toolSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!; + + [Dependency] private readonly SharedBodySystem _bodySystem = default!; + public override void Initialize() + { + SubscribeLocalEvent(Repair); + SubscribeLocalEvent(OnRepairFinished); + } + + private void OnRepairFinished(EntityUid uid, WeldingHealableComponent healableComponent, SiliconRepairFinishedEvent args) + { + if (args.Cancelled || args.Used == null + || !TryComp(args.Target, out var damageable) + || !TryComp(args.Used, out var component) + || damageable.DamageContainerID is null + || !component.DamageContainers.Contains(damageable.DamageContainerID) + || !HasDamage((args.Target.Value, damageable), component, args.User) + || !TryComp(args.Used, out var welder) + || !TryComp(args.Used, out var solutionContainer) + || !_solutionContainer.TryGetSolution(((EntityUid) args.Used, solutionContainer), welder.FuelSolutionName, out var solution)) + return; + + _damageableSystem.TryChangeDamage(uid, component.Damage, true, false, origin: args.User); + + _solutionContainer.RemoveReagent(solution.Value, welder.FuelReagent, component.FuelCost); + + var str = Loc.GetString("comp-repairable-repair", + ("target", uid), + ("tool", args.Used!)); + _popup.PopupEntity(str, uid, args.User); + + if (!args.Used.HasValue) + return; + + args.Handled = _toolSystem.UseTool + (args.Used.Value, + args.User, + uid, + args.Delay, + component.QualityNeeded, + new SiliconRepairFinishedEvent + { + Delay = args.Delay + }); + } + private async void Repair(EntityUid uid, WeldingHealableComponent healableComponent, InteractUsingEvent args) + { + if (args.Handled + || !EntityManager.TryGetComponent(args.Used, out WeldingHealingComponent? component) + || !EntityManager.TryGetComponent(args.Target, out DamageableComponent? damageable) + || damageable.DamageContainerID is null + || !component.DamageContainers.Contains(damageable.DamageContainerID) + || !HasDamage((args.Target, damageable), component, args.User) + || !_toolSystem.HasQuality(args.Used, component.QualityNeeded) + || args.User == args.Target && !component.AllowSelfHeal) + return; + + float delay = args.User == args.Target + ? component.DoAfterDelay * component.SelfHealPenalty + : component.DoAfterDelay; + + args.Handled = _toolSystem.UseTool + (args.Used, + args.User, + args.Target, + delay, + component.QualityNeeded, + new SiliconRepairFinishedEvent + { + Delay = delay, + }); + } + + private bool HasDamage(Entity damageable, WeldingHealingComponent healable, EntityUid user) + { + if (healable.Damage.DamageDict is null) + return false; + + foreach (var type in healable.Damage.DamageDict) + if (damageable.Comp.Damage.DamageDict[type.Key].Value > 0) + return true; + + // In case the healer is a humanoid entity with targeting, we run the check on the targeted parts. + if (!TryComp(user, out TargetingComponent? targeting)) + return false; + var (targetType, targetSymmetry) = _bodySystem.ConvertTargetBodyPart(targeting.Target); + foreach (var part in _bodySystem.GetBodyChildrenOfType(damageable, targetType, symmetry: targetSymmetry)) + if (TryComp(part.Id, out var damageablePart)) + foreach (var type in healable.Damage.DamageDict) + if (damageablePart.Damage.DamageDict[type.Key].Value > 0) + return true; + + return false; + } +} diff --git a/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealingComponent.cs b/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealingComponent.cs new file mode 100644 index 00000000000..12d934ac10e --- /dev/null +++ b/Content.Server/_EE/Silicon/WeldingHealable/WeldingHealingComponent.cs @@ -0,0 +1,48 @@ +using Content.Shared.Damage; +using Content.Shared.Tools; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server._EE.Silicon.WeldingHealing +{ + [RegisterComponent] + public sealed partial class WeldingHealingComponent : Component + { + /// + /// All the damage to change information is stored in this . + /// + /// + /// If this data-field is specified, it will change damage by this amount instead of setting all damage to 0. + /// in order to heal/repair the damage values have to be negative. + /// + + [DataField(required: true)] + public DamageSpecifier Damage; + + [DataField(customTypeSerializer:typeof(PrototypeIdSerializer))] + public string QualityNeeded = "Welding"; + + /// + /// The fuel amount needed to repair physical related damage + /// + [DataField] + public int FuelCost = 15; + + [DataField] + public int DoAfterDelay = 3; + + /// + /// A multiplier that will be applied to the above if an entity is repairing themselves. + /// + [DataField] + public float SelfHealPenalty = 4f; + + /// + /// Whether or not an entity is allowed to repair itself. + /// + [DataField] + public bool AllowSelfHeal = true; + + [DataField(required: true)] + public List DamageContainers; + } +} diff --git a/Content.Server/_Goobstation/Temperature/KillOnOverheatComponent.cs b/Content.Server/_Goobstation/Temperature/KillOnOverheatComponent.cs new file mode 100644 index 00000000000..fc4e6155395 --- /dev/null +++ b/Content.Server/_Goobstation/Temperature/KillOnOverheatComponent.cs @@ -0,0 +1,16 @@ +using Content.Shared.Atmos; + +namespace Content.Server._Goobstation.Temperature; + +/// +/// Kills an entity when its temperature goes over a threshold. +/// +[RegisterComponent, Access(typeof(KillOnOverheatSystem))] +public sealed partial class KillOnOverheatComponent : Component +{ + [DataField] + public float OverheatThreshold = Atmospherics.T0C + 110f; + + [DataField] + public LocId OverheatPopup = "ipc-overheat-popup"; +} diff --git a/Content.Server/_Goobstation/Temperature/KillOnOverheatSystem.cs b/Content.Server/_Goobstation/Temperature/KillOnOverheatSystem.cs new file mode 100644 index 00000000000..e8c10154ee1 --- /dev/null +++ b/Content.Server/_Goobstation/Temperature/KillOnOverheatSystem.cs @@ -0,0 +1,30 @@ +using Content.Server.Temperature.Components; +using Content.Shared.IdentityManagement; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Popups; + +namespace Content.Server._Goobstation.Temperature; + +public sealed class KillOnOverheatSystem : EntitySystem +{ + [Dependency] private readonly MobStateSystem _mob = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp, out var temp, out var mob)) + { + if (mob.CurrentState == MobState.Dead || temp.CurrentTemperature < comp.OverheatThreshold) + continue; + + var msg = Loc.GetString(comp.OverheatPopup, ("name", Identity.Name(uid, EntityManager))); + _popup.PopupEntity(msg, uid, PopupType.LargeCaution); + _mob.ChangeMobState(uid, MobState.Dead, mob); + } + } +} diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs index 45935566e17..e745708924c 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs @@ -188,7 +188,7 @@ private void MapInitParts(EntityUid rootPartId, BodyPartComponent rootPart, Body cameFromEntities[connection] = childPart; var childPartComponent = Comp(childPart); - var partSlot = CreatePartSlot(parentEntity, connection, childPartComponent.PartType, parentPartComponent); + TryCreatePartSlot(parentEntity, connection, childPartComponent.PartType, out var partSlot, parentPartComponent); // Shitmed Change Start childPartComponent.ParentSlot = partSlot; Dirty(childPart, childPartComponent); @@ -215,7 +215,7 @@ private void SetupOrgans(Entity ent, Dictionary(parent.Value, GetOrganContainerId(slotId)); slot = new OrganSlot(slotId); - return part.Organs.TryAdd(slotId, slot.Value); + // Shitmed Change Start + if (!part.Organs.ContainsKey(slotId) + && !part.Organs.TryAdd(slotId, slot.Value)) + return false; + + return true; + // Shitmed Change End } /// diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs index 48b48baf187..18d46604c4a 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs @@ -502,7 +502,8 @@ public bool TryCreatePartSlot( Containers.EnsureContainer(partId.Value, GetPartSlotContainerId(slotId)); slot = new BodyPartSlot(slotId, partType); - if (!part.Children.TryAdd(slotId, slot.Value)) + if (!part.Children.ContainsKey(slotId) // Shitmed Change + && !part.Children.TryAdd(slotId, slot.Value)) return false; Dirty(partId.Value, part); diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 316d9b8690a..b076e1192dd 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -25,4 +25,10 @@ public sealed partial class CCVars : CVars /// public static readonly CVarDef DebugPow3rDisableParallel = CVarDef.Create("debug.pow3r_disable_parallel", true, CVar.SERVERONLY); + + /// + /// Goobstation: 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); } diff --git a/Content.Shared/Electrocution/ElectrocutionEvents.cs b/Content.Shared/Electrocution/ElectrocutionEvents.cs index fe5753c7fb3..3492ce535cb 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; // Goobstation - public ElectrocutedEvent(EntityUid targetUid, EntityUid? sourceUid, float siemensCoefficient) + public ElectrocutedEvent(EntityUid targetUid, EntityUid? sourceUid, float siemensCoefficient, float shockDamage) // Goobstation { TargetUid = targetUid; SourceUid = sourceUid; SiemensCoefficient = siemensCoefficient; + ShockDamage = shockDamage; // Goobstation } } } diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index b3f1c69a65d..fca70fcd516 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -40,6 +40,9 @@ public string GetName(string species, Gender? gender = null) case SpeciesNaming.FirstDashFirst: return Loc.GetString("namepreset-firstdashfirst", ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender))); + case SpeciesNaming.FirstDashLast: // Goobstation + return Loc.GetString("namepreset-firstdashlast", + ("first", GetFirstName(speciesProto, gender)), ("last", GetLastName(speciesProto))); case SpeciesNaming.LastFirst: // DeltaV: Rodentia name scheme return Loc.GetString("namepreset-lastfirst", ("last", GetLastName(speciesProto)), ("first", GetFirstName(speciesProto, gender))); diff --git a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs index 3477655d8c5..3dffb26f6dd 100644 --- a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs @@ -132,4 +132,5 @@ public enum SpeciesNaming : byte //End of Nyano - Summary: for Oni naming TheFirstofLast, LastFirst, // DeltaV + FirstDashLast, // Goobstation } diff --git a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs index 2ec48085c47..e1ee829269c 100644 --- a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs +++ b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs @@ -21,6 +21,16 @@ using Robust.Shared.Serialization; using Robust.Shared.Timing; +// Goobstation Change +using Content.Shared.CCVar; +using Content.Shared._Goobstation.CCVar; +using Content.Shared.Weapons.Ranged.Events; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Inventory.VirtualItem; +using Robust.Shared.Configuration; +using Content.Shared.Implants.Components; + namespace Content.Shared.Mech.EntitySystems; /// @@ -39,6 +49,12 @@ public abstract class SharedMechSystem : EntitySystem [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; // Goobstation Change + [Dependency] private readonly SharedVirtualItemSystem _virtualItem = default!; // Goobstation Change + [Dependency] private readonly IConfigurationManager _config = default!; // Goobstation Change + + // Goobstation: Local variable for checking if mech guns can be used out of them. + private bool _canUseMechGunOutside; /// public override void Initialize() @@ -55,6 +71,14 @@ public override void Initialize() SubscribeLocalEvent(OnGetMeleeWeapon); SubscribeLocalEvent(OnCanAttackFromContainer); SubscribeLocalEvent(OnAttackAttempt); + SubscribeLocalEvent(OnEntGotRemovedFromContainer); + SubscribeLocalEvent(OnShotAttempted); // Goobstation + Subs.CVar(_config, GoobCVars.MechGunOutsideMech, value => _canUseMechGunOutside = value, true); // Goobstation + } + // GoobStation: Fixes scram implants or teleports locking the pilot out of being able to move. + private void OnEntGotRemovedFromContainer(EntityUid uid, MechPilotComponent component, EntGotRemovedFromContainerMessage args) + { + TryEject(component.Mech, pilot: uid); } private void OnToggleEquipmentAction(EntityUid uid, MechComponent component, MechToggleEquipmentEvent args) @@ -368,6 +392,7 @@ public bool TryInsert(EntityUid uid, EntityUid? toInsert, MechComponent? compone SetupUser(uid, toInsert.Value); _container.Insert(toInsert.Value, component.PilotSlot); UpdateAppearance(uid, component); + UpdateHands(toInsert.Value, uid, true); // Goobstation return true; } @@ -376,23 +401,64 @@ public bool TryInsert(EntityUid uid, EntityUid? toInsert, MechComponent? compone /// /// /// + /// The pilot to eject /// Whether or not the pilot was ejected. - public bool TryEject(EntityUid uid, MechComponent? component = null) + public bool TryEject(EntityUid uid, MechComponent? component = null, EntityUid? pilot = null) { if (!Resolve(uid, ref component)) return false; - if (component.PilotSlot.ContainedEntity == null) - return false; + if (component.PilotSlot.ContainedEntity != null) + pilot = component.PilotSlot.ContainedEntity.Value; - var pilot = component.PilotSlot.ContainedEntity.Value; + if (pilot == null) + return false; - RemoveUser(uid, pilot); - _container.RemoveEntity(uid, pilot); + RemoveUser(uid, pilot.Value); + _container.RemoveEntity(uid, pilot.Value); UpdateAppearance(uid, component); + UpdateHands(pilot.Value, uid, false); // Goobstation return true; } + // Goobstation Change Start + private void UpdateHands(EntityUid uid, EntityUid mech, bool active) + { + if (!TryComp(uid, out var handsComponent)) + return; + if (active) + BlockHands(uid, mech, handsComponent); + else + FreeHands(uid, mech); + } + private void BlockHands(EntityUid uid, EntityUid mech, HandsComponent handsComponent) + { + var freeHands = 0; + foreach (var hand in _hands.EnumerateHands(uid, handsComponent)) + { + if (hand.HeldEntity == null) + { + freeHands++; + continue; + } + // Is this entity removable? (they might have handcuffs on) + if (HasComp(hand.HeldEntity) && hand.HeldEntity != mech) + continue; + _hands.DoDrop(uid, hand, true, handsComponent); + freeHands++; + if (freeHands == 2) + break; + } + if (_virtualItem.TrySpawnVirtualItemInHand(mech, uid, out var virtItem1)) + EnsureComp(virtItem1.Value); + if (_virtualItem.TrySpawnVirtualItemInHand(mech, uid, out var virtItem2)) + EnsureComp(virtItem2.Value); + } + private void FreeHands(EntityUid uid, EntityUid mech) + { + _virtualItem.DeleteInHandsMatching(uid, mech); + } + // Goobstation Change End private void OnGetMeleeWeapon(EntityUid uid, MechPilotComponent component, GetMeleeWeaponEvent args) { if (args.Handled) @@ -417,6 +483,20 @@ private void OnAttackAttempt(EntityUid uid, MechPilotComponent component, Attack args.Cancel(); } + // Goobstation: Prevent guns being used out of mechs if CCVAR is set. + private void OnShotAttempted(EntityUid uid, MechEquipmentComponent component, ref ShotAttemptedEvent args) + { + if (!component.EquipmentOwner.HasValue + || !HasComp(component.EquipmentOwner.Value)) + { + if (!_canUseMechGunOutside) + args.Cancel(); + return; + } + var ev = new HandleMechEquipmentBatteryEvent(); + RaiseLocalEvent(uid, ev); + } + private void UpdateAppearance(EntityUid uid, MechComponent? component = null, AppearanceComponent? appearance = null) { @@ -476,3 +556,12 @@ public sealed partial class MechExitEvent : SimpleDoAfterEvent public sealed partial class MechEntryEvent : SimpleDoAfterEvent { } + + +/// +/// Event raised when an user attempts to fire a mech weapon to check if its battery is drained +/// +[Serializable, NetSerializable] +public sealed partial class HandleMechEquipmentBatteryEvent : EntityEventArgs +{ +} diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index 0f5f9172cc6..b456e47007c 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; +using Content.Shared._EE.Silicon.Components; // Goobstation using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Examine; @@ -532,7 +533,7 @@ public string MindOwnerLoggingString(MindComponent mind) /// /// Returns a list of every living humanoid player's minds, except for a single one which is exluded. /// - public HashSet> GetAliveHumans(EntityUid? exclude = null) + public HashSet> GetAliveHumans(EntityUid? exclude = null, bool excludeSilicon = false) { var allHumans = new HashSet>(); // HumanoidAppearanceComponent is used to prevent mice, pAIs, etc from being chosen @@ -544,6 +545,10 @@ public HashSet> GetAliveHumans(EntityUid? exclude = null) if (!TryGetMind(uid, out var mind, out var mindComp) || mind == exclude || !_mobState.IsAlive(uid, mobState)) continue; + // Goobstation: Skip IPCs from selections + if (excludeSilicon && HasComp(uid)) + continue; + allHumans.Add(new Entity(mind, mindComp)); } diff --git a/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs b/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs index bd49acf9090..72d6a55b415 100644 --- a/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs +++ b/Content.Shared/Radio/Components/EncryptionKeyHolderComponent.cs @@ -53,4 +53,11 @@ public sealed partial class EncryptionKeyHolderComponent : Component /// [ViewVariables] public string? DefaultChannel; + + /// + /// Goobstation: 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; } diff --git a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs index 7b050273db6..145233cb4ac 100644 --- a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs +++ b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs @@ -174,7 +174,9 @@ private void OnStartup(EntityUid uid, EncryptionKeyHolderComponent component, Co private void OnHolderExamined(EntityUid uid, EncryptionKeyHolderComponent component, ExaminedEvent args) { - if (!args.IsInDetailsRange) + if (!args.IsInDetailsRange + || !component.ExamineWhileLocked && !component.KeysUnlocked // Goobstation + || !component.ExamineWhileLocked && TryComp(uid, out var panel) && !panel.Open) // Goobstation return; if (component.KeyContainer.ContainedEntities.Count == 0) diff --git a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs index a048844a119..5ec68d2083f 100644 --- a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs +++ b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs @@ -72,7 +72,7 @@ public sealed partial class MeleeWeaponComponent : Component /// [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public bool ResistanceBypass = false; - + /// /// Base damage for this weapon. Can be modified via heavy damage or other means. /// @@ -170,6 +170,10 @@ public sealed partial class MeleeWeaponComponent : Component public float HeavyPartDamageMultiplier = 0.5f; // Shitmed Change End + + // Goobstation + [DataField, AutoNetworkedField] + public bool CanWideSwing = true; } /// diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index 3a496e22cf1..6d91d8265d2 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -191,7 +191,8 @@ private void OnHeavyAttack(HeavyAttackEvent msg, EntitySessionEventArgs args) return; if (!TryGetWeapon(user, out var weaponUid, out var weapon) || - weaponUid != GetEntity(msg.Weapon)) + weaponUid != GetEntity(msg.Weapon) || + !weapon.CanWideSwing) // Goobstation Change { return; } diff --git a/Content.Shared/_EE/Silicon/BatteryDrinkerEvent.cs b/Content.Shared/_EE/Silicon/BatteryDrinkerEvent.cs new file mode 100644 index 00000000000..25ce74ba1ce --- /dev/null +++ b/Content.Shared/_EE/Silicon/BatteryDrinkerEvent.cs @@ -0,0 +1,12 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared._EE.Silicon; + +[Serializable, NetSerializable] +public sealed partial class BatteryDrinkerDoAfterEvent : SimpleDoAfterEvent +{ + public BatteryDrinkerDoAfterEvent() + { + } +} \ No newline at end of file diff --git a/Content.Shared/_EE/Silicon/BlindHealing/SharedBlindHealingSystem.cs b/Content.Shared/_EE/Silicon/BlindHealing/SharedBlindHealingSystem.cs new file mode 100644 index 00000000000..3534db7fb63 --- /dev/null +++ b/Content.Shared/_EE/Silicon/BlindHealing/SharedBlindHealingSystem.cs @@ -0,0 +1,12 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared._EE.Silicon.BlindHealing; + +public abstract partial class SharedBlindHealingSystem : EntitySystem +{ + [Serializable, NetSerializable] + protected sealed partial class HealingDoAfterEvent : SimpleDoAfterEvent + { + } +} \ No newline at end of file diff --git a/Content.Shared/_EE/Silicon/Components/SiliconComponent.cs b/Content.Shared/_EE/Silicon/Components/SiliconComponent.cs new file mode 100644 index 00000000000..021a13bca15 --- /dev/null +++ b/Content.Shared/_EE/Silicon/Components/SiliconComponent.cs @@ -0,0 +1,114 @@ +using Robust.Shared.GameStates; +using Content.Shared._EE.Silicon.Systems; +using Robust.Shared.Serialization.TypeSerializers.Implementations; +using Robust.Shared.Prototypes; +using Content.Shared.Alert; + +namespace Content.Shared._EE.Silicon.Components; + +/// +/// Component for defining a mob as a robot. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class SiliconComponent : Component +{ + [ViewVariables(VVAccess.ReadOnly)] + public short ChargeState = 10; + + [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. + /// + + /// + /// 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. + /// Setting this to Npc will delay charge state updates by LastDrainTime and skip battery heat calculations + /// + [DataField(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] + public bool BatteryPowered = false; + + /// + /// How much power is drained by this Silicon every second by default. + /// + [DataField] + 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] + public float? ChargeThresholdMid = 0.5f; + + /// + [DataField] + public float? ChargeThresholdLow = 0.25f; + + /// + [DataField] + public float? ChargeThresholdCritical = 0.1f; + + [DataField] + public ProtoId BatteryAlert = "BorgBattery"; + + [DataField] + public ProtoId NoBatteryAlert = "BorgBatteryNone"; + + + /// + /// The amount the Silicon will be slowed at each charge state. + /// + [DataField(required: true)] + public Dictionary SpeedModifierThresholds = default!; + + [DataField] + public float FireStackMultiplier = 1f; + + /// + /// Whether or not a Silicon will cancel all sleep events. + /// Maybe you want an android that can sleep as well as drink APCs? I'm not going to judge. + /// + [DataField] + public bool DoSiliconsDreamOfElectricSheep; +} \ No newline at end of file diff --git a/Content.Shared/_EE/Silicon/DeadStartupButton/DeadStartupButtonComponent.cs b/Content.Shared/_EE/Silicon/DeadStartupButton/DeadStartupButtonComponent.cs new file mode 100644 index 00000000000..1e2fc2d768d --- /dev/null +++ b/Content.Shared/_EE/Silicon/DeadStartupButton/DeadStartupButtonComponent.cs @@ -0,0 +1,28 @@ +using Robust.Shared.Audio; + +namespace Content.Shared._EE.Silicon.DeadStartupButton; + +/// +/// This is used for... +/// +[RegisterComponent] +public sealed partial class DeadStartupButtonComponent : Component +{ + [DataField("verbText")] + public string VerbText = "dead-startup-button-verb"; + + [DataField("sound")] + public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Effects/Arcade/newgame.ogg"); + + [DataField("buttonSound")] + public SoundSpecifier ButtonSound = new SoundPathSpecifier("/Audio/Machines/button.ogg"); + + [DataField("doAfterInterval"), ViewVariables(VVAccess.ReadWrite)] + public float DoAfterInterval = 1f; + + [DataField("buzzSound")] + public SoundSpecifier BuzzSound = new SoundCollectionSpecifier("buzzes"); + + [DataField("verbPriority"), ViewVariables(VVAccess.ReadWrite)] + public int VerbPriority = 1; +} \ No newline at end of file diff --git a/Content.Shared/_EE/Silicon/DeadStartupButton/SharedDeadStartupButtonSystem.cs b/Content.Shared/_EE/Silicon/DeadStartupButton/SharedDeadStartupButtonSystem.cs new file mode 100644 index 00000000000..bc8b8e8bb85 --- /dev/null +++ b/Content.Shared/_EE/Silicon/DeadStartupButton/SharedDeadStartupButtonSystem.cs @@ -0,0 +1,66 @@ +using Content.Shared.DoAfter; +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Content.Shared.Verbs; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Network; +using Robust.Shared.Serialization; +using Robust.Shared.Utility; + +namespace Content.Shared._EE.Silicon.DeadStartupButton; + +/// +/// This creates a Button that can be activated after an entity, usually a silicon or an IPC, died. +/// This will activate a doAfter and then revive the entity, playing a custom afterward sound. +/// +public abstract partial class SharedDeadStartupButtonSystem : EntitySystem +{ + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly INetManager _net = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent>(AddTurnOnVerb); + } + + private void AddTurnOnVerb(EntityUid uid, DeadStartupButtonComponent component, GetVerbsEvent args) + { + if (!_mobState.IsDead(uid) + || !args.CanAccess || !args.CanInteract || args.Hands == null) + return; + + if (!TryComp(uid, out MobStateComponent? mobStateComponent) || !_mobState.IsDead(uid, mobStateComponent)) + return; + + args.Verbs.Add(new AlternativeVerb() + { + Act = () => TryStartup(args.User, uid, component), + Text = Loc.GetString(component.VerbText), + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png")), + Priority = component.VerbPriority + }); + } + + private void TryStartup(EntityUid user, EntityUid target, DeadStartupButtonComponent comp) + { + if (!_net.IsServer) + return; + _audio.PlayPvs(comp.ButtonSound, target); + var args = new DoAfterArgs(EntityManager, user, comp.DoAfterInterval, new OnDoAfterButtonPressedEvent(), target, target:target) + { + BreakOnDamage = true, + BreakOnMove = true, + }; + _doAfterSystem.TryStartDoAfter(args); + } + + [Serializable, NetSerializable] + public sealed partial class OnDoAfterButtonPressedEvent : SimpleDoAfterEvent + { + } + + +} \ No newline at end of file diff --git a/Content.Shared/_EE/Silicon/EmitBuzzWhileDamaged/EmitBuzzWhileDamagedSystem.cs b/Content.Shared/_EE/Silicon/EmitBuzzWhileDamaged/EmitBuzzWhileDamagedSystem.cs new file mode 100644 index 00000000000..e13b77f8bd4 --- /dev/null +++ b/Content.Shared/_EE/Silicon/EmitBuzzWhileDamaged/EmitBuzzWhileDamagedSystem.cs @@ -0,0 +1,26 @@ +using System.ComponentModel.DataAnnotations; +using Robust.Shared.Audio; + +namespace Content.Shared._EE.Silicon.EmitBuzzWhileDamaged; + +/// +/// This is used for controlling the cadence of the buzzing emitted by EmitBuzzOnCritSystem. +/// This component is used by mechanical species that can get to critical health. +/// +[RegisterComponent] +public sealed partial class EmitBuzzWhileDamagedComponent : Component +{ + [DataField("buzzPopupCooldown")] + public TimeSpan BuzzPopupCooldown { get; private set; } = TimeSpan.FromSeconds(8); + + [ViewVariables] + public TimeSpan LastBuzzPopupTime; + + [DataField("cycleDelay")] + public float CycleDelay = 2.0f; + + public float AccumulatedFrametime; + + [DataField("sound")] + public SoundSpecifier Sound = new SoundCollectionSpecifier("buzzes"); +} \ No newline at end of file diff --git a/Content.Shared/_EE/Silicon/SharedSiliconSystem.cs b/Content.Shared/_EE/Silicon/SharedSiliconSystem.cs new file mode 100644 index 00000000000..a92b271c29a --- /dev/null +++ b/Content.Shared/_EE/Silicon/SharedSiliconSystem.cs @@ -0,0 +1,109 @@ +using Content.Shared._EE.Silicon.Components; +using Content.Shared.Alert; +using Content.Shared.Bed.Sleep; +using Robust.Shared.Serialization; +using Content.Shared.Movement.Systems; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.PowerCell.Components; + +namespace Content.Shared._EE.Silicon.Systems; + + +public sealed class SharedSiliconChargeSystem : EntitySystem +{ + [Dependency] private readonly AlertsSystem _alertsSystem = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSiliconInit); + SubscribeLocalEvent(OnSiliconChargeStateUpdate); + SubscribeLocalEvent(OnRefreshMovespeed); + SubscribeLocalEvent(OnItemSlotInsertAttempt); + SubscribeLocalEvent(OnItemSlotEjectAttempt); + SubscribeLocalEvent(OnTryingToSleep); + } + + private void OnItemSlotInsertAttempt(EntityUid uid, SiliconComponent component, ref ItemSlotInsertAttemptEvent args) + { + if (args.Cancelled + || !TryComp(uid, out var cellSlotComp) + || !_itemSlots.TryGetSlot(uid, cellSlotComp.CellSlotId, out var cellSlot) + || cellSlot != args.Slot || args.User != uid) + return; + + args.Cancelled = true; + } + + private void OnItemSlotEjectAttempt(EntityUid uid, SiliconComponent component, ref ItemSlotEjectAttemptEvent args) + { + if (args.Cancelled + || !TryComp(uid, out var cellSlotComp) + || !_itemSlots.TryGetSlot(uid, cellSlotComp.CellSlotId, out var cellSlot) + || cellSlot != args.Slot || args.User != uid) + return; + + args.Cancelled = true; + } + + private void OnSiliconInit(EntityUid uid, SiliconComponent component, ComponentInit args) + { + if (!component.BatteryPowered) + return; + + _alertsSystem.ShowAlert(uid, component.BatteryAlert, component.ChargeState); + } + + private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconComponent component, SiliconChargeStateUpdateEvent ev) + { + _alertsSystem.ShowAlert(uid, component.BatteryAlert, ev.ChargePercent); + } + + private void OnRefreshMovespeed(EntityUid uid, SiliconComponent component, RefreshMovementSpeedModifiersEvent args) + { + if (!component.BatteryPowered) + return; + + var closest = 0; + + foreach (var state in component.SpeedModifierThresholds) + if (component.ChargeState >= state.Key && state.Key > closest) + closest = state.Key; + + var speedMod = component.SpeedModifierThresholds[closest]; + + args.ModifySpeed(speedMod, speedMod); + } + + /// + /// Silicon entities can now also be Living player entities. We may want to prevent them from sleeping if they can't sleep. + /// + private void OnTryingToSleep(EntityUid uid, SiliconComponent component, ref TryingToSleepEvent args) + { + args.Cancelled = !component.DoSiliconsDreamOfElectricSheep; + } +} + + +public enum SiliconType +{ + Player, + GhostRole, + Npc, +} + +/// +/// Event raised when a Silicon's charge state needs to be updated. +/// +[Serializable, NetSerializable] +public sealed class SiliconChargeStateUpdateEvent : EntityEventArgs +{ + public short ChargePercent { get; } + + public SiliconChargeStateUpdateEvent(short chargePercent) + { + ChargePercent = chargePercent; + } +} \ No newline at end of file diff --git a/Content.Shared/_EE/Silicon/SiliconRepairable/SharedWeldingHealableSystem.cs b/Content.Shared/_EE/Silicon/SiliconRepairable/SharedWeldingHealableSystem.cs new file mode 100644 index 00000000000..c8e1921e403 --- /dev/null +++ b/Content.Shared/_EE/Silicon/SiliconRepairable/SharedWeldingHealableSystem.cs @@ -0,0 +1,13 @@ +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared._EE.Silicon.WeldingHealing; + +public abstract partial class SharedWeldingHealableSystem : EntitySystem +{ + [Serializable, NetSerializable] + protected sealed partial class SiliconRepairFinishedEvent : SimpleDoAfterEvent + { + public float Delay; + } +} \ No newline at end of file diff --git a/Content.Shared/_Goobstation/CCVars/CCVars.Goob.cs b/Content.Shared/_Goobstation/CCVars/CCVars.Goob.cs index b3348d52b97..0ff26f90aca 100644 --- a/Content.Shared/_Goobstation/CCVars/CCVars.Goob.cs +++ b/Content.Shared/_Goobstation/CCVars/CCVars.Goob.cs @@ -17,4 +17,14 @@ public sealed partial class GoobCVars /// public static readonly CVarDef AutoGetUp = CVarDef.Create("white.auto_get_up", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); // WD EDIT + + #region Mechs + + /// + /// Whether or not players can use mech guns outside of mechs. + /// + public static readonly CVarDef MechGunOutsideMech = + CVarDef.Create("mech.gun_outside_mech", true, CVar.SERVER | CVar.REPLICATED); + + #endregion } diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz1.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz1.ogg new file mode 100644 index 00000000000..aa21acee3ca Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz1.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz2.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz2.ogg new file mode 100644 index 00000000000..652d331abc5 Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz2.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz3.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz3.ogg new file mode 100644 index 00000000000..e7721fa6664 Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz3.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz4.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz4.ogg new file mode 100644 index 00000000000..8c400abe858 Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz4.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz5.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz5.ogg new file mode 100644 index 00000000000..b24a684e43e Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz5.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz6.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz6.ogg new file mode 100644 index 00000000000..81b206c6ed6 Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz6.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz7.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz7.ogg new file mode 100644 index 00000000000..f58bfaa2eaa Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz7.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz8.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz8.ogg new file mode 100644 index 00000000000..75ad0c4fee2 Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz8.ogg differ diff --git a/Resources/Audio/_EE/Effects/Buzzes/buzz9.ogg b/Resources/Audio/_EE/Effects/Buzzes/buzz9.ogg new file mode 100644 index 00000000000..1e3a743f73c Binary files /dev/null and b/Resources/Audio/_EE/Effects/Buzzes/buzz9.ogg differ diff --git a/Resources/Audio/_EE/Effects/Silicon/startup.ogg b/Resources/Audio/_EE/Effects/Silicon/startup.ogg new file mode 100644 index 00000000000..33d90e78454 Binary files /dev/null and b/Resources/Audio/_EE/Effects/Silicon/startup.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/attributions.yml b/Resources/Audio/_EE/Voice/IPC/attributions.yml new file mode 100644 index 00000000000..d2bcb8d8941 --- /dev/null +++ b/Resources/Audio/_EE/Voice/IPC/attributions.yml @@ -0,0 +1,14 @@ +- files: ["beep_500.ogg", "beep_2000.ogg"] + license: "CC0-1.0" + copyright: "Synthesized in Audacity by BasedUser." + source: "https://github.com/ekrixi-14/ekrixi" + +- files: ["pai_whistle.ogg"] + license: "CC-BY-4.0" + copyright: "Source sound by hubismal@GitHub, modified in Audacity by BasedUser." + source: "https://github.com/space-wizards/space-station-14/commit/3421e4f4de2613df1e92a4169a778335bc9faac4" + +- files: ["whirr1.ogg", "whirr2.ogg", "whirr3.ogg"] + license: "CC0-1.0" + copyright: "Taken from source, spectrally modified and clipped" + source: "https://freesound.org/people/sad3d/sounds/500168/" diff --git a/Resources/Audio/_EE/Voice/IPC/beep_2000.ogg b/Resources/Audio/_EE/Voice/IPC/beep_2000.ogg new file mode 100644 index 00000000000..1caa98ff9a9 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/beep_2000.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/beep_500.ogg b/Resources/Audio/_EE/Voice/IPC/beep_500.ogg new file mode 100644 index 00000000000..5435eefb472 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/beep_500.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/cry_robot_1.ogg b/Resources/Audio/_EE/Voice/IPC/cry_robot_1.ogg new file mode 100644 index 00000000000..78a27496a59 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/cry_robot_1.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/pai_whistle.ogg b/Resources/Audio/_EE/Voice/IPC/pai_whistle.ogg new file mode 100644 index 00000000000..42aebd11972 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/pai_whistle.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/robot-laugh_3.ogg b/Resources/Audio/_EE/Voice/IPC/robot-laugh_3.ogg new file mode 100644 index 00000000000..331151f6b57 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/robot-laugh_3.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/robot-scream.ogg b/Resources/Audio/_EE/Voice/IPC/robot-scream.ogg new file mode 100644 index 00000000000..6420a4009db Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/robot-scream.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/whirr1.ogg b/Resources/Audio/_EE/Voice/IPC/whirr1.ogg new file mode 100644 index 00000000000..2679d794f06 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/whirr1.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/whirr2.ogg b/Resources/Audio/_EE/Voice/IPC/whirr2.ogg new file mode 100644 index 00000000000..6f74bebed84 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/whirr2.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/whirr3.ogg b/Resources/Audio/_EE/Voice/IPC/whirr3.ogg new file mode 100644 index 00000000000..45ececee626 Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/whirr3.ogg differ diff --git a/Resources/Audio/_EE/Voice/IPC/wilhelm.ogg b/Resources/Audio/_EE/Voice/IPC/wilhelm.ogg new file mode 100644 index 00000000000..b8ad9d97d4f Binary files /dev/null and b/Resources/Audio/_EE/Voice/IPC/wilhelm.ogg differ diff --git a/Resources/Locale/en-US/_EE/body/behavior/behavior.ftl b/Resources/Locale/en-US/_EE/body/behavior/behavior.ftl new file mode 100644 index 00000000000..d952341b4ea --- /dev/null +++ b/Resources/Locale/en-US/_EE/body/behavior/behavior.ftl @@ -0,0 +1 @@ +silicon-behavior-buzz = Bzzzzt... diff --git a/Resources/Locale/en-US/_EE/emotes/emotes.ftl b/Resources/Locale/en-US/_EE/emotes/emotes.ftl new file mode 100644 index 00000000000..d9cdd381ba6 --- /dev/null +++ b/Resources/Locale/en-US/_EE/emotes/emotes.ftl @@ -0,0 +1,2 @@ +silicon-emote-deathgasp = seizes up and falls limp, {POSS-ADJ($entity)} lights sputtering into darkness... +chat-emote-msg-deathgasp-silicon = suddenly goes silent, with a hiss of grinding servos and a screech of dying myomers. \ No newline at end of file diff --git a/Resources/Locale/en-US/_EE/lock/batterySlotRequiresLock.ftl b/Resources/Locale/en-US/_EE/lock/batterySlotRequiresLock.ftl new file mode 100644 index 00000000000..25a7f0723eb --- /dev/null +++ b/Resources/Locale/en-US/_EE/lock/batterySlotRequiresLock.ftl @@ -0,0 +1 @@ +batteryslotrequireslock-component-alert-owner = {$user} is messing with your maintenance panel! diff --git a/Resources/Locale/en-US/_EE/power/batteries.ftl b/Resources/Locale/en-US/_EE/power/batteries.ftl new file mode 100644 index 00000000000..15ebafae77b --- /dev/null +++ b/Resources/Locale/en-US/_EE/power/batteries.ftl @@ -0,0 +1 @@ +battery-electrocute-charge = The battery surges with energy! diff --git a/Resources/Locale/en-US/_EE/power/batteryDrinker.ftl b/Resources/Locale/en-US/_EE/power/batteryDrinker.ftl new file mode 100644 index 00000000000..950b321d407 --- /dev/null +++ b/Resources/Locale/en-US/_EE/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/_EE/power/silicons.ftl b/Resources/Locale/en-US/_EE/power/silicons.ftl new file mode 100644 index 00000000000..4e047d36539 --- /dev/null +++ b/Resources/Locale/en-US/_EE/power/silicons.ftl @@ -0,0 +1,4 @@ +ipc-recharge-tip = You charged a litte of your battery. +dead-startup-button-verb = Reboot +dead-startup-system-reboot-success = {$target}'s system was rebooted. +dead-startup-system-reboot-failed = {$target}'s chassis is way too damaged. diff --git a/Resources/Locale/en-US/_EE/prototypes/entities/mobs/customization/ipcAntenna.ftl b/Resources/Locale/en-US/_EE/prototypes/entities/mobs/customization/ipcAntenna.ftl new file mode 100644 index 00000000000..ec3efd9f553 --- /dev/null +++ b/Resources/Locale/en-US/_EE/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/_EE/prototypes/entities/mobs/customization/ipcScreens.ftl b/Resources/Locale/en-US/_EE/prototypes/entities/mobs/customization/ipcScreens.ftl new file mode 100644 index 00000000000..3f53f2d3f93 --- /dev/null +++ b/Resources/Locale/en-US/_EE/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/_EE/silicons/cyberlimbs.ftl b/Resources/Locale/en-US/_EE/silicons/cyberlimbs.ftl new file mode 100644 index 00000000000..2c4da305b3e --- /dev/null +++ b/Resources/Locale/en-US/_EE/silicons/cyberlimbs.ftl @@ -0,0 +1,96 @@ +marking-MobIPCHeadDefault = Standard Operational Monitor +marking-MobIPCTorsoDefault = Standard Robotic Chassis +marking-MobIPCTorsoFemaleDefault = Standard Robotic Chassis +marking-MobIPCLArmDefault = Standard Left Robotic Arm +marking-MobIPCLHandDefault = Standard Left Robotic Hand +marking-MobIPCLLegDefault = Standard Left Robotic Leg +marking-MobIPCLFootDefault = Standard Left Robotic Foot +marking-MobIPCRArmDefault = Standard Right Robotic Arm +marking-MobIPCRHandDefault = Standard Right Robotic Hand +marking-MobIPCRLegDefault = Standard Right Robotic Leg +marking-MobIPCRFootDefault = Standard Right Robotic Foot + +marking-CyberLimbsMarkingBishopHead = Operational Monitor from Bishop Cybernetics +marking-CyberLimbsMarkingBishopHeadAlt = Head from Bishop Cybernetics +marking-CyberLimbsMarkingBishopHeadAlt1 = Alternate Head from Bishop Cybernetics +marking-CyberLimbsMarkingBishopChest = Robotic Chassis from Bishop Cybernetics +marking-CyberLimbsMarkingBishopLArm = Left Robotic Arm from Bishop Cybernetics +marking-CyberLimbsMarkingBishopLHand = Left Robotic Hand from Bishop Cybernetics +marking-CyberLimbsMarkingBishopLLeg = Left Robotic Leg from Bishop Cybernetics +marking-CyberLimbsMarkingBishopLFoot = Left Robotic Foot from Bishop Cybernetics +marking-CyberLimbsMarkingBishopRArm = Right Robotic Arm from Bishop Cybernetics +marking-CyberLimbsMarkingBishopRHand = Right Robotic Hand from Bishop Cybernetics +marking-CyberLimbsMarkingBishopRLeg = Right Robotic Leg from Bishop Cybernetics +marking-CyberLimbsMarkingBishopRFoot = Right Robotic Foot from Bishop Cybernetics + +marking-CyberLimbsMarkingHesphiastosHead = Operational Monitor from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosHeadAlt = Head from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosChest = Robotic Chassis from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosLArm = Left Robotic Arm from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosLHand = Left Robotic Hand from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosLLeg = Left Robotic Leg from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosLFoot = Left Robotic Foot from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosRArm = Right Robotic Arm from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosRHand = Right Robotic Hand from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosRLeg = Right Robotic Leg from Hesphiastos Industries +marking-CyberLimbsMarkingHesphiastosRFoot = Right Robotic Foot from Hesphiastos Industries + +marking-CyberLimbsMarkingWardtakahashiHead = Operational Monitor from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiHeadAlt = Head from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiHeadAlt1 = Alternate Head from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiChest = Robotic Chassis from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiLArm = Left Robotic Arm from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiLHand = Left Robotic Hand from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiLLeg = Left Robotic Leg from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiLFoot = Left Robotic Foot from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiRArm = Right Robotic Arm from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiRHand = Right Robotic Hand from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiRLeg = Right Robotic Leg from Ward-Takahashi +marking-CyberLimbsMarkingWardtakahashiRFoot = Right Robotic Foot from Ward-Takahashi + +marking-CyberLimbsMarkingXionHead = Operational Monitor from Xion Manufacturing Group +marking-CyberLimbsMarkingXionHeadAlt = Head from Xion Manufacturing Group +marking-CyberLimbsMarkingXionChest = Robotic Chassis from Xion Manufacturing Group +marking-CyberLimbsMarkingXionLArm = Left Robotic Arm from Xion Manufacturing Group +marking-CyberLimbsMarkingXionLHand = Left Robotic Hand from Xion Manufacturing Group +marking-CyberLimbsMarkingXionLLeg = Left Robotic Leg from Xion Manufacturing Group +marking-CyberLimbsMarkingXionLFoot = Left Robotic Foot from Xion Manufacturing Group +marking-CyberLimbsMarkingXionRArm = Right Robotic Arm from Xion Manufacturing Group +marking-CyberLimbsMarkingXionRHand = Right Robotic Hand from Xion Manufacturing Group +marking-CyberLimbsMarkingXionRLeg = Right Robotic Leg from Xion Manufacturing Group +marking-CyberLimbsMarkingXionRFoot = Right Robotic Foot from Xion Manufacturing Group + +marking-CyberLimbsMarkingShellguardHead = Operational Monitor from Shellguard Munitions +marking-CyberLimbsMarkingShellguardHeadAlt = Head from Shellguard Munitions +marking-CyberLimbsMarkingShellguardChest = Robotic Chassis from Shellguard Munitions +marking-CyberLimbsMarkingShellguardLArm = Left Robotic Arm from Shellguard Munitions +marking-CyberLimbsMarkingShellguardLHand = Left Robotic Hand from Shellguard Munitions +marking-CyberLimbsMarkingShellguardLLeg = Left Robotic Leg from Shellguard Munitions +marking-CyberLimbsMarkingShellguardLFoot = Left Robotic Foot from Shellguard Munitions +marking-CyberLimbsMarkingShellguardRArm = Right Robotic Arm from Shellguard Munitions +marking-CyberLimbsMarkingShellguardRHand = Right Robotic Hand from Shellguard Munitions +marking-CyberLimbsMarkingShellguardRLeg = Right Robotic Leg from Shellguard Munitions +marking-CyberLimbsMarkingShellguardRFoot = Right Robotic Foot from Shellguard Munitions + +marking-CyberLimbsMarkingMorpheusHead = Operational Monitor from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusHeadAlt = Head from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusChest = Robotic Chassis from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusLArm = Left Robotic Arm from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusLHand = Left Robotic Hand from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusLLeg = Left Robotic Leg from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusLFoot = Left Robotic Foot from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusRArm = Right Robotic Arm from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusRHand = Right Robotic Hand from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusRLeg = Right Robotic Leg from Morpheus Cyberkinetics +marking-CyberLimbsMarkingMorpheusRFoot = Right Robotic Foot from Morpheus Cyberkinetics + +marking-CyberLimbsMarkingZenghuHead = Head from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuChest = Robotic Chassis from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuRHand = Right Robotic Hand from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuRArm = Right Robotic Arm from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuLHand = Left Robotic Hand from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuLArm = Left Robotic Arm from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuRLeg = Right Robotic Leg from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuRFoot = Right Robotic Foot from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuLLeg = Left Robotic Leg from Zenghu Pharmaceuticals +marking-CyberLimbsMarkingZenghuLFoot = Left Robotic Foot from Zenghu Pharmaceuticals diff --git a/Resources/Locale/en-US/_EE/silicons/siliconChargers.ftl b/Resources/Locale/en-US/_EE/silicons/siliconChargers.ftl new file mode 100644 index 00000000000..4d143b6337e --- /dev/null +++ b/Resources/Locale/en-US/_EE/silicons/siliconChargers.ftl @@ -0,0 +1,4 @@ +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/_EE/silicons/silicons.ftl b/Resources/Locale/en-US/_EE/silicons/silicons.ftl new file mode 100644 index 00000000000..f7a9650fff3 --- /dev/null +++ b/Resources/Locale/en-US/_EE/silicons/silicons.ftl @@ -0,0 +1,3 @@ +silicon-overheating = You feel your circuits overheating! +silicon-crit = Structural integrity critical! +silicon-power-low = Power low! diff --git a/Resources/Locale/en-US/_EE/species/namePreset.ftl b/Resources/Locale/en-US/_EE/species/namePreset.ftl new file mode 100644 index 00000000000..be280a7ba20 --- /dev/null +++ b/Resources/Locale/en-US/_EE/species/namePreset.ftl @@ -0,0 +1 @@ +namepreset-firstdashlast = {$first}-{$last} diff --git a/Resources/Locale/en-US/_EE/species/species.ftl b/Resources/Locale/en-US/_EE/species/species.ftl new file mode 100644 index 00000000000..faec6dde93a --- /dev/null +++ b/Resources/Locale/en-US/_EE/species/species.ftl @@ -0,0 +1 @@ +species-name-ipc = IPC diff --git a/Resources/Locale/en-US/_Goobstation/power/silicons.ftl b/Resources/Locale/en-US/_Goobstation/power/silicons.ftl new file mode 100644 index 00000000000..9d52b2210d1 --- /dev/null +++ b/Resources/Locale/en-US/_Goobstation/power/silicons.ftl @@ -0,0 +1 @@ +ipc-overheat-popup = {$name}'s circuits shut down from overheating! diff --git a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml index f7d412ec756..19e86b0be7e 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml @@ -200,6 +200,7 @@ tags: - ClownMask - WhitelistChameleon + - IPCMaskWearable # EE - IPCs - type: HideLayerClothing slots: - Snout @@ -263,6 +264,9 @@ - type: HideLayerClothing slots: - Snout + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase @@ -280,6 +284,7 @@ tags: - HamsterWearable - WhitelistChameleon + - IPCMaskWearable # EE - IPCs - type: HideLayerClothing slots: - Snout @@ -460,6 +465,7 @@ tags: - HamsterWearable - WhitelistChameleon + - IPCMaskWearable # EE - IPCs - type: HideLayerClothing slots: - Snout @@ -480,6 +486,9 @@ - type: HideLayerClothing slots: - Snout + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase @@ -496,6 +505,9 @@ - type: HideLayerClothing slots: - Snout + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase @@ -512,6 +524,9 @@ - type: HideLayerClothing slots: - Snout + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase @@ -528,6 +543,9 @@ - type: HideLayerClothing slots: - Snout + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase @@ -544,6 +562,9 @@ - type: HideLayerClothing slots: - Snout + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase @@ -560,6 +581,9 @@ - type: HideLayerClothing slots: - Snout + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase @@ -576,6 +600,7 @@ - type: Tag tags: - WhitelistChameleon + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskNeckGaiter @@ -662,6 +687,9 @@ - type: EyeProtection - type: BreathMask - type: IdentityBlocker + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskGas @@ -685,3 +713,4 @@ - type: Tag tags: - WhitelistChameleon + - IPCMaskWearable # EE - IPCs diff --git a/Resources/Prototypes/Entities/Clothing/Masks/specific.yml b/Resources/Prototypes/Entities/Clothing/Masks/specific.yml index 286dfd6cf1c..8d052ec2898 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/specific.yml @@ -39,6 +39,9 @@ type: ChameleonBoundUserInterface enum.VoiceMaskUIKey.Key: type: VoiceMaskBoundUserInterface + - type: Tag + tags: + - IPCMaskWearable # EE - IPCs - type: entity parent: ClothingMaskBase diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 59d8ed19220..2ea0d76a2c3 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -48,6 +48,12 @@ solutions: glass: canReact: false + # EE - IPC Healing + - type: BlindHealing + damageContainers: + - Silicon + - type: StackPrice + price: 2 - type: entity parent: SheetGlassBase diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml index 4c4e44c28cd..e407ef99bf0 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml @@ -42,6 +42,7 @@ enum.MechUiKey.Key: type: MechBoundUserInterface - type: MeleeWeapon + canWideSwing: false hidden: true attackRate: 0.75 damage: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml index 712c2167e33..37a8d9e8071 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/mmi.yml @@ -99,6 +99,9 @@ stopSearchVerbText: positronic-brain-stop-searching-verb-text stopSearchVerbPopup: positronic-brain-stopped-searching job: Borg + - type: Organ + slotId: posbrain + - type: Brain - type: BlockMovement - type: Examiner - type: BorgBrain diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index a397e80dbe8..10bad83c262 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -29,6 +29,19 @@ - type: PhysicalComposition materialComposition: Steel: 15 + # EE Change Start + #Same as Ointment but divided by 5 and 3 because StackPrice needs to be 1 - Estacao Pirata IPCs + #1 Ointment = -50 damage of those types + #1 Cable ~= -50 (-49.8) damage of those types + - type: Healing + delay: 0.6 + damageContainers: + - Silicon + damage: + types: # these are all split across multiple types + Heat: -1.66 + Shock: -1.66 + # EE Change End - type: GuideHelp guides: - VoltageNetworks diff --git a/Resources/Prototypes/Entities/Objects/Tools/welders.yml b/Resources/Prototypes/Entities/Objects/Tools/welders.yml index b834068ee9e..757ff48c9be 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/welders.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/welders.yml @@ -105,6 +105,15 @@ price: 40 - type: IgnitionSource temperature: 700 + - type: WeldingHealing # Same as Brutepack - EE IPCs + damageContainers: + - Silicon + fuelCost: 15 + damage: + types: + Blunt: -15 + Piercing: -15 + Slash: -15 - type: Cautery # Shitmed speed: 0.7 - type: SurgeryTool # Shitmed diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 5fffb856a36..fd22819dd6e 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -656,6 +656,20 @@ - LightHeadBorg - TorsoBorg - BorgModuleSurgery # Shitmed Change + # Shitmed Change + - BorgModuleSurgery + - TorsoIPC + - LeftArmIPC + - RightArmIPC + - LeftLegIPC + - RightLegIPC + - HeadIPC + - LeftHandIPC + - RightHandIPC + - LeftFootIPC + - RightFootIPC + - OrganIPCEyes + - OrganIPCPump dynamicRecipes: - ProximitySensor - ClothingEyesHudDiagnostic diff --git a/Resources/Prototypes/Entities/Structures/Power/apc.yml b/Resources/Prototypes/Entities/Structures/Power/apc.yml index 0a2a8c37e3d..4bb57e2d438 100644 --- a/Resources/Prototypes/Entities/Structures/Power/apc.yml +++ b/Resources/Prototypes/Entities/Structures/Power/apc.yml @@ -143,6 +143,8 @@ priority: 1 - type: StaticPrice price: 500 + - type: BatteryDrinkerSource # EE IPCs + maxAmount: 10000 - type: GuideHelp guides: - VoltageNetworks @@ -213,6 +215,8 @@ - type: Battery maxCharge: 50000 startingCharge: 50000 + - type: BatteryDrinkerSource # EE IPCs + maxAmount: 5000 - type: entity parent: BaseAPC @@ -222,6 +226,8 @@ - type: Battery maxCharge: 100000 startingCharge: 100000 + - type: BatteryDrinkerSource # EE IPCs + maxAmount: 12000 - type: entity parent: BaseAPC @@ -231,6 +237,8 @@ - type: Battery maxCharge: 150000 startingCharge: 150000 + - type: BatteryDrinkerSource # EE IPCs + maxAmount: 18000 - type: entity parent: BaseAPC @@ -240,3 +248,5 @@ - type: Battery maxCharge: 200000 startingCharge: 200000 + - type: BatteryDrinkerSource # EE IPCs + maxAmount: 26000 \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Power/chargers.yml b/Resources/Prototypes/Entities/Structures/Power/chargers.yml index 4094b3fb072..b6f67ba7bf0 100644 --- a/Resources/Prototypes/Entities/Structures/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Structures/Power/chargers.yml @@ -247,6 +247,7 @@ whitelist: components: - BorgChassis + - Silicon # EE IPCs - type: Construction containers: - machine_parts diff --git a/Resources/Prototypes/Guidebook/species.yml b/Resources/Prototypes/Guidebook/species.yml index 998b06d24f3..5e342397cc4 100644 --- a/Resources/Prototypes/Guidebook/species.yml +++ b/Resources/Prototypes/Guidebook/species.yml @@ -18,6 +18,7 @@ - Oni - Rodentia - Chitinid + - IPC - type: guideEntry id: Arachnid @@ -58,3 +59,8 @@ id: Vox name: species-name-vox text: "/ServerInfo/Guidebook/Mobs/Vox.xml" + +- type: guideEntry + id: IPC + name: species-name-ipc + text: "/ServerInfo/Guidebook/Mobs/IPCs.xml" diff --git a/Resources/Prototypes/Roles/Antags/zombie.yml b/Resources/Prototypes/Roles/Antags/zombie.yml index 859f89d70a6..0360515d25f 100644 --- a/Resources/Prototypes/Roles/Antags/zombie.yml +++ b/Resources/Prototypes/Roles/Antags/zombie.yml @@ -7,6 +7,10 @@ requirements: - !type:OverallPlaytimeRequirement # DeltaV - Playtime requirement time: 43200 # DeltaV - 12 hours + - !type:SpeciesRequirement + inverted: true + species: + - IPC guides: [ Zombies ] - type: antag @@ -15,4 +19,9 @@ antagonist: true setPreference: false objective: roles-antag-zombie-objective + requirements: + - !type:SpeciesRequirement + inverted: true + species: + - IPC guides: [ Zombies ] diff --git a/Resources/Prototypes/_EE/Body/Organs/ipc.yml b/Resources/Prototypes/_EE/Body/Organs/ipc.yml new file mode 100644 index 00000000000..4f79b856096 --- /dev/null +++ b/Resources/Prototypes/_EE/Body/Organs/ipc.yml @@ -0,0 +1,76 @@ +- type: entity + id: BaseIPCOrgan + parent: BaseItem + abstract: true + components: + - type: Sprite + netsync: false + sprite: _Shitmed/Mobs/Species/IPC/organs.rsi + - type: Organ + # - type: Food + # - type: Extractable + # grindableSolutionName: organ + - type: SolutionContainerManager + solutions: + organ: + reagents: + - ReagentId: Oil + Quantity: 10 + +- 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 + slotId: eyes + - type: Eyes + +- 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 + slotId: pump + - type: Heart + # 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/_EE/Body/Parts/ipc.yml b/Resources/Prototypes/_EE/Body/Parts/ipc.yml new file mode 100644 index 00000000000..67c29962fd0 --- /dev/null +++ b/Resources/Prototypes/_EE/Body/Parts/ipc.yml @@ -0,0 +1,263 @@ +- type: entity + id: PartIPC + parent: BaseItem + name: "ipc body part" + abstract: true + components: + - type: Damageable + damageContainer: Inorganic # Shitmed Change + - type: BodyPart + - type: Gibbable + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + - type: SurgeryTool + startSound: + path: /Audio/_Shitmed/Medical/Surgery/organ1.ogg + endSound: + path: /Audio/_Shitmed/Medical/Surgery/organ2.ogg + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 110 + behaviors: + - !type:GibPartBehavior { } + - trigger: + !type:DamageTypeTrigger + damageType: Slash + damage: 150 + behaviors: + - !type:GibPartBehavior { } + - type: StaticPrice + price: 100 + +- type: entity + id: TorsoIPC + name: "ipc torso" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "torso_m" + - type: Icon + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "torso_m" + - type: BodyPart + partType: Torso + children: # I hate this so much I want to kill it AAAAAAAAAAAAAAAAAAAAAAAA + head: + id: "head" + type: Head + left arm: + id: "left arm" + type: Arm + right arm: + id: "right arm" + type: Arm + left leg: + id: "left leg" + type: Leg + right leg: + id: "right leg" + type: Leg + organs: + posbrain: + id: "posbrain" + pump: + id: "pump" + - type: ContainerContainer + containers: + torso_slot: !type:ContainerSlot {} + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 400 + behaviors: + - !type:GibPartBehavior { } + - trigger: + !type:DamageTypeTrigger + damageType: Slash + damage: 400 + behaviors: + - !type:GibPartBehavior { } + +- type: entity + id: HeadIPC + name: "ipc head" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "head_m" + - type: Icon + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "head_m" + - type: BodyPart + partType: Head + organs: + eyes: + id: "eyes" + 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: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "l_arm" + - type: Icon + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "l_arm" + - type: BodyPart + partType: Arm + symmetry: Left + children: + left hand: + id: "left hand" + type: Hand + +- type: entity + id: RightArmIPC + name: "right ipc arm" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "r_arm" + - type: Icon + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "r_arm" + - type: BodyPart + partType: Arm + symmetry: Right + children: + right hand: + id: "right hand" + type: Hand + +- type: entity + id: LeftHandIPC + name: "left ipc hand" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "l_hand" + - type: Icon + sprite: _Shitmed/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: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "r_hand" + - type: Icon + sprite: _Shitmed/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: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "l_leg" + - type: Icon + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "l_leg" + - type: BodyPart + partType: Leg + symmetry: Left + children: + left foot: + id: "left foot" + type: Foot + - type: MovementBodyPart + +- type: entity + id: RightLegIPC + name: "right ipc leg" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "r_leg" + - type: Icon + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "r_leg" + - type: BodyPart + partType: Leg + symmetry: Right + children: + right foot: + id: "right foot" + type: Foot + - type: MovementBodyPart + +- type: entity + id: LeftFootIPC + name: "left ipc foot" + parent: PartIPC + components: + - type: Sprite + netsync: false + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "l_foot" + - type: Icon + sprite: _Shitmed/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: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "r_foot" + - type: Icon + sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: "r_foot" + - type: BodyPart + partType: Foot + symmetry: Right diff --git a/Resources/Prototypes/_EE/Body/Prototypes/ipc.yml b/Resources/Prototypes/_EE/Body/Prototypes/ipc.yml new file mode 100644 index 00000000000..12a6213d00d --- /dev/null +++ b/Resources/Prototypes/_EE/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: + - right arm + - left arm + - right leg + - left leg + organs: + posbrain: PositronicBrain + pump: 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 \ No newline at end of file diff --git a/Resources/Prototypes/_EE/Damage/modifier_sets.yml b/Resources/Prototypes/_EE/Damage/modifier_sets.yml new file mode 100644 index 00000000000..e91554257fc --- /dev/null +++ b/Resources/Prototypes/_EE/Damage/modifier_sets.yml @@ -0,0 +1,7 @@ +- type: damageModifierSet + id: IPC + coefficients: + Poison: 0 + Cold: 0.5 + Heat: 1.5 + Shock: 2.0 diff --git a/Resources/Prototypes/_EE/Datasets/ipc_names.yml b/Resources/Prototypes/_EE/Datasets/ipc_names.yml new file mode 100644 index 00000000000..2b46f41ec23 --- /dev/null +++ b/Resources/Prototypes/_EE/Datasets/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 \ No newline at end of file diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/antenna.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/antenna.yml new file mode 100644 index 00000000000..b90200a45db --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/antenna.yml @@ -0,0 +1,89 @@ +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaTv + bodyPart: HeadTop + markingCategory: HeadTop + sprites: + - sprite: _EE/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_tv + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaTesla + bodyPart: HeadTop + markingCategory: HeadTop + sprites: + - sprite: _EE/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_tesla + +# - type: marking +# speciesRestriction: [IPC] +# id: RobotAntennaLightb +# bodyPart: HeadTop +# markingCategory: HeadTop +# sprites: +# - sprite: _EE/Mobs/Customization/ipc_antenna.rsi +# state: ipc_antenna_lightb + +# - type: marking +# speciesRestriction: [IPC] +# id: RobotAntennaLight +# bodyPart: HeadTop +# markingCategory: HeadTop +# sprites: +# - sprite: _EE/Mobs/Customization/ipc_antenna.rsi +# state: ipc_antenna_light + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaCyberhead + bodyPart: HeadTop + markingCategory: HeadTop + sprites: + - sprite: _EE/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_cyberhead + +# - type: marking +# speciesRestriction: [IPC] +# id: RobotAntennaSidelights +# bodyPart: HeadTop +# markingCategory: HeadTop +# sprites: +# - sprite: _EE/Mobs/Customization/ipc_antenna.rsi +# state: ipc_antenna_sidelights + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaAntlers + bodyPart: HeadTop + markingCategory: HeadTop + sprites: + - sprite: _EE/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_antlers + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaDroneeyes + bodyPart: HeadTop + markingCategory: HeadTop + sprites: + - sprite: _EE/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_droneeyes + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaCrowned + bodyPart: HeadTop + markingCategory: HeadTop + sprites: + - sprite: _EE/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_crowned + +- type: marking + speciesRestriction: [IPC] + id: RobotAntennaTowers + bodyPart: HeadTop + markingCategory: HeadTop + sprites: + - sprite: _EE/Mobs/Customization/ipc_antenna.rsi + state: ipc_antenna_towers \ No newline at end of file diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/bishop.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/bishop.yml new file mode 100644 index 00000000000..5f7e3724498 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/bishop.yml @@ -0,0 +1,128 @@ +- type: marking + id: CyberLimbsMarkingBishopHead + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_monitor.rsi + state: head + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_monitor.rsi + state: head-2 + +- type: marking + id: CyberLimbsMarkingBishopHeadAlt + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: head + +- type: marking + id: CyberLimbsMarkingBishopHeadAlt1 + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_alt1.rsi + state: head + +- type: marking + id: CyberLimbsMarkingBishopChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: torso-primary + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: torso-secondary + +- type: marking + id: CyberLimbsMarkingBishopLArm + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: l_arm-primary + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: l_arm-secondary + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: l_arm-tertiary + +- type: marking + id: CyberLimbsMarkingBishopLHand + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: l_hand + +- type: marking + id: CyberLimbsMarkingBishopLLeg + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: l_leg-primary + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: l_leg-secondary + + +- type: marking + id: CyberLimbsMarkingBishopLFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: l_foot + + + +- type: marking + id: CyberLimbsMarkingBishopRArm + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: r_arm-primary + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: r_arm-secondary + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: r_arm-tertiary + + +- type: marking + id: CyberLimbsMarkingBishopRHand + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: r_hand + +- type: marking + id: CyberLimbsMarkingBishopRLeg + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: r_leg-primary + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: r_leg-secondary + + +- type: marking + id: CyberLimbsMarkingBishopRFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi + state: r_foot diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/hephiastos.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/hephiastos.yml new file mode 100644 index 00000000000..58481694f73 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/hephiastos.yml @@ -0,0 +1,128 @@ +- type: marking + id: CyberLimbsMarkingHesphiastosHead + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_monitor.rsi + state: head-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_monitor.rsi + state: head-2 + +- type: marking + id: CyberLimbsMarkingHesphiastosHeadAlt + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_alt1.rsi + state: head-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_alt1.rsi + state: head-2 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_alt1.rsi + state: head-3 + +- type: marking + id: CyberLimbsMarkingHesphiastosChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: torso-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: torso-2 + +- type: marking + id: CyberLimbsMarkingHesphiastosLArm + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_arm-2 + +- type: marking + id: CyberLimbsMarkingHesphiastosLHand + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_hand-2 + +- type: marking + id: CyberLimbsMarkingHesphiastosLLeg + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_leg-2 + + +- type: marking + id: CyberLimbsMarkingHesphiastosLFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: l_foot-2 + + + +- type: marking + id: CyberLimbsMarkingHesphiastosRArm + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_arm-2 + + +- type: marking + id: CyberLimbsMarkingHesphiastosRHand + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_hand-2 + + +- type: marking + id: CyberLimbsMarkingHesphiastosRLeg + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_leg-2 + + +- type: marking + id: CyberLimbsMarkingHesphiastosRFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC, Moth, Dwarf, Human, Arachnid, Felinid, Oni, Vulpkanin, HumanoidFoxes, Reptilian] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/hesphiastos/hesphiastos_main.rsi + state: r_foot-2 diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/morpheus.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/morpheus.yml new file mode 100644 index 00000000000..ddb18e26082 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/morpheus.yml @@ -0,0 +1,158 @@ +- type: marking + id: CyberLimbsMarkingMorpheusHead + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: head + +- type: marking + id: CyberLimbsMarkingMorpheusHeadAlt + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_alt1.rsi + state: head + +- type: marking + id: CyberLimbsMarkingMorpheusChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: torso + +- type: marking + id: CyberLimbsMarkingMorpheusLArm + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: l_arm + +- type: marking + id: CyberLimbsMarkingMorpheusLHand + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: l_hand + +- type: marking + id: CyberLimbsMarkingMorpheusLLeg + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: l_leg + + +- type: marking + id: CyberLimbsMarkingMorpheusLFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: l_foot + + + +- type: marking + id: CyberLimbsMarkingMorpheusRArm + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: r_arm + + +- type: marking + id: CyberLimbsMarkingMorpheusRHand + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: r_hand + +- type: marking + id: CyberLimbsMarkingMorpheusRLeg + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: r_leg + + +- type: marking + id: CyberLimbsMarkingMorpheusRFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/morpheus/morpheus_main.rsi + state: r_foot diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/screens.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/screens.yml new file mode 100644 index 00000000000..ee45913fe8d --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/screens.yml @@ -0,0 +1,390 @@ +## CANT SET THESE SCREENS TO "shader: unshaded" +## RobustToolbox/Robust.Shared/Utility/SpriteSpecifier.cs + +- type: marking + speciesRestriction: [IPC] + id: ScreenStatic + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_static + + +- type: marking + speciesRestriction: [IPC] + id: ScreenBlue + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_blue + + +- type: marking + speciesRestriction: [IPC] + id: ScreenBreakout + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_breakout + + +- type: marking + speciesRestriction: [IPC] + id: ScreenEight + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eight + + +- type: marking + speciesRestriction: [IPC] + id: ScreenGoggles + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_goggles + + +- type: marking + speciesRestriction: [IPC] + id: ScreenExclaim + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_exclaim + + +- type: marking + speciesRestriction: [IPC] + id: ScreenHeart + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_heart + + +- type: marking + speciesRestriction: [IPC] + id: ScreenMonoeye + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_monoeye + + +- type: marking + speciesRestriction: [IPC] + id: ScreenNature + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_nature + + +- type: marking + speciesRestriction: [IPC] + id: ScreenOrange + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_orange + + +- type: marking + speciesRestriction: [IPC] + id: ScreenPink + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_pink + + +- type: marking + speciesRestriction: [IPC] + id: ScreenQuestion + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_question + + +- type: marking + speciesRestriction: [IPC] + id: ScreenShower + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_shower + + +- type: marking + speciesRestriction: [IPC] + id: ScreenYellow + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_yellow + + +- type: marking + speciesRestriction: [IPC] + id: ScreenScroll + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_scroll + + +- type: marking + speciesRestriction: [IPC] + id: ScreenConsole + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_console + + +- type: marking + speciesRestriction: [IPC] + id: ScreenRgb + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_rgb + + +- type: marking + speciesRestriction: [IPC] + id: ScreenGlider + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_glider + + +- type: marking + speciesRestriction: [IPC] + id: ScreenRainbowhoriz + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_rainbowhoriz + + +- type: marking + speciesRestriction: [IPC] + id: ScreenBsod + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_bsod + + +- type: marking + speciesRestriction: [IPC] + id: ScreenRedtext + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_redtext + + +- type: marking + speciesRestriction: [IPC] + id: ScreenSinewave + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_sinewave + + +- type: marking + speciesRestriction: [IPC] + id: ScreenSquarewave + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_squarewave + + +- type: marking + speciesRestriction: [IPC] + id: ScreenEcgwave + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_ecgwave + + +- type: marking + speciesRestriction: [IPC] + id: ScreenEyes + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eyes + + +- type: marking + speciesRestriction: [IPC] + id: ScreenEyestall + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eyestall + + +- type: marking + speciesRestriction: [IPC] + id: ScreenEyesangry + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_eyesangry + + +- type: marking + speciesRestriction: [IPC] + id: ScreenLoading + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_loading + + +- type: marking + speciesRestriction: [IPC] + id: ScreenWindowsxp + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_windowsxp + + +- type: marking + speciesRestriction: [IPC] + id: ScreenTetris + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_tetris + + +- type: marking + speciesRestriction: [IPC] + id: ScreenTv + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_tv + + +- type: marking + speciesRestriction: [IPC] + id: ScreenTextdrop + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_textdrop + + +- type: marking + speciesRestriction: [IPC] + id: ScreenStars + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_stars + + +- type: marking + speciesRestriction: [IPC] + id: ScreenRainbowdiag + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_rainbowdiag + + +- type: marking + speciesRestriction: [IPC] + id: ScreenBlank + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_blank + + +- type: marking + speciesRestriction: [IPC] + id: ScreenSmile + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_smile + +- type: marking + speciesRestriction: [IPC] + id: ScreenFrown + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_frown + + +- type: marking + speciesRestriction: [IPC] + id: ScreenRing + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_ring + + +- type: marking + speciesRestriction: [IPC] + id: ScreenL + bodyPart: HeadSide + markingCategory: HeadSide + sprites: + - sprite: _EE/Mobs/Customization/ipc_screens.rsi + state: ipc_screen_l \ No newline at end of file diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/shellguard.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/shellguard.yml new file mode 100644 index 00000000000..26bb00052bf --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/shellguard.yml @@ -0,0 +1,125 @@ +- type: marking + id: CyberLimbsMarkingShellguardHead + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_monitor.rsi + state: head-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_monitor.rsi + state: head-2 + +- type: marking + id: CyberLimbsMarkingShellguardHeadAlt + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_alt1.rsi + state: head-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_alt1.rsi + state: head-2 + +- type: marking + id: CyberLimbsMarkingShellguardChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: torso-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: torso-2 + +- type: marking + id: CyberLimbsMarkingShellguardLArm + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_arm-2 + +- type: marking + id: CyberLimbsMarkingShellguardLHand + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_hand-2 + +- type: marking + id: CyberLimbsMarkingShellguardLLeg + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_leg-2 + + +- type: marking + id: CyberLimbsMarkingShellguardLFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: l_foot-2 + + + +- type: marking + id: CyberLimbsMarkingShellguardRArm + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_arm-2 + + +- type: marking + id: CyberLimbsMarkingShellguardRHand + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_hand-2 + +- type: marking + id: CyberLimbsMarkingShellguardRLeg + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_leg-2 + + +- type: marking + id: CyberLimbsMarkingShellguardRFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/shellguard/shellguard_main.rsi + state: r_foot-2 diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/wardtakahashi.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/wardtakahashi.yml new file mode 100644 index 00000000000..85c68714ae1 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/wardtakahashi.yml @@ -0,0 +1,112 @@ +- type: marking + id: CyberLimbsMarkingWardtakahashiHead + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_monitor.rsi + state: head + +- type: marking + id: CyberLimbsMarkingWardtakahashiHeadAlt + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: head + +- type: marking + id: CyberLimbsMarkingWardtakahashiHeadAlt1 + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_alt1.rsi + state: head + +- type: marking + id: CyberLimbsMarkingWardtakahashiChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: torso + +- type: marking + id: CyberLimbsMarkingWardtakahashiLArm + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: l_arm + +- type: marking + id: CyberLimbsMarkingWardtakahashiLHand + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: l_hand + +- type: marking + id: CyberLimbsMarkingWardtakahashiLLeg + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: l_leg + + +- type: marking + id: CyberLimbsMarkingWardtakahashiLFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: l_foot + + + +- type: marking + id: CyberLimbsMarkingWardtakahashiRArm + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: r_arm + + +- type: marking + id: CyberLimbsMarkingWardtakahashiRHand + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: r_hand + +- type: marking + id: CyberLimbsMarkingWardtakahashiRLeg + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: r_leg + + +- type: marking + id: CyberLimbsMarkingWardtakahashiRFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/wardtakahashi/wardtakahashi_main.rsi + state: r_foot diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/xion.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/xion.yml new file mode 100644 index 00000000000..7b8d0394d5d --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/xion.yml @@ -0,0 +1,126 @@ +- type: marking + id: CyberLimbsMarkingXionHead + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_monitor.rsi + state: head-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_monitor.rsi + state: head-2 + +- type: marking + id: CyberLimbsMarkingXionHeadAlt + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_alt1.rsi + state: head-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_alt1.rsi + state: head-2 + +- type: marking + id: CyberLimbsMarkingXionChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: torso-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: torso-2 + +- type: marking + id: CyberLimbsMarkingXionLArm + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_arm-2 + +- type: marking + id: CyberLimbsMarkingXionLHand + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_hand-2 + +- type: marking + id: CyberLimbsMarkingXionLLeg + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_leg-2 + + +- type: marking + id: CyberLimbsMarkingXionLFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: l_foot-2 + + + +- type: marking + id: CyberLimbsMarkingXionRArm + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_arm-2 + + + +- type: marking + id: CyberLimbsMarkingXionRHand + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_hand-2 + +- type: marking + id: CyberLimbsMarkingXionRLeg + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_leg-2 + + +- type: marking + id: CyberLimbsMarkingXionRFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/xion/xion_main.rsi + state: r_foot-2 diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Customization/zenghu.yml b/Resources/Prototypes/_EE/Entities/Mobs/Customization/zenghu.yml new file mode 100644 index 00000000000..a0e0f59653c --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Customization/zenghu.yml @@ -0,0 +1,115 @@ +- type: marking + id: CyberLimbsMarkingZenghuHead + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: head-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: head-2 + +- type: marking + id: CyberLimbsMarkingZenghuChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: torso-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: torso-2 + +- type: marking + id: CyberLimbsMarkingZenghuLArm + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_arm-2 + +- type: marking + id: CyberLimbsMarkingZenghuLHand + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_hand-2 + +- type: marking + id: CyberLimbsMarkingZenghuLLeg + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_leg-2 + + +- type: marking + id: CyberLimbsMarkingZenghuLFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: l_foot-2 + + + +- type: marking + id: CyberLimbsMarkingZenghuRArm + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_arm-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_arm-2 + + + +- type: marking + id: CyberLimbsMarkingZenghuRHand + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_hand-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_hand-2 + +- type: marking + id: CyberLimbsMarkingZenghuRLeg + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_leg-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_leg-2 + + +- type: marking + id: CyberLimbsMarkingZenghuRFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_foot-1 + - sprite: _Shitmed/Mobs/Species/Cybernetics/zenghu/zenghu_main.rsi + state: r_foot-2 diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Player/ipc.yml b/Resources/Prototypes/_EE/Entities/Mobs/Player/ipc.yml new file mode 100644 index 00000000000..5215fac5179 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Player/ipc.yml @@ -0,0 +1,116 @@ +- type: entity + id: MobIPC + parent: PlayerSiliconHumanoidBase + name: Urist McPositronic + description: A positronic brain in a metal body. + components: + - type: PowerCellSlot + cellSlotId: cell_slot + fitsInCharger: true + - type: ItemSlots + slots: + cell_slot: + locked: true + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium + - type: BatterySlotRequiresLock + itemSlot: cell_slot + - type: EncryptionHolderRequiresLock + - type: SiliconEmitSoundOnDrained + sound: "/Audio/Weapons/Guns/EmptyAlarm/smg_empty_alarm.ogg" # SOMEONE PLEASE FIND A BETTER SOUND FOR THIS. + minInterval: 15 + maxInterval: 30 + popUp: "silicon-power-low" + - type: Lock + locked: true + lockOnClick: false + unlockOnClick: false + lockTime: 5 + unlockTime: 5 + - type: InteractionPopup + successChance: 1 + interactSuccessString: hugging-success-generic + interactSuccessSound: /Audio/Effects/thudswoosh.ogg + messagePerceivedByOthers: hugging-success-generic-others + - type: NpcFactionMember + factions: + - NanoTrasen + - type: StandingState + - type: MobState + allowedStates: + - Alive + - Critical + - Dead + - type: MobThresholds + thresholds: + 0: Alive + 119.999: Critical # TO make it almost impossible + 120: Dead + stateAlertDict: + Alive: BorgHealth + Critical: BorgCrit + Dead: BorgDead + - 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: GuideHelp + guides: + - IPC + - type: Silicon + entityType: enum.SiliconType.Player + batteryPowered: true + drainPerSecond: 1.5 + chargeThresholdMid: 0.80 + chargeThresholdLow: 0.35 + chargeThresholdCritical: 0.10 + speedModifierThresholds: + 4: 1 + 3: 1 + 2: 0.80 + 1: 0.45 + 0: 0.00 + - type: BatteryDrinker + - type: EncryptionKeyHolder + keySlots: 4 + examineWhileLocked: false + keysExtractionMethod: Cutting + keysUnlocked: false + - type: ActiveRadio + - type: IntrinsicRadioReceiver + - type: IntrinsicRadioTransmitter + - type: DeadStartupButton + sound: + path: /Audio/_EE/Effects/Silicon/startup.ogg +# Erro de linter +# - type: Wires +# layoutId: IPC + - type: EmitBuzzWhileDamaged + - type: CanHostGuardian + - type: WeldingHealable + +- type: entity + save: false + name: Urist McPositronic + parent: MobHumanDummy + id: MobIPCDummy + description: A dummy IPC meant to be used in character setup. + components: + - type: HumanoidAppearance + species: IPC + - type: Inventory + templateId: ipc \ No newline at end of file diff --git a/Resources/Prototypes/_EE/Entities/Mobs/Player/silicon_base.yml b/Resources/Prototypes/_EE/Entities/Mobs/Player/silicon_base.yml new file mode 100644 index 00000000000..89b3ae2c09b --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Mobs/Player/silicon_base.yml @@ -0,0 +1,313 @@ +- type: entity + save: false + id: PlayerSiliconHumanoidBase + parent: [BaseMob, MobDamageable, MobCombat, MobAtmosExposed, MobFlammable] + abstract: true + components: + - type: ContentEye + - type: CameraRecoil + - type: Reactive + groups: + Flammable: [Touch] + Extinguish: [Touch] + Acidic: [Touch] + reactions: + - reagents: [Water, SpaceCleaner] + methods: [Touch] + effects: + - !type:WashCreamPieReaction + - type: DamageOnHighSpeedImpact + damage: + types: + Blunt: 10 + soundHit: + path: /Audio/Effects/hit_kick.ogg + - type: Damageable + damageContainer: Silicon + damageModifierSet: IPC + - type: InteractionOutline + - type: MovementSpeedModifier + baseWalkSpeed: 4 + baseSprintSpeed: 3 + - type: ZombieImmune + - type: DoAfter + - type: RotationVisuals + horizontalRotation: 90 + - type: Examiner + # - type: Recyclable + # safe: false + # - type: EyeProtection # You'll want this if your robot can't wear glasses, like an IPC. + # protectionTime: 12 + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.35 + density: 185 + restitution: 0.0 + mask: + - MobMask + layer: + - MobLayer + - 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: Temperature + heatDamageThreshold: 1800 # GoobStation: Roughly the melting point of mild steels + coldDamageThreshold: 260 + currentTemperature: 310.15 + specificHeat: 42 + coldDamage: + types: + Cold: 0.1 #per second, scales with temperature & other constants + heatDamage: + types: + Heat: 3 #per second, scales with temperature & other constants + atmosTemperatureTransferEfficiency: 0.05 + - type: KillOnOverheat # GoobStation + - type: Deathgasp + prototype: SiliconDeathgasp + needsCritical: false + - 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: _Shitmed/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: ["clownedon"] # Dynamically generated + sprite: "Effects/creampie.rsi" + state: "creampie_human" + visible: false + #- type: Bloodstream This is left commented out because it's not necessary for a robot, but you may want it. + # damageBleedModifiers: BloodlossIPC + # bloodReagent: Oil + # 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 # GoobStation: Replaced fire damage with overheating shutdown + # - 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: Identity + # soundHit: + # path: /Audio/Effects/metalbreak.ogg + - 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: Cuffable + - type: AnimationPlayer + - type: Buckle + - type: CreamPied + - type: Stripping + - type: Strippable + - type: UserInterface + interfaces: + enum.VoiceMaskUIKey.Key: + type: VoiceMaskBoundUserInterface + enum.HumanoidMarkingModifierKey.Key: + type: HumanoidMarkingModifierBoundUserInterface + enum.StrippingUiKey.Key: + type: StrippableBoundUserInterface + enum.SurgeryUIKey.Key: # Shitmed + type: SurgeryBui + - type: Emoting + - type: Grammar + attributes: + proper: true + - type: Climbing + - type: StandingState + - type: MindContainer + showExamineInfo: true + - type: SSDIndicator + - 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 + wilhelm: "/Audio/_EE/Voice/IPC/wilhelm.ogg" + sounds: + Male: UnisexIPC + Female: UnisexIPC + Unsexed: UnisexIPC + - 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: BodyEmotes + soundsId: GeneralBodyEmotes + - type: DamageVisuals + thresholds: [ 10, 20, 30, 50, 70, 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" + # 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 + - type: FireVisuals + alternateState: Standing + - type: LightningTarget + priority: 1 + lightningExplode: false + - type: ComplexInteraction + - type: FootPrints + - type: Carriable + - type: Targeting + - type: SurgeryTarget + - type: LayingDown diff --git a/Resources/Prototypes/_EE/InventoryTemplates/ipc_inventory_template.yml b/Resources/Prototypes/_EE/InventoryTemplates/ipc_inventory_template.yml new file mode 100644 index 00000000000..a5a79df96e6 --- /dev/null +++ b/Resources/Prototypes/_EE/InventoryTemplates/ipc_inventory_template.yml @@ -0,0 +1,143 @@ +- type: inventoryTemplate + id: ipc + slots: + - name: shoes + slotTexture: shoes + slotFlags: FEET + stripTime: 3 + uiWindowPos: 1,0 + strippingWindowPos: 1,3 + displayName: Shoes + - name: jumpsuit + slotTexture: uniform + slotFlags: INNERCLOTHING + stripTime: 6 + uiWindowPos: 0,1 + strippingWindowPos: 0,2 + displayName: Jumpsuit + - name: outerClothing + slotTexture: suit + slotFlags: OUTERCLOTHING + stripTime: 6 + uiWindowPos: 1,1 + 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,1 + strippingWindowPos: 2,0 + displayName: Gloves + - name: neck + slotTexture: neck + slotFlags: NECK + uiWindowPos: 0,2 + strippingWindowPos: 0,1 + displayName: Neck + - name: mask + uiWindowPos: 1,2 + slotTexture: mask + slotFlags: MASK + strippingWindowPos: 1,1 + displayName: Mask + whitelist: + components: + - IdentityBlocker + tags: + - IPCMaskWearable + - 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,3 + strippingWindowPos: 1,0 + displayName: Head + - 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 + slotGroup: MainHotbar + 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 \ No newline at end of file diff --git a/Resources/Prototypes/_EE/SoundCollections/buzzes.yml b/Resources/Prototypes/_EE/SoundCollections/buzzes.yml new file mode 100644 index 00000000000..1d66f186406 --- /dev/null +++ b/Resources/Prototypes/_EE/SoundCollections/buzzes.yml @@ -0,0 +1,12 @@ +- type: soundCollection + id: buzzes + files: + - /Audio/_EE/Effects/Buzzes/buzz1.ogg + - /Audio/_EE/Effects/Buzzes/buzz2.ogg + - /Audio/_EE/Effects/Buzzes/buzz3.ogg + - /Audio/_EE/Effects/Buzzes/buzz4.ogg + - /Audio/_EE/Effects/Buzzes/buzz5.ogg + - /Audio/_EE/Effects/Buzzes/buzz6.ogg + - /Audio/_EE/Effects/Buzzes/buzz7.ogg + - /Audio/_EE/Effects/Buzzes/buzz8.ogg + - /Audio/_EE/Effects/Buzzes/buzz9.ogg diff --git a/Resources/Prototypes/_EE/SoundCollections/emotes.yml b/Resources/Prototypes/_EE/SoundCollections/emotes.yml new file mode 100644 index 00000000000..1c934c2a2da --- /dev/null +++ b/Resources/Prototypes/_EE/SoundCollections/emotes.yml @@ -0,0 +1,6 @@ +- type: soundCollection + id: IPCWhirrs + files: + - /Audio/_EE/Voice/IPC/whirr1.ogg + - /Audio/_EE/Voice/IPC/whirr2.ogg + - /Audio/_EE/Voice/IPC/whirr3.ogg diff --git a/Resources/Prototypes/_EE/Species/ipc.yml b/Resources/Prototypes/_EE/Species/ipc.yml new file mode 100644 index 00000000000..e99f22d40de --- /dev/null +++ b/Resources/Prototypes/_EE/Species/ipc.yml @@ -0,0 +1,238 @@ +- type: species + id: IPC + name: species-name-ipc + roundStart: true + prototype: MobIPC + sprites: MobIPCSprites + markingLimits: MobIPCMarkingLimits + dollPrototype: MobIPCDummy + skinColoration: Hues + 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 + HeadTop: MobHumanoidAnyMarking + HeadSide: MobHumanoidAnyMarking + Tail: MobHumanoidAnyMarking + Hair: MobHumanoidMarkingMatchSkin + Chest: MobIPCTorso + LArm: MobIPCLArm + RArm: MobIPCRArm + LHand: MobIPCLHand + RHand: MobIPCRHand + LLeg: MobIPCLLeg + RLeg: MobIPCRLeg + LFoot: MobIPCLFoot + RFoot: MobIPCRFoot + +- type: markingPoints + id: MobIPCMarkingLimits + points: + Head: + points: 1 + required: true + defaultMarkings: [ MobIPCHeadDefault ] + Chest: + points: 1 + required: true + defaultMarkings: [ MobIPCTorsoDefault ] + Legs: + points: 4 + required: true + defaultMarkings: [ MobIPCLLegDefault, MobIPCLFootDefault, MobIPCRLegDefault, MobIPCRFootDefault ] + Arms: + points: 4 + required: true + defaultMarkings: [ MobIPCLArmDefault, MobIPCLHandDefault, MobIPCRArmDefault, MobIPCRHandDefault ] + HeadSide: + points: 1 + required: false + +- type: humanoidBaseSprite + id: MobIPCMarkingFollowSkin + markingsMatchSkin: true + layerAlpha: 0.5 + +- type: humanoidBaseSprite + id: MobIPCScreen + +# Head + +- type: humanoidBaseSprite + id: MobIPCHead + +- type: humanoidBaseSprite + id: MobIPCHeadMale + +- type: humanoidBaseSprite + id: MobIPCHeadFemale + +- type: marking + id: MobIPCHeadDefault + bodyPart: Head + markingCategory: Head + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: head_m + +# Torso + +- type: humanoidBaseSprite + id: MobIPCTorso + +- type: humanoidBaseSprite + id: MobIPCTorsoMale + +- type: humanoidBaseSprite + id: MobIPCTorsoFemale + +- type: marking + id: MobIPCTorsoDefault + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: torso_m + +- type: marking + id: MobIPCTorsoFemaleDefault + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: torso_f + +# Left Leg + +- type: humanoidBaseSprite + id: MobIPCLLeg + +- type: marking + id: MobIPCLLegDefault + bodyPart: LLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: l_leg + +# Left Arm + +- type: humanoidBaseSprite + id: MobIPCLArm + +- type: marking + id: MobIPCLArmDefault + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: l_arm + +#LHand + +- type: humanoidBaseSprite + id: MobIPCLHand + +- type: marking + id: MobIPCLHandDefault + bodyPart: LHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: l_hand + +#LFoot + +- type: humanoidBaseSprite + id: MobIPCLFoot + +- type: marking + id: MobIPCLFootDefault + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: l_foot + +#RLeg + +- type: humanoidBaseSprite + id: MobIPCRLeg + +- type: marking + id: MobIPCRLegDefault + bodyPart: RLeg + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: r_leg + +#RArm + +- type: humanoidBaseSprite + id: MobIPCRArm + +- type: marking + id: MobIPCRArmDefault + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: r_arm + +#RHand + +- type: humanoidBaseSprite + id: MobIPCRHand + +- type: marking + id: MobIPCRHandDefault + bodyPart: RHand + markingCategory: Arms + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: r_hand + +#RFoot + +- type: humanoidBaseSprite + id: MobIPCRFoot + +- type: marking + id: MobIPCRFootDefault + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [IPC] + sprites: + - sprite: _Shitmed/Mobs/Species/IPC/parts.rsi + state: r_foot + +- type: Tag + id: IPCMaskWearable diff --git a/Resources/Prototypes/_EE/Voice/speech_emote_sounds.yml b/Resources/Prototypes/_EE/Voice/speech_emote_sounds.yml new file mode 100644 index 00000000000..7bf9d533d10 --- /dev/null +++ b/Resources/Prototypes/_EE/Voice/speech_emote_sounds.yml @@ -0,0 +1,67 @@ +- type: emoteSounds + id: UnisexIPC + params: + variation: 0 + sounds: + Scream: + path: /Audio/_EE/Voice/IPC/robot-scream.ogg + params: + variation: 0.125 + Laugh: + path: /Audio/_EE/Voice/IPC/robot-laugh_3.ogg + params: + variation: 0.125 + Chitter: + path: /Audio/Voice/Talk/pai.ogg + Squeak: + path: /Audio/Voice/Talk/pai.ogg + CatMeow: + collection: CatMeows + params: + variation: 0.125 + CatHisses: + collection: CatHisses + params: + variation: 0.125 + MonkeyScreeches: + collection: MonkeyScreeches + params: + variation: 0.125 + Sigh: + path: /Audio/Voice/Talk/pai.ogg + params: + variation: 0.125 + Crying: + path: /Audio/_EE/Voice/IPC/cry_robot_1.ogg + params: + variation: 0.125 + Whistle: + path: /Audio/_EE/Voice/IPC/pai_whistle.ogg + params: + variation: 0.125 + RobotBeep: # disease + path: /Audio/Effects/tesla_consume.ogg + params: + variation: 0.125 + Beep: # normal + path: /Audio/_EE/Voice/IPC/beep_2000.ogg + Boop: + path: /Audio/_EE/Voice/IPC/beep_500.ogg + Buzz: + path: /Audio/Machines/buzz-sigh.ogg + Honk: + path: /Audio/Items/bikehorn.ogg + params: + variation: 0.125 + Chime: + path: /Audio/Effects/Cargo/ping.ogg + Buzz-Two: + path: /Audio/Machines/buzz-two.ogg + Ping: + path: /Audio/Effects/beep1.ogg + params: # to prevent it from being definitively read by players as "OH SHIT A GRENADE" + variation: 0.125 + Whirr: + collection: IPCWhirrs + params: + variation: 0 \ No newline at end of file diff --git a/Resources/Prototypes/_EE/Voice/speech_emotes.yml b/Resources/Prototypes/_EE/Voice/speech_emotes.yml new file mode 100644 index 00000000000..a499cc071a9 --- /dev/null +++ b/Resources/Prototypes/_EE/Voice/speech_emotes.yml @@ -0,0 +1,22 @@ +- type: emote + id: SiliconDeathgasp + name: chat-emote-name-deathgasp + icon: Interface/Emotes/deathgasp.png + chatMessages: ["chat-emote-msg-deathgasp-silicon"] + chatTriggers: + - sdeathgasp + +- type: emote + id: Boop + name: chat-emote-name-boop + category: Vocal + chatMessages: [ boops ] + chatTriggers: + - boops + +- type: emote + id: Whirr # uncategorized as it is generic + name: chat-emote-name-whirr + chatMessages: [ whirrs ] + chatTriggers: + - whirrs \ No newline at end of file diff --git a/Resources/Prototypes/_Shitmed/Body/Organs/cybernetic.yml b/Resources/Prototypes/_Shitmed/Body/Organs/cybernetic.yml index 514920257c1..efef0d113f7 100644 --- a/Resources/Prototypes/_Shitmed/Body/Organs/cybernetic.yml +++ b/Resources/Prototypes/_Shitmed/Body/Organs/cybernetic.yml @@ -48,4 +48,4 @@ - Biological - type: ShowHealthIcons damageContainers: - - Biological \ No newline at end of file + - Biological diff --git a/Resources/Prototypes/_Shitmed/Recipes/Lathes/robotics.yml b/Resources/Prototypes/_Shitmed/Recipes/Lathes/robotics.yml index 66b21379f0a..d3b20d56b0e 100644 --- a/Resources/Prototypes/_Shitmed/Recipes/Lathes/robotics.yml +++ b/Resources/Prototypes/_Shitmed/Recipes/Lathes/robotics.yml @@ -77,4 +77,90 @@ Glass: 500 Plastic: 500 Gold: 300 - Silver: 300 \ No newline at end of file + Silver: 300 + +- type: latheRecipe + abstract: true + parent: BaseRoboticsRecipe + id: BaseIPCLimbRecipe + materials: + Steel: 250 + Plastic: 100 + Glass: 250 + +- type: latheRecipe + abstract: true + parent: BaseRoboticsRecipe + id: BaseIPCOrganRecipe + materials: + Steel: 250 + Plasma: 100 + Plastic: 100 + +- type: latheRecipe + parent: BaseRoboticsRecipe + id: TorsoIPC + result: TorsoIPC + completetime: 3 + materials: + Steel: 3000 + Gold: 500 + Plastic: 500 + Plasma: 500 + +# Generic + +- type: latheRecipe + parent: BaseIPCLimbRecipe + id: LeftArmIPC + result: LeftArmIPC + +- type: latheRecipe + parent: BaseIPCLimbRecipe + id: RightArmIPC + result: RightArmIPC + +- type: latheRecipe + parent: BaseIPCLimbRecipe + id: LeftHandIPC + result: LeftHandIPC + +- type: latheRecipe + parent: BaseIPCLimbRecipe + id: RightHandIPC + result: RightHandIPC + +- type: latheRecipe + parent: BaseBorgLimbRecipe + id: LeftLegIPC + result: LeftLegIPC + +- type: latheRecipe + parent: BaseBorgLimbRecipe + id: RightLegIPC + result: RightLegIPC + +- type: latheRecipe + parent: BaseIPCLimbRecipe + id: LeftFootIPC + result: LeftFootIPC + +- type: latheRecipe + parent: BaseIPCLimbRecipe + id: RightFootIPC + result: RightFootIPC + +- type: latheRecipe + parent: BaseIPCLimbRecipe + id: HeadIPC + result: HeadIPC + +- type: latheRecipe + parent: BaseIPCOrganRecipe + id: OrganIPCEyes + result: OrganIPCEyes + +- type: latheRecipe + parent: BaseIPCOrganRecipe + id: OrganIPCPump + result: OrganIPCPump diff --git a/Resources/Prototypes/_Shitmed/Species/cybernetics.yml b/Resources/Prototypes/_Shitmed/Species/cybernetics.yml index 4b945e40895..e0143a220c4 100644 --- a/Resources/Prototypes/_Shitmed/Species/cybernetics.yml +++ b/Resources/Prototypes/_Shitmed/Species/cybernetics.yml @@ -44,4 +44,4 @@ id: MobCyberneticBishopRFoot baseSprite: sprite: _Shitmed/Mobs/Species/Cybernetics/bishop/bishop_main.rsi - state: "r_foot" \ No newline at end of file + state: "r_foot" diff --git a/Resources/ServerInfo/Guidebook/Mobs/IPCs.xml b/Resources/ServerInfo/Guidebook/Mobs/IPCs.xml new file mode 100644 index 00000000000..7bdd75900fd --- /dev/null +++ b/Resources/ServerInfo/Guidebook/Mobs/IPCs.xml @@ -0,0 +1,51 @@ + + # I.P.C. + + An IPC (short for Integrated Positronic Chassis) is a type of sentient robot and is considered an [color=yellow]independent individual[/color], meaning [color=red]they are not guided by any laws of robotics[/color]. IPCs cannot be hacked by Emags because they do not have to follow any predefined directives in their system. [color=red]IPCs are silicon-based beings, so doctors do not have the skills to repair them.[/color] + + + + + Like borgs, IPCs have a positronic brain as their processing source. However, unlike them, IPCs can't be assembled. "It's cheaper to create a shell that obeys you than one that doesn't! *wink*" + ## Recharging an IPC + + + + + + IPCs can be recharged in three different ways: + + APC Terminal: IPCs can use APC terminals to recharge. Press [color=yellow]Alt + left click[/color] on a terminal as many times as needed to fully recharge. + + Borg Rechargers: IPCs can use borg rechargers to recharge. Always prioritize the ones outside of the Sci area to avoid headaches. + + Power Cell: IPCs have an internal power cell that serves as their battery. They can simply swap it out by opening the hatch and manually replacing it. + + ## Integrated Radio + + + + + IPCs do [bold]not[/bold] use external radios because they already have one built in. They only need to get an encryption key from a radio. By clicking on an IPC with a [color=yellow]wire cutter[/color], you can remove their keys. + You can find new keys around the station or remove one from a sector radio using a [color=yellow]screwdriver[/color]. + + ## Repairing + + + Welders can be used to repair [color=yellow]Brute[/color] damage. + + + + Cables can be used to repair [color=yellow]Burns[/color]. + + + + Glass Sheets can be used to repair [color=yellow]Blindness[/color]. + + + In the event an IPC dies, after being fully repaired, it should be restarted using the [color=yellow]"Restart"[/color] button (located by right-clicking). + + [color=red]NEVER ELECTROCUTE AN IPC with a defibrillator or in any other way while it is dead, as this will cause the battery to discharge energy rays outward![/color] + + + \ No newline at end of file diff --git a/Resources/ServerInfo/Guidebook/Mobs/Species.xml b/Resources/ServerInfo/Guidebook/Mobs/Species.xml index 08bff6a62e0..71a7c8b52e2 100644 --- a/Resources/ServerInfo/Guidebook/Mobs/Species.xml +++ b/Resources/ServerInfo/Guidebook/Mobs/Species.xml @@ -14,6 +14,7 @@ + # Delta-V specific species diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_antlers.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_antlers.png new file mode 100644 index 00000000000..125f9cf913e Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_antlers.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_crowned.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_crowned.png new file mode 100644 index 00000000000..2fd0cdd06d2 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_crowned.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_cyberhead.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_cyberhead.png new file mode 100644 index 00000000000..c3d1111199e Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_cyberhead.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_droneeyes.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_droneeyes.png new file mode 100644 index 00000000000..5b2a67a813a Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_droneeyes.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_light.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_light.png new file mode 100644 index 00000000000..91f5fd25e78 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_light.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_lightb.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_lightb.png new file mode 100644 index 00000000000..bc1133d8d3c Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_lightb.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_sidelights.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_sidelights.png new file mode 100644 index 00000000000..7a1c31e45e4 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_sidelights.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tesla.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tesla.png new file mode 100644 index 00000000000..98cb10d3cbc Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tesla.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_towers.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_towers.png new file mode 100644 index 00000000000..f971130b8e4 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_towers.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tv.png b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tv.png new file mode 100644 index 00000000000..ae53b4762ed Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/ipc_antenna_tv.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/meta.json b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/meta.json new file mode 100644 index 00000000000..69316d7e57c --- /dev/null +++ b/Resources/Textures/_EE/Mobs/Customization/ipc_antenna.rsi/meta.json @@ -0,0 +1,107 @@ +{ + "version": 1, + "license": "CC-BY-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 + } + ] +} diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_blank.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_blank.png new file mode 100644 index 00000000000..4361a36c1ed Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_blank.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_blue.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_blue.png new file mode 100644 index 00000000000..f1568848807 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_blue.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_breakout.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_breakout.png new file mode 100644 index 00000000000..54a282bd95c Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_breakout.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_bsod.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_bsod.png new file mode 100644 index 00000000000..7d7a8efb62e Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_bsod.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_console.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_console.png new file mode 100644 index 00000000000..dfed44e10cd Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_console.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_ecgwave.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_ecgwave.png new file mode 100644 index 00000000000..2d2c405734d Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_ecgwave.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eight.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eight.png new file mode 100644 index 00000000000..8421ae30bd9 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eight.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_exclaim.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_exclaim.png new file mode 100644 index 00000000000..e280615e504 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_exclaim.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyes.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyes.png new file mode 100644 index 00000000000..42ee79361b1 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyes.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyesangry.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyesangry.png new file mode 100644 index 00000000000..8a7e45c7e8f Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyesangry.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyestall.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyestall.png new file mode 100644 index 00000000000..d8c03fa3240 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_eyestall.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_frown.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_frown.png new file mode 100644 index 00000000000..f297c401a10 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_frown.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_glider.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_glider.png new file mode 100644 index 00000000000..afd5349ee6b Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_glider.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_goggles.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_goggles.png new file mode 100644 index 00000000000..422a603cc7c Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_goggles.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_heart.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_heart.png new file mode 100644 index 00000000000..77578d774ed Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_heart.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_l.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_l.png new file mode 100644 index 00000000000..902845f11fc Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_l.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_loading.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_loading.png new file mode 100644 index 00000000000..9a1f705a0d7 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_loading.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_monoeye.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_monoeye.png new file mode 100644 index 00000000000..4e5056528d9 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_monoeye.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_nature.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_nature.png new file mode 100644 index 00000000000..6425fe2b517 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_nature.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_orange.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_orange.png new file mode 100644 index 00000000000..f4c98278e1d Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_orange.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_pink.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_pink.png new file mode 100644 index 00000000000..dc50eb693db Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_pink.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_question.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_question.png new file mode 100644 index 00000000000..f90dcc94abb Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_question.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowdiag.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowdiag.png new file mode 100644 index 00000000000..37274191d37 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowdiag.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowhoriz.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowhoriz.png new file mode 100644 index 00000000000..9b6192dd6dc Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rainbowhoriz.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_redtext.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_redtext.png new file mode 100644 index 00000000000..c180b8e674e Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_redtext.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rgb.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rgb.png new file mode 100644 index 00000000000..36f48e75d7a Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_rgb.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_ring.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_ring.png new file mode 100644 index 00000000000..e5454221602 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_ring.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_scroll.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_scroll.png new file mode 100644 index 00000000000..cbf936810a1 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_scroll.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_shower.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_shower.png new file mode 100644 index 00000000000..1546c8dbf13 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_shower.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_sinewave.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_sinewave.png new file mode 100644 index 00000000000..c976f421791 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_sinewave.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_smile.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_smile.png new file mode 100644 index 00000000000..7ecd324e898 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_smile.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_squarewave.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_squarewave.png new file mode 100644 index 00000000000..04211f366e8 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_squarewave.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_stars.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_stars.png new file mode 100644 index 00000000000..8feda85c428 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_stars.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_static.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_static.png new file mode 100644 index 00000000000..08e96db1508 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_static.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_tetris.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_tetris.png new file mode 100644 index 00000000000..d4ea13ea39b Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_tetris.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_textdrop.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_textdrop.png new file mode 100644 index 00000000000..c71ba6d24e9 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_textdrop.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_tv.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_tv.png new file mode 100644 index 00000000000..5b9b25dcd9a Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_tv.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_windowsxp.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_windowsxp.png new file mode 100644 index 00000000000..595ab8444b2 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_windowsxp.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_yellow.png b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_yellow.png new file mode 100644 index 00000000000..bbf4c92cb32 Binary files /dev/null and b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/ipc_screen_yellow.png differ diff --git a/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/meta.json b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/meta.json new file mode 100644 index 00000000000..b6314cde9c2 --- /dev/null +++ b/Resources/Textures/_EE/Mobs/Customization/ipc_screens.rsi/meta.json @@ -0,0 +1,1363 @@ +{ + "version": 1, + "license": "CC-BY-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 + } + ] +}