diff --git a/Content.Client/ADT/_RMC14/Stealth/EntityInvisibilityVisualsSystem.cs b/Content.Client/ADT/_RMC14/Stealth/EntityInvisibilityVisualsSystem.cs new file mode 100644 index 00000000000..e0a5ae361b4 --- /dev/null +++ b/Content.Client/ADT/_RMC14/Stealth/EntityInvisibilityVisualsSystem.cs @@ -0,0 +1,48 @@ +using Content.Shared._RMC14.Stealth; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Shared.Prototypes; + +namespace Content.Client._RMC14.Stealth; + +public sealed class EntityInvisibilityVisualsSystem : EntitySystem +{ + [Dependency] private readonly IPrototypeManager _prototypes = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnShutdown); + } + + private void OnStartup(Entity ent, ref ComponentStartup args) + { + if (!TryComp(ent, out SpriteComponent? sprite)) + return; + + sprite.PostShader = _prototypes.Index("RMCInvisible").InstanceUnique(); + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + if (TerminatingOrDeleted(ent)) + return; + + if (!TryComp(ent, out SpriteComponent? sprite)) + return; + + sprite.PostShader = null; + } + + public override void Update(float frameTime) + { + var invisible = EntityQueryEnumerator(); + while (invisible.MoveNext(out var uid, out var comp, out var sprite)) + { + var opacity = TryComp(uid, out var activeInvisible) ? activeInvisible.Opacity : 1; + sprite.PostShader?.SetParameter("visibility", opacity); + } + } +} diff --git a/Content.Client/StatusIcon/StatusIconSystem.cs b/Content.Client/StatusIcon/StatusIconSystem.cs index 50908dcb339..df0c8a8e853 100644 --- a/Content.Client/StatusIcon/StatusIconSystem.cs +++ b/Content.Client/StatusIcon/StatusIconSystem.cs @@ -7,6 +7,7 @@ using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Configuration; +using Content.Shared._RMC14.Stealth; // ADT Tweak namespace Content.Client.StatusIcon; @@ -85,6 +86,9 @@ public bool IsVisible(Entity ent, StatusIconData data) if (data.HideOnStealth && TryComp(ent, out var stealth) && stealth.Enabled) return false; + if (data.HideOnStealth && HasComp(ent)) // ADT Tweak + return false; + if (data.ShowTo != null && !_entityWhitelist.IsValid(data.ShowTo, viewer)) return false; diff --git a/Content.Server/ADT/Eye/Blinding/Components/NoDamageEyesOnFlashComponent.cs b/Content.Server/ADT/Eye/Blinding/Components/NoDamageEyesOnFlashComponent.cs deleted file mode 100644 index 0ab64d78a06..00000000000 --- a/Content.Server/ADT/Eye/Blinding/Components/NoDamageEyesOnFlashComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Content.Server.ADT.Eye.Blinding; - -[RegisterComponent] -public sealed partial class NoEyeDamageOnFlashComponent : Component -{ -} diff --git a/Content.Server/Flash/FlashSystem.cs b/Content.Server/Flash/FlashSystem.cs index e49af324221..c2a77106978 100644 --- a/Content.Server/Flash/FlashSystem.cs +++ b/Content.Server/Flash/FlashSystem.cs @@ -21,7 +21,7 @@ using Robust.Shared.Audio; using Robust.Shared.Random; using InventoryComponent = Content.Shared.Inventory.InventoryComponent; -using Content.Server.ADT.Eye.Blinding; +using Content.Shared.ADT.Eye.Blinding; namespace Content.Server.Flash { diff --git a/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs index 14a837aab73..a9c703c02a3 100644 --- a/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs @@ -75,7 +75,7 @@ public sealed partial class NukeopsRuleComponent : Component /// Minimal operatives count for war declaration /// [DataField] - public int WarDeclarationMinOps = 4; + public int WarDeclarationMinOps = 3; // adt tweak [DataField] public WinType WinType = WinType.Neutral; diff --git a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.cs b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.cs index 70af8419c38..9099410ef95 100644 --- a/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.cs +++ b/Content.Server/Humanoid/Systems/HumanoidAppearanceSystem.cs @@ -9,6 +9,7 @@ using Content.Shared.Verbs; using Robust.Shared.GameObjects.Components.Localization; using Robust.Shared.Prototypes; // ADT-Changeling-Tweak +using Content.Server.Forensics; // ADT DNA-Cloning Tweak namespace Content.Server.Humanoid; @@ -67,6 +68,12 @@ public void SetAppearance(HumanoidAppearanceComponent sourceHumanoid, HumanoidAp grammar.Gender = sourceHumanoid.Gender; } + if (TryComp(targetHumanoid.Owner, out var targetDNAComp) && + TryComp(sourceHumanoid.Owner, out var sourceDNAComp)) + { + targetDNAComp.DNA = sourceDNAComp.DNA; // ADT DNA-Cloning Tweak + } + Dirty(targetHumanoid.Owner, targetHumanoid); } // ADT-Changeling-Tweak-End diff --git a/Content.Server/ADT/Eye/Blinding/Components/DamageEyesOnFlashedComponent.cs b/Content.Shared/ADT/Eye/Blinding/Components/DamageEyesOnFlashedComponent.cs similarity index 59% rename from Content.Server/ADT/Eye/Blinding/Components/DamageEyesOnFlashedComponent.cs rename to Content.Shared/ADT/Eye/Blinding/Components/DamageEyesOnFlashedComponent.cs index fc22974f66c..a68ea4c1dae 100644 --- a/Content.Server/ADT/Eye/Blinding/Components/DamageEyesOnFlashedComponent.cs +++ b/Content.Shared/ADT/Eye/Blinding/Components/DamageEyesOnFlashedComponent.cs @@ -1,7 +1,8 @@ -namespace Content.Server.ADT.Eye.Blinding; +using Robust.Shared.GameStates; -[RegisterComponent] -[Access(typeof(DamageEyesOnFlashSystem))] +namespace Content.Shared.ADT.Eye.Blinding; + +[RegisterComponent, NetworkedComponent] public sealed partial class DamageEyesOnFlashedComponent : Component { [DataField] diff --git a/Content.Shared/ADT/Eye/Blinding/Components/NoDamageEyesOnFlashComponent.cs b/Content.Shared/ADT/Eye/Blinding/Components/NoDamageEyesOnFlashComponent.cs new file mode 100644 index 00000000000..df983985448 --- /dev/null +++ b/Content.Shared/ADT/Eye/Blinding/Components/NoDamageEyesOnFlashComponent.cs @@ -0,0 +1,8 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.ADT.Eye.Blinding; + +[RegisterComponent, NetworkedComponent] +public sealed partial class NoEyeDamageOnFlashComponent : Component +{ +} diff --git a/Content.Server/ADT/Eye/Blinding/FlashedEvent.cs b/Content.Shared/ADT/Eye/Blinding/FlashedEvent.cs similarity index 65% rename from Content.Server/ADT/Eye/Blinding/FlashedEvent.cs rename to Content.Shared/ADT/Eye/Blinding/FlashedEvent.cs index 370fd34c129..d37bfd30149 100644 --- a/Content.Server/ADT/Eye/Blinding/FlashedEvent.cs +++ b/Content.Shared/ADT/Eye/Blinding/FlashedEvent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.ADT.Eye.Blinding; +namespace Content.Shared.ADT.Eye.Blinding; [ByRefEvent] public record struct FlashedEvent(EntityUid? User, EntityUid? Used); diff --git a/Content.Server/ADT/Eye/Blinding/Systems/DamageEyesOnFlashSystem.cs b/Content.Shared/ADT/Eye/Blinding/Systems/DamageEyesOnFlashSystem.cs similarity index 95% rename from Content.Server/ADT/Eye/Blinding/Systems/DamageEyesOnFlashSystem.cs rename to Content.Shared/ADT/Eye/Blinding/Systems/DamageEyesOnFlashSystem.cs index 7bb4c9570d2..510c73757d3 100644 --- a/Content.Server/ADT/Eye/Blinding/Systems/DamageEyesOnFlashSystem.cs +++ b/Content.Shared/ADT/Eye/Blinding/Systems/DamageEyesOnFlashSystem.cs @@ -1,7 +1,7 @@ using Content.Shared.Eye.Blinding.Systems; using Robust.Shared.Timing; -namespace Content.Server.ADT.Eye.Blinding; +namespace Content.Shared.ADT.Eye.Blinding; public sealed class DamageEyesOnFlashSystem : EntitySystem { diff --git a/Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs b/Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs index 85a7bff3663..6414445397b 100644 --- a/Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs +++ b/Content.Shared/ADT/NightVision/SharedNightVisionSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Rounding; using Content.Shared.Toggleable; using Robust.Shared.Timing; +using Content.Shared.ADT.Eye.Blinding; namespace Content.Shared.ADT.NightVision; @@ -127,10 +128,10 @@ private void UpdateAlert(Entity ent) { if (ent.Comp.Alert is { } alert) { - var level = MathF.Max((int) NightVisionState.Off, (int) ent.Comp.State); + var level = MathF.Max((int)NightVisionState.Off, (int)ent.Comp.State); var max = _alerts.GetMaxSeverity(alert); - var severity = max - ContentHelpers.RoundToLevels(level, (int) NightVisionState.Full, max + 1); - _alerts.ShowAlert(ent, alert, (short) severity); + var severity = max - ContentHelpers.RoundToLevels(level, (int)NightVisionState.Full, max + 1); + _alerts.ShowAlert(ent, alert, (short)severity); } NightVisionChanged(ent); @@ -161,6 +162,9 @@ private void EnableNightVisionItem(Entity item, Entity var nightVision = EnsureComp(user); nightVision.State = NightVisionState.Full; Dirty(user, nightVision); + + var eyeDamage = EnsureComp(user); + Dirty(user, eyeDamage); } _actions.SetToggled(item.Comp.Action, true); @@ -187,6 +191,7 @@ protected void DisableNightVisionItem(Entity item, Ent !nightVision.Innate) { RemCompDeferred(user.Value); + RemCompDeferred(user.Value); } } diff --git a/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakComponent.cs b/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakComponent.cs new file mode 100644 index 00000000000..8f1f0a1221a --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakComponent.cs @@ -0,0 +1,61 @@ +using Content.Shared.Humanoid; +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared._RMC14.Armor.ThermalCloak; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ThermalCloakComponent : Component +{ + public bool Enabled; + + [DataField, AutoNetworkedField] + public TimeSpan Cooldown = TimeSpan.FromSeconds(3); + + [DataField, AutoNetworkedField] + public TimeSpan ForcedCooldown = TimeSpan.FromSeconds(10); + + [DataField, AutoNetworkedField] + public float Opacity = 0.1f; + + [DataField, AutoNetworkedField] + public SoundSpecifier? CloakSound; + + [DataField, AutoNetworkedField] + public SoundSpecifier? UncloakSound; + + [DataField, AutoNetworkedField] + public bool RestrictWeapons; + + /// + /// Layers to hide while cloaked + /// + [DataField] + public HashSet CloakedHideLayers = new(); + + /// + /// Amount of time after uncloaking weapons remain locked + /// + [DataField] + [AutoNetworkedField] + public TimeSpan UncloakWeaponLock = TimeSpan.FromSeconds(1); + + [DataField, AutoNetworkedField] + public EntProtoId ActionId = "ADTActionToggleCloak"; + + [DataField, AutoNetworkedField] + public EntityUid? Action; + + [DataField, AutoNetworkedField] + public EntProtoId CloakEffect = "RMCEffectCloak"; + + [DataField, AutoNetworkedField] + public EntProtoId UncloakEffect = "RMCEffectUncloak"; + + [DataField, AutoNetworkedField] + public bool NinjaSuit = false; + + [DataField, AutoNetworkedField] + public bool HandsBlock = true; +} diff --git a/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakSystem.cs b/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakSystem.cs new file mode 100644 index 00000000000..9d511c6e5de --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakSystem.cs @@ -0,0 +1,269 @@ +using Content.Shared._RMC14.Stealth; +using Content.Shared.Actions; +using Content.Shared.Coordinates; +using Content.Shared.Explosion.Components.OnTrigger; +using Content.Shared.Humanoid; +using Content.Shared.Interaction.Events; +using Content.Shared.Inventory; +using Content.Shared.Inventory.Events; +using Content.Shared.Mobs; +using Content.Shared.Popups; +using Content.Shared.Projectiles; +using Content.Shared.Weapons.Ranged.Components; +using Content.Shared.Weapons.Ranged.Systems; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Network; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; +using Content.Shared.Weapons.Melee; +using Content.Shared.Weapons.Melee.Events; +using Content.Shared.Ninja.Systems; +using Content.Shared.Hands.EntitySystems; + +namespace Content.Shared._RMC14.Armor.ThermalCloak; + +/// +/// Handles Thermal Cloak's cloaking ability +/// +public sealed class ThermalCloakSystem : EntitySystem +{ + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedHumanoidAppearanceSystem _humanoidSystem = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly SharedSpaceNinjaSystem _ninja = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetItemActions); + SubscribeLocalEvent(OnCloakAction); + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnequipped); + + SubscribeLocalEvent(OnMobStateChanged); + + SubscribeLocalEvent(OnAttemptShoot); + SubscribeLocalEvent(OnTimerUse); + SubscribeLocalEvent(OnProjectile); + SubscribeLocalEvent(OnMeleeHit); + } + + private void OnGetItemActions(Entity ent, ref GetItemActionsEvent args) + { + var comp = ent.Comp; + + if (comp.HandsBlock && _hands.IsHolding(ent.Owner, comp.Owner)) + return; + + if (comp.NinjaSuit && _ninja.IsNinja(ent)) + args.AddAction(ref comp.Action, comp.ActionId); + else if (!comp.NinjaSuit) + args.AddAction(ref comp.Action, comp.ActionId); + + Dirty(ent); + } + + private void OnCloakAction(Entity ent, ref ThermalCloakTurnInvisibleActionEvent args) + { + if (args.Handled) + return; + + args.Handled = true; + + SetInvisibility(ent, args.Performer, !ent.Comp.Enabled, false); + } + + private void OnEquipped(Entity ent, ref GotEquippedEvent args) + { + if (_timing.ApplyingState) + return; + + // if (!_inventory.InSlotWithFlags((ent, null, null), SlotFlags.All)) + // return; + + var comp = EnsureComp(args.Equipee); + comp.RestrictWeapons = ent.Comp.RestrictWeapons; + comp.UncloakWeaponLock = ent.Comp.UncloakWeaponLock; + Dirty(args.Equipee, comp); + } + + private void OnUnequipped(Entity ent, ref GotUnequippedEvent args) + { + if (_timing.ApplyingState) + return; + + // if (_inventory.InSlotWithFlags((ent, null, null), SlotFlags.All)) + // return; + + SetInvisibility(ent, args.Equipee, false, false); + RemCompDeferred(args.Equipee); + } + + public void SetInvisibility(Entity ent, EntityUid user, bool enabling, bool forced) + { + if (!TryComp(user, out var turnInvisible)) + return; + + if (enabling && !HasComp(user)) + { + var activeInvisibility = EnsureComp(user); + activeInvisibility.Opacity = ent.Comp.Opacity; + Dirty(user, activeInvisibility); + + ent.Comp.Enabled = true; + turnInvisible.Enabled = true; + if (TryComp(ent.Comp.Action, out var action)) + { + action.Cooldown = (_timing.CurTime, _timing.CurTime + ent.Comp.Cooldown); + action.UseDelay = ent.Comp.Cooldown; + Dirty(ent.Comp.Action.Value, action); + } + + turnInvisible.UncloakTime = _timing.CurTime; // Just in case + + ToggleLayers(user, ent.Comp.CloakedHideLayers, false); + SpawnCloakEffects(user, ent.Comp.CloakEffect); + + var popupOthers = Loc.GetString("rmc-cloak-activate-others", ("user", user)); + _popup.PopupPredicted(Loc.GetString("rmc-cloak-activate-self"), popupOthers, user, user, PopupType.Medium); + + if (_net.IsServer) + _audio.PlayPvs(ent.Comp.CloakSound, user); + + return; + } + + if (!enabling && TryComp(user, out var invisible)) + { + invisible.Opacity = 1; + Dirty(user, invisible); + ent.Comp.Enabled = false; + turnInvisible.Enabled = false; + + if (forced) + { + if (TryComp(ent.Comp.Action, out var action)) + { + action.Cooldown = (_timing.CurTime, _timing.CurTime + ent.Comp.ForcedCooldown); + action.UseDelay = ent.Comp.ForcedCooldown; + Dirty(ent.Comp.Action.Value, action); + } + + turnInvisible.UncloakTime = _timing.CurTime; + + var forcedPopupOthers = Loc.GetString("rmc-cloak-forced-deactivate-others", ("user", user)); + _popup.PopupPredicted(Loc.GetString("rmc-cloak-forced-deactivate-self"), forcedPopupOthers, user, user, PopupType.Medium); + } + else + { + if (TryComp(ent.Comp.Action, out var action)) + { + action.Cooldown = (_timing.CurTime, _timing.CurTime + ent.Comp.Cooldown); + action.UseDelay = ent.Comp.Cooldown; + Dirty(ent.Comp.Action.Value, action); + } + + turnInvisible.UncloakTime = _timing.CurTime; + var popupOthers = Loc.GetString("rmc-cloak-deactivate-others", ("user", user)); + _popup.PopupPredicted(Loc.GetString("rmc-cloak-deactivate-self"), popupOthers, user, user, PopupType.Medium); + } + + ToggleLayers(user, ent.Comp.CloakedHideLayers, true); + SpawnCloakEffects(user, ent.Comp.UncloakEffect); + + RemCompDeferred(user); + + if (_net.IsServer) + _audio.PlayPvs(ent.Comp.UncloakSound, user); + } + } + + public void TrySetInvisibility(EntityUid uid, bool enabling, bool forced, ThermalCloakComponent? component = null) + { + var cloak = FindWornCloak(uid); + if (cloak.HasValue) + SetInvisibility(cloak.Value, uid, enabling, forced); + } + + private void OnAttemptShoot(Entity ent, ref AttemptShootEvent args) + { + if (args.Cancelled || !TryComp(args.User, out var comp)) + return; + + if (comp.RestrictWeapons && comp.Enabled || comp.UncloakTime + comp.UncloakWeaponLock > _timing.CurTime) + { + args.Cancelled = true; + + var popup = Loc.GetString("rmc-cloak-attempt-shoot"); + _popup.PopupClient(popup, args.User, args.User, PopupType.SmallCaution); + } + } + + private void OnTimerUse(Entity ent, ref UseInHandEvent args) + { + if (args.Handled || !TryComp(args.User, out var comp)) + return; + + if (comp.RestrictWeapons && comp.Enabled || comp.UncloakTime + comp.UncloakWeaponLock > _timing.CurTime) + { + args.Handled = true; + + var popup = Loc.GetString("rmc-cloak-attempt-prime"); + _popup.PopupClient(popup, args.User, args.User, PopupType.SmallCaution); + } + } + + private void OnProjectile(Entity ent, ref ProjectileHitEvent args) + { + TrySetInvisibility(args.Target, false, true); + } + + private void OnMeleeHit(Entity ent, ref MeleeHitEvent args) + { + TrySetInvisibility(args.User, false, true); + } + + private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) + { + if (args.NewMobState != MobState.Dead) + return; + + TrySetInvisibility(ent.Owner, false, true); + } + private Entity? FindWornCloak(EntityUid player) + { + var slots = _inventory.GetSlotEnumerator(player, SlotFlags.All); + while (slots.MoveNext(out var slot)) + { + if (TryComp(slot.ContainedEntity, out var comp)) + return (slot.ContainedEntity.Value, comp); + } + + return null; + } + + private void ToggleLayers(EntityUid equipee, HashSet layers, bool showLayers) + { + foreach (HumanoidVisualLayers layer in layers) + { + _humanoidSystem.SetLayerVisibility(equipee, layer, showLayers); + } + } + + public void SpawnCloakEffects(EntityUid user, EntProtoId cloakProtoId) + { + if (_net.IsClient) + return; + + var coordinates = _transform.GetMapCoordinates(user); + var rotation = _transform.GetWorldRotation(user); + + Spawn(cloakProtoId, coordinates, rotation: rotation); + } +} diff --git a/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakTurnInvisibleActionEvent.cs b/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakTurnInvisibleActionEvent.cs new file mode 100644 index 00000000000..e44c9bac796 --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Armor/ThermalCloak/ThermalCloakTurnInvisibleActionEvent.cs @@ -0,0 +1,5 @@ +using Content.Shared.Actions; + +namespace Content.Shared._RMC14.Armor.ThermalCloak; + +public sealed partial class ThermalCloakTurnInvisibleActionEvent : InstantActionEvent; diff --git a/Content.Shared/ADT/_RMC14/Stealth/ActiveInvisibleToggledEvent.cs b/Content.Shared/ADT/_RMC14/Stealth/ActiveInvisibleToggledEvent.cs new file mode 100644 index 00000000000..9d5dce0a81b --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Stealth/ActiveInvisibleToggledEvent.cs @@ -0,0 +1,8 @@ +using Content.Shared.FixedPoint; + +namespace Content.Shared._RMC14.Stealth; + +[ByRefEvent] +public record struct ActiveInvisibleToggledEvent( + bool Enabled +); diff --git a/Content.Shared/ADT/_RMC14/Stealth/EntityActiveInvisibleComponent.cs b/Content.Shared/ADT/_RMC14/Stealth/EntityActiveInvisibleComponent.cs new file mode 100644 index 00000000000..cea632d3e68 --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Stealth/EntityActiveInvisibleComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.FixedPoint; +using Robust.Shared.GameStates; + +namespace Content.Shared._RMC14.Stealth; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] +public sealed partial class EntityActiveInvisibleComponent : Component +{ + [DataField, AutoNetworkedField] + public float Opacity = 0.1f; +} diff --git a/Content.Shared/ADT/_RMC14/Stealth/EntityTurnInvisibleComponent.cs b/Content.Shared/ADT/_RMC14/Stealth/EntityTurnInvisibleComponent.cs new file mode 100644 index 00000000000..8240a77b39b --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Stealth/EntityTurnInvisibleComponent.cs @@ -0,0 +1,26 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._RMC14.Stealth; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class EntityTurnInvisibleComponent : Component +{ + public bool Enabled; + + [DataField, AutoNetworkedField] + public float Opacity = 1f; + + [DataField, AutoNetworkedField] + public bool RestrictWeapons; + + [DataField] + [AutoNetworkedField] + public TimeSpan UncloakTime; + + /// + /// Amount of time after uncloaking weapons remain locked + /// + [DataField] + [AutoNetworkedField] + public TimeSpan UncloakWeaponLock; +} diff --git a/Content.Shared/ADT/_RMC14/Stealth/RMCPassiveStealthComponent.cs b/Content.Shared/ADT/_RMC14/Stealth/RMCPassiveStealthComponent.cs new file mode 100644 index 00000000000..046d6dd0ad6 --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Stealth/RMCPassiveStealthComponent.cs @@ -0,0 +1,32 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._RMC14.Stealth; + +/// +/// Will slowly lower an entity's opacity +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class RMCPassiveStealthComponent : Component +{ + [DataField, AutoNetworkedField] + public float MinOpacity = 0.2f; + + [DataField, AutoNetworkedField] + public float MaxOpacity = 1f; + + [DataField, AutoNetworkedField] + public bool? Enabled = null; + + /// + /// How long it will take to get to full invisibility + /// + [DataField, AutoNetworkedField] + public TimeSpan Delay = TimeSpan.Zero; + + [DataField, AutoNetworkedField] + public TimeSpan ToggleTime; + + [DataField] + public bool Toggleable; + +} diff --git a/Content.Shared/ADT/_RMC14/Stealth/RMCPassiveStealthSystem.cs b/Content.Shared/ADT/_RMC14/Stealth/RMCPassiveStealthSystem.cs new file mode 100644 index 00000000000..f2d0798ad38 --- /dev/null +++ b/Content.Shared/ADT/_RMC14/Stealth/RMCPassiveStealthSystem.cs @@ -0,0 +1,129 @@ +using Content.Shared.Foldable; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Storage.EntitySystems; +using Robust.Shared.Network; +using Robust.Shared.Timing; + +namespace Content.Shared._RMC14.Stealth; + +public sealed class RMCPassiveStealthSystem : EntitySystem +{ + [Dependency] private readonly SharedEntityStorageSystem _entityStorage = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnFolded, after: [typeof(SharedEntityStorageSystem)]); + SubscribeLocalEvent(OnToggle); + } + + private void OnInit(Entity ent, ref ComponentInit args) + { + if (_timing.ApplyingState) + return; + + if (Paused(ent.Owner)) + return; + + ent.Comp.Enabled = false; + EnsureComp(ent.Owner); + } + + private void OnFolded(Entity ent, ref FoldedEvent args) + { + if (_timing.ApplyingState) + return; + + if (ent.Comp.Enabled == null) + return; + + if (!args.IsFolded) + { + _entityStorage.OpenStorage(ent.Owner); + ent.Comp.Enabled = false; + return; + } + ent.Comp.Enabled = false; + RemCompDeferred(ent.Owner); + } + + private void OnToggle(Entity ent, ref ActivateInWorldEvent args) + { + if (_timing.ApplyingState) + return; + + if (!ent.Comp.Toggleable) + return; + + if (TryComp(ent.Owner, out var fold) && fold.IsFolded) + return; + + ent.Comp.Enabled ??= false; + + if (ent.Comp.Enabled.Value) + { + ent.Comp.Enabled = false; + ent.Comp.ToggleTime = _timing.CurTime; + Dirty(ent.Owner, ent.Comp); + } + else + { + ent.Comp.Enabled = true; + ent.Comp.ToggleTime = _timing.CurTime; + Dirty(ent.Owner, ent.Comp); + } + } + + public override void Update(float frameTime) + { + if (!_timing.IsFirstTimePredicted) + return; + + var stealth = EntityQueryEnumerator(); + while (stealth.MoveNext(out var uid, out var stealthComp)) + { + if (!stealthComp.Enabled.HasValue) + continue; + + if (_net.IsClient) + continue; + + var time = _timing.CurTime - stealthComp.ToggleTime; + if (stealthComp.Enabled.Value) + { + var invis = EnsureComp(uid); + if (time < stealthComp.Delay) + { + invis.Opacity = (float)(stealthComp.MaxOpacity - (time / stealthComp.Delay) * (stealthComp.MaxOpacity - stealthComp.MinOpacity)); // Linear function from 1 to MinOpacity + } + else + { + invis.Opacity = stealthComp.MinOpacity; + } + + Dirty(uid, invis); + + } + else + { + if (!TryComp(uid, out var invis)) + continue; + + if (time < stealthComp.Delay) + { + invis.Opacity = (float)(stealthComp.MinOpacity + (time / stealthComp.Delay) * (stealthComp.MaxOpacity - stealthComp.MinOpacity)); // Linear function from MinOpacity to 1 + Dirty(uid, invis); + continue; + } + + RemCompDeferred(uid); + } + } + } +} diff --git a/Content.Shared/Ninja/Components/StunProviderComponent.cs b/Content.Shared/Ninja/Components/StunProviderComponent.cs index 2da094291d7..4005205a282 100644 --- a/Content.Shared/Ninja/Components/StunProviderComponent.cs +++ b/Content.Shared/Ninja/Components/StunProviderComponent.cs @@ -55,7 +55,7 @@ public sealed partial class StunProviderComponent : Component /// How long stunning is disabled after stunning something. /// [DataField] - public TimeSpan Cooldown = TimeSpan.FromSeconds(2); + public TimeSpan Cooldown = TimeSpan.FromSeconds(6); // adt tweak xz /// /// ID of the cooldown use delay. diff --git a/Resources/Audio/ADT/Effects/Cloak/attributions.yml b/Resources/Audio/ADT/Effects/Cloak/attributions.yml new file mode 100644 index 00000000000..e4b3ae5ff78 --- /dev/null +++ b/Resources/Audio/ADT/Effects/Cloak/attributions.yml @@ -0,0 +1,4 @@ +- files: ["scout_cloak_on.ogg, scout_cloak_off.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from cmss13" + source: "https://github.com/cmss13-devs/cmss13/commit/7bf8ce23bdf2dec7429ee4ae9c6e350d6cdb9f00" \ No newline at end of file diff --git a/Resources/Audio/ADT/Effects/Cloak/cloak_scout_off.ogg b/Resources/Audio/ADT/Effects/Cloak/cloak_scout_off.ogg new file mode 100644 index 00000000000..e1a188e35ae Binary files /dev/null and b/Resources/Audio/ADT/Effects/Cloak/cloak_scout_off.ogg differ diff --git a/Resources/Audio/ADT/Effects/Cloak/cloak_scout_on.ogg b/Resources/Audio/ADT/Effects/Cloak/cloak_scout_on.ogg new file mode 100644 index 00000000000..2df636c9100 Binary files /dev/null and b/Resources/Audio/ADT/Effects/Cloak/cloak_scout_on.ogg differ diff --git a/Resources/Locale/ru-RU/ADT/clothing/invisible_cloak.ftl b/Resources/Locale/ru-RU/ADT/clothing/invisible_cloak.ftl new file mode 100644 index 00000000000..5f6e5349f86 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/clothing/invisible_cloak.ftl @@ -0,0 +1,9 @@ +rmc-cloak-activate-self = Вы активировали камуфляж плаща. +rmc-cloak-activate-others = {$user} исчезает в воздухе! +rmc-cloak-deactivate-self = Камуфляж вашего плаща отключен! +rmc-cloak-deactivate-others = {$user} появляется из воздуха! +rmc-cloak-forced-deactivate-self = Ваш плащ неожиданно отключился! +rmc-cloak-forced-deactivate-others = Плащ {$user} неожиданно отключился! + +rmc-cloak-attempt-shoot = Ваш плащ не позволяет вам стрелять! +rmc-cloak-attempt-prime = Ваш плащ не позволяет вам активировать эту гранату! diff --git a/Resources/Locale/ru-RU/ADT/prototypes/Catalog/Fills/backpacks/duffelbag.ftl b/Resources/Locale/ru-RU/ADT/prototypes/Catalog/Fills/backpacks/duffelbag.ftl index 4b8830bbe73..480cd63a752 100644 --- a/Resources/Locale/ru-RU/ADT/prototypes/Catalog/Fills/backpacks/duffelbag.ftl +++ b/Resources/Locale/ru-RU/ADT/prototypes/Catalog/Fills/backpacks/duffelbag.ftl @@ -37,5 +37,8 @@ ent-ADTClothingBackpackDuffelSyndicateFilledBlackmail = набор шантаж ent-ADTClothingBackpackDuffelSyndicateFilledElite = набор элитного налетчика .desc = Содержит улучшенный скафандр Синдиката, продвинутые магнитные сапоги и энергомеч с щитом. +ent-ADTClothingBackpackDuffelSyndicateModuleGrenade = набор модульных гранат + .desc = Содержит материалы для создания двух модульных пенных гранат. Распыляемый в пене реагент нужно достать самому. + ent-ADTClothingBackpackDuffelSyndicateFilledWeaponAttachments = набор оружейных модулей .desc = Комплект из вертикальной рукояти, лазерного целеуказателя, коллиматорного и оптического прицелов. diff --git a/Resources/Locale/ru-RU/ADT/prototypes/Catalog/store/uplink-catalog.ftl b/Resources/Locale/ru-RU/ADT/prototypes/Catalog/store/uplink-catalog.ftl index 65b3d254a84..021df34af92 100644 --- a/Resources/Locale/ru-RU/ADT/prototypes/Catalog/store/uplink-catalog.ftl +++ b/Resources/Locale/ru-RU/ADT/prototypes/Catalog/store/uplink-catalog.ftl @@ -99,9 +99,18 @@ ADTuplink-grenade-launcher-bundle-desc = Набор, содержащий в с uplink-mask-name = Балаклава uplink-mask-desc = Идеально, если вы террорист. +uplink-invisible-cloak-name = плащ-невидимка +uplink-invisible-cloak-desc = Плащ, который скрывает владельца, приобретая цвета и очертание окружающей среды с помощью нанотехнологий. Также, он дает небольшую защиту от внешних воздействий, но обратная сторона таких свойств - замедление. + +uplink-night-vision-name = прибор ночного видения +uplink-night-vision-desc = Прибор, позволяющий лучше видеть в темноте или при плохой освещенности. Обратной стороной является возможность стать ослепленным при воздействии яркой вспышки света. + uplink-nukiesShield-name = двуручный штурмовой щит uplink-nukiesShield-desc = Массивный и опасный, двуручный щит из элитных материалов для лучшей защиты, имеет несколько рядов пластин, а также несколько шипов на основе щита. +uplink-ADTModularGrenadeBundle-name = набор модульных гранат +uplink-ADTModularGrenadeBundle-desc = Содержит материалы для создания двух модульных пенных гранат. Распыляемый в пене реагент нужно достать самому. + uplink-omnizinpizza-name = коробка с пиццей Синдиката uplink-omnizinpizza-desc = Это коробка с самой обычной пиццей внутри. Именно то, что используют элитные агенты для перекуса между перестрелками с Капитаном и кражей Иана. diff --git a/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Eyes/glasses.ftl b/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Eyes/glasses.ftl index e018e9dbd1b..dcee8da40cb 100644 --- a/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Eyes/glasses.ftl +++ b/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Eyes/glasses.ftl @@ -21,3 +21,6 @@ ent-ADTNeonTacticalGlasses = неоновые тактические очки ent-ADTServantOfEvilGlasses = сварочные очки прислужника зла .suffix = Хеллоуин .desc = К сожалению, вместо защитных линз, здесь теперь обычное стекло, так что они утратили свои свойства. + +ent-ClothingEyesNightVision = прибор ночного видения + .desc = Прибор, позволяющий лучше видеть в темноте или при плохой освещенности. Обратной стороной является возможность стать ослепленным при воздействии яркой вспышки света. diff --git a/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Neck/cloaks.ftl b/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Neck/cloaks.ftl index 211b98478dc..324c481c313 100644 --- a/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Neck/cloaks.ftl +++ b/Resources/Locale/ru-RU/ADT/prototypes/Entities/Clothing/Neck/cloaks.ftl @@ -44,3 +44,6 @@ ent-ADTVergileCloak = плащ темного убийцы ent-ADTClothingNeckCloakRedhat = мантия Красной шапочки .suffix = Хеллоуин .desc = Красная Шапочка, я тебя съем! сказал большой страшный серый волк. А попробуй! сказала красная шапочка, держа в руках лом + +ent-ADTClothingNeckInvisibleCloak = плащ-невидимка + .desc = Плащ, который скрывает владельца, приобретая цвета и очертание окружающей среды с помощью нанотехнологий. Также, он дает небольшую защиту от внешних воздействий, но обратная сторона таких свойств - замедление. diff --git a/Resources/Locale/ru-RU/ADT/prototypes/Entities/Objects/Specific/Chemistry/chemical-bottles.ftl b/Resources/Locale/ru-RU/ADT/prototypes/Entities/Objects/Specific/Chemistry/chemical-bottles.ftl index 49d819297b3..0cb7ada89c9 100644 --- a/Resources/Locale/ru-RU/ADT/prototypes/Entities/Objects/Specific/Chemistry/chemical-bottles.ftl +++ b/Resources/Locale/ru-RU/ADT/prototypes/Entities/Objects/Specific/Chemistry/chemical-bottles.ftl @@ -36,3 +36,6 @@ ent-ADTOpiumBottle = бутылочка опиума .desc = Небольшая бутылочка, за которую велись целые войны в далёком прошлом. Но сейчас же никто не будет убивать других ради короткого момента эйфории, верно? ent-ADTFormalinBottle = бутылочка формалина .desc = Основа работы патологоанатома. + +ent-ADTObjectsSpecificFluorosurfactantChemistryBottle = бутылочка фторсурфактанта + .desc = Бутылочка с перфторированнпй сульфоновой кислотой, образующей пену при смешивании с водой. diff --git a/Resources/Prototypes/ADT/Actions/cloak.yml b/Resources/Prototypes/ADT/Actions/cloak.yml new file mode 100644 index 00000000000..d658d70da26 --- /dev/null +++ b/Resources/Prototypes/ADT/Actions/cloak.yml @@ -0,0 +1,10 @@ +- type: entity + id: ADTActionToggleCloak + categories: + - HideSpawnMenu + name: Toggle Cloak + description: Enable or Disable your Thermal Cloak + components: + - type: InstantAction + event: !type:ThermalCloakTurnInvisibleActionEvent + useDelay: 5 diff --git a/Resources/Prototypes/ADT/Catalog/Fills/Backpacks/duffelbag.yml b/Resources/Prototypes/ADT/Catalog/Fills/Backpacks/duffelbag.yml index 3994d3e71d5..6bd061dc0ad 100644 --- a/Resources/Prototypes/ADT/Catalog/Fills/Backpacks/duffelbag.yml +++ b/Resources/Prototypes/ADT/Catalog/Fills/Backpacks/duffelbag.yml @@ -182,6 +182,33 @@ - id: EnergyShield - id: EnergySword +- type: entity + parent: ClothingBackpackDuffelSyndicateBundle + id: ADTClothingBackpackDuffelSyndicateModuleGrenade + name: module grenade bundle + description: bundle with a materials for module grenade + components: + - type: StorageFill + contents: + - id: SheetSteel + - id: BoxBeaker + - id: RemoteSignaller + - id: CableApcStack10 + - id: ADTObjectsSpecificFluorosurfactantChemistryBottle + amount: 4 + - id: DrinkWaterBottleFull + amount: 2 + - id: ChemicalPayload + amount: 4 + # - id: ModularGrenade + # amount: 2 + - id: TimerTrigger + amount: 2 + - id: SignalTrigger + amount: 2 + - id: VoiceTrigger + amount: 2 + - type: entity parent: ClothingBackpackDuffelSyndicateBundle id: ADTClothingBackpackDuffelSyndicateFilledChinaLikeGrenadeLauncher diff --git a/Resources/Prototypes/ADT/Catalog/boobr_catalog.yml b/Resources/Prototypes/ADT/Catalog/boobr_catalog.yml index e8a3db6e241..7f0376dcff7 100644 --- a/Resources/Prototypes/ADT/Catalog/boobr_catalog.yml +++ b/Resources/Prototypes/ADT/Catalog/boobr_catalog.yml @@ -296,3 +296,13 @@ Productunit: 4 categories: - ADTUplinkERTMisc + +- type: listing + id: ADTBoberNightVision + name: uplink-night-vision-name + description: uplink-night-vision-desc + productEntity: ClothingEyesNightVision + cost: + Productunit: 4 + categories: + - ADTUplinkERTMisc diff --git a/Resources/Prototypes/ADT/Catalog/uplink_catalog.yml b/Resources/Prototypes/ADT/Catalog/uplink_catalog.yml index 92f87a30486..9083954edba 100644 --- a/Resources/Prototypes/ADT/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/ADT/Catalog/uplink_catalog.yml @@ -279,7 +279,7 @@ icon: { sprite: ADT/Clothing/Shoes/Boots/jumpboots_syndie.rsi, state: icon } productEntity: ADTClothingJumpBootsSynd cost: - Telecrystal: 5 + Telecrystal: 4 # ADT-Tweak 4>5 categories: - UplinkWearables conditions: @@ -562,6 +562,36 @@ categories: - UplinkWearables +- type: listing + id: ADTUplinkInvisibleCloak + name: uplink-invisible-cloak-name + description: uplink-invisible-cloak-desc + productEntity: ADTClothingNeckInvisibleCloak + cost: + Telecrystal: 5 + categories: + - UplinkWearables + +- type: listing + id: ADTUplinkNightVision + name: uplink-night-vision-name + description: uplink-night-vision-desc + productEntity: ClothingEyesNightVision + cost: + Telecrystal: 5 + categories: + - UplinkWearables + +- type: listing + id: UplinkADTModularGrenadeBundle + name: uplink-ADTModularGrenadeBundle-name + description: uplink-ADTModularGrenadeBundle-desc + productEntity: ADTClothingBackpackDuffelSyndicateModuleGrenade + cost: + Telecrystal: 6 + categories: + - UplinkChemicals + - type: listing id: ADTUplinkGrenadeLauncherBundle name: ADTuplink-grenade-launcher-bundle-name @@ -585,4 +615,4 @@ - UplinkPointless conditions: - !type:ListingLimitedStockCondition - stock: 3 + stock: 3 \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Effects/cloak.yml b/Resources/Prototypes/ADT/Effects/cloak.yml new file mode 100644 index 00000000000..bbba5665c88 --- /dev/null +++ b/Resources/Prototypes/ADT/Effects/cloak.yml @@ -0,0 +1,33 @@ +- type: entity + id: RMCEffectCloakBase + abstract: true + components: + - type: Sprite + sprite: ADT/Effects/cloak.rsi + drawdepth: Effects + noRot: true + - type: EffectVisuals + - type: AnimationPlayer + - type: Tag + tags: + - HideContextMenu + +- type: entity + parent: RMCEffectCloakBase + id: RMCEffectCloak + categories: [ HideSpawnMenu ] + components: + - type: Sprite + state: cloak + - type: TimedDespawn + lifetime: 0.75 + +- type: entity + parent: RMCEffectCloakBase + id: RMCEffectUncloak + categories: [ HideSpawnMenu ] + components: + - type: Sprite + state: uncloak + - type: TimedDespawn + lifetime: 0.65 diff --git a/Resources/Prototypes/ADT/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/ADT/Entities/Clothing/Eyes/glasses.yml index ce91137aca9..a5ada0f40ae 100644 --- a/Resources/Prototypes/ADT/Entities/Clothing/Eyes/glasses.yml +++ b/Resources/Prototypes/ADT/Entities/Clothing/Eyes/glasses.yml @@ -103,3 +103,23 @@ state: icon - type: Clothing sprite: ADT/Clothing/Eyes/Glasses/sollux_captor.rsi + +- type: entity + parent: [ClothingEyesBase, BaseMajorContraband] + id: ClothingEyesNightVision + name: night vision + description: jungar privet + components: + - type: Sprite + sprite: Clothing/Eyes/Glasses/ninjavisor.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/ninjavisor.rsi + - type: NightVisionItem # RMC Night vision + - type: ItemToggle # RMC Night vision + - type: Appearance + - type: GenericVisualizer + visuals: + enum.NightVisionItemVisuals.Active: + icon: + True: { state: icon } + False: { state: icon } diff --git a/Resources/Prototypes/ADT/Entities/Clothing/Neck/Cloaks.yml b/Resources/Prototypes/ADT/Entities/Clothing/Neck/Cloaks.yml index 0f854572932..e7219f56bf4 100644 --- a/Resources/Prototypes/ADT/Entities/Clothing/Neck/Cloaks.yml +++ b/Resources/Prototypes/ADT/Entities/Clothing/Neck/Cloaks.yml @@ -129,3 +129,43 @@ - neck slot: head +- type: entity + parent: ClothingNeckBase + id: ADTClothingNeckInvisibleCloak + name: Invisible Cloak + description: kto eto chitaet + components: + - type: Sprite + sprite: ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi + - type: ThermalCloak + opacity: 0.08 + cooldown: 7 + restrictWeapons: true + cloakedHideLayers: + - Hair + - HeadTop + - HeadSide + - Tail + - Snout + cloakSound: + path: /Audio/ADT/Effects/Cloak/cloak_scout_on.ogg + params: + variation: 0.09 + uncloakSound: + path: /Audio/ADT/Effects/Cloak/cloak_scout_off.ogg + params: + variation: 0.09 + - type: ToggleClothing + action: ADTActionToggleCloak + - type: ClothingSpeedModifier + walkModifier: 0.90 + sprintModifier: 0.90 + - type: HeldSpeedModifier + - type: Armor + modifiers: + coefficients: + Blunt: 0.9 + Slash: 0.9 + Piercing: 0.9 + - type: Item + size: Normal diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/Tajaran.yml b/Resources/Prototypes/ADT/Entities/Mobs/Species/Tajaran.yml index f0054536163..98161eb7763 100644 --- a/Resources/Prototypes/ADT/Entities/Mobs/Species/Tajaran.yml +++ b/Resources/Prototypes/ADT/Entities/Mobs/Species/Tajaran.yml @@ -108,7 +108,6 @@ - DoorBumpOpener - AnomalyHost - ADTCatEmotes - - type: DamageEyesOnFlashed - type: entity save: false diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/Vulpkanin.yml b/Resources/Prototypes/ADT/Entities/Mobs/Species/Vulpkanin.yml index 5453b75729e..c3bbf6e1555 100644 --- a/Resources/Prototypes/ADT/Entities/Mobs/Species/Vulpkanin.yml +++ b/Resources/Prototypes/ADT/Entities/Mobs/Species/Vulpkanin.yml @@ -124,7 +124,6 @@ - DoorBumpOpener - AnomalyHost - ADTDogEmotes - - type: DamageEyesOnFlashed - type: entity save: false diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/shadekin.yml b/Resources/Prototypes/ADT/Entities/Mobs/Species/shadekin.yml index d1f02e02ee8..83667a5af25 100644 --- a/Resources/Prototypes/ADT/Entities/Mobs/Species/shadekin.yml +++ b/Resources/Prototypes/ADT/Entities/Mobs/Species/shadekin.yml @@ -166,7 +166,6 @@ color: "#3C0F24" Burn: sprite: Mobs/Effects/burn_damage.rsi - - type: DamageEyesOnFlashed - type: Inventory displacements: jumpsuit: diff --git a/Resources/Prototypes/ADT/Entities/Objects/Specific/Chemistry/chemical-bottles.yml b/Resources/Prototypes/ADT/Entities/Objects/Specific/Chemistry/chemical-bottles.yml index 4d68c7ce034..c89ad0a76b8 100644 --- a/Resources/Prototypes/ADT/Entities/Objects/Specific/Chemistry/chemical-bottles.yml +++ b/Resources/Prototypes/ADT/Entities/Objects/Specific/Chemistry/chemical-bottles.yml @@ -422,3 +422,16 @@ reagents: - ReagentId: Lexorin Quantity: 30 + +- type: entity + id: ADTObjectsSpecificFluorosurfactantChemistryBottle + name: Fluorosurfactant bottle + parent: BaseChemistryEmptyBottle + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: Fluorosurfactant + Quantity: 30 diff --git a/Resources/Prototypes/ADT/game_presets.yml b/Resources/Prototypes/ADT/game_presets.yml index a4538e1dd94..0cc4f1b9ff0 100644 --- a/Resources/Prototypes/ADT/game_presets.yml +++ b/Resources/Prototypes/ADT/game_presets.yml @@ -5,7 +5,7 @@ - ghosts name: phantom-title minPlayers: 1 - showInVote: true + showInVote: false description: phantom-description rules: - PhantomGameRule diff --git a/Resources/Prototypes/Catalog/thief_toolbox_sets.yml b/Resources/Prototypes/Catalog/thief_toolbox_sets.yml index fe1a4fe75c9..b602a9df06d 100644 --- a/Resources/Prototypes/Catalog/thief_toolbox_sets.yml +++ b/Resources/Prototypes/Catalog/thief_toolbox_sets.yml @@ -64,6 +64,7 @@ - Lighter - CigPackSyndicate - Telecrystal10 #The thief cannot use them, but it may induce communication with traitors + - ADTClothingNeckInvisibleCloak #ADT Tweak - type: thiefBackpackSet id: SleeperSet diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index baa4ac0e441..d399345dc1f 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -88,9 +88,9 @@ productEntity: ThrowingKnivesKit discountCategory: rareDiscounts discountDownTo: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 3>2 cost: - Telecrystal: 6 + Telecrystal: 4 # ADT-Tweak 6>4 categories: - UplinkWeaponry @@ -114,9 +114,9 @@ productEntity: ToolboxElectricalTurretFilled discountCategory: usualDiscounts discountDownTo: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 6>4 cost: - Telecrystal: 6 + Telecrystal: 4 # ADT-Tweak 6>4 categories: - UplinkWeaponry conditions: @@ -232,7 +232,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkExplosives @@ -380,7 +380,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkExplosives @@ -567,9 +567,9 @@ productEntity: HypopenBox discountCategory: rareDiscounts discountDownTo: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 cost: - Telecrystal: 6 + Telecrystal: 5 # ADT-Tweak 6>4 categories: - UplinkChemicals @@ -595,9 +595,9 @@ productEntity: ChemicalSynthesisKit discountCategory: usualDiscounts discountDownTo: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 3>2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkChemicals @@ -628,9 +628,9 @@ productEntity: NocturineChemistryBottle discountCategory: usualDiscounts discountDownTo: - Telecrystal: 3 + Telecrystal: 3 # ADT-Tweak 4>3 cost: - Telecrystal: 6 + Telecrystal: 5 # ADT-Tweak 6>4 categories: - UplinkChemicals @@ -680,9 +680,9 @@ productEntity: StimkitFilled discountCategory: rareDiscounts discountDownTo: - Telecrystal: 8 + Telecrystal: 6 # ADT-Tweak 8>6 cost: - Telecrystal: 12 + Telecrystal: 10 # ADT-Tweak 12>10 categories: - UplinkChemicals @@ -732,7 +732,7 @@ discountDownTo: Telecrystal: 1 cost: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 3>2 categories: - UplinkDeception @@ -756,9 +756,9 @@ productEntity: ChameleonProjector discountCategory: rareDiscounts discountDownTo: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 cost: - Telecrystal: 7 + Telecrystal: 5 # ADT-Tweak 7>5 categories: - UplinkDeception @@ -829,7 +829,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkDeception @@ -851,9 +851,9 @@ productEntity: ClothingBackpackDuffelSyndicateDecoyKitFilled discountCategory: usualDiscounts discountDownTo: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 3>2 cost: - Telecrystal: 6 + Telecrystal: 4 # ADT-Tweak 6>4 categories: - UplinkDeception @@ -866,7 +866,7 @@ discountDownTo: Telecrystal: 1 cost: - Telecrystal: 4 + Telecrystal: 2 # ADT-Tweak 4>2 categories: - UplinkDeception @@ -879,9 +879,9 @@ productEntity: Emag discountCategory: veryRareDiscounts discountDownTo: - Telecrystal: 5 + Telecrystal: 4 # ADT-Tweak 5>4 cost: - Telecrystal: 8 + Telecrystal: 6 # ADT-Tweak 8>6 categories: - UplinkDisruption @@ -892,9 +892,9 @@ productEntity: RadioJammer discountCategory: usualDiscounts discountDownTo: - Telecrystal: 2 + Telecrystal: 1 # ADT-Tweak 2>1 cost: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 3>2 categories: - UplinkDisruption @@ -907,7 +907,7 @@ discountDownTo: Telecrystal: 3 cost: - Telecrystal: 5 + Telecrystal: 4 # ADT-Tweak 5>4 categories: - UplinkDisruption @@ -994,9 +994,9 @@ productEntity: PowerSink discountCategory: usualDiscounts discountDownTo: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 cost: - Telecrystal: 8 + Telecrystal: 6 # ADT-Tweak 8>6 categories: - UplinkDisruption conditions: @@ -1012,9 +1012,9 @@ productEntity: AntimovCircuitBoard discountCategory: usualDiscounts discountDownTo: - Telecrystal: 10 + Telecrystal: 6 # ADT-Tweak 10>6 cost: - Telecrystal: 14 + Telecrystal: 10 # ADT-Tweak 14>10 categories: - UplinkDisruption conditions: @@ -1098,7 +1098,7 @@ description: uplink-cameraBug-desc productEntity: CameraBug cost: - Telecrystal: 4 + Telecrystal: 2 # ADT-Tweak 4>2 categories: - UplinkDisruption @@ -1112,9 +1112,9 @@ productEntity: BoxHoloparasite discountCategory: usualDiscounts discountDownTo: - Telecrystal: 8 + Telecrystal: 6 # ADT-Tweak 8>6 cost: - Telecrystal: 14 + Telecrystal: 10 # ADT-Tweak 14>10 categories: - UplinkAllies conditions: @@ -1131,9 +1131,9 @@ icon: { sprite: Objects/Devices/communication.rsi, state: old-radio-urist } discountCategory: usualDiscounts discountDownTo: - Telecrystal: 7 + Telecrystal: 6 # ADT-Tweak 8>6 cost: - Telecrystal: 14 + Telecrystal: 10 # ADT-Tweak 14>10 categories: - UplinkAllies conditions: @@ -1165,7 +1165,7 @@ productEntity: ReinforcementRadioSyndicateCyborgAssault icon: { sprite: Objects/Devices/communication.rsi, state: old-radio-borg-assault } cost: - Telecrystal: 65 + Telecrystal: 40 # ADT-Tweak 65>40 categories: - UplinkAllies conditions: @@ -1182,9 +1182,9 @@ icon: { sprite: Objects/Devices/communication.rsi, state: old-radio-ancestor } discountCategory: usualDiscounts discountDownTo: - Telecrystal: 4 + Telecrystal: 2 # ADT-Tweak 4>2 cost: - Telecrystal: 6 + Telecrystal: 3 # ADT-Tweak 6>3 categories: - UplinkAllies conditions: @@ -1238,9 +1238,9 @@ productEntity: ReinforcementRadioSyndicateSyndiCat discountCategory: usualDiscounts discountDownTo: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 3>2 cost: - Telecrystal: 6 + Telecrystal: 4 # ADT-Tweak 6>4 categories: - UplinkAllies @@ -1287,9 +1287,9 @@ productEntity: FreedomImplanter discountCategory: veryRareDiscounts discountDownTo: - Telecrystal: 3 + Telecrystal: 2 # ADT-Tweak 3>2 cost: - Telecrystal: 5 + Telecrystal: 4 # ADT-Tweak 5>4 categories: - UplinkImplants @@ -1301,9 +1301,9 @@ productEntity: ScramImplanter discountCategory: veryRareDiscounts discountDownTo: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 cost: - Telecrystal: 6 # it's a gamble that may kill you easily so 6 TC per 2 uses, second one more of a backup + Telecrystal: 4 # it's a gamble that may kill you easily so 6 TC per 2 uses, second one more of a backup # ADT-Tweak 6>4 categories: - UplinkImplants @@ -1317,7 +1317,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 5 + Telecrystal: 4 # ADT-Tweak 5>4 categories: - UplinkImplants @@ -1487,7 +1487,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkWearables @@ -1513,7 +1513,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkWearables @@ -1539,7 +1539,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkWearables @@ -1695,7 +1695,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkPointless @@ -1718,7 +1718,7 @@ description: uplink-cat-ears-desc productEntity: ClothingHeadHatCatEars cost: - Telecrystal: 26 + Telecrystal: 10 # ADT-Tweak 26>10 categories: - UplinkPointless @@ -1844,7 +1844,7 @@ discountDownTo: Telecrystal: 3 cost: - Telecrystal: 6 + Telecrystal: 5 # ADT-Tweak 6>5 categories: - UplinkJob conditions: @@ -1861,7 +1861,7 @@ discountDownTo: Telecrystal: 3 cost: - Telecrystal: 6 + Telecrystal: 4 # ADT-Tweak 6>4 categories: - UplinkJob conditions: @@ -1895,7 +1895,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkJob conditions: @@ -1931,9 +1931,9 @@ productEntity: RevolverCapGunFake discountCategory: usualDiscounts discountDownTo: - Telecrystal: 5 + Telecrystal: 4 # ADT-Tweak 5>4 cost: - Telecrystal: 9 + Telecrystal: 8 # ADT-Tweak 9>8 categories: - UplinkJob conditions: @@ -1985,9 +1985,9 @@ productEntity: BoxHoloclown discountCategory: rareDiscounts discountDownTo: - Telecrystal: 6 + Telecrystal: 6 # ADT-Tweak 6>5 cost: - Telecrystal: 12 + Telecrystal: 10 # ADT-Tweak 12>10 categories: - UplinkJob conditions: @@ -2004,7 +2004,7 @@ Telecrystal: 2 productEntity: HotPotato cost: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 categories: - UplinkJob conditions: @@ -2041,7 +2041,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 5 # was 4, with my buff made it 5 to be closer to minibomb -panzer + Telecrystal: 4 # ADT-Tweak 5>4 categories: - UplinkJob conditions: @@ -2060,10 +2060,10 @@ icon: { sprite: Objects/Misc/monkeycube.rsi, state: box} discountCategory: rareDiscounts discountDownTo: - Telecrystal: 4 + Telecrystal: 3 # ADT-Tweak 4>3 productEntity: SyndicateSpongeBox cost: - Telecrystal: 7 + Telecrystal: 5 # ADT-Tweak 7>5 categories: - UplinkJob conditions: @@ -2084,7 +2084,7 @@ discountDownTo: Telecrystal: 2 cost: - Telecrystal: 5 + Telecrystal: 4 # ADT-Tweak 5>4 categories: - UplinkJob conditions: @@ -2103,7 +2103,7 @@ icon: { sprite: Objects/Consumable/Food/Baked/bread.rsi, state: baguette} productEntity: CombatBakeryKit cost: - Telecrystal: 6 + Telecrystal: 4 # ADT-Tweak 6>4 categories: - UplinkJob conditions: diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml index aac5ce37c2a..2213ae7cce8 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml @@ -154,13 +154,34 @@ Heat: 0.8 # phase cloak - type: ToggleClothing - action: ActionTogglePhaseCloak - - type: ComponentToggler - parent: true - components: - - type: Stealth - minVisibility: -0.4 #ADT_Tweak - lastVisibility: -0.4 #ADT_Tweak + action: ADTActionToggleCloak # adt tweak + # ADT TWEAK START + # - type: ComponentToggler + # parent: true + # components: + # - type: Stealth + # minVisibility: -0.4 #ADT_Tweak + # lastVisibility: -0.4 #ADT_Tweak + - type: ThermalCloak + opacity: 0.03 + restrictWeapons: true + ninjaSuit: true + cloakedHideLayers: + - Hair + - HeadTop + - HeadSide + - Tail + - Snout # I don't know if this is hugely problematic but better safe than sorry + cloakSound: + path: /Audio/ADT/Effects/Cloak/cloak_scout_on.ogg + params: + variation: 0.09 + uncloakSound: + path: /Audio/ADT/Effects/Cloak/cloak_scout_off.ogg + params: + variation: 0.09 + +# ADT TWEAK END - type: PowerCellDraw drawRate: 1.8 # 200 seconds on the default cell - type: ToggleCellDraw diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml index 6ede6ca8965..72dbf512da5 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml @@ -552,7 +552,7 @@ - type: SolutionContainerManager solutions: hypospray: - maxVol: 10 + maxVol: 15 #ADT Tweak 10>15 - type: RefillableSolution solution: hypospray # Corvax-HiddenDesc-Start @@ -563,7 +563,7 @@ - type: Hypospray onlyAffectsMobs: false - type: UseDelay - delay: 0.5 + delay: 0.25 #ADT Tweak 0.5>0.25 - type: StaticPrice # A new shitcurity meta price: 75 - type: EmitSoundOnUse diff --git a/Resources/Prototypes/Shaders/shaders.yml b/Resources/Prototypes/Shaders/shaders.yml index 136821efbb8..8465219c06d 100644 --- a/Resources/Prototypes/Shaders/shaders.yml +++ b/Resources/Prototypes/Shaders/shaders.yml @@ -104,3 +104,8 @@ id: Cataracts kind: source path: "/Textures/Shaders/cataracts.swsl" + +- type: shader + id: RMCInvisible + kind: source + path: "/Textures/ADT/Shaders/invisible.swsl" diff --git a/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/equipped-NECK.png b/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/equipped-NECK.png new file mode 100644 index 00000000000..2c0c76bba02 Binary files /dev/null and b/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/equipped-NECK.png differ diff --git a/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/icon.png b/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/icon.png new file mode 100644 index 00000000000..8c649e7d834 Binary files /dev/null and b/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/icon.png differ diff --git a/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/meta.json b/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/meta.json new file mode 100644 index 00000000000..254407c1598 --- /dev/null +++ b/Resources/Textures/ADT/Clothing/Neck/Cloaks/invisible_cloak.rsi/meta.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from cmss13 at https://github.com/cmss13-devs/cmss13/blob/38ced94fc7dee11e73f66f6c008983493aac13a5/icons/obj/items/clothing/backpacks.dmi and https://github.com/cmss13-devs/cmss13/blob/38ced94fc7dee11e73f66f6c008983493aac13a5/icons/mob/humans/onmob/back.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-NECK", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/ADT/Effects/cloak.rsi/cloak.png b/Resources/Textures/ADT/Effects/cloak.rsi/cloak.png new file mode 100644 index 00000000000..003e28d20ef Binary files /dev/null and b/Resources/Textures/ADT/Effects/cloak.rsi/cloak.png differ diff --git a/Resources/Textures/ADT/Effects/cloak.rsi/meta.json b/Resources/Textures/ADT/Effects/cloak.rsi/meta.json new file mode 100644 index 00000000000..4db6f5bd6cb --- /dev/null +++ b/Resources/Textures/ADT/Effects/cloak.rsi/meta.json @@ -0,0 +1,99 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/cmss13-devs/cmss13/blob/HEAD/icons/mob/mob.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "cloak", + "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": "uncloak", + "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 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/ADT/Effects/cloak.rsi/uncloak.png b/Resources/Textures/ADT/Effects/cloak.rsi/uncloak.png new file mode 100644 index 00000000000..093ba11071e Binary files /dev/null and b/Resources/Textures/ADT/Effects/cloak.rsi/uncloak.png differ diff --git a/Resources/Textures/ADT/Shaders/invisible.swsl b/Resources/Textures/ADT/Shaders/invisible.swsl new file mode 100644 index 00000000000..c5fc654ed41 --- /dev/null +++ b/Resources/Textures/ADT/Shaders/invisible.swsl @@ -0,0 +1,26 @@ +light_mode unshaded; + +uniform sampler2D SCREEN_TEXTURE; +uniform highp float visibility; // number between -1 and 1 +uniform mediump vec2 reference; + +const mediump float time_scale = 0.25; +const mediump float distance_scale = 0.125; + +void fragment() { + + highp vec4 sprite = zTexture(UV); + + if (sprite.a == 0.0) { + discard; + } + + lowp float alpha; + if (visibility>0.0) + alpha = sprite.a * visibility; + else + alpha = 0.0; + + COLOR.xyz = sprite.xyz; + COLOR.a = alpha; +}